adventofcode

Benjamin 2021-12-08T14:28:15.432Z

day8 spoilers

Benjamin 2021-12-08T14:28:23.432100Z

does it make sense to use core.logic?

erdos 2021-12-08T14:29:49.432300Z

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.

πŸ‘€ 1
βž• 1
nbardiuk 2021-12-08T17:09:15.437300Z

Short animation how algorithm slowly converges on answer

πŸ‘ 1
πŸ’― 1
πŸ‘ 1
πŸŽ‰ 1
jaihindhreddy 2021-12-13T08:43:06.090400Z

Looks very interesting. Mind sharing the code? (Or describing the algorithm?)

jaihindhreddy 2021-12-13T08:52:15.090600Z

Nevermind. Found it on your github πŸ˜ƒ

πŸ‘ 1
nbardiuk 2021-12-08T17:09:56.437600Z

Brightness of yellow represents certanty in output, brighter green is processed input

Aleks 2021-12-08T17:19:24.438200Z

https://twitter.com/algrison/status/1468541254455771139

πŸ‘ 5
🀯 2
Aleks 2021-12-08T04:56:05.418700Z

🧡Day 8 answers thread: post your answers here

genmeblog 2021-12-08T10:02:32.424Z

Went a path of segments difference https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2021/day08.clj

Kirill Chernyshov 2021-12-08T10:10:02.424600Z

;; 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 operations

Kirill Chernyshov 2021-12-08T10:29:43.424800Z

yep ) 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})

5
πŸ€” 2
Aleks 2021-12-08T12:31:25.428100Z

@delaguardo amazing! It seems you missed ?g 1 in the first map, or am I wrong?

Kirill Chernyshov 2021-12-08T12:33:34.428400Z

Oops, you are right)

erdos 2021-12-08T13:53:37.429600Z

solved with core logic: https://gist.github.com/erdos/e2a704552532554a209e8a7e23d8491e

πŸ‘ 5
Callum Oakley 2021-12-08T14:09:11.430300Z

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

😍 1
πŸ’ͺ 3
tschady 2021-12-08T14:56:43.432900Z

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

🍻 2
πŸ˜‚ 1
tschady 2021-12-08T16:09:50.434Z

too bad it’s not a line parsing competition: https://github.com/tschady/advent-of-code/blob/main/src/aoc/2021/d08.clj#L9

πŸ‘ 2
πŸ˜… 2
Aleks 2021-12-08T16:13:23.434400Z

Rewrote my solution with freqs https://github.com/zelark/AoC-2021/blob/main/src/zelark/aoc_2021/day_08.clj

🍻 3
Antonio Bibiano 2021-12-08T19:43:08.440600Z

oh man i'm really struggling today

2021-12-08T20:23:46.441200Z

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

2021-12-08T20:23:53.441400Z

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 +)))

jacoelho 2021-12-08T20:28:22.441600Z

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

Sam Adams 2021-12-08T20:31:10.442Z

My (rough) core.logic-based solution: https://samadams.dev/2021/12/08/advent-of-code-day-8.html

πŸ‘ 2
2021-12-08T21:20:20.443400Z

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

Andrew Byala 2021-12-08T21:22:35.443800Z

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

πŸ‘ 1
Andrew Byala 2021-12-08T21:27:09.444400Z

I'm making my way through the code, but I really like @sam.h.adams' 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!

Antonio Bibiano 2021-12-08T22:36:20.445900Z

Antonio Bibiano 2021-12-08T22:37:13.446300Z

done, a mix of segment frequency and a check with the number 4 to solve one ambiguity..

Sam Adams 2021-12-08T22:37:39.446500Z

Thanks Andrew! And that makes two of us 😁

2021-12-08T22:40:07.446700Z

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 I made an assumption that until substitution is solved or there is an easy pick (one which has only one possibility to substitute) there will be always at least one substitution that have only 2 possibilities and then did a fork on each of those substitutions when looking up for solutions. It proved to be enough but would really like to later modify my code so when it has to guess it will fork on the lowest guess count needed Fixing this assumption went much faster than I thought, so the code now if there is no easy substitution selects the ones with the lowest guesses needed and calls fn again recursively with each guess substituted in possibilities

Sam Adams 2021-12-08T22:53:40.447400Z

@abyala 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

BjΓΆrn Ebbinghaus 2021-12-08T23:47:50.448300Z

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

πŸ‘ 3
euccastro 2021-12-09T00:57:47.448800Z

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

kevinc 2021-12-09T00:59:35.449100Z

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.

euccastro 2021-12-09T01:16:30.449600Z

@jacoelho: you can use (let [{matches true misses false} (group-by f all)] ,,,) for separate

2021-12-09T05:41:03.450800Z

@zelark I think you deserve the achievement title "Mr. frequencies" πŸ™‚

πŸ˜… 1
Felipe 2021-12-11T01:58:23.038800Z

honestly relieved to see everyone else's solutions aren't like 10 lines

mchampine 2021-12-08T05:58:26.418900Z

(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

2021-12-08T06:19:11.421400Z

https://gitlab.com/maximoburrito/advent2021/-/blob/main/src/day8/main.clj Crude first pass, but it works. whee

πŸ‘ 2
peterc 2021-12-08T07:13:32.421800Z

Could set/subset? have helped you in your has-all function?

1
Aleks 2021-12-08T07:14:04.422Z

a terrible one but it does its job πŸ‘» https://github.com/zelark/AoC-2021/blob/main/src/zelark/aoc_2021/day_08.clj

R.A. Porter 2021-12-08T07:21:51.422300Z

It's...adequate. https://coyotesqrl.github.io/advent-of-code/2021/#/src%2Fcoyotesqrl%2F2021%2Fday8.clj

πŸ‘ 1