(ns edition2022.day7
(:require [clojure.string :as str]))
(def example "$ cd /\n$ ls\ndir a\n14848514 b.txt\n8504156 c.dat\ndir d\n$ cd a\n$ ls\ndir e\n29116 f\n2557 g\n62596 h.lst\n$ cd e\n$ ls\n584 i\n$ cd ..\n$ cd ..\n$ cd d\n$ ls\n4060174 j\n8033020 d.log\n5626152 d.ext\n7214296 k")
(def example-lines (str/split-lines example))
(defn add-file [tree command]
;(println command)
(assoc tree (second command) (bigint (Integer/parseInt (first command)))))
(defn create-dir-tree [lines tree]
(if (or (empty? lines) (= "$ cd .." (first lines)))
[(rest lines) tree]
(let [current-line (first lines)
other-lines (rest lines)
command (str/split current-line #" ")
new-args (cond
(= "$ cd /" current-line) [other-lines tree]
(= "ls" (second command)) [other-lines tree]
(= "dir" (first command)) [other-lines tree]
(= "cd" (second command)) (let [other-exec (create-dir-tree other-lines {})]
[(first other-exec)
(assoc tree (nth command 2) (second other-exec))])
:else [other-lines (add-file tree command)])]
(recur (first new-args) (second new-args)))))
(defn dir-structure [lines]
(second (create-dir-tree lines {})))
(defn dir-name [parent child]
(str parent \. child))
(defn compute-sizes [parent tree]
(let [files-size (->> (vals tree)
(filter #(not (map? %)))
(reduce + 0N))
dirs (->> (seq tree)
(filter #(map? (second %))))
sizes (->> dirs
(map #(compute-sizes (dir-name parent (first %)) (second %)))
(reduce conj {})
)
parent-size (->> (map first dirs)
(map #(dir-name parent %))
(select-keys sizes)
(vals)
(reduce + files-size))]
(assoc sizes parent parent-size)))
(defn sum-with-cap [lines]
(->> lines
(dir-structure)
(compute-sizes "/")
(vals)
(filter #(<= % 100000N))
(reduce + 0N)
))
(defn input-lines []
(->> (slurp "resources/day7.in")
(str/split-lines)))
(defn solution-part1 []
(->> (input-lines)
(sum-with-cap)))
(defn solution-part2 []
(let [sizes (->> (input-lines)
(dir-structure)
(compute-sizes "/"))
used-space (sizes "/")
free-space (- 70000000N used-space)]
(->> sizes
(vals)
(sort)
(drop-while #(< (+ % free-space) 30000000N))
(first))))
(comment
example-lines
(create-dir-tree ["14848514 b.txt" "8504156 c.dat"] {})
(create-dir-tree ["$ ls" "14848514 b.txt" "8504156 c.dat"] {})
(create-dir-tree ["$ ls" "14848514 b.txt" "8504156 c.dat" "dir aaaa"] {})
(create-dir-tree ["$ cd /" "$ ls" "14848514 b.txt" "8504156 c.dat" "dir aa"] {})
(create-dir-tree ["$ cd /" "$ ls" "14848514 b.txt" "8504156 c.dat" "dir a" "$ cd a" "$ ls" "29116 f"] {})
(dir-structure example-lines)
(compute-sizes "/" {"a" 10, "b" 20, "c" {"d" 40}})
(compute-sizes "/" (dir-structure example-lines))
(sum-with-cap example-lines)
(solution-part1)
(dir-structure (input-lines))
(compute-sizes "/" (dir-structure (input-lines)))
all-dirs-from-file
(count all-dirs-from-file)
(count (set all-dirs-from-file))
(count (filter #(str/includes? in %) all-dirs-from-file))
(count (compute-sizes "/" (dir-structure (input-lines))))
(solution-part2)
)