diff --git a/projects/aoc/src/year2021/Day4.hx b/projects/aoc/src/year2021/Day4.hx index 804f905d..a8bff528 100644 --- a/projects/aoc/src/year2021/Day4.hx +++ b/projects/aoc/src/year2021/Day4.hx @@ -4,11 +4,12 @@ import haxe.ds.Option; typedef Board = { uncalled:Array>>, - called:Array>> + called:Array>>, + won:Bool }; typedef GameState = { numbersToCall:Array, boards:Array, - boardsByNumber:Map> + boardsByNumber:Map>, }; diff --git a/projects/aoc/src/year2021/Solutions2021.kiss b/projects/aoc/src/year2021/Solutions2021.kiss index 01c514b7..719ca2d3 100644 --- a/projects/aoc/src/year2021/Solutions2021.kiss +++ b/projects/aoc/src/year2021/Solutions2021.kiss @@ -17,7 +17,9 @@ (day 4 (load "day4.kiss") (assert (= 4512 (winningScore "src/year2021/inputs/day4-example.txt"))) - (assert (= 46920 (winningScore "src/year2021/inputs/day4.txt")))) + (assert (= 46920 (winningScore "src/year2021/inputs/day4.txt"))) + (assert (= 1924 (lastWinningScore "src/year2021/inputs/day4-example.txt"))) + (assert (= 12635 (lastWinningScore "src/year2021/inputs/day4.txt")))) (dayTodo 5) (day 6 (load "day6.kiss") diff --git a/projects/aoc/src/year2021/day4.kiss b/projects/aoc/src/year2021/day4.kiss index f007530a..5b0e6482 100644 --- a/projects/aoc/src/year2021/day4.kiss +++ b/projects/aoc/src/year2021/day4.kiss @@ -8,7 +8,8 @@ (let [numbers (map (apply concat (for line group (filter (line.split " ")))) Std.parseInt) board (object uncalled (for line (groups numbers 5) (for number line (Some number))) - called (for y (range 5) (for x (range 5) None)))] + called (for y (range 5) (for x (range 5) None)) + won false)] (doFor number numbers (unless (boardsByNumber.exists number) (dictSet boardsByNumber number [])) (.push (dictGet boardsByNumber number) board)) @@ -39,14 +40,18 @@ (when won (return true)))) (return false))) -// Return the winning score when a board wins -(function :Null stepState [:GameState state] - (let [numberCalled (state.numbersToCall.shift)] +// Return the winning score(s) when a board(s) win +(function :Null> stepState [:GameState state] + // Keep returning the last score if there are no more numbers to call + (let [numberCalled (state.numbersToCall.shift) + winningScores []] (when (state.boardsByNumber.exists numberCalled) (doFor board (dictGet state.boardsByNumber numberCalled) - (when (stepBoard board numberCalled) - (return (boardScore board numberCalled))))) - null)) + (unless board.won + (when (stepBoard board numberCalled) + (set board.won true) + (winningScores.push (boardScore board numberCalled)))))) + winningScores)) (function :Int boardScore [:Board board numberCalled] (* numberCalled (apply + (for row board.uncalled (apply + (for square row (case square ((Some v) v) (otherwise 0)))))))) @@ -54,6 +59,17 @@ (function winningScore [file] (let [state (readState file)] (loop - (whenLet [winningScore (stepState state)] - (return winningScore)))) + // Assume that for potential solutions to the AOC problem, only one board wins at a time. + (whenLet [[score] (stepState state)] + (return score)))) + (throw "")) + +(function lastWinningScore [file] + (let [state (readState file) + &mut finishedBoards 0] + (loop + (whenLet [winningScores (stepState state)] + (+= finishedBoards winningScores.length) + (when (= finishedBoards state.boards.length) + (return (first winningScores)))))) (throw "")) \ No newline at end of file diff --git a/projects/aoc/src/year2021/day6.kiss b/projects/aoc/src/year2021/day6.kiss index 9d165ff1..14d581c1 100644 --- a/projects/aoc/src/year2021/day6.kiss +++ b/projects/aoc/src/year2021/day6.kiss @@ -24,7 +24,7 @@ (dictSet newMap -1 (dictGet theMap -1)) (doFor age (range 9) (let [count (dictGet theMap age)] - (case ~age + (case age // Lanternfish giving birth: (0 (dictInc newMap 8 count)