-
Notifications
You must be signed in to change notification settings - Fork 0
/
day7.js
123 lines (108 loc) · 2.98 KB
/
day7.js
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
122
123
import fs from "fs";
import assert from "assert";
import * as R from "ramda";
const addDirectory = (tree, path) => {
const foo = R.hasPath(path, tree) ? tree : R.assocPath(path, {}, tree);
return foo;
};
const addFile = (tree, path, file) => {
return R.assocPath(
path,
{ ...R.path(path, tree), [file.split(" ")[1]]: Number(file.split(" ")[0]) },
tree
);
};
const parseInput = (input) => input.split("\n");
const createTree = (prompt, currentPath = [], tree = {}) => {
const [head, ...tail] = prompt;
if (head === undefined) {
return tree;
} else if (head.match(/cd \.\./)) {
return createTree(tail, currentPath.slice(0, -1), tree);
} else if (head.match(/cd .+/)) {
const path = currentPath.concat(head.split(" ")[2]);
return createTree(tail, path, addDirectory(tree, path));
} else if (head.match(/\d+/)) {
return createTree(tail, currentPath, addFile(tree, currentPath, head));
} else {
return createTree(tail, currentPath, tree);
}
};
const getContents = (contents) =>
Object.entries(contents).reduce(
(acc, [key, value]) =>
isDirectory(value)
? { ...acc, dirs: acc.dirs.concat(key) }
: { ...acc, files: acc.files.concat(value) },
{ files: [], dirs: [] }
);
const isDirectory = (elem) => isNaN(elem);
const directoriesWithSizes = (tree, currentPath = ["/"], directories = []) => {
const { files, dirs } = getContents(R.path(currentPath, tree));
if (dirs.length === 0) {
return directories.concat({
dirName: currentPath.join("/"),
size: R.sum(files),
});
} else {
const childrenDirs = dirs.flatMap((dir) =>
directoriesWithSizes(tree, currentPath.concat(dir), directories)
);
return [
{
dirName: currentPath.join("/"),
size:
R.sum(files) +
R.sum(
childrenDirs
.filter((dir) =>
dirs
.map((dir) => `${currentPath.join("/")}/${dir}`)
.includes(dir.dirName)
)
.map((f) => f.size)
),
},
].concat(childrenDirs);
}
};
const part1 = (input) =>
directoriesWithSizes(createTree(parseInput(input)))
.filter((dir) => dir.size <= 100000)
.reduce((sum, curr) => (sum = sum + curr.size), 0);
const part2 = (input) => {
const directories = directoriesWithSizes(createTree(parseInput(input)));
const mustBeFreed =
30000000 - (70000000 - directories.find((d) => d.dirName === "/").size);
return directories
.sort((a, b) => a.size - b.size)
.find(({ size }) => size > mustBeFreed).size;
};
const testInput = `$ 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`;
assert(part1(testInput) === 95437);
assert(part2(testInput) === 24933642);
const input = fs.readFileSync("inputs/day7.txt", "utf-8");
console.log(`Part 1: ${part1(input)}`);
console.log(`Part 2: ${part2(input)}`);