Fork me on GitHub
#adventofcode
<
2019-12-07
>
jrwdunham04:12:30

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:

jrwdunham04:12:32

(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))))

fellshard06:12:49

Part 2 is a doozy and I love it.

fellshard06:12:49

I have no idea how I'm gonna visualize this, though, hahahah

fellshard06:12:12

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.

meikemertsch06:12:15

I have real trouble understanding how part 2 is supposed to work… 😢

meikemertsch06:12:55

Can anyone explain part2 without spoilers?

fellshard06:12:32

• 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.

fellshard06:12:50

(This is just a rephrasing of the information as it exists in part 2)

meikemertsch06:12:14

“so we’ll hold off on evaluating it further for now” THAT!

meikemertsch06:12:34

I think I get it now… Thanks

meikemertsch06:12:49

Now I just have to figure out how to do this 😂

pesterhazy10:12:39

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)

regen13:12:08

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.)

yenda13:12:15

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?

fellshard14:12:42

@ 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.

fellshard14:12:51

@ 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.

pesterhazy10:12:49

> 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.

regen12:12:26

ugh. today's part 2 is going to eat my whole weekend

yenda13:12:35

My part 2 is working for examples but doesnt halt with puzzle input :/

mpcjanssen13:12:19

finally finished part 2. solution is horrible though

mpcjanssen13:12:20

Note to self: don't try to print infinite lazy seqs

misha05:12:33

(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

mpcjanssen13:12:07

Seemed it wasn't halting actually was trying to print a lazy seq

fellshard14:12:26

I can't tell you the number of times I've had to kill cider because I did that in AoC.

mpcjanssen14:12:25

Haskell does that better

mpcjanssen14:12:14

I did run a bit into nested data structure confusion this round. Curious to see how others did it.

fellshard19:12:13

I was wondering if someone would use channels :)

lucaspolymeris00:12:22

I did something very similar. Just quite messier

dfehrenbach0401:12:41

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

namenu02:12:40

wow, great idea!

erwinrooijakkers16:12:41

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.

fellshard17:12:09

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. :)

pesterhazy16:12:12

Interesting @erwinrooijakkers, though it feels core.async is not an exact fit for the problem, as asynchronous operations is not necessary to solve it

pesterhazy16:12:13

Python generators (or ES6 generators in JS) are a better fit - do these have an implementation in Clojure?

mpcjanssen16:12:22

Just exhausting all input and continue running tje next amp works also but that is basically a manual yield

dmarjenburgh17:12:58

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.

pastafari17:12:26

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?

dmarjenburgh17:12:13

Like this?

(with-in-str "line1\nline2"
  [(read-line) (read-line)])
; => ["line1", "line2"]

pastafari17:12:16

Thanks much 🙂

pastafari17:12:09

I knew about with-out-str , never searched for with-in-str!

meikemertsch17:12:00

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>

lilactown22:12:09

I am still really struggling with day5

lilactown22:12:21

I keep running up against this instruction: ("101" "-80" "224" "224")

lilactown22:12:50

this seems to be saying "read position -80" which doesn't make sense

lilactown22:12:23

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

lilactown22:12:22

all of my diagnostic codes come back 0

regen22:12:40

Doesn't "101" mean read 1st parameter in immediate mode, so -80 should be interpreted as a value?

lilactown22:12:22

AFAICT "101" would be padded to "00101"?

lilactown22:12:20

> read right-to-left from the opcode

pastafari22:12:12

@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!

lilactown23:12:19

yeah I misread the problem, I was reading the modes left-to-right 😵

lilactown23:12:25

very frustrating