From 20203ea195c296629cdd20084aab591ca183e3c2 Mon Sep 17 00:00:00 2001 From: didier amyot Date: Fri, 5 Dec 2025 05:48:08 -0500 Subject: [PATCH] finally finished question 2b. --- clojure/src/question_2.clj | 107 ++++++++++++------------------------- 1 file changed, 33 insertions(+), 74 deletions(-) diff --git a/clojure/src/question_2.clj b/clojure/src/question_2.clj index a4c5967..6a59035 100644 --- a/clojure/src/question_2.clj +++ b/clojure/src/question_2.clj @@ -4,112 +4,71 @@ (def mock-input "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124") +(defn factors [n] (filter #(zero? (mod n %)) (range 1 n))) + +(defn -all-cycles [k] + (for [n (factors k)] + (for [m (range n)] (range m k n)))) + +(def all-cycles (zipmap (range 2 100) (mapv -all-cycles (range 2 100)))) + +(defn all-equals? [lst indexes] + (apply = (mapv #(get lst %) indexes))) + +(defn has-cycle? [lst cycle] + (every? #(all-equals? lst %) cycle)) + +(defn cyclic? [lst] + (some #(has-cycle? lst %) (all-cycles (count lst)))) + +(defn to-digits [n] + (let [[p r] [(quot n 10) (mod n 10)]] + (if (zero? p) + [r] + (conj (to-digits p) r)))) + (defn pow [x n] (reduce *' (repeat n x))) (defn repeat-x [x n] - #_(println "repeat-x " x " " n " times") (let [exp (long (Math/ceil (Math/log10 (inc x)))) - to-num #(*' x (pow 10 (*' % exp)))] (reduce +' (map to-num (range n))))) -(defn repeat-all [x] - (map #(repeat-x x %) (drop 2 (range)))) - -;; TODO: we need to handle the case when the elm goes in the very first place. -(defn insert-when-2 [pred lst elm] - (loop [f (first lst) - s (second lst) - r (rest (rest lst)) - acc (transient [])] - (conj! acc f) - (cond - (pred f s) (lazy-cat (persistent! acc) [elm s] r) - (empty? r) (lazy-cat (persistent! acc) [elm]) - :else (recur s (first r) (rest r) acc)))) - - - -(defn insert-when [pred lst elm] - (if (empty? lst) - (list elm) - (loop [prefix (-> lst first vector) - last-prefix (first lst) - suffix (rest lst)] - (cond - (empty? suffix) (seq (conj prefix elm)) - (pred last-prefix (first suffix)) (lazy-cat prefix [elm] suffix) - :else (recur (conj prefix (first suffix)) (first suffix) (rest suffix)))))) - - -(defn insert-list [list-of-lists [head & _ :as all]] - (if (empty? all) - list-of-lists - (insert-when #(<= (first %1) head (first %2)) list-of-lists all))) - -(defn sort-list-of-sorted-list-step [lists]) - - -(defn sort-list-of-sorted-list [[[head & new-first-list] & ret]] - (when head - (lazy-seq (cons head (sort-list-of-sorted-list (insert-list ret new-first-list)))))) (defn int->palindrome [x] (repeat-x x 2)) (def all-int-palindromes (map int->palindrome (rest (range)))) -(defn make-id-ranges [[start end]] - {:start start - :end end}) - -(def all-repeated-no-dedupe (sort-list-of-sorted-list (map repeat-all (drop 1 (range))))) - -(def all-repeated (dedupe (sort-list-of-sorted-list (map repeat-all (drop 1 (range)))))) - -(defn find-all-palindrome-ids [{start :start end :end}] +(defn find-all-palindrome-ids [[start end]] (let [xf (comp (drop-while #(< % start)) (take-while #(<= % end)))] (sequence xf all-int-palindromes))) -(defn find-all-repeated-ids [{start :start end :end}] - (let [xf (comp (drop-while #(< % start)) - (take-while #(<= % end)))] - (sequence xf all-repeated))) - -(defn sum-of-palindromes-ids [id-range] - (reduce + (find-all-palindrome-ids id-range))) - - -(defn sum-of-repeated-ids [id-range] - (reduce + (find-all-repeated-ids id-range))) - +(defn sum-of-palindromes-ids [id-ranges] + (reduce + (find-all-palindrome-ids id-ranges))) (defn question-2-a [document] (let [lines (strings/split document #"\,") make-filter-xf (comp (map #(strings/split % #"\-")) (map #(mapv Long/parseLong %)) - (map make-id-ranges) (map sum-of-palindromes-ids)) - filters (sequence make-filter-xf lines)] - + filters (eduction make-filter-xf lines)] (reduce + filters))) +(defn sum-of-cyclic-ids [[start end]] + (reduce + (filter #(cyclic? (to-digits %)) (range start (inc end))))) + (defn question-2-b [document] (let [lines (strings/split document #"\,") make-filter-xf (comp (map #(strings/split % #"\-")) (map #(mapv Long/parseLong %)) - (map make-id-ranges) - (map sum-of-repeated-ids)) - filters (sequence make-filter-xf lines)] - + (map sum-of-cyclic-ids)) + filters (eduction make-filter-xf lines)] (reduce + filters))) - - (defn -main [& args] (println "Solution to question 2-a is: " (question-2-a inputs/question-2)) - #_(mapv #(println ">>> " %) (take 10000 all-repeated)) - #_(println "Solution to question 2-b is: " (question-2-b mock-input))) + (println "Solution to question 2-b is: " (question-2-b inputs/question-2)))