Last active
April 3, 2024 21:47
-
-
Save alpox/cbe1b5b5d0260b0b1977cba3b9d5f6be to your computer and use it in GitHub Desktop.
FCC Challenge 3. April 2024
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns c13 | |
(:require | |
[clojure.string :as str] | |
[clojure.spec.alpha :as s] | |
[clojure.test :refer [testing is]] | |
[clojure.test.check :as check] | |
[clojure.test.check.generators :as gen] | |
[clojure.test.check.properties :as prop] | |
[com.gfredericks.test.chuck.generators :as gen'])) | |
(def row-width 10) | |
(def colour-regex #"[a-z]\d{3}") | |
(def part-line (str/join (repeat 7 "─"))) | |
(s/def ::colour #(re-matches colour-regex %)) | |
(def empty-row (vec (repeat row-width nil))) | |
(defn- row->index [row] (- (int row) (int \A))) | |
(defn- column->index [column] (dec column)) | |
(defn- index->row [index] (char (+ index (int \A)))) | |
(defn- index->column [index] (inc index)) | |
(defn- nail-location [row column] | |
[:nails (row->index row) (column->index column)]) | |
(defprotocol NailBookLike | |
(add-colour [this colour row column]) | |
(reset-row [this row]) | |
(display [this]) | |
(find-colour [this colour])) | |
(defrecord NailBook [nails] | |
NailBookLike | |
(add-colour [this colour row column] | |
(when-not (s/valid? ::colour colour) | |
(throw (ex-info (format "Invalid colour '%s'" colour) {:colour colour}))) | |
(assoc-in this (nail-location row column) colour)) | |
(reset-row [this row] | |
(assoc-in this [:nails (row->index row)] empty-row)) | |
(display [_] | |
(let [start-line (str "┌" (str/join "┬" (repeat (inc row-width) part-line)) "┐") | |
middle-line (str "├" (str/join "┼" (repeat (inc row-width) part-line)) "┤") | |
end-line (str "└" (str/join "┴" (repeat (inc row-width) part-line)) "┘")] | |
(with-out-str | |
(println start-line) | |
(print "│") | |
(print (format "%6s │" " ")) | |
(doseq [column-index (range row-width)] | |
(print (format "%6s │" (index->column column-index)))) | |
(doseq [row-index (range (count nails))] | |
(println) | |
(println middle-line) | |
(print "│") | |
(print (format "%6s │" (index->row row-index))) | |
(doseq [column (nth nails row-index)] | |
(print (format "%6s │" (if column column " "))))) | |
(println) | |
(println end-line)))) | |
(find-colour [_ colour] | |
(let [found (first (for [row-index (range (count nails)) | |
column-index (range row-width) | |
:when (= (get-in nails [row-index column-index]) colour)] | |
[(index->row row-index) (index->column column-index)]))] | |
(when (nil? found) | |
(throw (ex-info (format "Colour '%s' not found" colour) {:colour colour}))) | |
found))) | |
(defn make-nail-book [] | |
(->NailBook (vec (take 10 (repeat empty-row))))) | |
; --------------------------------------------------------------------------------------- | |
; Testing | |
; --------------------------------------------------------------------------------------- | |
(def add-colours-gen | |
(gen/tuple (gen'/bounded-int 0 9) | |
(gen'/bounded-int 0 9) | |
(gen'/string-from-regex colour-regex))) | |
(def filled-test-book | |
(reduce | |
(fn [book [row column colour]] | |
(add-colour book colour (index->row row) (index->column column))) | |
(make-nail-book) | |
(distinct (take 100 (gen/sample-seq add-colours-gen))))) | |
(def color-prop | |
(prop/for-all | |
[[row column v] add-colours-gen] | |
(let [book (add-colour (make-nail-book) v (index->row row) (index->column column))] | |
(is (= v (get-in book (nail-location (index->row row) (index->column column)))))))) | |
(testing "Nail book" | |
(testing "add-colour" | |
(check/quick-check 100 color-prop)) | |
(testing "reset-colour" | |
(check/quick-check | |
10 | |
(prop/for-all [row (gen'/bounded-int 0 9)] | |
(let [book (reset-row filled-test-book (index->row row))] | |
(is (= (get-in book [:nails row]) empty-row)))))) | |
(testing "find-colour" | |
(doseq [row (range 10) | |
column (range 10)] | |
(let [colour (get-in filled-test-book | |
(nail-location (index->row row) (index->column column)))] | |
(when colour | |
(is (= [(index->row row) (index->column column)] | |
(find-colour filled-test-book colour)))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment