adventofcode 2023-12-08

I guess that wouldn’t have been solvable without proper data inspection πŸ‘€

https://gitlab.com/maximoburrito/advent2023/-/blob/main/src/day08/main.clj After getting tricked by not trying the brute force approach, this time I wasted time on a brute force solution. When it was clear it wouldn't work, I wrote some code to explore the data a bit. Thankfully all the cycles repeated exactly, so it it was easy to calculate the solution and math where they all meet.

solution: https://github.com/erdos/advent-of-code/blob/master/2023/day08.clj went with counting reductions over the cycle of the instructions and using reduced to shortcut.

πŸ‘ 1

I just did day 8 In Clojure, having previously done it Kotlin. I'm pretty proud of how much more succinct my Clojure solution (very functional) is than my Kotlin one (which is a bit more OO). https://github.com/cdpjenkins/advent-of-code/blob/main/2023/clj-aoc-2023/src/clj_aoc_2023/day08.clj

(Was lazy and added numeric-tower to deps...)

πŸ‘ 1

wasted quite some time on the brute force approach for part2 before I actually looked at the size of the problem space and noped out. i reached for lcm because there's always a gcd/lcm puzzle in AOC and all the emphasis on "simultaneously" walking part2 made me think I probably shouldn't actually do that. Why LCM works though is pretty untuitive for me. https://github.com/Ramblurr/advent-of-code/blob/main/src/aoc/2023/day08.clj

Second part is waaay goood! I enjoyed and feel fun!

(defn f [i n]
  (cond
    (> (* i i) n) [n]
    (zero? (mod n i)) (conj (f i (quot n i)) i)
    :else (f (inc i) n)))

(let [[path m] (str/split input #"\n\n" 2)
      m (->> (str/split m #"\n")
             (keep (fn [s] (-> s
                               (str/replace #"[A-Z0-9]+" #(str "\"" % "\""))
                               (str/split #"\=" 2)
                               (->> (mapv read-string)))))
             (into {}))
      lr (fn [i p] (let [[l r] (get m p)
                         i (mod i (count path))]
                     (if (= \L (get path i)) l r)))
      g (fn [p-start]
          (loop [p p-start
                 i 0]
            (let [p (lr i p)]
              (if (= \Z (get p 2))
                (inc i)
                (recur p (inc i))))))]
  (->>  m
        keys
        (filter #(= \A (get % 2)))
        (map (comp frequencies (partial f 2) g))
        (apply merge-with max)
        (mapcat identity)
        (apply *)))

https://github.com/rjray/advent-2023-clojure/blob/master/src/advent_of_code/day08.clj I also (briefly) tried to brute-force part 2, and also figured out the cycles. Used clojure.math.numeric-tower/lcm for the math.

Lcm is easy to implement - look at f (efficient fast factorization, although it may be even more faster - by stepping in 2 or by prime numbers) in my code above, and last 3 strings - for combining factors in lcm

πŸ‘ 1

https://github.com/samcf/advent-of-code/blob/main/2023-08-haunted-wasteland.clj Finding where sequences converge is an aoc classic and I always trip up on it

🀯 1

Day 8 part 2 almost tricked me into implementing LCM. But then I looked closer at the inputs. https://github.com/bhauman/adv2023/blob/main/src/adv2023/day08/sol.clj

So the length of the directions string β€œLRLR …” is most likely a prime factor, because all the paths contain it. If you divide all the cycle-lengths (distance to first Z ending location) of the different paths followed by that factor you may end up with a set of unique prime factors, so the ultimate number of steps is (* dir-length (/ cycle-length-1 dir-length) ...

how did I not remember clojure.math.numeric-tower?

@bhauman I did end up dividing each steps count by my directions count and thought something fun could be done with that idea but wasn't quite sure so I abandoned it

πŸ‘ 1

Nice solution!

Thanks! but now I wish I’d done the numeric-tower/lcm route. It would have made my second answer very brief.

I’m really enjoying reading everyone’s solutions. This is my kind of fun. πŸŽ„

Nice solution @felipecortezfi! mapcat would be a good candidate on line 11:

;;(into {} (comp (map parse-mapping) cat) mappings)
VS
(into {} (mapcat parse-mapping) mappings)

mapcat isn’t a transducer though?

Not sure about transduser (need chek at clojredocs), but it is definitelly List monads bind, so that is why it widelly used in algorythms based on lists πŸ˜€

oh wait mapcat is a transducer it’s definition is (comp (map f) cat)

πŸ‘ 1

This gave me a chuckle.

πŸ˜‚ 9
πŸ˜† 3
πŸ’ͺ 2
5

I got that. The odd thing is that if you ask it to translate the input to English, it does change it

Yeah, it translates to, "HELP! I'M TRAPPED INSIDE A GRAPH TRAVERSAL PROBLEM!"

πŸ˜‚ 1