Skip to content

Instantly share code, notes, and snippets.

@featheredtoast
Last active December 12, 2017 07:31
Show Gist options
  • Save featheredtoast/147a187da0830196e46363b0664e4c33 to your computer and use it in GitHub Desktop.
Save featheredtoast/147a187da0830196e46363b0664e4c33 to your computer and use it in GitHub Desktop.
advent day 10
(defn tie-knot-round
[current-list knot-lengths skip-size offset]
(if (empty? knot-lengths)
{:result current-list :skip-size skip-size :offset offset}
(let [cycle-list (cycle current-list)
knot-length (first knot-lengths)
non-knot-length (- (count current-list) knot-length)
new-offset (mod (+ knot-length skip-size offset) (count current-list))
reversed-list (reverse (take knot-length cycle-list))
rest-of-list (take non-knot-length (drop knot-length cycle-list))
next-list (take (count current-list) (drop (+ knot-length skip-size) (cycle (concat reversed-list rest-of-list))))]
(tie-knot-round next-list (rest knot-lengths) (inc skip-size) new-offset))))
(defn convert-to-ascii [str]
(map int str))
(defn convert-to-bitstring [coll]
(apply bit-xor coll))
(defn base16-notation [num]
(let [b16 (Integer/toString num 16)]
(cond->> b16
(= (count b16) 1) (str "0"))))
(defn tie-knot
([current-list knot-lengths skip-size offset remaining-rounds]
(let [{:keys [result skip-size offset]} (tie-knot-round current-list knot-lengths skip-size offset)]
(if (<= remaining-rounds 1)
(take (count result) (drop (- (count result) offset) (cycle result)))
(tie-knot result knot-lengths skip-size offset (dec remaining-rounds)))))
([input]
(let [special-end-sequence [17, 31, 73, 47, 23]
knot-lengths (concat (convert-to-ascii input) special-end-sequence)
raw-result (tie-knot (range 256) knot-lengths 0 0 64)
converted-result (->> (partition 16 raw-result)
(map convert-to-bitstring)
(map base16-notation)
(apply str))]
converted-result)))
(defn tie-knot
([current-list knot-lengths skip-size offset]
(if (empty? knot-lengths)
;; restore by offset - going to be length - offset = position 0
(take (count current-list) (drop (- (count current-list) offset) (cycle current-list)))
(let [cycle-list (cycle current-list)
knot-length (first knot-lengths)
non-knot-length (- (count current-list) knot-length)
new-offset (mod (+ knot-length skip-size offset) (count current-list))
reversed-list (reverse (take knot-length cycle-list))
rest-of-list (take non-knot-length (drop knot-length cycle-list))
next-list (take (count current-list) (drop (+ knot-length skip-size) (cycle (concat reversed-list rest-of-list))))]
#_[next-list (rest knot-lengths) (inc skip-size) new-offset]
(tie-knot next-list (rest knot-lengths) (inc skip-size) new-offset))))
([current-list knot-lengths]
(tie-knot current-list knot-lengths 0 0)))
;; use like (tie-knot (range 5) [3, 4, 1, 5])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment