cleaning + added tests and missing days in main

This commit is contained in:
Yann Esposito (Yogsototh) 2017-12-13 20:19:51 +01:00
parent ffe0f250d6
commit ea35b588f8
Signed by untrusted user who does not match committer: yogsototh
GPG key ID: 7B19A4C650D59646
8 changed files with 217 additions and 82 deletions

View file

@ -7,3 +7,4 @@

View file

@ -2,7 +2,7 @@
-- --
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
-- --
-- hash: 454d3692225cbc9c59993888515dbf7f9c46a2d886ffebc91072c08157888c4d -- hash: ece24a6f206c14c1251a73fcaadfb901287003b3dc6bb86e59bb0df886d7d33d
name: adventofcode name: adventofcode
version: 0.1.0.0 version: 0.1.0.0
@ -79,6 +79,7 @@ test-suite adventofcode-test
HUnit HUnit
, adventofcode , adventofcode
, base , base
, protolude
, tasty , tasty
, tasty-hunit , tasty-hunit
other-modules: other-modules:

View file

@ -10,6 +10,8 @@ import qualified Data.Map as Map
import qualified Day01 import qualified Day01
import qualified Day02 import qualified Day02
import qualified Day03
import qualified Day04
import qualified Day05 import qualified Day05
import qualified Day06 import qualified Day06
import qualified Day07 import qualified Day07
@ -34,6 +36,8 @@ main = do
solutions :: Map [[Char]] (IO ()) solutions :: Map [[Char]] (IO ())
solutions = Map.fromList [(["01"], day01) solutions = Map.fromList [(["01"], day01)
,(["02"], day02) ,(["02"], day02)
,(["03"], day03)
,(["04"], day04)
,(["05"], day05) ,(["05"], day05)
,(["06"], day06) ,(["06"], day06)
,(["07"], day07) ,(["07"], day07)
@ -45,6 +49,12 @@ solutions = Map.fromList [(["01"], day01)
,(["13"], day13) ,(["13"], day13)
] ]
-- | Show ZERO in case of failure
mint = int . fromMaybe 0
-- | Show ZERO in case of failure
minteger = integer . fromMaybe 0
day01 :: IO () day01 :: IO ()
day01 = do day01 = do
putText "Day 01:" putText "Day 01:"
@ -61,6 +71,21 @@ day02 = do
let sol2 = maybe 0 Day02.solution2 input let sol2 = maybe 0 Day02.solution2 input
showSol "Solution 2" (integer sol2) showSol "Solution 2" (integer sol2)
day03 :: IO ()
day03 = do
putText "Day 03:"
showSol "Solution 1" (minteger (Day03.solution1 Day03.input))
showSol "Solution 2" (minteger (Day03.solution2 (fromIntegral Day03.input)))
day04 :: IO ()
day04 = do
putText "Day 04:"
input <- Day04.parseInput
let sol1 = Day04.solution1 input
showSol "Solution 1" (int sol1)
let sol2 = Day04.solution2 input
showSol "Solution 2" (int sol2)
day05 :: IO () day05 :: IO ()
day05 = do day05 = do
putText "Day 05:" putText "Day 05:"
@ -99,9 +124,10 @@ day08 = do
day09 :: IO () day09 :: IO ()
day09 = do day09 = do
putText "Day 09:" putText "Day 09:"
sol1 <- Day09.solution1 input <- Day09.parseInput
let sol1 = Day09.solution1 input
showSol "Solution 1" (int sol1) showSol "Solution 1" (int sol1)
sol2 <- Day09.solution2 let sol2 = Day09.solution2 input
showSol "Solution 2" (int sol2) showSol "Solution 2" (int sol2)
day10 :: IO () day10 :: IO ()

View file

@ -59,6 +59,7 @@ tests:
- -rtsopts - -rtsopts
- -with-rtsopts=-N - -with-rtsopts=-N
dependencies: dependencies:
- protolude
- base - base
- adventofcode - adventofcode
- tasty - tasty

View file

@ -57,6 +57,7 @@ import qualified Control.Foldl as F
import Data.List (words,lines) import Data.List (words,lines)
import qualified Data.Map as Map import qualified Data.Map as Map
input :: Int
input = 265149 input = 265149
@ -78,11 +79,14 @@ block1 = [ (2,1,0)
] ]
spiral = (1,0,0):concatMap (\n -> blocks (n+1) ((n+1)^2,n `div` 2,- (n `div` 2))) [0,2..] spiral = (1,0,0):concatMap (\n -> blocks (n+1) ((n+1)^2,n `div` 2,- (n `div` 2))) [0,2..]
returnPathLength :: Int -> Maybe Integer
returnPathLength i = returnPathLength i =
drop (i - 1) spiral drop (i - 1) spiral
& head & head
& fmap (\(_,x,y) -> abs x + abs y) & fmap (\(_,x,y) -> abs x + abs y)
solution1 :: Int -> Maybe Integer
solution1 = returnPathLength
-- Solution 2 -- Solution 2
@ -95,7 +99,7 @@ spiralDebug = go Map.empty (0,0)
in (val,nextcoord,neigh):go nextspiral nextcoord in (val,nextcoord,neigh):go nextspiral nextcoord
spiral2 = map (\(x,_,_) -> x) spiralDebug spiral2 = map (\(x,_,_) -> x) spiralDebug
solution2 = head $ dropWhile (< 265149) spiral2 solution2 input = head $ dropWhile (< input) spiral2
neighbor :: Spiral -> (Int,Int) -> [Maybe Integer] neighbor :: Spiral -> (Int,Int) -> [Maybe Integer]
neighbor spiral (x,y) = neighbor spiral (x,y) =

View file

@ -40,9 +40,10 @@ import Protolude
import qualified Data.Text as Text import qualified Data.Text as Text
parseInput :: IO [[Text]] parseInput :: IO [[Text]]
parseInput = do parseInput = parseTxt <$> readFile "inputs/day4.txt"
inputTxt <- readFile "inputs/day4.txt"
return $ inputTxt & Text.lines & map Text.words parseTxt :: Text -> [[Text]]
parseTxt txt = txt & Text.lines & map Text.words
allUniq :: Eq a => [a] -> Bool allUniq :: Eq a => [a] -> Bool
allUniq [] = True allUniq [] = True

View file

@ -84,15 +84,16 @@ How many non-canceled characters are within the garbage in your puzzle input?
|-} |-}
module Day09 where module Day09 where
import Protolude hiding ((<|>),many) import Protolude hiding ((<|>))
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Text.Parsec import Text.Parsec
solution1 :: IO Int parseInput :: IO Text
solution1 = do parseInput = readFile "inputs/day9.txt"
str <- readFile "inputs/day9.txt"
return $ either (const 0) identity (parseGroups str) solution1 :: Text -> Int
solution1 str = either (const 0) identity (parseGroups str)
parseGroups :: Text -> Either ParseError Int parseGroups :: Text -> Either ParseError Int
parseGroups = runParser groups (0,0) "Groups 1" parseGroups = runParser groups (0,0) "Groups 1"
@ -101,7 +102,7 @@ groups :: Parsec Text (Int,Int) Int
groups = do groups = do
c <- char '{' c <- char '{'
updateState (\(d,s) -> (d+1,s+d+1)) updateState (\(d,s) -> (d+1,s+d+1))
(groups <|> garbage) `sepBy` (char ',') (groups <|> garbage) `sepBy` char ','
c <- char '}' c <- char '}'
updateState (\(d,s) -> (d-1,s)) updateState (\(d,s) -> (d-1,s))
fmap snd getState fmap snd getState
@ -119,11 +120,8 @@ garbage = do
'!' -> anyChar >> endGarbage '!' -> anyChar >> endGarbage
_ -> endGarbage _ -> endGarbage
solution2 :: Text -> Int
solution2 :: IO Int solution2 txt = either (const 0) identity (parseGroups2 txt)
solution2 = do
str <- readFile "inputs/day9.txt"
return $ either (const 0) identity (parseGroups2 str)
parseGroups2 :: Text -> Either ParseError Int parseGroups2 :: Text -> Either ParseError Int
parseGroups2 = runParser groups2 0 "Groups 2" parseGroups2 = runParser groups2 0 "Groups 2"

View file

@ -1,4 +1,5 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
import Protolude
import Test.Tasty import Test.Tasty
import Test.Tasty.HUnit import Test.Tasty.HUnit
@ -6,10 +7,13 @@ import Control.Monad (when)
import qualified Day01 import qualified Day01
import qualified Day02 import qualified Day02
import qualified Day03
import qualified Day04
import qualified Day05 import qualified Day05
import qualified Day06 import qualified Day06
import qualified Day07 import qualified Day07
import qualified Day08 import qualified Day08
import qualified Day09
import qualified Day10 import qualified Day10
import qualified Day11 import qualified Day11
import qualified Day12 import qualified Day12
@ -18,7 +22,41 @@ import qualified Day13
main :: IO () main :: IO ()
main = defaultMain $ main = defaultMain $
testGroup "Advent Of Code 2017" testGroup "Advent Of Code 2017"
[ [ testDay01
, testDay02
, testDay03
, testDay04
, testDay05
, testDay06
, testDay07
, testDay08
, testDay09
, testDay10
, testGroup "Day 12"
[ testGroup "Solution 1"
[ testCase "Example" $
fmap Day12.solution1 (Day12.parseTxt Day12.testTxt) @?= Just 6
]
, testGroup "Solution 2"
[ testCase "Example" $
fmap Day12.solution2 (Day12.parseTxt Day12.testTxt) @?= Just 2
]
]
, testGroup "Day 13"
[ testGroup "Solution 1"
[ testCase "Example" $
(Day13.solution1 . Day13.mkAppState)
<$> Day13.parseTxt Day13.testInput
@?= Just 24
]
, testGroup "Solution 2"
[ testCase "Example" $
fmap Day13.solution2 (Day13.parseTxt Day13.testInput) @?= Just 10
]
]
]
testDay01 =
testGroup "Day 1" testGroup "Day 1"
[ testGroup "solution 1" [ testGroup "solution 1"
[ testCase "1122 is 3" $ Day01.solution1 "1122" @?= 3 [ testCase "1122 is 3" $ Day01.solution1 "1122" @?= 3
@ -34,27 +72,73 @@ main = defaultMain $
, testCase "12131415 is 4" $ Day01.solution2 "12131415" @?= 4 , testCase "12131415 is 4" $ Day01.solution2 "12131415" @?= 4
] ]
] ]
, testGroup "Day 2"
[ testCase "example problem 1" $ testDay02 =
Day02.solution1 [[5,1,9,5],[7,5,3],[2,4,6,8]] @?= 18 testGroup "Day 2"
, testCase "example problem 2" $ [ testCase "example problem 1" $
Day02.solution2 [[5,9,2,8],[9,4,7,3],[3,8,6,5]] @?= 9 Day02.solution1 [[5,1,9,5],[7,5,3],[2,4,6,8]] @?= 18
, testCase "example problem 2" $
Day02.solution2 [[5,9,2,8],[9,4,7,3],[3,8,6,5]] @?= 9
]
testDay03 =
testGroup "Day 3"
[ testGroup "Solution 1"
[ testCase "1" $ Day03.returnPathLength 1 @?= Just 0
, testCase "12" $ Day03.returnPathLength 12 @?= Just 3
, testCase "23" $ Day03.returnPathLength 23 @?= Just 2
, testCase "1024" $ Day03.returnPathLength 1024 @?= Just 31
] ]
, testGroup "Day 5" , testGroup "Solution 2"
[ testCaseSteps "example problem 1" $ \step -> do [ testCase "2" $ Day03.solution2 2 @?= Just 2
step "Loading input" , testCase "3" $ Day03.solution2 3 @?= Just 4
input <- Day05.testArray , testCase "4" $ Day03.solution2 4 @?= Just 4
step "Running solution 1" , testCase "6" $ Day03.solution2 6 @?= Just 10
sol1 <- Day05.solution1 input , testCase "747" $ Day03.solution2 747 @?= Just 747
when (sol1 /= 5) (assertFailure "Should be 5 steps") , testCase "748" $ Day03.solution2 748 @?= Just 806
, testCaseSteps "example problem 2" $ \step -> do , testCase "800" $ Day03.solution2 800 @?= Just 806
step "Loading input" , testCase "805" $ Day03.solution2 805 @?= Just 806
input <- Day05.testArray , testCase "806" $ Day03.solution2 806 @?= Just 806
step "Running solution 2"
sol2 <- Day05.solution2 input
when (sol2 /= 10) (assertFailure "Day 6 solution 2 on the example should be 4")
] ]
, testGroup "Day 6" ]
testDay04 =
testGroup "Day 4"
[ testGroup "Solution 1"
[ testCase "1" $ Day04.solution1 (Day04.parseTxt testTxt) @?= 2 ]
, testGroup "Solution 2"
[ testCase "2" $ Day04.solution2 (Day04.parseTxt testTxt2) @?= 3 ]
]
where
testTxt = "aa bb cc dd ee\n\
\aa bb cc dd aa\n\
\aa bb cc dd aaa\n"
testTxt2 = "abcde fghij\n\
\abcde xyz ecdab\n\
\a ab abc abd abf abj\n\
\iiii oiii ooii oooi oooo\n\
\oiii ioii iioi iiio\n"
testDay05 =
testGroup "Day 5"
[ testCaseSteps "example problem 1" $ \step -> do
step "Loading input"
input <- Day05.testArray
step "Running solution 1"
sol1 <- Day05.solution1 input
when (sol1 /= 5)
(assertFailure "Should be 5 steps")
, testCaseSteps "example problem 2" $ \step -> do
step "Loading input"
input <- Day05.testArray
step "Running solution 2"
sol2 <- Day05.solution2 input
when (sol2 /= 10)
(assertFailure "Day 6 solution 2 on the example should be 4")
]
testDay06 =
testGroup "Day 6"
[ testCaseSteps "example problem 1" $ \step -> do [ testCaseSteps "example problem 1" $ \step -> do
step "Loading input" step "Loading input"
input <- Day06.testArray input <- Day06.testArray
@ -68,7 +152,9 @@ main = defaultMain $
sol2 <- Day06.solution2 input sol2 <- Day06.solution2 input
when (sol2 /= 4) (assertFailure "Day 6 solution 2 on the example should be 4") when (sol2 /= 4) (assertFailure "Day 6 solution 2 on the example should be 4")
] ]
, testGroup "Day 7"
testDay07 =
testGroup "Day 7"
[ testCaseSteps "example problem 1" $ \step -> do [ testCaseSteps "example problem 1" $ \step -> do
step "Running solution 1" step "Running solution 1"
let input = Day07.testNodes let input = Day07.testNodes
@ -77,56 +163,73 @@ main = defaultMain $
, testCase "example on solution 2" $ , testCase "example on solution 2" $
maybe 0 snd (Day07.solution2 Day07.testNodes) @?= 60 maybe 0 snd (Day07.solution2 Day07.testNodes) @?= 60
] ]
, testGroup "Day 8"
testDay08 =
testGroup "Day 8"
[ testCase "example problem 1" $ [ testCase "example problem 1" $
Day08.solution1 Day08.testInstructions @?= 1 Day08.solution1 Day08.testInstructions @?= 1
, testCase "example problem 1" $ , testCase "example problem 1" $
Day08.solution2 Day08.testInstructions @?= 10 Day08.solution2 Day08.testInstructions @?= 10
] ]
, testGroup "Day 10"
[ testCase "example 1" $ testDay09 =
Day10.solution1 Day10.testInput @?= 12 testGroup "Day 9"
, testCase "solution 2 empty" $ [ testGroup "Solution 1"
Day10.solution2 "" @?= "a2582a3a0e66e6e86e3812dcb672a272" [ check1 "{}" 1
, testCase "solution 2 AoC 2017" $ , check1 "{{{}}}" 6
Day10.solution2 "AoC 2017" @?= "33efeb34ea91902bb2f59c9920caa6cd" , check1 "{{},{}}" 5
, testCase "solution 2 1,2,3" $ , check1 "{{{},{},{{}}}}" 16
Day10.solution2 "1,2,3" @?= "3efbe78a8d82f29979031a4aa0b16a9d" , check1 "{<a>,<a>,<a>,<a>}" 1
, testCase "solution 2 1,2,4" $ , check1 "{{<ab>},{<ab>},{<ab>},{<ab>}}" 9
Day10.solution2 "1,2,4" @?= "63960835bcdc130f0b66d7ff4f6a5a8e" , check1 "{{<!!>},{<!!>},{<!!>},{<!!>}}" 9
, check1 "{{<a!>},{<a!>},{<a!>},{<ab>}}" 3
] ]
, testGroup "Day 11" , testGroup "Solution 2"
[ testGroup "Solution 1" [ check2 "<>" 0
[ testCase "Example 1" $ , check2 "<random characters>" 17
Day11.solution1 (Day11.parseTxt "ne,ne,ne") @?= 3 , check2 "<<<<>" 3
, testCase "Example 2" $ , check2 "<{!>}>" 2
Day11.solution1 (Day11.parseTxt "ne,ne,sw,sw") @?= 0 , check2 "<!!>" 0
, testCase "Example 3" $ , check2 "<!!!>>" 0
Day11.solution1 (Day11.parseTxt "ne,ne,s,s") @?= 2 , check2 "<{o\"i!a,<{i<a>" 10
, testCase "Example 4" $
Day11.solution1 (Day11.parseTxt "se,sw,se,sw,sw") @?= 3
]
] ]
, testGroup "Day 12" ]
[ testGroup "Solution 1" where
[ testCase "Example" $ check1 txt v = testCase (toS txt) (Day09.solution1 txt @?= v)
fmap Day12.solution1 (Day12.parseTxt Day12.testTxt) @?= Just 6 check2 txt v = testCase (toS txt) (Day09.solution2 ("{" <> txt <> "}") @?= v)
]
, testGroup "Solution 2" testDay10 =
[ testCase "Example" $ testGroup "Day 10"
fmap Day12.solution2 (Day12.parseTxt Day12.testTxt) @?= Just 2 [ testGroup "Solution 1"
[ testCase "example 1" $ Day10.solution1 Day10.testInput @?= 12 ]
, testGroup "Solution 2"
[check2 "" "a2582a3a0e66e6e86e3812dcb672a272"
, check2 "AoC 2017" "33efeb34ea91902bb2f59c9920caa6cd"
, check2 "1,2,3" "3efbe78a8d82f29979031a4aa0b16a9d"
, check2 "1,2,4" "63960835bcdc130f0b66d7ff4f6a5a8e"
]
]
where
check2 txt v = testCase (toS ("\"" <> txt <> "\""))
(Day10.solution2 txt @?= v)
testDay11 =
testGroup "Day 11"
[ testGroup "Solution 1"
[ check1 "ne,ne,ne" 3
, check1 "ne,ne,sw,sw" 0
, check1 "ne,ne,s,s" 2
, check1 "se,sw,se,sw,sw" 3
] ]
, testGroup "Solution 2"
[ check2 "ne,ne,ne" 3
, check2 "ne,ne,sw,sw" 2
, check2 "ne,ne,s,s" 2
, check2 "se,sw,se,sw,sw" 3
] ]
, testGroup "Day 13"
[ testGroup "Solution 1"
[ testCase "Example" $
fmap Day13.solution1
(fmap Day13.mkAppState
(Day13.parseTxt Day13.testInput)) @?= Just 24
]
, testGroup "Solution 2"
[ testCase "Example" $
fmap Day13.solution2 (Day13.parseTxt Day13.testInput) @?= Just 10
]
] ]
] where
check1 txt v = testCase (toS txt)
(Day11.solution1 (Day11.parseTxt txt) @?= v)
check2 txt v = testCase (toS txt)
(Day11.solution2 (Day11.parseTxt txt) @?= v)