~ihabunek/aoc2021

4b2ae94cf267c024168cceb381615f8ba592ebf5 — Ivan Habunek 1 year, 4 months ago 908dff9 day24
Wip
4 files changed, 400 insertions(+), 0 deletions(-)

A day24.annotated.txt
A day24.py
A resources/day24.in
A src/aoc2021/day24.clj
A day24.annotated.txt => day24.annotated.txt +18 -0
@@ 0,0 1,18 @@
  inp w     | w = read()
  mul x 0   | x = 0          \ 
  add x z   | x = x + z       | x = (z % 26)
  mod x 26  | x = x % 26     /      
* div z 1   | z = z // 1
* add x 12  | x += 12        
  eql x w   | x = 1 if x == w else 0   | 
  eql x 0   | x = 1 if x == 0 else 0   |
  mul y 0   | y = 0    \
  add y 25  | y += 25   | z = z * (25 * x + 1) 
  mul y x   | y *= x    |
  add y 1   | y += 1    |
  mul z y   | z *= y   /
  mul y 0   | y = 0    \
  add y w   | y += w    |
* add y 4   | y += 4    | y = (w + 4) * x
  mul y x   | y *= x    |
  add z y   | z += y   /

A day24.py => day24.py +63 -0
@@ 0,0 1,63 @@
from random import randint

div_zs = [1, 1, 1, 26, 1, 1, 26, 1, 1, 26, 26, 26, 26, 26]
add_xs = [12, 11, 14, -6, 15, 12, -9, 14, 14, -5, -9, -5, -2, -7]
add_ys = [4, 10, 12, 14, 6, 16, 1, 7, 8, 11, 8, 3, 1, 8]


def plain(number):
    digits = split(number)
    x = y = z = w = 0

    for div_z, add_x, add_y, n in zip(div_zs, add_xs, add_ys, digits):
        w = n
        x = 0
        x += z
        x %= 26
        z = div(z, div_z)
        x += add_x
        x = 1 if x == w else 0
        x = 1 if x == 0 else 0
        y = 0
        y += 25
        y *= x
        y += 1
        z *= y
        y = 0
        y += w
        y += add_y
        y *= x
        z += y

    print(f"    plain {z=}")
    return z


def optimized(number):
    digits = split(number)
    z = 0

    for div_z, add_x, add_y, n in zip(div_zs, add_xs, add_ys, digits):
        cond = z % 26 + add_x
        z = div(z, div_z)
        if not cond == n:
            z = 26 * z + n + add_y
        print(f"{cond=:<2} {n=} {z=}")

    print(f"optimized {z=}\n")
    return z


def div(x, y):
    return int(x / y)


def split(n):
    return [int(x) for x in str(n)]


plain(11111111111111)
optimized(11111111111111)

# plain(13579246899999)
# optimized(13579246899999)

A resources/day24.in => resources/day24.in +252 -0
@@ 0,0 1,252 @@
inp w
mul x 0
add x z
mod x 26
div z 1
add x 12
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 4
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 11
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 10
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 12
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -6
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 14
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 15
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 6
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 12
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 16
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -9
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 1
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 7
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 1
add x 14
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 8
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -5
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 11
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -9
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 8
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -5
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 3
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -2
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 1
mul y x
add z y
inp w
mul x 0
add x z
mod x 26
div z 26
add x -7
eql x w
eql x 0
mul y 0
add y 25
mul y x
add y 1
mul z y
mul y 0
add y w
add y 8
mul y x
add z y

A src/aoc2021/day24.clj => src/aoc2021/day24.clj +67 -0
@@ 0,0 1,67 @@
; --- Day 24: Arithmetic Logic Unit ---
; https://adventofcode.com/2021/day/24

(ns aoc2021.day24
  (:require [clojure.java.io :as io]
            [clojure.string :as str]
            [clojure.edn :as edn]
            [clojure.pprint :refer [pprint cl-format]]
            [clojure.core.match :refer [match]]
            [aoc2021.utils :refer [parse-int]]))

(def input-file (-> "day24.in" io/resource io/file))

(defn parse-reg [x]
  (if (contains? #{"w" "x" "y" "z"} x)
    (keyword x)
    (parse-int x)))

(defn parse-instruction [bits]
  (conj
    (map parse-reg (rest bits))
    (keyword (first bits))))

(defn parse-line [line]
  (vec
    (parse-instruction
      (str/split line #" "))))

(defn get-input []
  (->> (slurp input-file)
       (str/split-lines)
       (map parse-line)))

(defn value [memory key]
  (if (integer? key) key (get memory key)))

(defn step [memory program input]
  (println ">" (first program) memory input)
  (let [line (first program)
        memory (match line
                 [:inp a]   (assoc memory a (first input))
                 [:add a b] (assoc memory a (+ (value memory a) (value memory b)))
                 [:mul a b] (assoc memory a (* (value memory a) (value memory b)))
                 [:mod a b] (assoc memory a (mod (value memory a) (value memory b)))
                 [:div a b] (assoc memory a (quot (value memory a) (value memory b)))
                 [:eql a b] (assoc memory a (if (= (value memory a) (value memory b)) 1 0)))
        input (if (= (first line) :inp) (rest input) input)]
    (println "<" line memory input)
    [memory (rest program) input]))

(defn run [memory program input]
  (loop [memory memory program program input input]
    (if (empty? program)
      (:z memory)
      (let [[memory program input] (step memory program input)]
        (recur memory program input)))))

(defn split-int [n]
  (map (comp parse-int str) (str n)))

(defn main []
  (let [program (get-input)
        memory {:w 0 :x 0 :y 0 :z 0}
        ; input (split-int 13579246899999)
        input (split-int 11111111111111)]
    (pprint
      (run memory program input))))