aoc-all

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

day02.nim (2028B)


      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 allIt, filter, map, mapIt, toSeq, zip
     16 from std/strutils  import parseInt, splitWhitespace
     17 
     18 # Read input file
     19 
     20 let data = stdin.lines().toSeq().mapIt(it.splitWhitespace().map(parseInt))
     21 
     22 # First puzzle
     23 
     24 func deltas(s: seq[int]): seq[int] =
     25   zip(s[1 .. ^1], s[0 .. ^2]).mapIt(it[0] - it[1])
     26 
     27 func isSafe(d: seq[int]): bool =
     28   (allIt(d, it < 0) or allIt(d, it > 0)) and allIt(d, abs(it) <= 3)
     29 
     30 echo "Puzzle 1: ", len(data.map(deltas).filter(isSafe))
     31 
     32 # Second puzzle
     33 # 611 is too low
     34 
     35 func dampenIndex(s: seq[int], iinc, idec, idelta: var int) =
     36   iinc = 0
     37   idec = 0
     38   idelta = 0
     39   for i in 1 .. len(s) - 1:
     40     if iinc == 0 and s[i] <= s[i-1]:
     41       iinc = i
     42     if idec == 0 and s[i] >= s[i-1]:
     43       idec = i
     44     if idelta == 0 and abs(s[i] - s[i-1]) > 3:
     45       idelta = i
     46     if iinc > 0 and idec > 0 and idelta > 0:
     47       break
     48 
     49 func isDampenedSafe(s: seq[int]): bool =
     50   var iinc, idec, idelta = 0
     51   dampenIndex(s, iinc, idec, idelta)
     52   for i in @[iinc, iinc-1, idec, idec-1, idelta, idelta-1]:
     53     if i > 0 and isSafe(deltas(s[0 .. i-1] & s[i + 1 .. ^1])):
     54       return true
     55 
     56 func isSafe2(s: seq[int]): bool =
     57   let d = deltas(s)
     58   result = isSafe(d) or isSafe(d[1 .. ^1]) or isDampenedSafe(s)
     59 
     60 echo "Puzzle 2: ", len(data.filter(isSafe2))