1HaskellADay

As of March 2020, School of Haskell has been switched to read-only mode.

This page contains solutions to #1HaskellADay puzzles. It doesn't contain all solutions and it certainly doesn't contain best solutions (whatever it might mean). Solutions to puzzles are ordered by date, descending, and are hidden by default.

May 14th, 2014

Puzzle

{- Find the previous element of a look-and-say sequence element if it exists
   Look and say is defined here: https://en.wikipedia.org/wiki/Look-and-say_sequence

   Example:

   >>> lookAndSayPrec [4,1,3,7]
   Just [1,1,1,1,7,7,7]

   >>> lookAndSayPrec []
   Nothing

-}
lookAndSayPrec :: [Int] -> Maybe [Int]
lookAndSayPrec = undefined

Solution

April 18th, 2014

Puzzle

{- | combinations 
   Builds all the combinations of length n of the elements of the initial list.

   Examples:

   >>> combinations 2 [0,1]
   [[0,0],[0,1],[1,0],[1,1]]

   >>> combinations 3 ['a','b']
   ["aaa","aab","aba","abb","baa","bab","bba","bbb"]
   
   >>> combinations (-2) ['a'..'z']
   [""]
-}
combinations :: Int -> [a] -> [[a]]
combinations = undefined

Solution

For point-free solution, I found tremendous help here.

April 15th, 2014

Puzzle

{- | lowestFreeInt
   Find the lowest non-negative integer not in the list

   (Thanks to @clementd for this one)

   Example:

   >>> lowestFreeInt [0..10]
   11

   >>> lowestFreeInt [1..10]
   0

   >>> lowestFreeInt $ [0..9] ++ [2000,1999..11]
   10
-}
lowestFreeInt :: [Int] -> Int
lowestFreeInt = undefined

Solution

April 8th, 2014

Puzzle

module HAD.Y2014.M04.D08.Exercise where

{- | replicateF
   replicate and chain an endofunction

   Examples:

   prop> x + 10 == replicateF 10 (+1) x

   prop> 10 * x == replicateF 10 (+x) 0

   prop> replicate 10 x == replicateF 10 (x:) []
-}
replicateF :: Int -> (a -> a) -> a -> a
replicateF = undefined

Solution

April 4th, 2014

Puzzle

module HAD.Y2014.M04.D04.Exercise where

-- | countFigures count the different figures that composes a number
--
-- Examples:
--
-- >>> countFigures 1
-- 1
-- >>> countFigures 1000000
-- 2
-- >>> countFigures 123
-- 3
-- >>> countFigures (-12)
-- 2
-- >>> countFigures 1234567890
-- 10
-- >>> countFigures 00001
-- 1
-- >>> countFigures 0
-- 1
--
countFigures :: Integral a => a -> Int
countFigures = undefined

Solution

April 3rd, 2014

Puzzle

module HAD.Y2014.M04.D03.Exercise where

-- | foo
-- Types. Powerful enough to get it right.
--
foo :: (a ->  b) -> [a] -> [(a,b)]
foo = undefined

Solution

April 2nd, 2014

Puzzle

module HAD.Y2014.M04.D02.Exercise where

-- | update update the nth element of a list
-- if the index is not a valid index, it leaves the list unchanged
--
-- Examples
--
-- >>> update (-2) 10 [0..4]
-- [0,1,2,3,4]
--
-- >>> update 6 10 [0..4]
-- [0,1,2,3,4]
--
-- >>> update 2 10 [0..4]
-- [0,1,10,3,4]
--
update :: Int -> a -> [a] -> [a]
update = undefined

Solution

March 31st, 2014

Puzzle

module HAD.Y2014.M02.D31.Exercise where

-- $setup
-- >>> import Control.Applicative

-- | emptyIndices List the indices of a list of maybes that contains Nothing
--
-- prop> (all (isNothing) .) . map . (!!) <*> emptyIndices $ xs
--
emptyIndices :: [Maybe a] -> [Int]
emptyIndices = undefined

Solution

March 24th, 2014

Puzzle

module HAD.Y2014.M03.D24.Exercise where

-- | squareList builds a list of x lists of size x from a given list of elements
-- If there aren't enough elements, fill the square with the second parameter
-- Examples:
--
-- >>> squareList 2  0 [0..]
-- [[0,1],[2,3]]
--
-- >>> squareList 2 0 [1]
-- [[1,0],[0,0]]
--
-- >>> squareList 3 () $ repeat ()
-- [[(),(),()],[(),(),()],[(),(),()]]
--
squareList :: Int -> a -> [a] -> [[a]] 
squareList = undefined

Solution

March 19th, 2014

Puzzle

-- $setup
-- >>> import Control.Applicative ((<*>))
-- >>> import Data.List (isInfixOf)
-- >>> import Test.QuickCheck

-- Level: Easy
-- Pointfree: yes


-- | mostRepeatedElem
-- Returns the element with the longest (consecutive) repetition and the
-- repetition number
-- If there are tie, the last most repeated element is returned
-- It returns error on empty string
-- 
-- Examples:
--
-- >>> mostRepeatedElem "hello world!"
-- ('l',2)
--
-- >>> mostRepeatedElem [1,1,2,2]
-- (2,2)
--
-- prop> (flip isInfixOf <*> uncurry (flip replicate) . mostRepeatedElem) . getNonEmpty

mostRepeatedElem :: Eq a => [a] -> (a,Int)
mostRepeatedElem = undefined

Solution

March 17th, 2014

Puzzle

-- | maximumList replace each element in a list by its maximum so far
-- 
-- Examples:
--
-- >>> maximumList [1..4]
-- [1,2,3,4]
--
-- >>> maximumList [10,9..7]
-- [10,10,10,10]
--
-- prop> and . (zipWith (<=) <*> tail) . maximumList

-- maximumList :: Find a general signature
maximumList = undefined

Solution

A common sense solution:

March 13th, 2014

Puzzle

-- | pairToList Transform a pair of same type elements in a list of two
-- elements.
--
-- Of course, the major challenge is to find a point free function
-- (without lambda). And, if you want more fun, do it without (++).
--
-- prop> replicate 2 (x :: Int) == pairToList (x,x)
--
-- prop> (\(f,s) -> [f,s]) x == pairToList x
--
pairToList :: (a,a) -> [a]
pairToList = undefined

Solution

Couldn't really come up with a point-free solution, although it seemed like it won't be hard.

March 12th, 2014

Puzzle

-- | localMax Given an entry list, it outputs the its list of local maxima.
-- A Local maximum is a an element greater than its predecessor and than its
-- successor.
--
-- No point-free today, at least for my solution.
--
-- Examples:
--
-- >>> localMax [0 .. 1000]
-- []
--
-- >>> localMax [1000 .. 0]
-- []
--
-- >>> localMax [2,2,1,5,4]
-- [5]
--
-- >>> take 4 . localMax $ [0..] >>= (\y -> [y,y+2])
-- [2,3,4,5]
--
localMax :: Ord a => [a] -> [a]
localMax = undefined

main = print $ localMax [2,2,1,5,4] -- [5]

Solution

March 11th, 2014

Puzzle

-- | lcAlphabetFrom
-- Display the alaphabet in lower cas, starting from the letter given in
-- parameter.
-- If the parameter is not a lowercase letter, displays the alphabet from 'a'
--
-- Point-free is quite easy
--
-- Examples:
--
-- >>> lcAlphabetFrom 'a'
-- "abcdefghijklmnopqrstuvwxyz"
--
-- >>> lcAlphabetFrom 'e'
-- "efghijklmnopqrstuvwxyzabcd"
--
-- >>> lcAlphabetFrom '`'
-- "abcdefghijklmnopqrstuvwxyz"
--
-- >>> lcAlphabetFrom '{'
-- "abcdefghijklmnopqrstuvwxyz"

lcAlphabetFrom :: Char -> String
lcAlphabetFrom = undefined

main = do
  print $ lcAlphabetFrom 'a' -- "abcdefghijklmnopqrstuvwxyz"
  print $ lcAlphabetFrom 'e' -- "efghijklmnopqrstuvwxyzabcd"
  print $ lcAlphabetFrom '`' -- "abcdefghijklmnopqrstuvwxyz"
  print $ lcAlphabetFrom '{' -- "abcdefghijklmnopqrstuvwxyz"

Solution

March 10th, 2014

Puzzle

-- $setup
-- >>> import Test.QuickCheck
-- >>> import Control.Applicative

-- | maybeReadPositiveInt Try to parse a positive Int
-- Can be done point-free (and it's probably funnier this way).
--
-- Examples:
--
-- prop> (==) <$> Just <*> maybeReadPositiveInt . show $ getNonNegative x
--
-- prop> Nothing == (maybeReadPositiveInt . show . negate . getPositive $ x)
--
-- >>> maybeReadPositiveInt "foo"
-- Nothing
--
-- >>> maybeReadPositiveInt "12 "
-- Nothing


maybeReadPositiveInt :: String -> Maybe Int
maybeReadPositiveInt = undefined

main = do
  print $ maybeReadPositiveInt "12" -- Just 12
  print $ maybeReadPositiveInt "-12" -- Nothing
  print $ maybeReadPositiveInt "12 a" -- Nothing
  print $ maybeReadPositiveInt "12 " -- Nothing

Solution

March 7th, 2014

Puzzle

-- | trueIndexes produce an infinite list where only the index given in the list

-- in parameter are true.
-- The parameter list is supposed to be sorted set of positive numbers
--
-- Point-free: Probably hard to find!
-- Level: HARD
--
-- Examples:
-- >>> take 2 $ trueIndexes [1]
-- [False,True]
--
-- >>> take 6 $ trueIndexes [0,2,4]
-- [True,False,True,False,True,False]
--
-- >>> take 3 $ trueIndexes []
-- [False, False, False]
--
trueIndexes :: [Int] -> [Bool]
trueIndexes = undefined

main = print $ take 6 $ trueIndexes [0,2,4]

Solution