2
\$\begingroup\$

I solve this problem in Swift. Looking for feedback on my code or a better solution:

enter image description here

import Foundation // parses line to return array of numbers in string format func readIntegers() -> [String] { return readLine()!.componentsSeparatedByString(" ").map { $0 } } // left rotates the array by a given input func leftRotation() -> String { let input = readIntegers() let array = readIntegers() var newArray = [String](count: Int(input[0])!, repeatedValue: "") let (count, rotations) = (Int(input[0])!, Int(input[1])!) for index in 0..<count { // newIndex after rotation let newIndex = index + rotations if newIndex < count { // up until count newArray[index] = array[newIndex] } else { // loops back to beginning index of array newArray[index] = array[newIndex - count] } } // joins the array return newArray.joinWithSeparator(" ") } print(leftRotation()) 
\$\endgroup\$

    4 Answers 4

    2
    \$\begingroup\$

    I am not a swift programmer so i will not be able to give you exact advice on how to improve the quality of your code but rather the algorithm you used to solve this challenge and nitpicks i have with your solution.

    Firstly lets look at the question itself.

    It asks you to print out the new array. why are you creating it and turning it back into a string?

    That considered, you can simply perform 2 for loops

    1 for loop up until the "break" where the array has overflown, and a second for loop for the rest of the untouched array.

    like that

    therfor we can simply print out the elements at location

    d to n 

    and then the elements from

    0 to d 

    This will shorten your code considerably and make it run a whole lot faster because no extra variables are needed and you arent doing array manipilation, its just a way to iterate over an array

    \$\endgroup\$
      1
      \$\begingroup\$

      First, whenever you see a phrase like "given x, perform y" you should think of the 'x' as inputs into a function that returns the result of 'y'.

      So you should have something like func rotate(array array: [Int], left distance: Int) -> [Int] somewhere in your code. Getting the data from the user and displaying it should be separate from the function that does the work.

      Second, the problem is underspecified. What if the distance to shift left is negative? Your solution will crash in the middle of the algorithm. It would be better to use the precondition function to make it explicit that this algorithm won't work with a negative count.

      Lastly, Swift's array class has methods to make this much more elegant. You should be able to implement this without a loop & without any vars. (Read up on the functions dropFirst and dropLast.)

      \$\endgroup\$
        0
        \$\begingroup\$

        This is what I did but still looking for any better answer available for this solution:

        import Foundation extension Array { func shiftedLeft(by rawOffset: Int = 1) -> Array { let rotation_amount = rawOffset % count let offset = rotation_amount < 0 ? count + rotation_amount : rotation_amount return Array(self[offset ..< count] + self[0 ..< offset]) } mutating func shiftLeft(by rawOffset: Int = 1) { self = self.shiftedLeft(by: rawOffset) } } class ArrayRotation { func readIntegers() -> [String] { return (readLine()?.components(separatedBy: " "))! } func rotateArray(){ let componentsMutableArray = readIntegers() let array = readIntegers() let number_of_rotation = Int(componentsMutableArray[1]) print(array.shiftedLeft(by: number_of_rotation!).joined(separator: " ")) } } 

        Looking for suggestions to improve, please share your thoughts too. Thanks

        \$\endgroup\$
          0
          \$\begingroup\$

          I've tried several variations and appart for a minor improvement on the offset calculation (to allow negatives to rotate to the right), I couldn't find anything meaningful to add:

           public func shiftedLeft(by rotation:Int) -> [Element] { guard count > 1 else { return self} let offset = ( count - rotation%count ) % count return Array(self[offset..<count] + self[0..<offset]) } 
          \$\endgroup\$

            Start asking to get answers

            Find the answer to your question by asking.

            Ask question

            Explore related questions

            See similar questions with these tags.