You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.3 KiB
Plaintext
68 lines
2.3 KiB
Plaintext
app [main] {
|
|
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.17.0/lZFLstMUCUvd5bjnnpYromZJXkQUrdhbva4xdBInicE.tar.br",
|
|
unicode: "https://github.com/roc-lang/unicode/releases/download/0.1.2/vH5iqn04ShmqP-pNemgF773f86COePSqMWHzVGrAKNo.tar.br"
|
|
}
|
|
|
|
import pf.Stdout
|
|
import unicode.Grapheme
|
|
import "data.txt" as data : Str
|
|
|
|
main =
|
|
lines = Str.splitOn data "\n" |> List.dropLast 1
|
|
grid = List.map lines \l -> Result.withDefault (Grapheme.split l) [""]
|
|
|
|
part1 = List.walkWithIndex grid 0 \total, line, row ->
|
|
total + List.walkWithIndex line 0 \rowTotal, _, col ->
|
|
rowTotal + visit1 grid row col
|
|
|
|
Stdout.line! "Part 1: $(Num.toStr part1)"
|
|
|
|
part2 = List.walkWithIndex grid 0 \total, line, row ->
|
|
total + List.walkWithIndex line 0 \rowTotal, _, col ->
|
|
rowTotal + visit2 grid row col
|
|
|
|
Stdout.line! "Part 2: $(Num.toStr part2)"
|
|
|
|
dirs1 = [
|
|
(-1, -1), (-1, 0), (-1, 1),
|
|
( 0, -1), ( 0, 1),
|
|
( 1, -1), ( 1, 0), ( 1, 1),
|
|
]
|
|
|
|
visit1 = \grid, row, col ->
|
|
# for each direction
|
|
List.walk dirs1 0 \state, dir ->
|
|
# walk 4 steps
|
|
state + List.walkWithIndexUntil ["X","M","A","S"] 0 \_, targetChar, i ->
|
|
newRow = (Num.intCast row) + dir.0 * (Num.intCast i)
|
|
newCol = (Num.intCast col) + dir.1 * (Num.intCast i)
|
|
char = gridChar grid newRow newCol
|
|
when char is
|
|
Ok c if c == targetChar -> Continue 1
|
|
_ -> Break 0
|
|
|
|
visit2 = \grid, row, col ->
|
|
char = gridChar grid row col
|
|
|
|
# if this cell isn't an "A", get out
|
|
if char != Ok "A" then
|
|
0
|
|
else
|
|
# grab the 4 corners
|
|
nw = gridChar grid (Num.intCast row - 1) (Num.intCast col - 1)
|
|
ne = gridChar grid (Num.intCast row - 1) (Num.intCast col + 1)
|
|
sw = gridChar grid (Num.intCast row + 1) (Num.intCast col - 1)
|
|
se = gridChar grid (Num.intCast row + 1) (Num.intCast col + 1)
|
|
|
|
if ((nw == Ok "M" && se == Ok "S") ||
|
|
(nw == Ok "S" && se == Ok "M")) &&
|
|
((ne == Ok "M" && sw == Ok "S") ||
|
|
(ne == Ok "S" && sw == Ok "M"))
|
|
then 1
|
|
else 0
|
|
|
|
# get the Result char at a row and col in the grid
|
|
gridChar = \grid, row, col ->
|
|
r = List.get? grid (Num.intCast row)
|
|
List.get? r (Num.intCast col)
|