Fork me on GitHub
#adventofcode
<
2021-12-13
>
alekszelark04:12:49

🧵Day 13 answers thread: post your answers here

AC06:12:43

this was a fun one..

(ns aoc21.day13
  (:require [ :as io]
            [clojure.string :as s]))

;; part 1

(defn parse-fold [s]
  (let [[_ var line] (re-matches #"fold along (.)=(\d+)" s)]
    [(keyword var) (Integer/parseInt line)]))

(defn make-grid [dots]
  (reduce (fn [g xy] (assoc g xy \X)) {} dots))

(defn input-data [filename]
  (let [[dots folds] (s/split (slurp (io/resource filename)) #"\n\n")]
    [(make-grid (partition 2 (map #(Integer/parseInt %) (re-seq #"\d+" dots))))
     (map parse-fold (s/split-lines folds))]))

(defn fold-y [grid offset]
  (into {} (map (fn [[[y x] _]] (cond (= x offset) nil
                                      (< x offset) [[y x] \X]
                                      (> x offset) [[y (- offset (- x offset))] \X]))
                grid)))

(defn fold-x [grid offset]
  (into {} (map (fn [[[y x] _]] (cond (= y offset) nil
                                      (< y offset) [[y x] \X]
                                      (> y offset) [[(- offset (- y offset)) x] \X]))
                grid)))

(defn fold [grid [axis offset]]
  (if (= axis :x)
    (fold-x grid offset)
    (fold-y grid offset)))

(defn soln-1 [filename]
  (let [[grid folds] (input-data filename)]
    (count (fold grid (first folds)))))

;; part 2

(defn dump-grid [grid]
  (let [[max-y max-x] (reduce (fn [[my mx] [[y x] _]]
                                [(max my y) (max mx x)])
                              [0 0]
                              grid)]
    (doseq [x (range (inc max-x))]
      (doseq [y (range (inc max-y))]
        (print (get grid [y x] \.)))
      (print "\n"))))

(defn soln-2 [filename]
  (let [[grid folds] (input-data filename)
        text (reduce (fn [g move] (fold g move)) grid folds)]
    (dump-grid text)
    (count text)))

Antonio Bibiano09:12:51

I'm happy about my folding 🙂 not as much about my rendering :D

alekszelark09:12:33

@U076FM90B I also enjoyed your solution, nice trick to avoid any if’s

drowsy11:12:19

parsing and drawing could be more concise but I'm fine with the folding in one line of specter https://github.com/IamDrowsy/aoc-2021/blob/main/src/aoc2021/d13.clj

👍 1
tschady13:12:47

Nothing new to offer really, I originally did a map, but copied @U44SHEP4N’s specter since I’m a fan. https://github.com/tschady/advent-of-code/blob/main/src/aoc/2021/d13.clj

Joe14:12:16

Bleh, not super happy with it. But it does work fine. On reflection, I made life difficult for myself by making the calculation for the post-fold coordinates based on the size of the paper, which meant I had to keep track of the size of the paper (since you can't determine it from the coordinates alone, though I didn't realize that at first) https://github.com/RedPenguin101/aoc2021/blob/main/clojure/src/aoc2021/day13.clj

Joe14:12:09

In fact, I just refactored that out, now it's much nicer 🙂 thanks @U1EP3BZ3Q

bananadance 1
drowsy14:12:20

@U1Z392WMQ you don't actually need the turn the transform result into a set. As long as the initial input is already a set. specter will keep types.

Sam Adams15:12:54

I liked this one too; printing the letters was very satisfying. https://samadams.dev/2021/12/13/advent-of-code-day-13.html

karol19:12:49

https://github.com/kfirmanty/advent-of-code-2021/blob/main/src/day13.clj day13 solution judging from if you want to avoid if... message identical to others 😄 Just printing the board for part2 and reading it manually felt like kind of cheating but I guess that is what most of the people did 😄

tschady20:12:47

in years past i considered doing an “OCR” on the text by comparing to a fingerprint, but he changes the letter size and font often so it’s not worth it.

Antonio Bibiano20:12:49

Maybe one can generate an image and send it off to an OCR api :D

Stuart22:12:59

Pretty easy one today

(ns stuartstein777.2021.day13
  (:require [stuartstein777.file :as f]
            [stuartstein777.utils :as u]
            [clojure.string :as str]
            [clojure.set :as set]))

(defn parse-coord [line]
  (->> (str/split line #",")
       (map #(Integer/parseInt %))))

(defn parse-folds [line]
  (let [[xy n] (u/frest (re-seq #"fold along (x|y)=(\d+)" line))]
    [xy (Integer/parseInt n)]))

(defn folder [xy n [x y]]
  (cond (and (= xy "x") (> x n))
        [(- n (Math/abs (- n x))) y]

        (and (= xy "y") (> y n))
        [x (- n (Math/abs (- n y)))]
        
        :else
        [x y]))

(defn row->str [max-x row]
  (let [xs (set (map first row))]
     (map (fn [n] (if (xs n) "⭐" "⬛")) (range (inc max-x)))))

(defn print [coords]
  (let [max-x (apply max (map first coords))]
    (->> coords
         (group-by #(second %))
         (sort-by key)
         (vals)
         (map (partial row->str max-x))
         (map (partial apply str))
         (str/join "\n")
         (println))))

(defn fold [coords [xy n]]
  (map (partial folder xy n) coords))

(let [input (->> (slurp "puzzle-inputs/2021/day13")
                 (str/split-lines))
      coords (->> input
                  (take-while #(not= "" %))
                  (map parse-coord))
      folds (->> input
                 (drop (inc (count coords)))
                 (map parse-folds)
                 #_(take 1))] ; uncomment to solve part 1
  (->> (reduce fold coords folds)
       distinct
       #_count ; uncomment to solve part 1
       print))

mario-star 3
Stuart23:12:52

Oh, i see from @U1EP3BZ3Q, I don't actually need the ((and (= xy "x") (> x n)) statements inside my cond in folder! Nice

bananadance 1
Stuart23:12:46

I just need the (= xy "x") and (= xy "y")

Andrew Byala02:12:02

Great solution, @U89SBUQ4T. I enjoyed both how you parsed your data with partition and especially with re-seq, without splitting the lines. For the fold function, your fold' made the map really clear. Thanks - I learned a lot from your tiny bit of code!

1
kevinc02:12:10

https://github.com/kconner/advent-of-code/blob/master/2021/13a.cljhttps://github.com/kconner/advent-of-code/blob/master/2021/13b.clj. I was inspired by one of yesterday's posts to compose all the folds into one, though I didn't go as far as using a transducer.

Miķelis Vindavs04:12:56

Thanks @U01HHBJ56J1, that’s nice to hear! I only picked the partition idea up myself a few days ago from another solution 🙂. Normally I also approach things top-down.

peterc05:12:55

Took me too long to render my result - spoiler in thread

peterc05:12:51

This is what I started with

Miķelis Vindavs06:12:25

The console is rotated 90deg? 😄

peterc06:12:10

and mirrored 😄

alekszelark06:12:00

fold along day=13:christmas_tree:

⤴️ 2
↩️ 3
genmeblog09:12:42

if you want to avoid if for folding (day13) you can use below formula (spoiler in thread)

👍 4
genmeblog09:12:00

(- a (m/abs (- v a))) - v - value, a - axis (edited a little bit)