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