|
1 | | -(ns otus-04.homework.crossword-puzzle) |
| 1 | +(ns otus-04.homework.crossword-puzzle |
| 2 | + (:require |
| 3 | + [clojure.string :as string])) |
2 | 4 |
|
3 | | -;; Оригинал: |
4 | | -;; https://www.hackerrank.com/challenges/crossword-puzzle/problem |
5 | | - |
6 | | -(defn solve |
7 | | - "Возвращает решённый кроссворд. Аргумент является строкой вида |
| 5 | +"Возвращает решённый кроссворд. Аргумент является строкой вида |
8 | 6 |
|
9 | 7 | +-++++++++ |
10 | 8 | +-++++++++ |
|
22 | 20 | '-' отмечены клетки для вписывания букв. В последней строке перечислены |
23 | 21 | слова, которые нужно 'вписать' в 'клетки'. Слова могут быть вписаны |
24 | 22 | сверху-вниз или слева-направо." |
| 23 | + |
| 24 | +;; Оригинал: |
| 25 | +;; https://www.hackerrank.com/challenges/crossword-puzzle/problem |
| 26 | + |
| 27 | +(def empty-s |
| 28 | + (str |
| 29 | + "----------\n" |
| 30 | + "----------\n" |
| 31 | + "----------\n" |
| 32 | + "----------\n" |
| 33 | + "----------\n" |
| 34 | + "----------\n" |
| 35 | + "----------\n" |
| 36 | + "----------\n" |
| 37 | + "----------\n" |
| 38 | + "----------\n")) |
| 39 | + |
| 40 | +(def s |
| 41 | + (str |
| 42 | + "+-++++++++\n" |
| 43 | + "+-++++++++\n" |
| 44 | + "+-++++++++\n" |
| 45 | + "+-----++++\n" |
| 46 | + "+-+++-++++\n" |
| 47 | + "+-+++-++++\n" |
| 48 | + "+++++-++++\n" |
| 49 | + "++------++\n" |
| 50 | + "+++++-++++\n" |
| 51 | + "+++++-++++\n")) |
| 52 | + |
| 53 | +(def london-s |
| 54 | + (str |
| 55 | + "+L++++++++\n" |
| 56 | + "+O++++++++\n" |
| 57 | + "+N++++++++\n" |
| 58 | + "+D----++++\n" |
| 59 | + "+O+++-++++\n" |
| 60 | + "+N+++-++++\n" |
| 61 | + "+++++-++++\n" |
| 62 | + "++------++\n" |
| 63 | + "+++++-++++\n" |
| 64 | + "+++++-++++\n")) |
| 65 | + |
| 66 | +(def filled |
| 67 | + (str |
| 68 | + "+l++++++++\n" |
| 69 | + "+o++++++++\n" |
| 70 | + "+n++++++++\n" |
| 71 | + "+delhi++++\n" |
| 72 | + "+o+++c++++\n" |
| 73 | + "+n+++e++++\n" |
| 74 | + "+++++l++++\n" |
| 75 | + "++ankara++\n" |
| 76 | + "+++++n++++\n" |
| 77 | + "+++++d++++\n")) |
| 78 | + |
| 79 | +(def input |
| 80 | + "+-++++++++ |
| 81 | + +-++++++++ |
| 82 | + +-++++++++ |
| 83 | + +-----++++ |
| 84 | + +-+++-++++ |
| 85 | + +-+++-++++ |
| 86 | + +++++-++++ |
| 87 | + ++------++ |
| 88 | + +++++-++++ |
| 89 | + +++++-++++ |
| 90 | + LONDON;DELHI;ICELAND;ANKARA") |
| 91 | + |
| 92 | +(def input1 |
| 93 | + |
| 94 | + "++++++-+++ |
| 95 | +++------++ |
| 96 | +++++++-+++ |
| 97 | +++++++-+++ |
| 98 | ++++------+ |
| 99 | +++++++-+-+ |
| 100 | +++++++-+-+ |
| 101 | +++++++++-+ |
| 102 | +++++++++-+ |
| 103 | +++++++++-+ |
| 104 | +ICELAND;MEXICO;PANAMA;ALMATY") |
| 105 | + |
| 106 | +(defn parse-to-s [s] |
| 107 | + (let [lines (clojure.string/split s #"\n") |
| 108 | + box (vec (map clojure.string/trim (take 10 lines))) |
| 109 | + words (clojure.string/split (clojure.string/trim (last lines)) #";")] |
| 110 | + [box, words])) |
| 111 | + |
| 112 | +(defn change-char-at [s pos new-char] |
| 113 | + (if (< pos (count s)) |
| 114 | + (let [before (subs s 0 pos) |
| 115 | + after (subs s (inc pos))] |
| 116 | + (str before new-char after)) |
| 117 | + s)) |
| 118 | + |
| 119 | +(defn change-box [box row col new-char] |
| 120 | + (let [line (nth box row) |
| 121 | + new-line (change-char-at line col new-char)] |
| 122 | + (assoc-in box [row] new-line))) |
| 123 | + |
| 124 | +(defn can-fit-s? [box row col c] |
| 125 | + (let [existing (nth (nth box row) col)] |
| 126 | + (or (= existing \-) (= existing c)))) |
| 127 | + |
| 128 | +(defn put-in-row-s [box row col word] |
| 129 | + (if (or (> col (- (count (nth box 0)) 1)) (> row (- (count box) 1))) nil |
| 130 | + (let [len (count (nth box 0)) word-len (count word)] |
| 131 | + (loop [index col |
| 132 | + word-index 0 |
| 133 | + can-fit (can-fit-s? box row col (nth word word-index)) |
| 134 | + new-box box] |
| 135 | + (if (or (= index len) (= word-index word-len)) |
| 136 | + (if (and can-fit (= word-index word-len)) new-box nil) |
| 137 | + (recur |
| 138 | + (+ 1 index) |
| 139 | + (+ 1 word-index) |
| 140 | + (and can-fit (can-fit-s? new-box row index (nth word word-index))) |
| 141 | + (change-box new-box row index (nth word word-index)))))))) |
| 142 | + |
| 143 | +(defn put-in-column-s [box row col word] |
| 144 | + (let [len (count box) |
| 145 | + word-len (count word)] |
| 146 | + (loop [row-index row |
| 147 | + word-index 0 |
| 148 | + can-fit (can-fit-s? box row col (nth word word-index)) |
| 149 | + new-box box] |
| 150 | + (if (or (= row-index len) (= word-index word-len)) |
| 151 | + (if (and can-fit (= word-index word-len)) new-box nil) |
| 152 | + (recur |
| 153 | + (+ 1 row-index) |
| 154 | + (+ 1 word-index) |
| 155 | + (and can-fit (can-fit-s? new-box row-index col (nth word word-index))) |
| 156 | + (change-box new-box row-index col (nth word word-index))))))) |
| 157 | + |
| 158 | +(defn is-filled-s [box] |
| 159 | + (reduce (fn [a e] (and a (not (some (fn [c] (= \- c)) e)))) true box)) |
| 160 | + |
| 161 | +(defn get-positions [box] |
| 162 | + (let [len (- (count box) 1)] |
| 163 | + (loop |
| 164 | + [row 0 |
| 165 | + col 0 |
| 166 | + positions []] |
| 167 | + (if (and (= row len) (= col len)) |
| 168 | + positions |
| 169 | + (recur |
| 170 | + (if (= col len) (+ row 1) row) |
| 171 | + (if (= col len) 0 (+ col 1)) |
| 172 | + (if (= \- (get-in box [row col])) (conj positions [row col]) positions)))))) |
| 173 | + |
| 174 | +(defn gen-s [box positions word] |
| 175 | + (let [columns (filter some? (map (fn [[row col]] (put-in-column-s box row col word)) positions)) |
| 176 | + rows (filter some? (map (fn [[row col]] (put-in-row-s box row col word)) positions))] |
| 177 | + (concat columns rows))) |
| 178 | + |
| 179 | +(defn solve |
25 | 180 | [input] |
26 | | - "") |
| 181 | + (let [[box, words] (parse-to-s input) |
| 182 | + words-len (count words) |
| 183 | + positions (get-positions box) |
| 184 | + variants (gen-s box positions (nth words 0))] |
| 185 | + (loop [word-index 1 v variants found ()] |
| 186 | + (if (or (= word-index words-len) (not-empty found)) (clojure.string/join "\n" (first v)) |
| 187 | + (recur |
| 188 | + (inc word-index) |
| 189 | + (mapcat identity (map (fn [b] (gen-s b positions (nth words word-index))) v)) |
| 190 | + (filter is-filled-s v)))))) |
| 191 | + |
| 192 | +; (solve input1) |
0 commit comments