Fork me on GitHub
<
2020-12-18
>
markw02:12:53

I thought day 17 looked reasonably easy at first… Now my back of the envelope guess for part 2 completion is 2.5 hours

markw02:12:42

guess that leaves me some time to consider my botched approach … or just be lazy and let it finish before day 18 😛

markw02:12:02

only an hour it turns out…. yay?

curlyfry04:12:06

While I have no clue what your solution looks like, maybe you can bring that down without rewriting your logic at all by using `memoize` (if you have any functions that will often have the same inputs throughout execution)

markw04:12:11

yeah i was considering going in that direction, but i just scrapped version one and did a big refactor.. now it’s < 1 second for part 1 and about 10 for part 2, good enough for me

Vincent Cantin05:12:00

euccastro05:12:47

mine is admittedly very hacky 🙂

Vincent Cantin05:12:08

I am awaiting the solution from @U067R559Q, hope to learn something new again.

Vincent Cantin05:12:32

mine is tricky 🙂 .. tricks are not always available.

euccastro06:12:27

I kind of knew postwalk existed but I had never used it so I stayed in string land all along 🙂

alekszelark06:12:47

@U8MJBRSR5 today is your turn to teach us something 🙂

☝️ 6
Vincent Cantin06:12:05

Not fair, I will ask a refund. 😉

alekszelark06:12:24

Nice catch to use `postwalk`, I even didn’t remember about it.

alekszelark06:12:21

Actually, I solved it in python, because it was faster for me. Now I’m going to have breakfast and go to work.

6
alekszelark08:12:42

Here is my solution, based on `postwalk` as well, but without tricks for part 2 https://github.com/zelark/AoC-2020/blob/master/src/zelark/aoc_2020/day_18.clj

👍 9
Joe11:12:24

https://github.com/RedPenguin101/aoc2020/blob/main/day18.clj no post walk, just good old recursive calls to evaluate. Feels very SICP'y

👍 15
erwinrooijakkers12:12:58

👍 9
😍 3
👏 3
erwinrooijakkers15:12:29

`(insta/visualize (arithmetic-parser2 "1 + (2 * 3) + (4 * (5 + 6))"))`

6
Vincent Cantin16:12:49

@U2PGHFU5U at the end of your program, you do a map inside your reduce

Vincent Cantin16:12:01

you may also do something like

``````(->> input
(map (comp-> arithmetic-parser (partial insta/transform parse-tree->sexp)))
(reduce +))``````

👍 3
Average-user16:12:42

(not mine) But I found this solution quite fun https://github.com/elektronaut/advent-of-code/blob/main/day18/day18.clj Don't know if this guy is here or not

👍 9
nbardiuk17:12:35

I feel you pain, I also manually processed tokens and spend too much time debugging precedence and parenthesis

genmeblog18:12:55

Yeah... The most frustrating moment was when all tests were passing but total result was wrong. After a while I've found that `(9*((1+1))+1)` gave different result than `(9*(1+1)+1)`....

R.A. Porter03:12:52

I also went the grammar + instaparse route, anticipating that part 2 might be harder or, finally, tomorrow would build upon today. Made for almost no clojure code, but here are my crappy grammars https://github.com/coyotesqrl/advent2020/blob/master/resources/day18-no-precedence.grammar https://github.com/coyotesqrl/advent2020/blob/master/resources/day18-plus-precedence.grammar

🎉 3
curlyfry08:12:38

Should have gone with instaparse right away, I also got all the test data working but failed on the file. https://github.com/Dexterminator/advent-of-code-2020/blob/main/src/day18/core.clj

👍 3
misha10:12:20

``````(defn calc
;; outer
([priority form]
(let [f (complement number?)
x (reduce
(fn [form ops]
(if (f form)
(calc priority ops form)
(reduced form)))
form
priority)]
(if (f x) (first x) x)))

;;inner
([priority OP form]
(if (number? form)
form
(loop [todo  (rest form)
done  [(calc priority (first form))]]
(if (empty? todo)
done
(let [[op x & todo] todo
f (eval op)
a (peek done)
b (if (list? x) (calc priority x) x)]
(if (OP op)
(recur todo (conj (pop done) (f a b)))
(recur todo (conj done op b)))))))))

(calc '[#{+} #{*}] '[(4 * (3 * 2 + 2) * (9 * 7 * 5 * 4 * 9) * (7 * 7 + 7 * 4 + 9)) + 6 * 4 + 8 + ((6 * 5) * 4 * (2 * 8 + 4 + 7 * 9 + 3) * 2 + 6) + 3])
(calc '[#{+} #{-}] '(10 + (6 * 5)))

(defn solve [input priority]
(->> input
(str/split-lines)
(map #(read-string (str "[" % "]")))
(map #(calc priority %))
(reduce +)))

(assert (= 15285807527593  (solve i '[#{+ *}])))
(assert (= 461295257566346 (solve i '[#{+} #{*}])))``````

👍 3
Average-user06:12:02

That was boring :c

Vincent Cantin06:12:41

Maybe it means that we improved.

Average-user06:12:35

Don't think so. My solution is still pretty ugly, but that is because the problem is not very motivating. At least for me of course, it is a matter of taste.

Vincent Cantin06:12:42

Small note about how to test the type of something that looks like a “list”:

``````;; Only use list? when you are sure what you want to test is a list.
(list? (map identity (list :a :b))) ; false
(list? (cons :a (list :b))) ; false
(list? `(:a :b)) ; false

;; sequential? is more generic.
(sequential? (map identity (list :a :b))) ; true
(sequential? (cons :a (list :b))) ; true
(sequential? `(:a :b)) ; true

;; Note: Strings are seqable, but not sequential?
(sequential? "foo")) ; false``````

6
🙏 6
Daw-Ran Liou11:12:58

TIL `clojure.lang.Symbol`s are also functions! I guess the purpose of it is to look up things inside a map or a set but I’m not sure how to use this effectively. Here is the source code: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Symbol.java#L127-L133

``````;; surprise!
('+ 1 2)
;; => 2

('+ {'+ 1})
;; => 1
('+ {'+ +})
;; => #function[clojure.core/+]
('+ {'* *})
;; => nil
('+ {'* *} :not-found)
;; => :not-found``````

👍 9
Daw-Ran Liou12:12:41

Had to learn this the hard way because my day 18 part 1 kept evaluating to the very last number in any given equation.

``````('+ ('+ 1 ('* 2 3)) ('* 4 ('+ 5 6)))
;; => 6``````

😅 6
Vincent Cantin13:12:24

I did not know that. Thank you for sharing.