adventofcode

Happy Advent 2020! Please put answers in the pinned threads or create one if it does not exist yet. | https://github.com/adventofcode-clojurians/adventofcode-clojurians | Join the private leaderboard with code 217019-4a55b8eb
fellshard 2019-12-12T00:09:52.084600Z

Lotta folks don't dig the cpu simulators; they've always been my favs, and it's much more interesting to me now that he's using it to drive other systems. The integration aspect is its own set of neat challenges that he wouldn't have been able to put in a single day previously. The downside I can see is that it makes catching up very linear; skipping days isn't as simple this year as it was in prior.

rjray 2019-12-12T00:19:39.086900Z

Yeah, I'd agree with you on the fun-aspect of integrating the sim with other systems. I only finally today got around to extracting the intcode "machine" into its own namespace and refactored my day 11 code to use the imported machine. Figure we've got at least 6 more days that'll use the machine, maybe more.

misha 2019-12-12T06:39:53.089500Z

nothing wrong with cpu simulator except too convoluted and verbose description of one, spread across 3 or 4 days, and like total of 15 pages of text. Even changes in requirements are not that bad comparing to this.

misha 2019-12-12T06:46:22.090100Z

any part 2 ideas?

rjray 2019-12-12T07:34:35.091100Z

Definitely can't brute-force it. I ran out of memory on the second test data set (and I have 16Gb of physical memory). Gonna sleep on it and see if I can think of something in the morning.

mpcjanssen 2019-12-12T07:58:22.091800Z

my velocities keep blowing up for part 1

2019-12-12T08:02:02.092900Z

Guess the name of the task itself is known problem with existing solutions

2019-12-12T08:13:31.093100Z

https://en.m.wikipedia.org/wiki/N-body_problem

👍 1
misha 2019-12-12T08:21:20.093700Z

I just read reddit for hints today :opieop:

misha 2019-12-12T08:22:14.094700Z

slow though:

p1 input   "Elapsed time: 35.301894 msecs"
p2 sample1 "Elapsed time: 2.732321 msecs"
p2 sample2 "Elapsed time: 293.312654 msecs"
p2 input   "Elapsed time: 11600.599702 msecs"

misha 2019-12-12T08:35:48.096300Z

spoiler inside

mpcjanssen 2019-12-12T08:36:52.096600Z

oh?

mpcjanssen 2019-12-12T08:37:18.096900Z

not for me 🙂

misha 2019-12-12T08:37:40.097100Z

total cycle can be predicted from cycles of each of the axes, which are much shorter. Think frequency of a wave which is a summary of sine waves with different frequencies

mpcjanssen 2019-12-12T08:38:29.097500Z

ah was almost there, needed to split by axis too

mpcjanssen 2019-12-12T09:37:12.098100Z

now some primw factor voodoo

mpcjanssen 2019-12-12T10:48:28.098300Z

am stuck example 1 works with my code exampen2 and my puzzle give way too high answers

misha 2019-12-12T11:20:40.098600Z

another spoiler: it is not (* x y z)

mpcjanssen 2019-12-12T11:45:30.098800Z

you need to check when the whole x axis and vx isnrhe same for all moons

mpcjanssen 2019-12-12T11:45:47.099Z

and you need some prime factor work indeed

mpcjanssen 2019-12-12T11:52:40.099200Z

bingo

mpcjanssen 2019-12-12T11:57:49.099400Z

main observation. The equations of motion in each axis are completely independent

mpcjanssen 2019-12-12T14:42:27.101200Z

interesting. Changing the moons from maps to records reduces the part 2 runtime from 40 to 30 seconds

mpcjanssen 2019-12-12T14:44:34.101600Z

Any other performance tips?

yuhan 2019-12-12T15:02:01.102300Z

You don't actually have to find the prime factorizations of each axis, just their lowest common multiple

yuhan 2019-12-12T15:02:37.102500Z

which you can use Euclid's algorithm for - LCM(a,b) = a*b / GCD(a,b)

yuhan 2019-12-12T15:07:36.102700Z

although I don't think that's the bottleneck - my solution for part2 runs in 680ms

mpcjanssen 2019-12-12T15:14:57.102900Z

Thats indeed not thw borrlenexk

mpcjanssen 2019-12-12T15:15:19.103100Z

It was a fun exercise though

mpcjanssen 2019-12-12T15:15:56.103300Z

how do check if you reached the initial state?

yuhan 2019-12-12T15:17:28.103500Z

I just use = on a seq of [p, v] tuples

yuhan 2019-12-12T15:18:28.103700Z

looking at your notebook, it's hard to read because of all the funky indentation

yuhan 2019-12-12T15:20:54.103900Z

I've only played around with Clojure notebooks for a while before, but the Parinfer plugin was essential for keeping some grasp on the parens: https://github.com/jelmerderonde/jupyter-lab-parinfer

yuhan 2019-12-12T15:21:27.104200Z

your dv-ax function is simply compare

mpcjanssen 2019-12-12T15:21:50.104400Z

my step is slow

mpcjanssen 2019-12-12T15:22:15.104600Z

i am doing this on my phone so indentation is not the best

yuhan 2019-12-12T15:22:28.104800Z

ah, that explains it

yuhan 2019-12-12T15:23:23.105Z

your addp is (mapv + p1 p2)

yuhan 2019-12-12T15:24:56.105200Z

30s on a phone with Clojurescript might not be that bad after all?

mpcjanssen 2019-12-12T15:30:45.105400Z

count on a lazy seq is slow?

yuhan 2019-12-12T15:31:48.105600Z

count forces the elements of the seq to be realised

mpcjanssen 2019-12-12T15:32:10.105800Z

if I remove the xount

mpcjanssen 2019-12-12T15:32:28.106Z

and add a doall, its much faster

mpcjanssen 2019-12-12T15:33:00.106200Z

did you use recur or iterate?

yuhan 2019-12-12T15:33:55.106400Z

iterate

mpcjanssen 2019-12-12T15:34:36.106600Z

how do you know the number of steps?

yuhan 2019-12-12T15:42:09.106800Z

iterate generates an infinite seq, I reduce over it and break using reduced when it cycles back around

yuhan 2019-12-12T15:43:06.107Z

Here's some of the relevant bits

(def input
  (parse "<x=14, y=9, z=14>
<x=9, y=11, z=6>
<x=-6, y=14, z=-4>
<x=4, y=-4, z=-3>"))
;; => ((14 9 14) (9 11 6) (-6 14 -4) (4 -4 -3))

(def test-input
  (parse "<x=-1, y=0, z=2>
<x=2, y=-10, z=-7>
<x=4, y=-8, z=8>
<x=3, y=5, z=-1>"))
;; => ((-1 0 2) (2 -10 -7) (4 -8 8(3 5 -1))


;; * Part 2
(defn axis-step
  [pvs]
  (map (fn [[p v]]
         (let [nv (+ v (reduce (fn [acc [p']]
                                 (+ acc (compare p' p)))
                         0 pvs))]
           [(+ p nv) nv]))
    pvs))

(defn axis-period
  [ps]
  (let [vs (repeat 0)
        pvs (map vector ps vs)]
    (reduce (fn [cnt x]
              (if (= pvs x)
                (reduced cnt)
                (inc cnt)))
      1 (next (iterate axis-step pvs)))))

(for [ps (apply map vector test-input)]
  (axis-period ps))
;; => (18 28 44)

(util/lcm 18 28 44)
;; => 2772


(apply util/lcm
  (for [ps (apply map vector input)]
    (axis-period ps)))
;; => 282399002133976

mpcjanssen 2019-12-12T15:47:07.107200Z

oww addp is just +

mpcjanssen 2019-12-12T15:47:35.107400Z

ah and reduce for the count

mpcjanssen 2019-12-12T16:15:31.108100Z

my phone is quite fast I am not much slower than the really fast solutions

misha 2019-12-12T16:53:45.108300Z

oh yeah, I did not think to completely split the computation from for-all-axes-in-a-single-step into 1-axis-per-step

2019-12-12T17:36:03.110300Z

Finally one that required some puzzling 😃. I drew a graph of one of the moon coordinates that hinted towards a solution. https://gitlab.com/dmarjenburgh/adventofcode/blob/master/src/adventofcode/year_2019.clj#L277-314

Average-user 2019-12-12T17:46:59.111Z

I got part 2 to run In about 3 seconds: https://github.com/Average-user/adventofcode-clj-2019/blob/master/src/adventofcode_clj_2019/day12.clj

👌 1
Average-user 2019-12-12T17:47:25.111200Z

adventofcode-clj-2019.day12> (time (part-2))
"Elapsed time: 2809.105945 msecs"
324618307124784

Mario C. 2019-12-12T23:38:42.112800Z

I am working on Day 11 part 2 and I keep getting a weird drawing. Looks like a rabbit. I already set the first panel to white as per the instructions but still no actual word.

fellshard 2019-12-12T23:43:38.113300Z

Hmm. I'd ask if there's something wrong with your turning implementation, but Part 1 should have rooted that out.

Mario C. 2019-12-12T23:46:46.113600Z

This would be my turning function

(defn move-bot
  [[face [x y]] outputs]
  (let [[_ turn] outputs]
    (if (empty? outputs)
      (do (println "OUTPUTS EMPTY standing still")
          [face [x y]])
      (case face
        :north (if (= turn 0)
                 [:west [(dec x) y]]
                 [:east [(inc x) y]])
        :south (if (= turn 0)
                 [:east [(inc x) y]]
                 [:west [(dec x) y]])
        :west (if (= turn 0)
                [:south [x (dec y)]]
                [:north [x (inc y)]])
        :east (if (= turn 0)
                [:north [x (inc y)]]
                [:south [x (dec y)]])))))

Mario C. 2019-12-13T16:19:39.001Z

Thats funny because I actually did this exact thing for another function

(defn get-input
  [[_ pos] grid]
  (let [color (get grid pos :black)]
    (get {:black 0 :white 1} color)))
Didn't think of using it for this! Good catch! :thumbsup:

misha 2019-12-13T16:28:21.001200Z

you'll get diff-functions though, instead of calculated values, so there will be extra apply step