2023-12-03 11:29:08 +00:00
|
|
|
#!/usr/bin/env janet
|
|
|
|
(use spork/test)
|
|
|
|
|
|
|
|
(def peg
|
2023-12-03 11:38:22 +00:00
|
|
|
'{:color
|
|
|
|
(+
|
|
|
|
(/ "red" :red)
|
|
|
|
(/ "green" :green)
|
|
|
|
(/ "blue" :blue))
|
2023-12-03 11:29:08 +00:00
|
|
|
:game-num (* "Game " (number :d+) ": ")
|
|
|
|
:color-group (group (* (number :d+) " " :color))
|
2023-12-03 11:38:22 +00:00
|
|
|
:subset (group (* (any (* :color-group ", ")) :color-group))
|
2023-12-03 11:29:08 +00:00
|
|
|
:main (* :game-num (group (* (any (* :subset "; ")) :subset)))})
|
2023-12-03 11:38:22 +00:00
|
|
|
|
2023-12-03 11:29:08 +00:00
|
|
|
(defn pmatch [input] (peg/match peg input))
|
|
|
|
|
2023-12-05 04:38:38 +00:00
|
|
|
(defn subset-pred
|
|
|
|
"Check a predicate against a subset"
|
|
|
|
[subset pred]
|
|
|
|
(all (fn [pair] (pred pair)) subset))
|
2023-12-03 11:29:08 +00:00
|
|
|
|
2023-12-05 04:38:38 +00:00
|
|
|
(defn all-pred
|
|
|
|
"Check if all subsets satisfy a predicate"
|
|
|
|
[subsets pred]
|
|
|
|
(all (fn [subset] (subset-pred subset pred)) subsets))
|
2023-12-03 11:29:08 +00:00
|
|
|
|
2023-12-05 04:59:49 +00:00
|
|
|
(def *die-pool*
|
2023-12-03 11:29:08 +00:00
|
|
|
@{:red 12
|
|
|
|
:green 13
|
|
|
|
:blue 14})
|
|
|
|
|
2023-12-05 04:38:38 +00:00
|
|
|
(defn possible
|
|
|
|
"Check if die fits in the die pool"
|
|
|
|
[pair]
|
|
|
|
(var [count color] pair)
|
2023-12-05 04:59:49 +00:00
|
|
|
(<= count (*die-pool* color)))
|
|
|
|
|
|
|
|
(defn create-pool [init]
|
|
|
|
@{:red init
|
|
|
|
:green init
|
|
|
|
:blue init})
|
|
|
|
|
|
|
|
(defn create-pool-walker
|
|
|
|
"Build up the die pool"
|
|
|
|
[pool]
|
|
|
|
(fn [pair]
|
|
|
|
(var [count color] pair)
|
|
|
|
(set (pool color) (max (pool color) count))))
|
2023-12-05 04:38:38 +00:00
|
|
|
|
|
|
|
(defn all-possible
|
|
|
|
"Check if all fit the pool"
|
|
|
|
[subsets]
|
|
|
|
(all-pred subsets possible))
|
|
|
|
|
2023-12-03 11:29:08 +00:00
|
|
|
(defn solve [lines]
|
2023-12-05 04:59:49 +00:00
|
|
|
(defn calc-power [pool]
|
|
|
|
(* (splice (values pool))))
|
|
|
|
(var power-sum 0)
|
2023-12-03 11:29:08 +00:00
|
|
|
(each line lines
|
2023-12-05 04:59:49 +00:00
|
|
|
(var pool (create-pool 0))
|
2023-12-03 11:29:08 +00:00
|
|
|
(var [game subsets] (pmatch line))
|
2023-12-05 04:59:49 +00:00
|
|
|
(all-pred subsets (create-pool-walker pool))
|
|
|
|
(pp pool)
|
|
|
|
(+= power-sum (calc-power pool)))
|
|
|
|
(print power-sum))
|
2023-12-03 11:29:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
(start-suite)
|
|
|
|
|
|
|
|
(def example
|
|
|
|
["Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green"
|
|
|
|
"Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue"
|
|
|
|
"Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red"
|
|
|
|
"Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red"
|
|
|
|
"Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"])
|
2023-12-03 11:38:22 +00:00
|
|
|
(assert (deep= @[42
|
|
|
|
@[@[@[1 :blue] @[4 :red]]
|
|
|
|
@[@[3 :green]]]]
|
|
|
|
(pmatch "Game 42: 1 blue, 4 red; 3 green")))
|
2023-12-03 11:29:08 +00:00
|
|
|
|
2023-12-05 04:38:38 +00:00
|
|
|
(assert (possible @[12 :blue]))
|
|
|
|
(assert (not (possible @[25 :blue])))
|
2023-12-03 11:29:08 +00:00
|
|
|
|
|
|
|
(def impossible-match
|
|
|
|
(pmatch "Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red"))
|
|
|
|
|
|
|
|
(def possible-match
|
|
|
|
(pmatch "Game 3: 8 green, 6 blue, 10 red; 5 blue, 4 red, 13 green; 5 green, 1 red"))
|
|
|
|
|
2023-12-05 04:38:38 +00:00
|
|
|
(assert (not (all-possible (impossible-match 1))))
|
|
|
|
(assert (all-possible (possible-match 1)))
|
2023-12-03 11:29:08 +00:00
|
|
|
|
|
|
|
(end-suite)
|
|
|
|
|
|
|
|
(print (with [f (file/open "p02.txt")] (solve (file/lines f))))
|