This commit is contained in:
Beatrice Szilvasy 2024-12-06 11:16:02 +00:00
parent 0d9eb13b5b
commit 170d9a3447
3 changed files with 117 additions and 39 deletions

View file

@ -1,44 +1,5 @@
Object subclass: Posn [
| x y | x [^x] y [^y] x: n [x:=n] y: n [y:=n]
+ o [ ^Posn x: x + o x y: y + o y ]
* n [ ^Posn x: x * n y: y * n ]
rotateCw [ ^Posn x: y y: x negated ]
rotateCcw [ ^Posn x: y negated y: x ]
rotate180 [ ^Posn x: x negated y: y negated ]
printOn: s [ s << '<' << x << ', ' << y << '>'. ]
]
Posn class extend [
x: x y: y [ ^Posn new x: x; y: y ]
up: n [ ^Posn x: 0 y: n negated ]
down: n [ ^Posn x: 0 y: n ]
left: n [ ^Posn x: n negated y: 0 ]
right: n [ ^Posn x: n y: 0 ]
up [^Posn up: 1]
down [^Posn down: 1]
left [^Posn left: 1]
right [^Posn right: 1]
]
Array extend [ asPosn [ ^Posn x: (self at: 1) y: (self at: 2) ] ]
Iterable extend [
orPats [ ^self fold: [:l :r | l or: r] ]
asPosns [ ^self collect: [:it | it asPosn] ]
]
Object subclass: Grid [
| rows | rows: n [rows:=n]
at: pos [ ^(rows at: pos y ifAbsent: [^nil]) at: pos x ifAbsent: [nil] ]
height [^rows size] width [^(rows at: 1) size]
allPosnsOf: elt
[ | oc p | oc := OrderedCollection new.
(1 to: self height) do:
[ :y | (1 to: self width) do:
[ :x | p := Posn x: x y: y.
elt = (self at: p) ifTrue: [ oc add: p ] ] ].
^oc ]
printOn: st [ rows do: [ :r | st << r; nl ] ]
]
Object subclass: Pattern [

58
days/day06.st Normal file
View file

@ -0,0 +1,58 @@
Grid extend [
| guard dir origGuard visitedPosns |
visitedPosns: n [visitedPosns:=n]
visitedPosns [^visitedPosns]
dir [^dir]
guard
[ guard ifNotNil: [:it|^it] ifNil:
[ self allPosnsDo:
[ :pos |
(self at: pos) = $^ ifTrue: [
origGuard := pos.
self at: pos put: $..
self resetGuard.
^guard.
]]].
^nil ]
resetGuard [ guard := origGuard. dir := Posn up. ]
isSolid: p [ ^(self at: p) = $# ]
copy [ ^Grid new rows: rows; restore: self state ]
stepGuard
[ self guard.
[self isSolid: (guard + dir)] whileTrue:
[ dir := dir rotateCcw. ].
guard := guard + dir. ]
state [^{self guard . self dir}]
restore: st [guard := st at: 1. dir := st at: 2]
guardOob [^(self at: self guard) isNil]
walkDo: block
[ [self guardOob] whileFalse: [block value. self stepGuard] ]
hasCycle
[ | fast | fast := self resetGuard copy.
[fast guardOob] whileFalse:
[self stepGuard. fast stepGuard stepGuard.
self state = fast state ifTrue: [^true]].
^false ]
]
AOC input: [ Grid new rows: stdin toLines asArray ];
part1: [ :grid | | posns |
posns := Set new.
grid walkDo: [posns add: grid guard].
grid visitedPosns: posns.
posns ];
part2: [ :grid | | i | i := 1.
grid visitedPosns select:
[ :p | grid at: p put: $#. i printNl. i := i + 1.
[grid hasCycle] ensure: [grid at: p put: $.] ] ];
result: [ :grid :part | (part value: grid resetGuard) size ];
finish.

View file

@ -189,3 +189,62 @@ nil subclass: MessageChain [
MessageChain class >> new [ ^self basicNew ]
]
Object extend [ chain [ ^MessageChain new pipelineValue: self ] ]
Object subclass: Posn [
| x y | x [^x] y [^y] x: n [x:=n] y: n [y:=n]
+ o [ ^Posn x: x + o x y: y + o y ]
* n [ ^Posn x: x * n y: y * n ]
rotateCw [ ^Posn x: y y: x negated ]
rotateCcw [ ^Posn x: y negated y: x ]
rotate180 [ ^Posn x: x negated y: y negated ]
< o [ ^(x < o x) & (y < o y) ]
<= o [ ^(x <= o x) & (y <= o y) ]
> o [ ^(x > o x) & (y > o y) ]
>= o [ ^(x >= o x) & (y >= o y) ]
= o [ ^(x = o x) & (y = o y) ]
hash [ ^{x. y} hash ]
printOn: s [ s << '<' << x << ', ' << y << '>'. ]
]
Posn class extend [
x: x y: y [ ^Posn new x: x; y: y ]
up: n [ ^Posn x: 0 y: n negated ]
down: n [ ^Posn x: 0 y: n ]
left: n [ ^Posn x: n negated y: 0 ]
right: n [ ^Posn x: n y: 0 ]
up [^Posn up: 1]
down [^Posn down: 1]
left [^Posn left: 1]
right [^Posn right: 1]
zero [^Posn x: 0 y: 0]
]
Array extend [ asPosn [ ^Posn x: (self at: 1) y: (self at: 2) ] ]
Iterable extend [ asPosns [ ^self collect: [:it | it asPosn] ] ]
Object subclass: Grid [
| rows | rows: n [rows:=n]
at: pos [ ^(rows at: pos y ifAbsent: [^nil]) at: pos x ifAbsent: [nil] ]
at: pos put: elt
[ ^(rows at: pos y ifAbsent: [self error: 'Out of bounds'])
at: pos x put: elt ]
isInBounds: posn
[ posn > Posn zero ifFalse: [^false].
^posn <= (Posn x: self width y: self height) ]
height [^rows size] width [^(rows at: 1) size]
allPosnsDo: block
[ (1 to: self height) do:
[ :y | (1 to: self width) do:
[ :x | block value: (Posn x: x y: y) ] ] ]
allPosnsOf: elt
[ | oc | oc := OrderedCollection new.
self allPosnsDo: [ :p | elt = (self at: p) ifTrue: [ oc add: p ] ].
^oc ]
printOn: st [ rows do: [ :r | st << r; nl ] ]
]