Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
106
Task/Maze-solving/Clojure/maze-solving.clj
Normal file
106
Task/Maze-solving/Clojure/maze-solving.clj
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
(ns small-projects.find-shortest-way
|
||||
(:require [clojure.string :as str]))
|
||||
|
||||
;Misk functions
|
||||
(defn cell-empty? [maze coords]
|
||||
(= :empty (get-in maze coords)))
|
||||
|
||||
(defn wall? [maze coords]
|
||||
(= :wall (get-in maze coords)))
|
||||
|
||||
(defn track? [maze coords]
|
||||
(= :track (get-in maze coords)))
|
||||
|
||||
(defn get-neighbours [maze [y x cell]]
|
||||
[[y (dec x)] [(inc y) x] [y (inc x)] [(dec y) x]])
|
||||
|
||||
(defn get-difference [coll1 filter-coll]
|
||||
(filter #(not (contains? filter-coll %)) coll1))
|
||||
|
||||
(defn get-empties [maze cell]
|
||||
(->> (get-neighbours maze cell)
|
||||
(filter (partial cell-empty? maze))))
|
||||
|
||||
(defn possible-ways [maze cell filter-coll]
|
||||
(-> (get-empties maze cell)
|
||||
(get-difference filter-coll)))
|
||||
|
||||
(defn replace-cells [maze coords v]
|
||||
(if (empty? coords)
|
||||
maze
|
||||
(recur (assoc-in maze (first coords) v) (rest coords) v)))
|
||||
|
||||
;Print and parse functions
|
||||
(def cell-code->str
|
||||
[" " " " " " " " "· " "╵ " "╴ " "┘ "
|
||||
" " " " " " " " "╶─" "└─" "──" "┴─"
|
||||
" " " " " " " " "╷ " "│ " "┐ " "┤ "
|
||||
" " " " " " " " "┌─" "├─" "┬─" "┼─"
|
||||
" " " " " " " " "■ " "╹ " "╸ " "┛ "
|
||||
" " " " " " " " "╺━" "┗━" "━━" "┻━"
|
||||
" " " " " " " " "╻ " "┃ " "┓ " "┫ "
|
||||
" " " " " " " " "┏━" "┣━" "┳━" "╋━"
|
||||
" "])
|
||||
|
||||
(defn get-cell-code [maze coords]
|
||||
(let [mode (if (track? maze coords) 1 0)
|
||||
check (if (zero? mode) wall? track?)]
|
||||
(transduce
|
||||
(comp
|
||||
(map (partial check maze))
|
||||
(keep-indexed (fn [idx test] (when test idx)))
|
||||
(map (partial bit-shift-left 1)))
|
||||
(completing bit-or)
|
||||
(bit-shift-left mode 5)
|
||||
(sort (conj (get-neighbours maze coords) coords)))))
|
||||
|
||||
(defn code->str [cell-code]
|
||||
(nth cell-code->str cell-code))
|
||||
|
||||
(defn maze->str-symbols [maze]
|
||||
(for [y (range (count maze))]
|
||||
(for [x (range (count (nth maze y)))]
|
||||
(code->str (get-cell-code maze [y x])))))
|
||||
|
||||
(defn maze->str [maze]
|
||||
(->> (maze->str-symbols maze)
|
||||
(map str/join)
|
||||
(str/join "\n")))
|
||||
|
||||
(defn parse-pretty-maze [maze-str]
|
||||
(->> (str/split-lines maze-str)
|
||||
(map (partial take-nth 2))
|
||||
(map (partial map #(if (= \space %) :empty :wall)))
|
||||
(map vec)
|
||||
(vec)))
|
||||
|
||||
;Core
|
||||
(defn find-new-border [maze border old-border]
|
||||
(apply conj (map (fn [cell]
|
||||
(zipmap (possible-ways maze cell (conj border old-border))
|
||||
(repeat cell)))
|
||||
(keys border))))
|
||||
|
||||
(defn backtrack [visited route]
|
||||
(let [cur-cell (get visited (first route))]
|
||||
(if (= cur-cell :start)
|
||||
route
|
||||
(recur visited (conj route cur-cell)))))
|
||||
|
||||
(defn breadth-first-search [maze start-cell end-cell]
|
||||
(loop [visited {start-cell :start}
|
||||
border {start-cell :start}
|
||||
old-border {start-cell :start}]
|
||||
(if (contains? old-border end-cell)
|
||||
(backtrack visited (list end-cell))
|
||||
(recur
|
||||
(conj visited border)
|
||||
(find-new-border maze border old-border)
|
||||
border))))
|
||||
|
||||
(def maze (parse-pretty-maze maze-str))
|
||||
|
||||
(def solved-maze
|
||||
(replace-cells maze (breadth-first-search maze [1 1] [19 19]) :track))
|
||||
|
||||
(println (maze->str solved-maze))
|
||||
Loading…
Add table
Add a link
Reference in a new issue