83 lines
2.9 KiB
Smalltalk
83 lines
2.9 KiB
Smalltalk
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 [
|
|
| orig symAndPosns | orig: n [orig:=n] symAndPosns: n [symAndPosns:=n]
|
|
occursAt: pos in: grid
|
|
[ ^symAndPosns allSatisfy: [
|
|
:sym :rel |
|
|
"stdout << (pos + rel) << ' = ' << sym << ' ' << ((grid at: pos + rel) = sym); nl."
|
|
(grid at: pos + rel) = sym ] asSpreader ]
|
|
countIn: grid
|
|
[ ^(grid allPosnsOf: orig) count: [ :pos | self occursAt: pos in: grid ] ]
|
|
or: oPat [ ^UnionPattern new patterns: {self. oPat} ]
|
|
mapPosns: block
|
|
[ ^Pattern new orig: orig;
|
|
symAndPosns: (
|
|
symAndPosns collect: [
|
|
:sym :rel | {sym . block value: rel}
|
|
] asSpreader) ]
|
|
]
|
|
Object subclass: UnionPattern [
|
|
| patterns | patterns: p [patterns:=p]
|
|
countIn: grid
|
|
[ ^patterns inject: 0 into: [ :acc :p | acc + (p countIn: grid) ] ]
|
|
or: oPat [ ^UnionPattern new patterns: patterns, {oPat} ]
|
|
]
|
|
|
|
AOC input: [ Grid new rows: (stdin toLines) ];
|
|
part1: (#((0 1) (0 -1) (1 0) (-1 0) (1 1) (-1 -1) (1 -1) (-1 1))
|
|
asPosns chain collect:
|
|
[ :pos | Pattern new orig: $X;
|
|
symAndPosns: (
|
|
#($M $A $S)
|
|
with: (1 to: 3)
|
|
collect: [:c :n | {c. pos * n}])];
|
|
orPats);
|
|
part2: ((#((1 1) (-1 -1)) asPosns collect:
|
|
[ :l | #((-1 1) (1 -1)) asPosns collect:
|
|
[ :r | Pattern new orig: $A;
|
|
symAndPosns: {{$M.l*-1}.{$S.l}.{$M.r*-1}.{$S.r}} ]])
|
|
join orPats);
|
|
result: [ :grid :pat | pat countIn: grid ];
|
|
finish.
|