6 changed files with 1328 additions and 0 deletions
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
import * as R from "remeda"; |
||||
import { readFile } from "../05/part1.js"; |
||||
import path from "path"; |
||||
|
||||
const readInput = (...args) => |
||||
readFile(...args) |
||||
.split("\n") |
||||
.filter((x) => x); |
||||
|
||||
export const puzzleInput = readInput(import.meta.url, "input"); |
||||
export const sample = readInput(import.meta.url, "sample"); |
||||
|
||||
export function parseInput(lines) { |
||||
lines = [...lines]; |
||||
|
||||
let currentDir = "/"; |
||||
|
||||
const data = {}; |
||||
|
||||
while (lines.length > 0) { |
||||
const line = lines.shift(); |
||||
|
||||
let match = line.match(/\$ cd (.*)/); |
||||
if (match) { |
||||
currentDir = match[1].startsWith("/") |
||||
? match[1] |
||||
: path.join(currentDir, match[1]); |
||||
if (!data[currentDir]) data[currentDir] = 0; |
||||
continue; |
||||
} |
||||
|
||||
if (/^\d+/.test(line)) { |
||||
const [size] = line.match(/\d+/); |
||||
data[currentDir] += parseInt(size); |
||||
} |
||||
} |
||||
|
||||
return data; |
||||
} |
||||
|
||||
export function cumulative(individual) { |
||||
const isIn = (k, targetKey) => { |
||||
const result = |
||||
k === targetKey || |
||||
k.startsWith(targetKey.endsWith("/") ? targetKey : targetKey + "/"); |
||||
return result; |
||||
}; |
||||
|
||||
return R.pipe( |
||||
individual, |
||||
R.mapValues((v, targetKey) => { |
||||
const sum = R.sumBy( |
||||
Object.values(R.pickBy(individual, (v, k) => isIn(k, targetKey))), |
||||
R.identity |
||||
); |
||||
return sum; |
||||
} |
||||
) |
||||
); |
||||
} |
||||
|
||||
export default R.createPipe( |
||||
parseInput, |
||||
cumulative, |
||||
R.pickBy((v) => v <= 100000), |
||||
R.values, |
||||
R.sumBy(R.identity) |
||||
); |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
import * as R from "remeda"; |
||||
|
||||
import { |
||||
cumulative, parseInput |
||||
} from './part1.js'; |
||||
|
||||
|
||||
export default (lines) => { |
||||
let cumu = R.pipe( lines, parseInput, cumulative); |
||||
|
||||
console.log(cumu); |
||||
|
||||
const spaceNeeded = 30000000 - 70000000 + cumu['/']; |
||||
|
||||
cumu = R.pickBy( |
||||
cumu, (v) => v >= spaceNeeded |
||||
); |
||||
|
||||
return R.pipe( |
||||
R.keys(cumu), |
||||
R.sortBy( k => cumu[k] ), |
||||
R.first, |
||||
(k => cumu[k]) |
||||
) |
||||
} |
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
## \--- Day 7: No Space Left On Device --- |
||||
|
||||
You can hear birds chirping and raindrops hitting leaves as the expedition proceeds. Occasionally, you can even hear much louder sounds in the distance; how big do the animals get out here, anyway? |
||||
|
||||
The device the Elves gave you has problems with more than just its communication system. You try to run a system update: |
||||
|
||||
``` |
||||
$ system-update --please --pretty-please-with-sugar-on-top |
||||
Error: No space left on device |
||||
|
||||
``` |
||||
|
||||
Perhaps you can delete some files to make space for the update? |
||||
|
||||
You browse around the filesystem to assess the situation and save the resulting terminal output (your puzzle input). For example: |
||||
|
||||
``` |
||||
$ 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 |
||||
|
||||
``` |
||||
|
||||
The filesystem consists of a tree of files (plain data) and directories (which can contain other directories or files). The outermost directory is called `/`. You can navigate around the filesystem, moving into or out of directories and listing the contents of the directory you're currently in. |
||||
|
||||
Within the terminal output, lines that begin with `$` are _commands you executed_, very much like some modern computers: |
||||
|
||||
- `cd` means _change directory_. This changes which directory is the current directory, but the specific result depends on the argument: |
||||
|
||||
- `cd x` moves _in_ one level: it looks in the current directory for the directory named `x` and makes it the current directory. |
||||
- `cd ..` moves _out_ one level: it finds the directory that contains the current directory, then makes that directory the current directory. |
||||
- `cd /` switches the current directory to the outermost directory, `/`. |
||||
|
||||
- `ls` means _list_. It prints out all of the files and directories immediately contained by the current directory: |
||||
- `123 abc` means that the current directory contains a file named `abc` with size `123`. |
||||
- `dir xyz` means that the current directory contains a directory named `xyz`. |
||||
|
||||
Given the commands and output in the example above, you can determine that the filesystem looks visually like this: |
||||
|
||||
``` |
||||
- / (dir) |
||||
- a (dir) |
||||
- e (dir) |
||||
- i (file, size=584) |
||||
- f (file, size=29116) |
||||
- g (file, size=2557) |
||||
- h.lst (file, size=62596) |
||||
- b.txt (file, size=14848514) |
||||
- c.dat (file, size=8504156) |
||||
- d (dir) |
||||
- j (file, size=4060174) |
||||
- d.log (file, size=8033020) |
||||
- d.ext (file, size=5626152) |
||||
- k (file, size=7214296) |
||||
|
||||
``` |
||||
|
||||
Here, there are four directories: `/` (the outermost directory), `a` and `d` (which are in `/`), and `e` (which is in `a`). These directories also contain files of various sizes. |
||||
|
||||
Since the disk is full, your first step should probably be to find directories that are good candidates for deletion. To do this, you need to determine the _total size_ of each directory. The total size of a directory is the sum of the sizes of the files it contains, directly or indirectly. (Directories themselves do not count as having any intrinsic size.) |
||||
|
||||
The total sizes of the directories above can be found as follows: |
||||
|
||||
- The total size of directory `e` is _584_ because it contains a single file `i` of size 584 and no other directories. |
||||
- The directory `a` has total size _94853_ because it contains files `f` (size 29116), `g` (size 2557), and `h.lst` (size 62596), plus file `i` indirectly (`a` contains `e` which contains `i`). |
||||
- Directory `d` has total size _24933642_. |
||||
- As the outermost directory, `/` contains every file. Its total size is _48381165_, the sum of the size of every file. |
||||
|
||||
To begin, find all of the directories with a total size of _at most 100000_, then calculate the sum of their total sizes. In the example above, these directories are `a` and `e`; the sum of their total sizes is `*95437*` (94853 + 584). (As in this example, this process can count files more than once!) |
||||
|
||||
Find all of the directories with a total size of at most 100000. _What is the sum of the total sizes of those directories?_ |
||||
|
||||
To begin, [get your puzzle input](7/input). |
||||
|
||||
Answer: |
||||
|
||||
You can also [Shareon [Twitter](https://twitter.com/intent/tweet?text=%22No+Space+Left+On+Device%22+%2D+Day+7+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F7&related=ericwastl&hashtags=AdventOfCode) [Mastodon](<javascript:void(0);>)] this puzzle. |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
$ 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 |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
import { test, expect, describe } from "vitest"; |
||||
|
||||
import { expectSolution } from "../01/main.js"; |
||||
import part1, { puzzleInput, sample, parseInput,cumulative } from "./part1.js"; |
||||
import part2 from "./part2.js"; |
||||
|
||||
describe("part 1", () => { |
||||
const expected = { '/': 23352670, '/a': 94269, '/a/e': 584, '/d': 24933642 }; |
||||
|
||||
test( "parseInput", () => { |
||||
const data = parseInput(sample); |
||||
|
||||
|
||||
expect(data).toEqual(expected); |
||||
}); |
||||
|
||||
test( "cumulative", () => { |
||||
|
||||
expect(cumulative(expected)).toEqual({ '/':48381165 , '/a': 94853, '/a/e': 584, '/d': 24933642 }); |
||||
}); |
||||
|
||||
|
||||
test("solution", () => { |
||||
expectSolution(part1(puzzleInput)).toEqual(1350966); |
||||
}); |
||||
}); |
||||
|
||||
describe("part 2", () => { |
||||
test("sample", () => { |
||||
expect(part2(sample)).toEqual(24933642); |
||||
}); |
||||
test("solution", () => { |
||||
expectSolution(part2(puzzleInput)).toBeLessThan(46647330); |
||||
expectSolution(part2(puzzleInput)).toEqual(6296435); |
||||
}); |
||||
}); |
Loading…
Reference in new issue