Skip to content

Commit 9536173

Browse files
committed
Day 19 actually works
1 parent faaa303 commit 9536173

File tree

2 files changed

+43
-25
lines changed

2 files changed

+43
-25
lines changed

src/advent_2020_clojure/day19.clj

+36-23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
(ns advent-2020-clojure.day19
22
(:require [clojure.string :as str]
3-
[advent-2020-clojure.utils :as utils]))
3+
[advent-2020-clojure.utils :as utils]
4+
[clojure.set :as set]))
45

56
(defn parse-rule [input]
67
(let [[_ id rule-str] (re-matches #"(\d+): (.*)" input)]
@@ -12,30 +13,42 @@
1213
(defn parse-rules [rule-str]
1314
(->> rule-str str/split-lines (map parse-rule) (into {})))
1415

15-
(defn word-combinations [[a-words b-words & others]]
16-
(if (some? b-words)
17-
(let [words (for [a a-words
18-
b b-words]
19-
(str a b))]
20-
(word-combinations (cons words others)))
21-
a-words))
16+
(defn match-length [rules word rule]
17+
(let [{:keys [s paths]} (rules rule)]
18+
(cond
19+
(str/blank? word) nil
20+
(some? s) (when (= s (subs word 0 (count s))) #{(count s)})
21+
:else (->> (for [path paths]
22+
(reduce (fn [lengths id]
23+
(if (empty? lengths)
24+
#{}
25+
(->> (map (fn [length]
26+
(->> (match-length rules (subs word length) id)
27+
(keep identity)
28+
(map (fn [p] (+ length p)))
29+
set))
30+
lengths)
31+
(apply set/union))))
32+
#{0}
33+
path))
34+
(keep identity)
35+
(apply set/union)))))
2236

23-
(defn valid-strings [rules id]
24-
(let [{:keys [s paths]} (rules id)]
25-
(if (some? s)
26-
(list s)
27-
(->> paths
28-
(map (fn [path]
29-
(->> path
30-
(map #(valid-strings rules %))
31-
word-combinations)))
32-
(apply concat)))))
37+
(defn valid? [rules word]
38+
(some #(= % (count word)) (match-length rules word "0")))
3339

3440
(defn part1 [input]
3541
(let [[rule-str message-str] (utils/split-blank-line input)
36-
rules (parse-rules rule-str)
37-
messages (str/split-lines message-str)
38-
valids (set (valid-strings rules "0"))]
39-
(->> messages
40-
(filter #(valids %))
42+
rules (parse-rules rule-str)]
43+
(->> (str/split-lines message-str)
44+
(keep #(valid? rules %))
45+
count)))
46+
47+
(defn part2 [input]
48+
(let [[rule-str message-str] (utils/split-blank-line input)
49+
rules (-> (parse-rules rule-str)
50+
(assoc "8" (second (parse-rule "8: 42 | 42 8")))
51+
(assoc "11" (second (parse-rule "11: 42 31 | 42 11 31"))))]
52+
(->> (str/split-lines message-str)
53+
(keep #(when (valid? rules %) %))
4154
count)))

test/advent_2020_clojure/day19_test.clj

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
(:require [clojure.test :refer :all]
33
[advent-2020-clojure.day19 :refer :all]))
44

5-
(def TEST_DATA "0: 4 1 5\n1: 2 3 | 3 2\n2: 4 4 | 5 5\n3: 4 5 | 5 4\n4: \"a\"\n5: \"b\"\n\nababbb\nbababa\nabbbab\naaabbb\naaaabbb")
5+
(def TEST_DATA_1 "0: 4 1 5\n1: 2 3 | 3 2\n2: 4 4 | 5 5\n3: 4 5 | 5 4\n4: \"a\"\n5: \"b\"\n\nababbb\nbababa\nabbbab\naaabbb\naaaabbb")
6+
(def TEST_DATA_2 "42: 9 14 | 10 1\n9: 14 27 | 1 26\n10: 23 14 | 28 1\n1: \"a\"\n11: 42 31\n5: 1 14 | 15 1\n19: 14 1 | 14 14\n12: 24 14 | 19 1\n16: 15 1 | 14 14\n31: 14 17 | 1 13\n6: 14 14 | 1 14\n2: 1 24 | 14 4\n0: 8 11\n13: 14 3 | 1 12\n15: 1 | 14\n17: 14 2 | 1 7\n23: 25 1 | 22 14\n28: 16 1\n4: 1 1\n20: 14 14 | 1 15\n3: 5 14 | 16 1\n27: 1 6 | 14 18\n14: \"b\"\n21: 14 1 | 1 14\n25: 1 1 | 1 14\n22: 14 14\n8: 42\n26: 14 22 | 1 20\n18: 15 15\n7: 14 5 | 1 21\n24: 14 1\n\nabbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa\nbbabbbbaabaabba\nbabbbbaabbbbbabbbbbbaabaaabaaa\naaabbbbbbaaaabaababaabababbabaaabbababababaaa\nbbbbbbbaaaabbbbaaabbabaaa\nbbbababbbbaaaaaaaabbababaaababaabab\nababaaaaaabaaab\nababaaaaabbbaba\nbaabbaaaabbaaaababbaababb\nabbbbabbbbaaaababbbbbbaaaababb\naaaaabbaabaaaaababaa\naaaabbaaaabbaaa\naaaabbaabbaaaaaaabbbabbbaaabbaabaaa\nbabaaabbbaaabaababbaabababaaab\naabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba")
67
(def PUZZLE_DATA (slurp "resources/day19_data.txt"))
78

89
(deftest part1-test
9-
(is (= 2 (part1 TEST_DATA)))
10+
(is (= 2 (part1 TEST_DATA_1)))
1011
(is (= 109 (part1 PUZZLE_DATA))))
12+
13+
(deftest part2-test
14+
(is (= 12 (part2 TEST_DATA_2)))
15+
(is (= 301 (part2 PUZZLE_DATA))))

0 commit comments

Comments
 (0)