diff --git a/otus-01/src/otus/homework.clj b/otus-01/src/otus/homework.clj index 82c8e9d..f507fc4 100644 --- a/otus-01/src/otus/homework.clj +++ b/otus-01/src/otus/homework.clj @@ -1,5 +1,5 @@ (ns otus.homework) -(defn solution "Add your solution as fuction body here" []) +(defn solution [] (double (/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5))))) (* 3 (- 6 2) (- 2 7))))) diff --git a/otus-02/src/otus_02/homework/palindrome.clj b/otus-02/src/otus_02/homework/palindrome.clj index 591f98e..08e0a8f 100644 --- a/otus-02/src/otus_02/homework/palindrome.clj +++ b/otus-02/src/otus_02/homework/palindrome.clj @@ -1,6 +1,8 @@ (ns otus-02.homework.palindrome (:require [clojure.string :as string])) - -(defn is-palindrome [test-string]) +(defn is-palindrome [test-string] + (->> test-string string/lower-case + (filter #(Character/isLetter %)) + (#(= % (reverse %))))) diff --git a/otus-02/src/otus_02/homework/pangram.clj b/otus-02/src/otus_02/homework/pangram.clj index dc5d34c..e599697 100644 --- a/otus-02/src/otus_02/homework/pangram.clj +++ b/otus-02/src/otus_02/homework/pangram.clj @@ -1,6 +1,10 @@ (ns otus-02.homework.pangram (:require [clojure.string :as string])) - -(defn is-pangram [test-string]) - +(defn is-pangram [test-string] + (->> test-string string/lower-case + (filter #(Character/isLetter %)) + (map int) + (into #{}) + count + (= 26))) diff --git a/otus-02/src/otus_02/homework/square_code.clj b/otus-02/src/otus_02/homework/square_code.clj index 823a185..22f7555 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.otus-02.homework.square-code +(:require [clojure.math :as math] [clojure.string :as string])) ;; Реализовать классический метод составления секретных сообщений, называемый `square code`. ;; Выведите закодированную версию полученного текста. @@ -48,9 +49,31 @@ "aohghn " "sseoau " +(defn encode-string [input] + (let [st (->> input string/lower-case + (filter #(Character/isLetter %))) + sqr (math/sqrt (count st)) + rnd (math/round sqr) + [x y] (if (= (int (math/ceil sqr)) rnd) [(inc rnd) rnd] [rnd rnd])] + (->> (repeat (inc x) (range (inc y))) + flatten + (map vector (concat st (repeat \space))) + (sort-by second) + (map first) + drop-last + (apply str)))) - -(defn encode-string [input]) - - -(defn decode-string [input]) +(defn decode-string [input] + (let [[x y] (->> (range) + (map #(vector % %)) + flatten + (#(map vector % (drop 1 %))) + (drop-while #(< (reduce * %) (count input))) + first)] + (->> (repeat x (range y)) + flatten + (map vector (concat input (repeat \space))) + (sort-by second) + (map first) + (apply str) + (string/trim)))) diff --git a/otus-04/src/otus_04/homework/magic_square.clj b/otus-04/src/otus_04/homework/magic_square.clj index c90f3bf..7b4ec13 100644 --- a/otus-04/src/otus_04/homework/magic_square.clj +++ b/otus-04/src/otus_04/homework/magic_square.clj @@ -6,12 +6,18 @@ ;; Подсказка: используйте "Siamese method" ;; https://en.wikipedia.org/wiki/Siamese_method -(defn magic-square - "Функция возвращает вектор векторов целых чисел, - описывающий магический квадрат размера n*n, - где n - нечётное натуральное число. - Магический квадрат должен быть заполнен так, что суммы всех вертикалей, - горизонталей и диагоналей длиной в n должны быть одинаковы." - [n] - [[0]]) +;; r = 1..n MagSq = n * mod(r' + (r - div(n + 3, 2)), n) + mod(r' + r * 2 - 2, n) + 1 +(defn magic-square [n] + {:pre [(odd? n)]} + (let [rng (map inc (range n)) + repeat-rng (fn [x] (flatten (repeat n x))) + sum-row-col (fn [x y] (map + (sort (repeat-rng x)) (repeat-rng y))) + f-main (fn [x] (map #(mod % n) (sum-row-col rng x))) + b1 (map #(- % (quot (+ n 3), 2)) rng) + b2 (map #(- (* % 2) 2) rng)] + (->> (map + (map #(* % n) (f-main b1)) (f-main b2)) + (map inc) + (partition n) + (map vec) + vec))) diff --git a/otus-04/src/otus_04/homework/scramblies.clj b/otus-04/src/otus_04/homework/scramblies.clj index f76d335..6481c8b 100644 --- a/otus-04/src/otus_04/homework/scramblies.clj +++ b/otus-04/src/otus_04/homework/scramblies.clj @@ -3,8 +3,9 @@ ;; Оригинальная задача: ;; https://www.codewars.com/kata/55c04b4cc56a697bb0000048 -(defn scramble? +(defn scramble? [letters word] "Функция возвращает true, если из букв в строке letters можно составить слово word." - [letters word] - nil) + (let [f-freq (fn [x] (map #(get (frequencies x) % 0) (set word))) + [x y] (map f-freq [letters word])] + (every? true? (map >= x y)))) diff --git a/otus-06/src/otus_06/homework.clj b/otus-06/src/otus_06/homework.clj index d5d5228..a98992b 100644 --- a/otus-06/src/otus_06/homework.clj +++ b/otus-06/src/otus_06/homework.clj @@ -1,4 +1,7 @@ -(ns otus-06.homework) +(ns otus-06.homework + (:require [clojure.string :as string]) + (:require [clojure.java.io :as io]) + (:require [clojure.set :as set])) ;; Загрузить данные из трех файлов на диске. ;; Эти данные сформируют вашу базу данных о продажах. @@ -94,3 +97,124 @@ ;; Файлы находятся в папке otus-06/resources/homework + +;; VARS +;;************************************************** + +(def files (map #(str "homework/" %) ["cust.txt" "prod.txt" "sales.txt"])) + +;; запросы +(def menu "\n*** Sales Menu *** +------------------ +1. Display Customer Table +2. Display Product Table +3. Display Sales Table +4. Total Sales for Customer +5. Total Count for Product +6. Exit + +Enter an option\n") + +(def cust-req "Enter a customer name\n") +(def item-req "Enter an item\n") + +;; ключи для чтения и отображения +(def cust-keys [:custID :name :address :phoneNumber]) +(def prod-keys [:prodID :itemDescription :unitCost]) +(def sales-keys [:salesID :custID :prodID :itemCount]) +(def sales-keys-to-show [:salesID :name :itemDescription :itemCount]) + +(def key-names [cust-keys prod-keys sales-keys]) + +;; ключи для конвертации и расчета total-sum +(def keys-to-int [:itemCount :prodID :custID :salesID]) +(def keys-to-double [:unitCost]) +(def keys-to-count-total-sum [:unitCost :itemCount]) + +;; ключи для агрегации +(def keys-to-cust-aggr [:name :totalCost]) +(def keys-to-item-aggr [:itemDescription :itemCount]) + +;; FUNCTIONS +;;********************************************************************** + +(defn read-to-maps + "читаем файл с соответствующими keys в список мап" + [f k] + (let [r (io/reader (io/resource f))] + (->> (line-seq r) + (map #(string/split % #"\|")) + (map #(zipmap k %))))) + +(defn update-mult-vals + "преобразуем несколько столбов (keys), например, конвертируем" + [map vals fun] + (reduce #(update-in % [%2] fun) map vals)) + +(defn add-new-key + "добавляем новый столбец (key), рассчитанный из нескольких существующих" + [map keys name fun] + (assoc map name (reduce fun (vals (select-keys map keys))))) + +(defn select-data + "выделяем несколько столбцов и преобразуем каждую строку к виду мапа (ID - данные)" + [keys-to-select key-to-first coll] + (->> coll + (map #(select-keys % keys-to-select)) + (map #((fn [x key] (merge {(key x) (dissoc x key)})) % key-to-first)))) + +(defn aggregate + "агрегируем данные aggr-key, группируя по name-key" + [[name-key aggr-key] coll] + (->> coll + (map #(select-keys % [name-key aggr-key])) + (group-by name-key) + (map (fn [[name vals]] + {name-key name + aggr-key (reduce + (map aggr-key vals))})) + (map #((fn [x key] {(key x) (dissoc x key)}) % name-key)) + (reduce merge))) + +(defn aggregate-and-filter + "агрегируем и фильтруем результат по запрошенному значению name-key" + [[name-key aggr-key] message coll] + (println message) + (flush) + (let [filter-input (read-line)] + (->> coll + (aggregate [name-key aggr-key]) + (#(find % filter-input))))) + +(defn print-result + "печатаем либо результат, либо уточняющий запрос" + [x] + (if-not (nil? x) + (run! println x) + (println "Precise your input\n"))) + + +;; собираем все данные в одну таблицу (список мап) +(def full-data (->> (map #(read-to-maps %1 %2) files key-names) + (reduce set/join) + (map (fn [x] (update-mult-vals x keys-to-int #(Integer/parseInt %)))) + (map (fn [x] (update-mult-vals x keys-to-double parse-double))) + (map (fn [x] (add-new-key x keys-to-count-total-sum :totalCost *))))) + +(defn main + "результирующая функция" + [coll] + (println menu) + (flush) + (let [x (read-line)] + (println (str x "\n")) + (->> (cond + (= x "1") (select-data cust-keys :custID coll) + (= x "2") (select-data prod-keys :prodID coll) + (= x "3") (select-data sales-keys-to-show :salesID coll) + (= x "4") (aggregate-and-filter keys-to-cust-aggr cust-req coll) + (= x "5") (aggregate-and-filter keys-to-item-aggr item-req coll) + (= x "6") ["Good Bye\n"]) + print-result) + (if (not= x "6") (main coll) nil))) + +(main full-data)