I ran across an awesome blog post today titled Programming Problems To Improve Your Language Skills. I never actually wrote anything in Haskell yet, but I thought that solving the Ninety-Nine Lisp Problems was a great way to start. That's the point of this post. There is, however, a goofy Scala snippet that's in order first.

## Scala Snippet

It's a funny thing, logical operators. In php and python, if you want to test that `this`

something is true and `that`

something is true, you'd simply write `if this and that`

.
Very straight forward. Those of us coming from C understand that `&&`

and `||`

represent
`and`

and `or`

respectively. I never actually questioned it... that's just the way it was.

My wife is taking a beginner CSC class at university, and when she saw `&&`

, she simply read
it as *and-and*.

*What's does "and-and" mean, and I never seen those vertical things before...*

A very natural response. In Scala, we can change this!

class BooleanExpression(origin: Boolean) { def and (expr: => Boolean) = origin && expr def or (expr: => Boolean) = origin || expr } implicit def boolean2BooleanX(some: Boolean) = new BooleanExpression(some)

Now your conditional sound very natural:

if (file.exists and something) println("Yeeeeee") val x = 5 if(x > 4 and (x < 10 or x > 100)) println("We got it anyway")

It is important to note that this is less efficient. It is, however, cool.

## Haskell Problems

And here's the first 20 problems, almost. I skipped a couple, but I plan
on going back to it. I tried not to use `Prelude`

with all the pre-defined
list functions, but it still doesn't hurt when the goal is to learn a
language.

-- problem 1 my_last :: [a] -> a my_last (x:[]) = x my_last (x:xs) = my_last xs -- problem 2 my_but_last :: [a] -> [a] my_but_last (x:y:[]) = [x, y] my_but_last (x:rest) = my_but_last rest -- problem 3 element_at :: [a] -> Int -> a element_at xs i = head [y | (x, y) <- zip [0..] xs, x == i] -- problem 4 count :: [a] -> Int count xs = foldl (\acc x -> acc + 1) 0 xs -- problem 5 rev :: [a] -> [a] rev [] = [] rev (x:xs) = rev xs ++ [x] -- problem 6 palindrome :: (Eq a) => [a] -> Bool palindrome xs = if(rev xs == xs) then True else False -- problem 7 -- problem 8 compress :: (Eq a) => [a] -> [a] compress [] = [] compress (x:xs) = [x] ++ compress(dropWhile(== x) xs) -- problem 9 pack :: (Eq a) => [a] -> [[a]] pack [] = [] pack (x:xs) = [[x] ++ takeWhile (== x) xs] ++ pack(dropWhile(== x) xs) -- problem 10 encode :: (Eq a) => [a] -> [(Int,a)] encode xs = [(count ls, head ls) | ls <- pack xs] -- problem 11 -- problem 12 decode :: (Eq a) => [(Int, a)] -> [a] decode xs = concat . map (\el -> let (times, i) = el in repl i times) xs -- problem 13 -- problem 14 dupe :: [a] -> [a] dupe [] = [] dupe (x:xs) = x : x : dupe xs -- problem 15 repl :: [a] -> Int -> [a] repl [] _ = [] repl (x:xs) n = map (\_ -> x) [1..n] ++ repl xs n -- problem 16 dropr :: [a] -> Int ->[a] dropr xs i | count xs < i = xs | otherwise = let (headr, (_:rest)) = splitAt (i - 1) xs in headr ++ dropr rest i -- problem 17 split :: [a] -> Int -> ([a], [a]) split xs n | n == 0 = ([], xs) | count xs < n = (xs, []) | otherwise = (take n xs, drop n xs) -- problem 18 slice :: [a] -> Int -> Int -> [a] slice xs from to | from == 1 && to == count xs = xs | from > to = [] | otherwise = [x | (index, x) <- zip [1..] xs, index >= from && index <= to] -- problem 19 rotate :: [a] -> Int -> [a] rotate xs n = let index = if n < 0 then count xs + n else n (first, second) = split xs index in second ++ first -- problem 20 remove :: [a] -> Int -> [a] remove xs n = [x | (i, x) <- zip [1..] xs, i /= n]

## No comments:

## Post a Comment