Skip to content

ready hm 21 #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
83 changes: 74 additions & 9 deletions otus-21/src/otus_21/homework/core.clj
Original file line number Diff line number Diff line change
@@ -1,9 +1,74 @@
(ns otus-21.homework.core)

(defn sum-of-sizes [input]
"По журналу сеанса работы в терминале воссоздаёт файловую систему
и подсчитывает сумму размеров директорий, занимающих на диске до
100000 байт (сумма размеров не учитывает случай, когда найденные
директории вложены друг в друга: размеры директорий всё так же
суммируются)."
0)
(ns otus-21.homework.core
(:require [clojure.zip :as z]
[clojure.walk :as w]
[clojure.string :as s]))


(defn map-zipper [m]
(z/zipper
(fn [x] (or (map? x) (map? (nth x 1))))
(fn [x] (seq (if (map? x) x (nth x 1))))
(fn [x children]
(if (map? x)
(into {} children)
(assoc x 1 (into {} children))))
m))

(defn insert-dir [loc name]
(z/append-child loc {name {}}))

(defn insert-file [loc name size]
(z/append-child loc [name (parse-long size)]))

(defn dir-loc [name loc]
(let [[key value] (z/node loc)]
(if (and (= name key) (map? value)) loc)
Copy link
Contributor

Choose a reason for hiding this comment

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

Лучше использовать when здесь.

))
(defn nav-to-dir [loc name]
(some #(dir-loc name %) (->> loc z/down (iterate z/right))))
(defn parse-command
[loc input]
(condp re-find input
#"\$ cd /" (map-zipper {"/" {}})
#"\$ ls" loc
#"dir (.+)" :>> (fn [[_ name]] (insert-dir loc name))
#"(\d+) (.+)" :>> (fn [[_ size name]] (insert-file loc name size))
#"cd \.\." (z/up loc)
#"cd (.+)" :>> (fn [[_ name]] (nav-to-dir loc name))))


(defn parse [input]
(->> input
s/split-lines
(reduce parse-command nil)
z/root))

(defn dir-in-walk? [x]
; [a {e {i 584}, f 29116, g 2557, h.lst 62596}]
(if (and (vector? x) (= 2 (count x)) (map? (second x))) true)
Copy link
Contributor

@astynax astynax Mar 5, 2024

Choose a reason for hiding this comment

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

(if ... true) странно выглядит. Может быть and достаточно было бы?

Copy link
Contributor

Choose a reason for hiding this comment

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

Сейчас код возвращает true или nil. Да, nil тоже "ложен", но как-то не хочется видеть в коде смешивание типов без нужды.

)
(defn sum-of-size-dirs [input max-dir-size]
(let [result (atom 0)]
(w/postwalk (fn [x]
(if (dir-in-walk? x)
(let
[name (nth x 0)
content (nth x 1)
size (apply + (vals content))]
(if (<= size max-dir-size) (swap! result #(+ size %)))
;(println "dir " name "size" size ":" content)
[name size]
)
x
)
)
(parse input))
@result))

(defn sum-of-sizes [input]
"По журналу сеанса работы в терминале воссоздаёт файловую систему
и подсчитывает сумму размеров директорий, занимающих на диске до
100000 байт (сумма размеров не учитывает случай, когда найденные
директории вложены друг в друга: размеры директорий всё так же
суммируются)."
(sum-of-size-dirs input 100000))