aoc-all

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

day11.nim (2066B)


      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/math     import `^`
     16 from std/sequtils import foldl, map, toSeq
     17 from std/strutils import parseInt, splitWhitespace
     18 from std/tables   import `[]=`, getOrDefault, initTable, pairs, Table, values
     19 
     20 # Read input file
     21 
     22 func tablize(s: seq[int]): Table[int, int] =
     23   result = initTable[int, int]()
     24   for i in s:
     25     result[i] = result.getOrDefault(i, 0) + 1
     26 
     27 let
     28   data = stdin.readLine().splitWhitespace().map(parseInt)
     29   tdata = tablize(data)
     30 
     31 # Puzzle 1
     32 # 217379 is tool high
     33 
     34 func digits(n: int): int =
     35   result = 1
     36   var ceiling = 10
     37   while ceiling <= n:
     38     result += 1
     39     ceiling *= 10
     40 
     41 proc update(t: Table[int, int]): Table[int, int] =
     42   result = initTable[int, int]()
     43   for i, n in t.pairs:
     44     var nd = digits(i)
     45     if i == 0:
     46       result[1] = result.getOrDefault(1, 0) + n
     47     elif nd mod 2 == 1:
     48       let ni = i * 2024
     49       result[ni] = result.getOrDefault(ni, 0) + n
     50     else:
     51       let sp = 10 ^ (nd div 2)
     52       result[i div sp] = result.getOrDefault(i div sp, 0) + n
     53       result[i mod sp] = result.getOrDefault(i mod sp, 0) + n
     54 
     55 proc updates(s: Table[int, int], n: int): Table[int, int] =
     56   result = s
     57   for i in 1 .. n:
     58     result = update(result)
     59 
     60 echo "Puzzle 1: ", updates(tdata, 25).values().toSeq().foldl(a + b)
     61 echo "Puzzle 2: ", updates(tdata, 75).values().toSeq().foldl(a + b)