This commit is contained in:
Beatrice Szilvasy 2024-12-22 07:08:57 +00:00
parent bf7f2fede6
commit beb0f4a8e7
3 changed files with 70 additions and 31 deletions

View file

@ -1,3 +1,9 @@
"Represents a set of minimum-length strings, along with the length and
cardinality. These can be concatenated and unioned. Maintaining the
anything other than the length is pointless, since the problem asks
for only the length of the solution, not the number of possibilities
(tragically), but it is helpful for debugging, and doesn't
particularly hurt performance."
Object subclass: KeyseqSet [ Object subclass: KeyseqSet [
| seqs size length | | seqs size length |
size [^size] size [^size]
@ -9,24 +15,18 @@ Object subclass: KeyseqSet [
len := self lengthOf: e. len := self lengthOf: e.
sz := self sizeOf: e. sz := self sizeOf: e.
length length
ifNil: [ ifNil: [ length := len. size := sz.
length := len. size := sz. seqs := OrderedCollection with: e ]
seqs := OrderedCollection with: e.
]
ifNotNil: [ ifNotNil: [
:l | :l |
len = l ifTrue: [ len = l ifTrue:
size := size + 1. [ size := size + sz.
seqs add: e. seqs add: e ]
] ifFalse: [ ifFalse:
len < l ifTrue: [ [ len < l ifTrue:
length := len. size := sz. [ length := len. size := sz.
seqs := OrderedCollection with: e. seqs := OrderedCollection with: e ]]]].
] seqs := seqs asArray ]
]]
].
seqs := seqs asArray.
]
sizeOf: e [e isString ifTrue: [^1] ifFalse: [^e size]] sizeOf: e [e isString ifTrue: [^1] ifFalse: [^e size]]
lengthOf: e [e isString ifTrue: [^e size] ifFalse: [^e length]] lengthOf: e [e isString ifTrue: [^e size] ifFalse: [^e length]]
@ -137,30 +137,27 @@ Keypad class extend [
] ]
Object subclass: Robot [ Object subclass: Robot [
| keypad controlledBy seqCache depth | | keypad controlledBy seqCache |
keypad: kp [keypad := kp. depth := 0] keypad: kp [keypad := kp]
keypad: kp controlledBy: robo keypad: kp controlledBy: robo [keypad := kp. controlledBy := robo]
[keypad := kp. controlledBy := robo.
depth := robo ifNil: [0] ifNotNil: [:it | it depth + 1]]
depth [^depth]
initialize [seqCache := LookupTable new] initialize [seqCache := LookupTable new]
keyseqFor: str keyseqFor: str
[ ^seqCache at: str ifAbsent: [ [ | res steps |
^seqCache at: str put: (self computeKeyseqFor: str)] ] res := seqCache at: str ifAbsent: [nil].
res ifNotNil: [^res].
computeKeyseqFor: str
[ | steps |
steps := 0 to: str size - 1 collect: [ steps := 0 to: str size - 1 collect: [
:i | | paths | :i | | paths |
paths := keypad pressPath: (str at: i ifAbsent: [$A]) paths := keypad pressPath: (str at: i ifAbsent: [$A])
to: (str at: i + 1). to: (str at: i + 1).
controlledBy ifNotNil: [ controlledBy ifNotNil: [
paths := paths collect: [:it | controlledBy keyseqFor: it]]. paths := paths collect: [:it | controlledBy keyseqFor: it]].
KeyseqSet new seqs: paths (paths size = 1)
]. ifTrue: [paths at: 1]
^KeyseqCat new seqs: steps ] ifFalse: [KeyseqSet new seqs: paths] ].
res := KeyseqCat new seqs: steps.
^seqCache at: str put: res ]
] ]
Robot class extend [ Robot class extend [

42
days/day22.st Normal file
View file

@ -0,0 +1,42 @@
Object subclass: Monkey [
| history |
history: h [history := h]
lastValue [^history at: history size]
collectPricesInto: intoTbl
[ | ch table prices deltas chMod |
table := Dictionary new.
prices := history collect: [:it | it \\ 10].
deltas := 2 to: history size collect: [
:i | (prices at: i) - (prices at: i - 1) + 9].
ch := 0.
1 to: 4 do: [
:i | ch := 20 * ch + (deltas at: i)].
chMod := 20 raisedTo: 4.
5 to: deltas size do: [
:i | ch := (20 * ch + (deltas at: i)) \\ chMod.
table at: ch ifAbsentPut: [prices at: i + 1]].
table keysAndValuesDo: [
:ch :v | intoTbl at: ch put: v + (intoTbl at: ch ifAbsent: [0])]]
]
Monkey class extend [
stepSecret: initial times: n
[ | s hist | s := initial.
hist := 1 to: n collect: [
:i |
s := (s bitXor: (s bitShift: 6)) bitAnd: 16777215.
s := (s bitXor: (s bitShift: -5)) bitAnd: 16777215.
s := (s bitXor: (s bitShift: 11)) bitAnd: 16777215.
s ].
^Monkey new history: {initial},hist ]
]
AOC input: [ stdin toLines collect: [
:it | Monkey stepSecret: it asNumber times: 2000] ];
part1: [ :monkeys | (monkeys collect: [:it | it lastValue]) sum ];
part2: [ :monkeys | | buyMap | buyMap := Dictionary new.
monkeys do: [:it | it collectPricesInto: buyMap].
buyMap values maximum ];
result: [ :monkeys :part | part value: monkeys ];
finish.