Posts Tagged ‘rotate’

Programming Praxis – Upside Up

May 27, 2011

In today’s Programming Praxis exercise, our task is to write a function to determine if a number remains the same if it is rotated 180 degrees. Let’s get started, shall we?

The function is pretty simple: reverse the number, and for each digit check if it the rotation of the corresponding digit in the original number. If a non-reversible digit is encountered, we can return false immediately. An optimization that could be made is to only check half of the number (rounding up), but in this case speed is not an issue so I opted for cleaner code.

upsideUp :: Show a => a -> Bool
upsideUp n = and . zipWith isRot (show n) . reverse $ show n where
    isRot a b = maybe False (== b) . lookup a $ zip "01689" "01986"

Two checks to see if everything is working properly:

main :: IO ()
main = do print $ head (filter upsideUp [1962..]) == 6009
          print $ length (filter upsideUp [0..9999]) == 39

Programming Praxis – Rotate An Array

October 12, 2010

In today’s Programming Praxis exercise, our goal is to write a function to rotate an array a selected number of places. Let’s get started, shall we?

While the assignment mentions arrays specifically, we’re going to be using plain lists, for the following reasons:

1. In Haskell lists are a far more common data structure than arrays.
2. The algorithm used in the Scheme solution is O(n) anyway, so it doesn’t matter all that much in terms of performance.
3. This way we can show off an alternative method, which is more fun than just implementing the provided algorithm in another language.

Instead of the triple reversing approach, we use a more straightforward method: what we effectively do when rotating a list is splitting it into a left and a right part and exchanging their places. So let’s just do that, making sure to keep the splitting point within the bounds of the list:

rotate :: Int -> [a] -> [a]
rotate _ [] = []
rotate n xs = b ++ a where (a,b) = splitAt (mod n $ length xs) xs

To see if it works, we test all the possible corner cases mentioned in the assignment, including the empty list, which the provided solution fails on (which is another reminder of why you should always consider all possible edge cases). To be honest, so did mine until I wrote ‘all possible edge cases’ and figured I’d better check if that was actually the case 🙂

main :: IO ()
main = do print $ rotate 1 [] == ([] :: [Int])
          print $ rotate 3 [1..3] == [1..3]
          print $ rotate 3 [1..3] == [1..3]
          print $ rotate 2 [1..6] == [3,4,5,6,1,2]
          print $ rotate 8 [1..6] == rotate 2 [1..6]
          print $ rotate (-2) (rotate 2 [1..6]) == [1..6]