adventofcode

Apple 2022-12-21T21:20:32.617589Z

Day 21 - Can your solution solve this

root: pppw + sjmn
pppw: 3 + humn
sjmn: 5 - humn

bhauman 2022-12-21T21:24:17.781879Z

Is that your input? Or just a case that you accounted for?

Apple 2022-12-21T21:24:48.358839Z

I am just wondering. The puzzle doesn't exclude this kind of input, right?

Apple 2022-12-21T21:26:04.148969Z

with * and / in the mix this could be a problem of solving an equation.

Apple 2022-12-21T21:26:41.179639Z

i think i can still manage if there's only + and -

bhauman 2022-12-21T21:27:27.804579Z

The puzzle does exclude this

bhauman 2022-12-21T21:27:40.049609Z

I can tell you more if you want

bhauman 2022-12-21T21:27:47.494259Z

I just finished

Apple 2022-12-21T21:28:19.541539Z

Oh that's good. So two lines join at the root pretty much

Miķelis Vindavs 2022-12-21T21:33:45.647659Z

@bhauman I re-read the problem statement but didn’t find anything that said that each value is used only once

Miķelis Vindavs 2022-12-21T21:33:51.435019Z

did I miss it?

Miķelis Vindavs 2022-12-21T21:34:24.710329Z

I did my initial p2 solution using z3, because i was worried the equality could be really complex and nonlinear, but ended up making a really simple “reverse application” solution instead

Miķelis Vindavs 2022-12-21T21:34:38.634749Z

but it assumes that humn is only referenced in one branch, and only once

bhauman 2022-12-21T21:34:47.295609Z

in my problem the humn value has a direct line to the root

Miķelis Vindavs 2022-12-21T21:35:08.629869Z

right, sure, but i mean the problem statement says nothing about this

bhauman 2022-12-21T21:35:45.767309Z

that’s true

Callum Oakley 2022-12-21T21:41:36.594469Z

properties of the input that aren't stated in the puzzle text have to be considered "part of the puzzle" imo or some previous days are borderline impossible

bhauman 2022-12-21T21:42:17.176889Z

yeah there is definitely a stage of doing data analysis on the input for a few of these

Callum Oakley 2022-12-21T21:43:26.576969Z

e.g. 2019 day 16 for a particularly infamous example 😅

2022-12-21T22:41:38.135029Z

This is one of the things that has always frustrated me about aoc - the input isn't input to your problem, it IS the problem to solve. The text along side is not a problem spec, it's just some text to help you understand the puzzle/problem you are given. I've come to peace with it over the years of aoc and don't treat it like I would other kinds of programming challenges. I also, always, look at my input and the question asked before I even read the text.

💯 1
tschady 2022-12-21T23:58:26.374679Z

Part1 my future/promise solution doesn’t care about special input structure, except that it’s solvable. Part2 I definitely looked at the behavior (linear) to simplify.

2022-12-21T06:33:28.498119Z

Day 21 - Solutions

Callum Oakley 2022-12-21T11:18:46.767409Z

https://github.com/callum-oakley/advent-of-code/blob/main/src/aoc/2022/21.clj I did the symbolic manipulation... sort of. let human input be h, then I kept track of the pair [a b] (represents ah + b) and then optimistically assumed that we'd never have to deal with an h^2 or h^-1 term... which turned out to be true 😅

👍 1
oddsor 2022-12-21T11:45:05.942049Z

I’m not sure my solution works for all datasets 🙈 Instead of replacing the root operator with = I replaced it with compare and used it to recursively narrow down to the right number. I created the expression as a list first and then created a function simplify that postwalks up the expression and evaluates all lists that contain just an operator and a number. https://github.com/Oddsor/advent-of-code-clj/blob/master/src/y2022/d21.clj

genmeblog 2022-12-21T11:47:39.768889Z

Macro for part-1 (still working on part-2):

(defn parse [line] (split-line line #":\s|\s"))

(def data (map parse (read-data 2022 21)))

(defmacro build-oparations
  []
  `(do ~@(for [[f a op b] data
               :let [f (symbol f)]]
           (do (println f a op b)
               (if-not op
                 `(def ~f (constantly ~(parse-long a)))
                 (let [[a op b] (map symbol [a op b])]
                   `(do (declare ~a) (declare ~b)
                        (defn ~f [] (~op (~a) (~b))))))))))

(build-oparations)
(root)
;; => 83056452926300

Callum Oakley 2022-12-21T12:28:09.089779Z

totally changed my approach since someone pointed out that the graph is a tree (should have been obvious given the "root" hint 🙄). since it's a tree the resulting function is guaranteed to be linear in h, so you can take the value at two points and extrapolate https://github.com/callum-oakley/advent-of-code/blob/main/src/aoc/2022/21.clj#L20-L24

1
🤯 3
❤️‍🔥 1
Aleks 2022-12-21T12:33:07.945699Z

@c.oakley108 brilliant, just came to the same

😎 1
2022-12-21T14:59:36.295759Z

I enjoyed today's puzzle. https://github.com/alexalemi/advent/blob/main/2022/clojure/p21.clj For the first part, I implemented a memoized recursive evaluator because I feared he would be unkind and have us recompute lots of things lots of times, but that turned out to be overkill. For part 2 I looked at the data and saw it was tree-like, so I wrote a solver but it simply 'unwinds' the equality at each stage. i.e. if we are sitting on a = x + b at the top, where a and b are numbers, we know that x = a - b. You can iterate this until you find the number.

2022-12-21T15:15:31.813769Z

Wow, yeah, it is linear. You can just search for it. (or compute it)

tschady 2022-12-21T15:33:08.388999Z

Using promises & futures. (I recycled my code with very few changes from 2015 day 7.) These are the only 2 where I keep state, but I like how this reads:

(defn run-prog! [memory prog]
  (reset! memory {})
  (alloc-registers! memory prog)
  (doseq [inst prog]
    (exec-inst! memory inst)))
https://github.com/tschady/advent-of-code/blob/main/src/aoc/2022/d21.clj

misha 2022-12-21T17:03:15.399999Z

;; p1
(let [parse (fn [line]
              (let [[id x op y] (map read-string (str/split line #":?\s"))]
                [id (if (number? x) x (list op x y))]))
      db    (->> input (str/split-lines) (map parse) (into {}))]
  (->> 'root db
    (clojure.walk/prewalk-replace db)
    (eval)
    (time)))
"Elapsed time: 30.751088 msecs"
=> 353837700405464

2
😆 1
Felipe 2022-12-21T20:13:29.945689Z

part 1 using promises. let me see if I can do the same for part 2 https://github.com/FelipeCortez/advent-of-code/blob/master/2022/21.clj

bhauman 2022-12-21T21:19:56.870609Z

part 2 “Elapsed time: 61.375238 msecs”

bhauman 2022-12-21T21:20:26.967849Z

this is a problem made for lispers

bhauman 2022-12-21T21:47:54.049399Z

Day 21: This was the funnest one for me. I did the symbolic algebra. https://github.com/bhauman/advent-of-code-2022/blob/main/src/adv2022/day21/sol.clj

bhauman 2022-12-21T21:56:48.323969Z

geez I made the mistake of reading the other solutions… great job! not as much fun as symbolic solver 😉 but I wished I’d thought of the fact that it was a linear function. Would have definitely would have saved some time.

Felipe 2022-12-22T02:34:47.117749Z

@tws I thought I was being original with the promises and futures 😞

Felipe 2022-12-22T02:34:58.412339Z

managed to solve part 2 through... visual inspection!

Felipe 2022-12-22T02:36:07.469779Z

👍 1
bhauman 2022-12-22T03:10:14.209319Z

Showing my symbolic manipulation output:

(- (/ (+ 4 (* 2 (- humn 3))) 4) 150)
(normalize)
[+ -150 [* 1/4 (+ 4 (* 2 [+ -3 humn]))]]
(simplifier)
[+ -301/2 [* 1/2 humn]]
This is where ‘= is replaced with ‘- effectively setting the equation equal to 0. The normalizing and simplifying code is pretty tidy thanks to core.match
(defn norm [[op exp1 exp2 :as all]]
  (condp = op
    '- (if (number? exp2)
         ['+ (* -1 exp2) exp1]
         ['+ exp1 ['* -1 exp2]])
    '/ (if (number? exp2)
         ['* (/ 1 exp2) exp1]
         all)
    (if (number? exp2) [op exp2 exp1] all)))

(defn simplify-exp [[op x exp2 :as arg]]
  (match [op (if (sequential? exp2) (vec exp2) [])]
         ['+ ['+ y other]] ['+ (+ x y) other]
         ['* ['* y other]] ['* (* x y) other]
         ['* ['+ y other]] ['+ (* x y) ['* x other]]
         :else arg))

(def normalize (partial postwalk #(cond-> % (sequential? %) norm)))
(def simplifier (partial postwalk #(cond-> % (sequential? %) simplify-exp)))

Apple 2022-12-22T06:00:32.330989Z

My solution for part2: 1. adds to the data set y=x*z and z=y/x when x=y/z is seen. 2. replaces root=x ops y with x=y+0 and y=x+0

stephenmhopper 2022-12-25T16:29:16.051509Z

Oh, I’d forgotten that core logic was a thing. Nice work!

Benjamin 2022-12-22T12:51:29.712379Z

learned the first thing about core.logic https://github.com/benjamin-asdf/advent-of-code/blob/master/src/Y2022/day21_logic.clj it was expecially satisfying that part 2 executed instantly

1
📚 1
1
1
2022-12-21T06:46:40.397769Z

https://gitlab.com/maximoburrito/advent2022/-/blob/main/src/day21/main.clj When part 2 came up, I wrote the code to generate an expression as a string. For the sample input, I was able to give that expression to wolfram alpha to solve, which it did. The full input was too long for wolfram. I was tempted to find something else that would solve it for kicks, but in the end i just wrote the code. The solver wasn't too hard, but it took at least an hour to figure out the cases correctly, which seems quite excessive...

bhauman 2022-12-23T12:44:31.392399Z

@benjamin.schwerdtner that is absolutely awesome!

🤩 1