summary refs log tree commit diff
path: root/src/Day2.idr
blob: c3b26aa47b9406448b472b0400280c7b77137d88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
module Day2

import Data.String


parseRow : String -> List Int
parseRow str = do
  num <- words str
  maybe [] pure (parseInteger num)

parseInp : String -> List (List Int)
parseInp inp = do
  numrow <- lines inp
  pure $ parseRow numrow
  
isSafe : List Int -> Bool
isSafe [] = False
isSafe (x :: xs) = fst up || fst down where
  up   = foldl (\(b, y) => \n => (b && y - n <= 3 && y - n > 0, n)) (True, x) xs
  down = foldl (\(b, y) => \n => (b && n - y <= 3 && n - y > 0, n)) (True, x) xs

btoi : Bool -> Int
btoi False = 0
btoi True = 1

part1 : List (List Int) -> Int
part1 iss = sum $ map (btoi . isSafe) iss

export sol1 : String -> String
sol1 = show . part1 . parseInp

upCheck, downCheck : Int -> Int -> Bool
upCheck   i j = i - j <= 3 && i - j > 0
downCheck i j = j - i <= 3 && j - i > 0

safeTerm : (Int -> Int -> Bool) -> (Bool, Bool, Int) -> Int -> (Bool, Bool, Int)
safeTerm f (False, (y, z)) i = (False, y, i)
safeTerm f (True, (False, z)) i = (f z i, False, i)
safeTerm f (True, (True, z)) i = if f z i then (True, True, i) else (True, False, z)

isSafe' : Bool -> List Int -> Bool
isSafe' b [] = False
isSafe' b (x :: []) = True
isSafe' b (x :: (y :: xs)) = isSafe (x :: y :: xs) || (b && isSafe' False (y :: xs)) || (b && isSafe' False (x :: xs))

part2 : List (List Int) -> Int
part2 iss = sum $ map (btoi . isSafe' True) iss

export sol2 : String -> String
sol2 = show . part2 . parseInp

export out : String -> String
out = show . parseInp