Skip to content

Commit d5d0dd0

Browse files
committed
Solve 2023/d4
1 parent 99cf95c commit d5d0dd0

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@
3232
| 2023 | [1](src/y2023/d1.clj) | overlapping regex, grrrrr... |
3333
| 2023 | [2](src/y2023/d2.clj) | zero snags; enjoyed making it nice :) |
3434
| 2023 | [3](src/y2023/d3.clj) | easy peeeeez... once I figured how best to parse things |
35+
| 2023 | [4](src/y2023/d4.clj) | neat! |
3536

3637
Feedback welcome!

src/y2023/d4.clj

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
(ns y2023.d4
2+
(:require [clojure.math :as math]
3+
[clojure.set :as set]
4+
[clojure.string :as str]
5+
[hyperfiddle.rcf :refer [tests]]
6+
[utils :as u]))
7+
8+
(def dummy-input
9+
["Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53"
10+
"Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19"
11+
"Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1"
12+
"Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83"
13+
"Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36"
14+
"Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11"])
15+
(def input (u/input))
16+
17+
; --- input parsing ---
18+
19+
(defn- parse-card [s]
20+
(let [[_ winning nums] (re-find #"Card +\d+: +(.*) +\| +(.*)" s)
21+
f (fn [s] (->> (str/split s #" +") (map parse-long) set))]
22+
{:winning (f winning)
23+
:nums (f nums)}))
24+
25+
(defn parse [input]
26+
(mapv parse-card input))
27+
28+
; --- solving ---
29+
30+
(defn points [{:keys [winning nums] :as _card}]
31+
(int (math/pow 2.0 (dec (count (set/intersection winning nums))))))
32+
33+
(defn copy-cards
34+
"Reduce over cards, accumulating copies. Return total copies."
35+
[cards]
36+
(->> (map-indexed vector cards) ; generate an index
37+
(reduce (fn [copies [i {:keys [winning nums]}]]
38+
(let [n (count (set/intersection winning nums))]
39+
; make <number of copies of this card> copies of (i+1)th -> (i+n)th cards
40+
(merge-with + copies (zipmap (range (inc i) (+ (inc i) n))
41+
(repeat (get copies i))))))
42+
; init copies to {0 1, 1 1, 2 1, ...} map
43+
; one entry for each card
44+
(zipmap (range (count cards)) (repeat 1)))
45+
(vals)
46+
(apply +)))
47+
48+
(defn solve [input & {:keys [part]}]
49+
(cond->> (parse input)
50+
(= 1 part) (map points)
51+
(= 1 part) (apply +)
52+
(= 2 part) (copy-cards)))
53+
54+
(tests
55+
(solve dummy-input :part 1) := 13
56+
(solve dummy-input :part 2) := 30
57+
)
58+
59+
(comment
60+
(solve input :part 1) ; => 21105
61+
(solve input :part 2) ; => 5329815
62+
)

0 commit comments

Comments
 (0)