This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-12-07
Channels
- # adventofcode (62)
- # babashka (88)
- # beginners (52)
- # boot (2)
- # bristol-clojurians (1)
- # calva (7)
- # cider (15)
- # circleci (4)
- # clj-kondo (12)
- # cljdoc (5)
- # cljsrn (4)
- # clojure (53)
- # clojure-dev (1)
- # clojure-spec (7)
- # clojure-uk (7)
- # clojurescript (25)
- # core-async (14)
- # duct (1)
- # emacs (10)
- # figwheel-main (3)
- # fulcro (11)
- # garden (14)
- # jobs (1)
- # klipse (2)
- # luminus (1)
- # malli (9)
- # re-frame (6)
- # reagent (13)
- # remote-jobs (1)
- # shadow-cljs (124)
- # sql (1)
- # testing (15)
- # tools-deps (13)
- # uncomplicate (1)
- # vim (1)
Whoah, pretty much all the solutions to Dec6/pt1 saw that you could just add all of the distances from each node to the root. I didn't see that so I added each node's orbiter count multiplied by the depth of the node—about an order of magnitude less efficient, but still works:
(defn count-orbits
([orbits] (count-orbits orbits 1 :o-COM))
([orbits depth node]
(let [orbiters (get-orbiters-of node orbits)] ;; (:o-A :o-X)
(if (seq orbiters)
(+ (* depth (count orbiters))
(->> orbiters
(map (fn [orbiter] (count-orbits orbits (inc depth) orbiter)))
(reduce +)))
0))))
Seriously, though, twists like this are what make me love these challenges. And I'm glad he's steadily building on the same machine this year.
I have real trouble understanding how part 2 is supposed to work… 😢
• Each amplifier is given their phase as their first input, just like in part 1. • Amplifier A receives input '0'. • Amplifier A runs and emits 1 or more elements to output. • Amplifier A tries to read an input, but has no input to read yet, and so we'll hold off on evaluating it further for now. • Amplifier B consumes A's outputs as its new inputs. • Amplifier B runs and consumes its inputs until it runs out, emitting outputs for C to consume • ... • Etc., until E emits outputs for A to consume as inputs. • ... • Eventually, all the machines will formally halt (opcode 99), and when the last machine does, its output is the output of the array as a whole.
OOOOOOHHHHH!
“so we’ll hold off on evaluating it further for now” THAT!
I think I get it now… Thanks
Now I just have to figure out how to do this 😂
They key is to understand that there are multiple VMs running now, each yielding to the next while keeping state (never need to reset now)
I'm very confused. Aren't the amplifiers only supposed to send the thruster signal to the next amp, each amp in turn increasing this number? Or do all of the amplifiers have their own thruster signal state, which only that specific amp increases, only to be added up when it finally halts? (And then communicating with the other amps via in/out signals that don't hold the actual thruster signal.)
When you hold off evaluating further because you have no more inputs, do you keep the offset and resume from where you suspended in the next iteration?
@UCW9TUDNK Each amplifier consumes inputs and generates outputs; those outputs are fed as inputs to the next amp in the chain, as shown in the pictures.
@U0DB715GU Correct. You can think of it as 'the amp is still running, but it's waiting for the 'in' operation to complete'. Similar to a CPU idling until data arrives from disk.
> And I'm glad he's steadily building on the same machine this year. Yes but... I had a bug apparently in my previous code (of the "why did this work before" variety) so that took me a while to debug.

finally finished part 2. solution is horrible though
(set! *print-length* 20)
=> 20
(println (range))
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...)
=> nil
Seemed it wasn't halting actually was trying to print a lazy seq
I can't tell you the number of times I've had to kill cider because I did that in AoC.
Haskell does that better
I did run a bit into nested data structure confusion this round. Curious to see how others did it.
I always make sure to set https://clojuredocs.org/clojure.core/*print-length* and https://clojuredocs.org/clojure.core/*print-level* if I’m printing off large/lazy structures
And TIL
Solution using core.async: https://github.com/transducer/adventofcode/blob/master/src/adventofcode/2019/day7.clj
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
I see the comments now. Thanks! 🙂 I didn’t see a way to solve the problem by passing state, but it is clearly possible looking at other solutions. I am also curious about ideas with other constructs that pass data from one process to another.
In this case, you can basically do it by forcing the asynchronous system to be fully synchronous; you impose some global order of execution across all amplifiers, and hop from one to the other as needed. It certainly feels kludgier, though. :)
Interesting @erwinrooijakkers, though it feels core.async is not an exact fit for the problem, as asynchronous operations is not necessary to solve it
Python generators (or ES6 generators in JS) are a better fit - do these have an implementation in Clojure?
Just exhausting all input and continue running tje next amp works also but that is basically a manual yield
Ugh, got part 1 pretty quickly, but for part 2 I had to refactor a large part of the intcode machine. I used core.async too. Will share later.
Hallo Clojurians - for Day 7, I am trying to figure out how can I feed input to the amplifiers.
Context, my Intcode interpreter uses (read-line)
for opcode 3 which reads from IN (ps: please read this as "star in star", Slack turns it into bold!).
I've been exploring binding IN to a Reader that will successively return phase and input on each call to read-line. The default impl. of IN is a LineNumberingPushbackReader that wraps System/in.
I want to make my own LineNumberingPushbackReader that closes over phase and input and returns them on succesive calls to read-line.
My Clojure is a bit rusty, so I'm not exactly sure about the best way to proceed. Any tips?
Like this?
(with-in-str "line1\nline2"
[(read-line) (read-line)])
; => ["line1", "line2"]
In the end I am pretty happy with my solution. I always am if I can use the same code for part 1 and 2 (I realize that my code is rather a beginner level… but in the end I get it somehow done 😆). Thanks to @fellshard for the explanation so I could finally understand what was going on! 🙏 <https://github.com/MeikeMertsch/AoC_2019/blob/master/src/christmas/day07.clj>
https://gitlab.com/dmarjenburgh/adventofcode/blob/master/src/adventofcode/year_2019.clj#L144-181
I've completely rewritten my code a couple times now. my intcode computer passes day2 and and all test cases I've found so far
Doesn't "101" mean read 1st parameter in immediate mode, so -80 should be interpreted as a value?
@lilactown I struggled with something similar, and then found a line in the instructions "Parameters that an instruction writes to will never be in immediate mode." - this line seems contradictory to me, but that was the problem with my code!
(set! *print-length* 20)
=> 20
(println (range))
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ...)
=> nil