This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-08
Channels
- # adventofcode (49)
- # babashka (21)
- # babashka-sci-dev (12)
- # beginners (250)
- # calva (23)
- # cider (6)
- # clj-kondo (11)
- # cljsrn (8)
- # clojure (129)
- # clojure-europe (50)
- # clojure-france (8)
- # clojure-italy (6)
- # clojure-nl (14)
- # clojure-romania (7)
- # clojure-spec (21)
- # clojure-uk (3)
- # clojurescript (17)
- # conjure (1)
- # core-async (40)
- # core-logic (24)
- # core-typed (7)
- # datavis (2)
- # datomic (2)
- # emacs (29)
- # fulcro (10)
- # graalvm (6)
- # graphql (24)
- # gratitude (6)
- # jobs (1)
- # lsp (9)
- # malli (6)
- # missionary (1)
- # nextjournal (46)
- # off-topic (2)
- # other-languages (3)
- # pathom (5)
- # portal (2)
- # re-frame (37)
- # remote-jobs (1)
- # shadow-cljs (15)
- # spacemacs (9)
- # testing (6)
- # tools-deps (13)
- # vim (32)
- # xtdb (16)
🧵Day 8 answers thread: post your answers here
(defn procline [l]
(->> (str/split l #"\|")
(map str/trim)
(util/split-all-spaces)))
(def input
(->> (util/load-lines "resources/day08.data")
(map procline)))
;; part 1
(->> (map second input)
(map #(map count %))
(map #(filter #{7 4 2 3} %))
(apply concat)
count)
;; => 421
;; part 2
(defn num-common [a b]
(count (filter (set (sort a)) (sort b))))
(defn decoderfn [gbc]
(zipmap
(->> (select-keys gbc [2 3 4 7])
vals
(map first))
[1 7 4 8]))
(defn nmaps [sharemap gbc decode-em n]
(let [codeslen-n (get gbc n)
nums (map sharemap (map decode-em codeslen-n))]
(zipmap codeslen-n nums)))
(def sharemap5 {'(1 2 2) 2 '(2 3 3) 3 '(1 2 3) 5})
(def sharemap6 {'(1 2 3) 6 '(2 3 4) 9 '(2 3 3) 0})
(defn outval [[signals patterns]]
(let [gbc (group-by count signals)
decoder (decoderfn gbc)
vk147 (map first (vals (select-keys gbc [2 3 4])))
decode-em (fn [code] (map (partial num-common code) vk147))
mapper (merge decoder
(nmaps sharemap5 gbc decode-em 5)
(nmaps sharemap6 gbc decode-em 6))]
(Integer/parseInt (apply str (map mapper patterns)))))
(reduce + (map outval input)) ;; 986163
https://gitlab.com/maximoburrito/advent2021/-/blob/main/src/day8/main.clj Crude first pass, but it works. whee
a terrible one but it does its job 👻 https://github.com/zelark/AoC-2021/blob/main/src/zelark/aoc_2021/day_08.clj
It's...adequate. https://coyotesqrl.github.io/advent-of-code/2021/#/src%2Fcoyotesqrl%2F2021%2Fday8.clj
https://github.com/raicotop/advent-of-code-2021/blob/main/src/advent_of_code_2021/day-08.clj
Went a path of segments difference https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2021/day08.clj
;; 0 2 3 5 6 9
(frequencies '(a b c e f g a c d e g a c d f g a b d f g a b d e f g a b c d f g))
(into (sorted-map) '{a 6, b 4, c 4, e 3, f 5, g 6, d 5})
;; => {a 6, b 4, c 4, d 5, e 3, f 5, g 6}
;; 1 4 7 8
(frequencies '(c f b c d f a c f a b c d e f))
(into (sorted-map) '{c 4, f 4, b 2, d 2, a 2, e 1})
;; => {a 2, b 2, c 4, d 2, e 1, f 4}
looks like it is possible to solve second part using frequencies only, without set operationsyep ) it is definitely possible )
(let [data (:input (first input-data))
{a 2
b 4
c 3
d 7
e 5
f 6} (group-by count data)]
(ml/matches (ml/matcher '[{?a 2, ?b 2, ?c 4, ?d 2, ?e 1, ?f 4}
{?a 6, ?b 4, ?c 4, ?d 5, ?e 3, ?f 5, ?g 6}])
[(frequencies (flatten (concat a b c d)))
(frequencies (flatten (concat e f)))]))
;; => ({?a \c, ?b \e, ?c \d, ?d \g, ?e \f, ?f \b, ?g \a})
@U04V4KLKC amazing! It seems you missed ?g 1 in the first map, or am I wrong?
Oops, you are right)
solved with core logic: https://gist.github.com/erdos/e2a704552532554a209e8a7e23d8491e
brute forced the permutations since there are only 7! (5040) of them https://github.com/callum-oakley/advent-of-code/blob/main/src/aoc/2021/08.clj takes 700ms
I took a hybrid approach between freqs and string diffs. I really wanted to try logic programming, but I was way past the Ballmer peak at that point last night. https://github.com/tschady/advent-of-code/blob/main/src/aoc/2021/d08.clj
Using sets https://gist.github.com/galuque/fdeba14c6103bf6482b6f7c53fd645db#file-aoc2021_day_8-clj
too bad it’s not a line parsing competition: https://github.com/tschady/advent-of-code/blob/main/src/aoc/2021/d08.clj#L9
Rewrote my solution with freqs https://github.com/zelark/AoC-2021/blob/main/src/zelark/aoc_2021/day_08.clj
oh man i'm really struggling today
I just had to brute force, even doing it on paper I couldn't see how to deduce the test input to get all the values. Part 1
(defn parser [line]
(let [[xs ys] (str/split line #" \| ")]
[(str/split xs #" ") (str/split ys #" ")]))
;; part 1
(let [input (f/read-all-lines-and-parse "puzzle-inputs/2021/day8" parser)]
(->> input
(map second)
(apply concat)
(map count)
(filter #(some #{2 3 4 7} #{%}))
(count))) ; 247
Part 2
(defn parser [line]
(str/split line #" \| "))
(def numbers {#{\c \f} 1
#{\a \c \d \e \g} 2
#{\a \c \d \f \g} 3
#{\b \c \d \f} 4
#{\a \b \d \f \g} 5
#{\a \b \d \e \f \g} 6
#{\a \c \f} 7
#{\a \b \c \d \e \f \g} 8
#{\a \b \c \d \f \g} 9
#{\a \b \c \e \f \g} 0})
(defn all-combos [xs]
(combo/permutations xs))
(defn get-replacer [[a b c d e f g]]
{"a" a, "b" b, "c" c, "d" d, "e" e, "f" f, "g" g})
(defn decoded->int [decoded]
(Integer/parseInt (str/join "" decoded)))
(defn to-display-num [num]
(map set (str/split num #"\s")))
(defn solve-line [[input to-solve]]
(loop [[perm & rest] (all-combos ["a" "b" "c" "d" "e" "f" "g"])]
(if (nil? rest)
:not-found
(let [replacements (get-replacer perm)
input' (str/replace input #"a|b|c|d|e|f|g" replacements)
nums (to-display-num input')]
(if (every? numbers nums)
(->> (str/replace to-solve #"a|b|c|d|e|f|g" replacements)
(to-display-num)
(map numbers)
(decoded->int))
(recur rest))))))
(let [input (f/read-all-lines-and-parse "puzzle-inputs/2021/day8" parser)]
(->> input
(map solve-line)
(reduce +)))
Using mainly exclusions https://github.com/jacoelho/advent-of-code-clj/blob/main/src/aoc/2021/day08.clj separate based on the old clojure-contrib, not sure if there is a replacement
My (rough) core.logic-based solution: https://samadams.dev/2021/12/08/advent-of-code-day-8.html
After running out of heap memory by trying to solve it via constraint propagation via recursion, I solved it in this simpler way:
(ns aoc-2021.day-8
(:require [ :as io]
[clojure.string :as str]
[clojure.set :as set]
[aoc.util :refer [comp->]]))
(def input
(->> (io/resource "2021/day8.txt")
slurp
str/split-lines
(mapv (fn [line]
(vec (re-seq #"\w+" line))))))
;; Part 1
(->> input
(mapcat (fn [line]
(subvec line 10)))
(filter (comp-> count #{2 4 3 7}))
count)
;; Part 2
(defn solve [line]
(let [digits (subvec line 0 10)
secrets (subvec line 10)
count->digits (group-by count (mapv set digits))
mapping {1 (-> 2 count->digits first)
7 (-> 3 count->digits first)
4 (-> 4 count->digits first)
8 (-> 7 count->digits first)}
mapping (assoc mapping 3 (-> 5 count->digits
(->> (filter #(set/superset? % (mapping 7))))
first))
mapping (assoc mapping 2 (-> 5 count->digits
(->> (remove #{(mapping 3)}))
(->> (filter #(= (count (set/intersection % (mapping 4))) 2)))
first))
mapping (assoc mapping 5 (-> 5 count->digits
(->> (remove #{(mapping 3) (mapping 2)}))
first))
mapping (assoc mapping 9 (-> 6 count->digits
(->> (filter #(set/superset? % (mapping 4))))
first))
mapping (assoc mapping 0 (-> 6 count->digits
(->> (remove #{(mapping 9)}))
(->> (filter #(set/superset? % (mapping 1))))
first))
mapping (assoc mapping 6 (-> 6 count->digits
(->> (remove #{(mapping 9) (mapping 0)}))
first))
rmapping (into {} (map (fn [[k v]] [v k])) mapping)]
(->> secrets
(map set)
(map rmapping)
(apply str)
parse-long)))
(transduce (map solve) + input)
; => 936117
I'm feeling ok about my solution. I threw together a few letfn
definitions to make my solution for each signal a bit easier on the eyes.
• https://github.com/abyala/advent-2021-clojure/blob/main/docs/day08.md
• https://github.com/abyala/advent-2021-clojure/blob/main/src/advent_2021_clojure/day08.clj
I'm making my way through the code, but I really like @U016C0EGHUN' parsing logic, calling (map #(partition-by #{"|"} %) lines)
to split both sides of the input line. I never thought of using a set of the delimiter to split the data sides (`false`) from the delimiter itself (`true`).
And I hope you liked that little compliment, because I don't understand core.logic and it looks rather intimidating!
done, a mix of segment frequency and a check with the number 4 to solve one ambiguity..
https://github.com/kfirmanty/advent-of-code-2021/blob/main/src/day8.clj really enjoyed today task. the first part was quite a breeze, the second one took more time. The core idea was that I made a function that given the input creates a possible substition map like:
{\a #{\c \f}
\b #{\g \d \c}}
etc. which was then just the case of substituting code looking for easy substitutions (where there is only one possibility in set) and removing them from other possibilities. If there were no easy substitution the code would make a "guess" and fork on possible substitutions based on that guess
@U01HHBJ56J1 your writeup flows very smoothly, and I like that the your code bits stand on their own with the commentary beforehand — I should not have mixed mine together in today’s blog
I think I have a good solution. Just based on set cardinality / intersection / difference https://github.com/MrEbbinghaus/advent-of-code/blob/master/2021/day08.clj#L40 5ms for task 2 with slurp + parse + execute in babashka
after some fumbling around I went for brute force in this one (takes about 15sec): https://github.com/euccastro/advent-of-code-2021/blob/main/day8.clj
https://github.com/kconner/advent-of-code/blob/master/2021/8a.clj, https://github.com/kconner/advent-of-code/blob/master/2021/8b.clj. Brief, but I wonder how I could improve the second part.
@U1UHFHABV: you can use (let [{matches true misses false} (group-by f all)] ,,,)
for separate
Not really, or at least not in a naive way. I have a https://gist.github.com/erdos/e2a704552532554a209e8a7e23d8491e in it but it is horribly slow.
Brightness of yellow represents certanty in output, brighter green is processed input
Looks very interesting. Mind sharing the code? (Or describing the algorithm?)