From 170d9a3447296a1d125315e8d7b6942d50a86c63 Mon Sep 17 00:00:00 2001 From: eutro Date: Fri, 6 Dec 2024 11:16:02 +0000 Subject: [PATCH] Day 6 --- days/day04.st | 39 ---------------------------------- days/day06.st | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ days/utils.st | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 39 deletions(-) create mode 100644 days/day06.st diff --git a/days/day04.st b/days/day04.st index 340f829..713cc46 100644 --- a/days/day04.st +++ b/days/day04.st @@ -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 [ diff --git a/days/day06.st b/days/day06.st new file mode 100644 index 0000000..904fd03 --- /dev/null +++ b/days/day06.st @@ -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. diff --git a/days/utils.st b/days/utils.st index 0aa909c..b214eea 100644 --- a/days/utils.st +++ b/days/utils.st @@ -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 ] ] +]