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)