adventofcode

Aleks 2021-12-07T08:47:59.379600Z

https://twitter.com/algrison/status/1468129198128648193

🦀 7
❤️ 6
Aleks 2021-12-07T09:54:01.382300Z

Haha, it reminds me about day 22 last year https://adventofcode.com/2020/day/22

lread 2021-12-07T17:51:07.402400Z

Uh oh, for me, part 1 test and real data work, part 2 test data works and real data fails. Hmm… dang.

Antonio Bibiano 2021-12-07T18:16:10.403400Z

What was your approach?

lread 2021-12-07T18:20:59.403600Z

For part1 I found pos via the median of positions, then calced cost. For part2 I started with brute force calcing cost for each possible pos, but found this slow, so I optimized via a binary-search-ish strategy. This leads me to same wrong answer for real-data, only faster. simple_smile

Antonio Bibiano 2021-12-07T18:28:09.405Z

Ah I see I did also a brute force approach but not optimized at all :D

sarcilav 2021-12-07T18:35:27.406Z

I also did binary search, it could be either and error on the cost function or on the stop condition of the binary search

sarcilav 2021-12-07T18:36:07.406200Z

are you doing binary search over the range from min to max pos or just on existing positions?

lread 2021-12-07T18:39:40.406400Z

I’m guessing it must be my cost function because my brute force also fails in same way.

lread 2021-12-07T18:40:19.406700Z

But costs all look good for test data. So… must be something silly… but I don’t know what yet.

lread 2021-12-07T18:49:17.407200Z

Oh yeah, very silly! I don’t know why I was, but I was answering the with the position and not the fuel cost.

🙌 2
lread 2021-12-07T18:51:00.407400Z

I have no excuses. simple_smile

2021-12-07T19:13:43.408400Z

Can someone help with my code for part 2 today, I'm getting an arrity exception and I've not idea why. Code in thread in case it's a spoiler.

Pradeep B 2021-12-08T10:36:09.425Z

good catch @pithyless and nice to see you around.

👋 1
2021-12-07T19:14:15.408500Z

(defn build-row [min max n]
  (let [to-max (reductions + (u/range-inclusive 1 (- max n)))
        to-min (reverse (reductions + (u/range-inclusive min n)))]
    (concat to-min [0] to-max)))

(let [input (f/parse-csv-ints "puzzle-inputs/2021/day7-test")
      min (apply min input)
      max (apply max input)]
  (->> input
       (map (partial build-row min max) input)
       #_(apply map vector)
       #_(mapv #(reduce + 0 %))
       #_(sort)
       #_(first)))
I'm getting arrity exception in the call to to build-row , it says its getting 4 arguments

2021-12-07T19:14:55.408700Z

but i thought with partial, it will get min and max, that leaves one. Then it will get 1 from input. input here is a list like (1 0 16 2 1 0 4)

pithyless 2021-12-07T19:15:03.408900Z

the input inside map

pithyless 2021-12-07T19:15:14.409100Z

(->> input
       (map (partial build-row min max) input)

👍 1
2021-12-07T19:15:22.409300Z

oh balls! I missed that! so input is going in twice isnt it

☝️ 1
2021-12-07T19:15:48.409600Z

thank you

pithyless 2021-12-07T19:15:55.409800Z

Happy to duckie :)

tschady 2021-12-07T20:06:56.410900Z

my 💰 is on a grid problem tonight

sarcilav 2021-12-07T20:11:44.413200Z

mine on a graph one

2021-12-07T20:20:19.413500Z

please god, no graphs

Antonio Bibiano 2021-12-07T20:11:11.412700Z

ahaha i bet on a "puzzle" thing

😩 1
Phil Shapiro 2021-12-07T21:08:40.414500Z

I'm hoping for another interpreter / mini machine language one, those are pretty fun.

☝️ 3
tschady 2021-12-07T22:13:35.415800Z

i’m still working on assembunny interpreter from 2016

Cora (she/her) 2021-12-07T21:49:20.415500Z

I might mess with fennel for days 6 and 7

👍 1
Sidestep 2021-12-11T12:02:08.045800Z

how come? how does it help?

Cora (she/her) 2021-12-11T12:48:10.048800Z

just to learn something new ¯\(ツ)

lread 2021-12-07T23:32:54.417Z

Is that your fennel answer?

🥁 7
😂 6
rmprescott 2021-12-07T01:13:12.361700Z

Too bad they didn't go a bit larger. ;D

(time (part-2 input 500))
"Elapsed time: 3.192168 msecs"
=> 2759581742718205387412N

Aleks 2021-12-07T04:54:43.365500Z

🧵Day 7 answers thread: post your answers here

euccastro 2021-12-07T08:04:34.376300Z

for day 7 I happened to remember the math trick to sum the 1..n integers. I tried an optimization (involving frequencies, of course) of the first thing I thought of, but that was hardly worth the trouble: https://github.com/euccastro/advent-of-code-2021/blob/main/day7.clj

euccastro 2021-12-07T08:10:48.376800Z

@zelark nice one! If you have already calculated the frequencies it's slightly more efficient and concise to iterate over the keys of that instead of (range min-pos (inc max-pos)) ?

euccastro 2021-12-07T08:22:56.377500Z

anyway, I was surprised about how little time is saved by reducing the number of positions to compare against, either with frequencies or range from min to max

jacoelho 2021-12-07T08:30:47.377700Z

brute force solution, memoize fuel calculations https://github.com/jacoelho/advent-of-code-clj/blob/main/src/aoc/2021/day07.clj

Aleks 2021-12-07T08:32:21.378Z

@euccastro that was my first thought, and it worked for my part 1. But for part 2 there is no position in the input which is the best to choose. So I ended up with a full range of the all positions.

euccastro 2021-12-07T08:33:44.378300Z

oh, great catch!

peterc 2021-12-07T08:33:59.378500Z

tossing in a pmap seems like the easiest win

euccastro 2021-12-07T08:34:33.378700Z

I interpreted the problem as picking the cheapest position from the given crab positions, so I guess I just got lucky with my puzzle input

🤞 1
jherrlin 2021-12-07T08:40:49.379200Z

Yeah I used a pmap, dont know if it was totally necessary but it felt cool 🙂 https://github.com/Kodkollektivet/advent-of-code-2021/blob/main/clojure/jherrlin/day7/problem2.clj

peterc 2021-12-07T09:05:15.379900Z

Is this right? For part 1, sorting the input, and calculating the cost at the midpoint yields the first solution. (There are two midpoints, so use the min).

peterc 2021-12-07T09:06:41.380100Z

Solution looks like this:

(defn part1 []
  (let [data (sort (input))
        mid  (/ (count data) 2)]
    (min (cost data (nth data mid))
         (cost data (nth data (dec mid))))))

peterc 2021-12-07T09:09:43.380300Z

upon reflection, i think the answer can lie between the two points

Callum Oakley 2021-12-07T09:23:34.380700Z

binary search ~50ms https://github.com/callum-oakley/advent-of-code/blob/main/src/aoc/2021/07.clj

🙌 1
tschady 2021-12-07T09:23:48.381Z

@nbardiuk your floor-median should probably be floor-mean?

nbardiuk 2021-12-07T09:48:19.381300Z

thank you! fixed

babardo 2021-12-07T10:26:07.382700Z

Avoided doing too much maths 😅 https://github.com/v-garcia/aoc_2021/blob/main/day_seven.clj

Antonio Bibiano 2021-12-07T10:27:37.383Z

I have to admit I solved mine with raw brute force 😄

(defn cost-1 [pos crab]
  (Math/abs (- pos crab)))

(defn cost-2 [pos crab]
  (let [dist (Math/abs (- pos crab))]
    (/ (* dist (inc dist)) 2)))

(defn brute-min-cost [crabs cost]
  (let [far (apply max crabs)]
    (apply min
           (map (fn [pos]
                  (reduce +
                          (map #(cost pos %) crabs)))
                (range (inc far))))))

(brute-min-cost crabs cost-1)
(brute-min-cost crabs cost-2)

Antonio Bibiano 2021-12-07T10:28:46.383300Z

then I wikipedia the shit out of the problem and found that median was the solution to part 1 and a friend suggested that the average is the solution to part 2 so here they are

Antonio Bibiano 2021-12-07T10:29:17.383500Z

(defn median [l]
  (let [len (count l)
        middle (/ len 2)
        sorted (sort l)]
    [(nth sorted (dec middle)) (nth sorted middle)]))

(defn avg* [crabs]
  (/ (apply + crabs) (count crabs)))

(defn avg [crabs]
  (let [res (avg* crabs)]
    [(int res) (inc (int res))]))

(defn cost-1 [pos crab]
  (Math/abs (- pos crab)))

(defn cost-2 [pos crab]
  (let [dist (Math/abs (- pos crab))]
    (/ (* dist (inc dist)) 2)))

(defn min-cost [crabs cost candidates]
  (apply min
         (map (fn [pos]
                (reduce + (map #(cost pos %) crabs)))
              candidates)))

(def crabs (parse large))
(min-cost crabs cost-1 (median crabs))
(min-cost crabs cost-2 (avg crabs))

Antonio Bibiano 2021-12-07T10:29:52.383700Z

i decided to return two candidates for median and average just in case

genmeblog 2021-12-07T11:40:18.386800Z

ups, sorry, density was wrong... had to delete previous message above - submarine trace, below - initial density of submarines 🙂

👏 2
borkdude 2021-12-07T12:13:17.388Z

Day 7 in #babashka and #clojure https://gist.github.com/borkdude/b5cf0e9d2d8ab7c678d88e27a3357b33#file-aoc21_07-clj

👍 1
Felipe 2021-12-07T12:38:41.388600Z

brute forced part 1 expecting part 2 to force me to think of a better solution, but my laziness paid off https://github.com/FelipeCortez/advent-of-code/blob/master/2021/07.clj

borkdude 2021-12-07T12:40:59.388900Z

@felipecortezfi Awesome! How fast is yours?

borkdude 2021-12-07T12:41:26.389100Z

Not that it matters, just wondering

Felipe 2021-12-07T12:43:52.389300Z

huh, time says "Elapsed time: 0.235105 msecs" , but it's definitely more

borkdude 2021-12-07T12:44:13.389500Z

this is because of laziness probably which escapes the time call

Felipe 2021-12-07T12:44:20.389700Z

yeah, mapv yields "Elapsed time: 11779.226753 msecs"

borkdude 2021-12-07T12:45:30.390Z

This guy has optimized it so it runs in tens of milliseconds in both clojure and babashka: https://github.com/mknoszlig/aoc2021/blob/76ef20928dd59d3810ca5e04f7f879357389268b/src/aoc2021/day7.clj

Felipe 2021-12-07T12:46:36.390400Z

nice! https://github.com/mknoszlig/aoc2021/commit/76ef20928dd59d3810ca5e04f7f879357389268b this is surprising for me

borkdude 2021-12-07T12:49:12.390600Z

Math/abs reflects in the absence of type hints

👍 1
Felipe 2021-12-07T12:49:54.390800Z

oh! makes sense

borkdude 2021-12-07T12:50:02.391Z

user=> (set! *warn-on-reflection* true)
true
user=> (defn foo [x] (Math/abs x))
Reflection warning, NO_SOURCE_PATH:1:15 - call to static method abs on java.lang.Math can't be resolved (argument types: unknown).
#'user/foo

nbardiuk 2021-12-07T13:16:39.391800Z

somebody worked out that correct answer differs from mean by up to 0.5 https://www.reddit.com/r/adventofcode/comments/rawxad/2021_day_7_part_2_i_wrote_a_paper_on_todays/

👌 5
borkdude 2021-12-07T13:18:31.392Z

woah! :)

tschady 2021-12-07T13:22:51.392400Z

welp, time to update my code 🙂

tschady 2021-12-07T13:25:42.392800Z

oh, to be young again

Callum Oakley 2021-12-07T13:25:48.393Z

if you have an intcode computer handy, there’s an easter egg in today’s puzzle :o

2
🎉 1
genmeblog 2021-12-07T13:37:15.393300Z

solution with optimizer (sometimes it can give wrong answer, mainly due to discrete domain):

(defn dist [a b] (int (m/abs (- a b))))
(defn fuel-burn [data cost-fn m] (reduce #(+ %1 (cost-fn %2 m)) 0 data))
(defn cost [d] (/ (* d (inc d)) 2))
(def target1 (comp (partial fuel-burn data dist) int))
(def target2 (comp (partial fuel-burn data (comp cost dist)) int))
(defn optimizer [target] 
  (->> {:bounds [[0 2000]] :N 100}
       (fastmath.optimization/scan-and-minimize :cmaes target)
       (second)
       (int)))

(optimizer target1)
;; => 336040
(optimizer target2)
;; => 94813675

;; --- also valid
(target1 (fastmath.stats/median data))
;; => 336040
(target2 (fastmath.stats/mean data))
;; => 94813675

tschady 2021-12-07T13:46:58.393800Z

cheater version with credit given: https://github.com/tschady/advent-of-code/blob/main/src/aoc/2021/d07.clj

Antonio Bibiano 2021-12-07T13:53:42.394400Z

adding the type hints really changes the performance!! thanks @borkdude for pointing that out

Antonio Bibiano 2021-12-07T13:53:52.394600Z

but I found this a bit odd when I tried to define the cost like this

(defn cost-1 [^int pos ^int crab]
  (Math/abs (- pos crab)))

Antonio Bibiano 2021-12-07T13:53:59.394800Z

; Syntax error (IllegalArgumentException) compiling fn* at (/home/antbbn/aoc_2021/day7.clj:63:1).
; Only long and double primitives are supported

genmeblog 2021-12-07T13:54:54.395500Z

yes, that works this way (I mean Clojure type hinting)

genmeblog 2021-12-07T13:55:21.395800Z

only longs can be used and these are possible up to arity 4

Antonio Bibiano 2021-12-07T13:56:49.396100Z

but on the reference it says that int is acceptable

genmeblog 2021-12-07T13:57:57.396300Z

but not as a type hint for a function arguments, you can use type hinting in any other places and there ^int is possible.

genmeblog 2021-12-07T13:59:53.396500Z

for example, this is ok:

(defn cost-1 [[^int pos ^int crab]]
  (Math/abs (- pos crab)))

genmeblog 2021-12-07T14:00:19.396700Z

or this:

(defn cost-1 [pos crab]
  (Math/abs (- ^int pos ^int crab)))

Antonio Bibiano 2021-12-07T14:04:27.398300Z

Ah I see, I guess it's a bit off topic but do you know the reason for that?

genmeblog 2021-12-07T14:12:38.398600Z

yep, there is a stub for a function for every combination of arguments and returning value

Antonio Bibiano 2021-12-07T14:27:29.399200Z

oh wow

Antonio Bibiano 2021-12-07T14:27:38.399400Z

thanks 🙂

2021-12-07T16:43:44.400100Z

https://github.com/kfirmanty/advent-of-code-2021/blob/main/src/day7.clj it was much easier for me than day7. Not very performant but when checking day6 solutions afterwards and seeing people using memoize it reminded me how nice of a function this is and basically used it today for part2

Sam Adams 2021-12-07T17:43:17.401100Z

Best I could come up with (through trial and error) for part 2 was that the solution position seemed to be bounded by the median and rounded mean. Apparently that’s faulty… unless the median indicates which direction the mean is pulled by up to 1/2…? That’s a question for later 🙂   https://samadams.dev/2021/12/07/advent-of-code-day-7.html

gabo 2021-12-07T18:31:37.405700Z

I brute forced it and part2 was taking ~20 s, just changing the naive summing of ranges for the gauss formula got me to 200ms 😳 https://gist.github.com/galuque/fdeba14c6103bf6482b6f7c53fd645db#file-aoc2021_day_7-clj

2021-12-07T19:44:28.410200Z

Part 2 got a bit messy for me:

(ns stuartstein777.2021.day7
  (:require [stuartstein777.file :as f]
            [stuartstein777.utils :as u]))

(defn get-distances [hps n]
  (mapv (fn [h] (Math/abs (- h n))) hps))

(let [input (f/parse-csv-ints "puzzle-inputs/2021/day7")
      minimum (apply min input)
      maximum (apply max input)
      h-positions (u/range-inclusive minimum maximum)]
  (->> input
       (mapv (partial get-distances h-positions))
       (apply mapv vector)
       (mapv #(reduce + 0 %))
       (apply min)))

;; part 2
(defn build-row [min max n]
  (let [to-max (if (= n max) [] (reductions + (u/range-inclusive 1 (- max n))))
        to-min (reverse (reductions + (u/range-inclusive min n)))]
    (concat to-min to-max)))

(let [input (f/parse-csv-ints "puzzle-inputs/2021/day7")
      minimum (apply min input)
      maximum (apply max input)]
  (->> input
       (mapv (partial build-row minimum maximum))
       (apply map vector)
       (mapv #(reduce + 0 %))
       (apply min)))
I built a table up of the distance to each possible horizontal position, then rotated it 90 degrees, summed each row and took the min. I expected it to be too slow but it runs in a couple of seconds or so for part 2.

Björn Ebbinghaus 2021-12-07T23:22:17.416200Z

I derived the sum of the consumption of the crabs for an alignment x https://twitter.com/MrEbbinghaus/status/1468359022453612549

mchampine 2021-12-07T05:33:38.367Z

(defn fuel [ex n] (apply + (map #(util/abs (- % n)) ex)))
(apply min (map (partial fuel input) (range (apply max input)))) ;; 335271

;; Part 2  (incfuel improved by mikelis observation)
(defn incfuel [n] (/ (* n (inc n)) 2))
(defn fuel2 [ex n] (apply + (map #(incfuel (util/abs (- % n))) ex)))
(apply min (map (partial fuel2 input) (range (apply max input)))) ;; 95851339

Miķelis Vindavs 2021-12-07T05:34:51.367200Z

By the way 1 + 2 + 3 + … + n == n * (n + 1) / 2

👍 6
➕ 2
👌 1
Aleks 2021-12-07T05:59:04.368500Z

Just brute force https://github.com/zelark/AoC-2021/blob/main/src/zelark/aoc_2021/day_07.clj

Miķelis Vindavs 2021-12-07T06:03:42.368900Z

nice use of frequencies to skip over duplicates

Pradeep B 2021-12-07T06:52:40.370300Z

(def example-input-list (list 16,1,2,0,4,2,7,1,2,14))
(def example-input-frequencies (sort-by val (frequencies ex)))

(defn calculate-diff [n pos]
  (if (> pos n) (- pos n) (- n pos)))

(first (sort 
        (map (fn [input] 
               (reduce + (map #(calculate-diff %1 (first input)) example-input-list)))
             example-input-frequencies)))
feedback is more than welcome, what else can be done to optimize (part1 only, understanding formula to calculate cost for part2)

peterc 2021-12-07T07:03:57.371800Z

You can sort the input and do a binary search on it You can do a binary search on the possible positions

👀 1
nbardiuk 2021-12-07T07:28:25.372700Z

After solving using brute force, I've noticed that positions are very close to median and mean, and looks like for a lot of people on reddit it also works https://github.com/nbardiuk/adventofcode/blob/master/2021/src/day07.clj

👍 5
peterc 2021-12-07T07:41:02.373100Z

Not the most idiomatic, but you can do something like this @pradeep.bishnoi

(defn cost-fn-1 [start end]
  (abs start end))

(defn cost-fn-2 [start end]
  (let [n (abs start end)]
    (/ (* n (inc n)) 2)))

(defn cost [data cost-fn n]
  (reduce + (map (partial cost-fn n) data)))

(defn mid [a b]
  (int (+ a (/ (- b a) 2))))

(defn  min-cost [f]
  (let [d  (parse-data)]
    (loop [mn   0
           mx   (apply max d)
           best (cost d f (mid mn mx))]
      (if (= mn mx)
        best
        (let [md     (mid mn mx)
              lower  (cost d f (mid mn md))
              higher (cost d f (mid md mx))]
          (if (< lower higher)
            (recur mn md (min lower best))
            (recur (inc md) mx (min higher best))))))))

(def part-1 (min-cost cost-fn-1))
(def part-2 (min-cost cost-fn-2))

🙌 1
Pradeep B 2021-12-07T07:42:09.373400Z

realised after looking at part2 that mean will be good approach/ thanks @peterc

peterc 2021-12-07T07:45:20.373600Z

There are a bunch of bugs in my code actually, my the input is nice enough to give me the correct solution.

peterc 2021-12-07T07:45:55.373800Z

Spits out an answer in about ~200ms on my machine

Miķelis Vindavs 2021-12-07T05:48:22.368400Z

I can share a pro tip I figured out for myself today: Running today’s code on yesterday’s input is most likely not going to work 😄

😁 12
euccastro 2021-12-07T08:18:49.377300Z

I got bitten by that mistake after reading this!

lread 2021-12-07T17:55:33.402500Z

I also stated with this “tactic”.

fingertoe 2021-12-07T06:59:30.371600Z

All caught up! My bingo card computation was buggy and overcomplicated. Rewrote it successfully today. Burnt out at about 23 stars last year. Better momentum this time..

👍 4