adventofcode 2024-12-12

Day 12 - Solutions

https://gitlab.com/maximoburrito/advent2024/-/blob/main/src/day12/main.clj This is definitely ugly. I struggled to name things and payed the price. I also payed the price for not having handy search abstractions built up. Normally I find it fun to write it by hand each time, but this time with a search on top of a search, it was quite awkward. Maybe this will get cleaned up tomorrow with some sleep.

Awful part 1 rank on this one and bad for part 2

🀯 1

at first glance, I think we did exactly the same thing for the sides, searching the graph of [perimeter direction] nodes

Which is awful lol

I will replace this with a proper solution

Even part1 I was 4300th place, took me way too long.

I had this stupid idea of representing boundary points as floats.. and then wasted a lot of time there. https://github.com/erdos/advent-of-code/blob/master/2024/day12.clj

My solution works for every test input I can find, but too high on real input on part2 😞

@malaingreclement ugh, I hate days like this... I know this might sound awfully obvious, but - as someone else said - it's best to have correct solution on the first try πŸ˜›

hmmm, my part 1 works for all three examples, but too low for the real input

@erdos I represented mine as rationals

wonder if I'm missing something in my perimeter calculation

(defn perimeter [region]
  (count
   (reduce (fn [s position]
             (into s (keep (fn [delta]
                             (let [neighbor (mapv + position delta)]
                               (when-not (contains? region neighbor)
                                 (mapv + neighbor (mapv (partial * 1/2) delta)))))
                           deltas)))
           #{}
           region)))

My idea was to store fence as a pair of fields in->out (this helped me to avoid crossed fence case eventually). https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2024/day12.clj

@felipecortezfi your neighbor is a vector and you call contains? on this vector (not elements of it). Is it right? Maybe you wanted to filter neighbors?

think it's right. region is #{[1 2] [2 2]}, I want to see if e.g. [2 2] + [-1 0] is a position in the region

Ah, ok, got it. It's just a vector adding.

Is it a safe assumption that every letter is its own unique region? It appears that the input reuses letter for unrelated regions.

@vincenz.chianese no! the X O example shows that

> Plants of the same type can appear in multiple separate regions

think I found my issue. I'm forgetting to detect some regions

Oh ok, it's more of a plant type

"corner counting" for part two https://gist.github.com/DeLaGuardo/b6e073a9551290fe8683fd688d095b38

πŸ‘ 1
πŸ‘πŸ» 1

I used a similar trick to last year's "squeeze through the pipes" problem, e.g. expand the graph so it's easier to count the borders. then it's flood fill + counting for p1, flood fill + following the border for p2. I spent a bunch of time on p2 trying to follow the border without tracking an explicit direction, which got me very close (passed on all examples) but I had to rewrite it. https://github.com/tildedave/advent-of-code/blob/main/src/advent2024/day12.clj I kind of wonder if for p1 perimeter you could just count cells that are NSEW adjacent to something with a different letter. (haven't checked reddit yet)

corner counting is quite clever.

Phew, I finally managed to get it done.

πŸ™Œ 1

(defn perimeter [region]
  (count
   (reduce (fn [s position]
             (into s (keep (fn [delta]
                             (let [neighbor (mapv + position delta)]
                               (when-not (contains? region neighbor)
                                 (mapv + neighbor (mapv (partial * 1/2) delta)))))
                           deltas)))
           #{}
           region)))
duh. completely wrong. (mapv + neighbor (mapv (partial * 1/2) delta) -> (mapv + position (mapv (partial * 1/4) delta)

got both parts!

how does one create collapsible code blocks aside from dragging files in again? not very clear from the slack interface

FINALLY

πŸ‘ 1
πŸ‘πŸ» 1

@doppiaelle1999 I don't drag the files. have to copy the contents, go to the bottom left corner and click the plus, text snippet

1

@doppiaelle1999 shift+ctrl+enter or click on the + on the bottom left and click on "create snippet"

πŸ‘ 1

It took me a decade and I had to go sleep in between but I'm finally done ><

proud of my little clojure.lang.Rational trick today

My solution is... kinda awful? I walk the outeredge and remember the coordinates of the void on the left, to then generate all the neighbors of the current region. Remove the outer edge from that and bam, got the islands.

It's a bit stupid imho, but it works, so it's not stupid.

This is so bad it's almost funny.

It doesn't matter, what matters is you nailed it!

1
3

The corner counting never occurred to me due to using graph searches as a golden hammer from the start, so part 2 is (especially) fugly

Here’s today’s and I got tree-seq in there: https://github.com/bhauman/adv2024/blob/main/src/adv2024/day12/sol.clj

πŸŽ„ 2

Second time I see you using tree-seq. I should learn to use it, it looks fun.

πŸ‘ 1

Conrer counting! Well that would have been nice to know. πŸ˜‚ Now I have to give it a try.

yeah, corner counting would be much faster to implement than mine: https://github.com/vollcheck/aoc/blob/master/src/y24/day12.clj I'm grouping boundaries by the direction they look to and then by x or y axis + checking if they are contiguous

πŸ‘ 1

Actually, after trying it, I don’t know that counting corners is significantly easier in terms of code, it might be conceptually easier????

corner counting since first solution hit both OOM and garbage collector walls :) not pretty. "Elapsed time: 111.823166 msecs" total

Okay I agree, maybe corner counting isn’t that easy

I counted corners. busy with work today, I think I can tighten this up.

Excited to see the simpler ways everyone solved part 2, mine really got out of hand πŸ˜… https://github.com/alexlapp/aoc_clojure/blob/main/src/advent_of_code/2024/day12.clj#L62 I found regions in part 1 by creating sets of [x y] coordinates where they shared edges. I found sides by looking at each cell and counting the which of the 4 sides did not touch other cells in the region. For part 2, I take the set of coordinates that represents a region, split it into rows, split each row into blocks (for cases where the shape "touches" a column in multiple sections), and then map those blocks into values of either :exposed or :covered if there is a block above them, then partition-by those values, filter out the covered sections, and count what's left. Doing the partition-by organizes these into sets of shared sides. Then I do the same for the row looking at exposed or covered for below, then split the region into columns and do the same for each column looking to the left and right.

alright so they decide in regards to A the highlighted part has 4 sides instead of 2. what a bummer for me.

Also don't forget : if one of those B were a C, the calculation for A would stay the same (the total would change, ofc, but it doesn't change the number of sides from A 's point of view).

thought i found an elegant way to solve it until only 4/5 pass

for part1 perimeter: the regions of garden plots are determined first. within each region, i map each garden plot [y x] to 4 edges in this form [y x y+1 x] [y x y x+1] [y+1 x y+1 x+1] [y x+1 y+1 x+1] then do a freq on the collections of all edges, and keep only those with count equals 1 then it's the perimeter

for part2 i try to build on top of part1 based on the 4 tuple form edges and unfortunately it fails for that particular case. looks like i need to walk the border garden plot. 😞

Godammit, the problem warned me about inside fencing and I still forgot -_-

3

This one really got me too. I'm still stuck πŸ˜…

So I don't see any, but maybe I'm wrong. Can someone spoil this for me: is there deeper nesting than one level in the real input ?

can't see any in mine tbh

Found my bug. Didn't account for co-linear nested inputs. Like

AAAA
ABCA
AAAA

we're back at the top of the hour!