Advertisement
jetrink

Untitled

Jan 20th, 2023 (edited)
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns day20.part1
  2.   (:use clojure.test)
  3.   (:require
  4.    [clojure.pprint :refer [pprint]]
  5.    [day20.os-tree :as ost]))
  6.  
  7. (defn mix [input]
  8.   (letfn [(rotate-nth [index n dist]
  9.             "Move the item at position n by dist within index, wrapping if necessary"
  10.             (let [input-size (count input)
  11.                   item (ost/select index n)
  12.                   prev-idx (mod n (dec input-size))
  13.                   insertion-idx (mod (+ prev-idx dist) (dec input-size))]
  14.               (-> index
  15.                   (ost/delete n)
  16.                   (ost/insert insertion-idx item))))]
  17.  
  18.     (let [initial-arrangement
  19.           (ost/construct
  20.            (vec (range (count input))))
  21.  
  22.           final-arrangement
  23.           (reduce-kv
  24.            (fn [index i n]
  25.              (let [target (ost/search index i)]
  26.                (rotate-nth index target n)))
  27.            initial-arrangement
  28.            input)]
  29.  
  30.       (map
  31.        input
  32.        (ost/in-order
  33.         final-arrangement)))))
  34.  
  35. (defn -main [file]
  36.   (let [input (->> file
  37.                    slurp
  38.                    clojure.string/trim
  39.                    clojure.string/split-lines
  40.                    (mapv read-string))]
  41.     (->> input
  42.          mix
  43.          repeat
  44.          (apply concat)
  45.          (drop-while (complement zero?))
  46.          (take-nth 1000)
  47.          rest
  48.          (take 3)
  49.          (apply +))))
  50.  
  51. (ns day20.os-tree
  52.   "Implements a binary tree that represents an ordered sequence
  53.   and allows for efficient access, insertion and deletion by index.
  54.   Each node is represented by a vector with the following format:
  55.  
  56.     [value index left-child right-child]"
  57.  
  58.   (:use clojure.test))
  59.  
  60. (defn construct [items]
  61.   "Create a balanced tree from a vector of items"
  62.   (if (zero? (count items))
  63.     nil
  64.     (let [midpoint (quot (count items) 2)
  65.           left-items (subvec items 0 midpoint)
  66.           right-items (subvec items (inc midpoint) (count items))]
  67.       (vector
  68.        (items midpoint)
  69.        (count left-items)
  70.        (construct left-items)
  71.        (construct right-items)))))
  72.  
  73. (defn insert [[node-val node-idx left right :as node] idx new-val]
  74.   "Insert new-val at position idx within the tree"
  75.   (cond
  76.     (nil? node)
  77.     [new-val 0 nil nil]
  78.  
  79.     (= node-idx idx)
  80.     (let [updated-right
  81.           (insert
  82.            right
  83.            (- idx node-idx)
  84.            node-val)]
  85.  
  86.       [new-val node-idx left updated-right])
  87.  
  88.     (< node-idx idx)
  89.     (let [updated-right
  90.           (insert
  91.            right
  92.            (dec (- idx node-idx))
  93.            new-val)]
  94.  
  95.       [node-val node-idx left updated-right])
  96.  
  97.     :else
  98.     [node-val
  99.      (inc node-idx)
  100.      (insert left idx new-val)
  101.      right]))
  102.  
  103. (defn select [[v node-idx left right] idx]
  104.   "Return the value located at idx"
  105.   (cond
  106.     (= node-idx idx) v
  107.  
  108.     (< node-idx idx)
  109.     (select
  110.      right
  111.      (dec (- idx node-idx)))
  112.  
  113.     :else
  114.     (select left idx)))
  115.  
  116. (defn search [[v node-idx left right :as node] needle]
  117.   "Return the index of needle"
  118.   (when-not (nil? node)
  119.     (or
  120.      (when (= v needle) node-idx)
  121.      (search left needle)
  122.      (when-let [right-result (search right needle)]
  123.        (+ right-result node-idx 1)))))
  124.  
  125. (defn delete [[node-val node-idx left right :as node] idx]
  126.   "Remove the value located at idx from the tree"
  127.   (letfn [(replace-self []
  128.             "Replace the node that is being deleted with
  129.             a descendant (or nothing)."
  130.             (cond
  131.               (and (nil? left) (nil? right)) nil
  132.  
  133.               (nil? right) left
  134.  
  135.               :else
  136.               (let [replacement (select right 0)]
  137.                 [replacement
  138.                  node-idx
  139.                  left
  140.                  (delete right 0)])))]
  141.  
  142.     (cond
  143.       (= node-idx idx) (replace-self)
  144.  
  145.       (< node-idx idx)
  146.       [node-val
  147.        node-idx
  148.        left
  149.        (delete right (dec (- idx node-idx)))]
  150.  
  151.       :else
  152.       [node-val
  153.        (dec node-idx)
  154.        (delete left idx)
  155.        right])))
  156.  
  157. (defn depth [[node-val node-idx left right :as node]]
  158.   "Determine the maximum depth of the tree"
  159.   (if (nil? node)
  160.     0
  161.     (max
  162.      (inc (depth left))
  163.      (inc (depth right)))))
  164.  
  165. (defn in-order [[node-val _ left right :as node]]
  166.   "Return the contents of the tree in index order"
  167.   (if (nil? node)
  168.     nil
  169.     (concat
  170.      (in-order left)
  171.      (cons node-val (in-order right)))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement