this post was submitted on 18 Dec 2024
17 points (94.7% liked)

Advent Of Code

995 readers
4 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

I thought about it for 15 mins, but couldn't think of any mathematical tricks. I thought of lots of minor tricks, like comparing the number to the result and not adding any more multiplications if it's over, things that would cut 10%-20% here and there, but nothing which fundamentally changes big O running time.

For reference, here's my solution for part 2 in smalltalk. I just generated every possible permutation and tested it. Part 1 is similar, mainly I just used bit magic to avoid generating permutations.

(even if you haven't used it, smalltalk is fairly readable, everything is left to right, except in parens)

day7p2: in
	| input | 
	
	input := in lines collect: [ :l | (l splitOn: '\:|\s' asRegex) reject: #isEmpty thenCollect: #asInteger ].
	
	^ (input select: [ :line |
		(#(1 2 3) permutationsWithRepetitionsOfSize: line size - 2) 
			anySatisfy: [ :num | (self d7addmulcat: line ops: num) = (line at: 1)]
	]) sum: #first.
d7addmulcat: nums ops: ops
	| final |
	
	final := nums at: 2.
	ops withIndexDo: [ :op :i |
		op = 1 ifTrue: [ final := final * (nums at: i + 2) ].
		op = 2 ifTrue: [ final := final + (nums at: i + 2) ].
		op = 3 ifTrue: [ final := (final asString, (nums at: i+2) asString) asInteger ]
	].

	^ final
you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 1 points 2 weeks ago (1 children)

The point is to prune away search space as early as possible. If the rightmost operand is 5, say, and the answer ends in a 7, then the rightmost operator cannot be anything other than plus. This is a deduction you can't make going left to right. Remember that in this problem the usual order of operations does not apply.

[–] [email protected] 2 points 2 weeks ago (1 children)

I actually did this. It did not end up being any faster than the brute-force solution since it seems to only catch the easy cases

[–] [email protected] 1 points 2 weeks ago* (last edited 2 weeks ago)

Perhaps your implementation continues the search longer than necessary? I got curious and tried it myself. Runtime went from 0.599s (brute force) to 0.017s.