I did something very similar. Just quite messier
I also did something similar, but I didn't use a go-loop... then had to deal with blocking IO. Argh! Should definitely have used a go-loop! Great job
My messy iterative solution https://github.com/mpcjanssen/aoc2019/blob/master/day07.ipynb
I was looking to some clever solutions using Haskells lazy evaluation:
amplify program [a,b,c,d,e] = last oute
where outa = intcode (a:0:oute) program 0
outb = intcode (b:outa) program 0
outc = intcode (c:outb) program 0
outd = intcode (d:outc) program 0
oute = intcode (e:outd) program 0
Would something like that possible in Clojure?
wow, great idea!
@lucaspolymeris you have a link to the full program?
Yep, give ma sec. But anyway, intcode is just the regular function from day5
https://github.com/bblum/aoc/blob/master/day07/Day07-lazy.hs#L49
thatโs super cool
Today's is downright trivial in Clojure. :)
yup
Unless you would want to read the output for part-2
Even that is pretty straightforward, minus a bit of forcing eagerness + string munging.
Visualization for this one is practically obvious, so I'm gonna take Quil for another spin
(As a total aside, since I discovered the 'fancy symbols' mode in Spacemacs' Clojure layer, I've used partial
so much more)
What is it? I do see prettify-symbols-mode
that changes lambda to a symbol, but what do you mean? ๐
That's the mode, yeah. It does a similar transformation for partial
into a... fancy P
, I guess?
I meant, making the computer read it, and return the word as a string (not a grid)
Ohhh
Yeah, that'd be a headache ๐
this pissed me off really hard in day5 for day7:
(defn next-input [input]
;; reuse last input if all consumed
(or (next input) input))
w/o it had nullpointers in few init combinations for part 2
Today was some welcome relief indeed
Yep. Easy in Clojure. I wound up with 3 lines of code for part 1, 5 for part 2. Not exactly pretty though. I used โascii artโ for the image, which was fastest and good enough.
http://quil.info/sketches/show/66648043ce20f4ae77390dbc6c628f743e8540e33fcb5535f4305c473fc8d30c
(The non-graphical solution is much cleaner, but boy is this more fun. ๐ )
Thatโs pretty neat. If there was extra credit youโd earn a bunch. ๐
earlier experience showed that weekend riddles are harder. Not this year. Iโm glad ๐ It was a fun one today
yes I was relieved too ๐
My Saturday was consumed by day 7 though ๐
I'm still working on day 7, but day 8 gave me something to work on while taking a break ๐
@fellshard I assumw thats from de lowest layer to thw front?
Correct. ๐
The 'actual solution' does it front to back, though.
I am pretty sure I re-wrote some magic core function that merges sets of vectors of that nature.. Got it done though. I have been struggling for motivation on the op-code puzzles.
The protocol elf should have a stern talk
I'm happy with my day7 solution, but I'm wondering how I can make my code more idiomatic: https://gitlab.com/gmbouvier/2019-aoc/blob/master/src/day7.clj I'm only a hobby clojurist but thinking about sharpening my skills for possible Clojure work so any feedback/conversation is appreciated ๐
(defn arity [opcode]
(get {1 3, 2 3, 3 1, 4 1, 5 2, 6 2, 7 3, 8 3, 99 0} opcode))
->
(def arity {1 3, 2 3, 3 1, 4 1, 5 2, 6 2, 7 3, 8 3, 99 0})
{program :program pointer :pointer output :output} state
->
{:keys [program pointer output]} state
(cond
(= 1 opcode) ...
->
(case opcode
1 ...
or
(condp = opcode
1 ...
you have a lot of fn indirection, which is hard to follow, like:
((-> {:program input :pointer 0}
(next-cont-state)
(:contfn)) i))
and
#((:m %))
and
((:i (last argslist)))
using last
too much, working with vectors and using peek
instead would be more performant (maybe not that much in this case)
I kept submitting the list of 0's and 1's as answer, haha ๐ https://gitlab.com/dmarjenburgh/adventofcode/blob/master/src/adventofcode/year_2019.clj#L183-198
(comp not zero?)
->
(complement zero?)
(fn [& args] :done)
->
(constantly :done)
after looking through all that, you begin to see things like: scanning op-code-seq multiple times:
(take-last 2)
and then
(reverse) (drop 2)
inside fn on the next line.
etc.(filter #(fn? (:contfn %)))
probably can be just
(filter :contfn)
since this key either mapped to fn or absentthis can be faster with
(last (map last (map :output amps)))
->
(last (:output (last amps)))
but it is way too many last
s(recur (concat (rest amps) [current-amp])
(last (:output current-amp)))))))))
this loop would be faster and without that many last
s if you put amps
in a queue, and then pop
and conj
it instead of first
and concat
:
(loop [amps (into PersistentQueue/EMPTY amps) ...
and in the end of the loop:
(-> amps vec peek ...)
instead of (... (last amps))
I suspect that today's (relatively straightforward) puzzle is laying the foundation for future image-related puzzles
Thanks! Those are all useful points.
As far as function indirection, would it be better if I assign the relevant fn in a let
? Possibly more verbose but could add clarity...
Or is there an issue in general with using fns as values in hash-maps?
in this particular case - it inhibits readablity for me, and feels like several unnecessary extra layers
https://github.com/transducer/adventofcode/blob/master/src/adventofcode/2019/day8.clj
Is there a nicer pattern than reducing with a state parameter in the accumulator (as in (reduce (fn [[result highest :as acc] e] (if (> e highest) [(new-state e) e] acc) [nil 0])
)?
if you already use group-by on every layer, then just frequencies
and sort-by
it instead
Thanks indeed ๐
min-key
and max-key
can also come in handy in such situations
Wow indeed. No need to sort-by and then first ๐
Better name would be max-by
and min-by
as mentioned in https://www.spacjer.com/blog/2016/01/12/lesser-known-clojure-max-key-and-min-key/
https://github.com/chrisblom/advent-of-code/blob/master/src/adventofcode/2019/day08.clj#L19
#spoiler for some. I went old school to figure out the letters ๐ This is not necessarily a spoiler for everyone, there's a bunch of random inputs per the sub-reddit!
never even heard of min-key, and it was added in 1.0, wow