aoc-all

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

day22.nim (2148B)


      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 foldl, map, mapIt, toSeq, zip
     16 from std/strutils import parseInt
     17 from std/tables   import `[]`, `[]=`, getOrDefault, hasKey, pairs, Table
     18 
     19 # Read input file
     20 
     21 let data = stdin.lines().toSeq().map(parseInt)
     22 
     23 # Puzzle 1
     24 
     25 func step(n: int): int =
     26   let
     27     s1 = ((n * 64) xor n) mod 16777216
     28     s2 = ((s1 div 32) xor s1) mod 16777216
     29     s3 = ((s2 * 2048) xor s2) mod 16777216
     30   result = s3
     31 
     32 let test_data = @[123, 15887950, 16495136, 527345, 704524, 1553684, 12683156, 11100544, 12249484, 7753432, 5908254]
     33 
     34 for (a,b) in zip(test_data[0 .. ^2], test_data[1 .. ^1]):
     35   assert step(a) == b
     36 
     37 func steps(n, s: int): int =
     38   result = n
     39   for i in 1 .. s:
     40     result = step(result)
     41 
     42 echo "Puzzle 1: ", data.mapIt(steps(it, 2000)).foldl(a + b)
     43 
     44 # Puzzle 2
     45 
     46 var scores: Table[seq[int], int]
     47 var max_score = 0
     48 
     49 for seed in data:
     50   let
     51     s1 = step(seed)
     52     s2 = step(s1)
     53     s3 = step(s2)
     54   var
     55     last = s3
     56     d = @[0, (s1 mod 10) - (seed mod 10), (s2 mod 10) - (s1 mod 10), (s3 mod 10) - (s2 mod 10)]
     57 
     58   var seen: Table[seq[int], bool]
     59   for i in 4 .. 2000:
     60     let next = step(last)
     61     d = d[1 .. ^1]
     62     d.add((next mod 10) - (last mod 10))
     63     if not seen.hasKey(d):
     64       seen[d] = true
     65       let new_score = scores.getOrDefault(d, 0) + (next mod 10)
     66       scores[d] = new_score
     67       max_score = max(max_score, new_score)
     68     last = next
     69 
     70 echo "Puzzle 2: ", max_score