Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 34 additions & 3 deletions otus-02/src/otus_02/homework/common_child.clj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
(ns otus-02.homework.common-child)


;; Строка называется потомком другой строки,
;; если она может быть образована путем удаления 0 или более символов из другой строки.
;; Строка S называется потомком другой строки P,
;; если она (S) может быть образована путем удаления 0 или более символов из другой строки (P).
;; Буквы нельзя переставлять.
;; Имея две строки одинаковой длины, какую самую длинную строку можно построить так,
;; чтобы она была потомком обеих строк?
Expand All @@ -16,4 +16,35 @@
;; Еще пример 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

хорошее решение
есть один совет по стилю. это не ошибка, но иногда приводит в замешательство
y-seq у вас и имя аргумента и имя переменной в цикле
это еще называется variable shadowing - https://en.wikipedia.org/wiki/Variable_shadowing
во многих компаниях это считается не очень хорошим стилем и программисты стараются этого избегать

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Приму к сведению - переделывать не вижу смысла сейчас)

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)
d (if (= x y) (inc top-left) (max top left))]
(recur
(rest y-seq)
(rest row)
(conj next-row d))))))

;; По сути это задача на нахождение 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))))))))
22 changes: 20 additions & 2 deletions otus-02/src/otus_02/homework/palindrome.clj
Original file line number Diff line number Diff line change
@@ -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" ""))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

хорошее решение
в этом месте регулярку можно немного упростить
(s/replace (s/lower-case s-not-normal) #"[^a-z]" "")
#"[^a-z]" сматчится на всё кроме букв

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Согласен, я переусложнил. Фиксить не вижу смысла сейчас)

reversed (str/reverse original)]
(= original reversed)))














(defn is-palindrome [test-string])
10 changes: 8 additions & 2 deletions otus-02/src/otus_02/homework/pangram.clj
Original file line number Diff line number Diff line change
@@ -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)))
49 changes: 43 additions & 6 deletions otus-02/src/otus_02/homework/square_code.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns otus-02.homework.square-code)
(ns otus-02.homework.square-code
(:require [clojure.string :as str]))

;; Реализовать классический метод составления секретных сообщений, называемый `square code`.
;; Выведите закодированную версию полученного текста.
Expand All @@ -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 — количество строк.
Expand All @@ -26,15 +30,51 @@
"vegivenu"
"sroots "

;; Чтение стобцов слева-направо в строку
(defn read-rectangle [rectangle]
(apply str
(loop [result '()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

если список пустой кавычку можно не ставить это специальный случай

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Спасибо, приму к сведению, переделывать не вижу смысла сейчас)

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)]
Comment on lines +71 to +72
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тут можно немного упростить если использовать partition
у этой функции есть специальный параметр pad (partition n step pad coll) элементы которого будут использоваться если не хватает элементов для равных слайсов

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Спасибо за замечание - буду иметь в виду, что есть такая функция) Переделывать не вижу смысла сейчас)

(str/join
" "
(concat
(map #(apply str %) complete-slices)
(map #(apply str (concat % '(\space))) incomplete-slices)))))

;; Обратите внимание, что если бы мы сложили их,
;; мы могли бы визуально декодировать зашифрованный текст обратно в исходное сообщение:
Expand All @@ -48,9 +88,6 @@
"aohghn "
"sseoau "

(defn decode-string [input]
(read-rectangle (str/split input #"\s+")))


(defn encode-string [input])


(defn decode-string [input])