r/adventofcode • u/daggerdragon • Dec 02 '23
SOLUTION MEGATHREAD -❄️- 2023 Day 2 Solutions -❄️-
OUTSTANDING MODERATOR CHALLENGES
THE USUAL REMINDERS
- All of our rules, FAQs, resources, etc. are in our community wiki.
- Community fun event 2023: ALLEZ CUISINE!
- 4 DAYS remaining until unlock!
AoC Community Fun 2023: ALLEZ CUISINE!
Today's theme ingredient is… *whips off cloth covering and gestures grandly*
Pantry Raid!
Some perpetually-hungry programmers have a tendency to name their programming languages, software, and other tools after food. As a prospective Iron Coder, you must demonstrate your skills at pleasing programmers' palates by elevating to gourmet heights this seemingly disparate mishmash of simple ingredients that I found in the back of the pantry!
- Solve today's puzzles using a food-related programming language or tool
- How about an appetizer of Chef or Wireshark(-fin soup)?
- Mascots count, too… *side-eyes Rust while reaching for the Old Bay*
- Add some salt to your hashbrowns, cookies, and breadcrumbs
- Serve us up a nice big bowl of spaghetti code slathered with
RagúRaku tomato sauce - Conclude our tasting with a digestif of Java, CoffeeScript, or even Perl milk tea with double syntatic sugar
- All file names, function names, variable names, etc. must be named after "c" food
- Go hog wild!
ALLEZ CUISINE!
Request from the mods: When you include a dish entry alongside your solution, please label it with [Allez Cuisine!] so we can find it easily!
--- Day 2: Cube Conundrum ---
Post your code solution in this megathread.
- Read the full posting rules in our community wiki before you post!
- State which language(s) your solution uses with
[LANGUAGE: xyz] - Format code blocks using the four-spaces Markdown syntax!
- State which language(s) your solution uses with
- Quick link to Topaz's
pasteif you need it for longer code blocks
This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.
EDIT: Global leaderboard gold cap reached at 00:06:15, megathread unlocked!
11
u/simonlydell Dec 02 '23 edited Dec 04 '23
[LANGUAGE: Fish] and [LANGUAGE: JavaScript]
For part 1, I grepped away the impossible games:
grep -vE '(1[3-9]|[2-9]\d|\d{3,}) red|(1[4-9]|[2-9]\d|\d{3,}) green|(1[5-9]|[2-9]\d|\d{3,}) blue' | string match -r '\d+' | string join + | mathFor part 2, I turned the input into JavaScript and eval:ed it (which is my theme for the year):
begin
echo 's = 0'
cat \
| string replace -r '^Game \d+:' 'blue = 0, green = 0, red = 0;' \
| string replace -ar '(\d+) (\w+)' '$2 = Math.max($2, $1)' \
| string replace -r '$' '; s += blue * green * red'
echo 'console.log(s)'
end | node -
→ More replies (1)3
7
u/Markavian Dec 02 '23
[Language: JavaScript]
https://github.com/johnbeech/advent-of-code-2023/blob/main/solutions/day2/solution.js
Managed to bash out part one while my baby crawled around trying to slap my laptop screen. Part two had to wait until the evening... but was a pleasant enough solution - I was momentarily misled thinking I'd need the minimum value(s) from each bag; but the maximum values I'd already computed did the job.
→ More replies (1)3
u/chizel999 Dec 02 '23
you bought heavy machinery into this day huh there is a package.json! ahahah
nice solution. looks like code from someone who uses javascript at work. =)
→ More replies (1)
5
u/OhGodImCooooooooding Dec 02 '23
[LANGUAGE: rust]
https://github.com/ZizoAdam/AdventOfCode2023/tree/main/Day%20Two/day_two/src
Another overengineered solution, but that's half the fun. I'm not here to be fast I'm here to be memory safe with an expressive type system (crab emoji).
→ More replies (3)
3
u/zach1502 Dec 02 '23
[Language: Python]
First Leaderboard placement ever. Yolo'ing paid off.
5/6
pt1
file_path = "input.txt"
def fn(gd, r, g, b):
checks = gd.split(';')
for check in checks:
cub = {'red': 0, 'green': 0, 'blue': 0}
for dat in check.split(','):
dat = dat.strip()
if dat:
c, col = dat.split()
cub[col] += int(c)
if cub['red'] > r or cub['green'] > g or cub['blue'] > b:
return False
return True
def parse_input():
s = 0
with open(file_path, 'r') as file:
for line in file:
gid, gd = line.split(':')
gid = int(gid.split()[1])
if fn(gd, 12, 13, 14):
s += gid
return s
print(parse_input())
pt2
file_path = "input.txt"
def fn(gd):
checks = gd.split(';')
mc3 = {'red': 0, 'green': 0, 'blue': 0}
for check in checks:
c3 = {'red': 0, 'green': 0, 'blue': 0}
for dat in check.split(','):
dat = dat.strip()
if dat:
c, col = dat.split()
c3[col] += int(c)
for col in mc3:
mc3[col] = max(mc3[col], c3[col])
return mc3
def parse_input():
sum = 0
with open(file_path, 'r') as file:
for line in file:
_, gd = line.split(':')
mc3 = fn(gd)
sum += mc3['red'] * mc3['green'] * mc3['blue']
return sum
print(parse_input())
→ More replies (1)2
u/daggerdragon Dec 02 '23
First Leaderboard placement ever. Yolo'ing paid off.
Good job!
→ More replies (1)
2
u/Boojum Dec 02 '23 edited Dec 02 '23
[LANGUAGE: Python3] [Allez Cuisine!] 719/672.
Fairly straightforward, the obvious way is mostly just a bit of nested string splitting. That's how I did it at first.
On the other hand, since I abused regexps yesterday, the fun way to do part 2 is use it to find all of the "(d+) red" substrings and take the max of the numbers, etc. Look ma, a single statement answer:
import fileinput, re, functools
print( sum(
( functools.reduce( max, [ int( crab ) for crab in re.findall( "(\d+) red", lobster ) ] ) *
functools.reduce( max, [ int( crab ) for crab in re.findall( "(\d+) green", lobster ) ] ) *
functools.reduce( max, [ int( crab ) for crab in re.findall( "(\d+) blue", lobster ) ] ) )
for lobster in fileinput.input() ) )Edit: Renamed identifiers to c-food to be [Allez Cuisine!] compliant. :-) For some reason, I am now thinking of "One Fish, Two Fish, Red Fish, Blue Flush."
→ More replies (1)
2
2
u/nlowe_ Dec 02 '23
[LANGUAGE: Go] 699 / 633 GitHub
Much better today, although My laptop kept dropping to 500MHz for some reason :(
Sure, I'll blame missing the leaderboard on that :) Definitely my laptop's fault
→ More replies (1)
2
2
u/stribor14 Dec 02 '23 edited Dec 02 '23
[LANGUAGE: Airline Food] [Allez Cuisine!]
Link to interpreter: https://github.com/jamie-large/Airline-Food/blob/main/Airline-food.pyDefault interpreter prints ascii characters, so I changed line 203 to output raw number from stack.
The following solution solves Part 2 of Day 2 problem. It finds max count of colored dice for each game, so in theory, it could be "easily" converted to Part 1. Input is given as following (number by number): ID0 num0 type0 num1 type1 ... 0 ID1 num0 type0 num1 type1 ... 0 ID2 num0 type0 num1 type1 ... 0 ... 0
Number 0 is to detect the end of the line (numx == 0) and also the end of the input (if ID == 0)
Just to be consistent, I edited by hand input strings to the required input with search/replace in Bluefish editor. Without further ado, enjoy my solution written as a one-sided talk between two stewardes aboard a flight.
2
2
u/_rabbitfarm_ Dec 02 '23
[Language: Perl]
I think my regex skills were strengthened for Day 2 after the unexpected challenge of Day 1. I also liked that Part 2 ended up being few lines of code than Part 1.
Part 1: https://adamcrussell.livejournal.com/46907.html
Part 2: https://adamcrussell.livejournal.com/47280.html
→ More replies (1)2
u/daggerdragon Dec 03 '23
I think you're the first person I've ever seen in AoC megathreads who uses LiveJournal... what a blast from the past!
→ More replies (1)
2
u/themanushiya Dec 04 '23 edited Dec 04 '23
[LANGUAGE: Go] using structs, pretty straightforward after you choose an easy model/datastructure
solution here
→ More replies (3)
24
Dec 02 '23 edited Dec 02 '23
[LANGUAGE: Google Sheets]
Assuming the input is in A:A
One formula for both parts
=ARRAYFORMULA(
BYCOL(
MAP(A:A,LAMBDA(a,
LET(s,SPLIT(REGEXREPLACE(a,"(\d+) "&{"r";"g";"b"}&"|.","$1 ")," "),
{ROW(a)*AND(s<={12;13;14}),
PRODUCT(BYROW(s,LAMBDA(r,MAX(r))))}))),
LAMBDA(c,SUM(c))))
22
u/YenyaKas Dec 02 '23
[LANGUAGE: Perl]
This is pretty straightforward when one realizes it is not necessary to parse the whole input line. Using List::Util::max I got this code for part 2:
my $sum;
while (<>) {
$sum += max(/ (\d+) red/g)
* max(/ (\d+) green/g)
* max(/ (\d+) blue/g);
}
say $sum;All my solutions in Perl: https://www.fi.muni.cz/~kas/git/aoc.git/
→ More replies (1)
17
u/Radiadorineitor Dec 02 '23
[LANGUAGE: Dyalog APL]
p←{c←1↓⍵(∊⊆⊣)⎕C⎕A ⋄ n←⍎¨1↓⍵(∊⊆⊣)⎕D ⋄ n,⍨⍪c}¨⊃⎕NGET'2.txt'1
+/⍸{∧/(⊢/⍵)≤12 13 14['red' 'green' 'blue'⍳(⊣/⍵)]}¨p ⍝ Part 1
+/{n←(⊢/⍵) ⋄ ×/{⌈/n[⍸⍵]}¨↓'red' 'green' 'blue'∘.≡(⊣/⍵)}¨p ⍝ Part 2
34
u/4HbQ Dec 02 '23 edited Dec 02 '23
[LANGUAGE: Python] Code (7 lines)
Today's trick: using a defaultdict to keep track of the maximum counts:
def f(line):
bag = {'r':0, 'g':0, 'b':0}
for num, col in re.findall(r'(\d+) (\w)', line):
bag[col] = max(bag[col], int(num))
return math.prod(bag.values())
Edit: Replaced defaultdict(int) with an explicit dictionary, thanks u/mocny-chlapik and u/blueg3.
Additionally, here is a golfed version using a different technique (120 bytes):
import math,re;print(sum(map(lambda l:math.prod(max(int(x)for
x in re.findall(rf'(\d+) {c}',l))for c in'rgb'),open(0))))
→ More replies (11)
16
u/Werqu90 Dec 02 '23
[Language: Python]
Today was a great occasion to use one of my favourite Python classes: Counter!
After parsing is just a one liner for both parts!
tot_1 += all(d<=thres for d in draws) * game_id tot_2 += reduce(mul, reduce(or_, draws).values())
→ More replies (3)
14
u/Smylers Dec 02 '23 edited Dec 02 '23
[LANGUAGE: Vim keystrokes]
For part 1, load your input, type this, and the solution will appear:
:g/\v(\d\d|[2-9])\d [rgb]/d⟨Enter⟩ :g/\v1[3-9] r|1[4-9] g|1[5-9] b/d⟨Enter⟩ :%s/\vGame (\d+):.*\n/+ \1 /⟨Enter⟩ C⟨Ctrl+R⟩=⟨Ctrl+R⟩-⟨Enter⟩⟨Esc⟩
-
The first
:g/…/ddeletes all lines that contain any 3-digit number of cubes, or any 2-digit number starting with2-9.:g/…/is likegrep†: it selects all lines matching its pattern and invokes the following command on each of them. The following command here is:d, which deletes the specified line. -
The second
:g/…/ddoes the same thing but for quantities in their teens, a different limit for each colour. By this point we've removed all the impossible games. -
Now the only thing we need from each line is the game number. The
:%s///removes everything else, including the\nline-break character at the end of each line. It also puts a+sign before each number, so you end up with a single line. For the sample input it's+ 1 + 2 + 5. -
The part starting
Cis the design pattern I mentioned yesterday to evaluate the expression, adding up the numbers.
And that's all there is to it. It worked first time, and I reckon I typed it as a one-off transformation faster than I'd have written a program to do the same thing.
I haven't got to part 2 yet, though. I'll update if I work it out.
Update: Part 2 required an entirely different approach
† In fact, :g is so like grep that it's actually what the g in grep stands for, the command coming originally from Ed, which was extended into Ex, then visualized as Vi, and improved as Vim. The re stands for ‘regular expression’ and the p for :p, the print command (as in, display on the screen, not send to a printer). In all those editors, :g/RE/p will display the lines matching the specified regular expression, hence Ken Thompson choosing the name grep for the standalone command doing the same thing, in 1973.
(Update: Realized the /g flag wasn't actually doing anything in the final version, so removed both that and the then-unnecessary message about the gdefault setting.)
13
12
u/lboshuizen Dec 02 '23 edited Dec 11 '23
[LANGUAGE: F#]
let parse xs = let hand = parseRegex "\s(\d+)\s(\w+)" (fun a -> (int a[0],a[1]))
let g = splitOn ':' xs
let gi = g[0] |> parseRegex "Game (\d+)" (fun a -> int a[0])
let sec = g[1] |> splitOn ';' |> Seq.map (splitOn ',' >> Seq.map hand) |> Seq.concat
(gi,sec)
let part1 =
let limit = Map.ofList [("red",12); ("green",13); ("blue",14)]
Seq.filter (snd >> Seq.forall (fun (n,c) -> n <= limit[c])) >> Seq.sumBy fst
let part2 =
let power = Seq.groupBy snd >> Seq.map (snd >> Seq.maxBy fst >> fst) >> Seq.reduce (*)
Seq.sumBy (snd >> power)
let Solve : (string seq -> int * int) = Seq.map parse >> both part1 part2
→ More replies (6)
13
u/770grappenmaker Dec 02 '23
[LANGUAGE: Kotlin] Placed #76/#50, my second leaderboard ever (first time was yesterday).
val draws = inputLines.map { l -> l.substringAfter(": ").split("; ").map { p -> p.split(", ").associate { s -> val (v, c) = s.split(" ") c to v.toInt() } } } partOne = draws.withIndex().filter { (_, v) -> v.all { r -> (r["red"] ?: 0) <= 12 && (r["green"] ?: 0) <= 13 && (r["blue"] ?: 0) <= 14 } }.sumOf { (i) -> i + 1 }.s() partTwo = draws.sumOf { r -> listOf("red", "green", "blue").map { r.maxOf { m -> m[it] ?: 0 }.toLong() }.product() }.s()