day04.nim (2160B)
1 # Copyright (c) 2024, Natacha Porté 2 # 3 # Permission to use, copy, modify, and distribute this software for any 4 # purpose with or without fee is hereby granted, provided that the above 5 # copyright notice and this permission notice appear in all copies. 6 # 7 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15 from std/sequtils import toSeq 16 17 # Read input file 18 19 let data = stdin.lines().toSeq() 20 let nlines = len(data) 21 let ncols = len(data[0]) 22 23 # Puzzle 1 24 25 proc isXmas(x, y, dx, dy: int): bool = 26 x + 3*dx >= 0 and 27 x + 3*dx < ncols and 28 y + 3*dy >= 0 and 29 y + 3*dy < ncols and 30 data[y][x] == 'X' and 31 data[y+dy][x+dx] == 'M' and 32 data[y+2*dy][x+2*dx] == 'A' and 33 data[y+3*dy][x+3*dx] == 'S' 34 35 const dirs = @[(1,0), (1,1), (0,1), (-1,1), (-1,0), (-1,-1), (0,-1), (1, -1)] 36 37 proc countXmasAt(x, y: int): int = 38 result = 0 39 if data[y][x] == 'X': 40 for d in dirs: 41 if isXmas(x, y, d[0], d[1]): 42 result += 1 43 44 proc countXmas(): int = 45 result = 0 46 for y in 0 ..< nlines: 47 for x in 0 ..< ncols: 48 result += countXmasAt(x, y) 49 50 echo "Puzzle 1: ", countXmas() 51 52 # Puzzle 2 53 54 const dirs2 = @[(1,1), (-1,1), (-1,-1), (1,-1)] 55 56 proc isMas(x, y, dx, dy: int): bool = 57 data[y-dy][x-dx] == 'M' and 58 data[y+dy][x+dx] == 'S' 59 60 proc is2Mas(x, y, i: int): bool = 61 let 62 i2 = (i + 1) mod len(dirs2) 63 d1 = dirs2[i] 64 d2 = dirs2[i2] 65 result = isMas(x, y, d1[0], d1[1]) and isMas(x, y, d2[0], d2[1]) 66 67 proc countMasAt(x, y: int): int = 68 result = 0 69 if data[y][x] == 'A': 70 for i in 0 ..< len(dirs2): 71 if is2Mas(x, y, i): 72 result += 1 73 74 proc countMas(): int = 75 result = 0 76 for y in 1 .. nlines-2: 77 for x in 1 .. ncols-2: 78 result += countMasAt(x, y) 79 80 echo "Puzzle 2: ", countMas()