Skip to content

Commit 907f144

Browse files
committed
add lesson 21
1 parent 25548b8 commit 907f144

File tree

6 files changed

+238
-0
lines changed

6 files changed

+238
-0
lines changed

otus-21/README.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# outs-21
2+
3+
Деревья, графы, зипперы, поиск пути.
4+
5+
## Домашнее задание
6+
7+
Вам предстоит решить первую часть [задачи дня №7](https://adventofcode.com/2022/day/7) из серии AdventOfCode 2022.
8+
9+
Суть задачи заключается в том, чтобы суметь декодировать "журнал работы в терминале", имеющий вид:
10+
11+
$ cd /
12+
$ ls
13+
dir a
14+
14848514 b.txt
15+
8504156 c.dat
16+
dir d
17+
$ cd a
18+
$ ls
19+
dir e
20+
29116 f
21+
2557 g
22+
62596 h.lst
23+
24+
Здесь вы видите команды
25+
26+
- `cd /` - переход в корень диска
27+
- `cd ..` - переход в родительскую директорию
28+
- `cd name` - переход в поддиректорию "name"
29+
- `ls` - вывод списка поддиректорий и файлов в текущей директории
30+
31+
Команда `cd` никогда не делает более одного "движения" за раз: вы либо спускаетесь на один уровень вниз (в поддиректорию) или поднимаетесь на один уровень вверх. Исключение ровно одно — `cd /`, но оно встречается только в начале журнала.
32+
33+
Содержимое директории выводится в виде списка, содержащего имена поддиректорий в формате `dir name` и файлы вместе с их размерами `<размер-в-байтах> имя`.
34+
35+
Вам предстоит подсчитать размер каждой директории, который равен сумме размеров поддиректорий и файлов.
36+
37+
Функция `sum-of-sizes` должна принимать журнал в виде строки и возвращать сумму размеров тех директорий, которые занимают на диске 100000 байт и меньше. Учитывать вложенность не нужно: если вы встретите две директории нужного размера и при этом окажется, что одна из них находится в другой, то никаких дополнительных действий делать не нужно — вы всё также складываете размеры.

otus-21/project.clj

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
(defproject otus-21 "0.1.0-SNAPSHOT"
2+
:description "FIXME: write description"
3+
:url "http://example.com/FIXME"
4+
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
5+
:url "https://www.eclipse.org/legal/epl-2.0/"}
6+
:dependencies [[org.clojure/clojure "1.11.1"]]
7+
:repl-options {:init-ns otus-21.core})

otus-21/src/otus_21/core.clj

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
;; * Clojure Developer, урок 21
2+
(ns otus-21.core
3+
(:require [clojure.zip :as z]
4+
[clojure.walk :as w]))
5+
6+
;; * Древовидные структуры
7+
8+
(def bin-tree
9+
[3 [1 nil [2 nil nil]]
10+
[7 [5 [4 nil nil] [6 nil nil]]
11+
[8 nil nil]]])
12+
13+
(def dict
14+
[:c [:a [:b
15+
:t]
16+
:olor]])
17+
18+
;; * Графы
19+
20+
;; b - c
21+
;; / /
22+
;; a e g
23+
;; \ / /
24+
;; d - f
25+
26+
;; ** Матрица смежности
27+
28+
;; a b c d e f g
29+
;; a x 1 0 1 0 0 0
30+
;; b 1 x 1 0 0 0 0
31+
;; c 0 1 x 0 1 0 1
32+
;; d x .
33+
;; e x .
34+
;; f x .
35+
;; g . . . . . . x
36+
37+
;; ** Списки смежности
38+
39+
;; a: b, d
40+
;; b: a, c
41+
;; c: b, e, g
42+
;; d: a, e, f
43+
;; e: c, d
44+
;; f: d
45+
;; g: c
46+
47+
;; *** пример
48+
49+
(def gr
50+
{:a [:b :d]
51+
:b [:a :c]
52+
:c [:b :e :g]
53+
:d [:a :e :f]
54+
:e [:c :d]
55+
:f [:d]
56+
:g [:c]})
57+
58+
(def gr2
59+
{:a [nil [:b :d]]
60+
:b [:a [:c]]
61+
;; ...
62+
})
63+
64+
;; * clojure.walk
65+
66+
;; ** walk
67+
68+
(comment
69+
(w/walk (fn [x] (if (number? x) (str x) x))
70+
identity bin-tree)
71+
72+
(letfn [(sum [t]
73+
(cond (coll? t)
74+
(w/walk sum (partial reduce +) t)
75+
76+
(nil? t) 0
77+
78+
true t))]
79+
(sum bin-tree)))
80+
81+
;; ** prewalk/postwalk
82+
83+
(comment
84+
(w/prewalk str bin-tree)
85+
(w/postwalk
86+
(fn [x] (if (number? x) (str x) x))
87+
bin-tree))
88+
89+
;; * clojure.zip
90+
91+
(comment
92+
(-> bin-tree
93+
z/vector-zip
94+
z/down
95+
z/right
96+
z/down
97+
z/rightmost
98+
z/down
99+
(z/edit + 100)
100+
z/root)
101+
102+
(-> bin-tree
103+
z/vector-zip
104+
z/down
105+
z/right
106+
z/down))
107+
108+
;; FIXME: broken
109+
(comment
110+
(loop [c (z/vector-zip bin-tree)]
111+
(let [n (if (odd? (z/node c))
112+
(z/edit c + 100)
113+
c)]
114+
(if (z/branch? n)
115+
(recur (z/down n))
116+
(loop [n (z/up n)
117+
prev n]
118+
(let [[found n]
119+
(cond (nil? n)
120+
[true (z/root prev)]
121+
122+
(nil? (z/right n))
123+
(recur (z/up n) n)
124+
125+
[false (z/right n)])]
126+
(if found n
127+
(recur n))))))))
128+
129+
;; ** zipper
130+
131+
(def gr-zipper
132+
(z/zipper
133+
(constantly true)
134+
#(get gr %)
135+
(fn [n _] n)
136+
:a))
137+
138+
(comment
139+
(-> gr-zipper
140+
z/down
141+
z/down
142+
z/right
143+
z/down
144+
z/right
145+
z/right
146+
z/children))
147+
148+
;; * Поиск

otus-21/src/otus_21/homework/core.clj

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(ns otus-21.homework.core)
2+
3+
(defn sum-of-sizes [input]
4+
"По журналу сеанса работы в терминале воссоздаёт файловую систему
5+
и подсчитывает сумму размеров директорий, занимающих на диске до
6+
100000 байт (сумма размеров не учитывает случай, когда найденные
7+
директории вложены друг в друга: размеры директорий всё так же
8+
суммируются)."
9+
0)

otus-21/test/otus_21/core_test.clj

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(ns otus-21.core-test
2+
(:require [clojure.test :refer :all]
3+
[otus-21.core :refer :all]))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
(ns otus-21.homework.core-test
2+
(:require [clojure.test :refer :all]
3+
[otus-21.homework.core :refer :all]))
4+
5+
(def example
6+
"$ cd /
7+
$ ls
8+
dir a
9+
14848514 b.txt
10+
8504156 c.dat
11+
dir d
12+
$ cd a
13+
$ ls
14+
dir e
15+
29116 f
16+
2557 g
17+
62596 h.lst
18+
$ cd e
19+
$ ls
20+
584 i
21+
$ cd ..
22+
$ cd ..
23+
$ cd d
24+
$ ls
25+
4060174 j
26+
8033020 d.log
27+
5626152 d.ext
28+
7214296 k
29+
")
30+
31+
(deftest sum-of-sizes-test
32+
(testing "Work with the example"
33+
(is (= (sum-of-sizes example)
34+
95437))))

0 commit comments

Comments
 (0)