Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ummels/1865050 to your computer and use it in GitHub Desktop.
Save ummels/1865050 to your computer and use it in GitHub Desktop.
;; ummels's solution to Squares Squared
;; https://4clojure.com/problem/138
(fn [start end]
(letfn
[(squares [start end]
(take-while #(<= % end) (iterate #(* % %) start)))
(arrange [x]
(let [n (count x)
dim (int (Math/ceil (Math/sqrt n)))
dim1 (dec (* 2 dim))
y (concat x (repeat (- (* dim dim) n) \*))
rot (fn [[i j]] (if (= j 0) [(* i -1) i] [i 0]))
legal? (fn [[i j]] (and (>= i 0) (>= j 0) (< i dim1) (< j dim)))]
(loop [p (if (odd? dim) [(dec dim) (dec dim)] [(dec dim) 0])
d (if (odd? dim) [-1 0] [1 0])
in (reverse y)
res (vec (repeat dim1 (vec (repeat dim nil))))]
(cond
(empty? in) res
(and (legal? (map + p d)) (nil? (get-in res (map + p d))))
(recur (map + p d) d (rest in) (assoc-in res p (first in)))
:else
(recur (map + p (rot d)) (rot d) (rest in) (assoc-in res p (first in)))))))
(pretty [x]
(for [r x]
(let [s (take-while (complement nil?) (drop-while nil? r))
m (- (count r) (count s))]
(apply str
(concat (repeat m \space)
(rest (interleave (repeat \space) s))
(repeat m \space))))))]
(pretty (arrange (mapcat str (squares start end))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment