aoc-all

My solutions to all Advent of Code
git clone https://git.instinctive.eu/aoc-all.git
Log | Files | Refs | README | LICENSE

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()