Created
November 1, 2013 13:51
-
-
Save pallix/7265727 to your computer and use it in GitHub Desktop.
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 flood.core) | |
(defn get-row | |
[matrix y] | |
(get matrix (- (dec (count matrix)) y))) | |
(defn assoc-xy | |
[matrix x y v] | |
(assoc-in matrix [(- (dec (count matrix)) y) x] v)) | |
(defn get-xy | |
[matrix x y] | |
(get (get-row matrix y) x)) | |
(defn print-matrix | |
[matrix] | |
(doseq [row matrix] | |
(println row))) | |
(defn fill-column | |
[matrix x high v] | |
(reduce (fn [matrix level] | |
(assoc-xy matrix x level v)) | |
matrix | |
(range high))) | |
(defn assign-topology | |
[matrix problem] | |
(:matrix | |
(reduce (fn [{:keys [matrix index] :as acc} high] | |
(assoc acc | |
:matrix (fill-column matrix index high 1) | |
:index (inc index))) | |
{:matrix matrix | |
:index 0} | |
problem))) | |
(defn create-matrix | |
[problem] | |
(let [matrix (vec (repeatedly (count problem) #(vec (take 8 (repeat 2))))) | |
matrix (assign-topology matrix problem)] | |
matrix)) | |
(defn flooded? | |
[v] | |
(= v 2)) | |
(defn dry? | |
[v] | |
(= v 0)) | |
(defn flooded-area-in-row | |
"Returns the indices of the flooded area in a row." | |
[row] | |
(reverse | |
(:area | |
(reduce (fn [{:keys [area pred-is-flooded index] :as acc} v] | |
(cond (and (flooded? v) pred-is-flooded) | |
(let [head (conj (first area) index)] | |
(assoc acc | |
:area (conj (rest area) head) | |
:index (inc index) | |
:pred-is-flooded true)) | |
(flooded? v) | |
(assoc acc | |
:area (conj area [index]) | |
:index (inc index) | |
:pred-is-flooded true) | |
:else (assoc acc | |
:index (inc index) | |
:pred-is-flooded false))) | |
{:pred-is-flooded false | |
:area () | |
:index 0} | |
row)))) | |
(defn flow | |
[matrix]) | |
(defn can-flow-left? | |
[matrix x y] | |
(or (= x 0) | |
(dry? (get-xy matrix (dec x) y)))) | |
(defn can-flow-right? | |
[matrix x y] | |
(or (= x (dec (count matrix))) | |
(dry? (get-xy matrix (inc x) y)))) | |
(defn can-flow? | |
[matrix x y] | |
(and (can-flow-left? matrix x y) | |
(can-flow-right? matrix x y))) | |
(defn dry-cell | |
[matrix x y] | |
(reduce (fn [matrix offset] | |
(assoc-xy matrix x (+ y offset) 0)) | |
matrix | |
(range (- (count matrix) y)))) | |
(defn try-dry-cell | |
[matrix x y] | |
(if (or (can-flow-left? matrix x y) | |
(can-flow-right? matrix x y)) | |
(dry-cell matrix x y) | |
matrix)) | |
(defn dry-row | |
[matrix y] | |
(let [area (flooded-area-in-row (get-row matrix y))] | |
(reduce (fn [matrix one-area] | |
(let [front (first one-area) | |
back (last one-area) | |
middle (butlast (rest one-area)) | |
matrix (try-dry-cell matrix front y) | |
matrix (if (nil? middle) matrix | |
(reduce (fn [matrix x] | |
(try-dry-cell matrix x y)) | |
matrix middle)) | |
matrix (if (nil? back) matrix | |
(try-dry-cell matrix back y))] | |
matrix)) | |
matrix | |
area))) | |
(defn dry-matrix | |
[matrix] | |
(reduce (fn [matrix y] | |
(dry-row matrix y)) | |
matrix | |
(range (count matrix)))) | |
(defn find-solution | |
[matrix] | |
(some (fn [[m1 m2]] | |
(when (= m1 m2) | |
m1)) | |
(partition 2 (iterate dry-matrix matrix)))) | |
(def problem1 [2 3 1 1 3 2 1 1]) | |
(def problem2 [2 3 1 1 3 2 1 2]) | |
(defn -main | |
[] | |
(print-matrix (find-solution (create-matrix problem1)))) | |
;; (-main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
the dry-row function should call try-dry-cell on the back element before calling it on the middle elements