diff --git a/days/day21.st b/days/day21.st index 55af2b4..86df3aa 100644 --- a/days/day21.st +++ b/days/day21.st @@ -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 [ | seqs size length | size [^size] @@ -9,24 +15,18 @@ Object subclass: KeyseqSet [ len := self lengthOf: e. sz := self sizeOf: e. length - ifNil: [ - length := len. size := sz. - seqs := OrderedCollection with: e. - ] + ifNil: [ length := len. size := sz. + seqs := OrderedCollection with: e ] ifNotNil: [ :l | - len = l ifTrue: [ - size := size + 1. - seqs add: e. - ] ifFalse: [ - len < l ifTrue: [ - length := len. size := sz. - seqs := OrderedCollection with: e. - ] - ]] - ]. - seqs := seqs asArray. - ] + len = l ifTrue: + [ size := size + sz. + seqs add: e ] + ifFalse: + [ len < l ifTrue: + [ length := len. size := sz. + seqs := OrderedCollection with: e ]]]]. + seqs := seqs asArray ] sizeOf: e [e isString ifTrue: [^1] ifFalse: [^e size]] lengthOf: e [e isString ifTrue: [^e size] ifFalse: [^e length]] @@ -137,30 +137,27 @@ Keypad class extend [ ] Object subclass: Robot [ - | keypad controlledBy seqCache depth | - keypad: kp [keypad := kp. depth := 0] - keypad: kp controlledBy: robo - [keypad := kp. controlledBy := robo. - depth := robo ifNil: [0] ifNotNil: [:it | it depth + 1]] + | keypad controlledBy seqCache | + keypad: kp [keypad := kp] + keypad: kp controlledBy: robo [keypad := kp. controlledBy := robo] - depth [^depth] initialize [seqCache := LookupTable new] keyseqFor: str - [ ^seqCache at: str ifAbsent: [ - ^seqCache at: str put: (self computeKeyseqFor: str)] ] - - computeKeyseqFor: str - [ | steps | + [ | res steps | + res := seqCache at: str ifAbsent: [nil]. + res ifNotNil: [^res]. steps := 0 to: str size - 1 collect: [ :i | | paths | paths := keypad pressPath: (str at: i ifAbsent: [$A]) to: (str at: i + 1). controlledBy ifNotNil: [ paths := paths collect: [:it | controlledBy keyseqFor: it]]. - KeyseqSet new seqs: paths - ]. - ^KeyseqCat new seqs: steps ] + (paths size = 1) + ifTrue: [paths at: 1] + ifFalse: [KeyseqSet new seqs: paths] ]. + res := KeyseqCat new seqs: steps. + ^seqCache at: str put: res ] ] Robot class extend [ diff --git a/days/day22.st b/days/day22.st new file mode 100644 index 0000000..0500a30 --- /dev/null +++ b/days/day22.st @@ -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. diff --git a/days/utils.st b/days/utils.st index ff47bca..245c23f 100644 --- a/days/utils.st +++ b/days/utils.st @@ -50,7 +50,7 @@ AOC class extend [ file := (file,ext) asFile. file printNl. file parent createDirectories. - io := file writeStream. [ block value: io ] ensure: [io close] ] + io := file writeStream. [block value: io] ensure: [io close] ] ] AOC initialize.