Further work on the Falls of Clyde problem, and on optimisation.
This commit is contained in:
parent
1c8d8c4219
commit
337d1ae07e
|
@ -22,22 +22,45 @@
|
||||||
`cell` and for which this cell is the lowest neighbour, or which are at the
|
`cell` and for which this cell is the lowest neighbour, or which are at the
|
||||||
same altitude and have greater flow"
|
same altitude and have greater flow"
|
||||||
[world cell]
|
[world cell]
|
||||||
(remove nil?
|
(filter #(map? %)
|
||||||
(into []
|
|
||||||
(map
|
(map
|
||||||
(fn [n]
|
(fn [n]
|
||||||
(cond (= cell (get-least-cell (get-neighbours world n) :altitude)) n
|
(cond
|
||||||
(and (= (:altitude cell) (:altitude n))(> (or (:flow n) 0) (or (:flow cell) 0))) n))
|
(= cell (get-least-cell (get-neighbours world n) :altitude)) n
|
||||||
(get-neighbours-with-property-value world (:x cell) (:y cell) 1
|
(and (= (:altitude cell) (:altitude n))
|
||||||
:altitude
|
(> (or (:flow n) 0) (or (:flow cell) 0))) n))
|
||||||
(or (:altitude cell) 0) >=)))))
|
(get-neighbours-with-property-value
|
||||||
|
world (:x cell) (:y cell) 1 :altitude
|
||||||
|
(or (:altitude cell) 0) >=))))
|
||||||
|
|
||||||
|
(defn is-hollow
|
||||||
|
"Detects point hollows - that is, individual cells all of whose neighbours
|
||||||
|
are higher. Return true if this `cell` has an altitude lower than any of
|
||||||
|
its neighbours in this `world`"
|
||||||
|
[world cell]
|
||||||
|
;; quicker to count the elements of the list and compare equality of numbers
|
||||||
|
;; than recursive equality check on members, I think. But worth benchmarking.
|
||||||
|
(let [neighbours (get-neighbours world cell)
|
||||||
|
altitude (or (:altitude cell) 0)]
|
||||||
|
(= (count neighbours)
|
||||||
|
(count (get-neighbours-with-property-value
|
||||||
|
world (:x cell) (:y cell) 1 :altitude >)))))
|
||||||
|
|
||||||
(defn flood-hollow
|
(defn flood-hollow
|
||||||
"Raise the altitude of a copy of this `cell` of this `world` to one unit above the lowest of these `neighbours`, and reflow."
|
"Raise the altitude of a copy of this `cell` of this `world` to the altitude
|
||||||
[cell world neighbours]
|
of the lowest of its `neighbours`."
|
||||||
|
([world cell neighbours]
|
||||||
(let [lowest (get-least-cell neighbours :altitude)]
|
(let [lowest (get-least-cell neighbours :altitude)]
|
||||||
(flow world (merge cell {:altitude (+ (:altitude lowest) 1)}))))
|
(merge cell {:state :water :altitude (:altitude lowest)})))
|
||||||
;; cell)
|
([world cell]
|
||||||
|
(flood-hollow world cell (get-neighbours world cell))))
|
||||||
|
|
||||||
|
(defn flood-hollows
|
||||||
|
"Flood all local hollows in this `world`. At this stage only floods single
|
||||||
|
cell hollows."
|
||||||
|
[world]
|
||||||
|
(map-world world
|
||||||
|
#(if (is-hollow %1 %2) (flood-hollow %1 %2) %2)))
|
||||||
|
|
||||||
(def flow
|
(def flow
|
||||||
"Compute the total flow upstream of this `cell` in this `world`, and return a cell identical
|
"Compute the total flow upstream of this `cell` in this `world`, and return a cell identical
|
||||||
|
@ -52,17 +75,11 @@
|
||||||
(not (nil? (:flow cell))) cell
|
(not (nil? (:flow cell))) cell
|
||||||
(<= (or (:altitude cell) 0) *sealevel*) cell
|
(<= (or (:altitude cell) 0) *sealevel*) cell
|
||||||
true
|
true
|
||||||
(let [contributors (flow-contributors world cell)]
|
|
||||||
;; (if
|
|
||||||
;; (= (count contributors) 8)
|
|
||||||
;; local lowspot - lake bottom
|
|
||||||
;; (flood-hollow cell world contributors)
|
|
||||||
;; otherwise...
|
|
||||||
(merge cell
|
(merge cell
|
||||||
{:flow (+ (:rainfall cell)
|
{:flow (+ (:rainfall cell)
|
||||||
(apply +
|
(apply +
|
||||||
(map (fn [neighbour] (:flow (flow world neighbour)))
|
(map (fn [neighbour] (:flow (flow world neighbour)))
|
||||||
(flow-contributors world cell))))}))))))
|
(flow-contributors world cell))))})))))
|
||||||
|
|
||||||
(defn flow-world
|
(defn flow-world
|
||||||
"Return a world like this `world`, but with cells tagged with the amount of
|
"Return a world like this `world`, but with cells tagged with the amount of
|
||||||
|
|
|
@ -106,6 +106,16 @@
|
||||||
[cell species]
|
[cell species]
|
||||||
(get-int cell species))
|
(get-int cell species))
|
||||||
|
|
||||||
|
(def memo-get-neighbours
|
||||||
|
"Memoised core primitive for `get-neighbours` for efficiency."
|
||||||
|
(memoize
|
||||||
|
(fn [world x y depth]
|
||||||
|
(remove nil?
|
||||||
|
(map #(get-cell world (first %) (first (rest %)))
|
||||||
|
(remove #(= % (list x y))
|
||||||
|
(combo/cartesian-product
|
||||||
|
(range (- x depth) (+ x depth 1))
|
||||||
|
(range (- y depth) (+ y depth 1)))))))))
|
||||||
|
|
||||||
(defn get-neighbours
|
(defn get-neighbours
|
||||||
"Get the neighbours to distance depth of the cell at x, y in this world.
|
"Get the neighbours to distance depth of the cell at x, y in this world.
|
||||||
|
@ -116,12 +126,7 @@
|
||||||
* `depth` an integer representing the distance from [x,y] that
|
* `depth` an integer representing the distance from [x,y] that
|
||||||
should be searched."
|
should be searched."
|
||||||
([world x y depth]
|
([world x y depth]
|
||||||
(remove nil?
|
(memo-get-neighbours world x y depth))
|
||||||
(map #(get-cell world (first %) (first (rest %)))
|
|
||||||
(remove #(= % (list x y))
|
|
||||||
(combo/cartesian-product
|
|
||||||
(range (- x depth) (+ x depth 1))
|
|
||||||
(range (- y depth) (+ y depth 1)))))))
|
|
||||||
([world cell depth]
|
([world cell depth]
|
||||||
"Get the neighbours to distance depth of this cell in this world.
|
"Get the neighbours to distance depth of this cell in this world.
|
||||||
|
|
||||||
|
@ -129,7 +134,7 @@
|
||||||
* `cell` a cell within that world;
|
* `cell` a cell within that world;
|
||||||
* `depth` an integer representing the distance from [x,y] that
|
* `depth` an integer representing the distance from [x,y] that
|
||||||
should be searched."
|
should be searched."
|
||||||
(get-neighbours world (:x cell) (:y cell) depth))
|
(memo-get-neighbours world (:x cell) (:y cell) depth))
|
||||||
([world cell]
|
([world cell]
|
||||||
"Get the immediate neighbours of this cell in this world
|
"Get the immediate neighbours of this cell in this world
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue