From 20eb867ccc3f8949297457463562843dd811be04 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Tue, 9 May 2023 10:20:44 +0300 Subject: [PATCH 1/5] Homework2: is-palindrome --- otus-02/src/otus_02/homework/palindrome.clj | 22 +++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/otus-02/src/otus_02/homework/palindrome.clj b/otus-02/src/otus_02/homework/palindrome.clj index dd3d8a4..2f51bf1 100644 --- a/otus-02/src/otus_02/homework/palindrome.clj +++ b/otus-02/src/otus_02/homework/palindrome.clj @@ -1,4 +1,22 @@ -(ns otus-02.homework.palindrome) +(ns otus-02.homework.palindrome + (:require [clojure.string :as str])) + +(defn is-palindrome [test-string] + (let [original (str/lower-case + (str/replace test-string #",|!|\?|\.|\s" "")) + reversed (str/reverse original)] + (= original reversed))) + + + + + + + + + + + + -(defn is-palindrome [test-string]) From 8c2581504ae2e838d1b2b7635d930106944981d4 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Tue, 9 May 2023 12:44:39 +0300 Subject: [PATCH 2/5] Homework2: is-pangram --- otus-02/src/otus_02/homework/pangram.clj | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/otus-02/src/otus_02/homework/pangram.clj b/otus-02/src/otus_02/homework/pangram.clj index cc35c99..d6cad09 100644 --- a/otus-02/src/otus_02/homework/pangram.clj +++ b/otus-02/src/otus_02/homework/pangram.clj @@ -1,4 +1,10 @@ -(ns otus-02.homework.pangram) +(ns otus-02.homework.pangram + (:require [clojure.string :as str])) +(defn is-char [ch] (Character/isLetter ch)) -(defn is-pangram [test-string]) +(defn is-pangram [test-string] + (let + [tested-char-set (set (filter is-char (str/lower-case test-string))) + all-chars (set (map char (range (int \a) (inc (int \z)))))] + (= tested-char-set all-chars))) From 13fb73c5045c11942e09ceb1956ecb4de1d146f2 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Tue, 9 May 2023 16:35:45 +0300 Subject: [PATCH 3/5] Homework2: common-child-length --- otus-02/src/otus_02/homework/common_child.clj | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/otus-02/src/otus_02/homework/common_child.clj b/otus-02/src/otus_02/homework/common_child.clj index 04c5e8a..336b605 100644 --- a/otus-02/src/otus_02/homework/common_child.clj +++ b/otus-02/src/otus_02/homework/common_child.clj @@ -1,8 +1,8 @@ (ns otus-02.homework.common-child) -;; Строка называется потомком другой строки, -;; если она может быть образована путем удаления 0 или более символов из другой строки. +;; Строка S называется потомком другой строки P, +;; если она (S) может быть образована путем удаления 0 или более символов из другой строки (P). ;; Буквы нельзя переставлять. ;; Имея две строки одинаковой длины, какую самую длинную строку можно построить так, ;; чтобы она была потомком обеих строк? @@ -16,4 +16,39 @@ ;; Еще пример HARRY и SALLY. Ответ будет - 2, так как общий элемент у них AY -(defn common-child-length [fist-string second-string]) +;; Хелпер, который строит следующую строку dynamic programming таблицы по текущей +(defn next-row-helper [x y-seq row] + (loop [y-seq y-seq + row row + next-row '(0)] + (if (empty? y-seq) + next-row + (let [y (first y-seq) + top-left (first row) + top (first (rest row)) + left (first next-row)] + (if (= x y) + (recur + (rest y-seq) + (rest row) + (conj next-row (inc top-left))) + (recur + (rest y-seq) + (rest row) + (conj next-row (max top left)))))))) + +;; По сути это задача на нахождение LCS (longest common subsequence) +;; Решение - dynamic programming, но без хранения всей таблицы в памяти, а только 2х строк: предыдущей и текущей +;; Ячейка на последней строке и последней строчке и будет является LCS +(defn common-child-length [x y] + (first + (let [x-seq (seq x) + y-seq (seq y)] + (loop [ + x-seq x-seq + row (repeat (inc (count y-seq)) 0)] + (if (empty? x-seq) + row + (recur + (rest x-seq) + (next-row-helper (first x-seq) y-seq (reverse row)))))))) \ No newline at end of file From 9c164737167e98bf7220baf3e9588cc4d369bc1c Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Tue, 9 May 2023 22:04:29 +0300 Subject: [PATCH 4/5] Homework2: square-code --- otus-02/src/otus_02/homework/square_code.clj | 49 +++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/otus-02/src/otus_02/homework/square_code.clj b/otus-02/src/otus_02/homework/square_code.clj index 823a185..2c892a0 100644 --- a/otus-02/src/otus_02/homework/square_code.clj +++ b/otus-02/src/otus_02/homework/square_code.clj @@ -1,4 +1,5 @@ -(ns otus-02.homework.square-code) +(ns otus-02.homework.square-code + (:require [clojure.string :as str])) ;; Реализовать классический метод составления секретных сообщений, называемый `square code`. ;; Выведите закодированную версию полученного текста. @@ -13,6 +14,9 @@ ;; нормализуется в строку: "ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots" +(defn is-letter [c] (Character/isLetter c)) +(defn normalize [s] (filter is-letter (str/lower-case s))) + ;; Разбиваем текст в виде прямоугольника. ;; Размер прямоугольника (rows, cols) должен определяться длиной сообщения, ;; так что c >= r и c - r <= 1, где c — количество столбцов, а r — количество строк. @@ -26,15 +30,51 @@ "vegivenu" "sroots " +;; Чтение стобцов слева-направо в строку +(defn read-rectangle [rectangle] + (apply str + (loop [result '() + rectangle rectangle] + (if (empty? (first rectangle)) + result + (recur + (concat result (map first rectangle)) + (map rest rectangle)))))) + ;; Закодированное сообщение получается путем чтения столбцов слева направо. ;; Сообщение выше закодировано как: "imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau" +(defn encode-helper [input] + (let [normalized (normalize input) + cnt (count normalized) + r (int (Math/sqrt cnt)) + c (if (< (* r r) cnt) (inc r) r) + rectangle (partition-all c normalized)] + (read-rectangle rectangle))) ;; Полученный закодированный текст разбиваем кусками, которые заполняют идеальные прямоугольники (r X c), ;; с кусочками c длины r, разделенными пробелами. ;; Для фраз, которые на n символов меньше идеального прямоугольника, ;; дополните каждый из последних n фрагментов одним пробелом в конце. "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau " +(defn encode-string [input] + (let [ + input (encode-helper input) + cnt (count input) + cols-cnt (int (Math/sqrt cnt)) + rows-cnt (if (< (* cols-cnt cols-cnt) cnt) (inc cols-cnt) cols-cnt) + incomplete-cnt (- (* rows-cnt cols-cnt) cnt) + complete-cnt (- rows-cnt incomplete-cnt) + sub-str-cnt (* complete-cnt cols-cnt) + complete-sub-str (subs input 0 sub-str-cnt) + incomplete-sub-str (subs input sub-str-cnt) + complete-slices (partition-all cols-cnt complete-sub-str) + incomplete-slices (partition-all (dec cols-cnt) incomplete-sub-str)] + (str/join + " " + (concat + (map #(apply str %) complete-slices) + (map #(apply str (concat % '(\space))) incomplete-slices))))) ;; Обратите внимание, что если бы мы сложили их, ;; мы могли бы визуально декодировать зашифрованный текст обратно в исходное сообщение: @@ -48,9 +88,6 @@ "aohghn " "sseoau " +(defn decode-string [input] + (read-rectangle (str/split input #"\s+"))) - -(defn encode-string [input]) - - -(defn decode-string [input]) From 498677ba201818a79f3479b42231a45564ccda05 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Thu, 11 May 2023 11:00:27 +0300 Subject: [PATCH 5/5] Homework2: dedoublicate a little bit --- otus-02/src/otus_02/homework/common_child.clj | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/otus-02/src/otus_02/homework/common_child.clj b/otus-02/src/otus_02/homework/common_child.clj index 336b605..a321fd2 100644 --- a/otus-02/src/otus_02/homework/common_child.clj +++ b/otus-02/src/otus_02/homework/common_child.clj @@ -26,16 +26,12 @@ (let [y (first y-seq) top-left (first row) top (first (rest row)) - left (first next-row)] - (if (= x y) + left (first next-row) + d (if (= x y) (inc top-left) (max top left))] (recur (rest y-seq) (rest row) - (conj next-row (inc top-left))) - (recur - (rest y-seq) - (rest row) - (conj next-row (max top left)))))))) + (conj next-row d)))))) ;; По сути это задача на нахождение LCS (longest common subsequence) ;; Решение - dynamic programming, но без хранения всей таблицы в памяти, а только 2х строк: предыдущей и текущей