-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day07Test.scala
121 lines (106 loc) · 2.94 KB
/
Day07Test.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package org.lemon.advent.year2022
import scala.collection.mutable
import org.lemon.advent._
class Day07Test extends UnitTest {
sealed trait File:
def size: Int
def name: String
case class Directory(name: String, parent: Directory, contents: mutable.Set[File] = mutable.Set()) extends File:
def size = contents.map(_.size).sum
case class Obj(name: String, size: Int) extends File
def buildTree(lines: Iterator[String]) =
val root = Directory("/", parent = null)
var pwd = root
lines.foreach(_ match
case "$ cd .." => pwd = pwd.parent
case "$ cd /" => pwd = root
case s"$$ cd $dir" =>
pwd = pwd.contents.filter(_.isInstanceOf[Directory]).map(_.asInstanceOf[Directory]).find(_.name == dir).get
case "$ ls" => "nothing to do"
case s"dir $dir" => pwd.contents.add(Directory(dir, pwd))
case s"$size $name" => pwd.contents.add(Obj(name = name, size = size.toInt))
)
root
def iterator(tree: File): Iterator[File] = tree match
case obj: Obj => Iterator(obj)
case dir: Directory => Iterator(dir) ++ dir.contents.flatMap(iterator)
def part1(in: String) =
val root = buildTree(in.linesIterator)
iterator(root)
.filter(_.isInstanceOf[Directory])
.map(_.size)
.filter(_ <= 100000)
.sum
def part2(in: String) =
val total = 70000000
val required = 30000000
val root = buildTree(in.linesIterator)
val unused = total - root.size
val needToIce = required - unused
iterator(root)
.filter(_.isInstanceOf[Directory])
.map(_.size)
.filter(_ >= needToIce)
.min
test("part 1 example") {
val in = """
|$ cd /
|$ ls
|dir a
|14848514 b.txt
|8504156 c.dat
|dir d
|$ cd a
|$ ls
|dir e
|29116 f
|2557 g
|62596 h.lst
|$ cd e
|$ ls
|584 i
|$ cd ..
|$ cd ..
|$ cd d
|$ ls
|4060174 j
|8033020 d.log
|5626152 d.ext
|7214296 k""".stripMargin.strip
buildTree(in.linesIterator).size shouldBe 48381165
part1(in) shouldBe 95437
}
test("part 1") {
part1(read(file(2022)(7))) shouldBe 1770595
}
test("part 2 example") {
val in = """
|$ cd /
|$ ls
|dir a
|14848514 b.txt
|8504156 c.dat
|dir d
|$ cd a
|$ ls
|dir e
|29116 f
|2557 g
|62596 h.lst
|$ cd e
|$ ls
|584 i
|$ cd ..
|$ cd ..
|$ cd d
|$ ls
|4060174 j
|8033020 d.log
|5626152 d.ext
|7214296 k""".stripMargin.strip
part2(in) shouldBe 24933642
}
test("part 2") {
part2(read(file(2022)(7))) shouldBe 2195372
}
}