I don't like day 3. it's mentally draining
Day 03 - Solutions
I learned how to use flags on regexes in clojurescript, it was ok after that and @borkdude’s tips related to javascript object keys.
@mynomoto excellent, added it https://github.com/squint-cljs/squint/blob/main/examples/aoc/solutions.md!
https://gist.github.com/coadan/25b0e8b68c1d5acf87114c9bf4ad942f
part 1 in plain clojure with hyperfiddle rcf tests https://gist.github.com/corasaurus-hex/9cbe6a0190f1dce0acbe79ccfdcc9593
Not sure if I used the best datastructure but it worked out quite well
I struggled a bit with scanning the input. Seeing where I went overboard when looking at your solution, @alpox
@pez I struggled too. I rewrote the parsing multiple times 😄
A bit late to the party but I'm pretty happy with how this turned out. Calculation done in a single pass transduction, and it's my first time using iteration too. https://github.com/imrekoszo/advent-of-clj/blob/master/src/imrekoszo/advent/y23/day3.clj
Mine was actually quite clean: https://gitlab.com/mauricioszabo/advent-of-code-2023-clj/-/blob/master/src/advent_2023_clj/day03.clj?ref_type=heads
I'm super glad I wasn't the only one thinking, "Jeeze this is day THREE?" https://github.com/potetm/advent-of-code/blob/master/src/advent_2023/day_3.clj
Yesterday was super busy with christmas festivities, but finally got round to it
Looks like me and @ghadi went similar ways. Always a good sign :D
I got a bit stopped on part-1 because I had missed to collect the scanned digits as a number if the number was the last thing on the line. But when that was fixed, part 2 was an easy adaption. Probably not the most efficient solution, though. Takes about a second for my input for part 1 and half a second for part 2.
Goddamnit, I definitely chose the wrong approach in part 1 given what part 2 turns out to be about; see this REPL output:
clj꞉clj-playground.aoc-2023.day3꞉>
({:val [\4 \6 \7], :coords [[0 0] [0 1] [0 2]], :neighbours ((\*) () ())}
{:val [\1 \1 \4], :coords [[0 5] [0 6] [0 7]], :neighbours (() () ())}
{:val [\3 \5], :coords [[2 2] [2 3]], :neighbours ((\*) (\*))}@m.reinhard Maybe it is not too hard to do the “reverse” matching?
@borkdude I can’t figure out how to start an aoc cherry playground.
@pez Have you tried this link? https://squint-cljs.github.io/cherry/?boilerplate=https://gist.githubusercontent.com/borkdude/cf94b492d948f7f418aa81ba54f428ff/raw/3e871513ab6f2462841f75fc99668f841f33dabb/aoc_ui.cljs&src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4CgooZGVmIGlucHV0ICgtPj4gKGpzLWF3YWl0IChmZXRjaC1pbnB1dCAyMDIyIDEpKQogICAgICAgICAgICAgI19zcHkKICAgICAgICAgICAgIHN0ci9zcGxpdC1saW5lcwogICAgICAgICAgICAgKG1hcHYgcGFyc2UtbG9uZykpKQoKKGRlZm4gcGFydC0xCiAgW10KICAoLT4%2BIGlucHV0CiAgICAocGFydGl0aW9uLWJ5IG5pbD8pCiAgICAodGFrZS1udGggMikKICAgIChtYXAgIyhhcHBseSArICUpKQogICAgKGFwcGx5IG1heCkpKQoKKGRlZm4gcGFydC0yCiAgW10KICAoLT4%2BIGlucHV0CiAgICAocGFydGl0aW9uLWJ5IG5pbD8pCiAgICAodGFrZS1udGggMikKICAgIChtYXAgIyhhcHBseSArICUpKQogICAgKHNvcnQtYnkgLSkKICAgICh0YWtlIDMpCiAgICAoYXBwbHkgKykpKQoKKHRpbWUgKHBhcnQtMSkpCiNfKHRpbWUgKHBhcnQtMikp&repl=true
What isn't working for you?
I had no idea where to find the link. 😃
🎉
I added a bookmark to this channel.
I've gone through several iterations of the playground, but the most recent version can always be found via this redirect page:
https://squint-cljs.github.io/squint/examples/aoc/index.html
and then change /squint/ to /cherry/ for the cherry playground
@pez yeah, you're probably right re: the reverse matching. Find all the *s, identify the touching numbers, filter for those * touched by two nums, and then do the maths.
maybe I should also make a redirect page for cherry directly
Already feel tired of seeing an "adjacent coordinate" puzzle in AoC again, so I'm just going to steal some of your solutions to test-drive squint :)
Also quite a mess, have to clean up a bit later 🙂 https://github.com/jantorestolsvik/advent-of-code-2023/blob/main/src/day03.clj
I stored the gear coordinates by concatenating x and y coordinates. Ofc there was an overlapping index then, so had to add a “-” in between
Apparently the grid is created with some assumptions that made the logic simpler, so was able to solve both parts with same algo basically: https://github.com/caseneuve/aoc2023/blob/master/day03/solution.clj
Hi all! I am a bit bored by parsing this year. Didn’t want initially post my solutions, but here we go. Maybe it’ll help someone https://github.com/zelark/AoC/blob/master/src/zelark/aoc_2023/day_03.clj
Wrote a recursive parser that handled conjoining the nums from the start, so both parts were just fancy transductions: https://github.com/alexalemi/advent/blob/main/2023/clojure/p03.clj doesn't feel the cleanest.
@russell.matney https://squint-cljs.github.io/cherry/?boilerplate=https%3A%2F%2Fgist.githubusercontent.com%2Fborkdude%2Fcf94b492d948f7f418aa81ba54f428ff%2Fraw%2F3e871513ab6f2462841f75fc99668f841f33dabb%2Faoc_ui.cljs&repl=true&src=OzsgSGVscGVyIGZ1bmN0aW9uczoKOzsgKGZldGNoLWlucHV0IHllYXIgZGF5KSAtIGdldCBBT0MgaW5wdXQKOzsgKGFwcGVuZCBzdHIpIC0gYXBwZW5kIHN0ciB0byBET00KOzsgKHNweSB4KSAtIGxvZyB4IHRvIGNvbnNvbGUgYW5kIHJldHVybiB4CgooZGVmIGlucHV0ICgtPj4gKGpzLWF3YWl0IChmZXRjaC1pbnB1dCAyMDIzIDMpKQogICAgICAgICAgICAgc3RyL3NwbGl0LWxpbmVzKSkKCihkZWZuIGRpZ2l0PyBbeF0KICAoI3tcMSBcMiBcMyBcNCBcNSBcNiBcNyBcOCBcOSBcMH0geCkpCgooZGVmbiAtPmdyaWQKICAoW3Jhd10gKC0%2BZ3JpZCBuaWwgcmF3KSkKICAoW3ByZWQgcmF3XQogICAoLT4%2BIHJhdwogICAgICAgIChtYXAtaW5kZXhlZAogICAgICAgICAgKGZuIFt5IHJvd10KICAgICAgICAgICAgKC0%2BPiByb3cgKG1hcC1pbmRleGVkCiAgICAgICAgICAgICAgICAgICAgICAgKGZuIFt4IGNoYXJdCiAgICAgICAgICAgICAgICAgICAgICAgICAoaWYgcHJlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAod2hlbiAocHJlZCBjaGFyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtbeCB5XSBjaGFyXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgW1t4IHldIGNoYXJdKSkpCiAgICAgICAgICAgICAgICAgKGZpbHRlciBzZXEpCiAgICAgICAgICAgICAgICAgKGludG8gW10pKSkpCiAgICAgICAgKGZpbHRlciBzZXEpCiAgICAgICAgKGludG8gW10pCiAgICAgICAgKGFwcGx5IGNvbmNhdCkKICAgICAgICAoaW50byB7fSkpKSkKCihkZWZuIHBhcnQ%2FIFtjaGFyXQogIChub3QgKG9yICg9IFwuIGNoYXIpIChkaWdpdD8gY2hhcikpKSkKCihkZWZuIC0%2BcGFydC1sb2NzIFtyYXddCiAgKC0%2BZ3JpZCBwYXJ0PyByYXcpKQoKKGNvbW1lbnQKICAoLT5wYXJ0LWxvY3MgaW5wdXQpCiAgKC0%2BZ3JpZCBpbnB1dCkKCiAgKC0%2BPiAiNDUuLiouNCIgKG1hcCAoZm4gW2NoYXJdIChkaWdpdD8gY2hhcikpKSkpCgooZGVmbiBuZWlnaGJvcnMgW1t4IHldXQogICN7W3ggKGluYyB5KV0KICAgIFt4IChkZWMgeSldCiAgICBbKGluYyB4KSB5XQogICAgWyhkZWMgeCkgeV0KICAgIFsoaW5jIHgpIChpbmMgeSldCiAgICBbKGRlYyB4KSAoZGVjIHkpXQogICAgWyhkZWMgeCkgKGluYyB5KV0KICAgIFsoaW5jIHgpIChkZWMgeSldfSkKCihkZWZuIHgtbnVtLW5laWdoYm9ycyBbZ3JpZCBbeCB5XV0KICAobGV0IFstPngtbmJycwogICAgICAgIChmbiBbLT54XQogICAgICAgICAgKGxvb3AgW25ldy1jb29yZCBbKC0%2BeCB4KSB5XSBuYnJzIFtdXQogICAgICAgICAgICAoY29uZAogICAgICAgICAgICAgIChuaWw%2FIChncmlkIG5ldy1jb29yZCkpIG5icnMKICAgICAgICAgICAgICAoZGlnaXQ%2FIChncmlkIG5ldy1jb29yZCkpCiAgICAgICAgICAgICAgKHJlY3VyIFsoLT4gKGZpcnN0IG5ldy1jb29yZCkgLT54KSB5XSAoY29uY2F0IG5icnMgW25ldy1jb29yZF0pKQogICAgICAgICAgICAgIDplbHNlICAgICAgICAgICAgICAgICAgIG5icnMpKSkKICAgICAgICBsZWZ0LW5icnMgICgtPngtbmJycyBkZWMpCiAgICAgICAgcmlnaHQtbmJycyAoLT54LW5icnMgaW5jKV0KICAgIChjb25jYXQgKHJldmVyc2UgbGVmdC1uYnJzKSBbW3ggeV1dIHJpZ2h0LW5icnMpKSkKCihjb21tZW50CiAgKHgtbnVtLW5laWdoYm9ycyAoLT5ncmlkIGlucHV0KSBbMyAyXSkKICAoeC1udW0tbmVpZ2hib3JzICgtPmdyaWQgaW5wdXQpIFsyIDJdKQogICh4LW51bS1uZWlnaGJvcnMgKC0%2BZ3JpZCBpbnB1dCkgWzAgMF0pCiAgKQoKKGRlZm4gY29vcmQtPm51bWJlciBbZ3JpZCBjb29yZF0KICAobGV0IFtudW0tY29vcmRzICh4LW51bS1uZWlnaGJvcnMgZ3JpZCBjb29yZCldCiAgICBbKGZpcnN0IG51bS1jb29yZHMpCiAgICAgKC0%2BPiBudW0tY29vcmRzCiAgICAgICAgICAobWFwIGdyaWQpCiAgICAgICAgICAoYXBwbHkgc3RyKQogICAgICAgICAgKHBhcnNlLWxvbmcpKV0pKQoKKGNvbW1lbnQKICAoY29vcmQtPm51bWJlciAoLT5ncmlkIGlucHV0KSBbMiAyXSkKICAoY29vcmQtPm51bWJlciAoLT5ncmlkIGlucHV0KSBbMCAwXSkKICApCgoKKGRlZm4gcGFydC1udW1iZXJzCiAgKFtyYXddIChwYXJ0LW51bWJlcnMgbmlsIHJhdykpCiAgKFtvcHRzIHJhd10KICAgKGxldCBbZ3JpZCAgICAgICgtPmdyaWQgcmF3KQogICAgICAgICBwYXJ0LWxvY3MgKC0%2BcGFydC1sb2NzIHJhdyldCiAgICAgOzsgc3ltYm9scy0%2BbmVpZ2hib3ItZGlnaXRzCiAgICAgKGNvbmQtPj4gcGFydC1sb2NzCiAgICAgICB0cnVlCiAgICAgICAobWFwIChmbiBbW2Nvb3JkIHN5bV1dCiAgICAgICAgICAgICAgW3N5bQogICAgICAgICAgICAgICAobGV0IFtuYnJzIChuZWlnaGJvcnMgY29vcmQpXQogICAgICAgICAgICAgICAgICgtPj4gbmJycwogICAgICAgICAgICAgICAgICAgICAgKGZpbHRlciAoZm4gW25icl0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGV0IFtjaGFyIChncmlkIG5icildCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGlnaXQ%2FIGNoYXIpKSkpCiAgICAgICAgICAgICAgICAgICAgICAobWFwIChmbiBbbmJyXSBbbmJyIChncmlkIG5icildKSkpKV0pKQoKICAgICAgICg6c3ltYm9sIG9wdHMpIChmaWx0ZXIgKGZuIFtbc3ltIF9uYnJzXV0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoI3soOnN5bWJvbCBvcHRzKX0gc3ltKSkpCgogICAgICAgdHJ1ZQogICAgICAgKG1hcCAoZm4gW1tfc3ltIG5icnNdXQogICAgICAgICAgICAgICgtPj4gbmJycwogICAgICAgICAgICAgICAgICAgKG1hcCAoZm4gW1tjb29yZCBfZGlnaXRdXQogICAgICAgICAgICAgICAgICAgICAgICAgIChjb29yZC0%2BbnVtYmVyIGdyaWQgY29vcmQpKSkKICAgICAgICAgICAgICAgICAgIChpbnRvIHt9KSkpKQoKICAgICAgICg6cGFydC1jb3VudCBvcHRzKQogICAgICAgKGZpbHRlciAoZm4gW3hzXQogICAgICAgICAgICAgICAgICg9ICg6cGFydC1jb3VudCBvcHRzKSAoY291bnQgeHMpKSkpKSkpKQoKKGNvbW1lbnQKICA7OyBwYXJ0IDEKICAoLT4%2BCiAgICAocGFydC1udW1iZXJzIGlucHV0KQogICAgKG1hcCB2YWxzKQogICAgKGFwcGx5IGNvbmNhdCkKICAgIChyZWR1Y2UgKykpCgogIDs7IHBhcnQgMgogICgtPj4KICAgIGlucHV0CiAgICAocGFydC1udW1iZXJzCiAgICAgIHs6c3ltYm9sICAgICBcKgogICAgICAgOnBhcnQtY291bnQgMn0pCiAgICAobWFwIHZhbHMpCiAgICAobWFwICMoYXBwbHkgKiAlKSkKICAgIChyZWR1Y2UgKykpICAKICAp
Code much more complicated than it should be, but everything passed on the first try (rather rare on my side!) : https://github.com/arnaudgeiser/advent-of-code/blob/master/2023/clojure/src/advent_of_code/day3.clj
Always happy to use (almost) the same code and processed data for both parts. https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2023/day03.clj
my day3 https://gist.github.com/ghadishayban/c09b298235f73cb56e223f46c53873e5
https://github.com/ChrisBlom/advent-of-code/blob/master/src/adventofcode/2023/day03.clj#L1
Didn't want to do neighbor lookup in the grid, so decided to split out location of all operations & numbers beforehand: https://github.com/skazhy/advent/blob/master/src/advent/2023/day3.clj
not happy with anything here, but it works! https://github.com/FelipeCortez/advent-of-code/blob/master/2023/03.clj
@ghadi TIL Java’s matcher supports indices. nice!
Got myself in a bit of a tangle today wrt how best to parse the input. But the rest was smooth once that piece fell into place... :)))
; ...
(defn parse
"Returns a map of the form
{:n+coords [<int> #{<coord> ...} ...]
:x+y->sym {<coord> <symbol char>, ...}}
where :n+coords represents the multiple coordinates of each number in the grid, and :x+y->sym the coordinates of
'symbol' characters."
[input]
(let [rows (map-indexed (fn [y row] (parse-row row y)) input)]
; combine data across rows
{:n+coords (vec (mapcat :n+coords rows))
:x+y->sym (into {} (mapcat :x+y->sym rows))}))
; ...
https://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2023/d3.cljMaybe only interesting thing is my (partition-by token line)to group the integers together.
https://github.com/tschady/advent-of-code/blob/main/src/aoc/2023/d03.clj
I just don’t even know where to begin…
I look at problems like this and think “why?” I mean it’s so far from anything I’ve ever had to do professionally in 20+ years…. I WANT to be good at this stuff, but honestly it doesn’t feel as though I am learning something so much as overcoming an unlikely obstacle… Please convince me I am wrong…
Depends on your interests but conceviably similar things you might think about if you made a game
Or analyse raster images in some specific way
> I just don’t even know where to begin… me too. at first i thought the input was a hexdump. spent 12 hrs on part 1, and looking at part 2 now makes me want to stop and continue tmr
(Also bears mentioning that I ran out of gas - heating runs on propane - on Friday morning and despite being into my fifth week of waiting for a delivery Calor keep telling me they will deliver as soon as they can, so my house is freezing and I am grouchy)
I feel you @hi897 - yesterday’s two puzzles took me far too long, admittedly my attention was fractured by my kids and making dinner and watching a movie with my kids instead of finishing it off as quickly as I could, but the most annoying thing about it was how much hassle I had to go through to shape the data to make the calculations required easier. This one (day #3) feels like another “please spend forever parsing simplistic fixed width data based on arbitrary constraints in order to solve an improbable. problem…
@larzeitlin - I guess my point is that I would feel less futility in the scenario if I was going to get some reusable code that would actually help with a regular workload of image / raster analysis or similar. If I had more time and more motivation I would put the input into something like TileDB and have the power of that engine to do the searches on the sparse arrays (that’s what they are, the periods are just nils by another name), instead of trying to figure out how to write my own adjacency algorithm, but I suppose that’s the point, right?
Yeah fair. Often these kinds of problems are heavy on the "get the data into the right shape" which can be fiddly and error-prone
After you get your data into the right shape and solve part 1, part 2 comes in and...
can we skip days? I really don't like this one
my opinion of elves changed forever
new to Clojure, but fought through it, finally done. I haven't chosen a good structure to store data, and I ended up with quite bloated code. it's quite inspiring to see other approaches, always learning something new https://github.com/mkrcah/advent-of-code/blob/main/src/dev_03.clj
Did most of y’all do your adjacency stuff on the grid? I just made a big map of coordinates to part ids/symbols, adjacency was just “is an adjacent coordinate in the map” https://github.com/maxrothman/advent-of-code/blob/main/2023/clj2023/src/clj2023/day3.clj
I suppose that there's no "wrong" way to approach advent of code - it can really be whatever you want it to be. But, looking at advent of code for "real world" coding challenges seems ... unproductive. I think the whole point is that this isn't stuff you'd be directly writing on a day to day basis. However. most of these problems come down • analysis of a problem (understanding and solving the problem) • choosing an appropriate data representation • coding an algorithm to manipulate the data and solve the problem In that sense, maybe it's pretty good training after all...
You do make a valid point @norman - I think I am just frustrated and cold… Will come back to day 3
It was definitely a bit much for day 3, but looking at the problem with fresh eyes I actually kind of like it. But just wait, at some point we're going to get a problem where you need some stupid math trick to solve and I'll be the one here complaining 🙂
@max.r.rothman I'm a bit of a Clojure noob, so I'm just trying to make sure I understand... Does this part rely on two symbols never being adjacent? https://github.com/maxrothman/advent-of-code/blob/main/2023/clj2023/src/clj2023/day3.clj#L49-L50
That’s just pulling the numbers out of the match maps and adding them up. My pt1 solution does rely on symbols not being adjacent to each other because I don’t filter the adjacent-to-symbol things, though that filter would be easy to add after L47. The problem in pt2 isn’t well-defined for multiple adjacent symbols, so that’s a decent hint that it’s not going to happen.
https://github.com/samcf/advent-of-code/blob/main/2023-03-gear-ratios.clj Just a straight loop through a concatenated version of the board, returning a vector of [number, indices of neighboring parts] which can be repurposed for both parts. Runs in about 20ms on babashka
Ok, cool. Just wanted to make sure I understood what the shape of the hashmap was.
The shape of the the match maps is https://github.com/maxrothman/advent-of-code/blob/main/2023/clj2023/src/clj2023/day3.clj#L22-L24, parsed spits out a map of matches and I use it it on https://github.com/maxrothman/advent-of-code/blob/main/2023/clj2023/src/clj2023/day3.clj#L47 to turn coordinates into matches
I couldn’t help myself and did a https://github.com/wevre/advent-of-code/blob/master/src/advent_of_code/2023/day_03_v2.clj. I haven’t perused this thread yet but I’m sure most people did something more similar to my second version than my first. I wrote up https://github.com/wevre/advent-of-code/blob/68de28244ad560a5c119348bb54122fd6db17087/notes/notes-aoc2023.txt#L55 about my design choices.
ugh, the second part got a bit messy https://github.com/rgm/experiments/commit/72162fa80a1a85f18521599638a5e438d44487f0
https://gitlab.com/maximoburrito/advent2023/-/blob/main/src/day03/main.clj?ref_type=heads day 3 is very early in aoc to for such messy code...
crazy one! definitely feel like they're starting harder this year, tho i believe they try to assign harder problems on weekends vs weekdays https://github.com/russmatney/advent-of-code/blob/master/src/_2023/_03/core.clj
I might still do some tweaking to this, I sort of “over-built” my data maps and can probably streamline them a little bit. https://github.com/wevre/advent-of-code/blob/master/src/advent_of_code/2023/day_03.clj
I added some commentary to my two hairiest functions.
How can I solve this using regex 🤔
@ben.sless I think re-matcher might be of help for that.
I can stagger the lines then do something like
(let [m (re-matcher #"((...)?(.\d.)+(...)?)"
(str/join (map str/join (map vector
"..2......."
"467..114.."
"...*......"))))]
[(re-find m)
(re-find m)
(re-find m)])
then in each group look for one containing a symbol which marks it as a part, and extract the numbers from every 3rd index starting from the second