From a9cbcee00af7d280c4058f5ff62226956910073b Mon Sep 17 00:00:00 2001 From: Artur Taranchiev Date: Sun, 7 Jul 2024 05:29:29 +0000 Subject: [PATCH 1/4] homework-02 - first part --- otus-02/src/otus_02/homework/palindrome.clj | 82 ++++++++++++++++++++- otus-02/src/otus_02/homework/pangram.clj | 13 +++- 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/otus-02/src/otus_02/homework/palindrome.clj b/otus-02/src/otus_02/homework/palindrome.clj index 591f98e..b5937e3 100644 --- a/otus-02/src/otus_02/homework/palindrome.clj +++ b/otus-02/src/otus_02/homework/palindrome.clj @@ -1,6 +1,86 @@ (ns otus-02.homework.palindrome (:require [clojure.string :as string])) +(def ^:private alpha (set "abcdefghijklmnopqrstuvwxyz")) -(defn is-palindrome [test-string]) +(defn is-palindrome + [test-string] + (->> test-string + (string/lower-case) + (filter #(contains? alpha %1)) + (#(= %1 (reverse %1))))) +(defn is-palindrome-0 + "Using vector instead of seq." + [test-string] + (->> test-string + (string/lower-case) + (vec) + (filterv #(contains? alpha %1)) + (#(= %1 (reverse %1))))) + +(defn is-palindrome-1 + "Using rseq instead of reverse." + [test-string] + (->> test-string + (string/lower-case) + (vec) + (filterv #(contains? alpha %1)) + (#(= %1 (rseq %1))))) + +(defn is-palindrome-2 + "More efficient. Using filter based on ascii code. 3.5X to speed from the first implementation." + [test-string] + (->> test-string + (string/lower-case) + (vec) + (filterv #(let [i (int %1)] (and (> i 96) (< i 123)))) + (#(= %1 (rseq %1))))) + +(comment + (do (time (dotimes [_ 10000] + (is-palindrome "civic") + (is-palindrome "tattarrattat") + (is-palindrome "taco cat") + (is-palindrome "no lemon, no melon") + (is-palindrome "Eva, can I see bees in a cave?") + (is-palindrome "Was it a cat I saw?") + (not (is-palindrome "civics")) + (not (is-palindrome "They all have one thing")) + (not (is-palindrome "knock on the door")))) + (time (dotimes [_ 10000] + (is-palindrome-0 "civic") + (is-palindrome-0 "tattarrattat") + (is-palindrome-0 "taco cat") + (is-palindrome-0 "no lemon, no melon") + (is-palindrome-0 "Eva, can I see bees in a cave?") + (is-palindrome-0 "Was it a cat I saw?") + (not (is-palindrome-0 "civics")) + (not (is-palindrome-0 "They all have one thing")) + (not (is-palindrome-0 "knock on the door")))) + (time (dotimes [_ 10000] + (is-palindrome-1 "civic") + (is-palindrome-1 "tattarrattat") + (is-palindrome-1 "taco cat") + (is-palindrome-1 "no lemon, no melon") + (is-palindrome-1 "Eva, can I see bees in a cave?") + (is-palindrome-1 "Was it a cat I saw?") + (not (is-palindrome-1 "civics")) + (not (is-palindrome-1 "They all have one thing")) + (not (is-palindrome-1 "knock on the door")))) + (time (dotimes [_ 10000] + (is-palindrome-2 "civic") + (is-palindrome-2 "tattarrattat") + (is-palindrome-2 "taco cat") + (is-palindrome-2 "no lemon, no melon") + (is-palindrome-2 "Eva, can I see bees in a cave?") + (is-palindrome-2 "Was it a cat I saw?") + (not (is-palindrome-2 "civics")) + (not (is-palindrome-2 "They all have one thing")) + (not (is-palindrome-2 "knock on the door")))))) + +;; Difference +; (out) "Elapsed time: 234.478698 msecs" +; (out) "Elapsed time: 110.865521 msecs" +; (out) "Elapsed time: 91.522656 msecs" +; (out) "Elapsed time: 64.476771 msecs" diff --git a/otus-02/src/otus_02/homework/pangram.clj b/otus-02/src/otus_02/homework/pangram.clj index dc5d34c..7681267 100644 --- a/otus-02/src/otus_02/homework/pangram.clj +++ b/otus-02/src/otus_02/homework/pangram.clj @@ -1,6 +1,13 @@ (ns otus-02.homework.pangram - (:require [clojure.string :as string])) + (:require [clojure.string :as string] + [clojure.set :refer [difference]])) +(def ^:private alpha (set "abcdefghijklmnopqrstuvwxyz")) -(defn is-pangram [test-string]) - +(defn is-pangram + [test-string] + (->> test-string + (string/lower-case) + (set) + (difference alpha) + (empty?))) From 03fc8089b07587a8845a0107f2c1b8e213cf0600 Mon Sep 17 00:00:00 2001 From: Artur Taranchiev Date: Thu, 11 Jul 2024 16:01:12 +0600 Subject: [PATCH 2/4] Updates + p2 --- otus-02/src/otus_02/homework/common_child.clj | 54 +++--- otus-02/src/otus_02/homework/lib.clj | 17 ++ otus-02/src/otus_02/homework/palindrome.clj | 83 +++------ otus-02/src/otus_02/homework/pangram.clj | 167 +++++++++++++++++- otus-02/src/otus_02/homework/square_code.clj | 97 +++++----- 5 files changed, 274 insertions(+), 144 deletions(-) create mode 100644 otus-02/src/otus_02/homework/lib.clj diff --git a/otus-02/src/otus_02/homework/common_child.clj b/otus-02/src/otus_02/homework/common_child.clj index f1474f6..57d9d0a 100644 --- a/otus-02/src/otus_02/homework/common_child.clj +++ b/otus-02/src/otus_02/homework/common_child.clj @@ -1,22 +1,32 @@ -(ns otus-02.homework.common-child) - - -;; Строка называется потомком другой строки, -;; если она может быть образована путем удаления 0 или более символов из другой строки. -;; Буквы нельзя переставлять. -;; Имея две строки одинаковой длины, какую самую длинную строку можно построить так, -;; чтобы она была потомком обеих строк? - -;; Например 'ABCD' и 'ABDC' - -;; Эти строки имеют два дочерних элемента с максимальной длиной 3, ABC и ABD. -;; Их можно образовать, исключив D или C из обеих строк. -;; Ответ в данном случае - 3 - -;; Еще пример HARRY и SALLY. Ответ будет - 2, так как общий элемент у них AY - - -(defn common-child-length [first-string second-string]) - - - +(ns otus-02.homework.common-child + (:require [clojure.set :refer [intersection]])) + +(defn common-chars + [f s] + (let [first (set f) second (set s)] (intersection first second))) + +(defn all-subseq + [s] + (set (for [start (range (count s)) + end (range (inc start) (inc (count s)))] + (take (- end start) (drop start s))))) + +(defn common-child-length + [f s] + (let [common-set (common-chars f s) + filtered-f (-> common-set + (filter f) + all-subseq) + filtered-s (-> common-set + (filter s) + all-subseq)] + ((fnil #(apply max %) [0]) + (seq (map count (intersection filtered-f filtered-s)))))) + + +(comment + (doseq [test [(= (common-child-length "SHINCHAN" "NOHARAAA") 3) + (= (common-child-length "HARRY" "SALLY") 2) + (= (common-child-length "AA" "BB") 0) + (= (common-child-length "ABCDEF" "FBDAMN") 2)]] + (prn test))) diff --git a/otus-02/src/otus_02/homework/lib.clj b/otus-02/src/otus_02/homework/lib.clj new file mode 100644 index 0000000..ff1ef93 --- /dev/null +++ b/otus-02/src/otus_02/homework/lib.clj @@ -0,0 +1,17 @@ +(ns otus-02.homework.lib + (:require [clojure.string :as string])) + +(defn- is-alpha? + [c] + (let [i (int c)] + (cond (and (> i 96) (< i 123)) true + (and (> i 64) (< i 91)) true + :else false))) + +(defn normalize + [s] + (->> s + string/lower-case + vec + (filterv is-alpha?) + (apply str))) diff --git a/otus-02/src/otus_02/homework/palindrome.clj b/otus-02/src/otus_02/homework/palindrome.clj index b5937e3..67ed179 100644 --- a/otus-02/src/otus_02/homework/palindrome.clj +++ b/otus-02/src/otus_02/homework/palindrome.clj @@ -1,86 +1,45 @@ (ns otus-02.homework.palindrome - (:require [clojure.string :as string])) + (:require [clojure.string :as string] + [clojure.test :refer [is]])) (def ^:private alpha (set "abcdefghijklmnopqrstuvwxyz")) (defn is-palindrome [test-string] (->> test-string - (string/lower-case) - (filter #(contains? alpha %1)) - (#(= %1 (reverse %1))))) + string/lower-case + (filter alpha) + (#(= % (reverse %))))) (defn is-palindrome-0 "Using vector instead of seq." [test-string] (->> test-string - (string/lower-case) - (vec) - (filterv #(contains? alpha %1)) - (#(= %1 (reverse %1))))) + string/lower-case + (filterv alpha) + (#(= % (reverse %))))) (defn is-palindrome-1 "Using rseq instead of reverse." [test-string] (->> test-string - (string/lower-case) - (vec) - (filterv #(contains? alpha %1)) - (#(= %1 (rseq %1))))) + string/lower-case + (filterv alpha) + (#(= % (rseq %))))) (defn is-palindrome-2 "More efficient. Using filter based on ascii code. 3.5X to speed from the first implementation." [test-string] (->> test-string - (string/lower-case) - (vec) - (filterv #(let [i (int %1)] (and (> i 96) (< i 123)))) - (#(= %1 (rseq %1))))) + string/lower-case + (filterv #(< 96 (int %) 123)) + (#(= % (rseq %))))) (comment - (do (time (dotimes [_ 10000] - (is-palindrome "civic") - (is-palindrome "tattarrattat") - (is-palindrome "taco cat") - (is-palindrome "no lemon, no melon") - (is-palindrome "Eva, can I see bees in a cave?") - (is-palindrome "Was it a cat I saw?") - (not (is-palindrome "civics")) - (not (is-palindrome "They all have one thing")) - (not (is-palindrome "knock on the door")))) - (time (dotimes [_ 10000] - (is-palindrome-0 "civic") - (is-palindrome-0 "tattarrattat") - (is-palindrome-0 "taco cat") - (is-palindrome-0 "no lemon, no melon") - (is-palindrome-0 "Eva, can I see bees in a cave?") - (is-palindrome-0 "Was it a cat I saw?") - (not (is-palindrome-0 "civics")) - (not (is-palindrome-0 "They all have one thing")) - (not (is-palindrome-0 "knock on the door")))) - (time (dotimes [_ 10000] - (is-palindrome-1 "civic") - (is-palindrome-1 "tattarrattat") - (is-palindrome-1 "taco cat") - (is-palindrome-1 "no lemon, no melon") - (is-palindrome-1 "Eva, can I see bees in a cave?") - (is-palindrome-1 "Was it a cat I saw?") - (not (is-palindrome-1 "civics")) - (not (is-palindrome-1 "They all have one thing")) - (not (is-palindrome-1 "knock on the door")))) - (time (dotimes [_ 10000] - (is-palindrome-2 "civic") - (is-palindrome-2 "tattarrattat") - (is-palindrome-2 "taco cat") - (is-palindrome-2 "no lemon, no melon") - (is-palindrome-2 "Eva, can I see bees in a cave?") - (is-palindrome-2 "Was it a cat I saw?") - (not (is-palindrome-2 "civics")) - (not (is-palindrome-2 "They all have one thing")) - (not (is-palindrome-2 "knock on the door")))))) - -;; Difference -; (out) "Elapsed time: 234.478698 msecs" -; (out) "Elapsed time: 110.865521 msecs" -; (out) "Elapsed time: 91.522656 msecs" -; (out) "Elapsed time: 64.476771 msecs" + (doseq [f [is-palindrome is-palindrome-0 is-palindrome-1 is-palindrome-2]] + (time (dotimes [_ 100] + (doseq [s ["civic" "tattarrattat" "taco cat" "no lemon, no melon" + "Eva, can I see bees in a cave?" "Was it a cat I saw?"]] + (is (f s))) + (doseq [s ["civics" "They all have one thing" "knock on the door"]] + (is (not (f s)))))))) diff --git a/otus-02/src/otus_02/homework/pangram.clj b/otus-02/src/otus_02/homework/pangram.clj index 7681267..1d53b09 100644 --- a/otus-02/src/otus_02/homework/pangram.clj +++ b/otus-02/src/otus_02/homework/pangram.clj @@ -1,13 +1,172 @@ (ns otus-02.homework.pangram (:require [clojure.string :as string] - [clojure.set :refer [difference]])) + [clojure.set :refer [difference]] + [clojure.test :refer [is]] + [otus-02.homework.lib :refer [normalize]])) (def ^:private alpha (set "abcdefghijklmnopqrstuvwxyz")) (defn is-pangram [test-string] (->> test-string - (string/lower-case) - (set) + string/lower-case + set (difference alpha) - (empty?))) + empty?)) + +(defn is-pangram-0 + [^String test-string] + (= 26 + (count (->> test-string + normalize + set)))) + +(defn is-pangram-1 + [^String test-string] + (loop [rest-alpha alpha + rest-string (lazy-seq test-string)] + (cond (empty? rest-alpha) true + (empty? rest-string) false + :else (recur (difference rest-alpha + (set (string/lower-case (first + rest-string)))) + (rest rest-string))))) + +(comment + (is-pangram "The quick brown fox jumps over the lazy dog") + (is-pangram-0 "The quick brown fox jumps over the lazy dog") + (is-pangram-1 "The quick brown fox jumps over the lazy dog") + (doseq [f [is-pangram is-pangram-0 is-pangram-1]] + (time + (dotimes [_ 1000] + (doseq + [s ["The quick brown fox jumps over the lazy dog" + " +abcdefghijklmnopqrstuvwxyz +Lorem ipsum dolor sit amet, consectetur adipiscing elit. In at sapien +nibh. Morbi condimentum gravida risus, quis interdum nunc efficitur +nec. Donec sollicitudin, nisi nec gravida gravida, nunc dolor tempor +odio, maximus molestie metus odio ut tellus. Proin semper ligula ut +est tempus congue. In et viverra dui. Nunc quis porttitor felis. In +imperdiet nisi ut urna vehicula malesuada. Aenean magna ex, egestas +eget massa id, fringilla consequat nunc. Integer a rutrum mauris. Proin +congue ut purus vitae finibus. Orci varius natoque penatibus et magnis +dis parturient montes, nascetur ridiculus mus. Maecenas porttitor augue +eget porta efficitur. Nunc sed sapien lectus. Maecenas ac mi dapibus, +porttitor nulla ut, vestibulum lorem. Donec id vehicula lectus. + +Praesent suscipit, magna nec faucibus congue, leo libero rutrum arcu, +sodales aliquet urna odio tincidunt felis. Nulla aliquam hendrerit +nibh. Etiam quis tincidunt odio. Nunc ultricies, libero eget tincidunt +rutrum, massa dui viverra eros, ac convallis erat magna vitae metus. Fusce +vehicula leo lacus, quis luctus turpis dignissim et. Donec ultrices, +tortor vitae faucibus faucibus, lorem arcu euismod enim, vitae venenatis +nibh dui vitae elit. Ut sed faucibus leo, at ornare ex. Pellentesque +ac lobortis metus. Fusce nec justo vitae tellus porta congue quis +vel justo. Curabitur finibus lectus velit, in tempor nibh tincidunt +sed. Donec ex neque, lacinia a erat quis, feugiat aliquet mauris. Donec +laoreet ipsum ac dui tristique consequat. Proin porta eros ex, non dapibus +magna convallis eget. Nam varius imperdiet velit ac dignissim. Duis ac +mi sit amet sapien aliquam hendrerit ac sit amet enim. Nunc a urna a +arcu feugiat mattis. + +Nunc quis suscipit elit. Praesent tincidunt, mauris ut auctor auctor, +urna sem eleifend ex, vitae feugiat nisl tortor id ligula. Suspendisse +potenti. Duis sodales tortor eu tortor posuere commodo. Duis non rhoncus +ligula, nec gravida quam. Mauris iaculis, justo eget dictum vestibulum, +lacus diam pharetra ipsum, eu auctor velit tortor quis libero. Integer +sit amet dolor dui. In et lectus ut mi blandit eleifend. Sed non mauris +massa. Nam vitae libero ac neque porttitor fringilla. Vestibulum pretium, +lorem sed accumsan fringilla, nibh lacus egestas urna, interdum dignissim +urna est et augue. Suspendisse eleifend volutpat enim, et maximus odio +accumsan vitae. + +Proin egestas sapien a interdum molestie. Nulla dapibus pretium +accumsan. Proin nec felis elit. Sed at egestas ipsum. Fusce luctus +odio vitae magna eleifend convallis. Vivamus pulvinar lacus mauris, +lobortis lobortis leo volutpat id. Vivamus feugiat cursus ante, nec +posuere est posuere ac. In eleifend vel est nec faucibus. Sed dolor +lectus, molestie sed nisl dapibus, ullamcorper mollis libero. Nulla +in eros et justo aliquam varius eget sit amet justo. Aenean efficitur +massa vel aliquam vestibulum. In turpis massa, lacinia sed pharetra non, +fringilla quis leo. Pellentesque tincidunt accumsan congue. Praesent in +mauris volutpat, auctor urna quis, tincidunt mauris. Sed posuere gravida +ipsum ac fringilla. + +Sed posuere a sem a tincidunt. Pellentesque lacinia pellentesque ligula eu +sagittis. Nam est arcu, egestas eu ipsum vel, lacinia rhoncus purus. Etiam +eleifend elit eget orci auctor posuere. Sed vel urna non risus mattis +gravida. Proin sodales justo eu congue placerat. Praesent posuere iaculis +laoreet. Praesent fermentum in augue nec ultrices. Aliquam pretium nibh +at nulla convallis commodo sed id ex. Cras sit amet eros ut purus accumsan +lacinia eget in risus. Cras vulputate enim arcu, eu fermentum leo aliquet +eu. Morbi auctor odio sit amet ullamcorper lobortis. Sed at nibh tempus, +lobortis enim nec, pretium enim. In ut dictum arcu. + +Aenean sit amet lacus egestas, scelerisque lacus vitae, luctus +dolor. Donec eleifend nulla augue, et dignissim est commodo id. Morbi +porttitor, dui in feugiat tempor, augue eros viverra ligula, ac facilisis +orci odio sed eros. Nulla vestibulum feugiat dapibus. Curabitur eros +lorem, feugiat a neque lacinia, placerat maximus dui. Proin vitae +felis eleifend, dapibus lectus eu, hendrerit magna. Nunc sapien lorem, +rhoncus eu condimentum nec, placerat sit amet ligula. Nullam elit augue, +sodales quis aliquet eu, auctor in nisi. Sed pulvinar tincidunt felis, +nec tincidunt eros viverra sed. Pellentesque eu vulputate mi, eget +mattis nulla. Donec bibendum volutpat urna in scelerisque. Donec +tincidunt accumsan feugiat. Nunc fringilla odio ut metus maximus, +finibus elementum arcu hendrerit. Interdum et malesuada fames ac ante +ipsum primis in faucibus. Integer enim magna, porta in malesuada congue, +scelerisque ut turpis. Aenean dapibus non purus sed sagittis. + +Aliquam erat volutpat. In sapien nulla, venenatis in facilisis at, +volutpat id orci. Nulla est libero, consequat gravida porta nec, +luctus nec lacus. Donec condimentum est et nisl fermentum auctor. Fusce +id bibendum sem, ac pellentesque sem. Pellentesque auctor sed sem ut +lacinia. Integer non risus vel diam bibendum tempus. Proin ipsum tortor, +ornare ut erat eu, pharetra pellentesque nisi. Donec rutrum ex mauris, +at consequat enim hendrerit in. Nunc lorem velit, condimentum ac commodo +non, placerat vel ante. + +Phasellus sed ipsum dignissim, sodales felis eu, imperdiet +nunc. Vestibulum semper quam ac leo porta, quis hendrerit leo +auctor. Pellentesque malesuada tristique orci, eget fringilla erat gravida +ut. Pellentesque habitant morbi tristique senectus et netus et malesuada +fames ac turpis egestas. Nulla non mi arcu. Nullam venenatis odio eget +mauris pretium, id scelerisque diam aliquam. Quisque non felis ex. Donec +non augue porta, ultrices mi eu, accumsan tellus. Suspendisse arcu ligula, +accumsan non metus ut, semper posuere ipsum. Integer sollicitudin ante eu +massa cursus lacinia. Cras id placerat eros. In sed feugiat lectus. Proin +at eros vel dolor blandit hendrerit vel iaculis leo. Proin non quam sit +amet erat mattis pellentesque sit amet in magna. + +Quisque vel scelerisque est. Donec ultrices condimentum pharetra. Aliquam +rutrum vel massa id maximus. Maecenas vel varius ligula. Praesent vitae +tellus hendrerit, porta lacus ac, auctor lectus. Phasellus a lacus sit +amet ligula rhoncus iaculis. Vestibulum at bibendum turpis. Aenean ac +volutpat metus, vitae pulvinar dolor. Ut a sagittis nulla. Curabitur in +ullamcorper orci. Cras eleifend et tortor eu efficitur. Mauris vitae +turpis ac velit tristique vestibulum in at urna. Aenean porta nunc eu +porttitor malesuada. Vestibulum tortor odio, hendrerit vitae felis ac, +elementum tincidunt tellus. Aliquam gravida quam finibus lorem cursus +pellentesque. + " + "How vexingly quick daft zebras jump" + "Waltz, bad nymph, for quick jigs vex" + "Sphinx of black quartz, judge my vow" + "Jackdaws love my big sphinx of quartz"]] + (is (f s))) + (doseq [s ["The quick brown fox jumps over the dog" + "Keep in mind that"]] + (is (not (f s)))))))) + +;; Without Lorem ipsum +; (out) "Elapsed time: 43.664686 msecs" +; (out) "Elapsed time: 29.749669 msecs" +; (out) "Elapsed time: 52.491599 msecs" + +;; Without Lorem ipsum +; (out) "Elapsed time: 391.425171 msecs" +; (out) "Elapsed time: 475.359696 msecs" +; (out) "Elapsed time: 59.689839 msecs" + +;; is-pangram-1 optimized for large texts. diff --git a/otus-02/src/otus_02/homework/square_code.clj b/otus-02/src/otus_02/homework/square_code.clj index 823a185..83b9f74 100644 --- a/otus-02/src/otus_02/homework/square_code.clj +++ b/otus-02/src/otus_02/homework/square_code.clj @@ -1,56 +1,41 @@ -(ns otus-02.homework.square-code) - -;; Реализовать классический метод составления секретных сообщений, называемый `square code`. -;; Выведите закодированную версию полученного текста. - -;; Во-первых, текст нормализуется: из текста удаляются пробелы и знаки препинания, -;; также текст переводится в нижний регистр. -;; Затем нормализованные символы разбиваются на строки. -;; Эти строки можно рассматривать как образующие прямоугольник при печати их друг под другом. - -;; Например, -"If man was meant to stay on the ground, god would have given us roots." -;; нормализуется в строку: -"ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots" - -;; Разбиваем текст в виде прямоугольника. -;; Размер прямоугольника (rows, cols) должен определяться длиной сообщения, -;; так что c >= r и c - r <= 1, где c — количество столбцов, а r — количество строк. -;; Наш нормализованный текст имеет длину 54 символа -;; и представляет собой прямоугольник с c = 8 и r = 7: -"ifmanwas" -"meanttos" -"tayonthe" -"groundgo" -"dwouldha" -"vegivenu" -"sroots " - -;; Закодированное сообщение получается путем чтения столбцов слева направо. -;; Сообщение выше закодировано как: -"imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau" - -;; Полученный закодированный текст разбиваем кусками, которые заполняют идеальные прямоугольники (r X c), -;; с кусочками c длины r, разделенными пробелами. -;; Для фраз, которые на n символов меньше идеального прямоугольника, -;; дополните каждый из последних n фрагментов одним пробелом в конце. -"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau " - -;; Обратите внимание, что если бы мы сложили их, -;; мы могли бы визуально декодировать зашифрованный текст обратно в исходное сообщение: - -"imtgdvs" -"fearwer" -"mayoogo" -"anouuio" -"ntnnlvt" -"wttddes" -"aohghn " -"sseoau " - - - -(defn encode-string [input]) - - -(defn decode-string [input]) +(ns otus-02.homework.square-code + (:require [otus-02.homework.lib :refer [normalize]] + [clojure.math :as math] + [clojure.string :as string])) + +(defn- get-dimensions + [^Integer length] + (let [sq (math/sqrt length)] + [(-> sq + math/ceil + int) (int sq)])) + + +(defn encode-string + [^String input] + (let [normalized-input (normalize input) + input-size (count normalized-input) + [columns rows] (get-dimensions input-size)] + (->> (concat normalized-input + (repeat (- (* columns rows) input-size) \space)) + (partition columns) + (apply map str) + (string/join \space)))) + +(defn decode-string + [^String input] + (let [input-size (count input) + [_ rows] (get-dimensions input-size)] + (->> (str input \space) + (partition (inc rows)) + (map butlast) + (apply map str) + string/join + string/trimr))) + +(comment + (let + [source + "If man was meant to stay on the ground, god would have given us roots."] + (prn (encode-string source)) + (prn (decode-string (encode-string source))))) From b8cb73af3fc197d64e79886337c0b207e2e40c8d Mon Sep 17 00:00:00 2001 From: Artur Taranchiev Date: Fri, 12 Jul 2024 02:53:07 +0600 Subject: [PATCH 3/4] fix common_child --- otus-02/src/otus_02/homework/common_child.clj | 54 ++++++++++++++----- otus-02/src/otus_02/homework/pangram.clj | 1 + 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/otus-02/src/otus_02/homework/common_child.clj b/otus-02/src/otus_02/homework/common_child.clj index 57d9d0a..b5f4712 100644 --- a/otus-02/src/otus_02/homework/common_child.clj +++ b/otus-02/src/otus_02/homework/common_child.clj @@ -1,32 +1,60 @@ (ns otus-02.homework.common-child - (:require [clojure.set :refer [intersection]])) + (:require [clojure.set :refer [intersection]] + [clojure.string :as string])) (defn common-chars [f s] (let [first (set f) second (set s)] (intersection first second))) -(defn all-subseq +(defn remove-char-at [s i] (str (subs s 0 i) (subs s (inc i)))) + +(defn all-children [s] - (set (for [start (range (count s)) - end (range (inc start) (inc (count s)))] - (take (- end start) (drop start s))))) + (if (empty? s) + #{} + (reduce (fn [result idx] + (let [new-str (remove-char-at s idx)] + (into result (conj (all-children new-str) new-str)))) + #{} + (range (count s))))) -(defn common-child-length +;; Not optimized +;; will take long time to run on elements more then 8 or 9 +;; And does not work on HARRY and SALLY =((( +(defn common-child-length-0 [f s] (let [common-set (common-chars f s) filtered-f (-> common-set (filter f) - all-subseq) + string/join + all-children) filtered-s (-> common-set (filter s) - all-subseq)] + string/join + all-children)] ((fnil #(apply max %) [0]) (seq (map count (intersection filtered-f filtered-s)))))) +;; Using recursion +(defn common-child-length + [^String f ^String s] + (let [inner-f (fn [inner-f-wr idx-f idx-s] + (let [inner-f-mem (partial inner-f-wr inner-f-wr)] + (cond (or (< idx-f 0) (< idx-s 0)) 0 + (= (.charAt f idx-f) (.charAt s idx-s)) + (inc (inner-f-mem (dec idx-f) (dec idx-s))) + :else (max (inner-f-mem (dec idx-f) idx-s) + (inner-f-mem idx-f (dec idx-s)))))) + inner-f-mem (memoize inner-f)] + (inner-f-mem inner-f-mem (dec (count f)) (dec (count s))))) + + (comment - (doseq [test [(= (common-child-length "SHINCHAN" "NOHARAAA") 3) - (= (common-child-length "HARRY" "SALLY") 2) - (= (common-child-length "AA" "BB") 0) - (= (common-child-length "ABCDEF" "FBDAMN") 2)]] - (prn test))) + (doseq [f [common-child-length common-child-length-0]] + (time (doseq [test [(= (f "SHINCHAN" "NOHARAAA") 3) + ; (= (f "SHINCHANSHINCHANSHINCHAN" + ; "NOHARAAANOHARAAANOHARAAA") 9) + (= (f "HARRY" "SALLY") 2) (= (f "AA" "BB") 0) + (= (f "ABCDEF" "FBDAMN") 2)]] + (prn test))))) diff --git a/otus-02/src/otus_02/homework/pangram.clj b/otus-02/src/otus_02/homework/pangram.clj index 1d53b09..3a352c8 100644 --- a/otus-02/src/otus_02/homework/pangram.clj +++ b/otus-02/src/otus_02/homework/pangram.clj @@ -21,6 +21,7 @@ normalize set)))) +;; optimized for large text (defn is-pangram-1 [^String test-string] (loop [rest-alpha alpha From 753816b54e21ad056eb257ee2059781e094f6a58 Mon Sep 17 00:00:00 2001 From: Artur Taranchiev Date: Fri, 12 Jul 2024 02:57:48 +0600 Subject: [PATCH 4/4] fix comment --- otus-02/src/otus_02/homework/pangram.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/otus-02/src/otus_02/homework/pangram.clj b/otus-02/src/otus_02/homework/pangram.clj index 3a352c8..148f4af 100644 --- a/otus-02/src/otus_02/homework/pangram.clj +++ b/otus-02/src/otus_02/homework/pangram.clj @@ -165,7 +165,7 @@ pellentesque. ; (out) "Elapsed time: 29.749669 msecs" ; (out) "Elapsed time: 52.491599 msecs" -;; Without Lorem ipsum +;; With Lorem ipsum ; (out) "Elapsed time: 391.425171 msecs" ; (out) "Elapsed time: 475.359696 msecs" ; (out) "Elapsed time: 59.689839 msecs"