mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-27 22:00:31 +01:00
Compare commits
1 Commits
79387b5f14
...
2021-day23
| Author | SHA1 | Date | |
|---|---|---|---|
| 81f244bde9 |
@@ -1,7 +1,7 @@
|
|||||||
on:
|
on:
|
||||||
- push
|
- push
|
||||||
|
|
||||||
name: Advent of Code 2022
|
name: Advent of Code 2021
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
ci:
|
||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
continue-on-error: ${{ matrix.experimental }}
|
continue-on-error: ${{ matrix.experimental }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install toolchain
|
- name: Install toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -30,23 +30,17 @@ jobs:
|
|||||||
override: true
|
override: true
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|
||||||
- name: Set up caching
|
|
||||||
uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
workspaces: >
|
|
||||||
2022 -> target
|
|
||||||
|
|
||||||
- name: Build binaries
|
- name: Build binaries
|
||||||
working-directory: 2022
|
working-directory: 2021
|
||||||
run: >
|
run: >
|
||||||
cargo build --all-targets
|
cargo build --all-targets
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
working-directory: 2022
|
working-directory: 2021
|
||||||
run: >
|
run: >
|
||||||
cargo test
|
cargo test
|
||||||
|
|
||||||
- name: Run clippy
|
- name: Run clippy
|
||||||
working-directory: 2022
|
working-directory: 2021
|
||||||
run: >
|
run: >
|
||||||
cargo clippy -- --deny warnings
|
cargo clippy -- --deny warnings
|
||||||
@@ -4,4 +4,4 @@ version = "0.1.0"
|
|||||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1"
|
regex = "0.1"
|
||||||
|
|||||||
@@ -73,10 +73,10 @@ fn main() {
|
|||||||
let door_label = line.unwrap();
|
let door_label = line.unwrap();
|
||||||
let caps = room_pattern.captures(&door_label).unwrap();
|
let caps = room_pattern.captures(&door_label).unwrap();
|
||||||
|
|
||||||
let name = caps.get(1).unwrap().as_str();
|
let name = caps.at(1).unwrap();
|
||||||
let checksum = caps.get(4).unwrap().as_str();
|
let checksum = caps.at(4).unwrap();
|
||||||
if is_valid(name, checksum) {
|
if is_valid(name, checksum) {
|
||||||
let sector_id = caps.get(3).unwrap().as_str().parse().unwrap();
|
let sector_id = caps.at(3).unwrap().parse().unwrap();
|
||||||
cur_sum += sector_id;
|
cur_sum += sector_id;
|
||||||
|
|
||||||
let decoded: String = name.chars()
|
let decoded: String = name.chars()
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ version = "0.1.0"
|
|||||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1"
|
regex = "^0.1"
|
||||||
lazy_static = "1"
|
lazy_static = "^0.2"
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ version = "0.1.0"
|
|||||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex="1"
|
regex="^0.1"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ edition = "2021"
|
|||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "3", features = ["derive"] }
|
clap = { version = "3.0.0-rc.0", features = ["derive"] }
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
nom = "7"
|
nom = "7"
|
||||||
|
|
||||||
|
|||||||
@@ -20,15 +20,3 @@ OPTIONS:
|
|||||||
-i, --input <INPUT> Read input from the given file instead of stdin
|
-i, --input <INPUT> Read input from the given file instead of stdin
|
||||||
-t, --time Print time taken
|
-t, --time Print time taken
|
||||||
```
|
```
|
||||||
|
|
||||||
## That goal was achieved
|
|
||||||
|
|
||||||
Runtime benchmarked with [Criterion], reading input directly from memory to avoid disk IO
|
|
||||||
inconsistencies.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
[Criterion]: https://github.com/bheisler/criterion.rs
|
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
import json
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Dict
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
|
|
||||||
def read_timings() -> Dict[int, Dict]:
|
|
||||||
timings = {}
|
|
||||||
|
|
||||||
for day in Path('target/criterion/part1').iterdir():
|
|
||||||
with open(day / 'new' / 'estimates.json', mode='rb') as f:
|
|
||||||
timings[int(day.parts[-1])] = {
|
|
||||||
1: json.load(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
for day in Path('target/criterion/part2').iterdir():
|
|
||||||
with open(day / 'new' / 'estimates.json', mode='rb') as f:
|
|
||||||
timings[int(day.parts[-1])][2] = json.load(f)
|
|
||||||
|
|
||||||
return timings
|
|
||||||
|
|
||||||
|
|
||||||
def plot_cumulative_time(timings: Dict[int, Dict]):
|
|
||||||
plt.clf()
|
|
||||||
|
|
||||||
times = [0]
|
|
||||||
|
|
||||||
for day in range(min(timings.keys()), max(timings.keys()) + 1):
|
|
||||||
times.append(timings[day][1]['mean']['point_estimate'])
|
|
||||||
if day < 25:
|
|
||||||
times.append(timings[day][2]['mean']['point_estimate'])
|
|
||||||
else:
|
|
||||||
times.append(0)
|
|
||||||
|
|
||||||
cumulative = np.cumsum(times)
|
|
||||||
# Convert from nanoseconds to seconds
|
|
||||||
cumulative /= 1e9
|
|
||||||
|
|
||||||
x = np.arange(0.0, 25.5, 0.5)
|
|
||||||
|
|
||||||
plt.plot(x, cumulative, label="Cumulative time", drawstyle='steps-post')
|
|
||||||
plt.plot([0, 25], [0, 0.5], label="Target time")
|
|
||||||
plt.ylabel('Cumulative time (s)')
|
|
||||||
plt.xlabel('Days completed')
|
|
||||||
|
|
||||||
plt.legend()
|
|
||||||
plt.tight_layout()
|
|
||||||
|
|
||||||
plt.xlim(0, 25)
|
|
||||||
plt.ylim(0, 0.5)
|
|
||||||
|
|
||||||
plt.savefig('cumulative-time.svg')
|
|
||||||
|
|
||||||
|
|
||||||
def plot_individual_times(timings: Dict[int, Dict]):
|
|
||||||
plt.clf()
|
|
||||||
|
|
||||||
def plot(parts, **kwargs):
|
|
||||||
x = np.arange(1, len(parts) + 1)
|
|
||||||
|
|
||||||
values = np.array(list(part['mean']['point_estimate'] for part in parts))
|
|
||||||
upper = np.array(list(part['mean']['confidence_interval']['upper_bound'] for part in parts))
|
|
||||||
lower = np.array(list(part['mean']['confidence_interval']['lower_bound'] for part in parts))
|
|
||||||
|
|
||||||
# Convert from ns to s
|
|
||||||
yerr = np.array([upper - values, lower - values]) / 1e9
|
|
||||||
values = values / 1e9
|
|
||||||
|
|
||||||
plt.bar(x, values, yerr=yerr, align='edge', log=True, **kwargs)
|
|
||||||
pass
|
|
||||||
|
|
||||||
plot(list(timings[day][1] for day in range(1, 26)), label="Part 1", width=-0.4)
|
|
||||||
plot(list(timings[day][2] for day in range(1, 25)), label="Part 2", width=0.4)
|
|
||||||
|
|
||||||
plt.ylabel('Runtime (s)')
|
|
||||||
plt.xlabel('Day')
|
|
||||||
|
|
||||||
plt.xlim(0, 26)
|
|
||||||
plt.xticks(np.arange(1, 26))
|
|
||||||
|
|
||||||
plt.legend()
|
|
||||||
plt.tight_layout()
|
|
||||||
|
|
||||||
plt.savefig('individual-time.svg')
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
timings = read_timings()
|
|
||||||
plot_cumulative_time(timings)
|
|
||||||
plot_individual_times(timings)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 16 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 32 KiB |
@@ -90,65 +90,7 @@ where
|
|||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
input.read_to_end(&mut buffer).unwrap();
|
input.read_to_end(&mut buffer).unwrap();
|
||||||
|
|
||||||
match parser(&buffer).finish() {
|
let (_, output) = parser(&buffer).finish().unwrap();
|
||||||
Ok((_, output)) => output,
|
|
||||||
Err(err) => {
|
output
|
||||||
panic!(
|
|
||||||
"Failed to parse input with error {:?} at \"{}\"",
|
|
||||||
err.code,
|
|
||||||
String::from_utf8_lossy(err.input)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct BitSet {
|
|
||||||
buffer: Vec<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BitSet {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_capacity(capacity: usize) -> Self {
|
|
||||||
let buffer = vec![0; capacity / 32];
|
|
||||||
|
|
||||||
Self { buffer }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn convert_value(value: usize) -> (usize, u32) {
|
|
||||||
let chunk = value / 32;
|
|
||||||
let bit = 1 << (31 - (value % 32));
|
|
||||||
|
|
||||||
(chunk, bit)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert(&mut self, value: usize) -> bool {
|
|
||||||
let (chunk, bit) = Self::convert_value(value);
|
|
||||||
|
|
||||||
if self.buffer.len() <= chunk + 1 {
|
|
||||||
self.buffer.resize(chunk + 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
let not_present = self.buffer[chunk] & bit;
|
|
||||||
|
|
||||||
self.buffer[chunk] |= bit;
|
|
||||||
|
|
||||||
not_present == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.buffer.iter().map(|c| c.count_ones() as usize).sum()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contains(&self, value: usize) -> bool {
|
|
||||||
let (chunk, bit) = Self::convert_value(value);
|
|
||||||
|
|
||||||
self.buffer
|
|
||||||
.get(chunk)
|
|
||||||
.map(|&c| c & bit != 0)
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +1,69 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
|
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
use nom::character::complete::newline;
|
use nom::sequence::tuple;
|
||||||
use nom::combinator::map;
|
use nom::Finish;
|
||||||
use nom::multi::separated_list1;
|
|
||||||
use nom::sequence::separated_pair;
|
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
|
|
||||||
use crate::common::ordered;
|
use crate::common::ordered;
|
||||||
use crate::common::read_input;
|
use crate::common::LineIter;
|
||||||
use crate::common::BitSet;
|
|
||||||
|
|
||||||
type Coord = (u16, u16);
|
type Coord = (u16, u16);
|
||||||
|
|
||||||
fn coordinates(input: &[u8]) -> IResult<&[u8], Coord> {
|
fn coordinates(input: &str) -> IResult<&str, Coord> {
|
||||||
use nom::character::complete::char;
|
use nom::character::complete;
|
||||||
use nom::character::complete::u16;
|
|
||||||
|
|
||||||
separated_pair(u16, char(','), u16)(input)
|
let (input, (x, _, y)) = tuple((complete::u16, complete::char(','), complete::u16))(input)?;
|
||||||
|
|
||||||
|
Ok((input, (x, y)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<(Coord, Coord)>> {
|
fn line_definition(input: &str) -> IResult<&str, (Coord, Coord)> {
|
||||||
let read_line = map(
|
let (input, (begin, _, end)) = tuple((coordinates, tag(" -> "), coordinates))(input)?;
|
||||||
separated_pair(coordinates, tag(" -> "), coordinates),
|
|
||||||
|(begin, end)| ordered(begin, end),
|
|
||||||
);
|
|
||||||
|
|
||||||
separated_list1(newline, read_line)(input)
|
// Sorting the coordinates saves trouble later
|
||||||
|
Ok((input, ordered(begin, end)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stripe(
|
fn stripe(
|
||||||
once: &mut BitSet,
|
map: &mut HashMap<Coord, u16>,
|
||||||
twice: &mut BitSet,
|
|
||||||
width: usize,
|
|
||||||
xs: impl Iterator<Item = u16>,
|
xs: impl Iterator<Item = u16>,
|
||||||
ys: impl Iterator<Item = u16>,
|
ys: impl Iterator<Item = u16>,
|
||||||
) {
|
) {
|
||||||
for (x, y) in xs.zip(ys) {
|
for (x, y) in xs.zip(ys) {
|
||||||
let index = x as usize + y as usize * width;
|
*map.entry((x, y)).or_default() += 1;
|
||||||
if !once.insert(index) {
|
|
||||||
twice.insert(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_common(input: &mut dyn Read, diagonals: bool) -> String {
|
fn part_common(input: &mut dyn Read, diagonals: bool) -> String {
|
||||||
let lines = read_input(input, parse_input);
|
let mut reader = LineIter::new(input);
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
|
||||||
let width = lines
|
while let Some(line) = reader.next() {
|
||||||
.iter()
|
let (begin, end) = line_definition(line).finish().unwrap().1;
|
||||||
.map(|&(_, (x, _))| x as usize + 1)
|
|
||||||
.max()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut once_map = BitSet::new();
|
|
||||||
let mut twice_map = BitSet::new();
|
|
||||||
|
|
||||||
for (begin, end) in lines {
|
|
||||||
if begin.0 == end.0 {
|
if begin.0 == end.0 {
|
||||||
let y_range = begin.1..=end.1;
|
let y_range = begin.1..=end.1;
|
||||||
stripe(
|
stripe(&mut map, repeat(begin.0), y_range);
|
||||||
&mut once_map,
|
|
||||||
&mut twice_map,
|
|
||||||
width,
|
|
||||||
repeat(begin.0),
|
|
||||||
y_range,
|
|
||||||
);
|
|
||||||
} else if begin.1 == end.1 {
|
} else if begin.1 == end.1 {
|
||||||
let x_range = begin.0..=end.0;
|
let x_range = begin.0..=end.0;
|
||||||
stripe(
|
stripe(&mut map, x_range, repeat(begin.1));
|
||||||
&mut once_map,
|
|
||||||
&mut twice_map,
|
|
||||||
width,
|
|
||||||
x_range,
|
|
||||||
repeat(begin.1),
|
|
||||||
);
|
|
||||||
} else if diagonals {
|
} else if diagonals {
|
||||||
let x_range = begin.0..=end.0;
|
let x_range = begin.0..=end.0;
|
||||||
let y_range = (begin.1.min(end.1))..=(begin.1.max(end.1));
|
let y_range = (begin.1.min(end.1))..=(begin.1.max(end.1));
|
||||||
|
|
||||||
if begin.1 > end.1 {
|
if begin.1 > end.1 {
|
||||||
// For a downward slope we need to reverse Y
|
// For a downward slope we need to reverse Y
|
||||||
stripe(&mut once_map, &mut twice_map, width, x_range, y_range.rev());
|
stripe(&mut map, x_range, y_range.rev());
|
||||||
} else {
|
} else {
|
||||||
stripe(&mut once_map, &mut twice_map, width, x_range, y_range);
|
stripe(&mut map, x_range, y_range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
twice_map.len().to_string()
|
map.values().filter(|&&v| v > 1).count().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part1(input: &mut dyn Read) -> String {
|
pub fn part1(input: &mut dyn Read) -> String {
|
||||||
@@ -108,6 +82,11 @@ mod tests {
|
|||||||
|
|
||||||
const SAMPLE: &[u8] = include_bytes!("samples/05.txt");
|
const SAMPLE: &[u8] = include_bytes!("samples/05.txt");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parser() {
|
||||||
|
assert_eq!(line_definition("6,4 -> 2,0"), Ok(("", ((2, 0), (6, 4)))));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sample_part1() {
|
fn sample_part1() {
|
||||||
test_implementation(part1, SAMPLE, 5)
|
test_implementation(part1, SAMPLE, 5)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ fn parse_fold(input: &[u8]) -> IResult<&[u8], Fold> {
|
|||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_fold(dots: &mut [Coords], fold: Fold) {
|
fn apply_fold(dots: &mut Vec<Coords>, fold: Fold) {
|
||||||
match fold {
|
match fold {
|
||||||
Fold::X(coord) => dots.iter_mut().for_each(|(x, _)| {
|
Fold::X(coord) => dots.iter_mut().for_each(|(x, _)| {
|
||||||
if *x >= coord {
|
if *x >= coord {
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ mod tests {
|
|||||||
fn sample_part1() {
|
fn sample_part1() {
|
||||||
let answers = [16, 12, 23, 31];
|
let answers = [16, 12, 23, 31];
|
||||||
|
|
||||||
for (&sample, answer) in SAMPLE.iter().zip(answers) {
|
for (&sample, answer) in SAMPLE.into_iter().zip(answers) {
|
||||||
test_implementation(part1, sample, answer);
|
test_implementation(part1, sample, answer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use std::ops::Deref;
|
|
||||||
use std::ops::Sub;
|
use std::ops::Sub;
|
||||||
|
|
||||||
use nom::bytes::complete::tag;
|
use nom::bytes::complete::tag;
|
||||||
@@ -25,10 +23,6 @@ impl Point3 {
|
|||||||
pub fn manhattan(&self) -> i32 {
|
pub fn manhattan(&self) -> i32 {
|
||||||
self.0.into_iter().map(i32::abs).sum()
|
self.0.into_iter().map(i32::abs).sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn euler_square(&self) -> i32 {
|
|
||||||
self.0.into_iter().map(|c| c * c).sum()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sub for Point3 {
|
impl Sub for Point3 {
|
||||||
@@ -55,44 +49,6 @@ impl Add for Point3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Scanner {
|
|
||||||
visible: Vec<Point3>,
|
|
||||||
distances: HashMap<i32, (Point3, Point3)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Scanner {
|
|
||||||
pub fn new(visible: Vec<Point3>) -> Self {
|
|
||||||
let distances = visible
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.flat_map(|(skip, &a)| {
|
|
||||||
visible[(skip + 1)..]
|
|
||||||
.iter()
|
|
||||||
.map(move |&b| ((a - b).euler_square(), (a, b)))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Self { visible, distances }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_overlap(&self, other: &Self) -> bool {
|
|
||||||
other
|
|
||||||
.distances
|
|
||||||
.keys()
|
|
||||||
.filter(|&k| self.distances.contains_key(k))
|
|
||||||
.count()
|
|
||||||
>= 11
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for Scanner {
|
|
||||||
type Target = [Point3];
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.visible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Rotations<'a> {
|
struct Rotations<'a> {
|
||||||
points: &'a [Point3],
|
points: &'a [Point3],
|
||||||
axes: [usize; 3],
|
axes: [usize; 3],
|
||||||
@@ -163,56 +119,32 @@ fn parse_point(input: &[u8]) -> IResult<&[u8], Point3> {
|
|||||||
)(input)
|
)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Scanner>> {
|
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Vec<Point3>>> {
|
||||||
use nom::character::complete::i32;
|
use nom::character::complete::i32;
|
||||||
let parse_header = delimited(tag("--- scanner "), i32, tag(" ---\n"));
|
let parse_header = delimited(tag("--- scanner "), i32, tag(" ---\n"));
|
||||||
|
|
||||||
let parse_scanner = map(
|
let parse_scanner = preceded(parse_header, many1(terminated(parse_point, newline)));
|
||||||
preceded(parse_header, many1(terminated(parse_point, newline))),
|
|
||||||
Scanner::new,
|
|
||||||
);
|
|
||||||
separated_list1(newline, parse_scanner)(input)
|
separated_list1(newline, parse_scanner)(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_pivot(group: &Scanner, related: &Scanner) -> Option<Point3> {
|
fn try_overlap(
|
||||||
let mut counter = HashMap::new();
|
correct: &[(Point3, HashSet<Point3>)],
|
||||||
|
candidate: &[Point3],
|
||||||
for (distance, &(a, b)) in &group.distances {
|
) -> Option<(Point3, Vec<Point3>)> {
|
||||||
if related.distances.contains_key(distance) {
|
let mut relative = HashSet::new();
|
||||||
*counter.entry(a).or_insert(0) += 1;
|
|
||||||
*counter.entry(b).or_insert(0) += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
counter
|
|
||||||
.into_iter()
|
|
||||||
.max_by_key(|(_, count)| *count)
|
|
||||||
.map(|t| t.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_overlap(matched: &Scanner, candidate: &Scanner) -> Option<(Point3, Scanner)> {
|
|
||||||
if !matched.can_overlap(candidate) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let matched_pivot = find_pivot(matched, candidate)?;
|
|
||||||
|
|
||||||
let correct: HashSet<_> = matched.iter().map(|&base| base - matched_pivot).collect();
|
|
||||||
|
|
||||||
for rot in Rotations::new(candidate) {
|
for rot in Rotations::new(candidate) {
|
||||||
for &start in &rot {
|
for &start in &rot {
|
||||||
let translated_iter = rot.iter().map(|&other| other - start);
|
relative.clear();
|
||||||
|
|
||||||
if translated_iter
|
relative.extend(rot.iter().map(|&other| other - start));
|
||||||
.clone()
|
|
||||||
.filter(|p| correct.contains(p))
|
if let Some((base, _)) = correct.iter().find(|(_, correct_relative)| {
|
||||||
.count()
|
correct_relative.intersection(&relative).count() >= 12
|
||||||
>= 12
|
}) {
|
||||||
{
|
|
||||||
// Found a solution, build the correct output
|
// Found a solution, build the correct output
|
||||||
let translated = translated_iter.map(|point| point + matched_pivot).collect();
|
let translated = relative.drain().map(|point| point + *base).collect();
|
||||||
|
|
||||||
return Some((start - matched_pivot, Scanner::new(translated)));
|
return Some((start - *base, translated));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,30 +157,33 @@ fn parts_common(input: &mut dyn Read) -> (HashSet<Point3>, Vec<Point3>) {
|
|||||||
|
|
||||||
let mut points: HashSet<_> = scanners[0].iter().copied().collect();
|
let mut points: HashSet<_> = scanners[0].iter().copied().collect();
|
||||||
|
|
||||||
let mut todo = vec![scanners.remove(0)];
|
let mut todo = vec![std::mem::take(&mut scanners[0])];
|
||||||
let mut scanners_found = vec![Point3::default()];
|
let mut scanners_found = vec![Point3::default()];
|
||||||
|
|
||||||
while let Some(matched) = todo.pop() {
|
while let Some(matched) = todo.pop() {
|
||||||
if scanners.is_empty() {
|
if scanners.iter().all(Vec::is_empty) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut i = 0;
|
let relative: Vec<(Point3, HashSet<Point3>)> = matched
|
||||||
|
.iter()
|
||||||
|
.map(|&base| (base, matched.iter().map(|&other| (other - base)).collect()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
while i < scanners.len() {
|
for candidate in &mut scanners {
|
||||||
if let Some((scanner, result)) = try_overlap(&matched, &scanners[i]) {
|
if candidate.is_empty() {
|
||||||
scanners.remove(i);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((scanner, result)) = try_overlap(&relative, candidate) {
|
||||||
scanners_found.push(scanner);
|
scanners_found.push(scanner);
|
||||||
points.extend(result.iter().copied());
|
points.extend(result.iter().copied());
|
||||||
todo.push(result);
|
todo.push(result);
|
||||||
} else {
|
candidate.clear();
|
||||||
i += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(scanners.is_empty());
|
|
||||||
|
|
||||||
(points, scanners_found)
|
(points, scanners_found)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,124 +1,10 @@
|
|||||||
use std::fmt::Display;
|
use std::collections::HashSet;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::ops::Index;
|
use std::mem::swap;
|
||||||
|
|
||||||
use crate::common::BitSet;
|
|
||||||
|
|
||||||
type Translation = [bool; 512];
|
type Translation = [bool; 512];
|
||||||
|
type Point = (i32, i32);
|
||||||
struct Field {
|
type Field = HashSet<Point>;
|
||||||
width: usize,
|
|
||||||
height: usize,
|
|
||||||
infinity: bool,
|
|
||||||
finite: BitSet,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Field {
|
|
||||||
pub fn from_input<'a>(input: impl Iterator<Item = &'a [u8]>) -> Self {
|
|
||||||
let mut input = input.peekable();
|
|
||||||
|
|
||||||
let width = input.peek().unwrap().len();
|
|
||||||
|
|
||||||
let mut finite = BitSet::new();
|
|
||||||
|
|
||||||
let len = input
|
|
||||||
.flatten()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(index, &c)| {
|
|
||||||
if c == b'#' {
|
|
||||||
finite.insert(index);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.count();
|
|
||||||
|
|
||||||
debug_assert_eq!(len % width, 0);
|
|
||||||
let height = len / width;
|
|
||||||
|
|
||||||
Self {
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
finite,
|
|
||||||
infinity: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn advance(&mut self, translation: &[bool; 512]) {
|
|
||||||
const INDEX_MASK: usize = (1 << 9) - 1;
|
|
||||||
|
|
||||||
let new_width = self.width + 2;
|
|
||||||
let new_height = self.height + 2;
|
|
||||||
|
|
||||||
let mut new_finite = BitSet::with_capacity(new_width * new_height);
|
|
||||||
|
|
||||||
for y in 0..new_height {
|
|
||||||
let mut mask = if self.infinity { INDEX_MASK } else { 0 };
|
|
||||||
|
|
||||||
for x in 0..new_width {
|
|
||||||
const COLUMN_MASK: usize = 0b001001001;
|
|
||||||
let mut submask = if self.infinity { COLUMN_MASK } else { 0 };
|
|
||||||
|
|
||||||
for y in y.saturating_sub(2)..=y {
|
|
||||||
submask = (submask << 3) | (self[(x, y)] as usize);
|
|
||||||
}
|
|
||||||
|
|
||||||
mask <<= 1;
|
|
||||||
mask &= !COLUMN_MASK;
|
|
||||||
mask |= submask;
|
|
||||||
mask &= INDEX_MASK;
|
|
||||||
|
|
||||||
if translation[mask] {
|
|
||||||
let index = x + y * new_width;
|
|
||||||
new_finite.insert(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.width += 2;
|
|
||||||
self.height += 2;
|
|
||||||
self.finite = new_finite;
|
|
||||||
self.infinity = translation[if self.infinity { INDEX_MASK } else { 0 }];
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
assert!(!self.infinity);
|
|
||||||
self.finite.len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Index<(usize, usize)> for Field {
|
|
||||||
type Output = bool;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
|
|
||||||
if x >= self.width || y >= self.height {
|
|
||||||
return &self.infinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
let index = x + y * self.width;
|
|
||||||
|
|
||||||
if self.finite.contains(index) {
|
|
||||||
&true
|
|
||||||
} else {
|
|
||||||
&false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Field {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
for y in 0..self.height {
|
|
||||||
for x in 0..self.width {
|
|
||||||
if self[(x, y)] {
|
|
||||||
write!(f, "#")?
|
|
||||||
} else {
|
|
||||||
write!(f, ".")?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeln!(f)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_input(input: &mut dyn Read) -> (Translation, Field) {
|
fn read_input(input: &mut dyn Read) -> (Translation, Field) {
|
||||||
let mut buffer = Vec::new();
|
let mut buffer = Vec::new();
|
||||||
@@ -133,16 +19,67 @@ fn read_input(input: &mut dyn Read) -> (Translation, Field) {
|
|||||||
.zip(it.next().unwrap())
|
.zip(it.next().unwrap())
|
||||||
.for_each(|(t, &c)| *t = c == b'#');
|
.for_each(|(t, &c)| *t = c == b'#');
|
||||||
|
|
||||||
let field = Field::from_input(it.skip(1));
|
let mut field = Field::default();
|
||||||
|
|
||||||
|
for (y, line) in it.skip(1).enumerate() {
|
||||||
|
for (x, _) in line.iter().enumerate().filter(|(_, &c)| c == b'#') {
|
||||||
|
field.insert((x as i32, y as i32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(translation, field)
|
(translation, field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_dimensions(field: &Field) -> ((i32, i32), (i32, i32)) {
|
||||||
|
field
|
||||||
|
.iter()
|
||||||
|
.fold(((0, 0), (0, 0)), |((xmin, xmax), (ymin, ymax)), &(x, y)| {
|
||||||
|
((xmin.min(x), xmax.max(x)), (ymin.min(y), ymax.max(y)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn advance(translation: &Translation, field: &Field, new_field: &mut Field, infinity: &mut bool) {
|
||||||
|
const INDEX_MASK: usize = (1 << 9) - 1;
|
||||||
|
new_field.clear();
|
||||||
|
|
||||||
|
let ((xmin, xmax), (ymin, ymax)) = find_dimensions(field);
|
||||||
|
|
||||||
|
for x in (xmin - 1)..=(xmax + 1) {
|
||||||
|
let mut index = if *infinity { INDEX_MASK } else { 0 };
|
||||||
|
|
||||||
|
for y in (ymin - 1)..=(ymax + 1) {
|
||||||
|
for dx in -1..=1 {
|
||||||
|
index <<= 1;
|
||||||
|
|
||||||
|
let nx = x + dx;
|
||||||
|
let ny = y + 1;
|
||||||
|
|
||||||
|
if nx < xmin || nx > xmax || ny < ymin || ny > ymax {
|
||||||
|
index |= *infinity as usize;
|
||||||
|
} else if field.contains(&(nx, ny)) {
|
||||||
|
index |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index &= INDEX_MASK;
|
||||||
|
|
||||||
|
if translation[index] {
|
||||||
|
new_field.insert((x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*infinity = translation[if *infinity { 511 } else { 0 }]
|
||||||
|
}
|
||||||
|
|
||||||
fn parts_common(input: &mut dyn Read, count: usize) -> String {
|
fn parts_common(input: &mut dyn Read, count: usize) -> String {
|
||||||
let (translation, mut field) = read_input(input);
|
let (translation, mut field) = read_input(input);
|
||||||
|
let mut new_field = Field::new();
|
||||||
|
let mut infinity = false;
|
||||||
|
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
field.advance(&translation);
|
advance(&translation, &field, &mut new_field, &mut infinity);
|
||||||
|
swap(&mut field, &mut new_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
field.len().to_string()
|
field.len().to_string()
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ use std::mem::swap;
|
|||||||
|
|
||||||
use crate::common::LineIter;
|
use crate::common::LineIter;
|
||||||
|
|
||||||
type Item<const S: usize> = (u32, State<S>);
|
type Item = (u32, u32, State);
|
||||||
type Todo<const S: usize> = BinaryHeap<Reverse<Item<S>>>;
|
type Todo = BinaryHeap<Reverse<Item>>;
|
||||||
type Visited<const S: usize> = HashMap<State<S>, u32>;
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
|
||||||
enum Pod {
|
enum Pod {
|
||||||
@@ -29,24 +28,6 @@ impl Pod {
|
|||||||
Pod::D => 1000,
|
Pod::D => 1000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dest(self) -> usize {
|
|
||||||
self as usize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<usize> for Pod {
|
|
||||||
type Error = usize;
|
|
||||||
|
|
||||||
fn try_from(index: usize) -> Result<Self, Self::Error> {
|
|
||||||
match index {
|
|
||||||
0 => Ok(Pod::A),
|
|
||||||
1 => Ok(Pod::B),
|
|
||||||
2 => Ok(Pod::C),
|
|
||||||
3 => Ok(Pod::D),
|
|
||||||
_ => Err(index),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<char> for Pod {
|
impl TryFrom<char> for Pod {
|
||||||
@@ -63,40 +44,26 @@ impl TryFrom<char> for Pod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
|
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
|
||||||
struct State<const S: usize> {
|
struct State {
|
||||||
hallway: [Option<Pod>; 11],
|
hallway: [Option<Pod>; 7],
|
||||||
rooms: [[Option<Pod>; S]; 4],
|
rooms: [[Option<Pod>; 2]; 4],
|
||||||
}
|
}
|
||||||
|
|
||||||
fn room_hallway_pos(room: usize) -> usize {
|
impl State {
|
||||||
room * 2 + 2
|
|
||||||
}
|
|
||||||
|
|
||||||
fn abs_delta(a: usize, b: usize) -> usize {
|
|
||||||
if a < b {
|
|
||||||
b - a
|
|
||||||
} else {
|
|
||||||
a - b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<const S: usize> State<S> {
|
|
||||||
const VALID_HALLWAY_POS: [usize; 7] = [0, 1, 3, 5, 7, 9, 10];
|
|
||||||
|
|
||||||
pub fn is_done(&self) -> bool {
|
pub fn is_done(&self) -> bool {
|
||||||
self == &State {
|
self == &State {
|
||||||
hallway: Default::default(),
|
hallway: [None; 7],
|
||||||
rooms: [
|
rooms: [
|
||||||
[Some(Pod::A); S],
|
[Some(Pod::A); 2],
|
||||||
[Some(Pod::B); S],
|
[Some(Pod::B); 2],
|
||||||
[Some(Pod::C); S],
|
[Some(Pod::C); 2],
|
||||||
[Some(Pod::D); S],
|
[Some(Pod::D); 2],
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_to_queue(self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
fn add_to_queue(self, cost: u32, todo: &mut Todo, visited: &mut HashMap<Self, u32>) {
|
||||||
let entry = visited.entry(self.clone());
|
let entry = visited.entry(self.clone());
|
||||||
|
|
||||||
if matches!(&entry, Entry::Occupied(entry) if *entry.get() <= cost) {
|
if matches!(&entry, Entry::Occupied(entry) if *entry.get() <= cost) {
|
||||||
@@ -104,219 +71,167 @@ impl<const S: usize> State<S> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print!("Next: \n{}", self);
|
||||||
|
|
||||||
// nightly only :'(
|
// nightly only :'(
|
||||||
// entry.insert(cost);
|
// entry.insert(cost);
|
||||||
*entry.or_default() = cost;
|
*entry.or_default() = cost;
|
||||||
|
|
||||||
todo.push(Reverse((cost + self.estimate(), self)))
|
todo.push(Reverse((cost + self.estimate(), cost, self)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn estimate(&self) -> u32 {
|
fn estimate(&self) -> u32 {
|
||||||
// A* estimate. For every entry that is not already "at rest", the cost is the cost
|
// A* estimate. For every entry that is not already "at rest", the cost is the cost
|
||||||
// required to get it to the top of its intended room.
|
// required to get it to the top of its intended room.
|
||||||
|
let mut estimate = 0;
|
||||||
|
|
||||||
// Cost to enter the hole for all pods that still need to
|
for (x, &pod) in self.hallway.iter().enumerate() {
|
||||||
let enter_estimate: u32 = self
|
if let Some(pod) = pod {
|
||||||
.rooms
|
let cost = if x == 0 {
|
||||||
.iter()
|
4 + pod as u32 * 2
|
||||||
.enumerate()
|
} else if x == 6 {
|
||||||
.map(|(index, room)| {
|
4 + (3 - pod as u32) * 2
|
||||||
let pod = Pod::try_from(index).unwrap();
|
} else if x <= (pod as usize) + 1 {
|
||||||
|
2 + 2 * (pod as u32 + (x as u32 - 1))
|
||||||
|
} else {
|
||||||
|
2 + 2 * (x as u32 - pod as u32 - 2)
|
||||||
|
};
|
||||||
|
estimate += cost * pod.cost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
room.iter()
|
|
||||||
.enumerate()
|
|
||||||
.rev()
|
|
||||||
.skip_while(|&(_, &entry)| entry == Some(pod))
|
|
||||||
.map(|(index, _)| index as u32 + 1)
|
|
||||||
.sum::<u32>()
|
|
||||||
* pod.cost()
|
|
||||||
})
|
|
||||||
.sum();
|
|
||||||
|
|
||||||
// Cost for all of the hallway to move to above their intended rooms
|
|
||||||
let hallway_estimate: u32 = self
|
|
||||||
.hallway
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter_map(|(pos, &pod)| {
|
|
||||||
let pod = pod?;
|
|
||||||
|
|
||||||
let destination_pos = room_hallway_pos(pod.dest());
|
|
||||||
|
|
||||||
Some(abs_delta(pos, destination_pos) as u32 * pod.cost())
|
|
||||||
})
|
|
||||||
.sum();
|
|
||||||
|
|
||||||
// Cost to move out of the room and above the correct rooms
|
|
||||||
let rooms_estimate: u32 = self
|
|
||||||
.rooms
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(room_index, room)| {
|
|
||||||
let hallway_pos = room_hallway_pos(room_index);
|
|
||||||
|
|
||||||
room.iter()
|
|
||||||
.enumerate()
|
|
||||||
.rev()
|
|
||||||
.skip_while(|&(_, &entry)| {
|
|
||||||
entry.map(|pod| pod.dest() == room_index).unwrap_or(false)
|
|
||||||
})
|
|
||||||
.filter_map(|(room_pos, &pod)| {
|
|
||||||
let pod = pod?;
|
|
||||||
|
|
||||||
let destination_pos = room_hallway_pos(pod.dest());
|
|
||||||
|
|
||||||
let steps = 1 + room_pos + abs_delta(hallway_pos, destination_pos).max(2);
|
|
||||||
|
|
||||||
Some(steps as u32 * pod.cost())
|
|
||||||
})
|
|
||||||
.sum::<u32>()
|
|
||||||
})
|
|
||||||
.sum();
|
|
||||||
|
|
||||||
enter_estimate + hallway_estimate + rooms_estimate
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_next(&self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
|
||||||
self.room_to_hallway(cost, todo, visited);
|
|
||||||
self.hallway_to_room(cost, todo, visited);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn room_to_hallway(&self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
|
||||||
for (index, room) in self.rooms.iter().enumerate() {
|
for (index, room) in self.rooms.iter().enumerate() {
|
||||||
// Check if we even want to move anything out of this room
|
if let Some(last) = room
|
||||||
if room
|
|
||||||
.iter()
|
.iter()
|
||||||
.all(|entry| entry.map(|pod| pod.dest() == index).unwrap_or(true))
|
.rposition(|&pod| !matches!(pod, Some(pod) if pod as usize == index))
|
||||||
{
|
{
|
||||||
|
for pos in 0..=last {
|
||||||
|
if let Some(pod) = room[pos] {
|
||||||
|
if pod as usize != index {
|
||||||
|
let abs_diff = index.max(pod as usize) - index.min(pod as usize);
|
||||||
|
estimate += (pos + 2 + 2 * abs_diff) as u32 * pod.cost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
estimate
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_next(&self, cost: u32, todo: &mut Todo, visited: &mut HashMap<Self, u32>) {
|
||||||
|
self.generate_hallway(cost, todo, visited);
|
||||||
|
self.generate_rooms(cost, todo, visited);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_rooms(&self, cost: u32, todo: &mut Todo, visited: &mut HashMap<Self, u32>) {
|
||||||
|
for (index, room) in self.rooms.iter().enumerate() {
|
||||||
|
// Check what part of the room should still move
|
||||||
|
if let Some(last) = room
|
||||||
|
.iter()
|
||||||
|
.rposition(|&pod| !matches!(pod, Some(pod) if pod as usize == index))
|
||||||
|
{
|
||||||
|
for pos in 0..=last {
|
||||||
|
let pod = match room[pos] {
|
||||||
|
Some(pod) => pod,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if we can move up
|
||||||
|
if pos > 0 && room[pos - 1].is_none() {
|
||||||
|
let mut new_state = self.clone();
|
||||||
|
new_state.rooms[index].swap(pos, pos - 1);
|
||||||
|
let new_cost = cost + pod.cost();
|
||||||
|
new_state.add_to_queue(new_cost, todo, visited);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we can move down
|
||||||
|
if pos + 1 < room.len() && room[pos + 1].is_none() {
|
||||||
|
let mut new_state = self.clone();
|
||||||
|
new_state.rooms[index].swap(pos, pos + 1);
|
||||||
|
let new_cost = cost + pod.cost();
|
||||||
|
new_state.add_to_queue(new_cost, todo, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we can pop out of the room
|
||||||
|
if let Some(pod) = room[0] {
|
||||||
|
for pos in [index + 1, index + 2] {
|
||||||
|
if self.hallway[pos].is_none() {
|
||||||
|
let mut new_state = self.clone();
|
||||||
|
swap(&mut new_state.rooms[index][0], &mut new_state.hallway[pos]);
|
||||||
|
let new_cost = cost + pod.cost();
|
||||||
|
new_state.add_to_queue(new_cost, todo, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_hallway(&self, cost: u32, todo: &mut Todo, visited: &mut HashMap<Self, u32>) {
|
||||||
|
for index in 0..self.hallway.len() {
|
||||||
|
let pod = if let Some(pod) = self.hallway[index] {
|
||||||
|
pod
|
||||||
|
} else {
|
||||||
continue;
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if we can move right
|
||||||
|
if index + 1 < self.hallway.len() && self.hallway[index + 1].is_none() {
|
||||||
|
let mut new_state = self.clone();
|
||||||
|
new_state.hallway.swap(index, index + 1);
|
||||||
|
let added_cost = if index == 0 || index == 5 {
|
||||||
|
pod.cost()
|
||||||
|
} else {
|
||||||
|
2 * pod.cost()
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_cost = cost + added_cost;
|
||||||
|
new_state.add_to_queue(new_cost, todo, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (pos, pod) = room
|
// Check if we can move left
|
||||||
.iter()
|
if index > 1 && self.hallway[index - 1].is_none() {
|
||||||
.enumerate()
|
let mut new_state = self.clone();
|
||||||
.find_map(|(pos, entry)| entry.map(|pod| (pos, pod)))
|
new_state.hallway.swap(index, index - 1);
|
||||||
.unwrap(); // Safe unwrap, we know it exists from above.
|
let added_cost = if index == 1 || index == 6 {
|
||||||
|
pod.cost()
|
||||||
|
} else {
|
||||||
|
2 * pod.cost()
|
||||||
|
};
|
||||||
|
|
||||||
let base_cost = 1 + pos;
|
let new_cost = cost + added_cost;
|
||||||
let hallway_pos = room_hallway_pos(index);
|
new_state.add_to_queue(new_cost, todo, visited);
|
||||||
|
}
|
||||||
|
|
||||||
let mut queue_new = |new_pos, new_cost| {
|
// Check if we can pop into a room to the right
|
||||||
|
if (1..=4).contains(&index) && self.rooms[index - 1][0].is_none() {
|
||||||
let mut new_state = self.clone();
|
let mut new_state = self.clone();
|
||||||
swap(
|
swap(
|
||||||
&mut new_state.hallway[new_pos],
|
&mut new_state.hallway[index],
|
||||||
&mut new_state.rooms[index][pos],
|
&mut new_state.rooms[index - 1][0],
|
||||||
);
|
);
|
||||||
|
|
||||||
new_state.add_to_queue(new_cost + cost, todo, visited)
|
let new_cost = cost + 2 * pod.cost();
|
||||||
};
|
new_state.add_to_queue(new_cost, todo, visited);
|
||||||
|
|
||||||
// Check positions to the left
|
|
||||||
for new_pos in (0..hallway_pos).rev() {
|
|
||||||
if self.hallway[new_pos].is_some() {
|
|
||||||
// Hit an occupied room
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !Self::VALID_HALLWAY_POS.contains(&new_pos) {
|
|
||||||
// Not allowed to stop here
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_cost = (base_cost + hallway_pos - new_pos) as u32 * pod.cost();
|
|
||||||
queue_new(new_pos, new_cost);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// And to the right
|
if (2..=5).contains(&index) && self.rooms[index - 2][0].is_none() {
|
||||||
for new_pos in hallway_pos..self.hallway.len() {
|
let mut new_state = self.clone();
|
||||||
if self.hallway[new_pos].is_some() {
|
swap(
|
||||||
// Hit an occupied room
|
&mut new_state.hallway[index],
|
||||||
break;
|
&mut new_state.rooms[index - 2][0],
|
||||||
}
|
);
|
||||||
|
|
||||||
if !Self::VALID_HALLWAY_POS.contains(&new_pos) {
|
let new_cost = cost + 2 * pod.cost();
|
||||||
// Not allowed to stop here
|
new_state.add_to_queue(new_cost, todo, visited);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_cost = (base_cost + new_pos - hallway_pos) as u32 * pod.cost();
|
|
||||||
queue_new(new_pos, new_cost);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hallway_to_room(&self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
|
||||||
for (pos, pod) in self
|
|
||||||
.hallway
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter_map(|(pos, pod)| pod.map(|pod| (pos, pod)))
|
|
||||||
{
|
|
||||||
let room = pod.dest();
|
|
||||||
let new_hallway_pos = room_hallway_pos(room);
|
|
||||||
|
|
||||||
// Check if the path is free
|
|
||||||
let in_between = if new_hallway_pos < pos {
|
|
||||||
&self.hallway[(new_hallway_pos + 1)..pos]
|
|
||||||
} else {
|
|
||||||
&self.hallway[(pos + 1)..new_hallway_pos]
|
|
||||||
};
|
|
||||||
|
|
||||||
if in_between.iter().any(Option::is_some) {
|
|
||||||
// Something's in the way
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we can move into the room
|
|
||||||
if self.rooms[room]
|
|
||||||
.iter()
|
|
||||||
.copied()
|
|
||||||
.flatten()
|
|
||||||
.any(|other| other != pod)
|
|
||||||
{
|
|
||||||
// Scared of other pods
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let room_pos = if let Some(pos) = self.rooms[room].iter().rposition(Option::is_none) {
|
|
||||||
pos
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_cost = (abs_delta(pos, new_hallway_pos) + room_pos + 1) as u32 * pod.cost();
|
|
||||||
let mut new_state = self.clone();
|
|
||||||
swap(
|
|
||||||
&mut new_state.hallway[pos],
|
|
||||||
&mut new_state.rooms[room][room_pos],
|
|
||||||
);
|
|
||||||
new_state.add_to_queue(cost + new_cost, todo, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn solve(&self) -> u32 {
|
|
||||||
let mut todo = Todo::new();
|
|
||||||
|
|
||||||
let mut visited = HashMap::new();
|
|
||||||
visited.insert(self.clone(), 0);
|
|
||||||
|
|
||||||
todo.push(Reverse((self.estimate(), self.clone())));
|
|
||||||
|
|
||||||
while let Some(Reverse((_, state))) = todo.pop() {
|
|
||||||
let cost = *visited.get(&state).unwrap_or(&0);
|
|
||||||
|
|
||||||
if state.is_done() {
|
|
||||||
return cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.generate_next(cost, &mut todo, &mut visited);
|
|
||||||
}
|
|
||||||
|
|
||||||
panic!("No route found!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const S: usize> Display for State<S> {
|
impl Display for State {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let helper = |opt_pod| match opt_pod {
|
let helper = |opt_pod| match opt_pod {
|
||||||
Some(Pod::A) => 'A',
|
Some(Pod::A) => 'A',
|
||||||
@@ -326,14 +241,13 @@ impl<const S: usize> Display for State<S> {
|
|||||||
None => '.',
|
None => '.',
|
||||||
};
|
};
|
||||||
writeln!(f, "#############")?;
|
writeln!(f, "#############")?;
|
||||||
write!(f, "#")?;
|
write!(f, "#{}{}", helper(self.hallway[0]), helper(self.hallway[1]))?;
|
||||||
|
for i in 2..=5 {
|
||||||
for entry in self.hallway {
|
write!(f, ".{}", helper(self.hallway[i]))?;
|
||||||
write!(f, "{}", helper(entry))?;
|
|
||||||
}
|
}
|
||||||
writeln!(f, "#")?;
|
writeln!(f, "{}#", helper(self.hallway[6]))?;
|
||||||
|
|
||||||
for i in 0..S {
|
for i in 0..(self.rooms[0].len()) {
|
||||||
writeln!(
|
writeln!(
|
||||||
f,
|
f,
|
||||||
" #{}#{}#{}#{}#",
|
" #{}#{}#{}#{}#",
|
||||||
@@ -348,12 +262,9 @@ impl<const S: usize> Display for State<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_input(input: &mut dyn Read) -> State<2> {
|
fn read_input(input: &mut dyn Read) -> State {
|
||||||
let mut reader = LineIter::new(input);
|
let mut reader = LineIter::new(input);
|
||||||
let mut state = State {
|
let mut state = State::default();
|
||||||
hallway: Default::default(),
|
|
||||||
rooms: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let _ = reader.next();
|
let _ = reader.next();
|
||||||
let _ = reader.next();
|
let _ = reader.next();
|
||||||
@@ -376,44 +287,28 @@ fn read_input(input: &mut dyn Read) -> State<2> {
|
|||||||
|
|
||||||
pub fn part1(input: &mut dyn Read) -> String {
|
pub fn part1(input: &mut dyn Read) -> String {
|
||||||
let state = read_input(input);
|
let state = read_input(input);
|
||||||
|
let mut todo = Todo::new();
|
||||||
|
|
||||||
state.solve().to_string()
|
let mut visited = HashMap::new();
|
||||||
|
visited.insert(state.clone(), 0);
|
||||||
|
|
||||||
|
todo.push(Reverse((state.estimate(), 0, state)));
|
||||||
|
|
||||||
|
while let Some(Reverse((_, cost, state))) = todo.pop() {
|
||||||
|
if state.is_done() {
|
||||||
|
return cost.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("\nExpanding:\n{}", state);
|
||||||
|
|
||||||
|
state.generate_next(cost, &mut todo, &mut visited);
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("No route found!")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn part2(input: &mut dyn Read) -> String {
|
pub fn part2(_input: &mut dyn Read) -> String {
|
||||||
let state2 = read_input(input);
|
todo!()
|
||||||
|
|
||||||
let state4 = State {
|
|
||||||
hallway: Default::default(),
|
|
||||||
rooms: [
|
|
||||||
[
|
|
||||||
state2.rooms[0][0],
|
|
||||||
Some(Pod::D),
|
|
||||||
Some(Pod::D),
|
|
||||||
state2.rooms[0][1],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
state2.rooms[1][0],
|
|
||||||
Some(Pod::C),
|
|
||||||
Some(Pod::B),
|
|
||||||
state2.rooms[1][1],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
state2.rooms[2][0],
|
|
||||||
Some(Pod::B),
|
|
||||||
Some(Pod::A),
|
|
||||||
state2.rooms[2][1],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
state2.rooms[3][0],
|
|
||||||
Some(Pod::A),
|
|
||||||
Some(Pod::C),
|
|
||||||
state2.rooms[3][1],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
state4.solve().to_string()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -430,9 +325,9 @@ mod tests {
|
|||||||
hallway: Default::default(),
|
hallway: Default::default(),
|
||||||
rooms: [
|
rooms: [
|
||||||
[Some(Pod::A); 2],
|
[Some(Pod::A); 2],
|
||||||
[Some(Pod::B); 2],
|
[Some(Pod::B), Some(Pod::B)],
|
||||||
[Some(Pod::C); 2],
|
[Some(Pod::C), Some(Pod::C)],
|
||||||
[Some(Pod::D); 2],
|
[Some(Pod::D), Some(Pod::D)],
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -443,9 +338,4 @@ mod tests {
|
|||||||
fn sample_part1() {
|
fn sample_part1() {
|
||||||
test_implementation(part1, SAMPLE, 12521);
|
test_implementation(part1, SAMPLE, 12521);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
test_implementation(part2, SAMPLE, 44169);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,159 +1,9 @@
|
|||||||
//! Very input-specific reverse-engineered solution
|
|
||||||
//!
|
|
||||||
//! # General implementation
|
|
||||||
//!
|
|
||||||
//! The code in the examples is a series of 14 times this:
|
|
||||||
//!
|
|
||||||
//! ```txt
|
|
||||||
//! inp w -> read digit
|
|
||||||
//! mul x 0
|
|
||||||
//! add x z
|
|
||||||
//! mod x 26 -> x = z % 26
|
|
||||||
//! div z $A -> pop Z (see below)
|
|
||||||
//! add x $B
|
|
||||||
//! eql x w -> x = ((z + $B) == w)
|
|
||||||
//! eql x 0 -> x = ((z + $B) != w)
|
|
||||||
//! mul y 0
|
|
||||||
//! add y 25
|
|
||||||
//! mul y x
|
|
||||||
//! add y 1 -> if x { 26 } else { 1 }
|
|
||||||
//! mul z y -> if x { z *= 26 } (push z, see below)
|
|
||||||
//! mul y 0
|
|
||||||
//! add y w
|
|
||||||
//! add y $C -> y = w + $C
|
|
||||||
//! mul y x
|
|
||||||
//! add z y -> if x { z += w + $C }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! `$A` is either `1` or `26` which we can translate to a bool `$A == 26` for convenience. This
|
|
||||||
//! simplifies to the following rust.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! fn validate<const A: bool, const B: i32, const C: i32>(mut z: i32, digit: i32) -> i32 {
|
|
||||||
//! let x = (z % 26 + B) != digit;
|
|
||||||
//! if A {
|
|
||||||
//! z /= 26;
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! if x {
|
|
||||||
//! z = 26 * z + digit + C;
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! z
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! In human terms, `z` is used to hold a base 26 number. When `$A` is `true`, we pop off the least
|
|
||||||
//! significant digit by dividing by 26. Then, depending on whether `(z + $B) % 26` is equal to our
|
|
||||||
//! digit, we push `digit + $C`. Ideally, we should pop as often as we push in order to arrive at `z
|
|
||||||
//! == 0` in the end. The input contains 7 pops, so we want each of those to not push.
|
|
||||||
//!
|
|
||||||
//! To solve this problem, we use a backtracking memoizing algorithm, where we cancel every sequence
|
|
||||||
//! that fails to pop at some point. A pop is failed whenever we execute a validation pop where we
|
|
||||||
//! can pop if `x` happened to be set to `0` at the time of the check. We can memoize this over the
|
|
||||||
//! running value of `z`.
|
|
||||||
//!
|
|
||||||
//! This implementation probably doesn't work on other people's input; to fix it, you'll want to
|
|
||||||
//! update the `parse_step` function. Good luck with that.
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
use nom::branch::alt;
|
pub fn part1(_input: &mut dyn Read) -> String {
|
||||||
use nom::bytes::complete::tag;
|
todo!()
|
||||||
use nom::character::complete::newline;
|
|
||||||
use nom::combinator::map;
|
|
||||||
use nom::multi::separated_list1;
|
|
||||||
use nom::sequence::delimited;
|
|
||||||
use nom::sequence::preceded;
|
|
||||||
use nom::sequence::tuple;
|
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
use crate::common::read_input;
|
|
||||||
|
|
||||||
type Cache = HashMap<(usize, i32), Option<i64>>;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Step(bool, i32, i32);
|
|
||||||
|
|
||||||
impl Step {
|
|
||||||
fn evaluate(&self, digit: i32, z: i32) -> Option<i32> {
|
|
||||||
if self.0 {
|
|
||||||
(z % 26 + self.1 == digit).then(|| z / 26)
|
|
||||||
} else {
|
|
||||||
Some(z * 26 + digit + self.2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_step(input: &[u8]) -> IResult<&[u8], Step> {
|
pub fn part2(_input: &mut dyn Read) -> String {
|
||||||
use nom::character::complete::i32;
|
todo!()
|
||||||
|
|
||||||
let parse_pop = preceded(
|
|
||||||
tag("inp w\nmul x 0\nadd x z\nmod x 26\ndiv z "),
|
|
||||||
alt((map(tag("1"), |_| false), map(tag("26"), |_| true))),
|
|
||||||
);
|
|
||||||
|
|
||||||
let parse_a = preceded(tag("\nadd x "), i32);
|
|
||||||
|
|
||||||
let parse_b = delimited(
|
|
||||||
tag("\neql x w\neql x 0\nmul y 0\nadd y 25\nmul y x\nadd y 1\nmul z y\nmul y 0\nadd y w\nadd y "),
|
|
||||||
i32,
|
|
||||||
tag("\nmul y x\nadd z y"),
|
|
||||||
);
|
|
||||||
|
|
||||||
map(tuple((parse_pop, parse_a, parse_b)), |(pop, a, b)| {
|
|
||||||
Step(pop, a, b)
|
|
||||||
})(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Step>> {
|
|
||||||
separated_list1(newline, parse_step)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn optimize(
|
|
||||||
current: usize,
|
|
||||||
steps: &[Step],
|
|
||||||
digits: &[i32],
|
|
||||||
z: i32,
|
|
||||||
cache: &mut Cache,
|
|
||||||
) -> Option<i64> {
|
|
||||||
if current >= steps.len() {
|
|
||||||
return (z == 0).then(|| 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(&memoized) = cache.get(&(current, z)) {
|
|
||||||
return memoized;
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = digits.iter().find_map(|&digit| {
|
|
||||||
let z = steps[current].evaluate(digit, z)?;
|
|
||||||
let result = optimize(current + 1, steps, digits, z, cache)?;
|
|
||||||
|
|
||||||
Some(result + digit as i64 * 10i64.pow(13 - current as u32))
|
|
||||||
});
|
|
||||||
cache.insert((current, z), result);
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parts_common(input: &mut dyn Read, digits: &[i32]) -> String {
|
|
||||||
let steps = read_input(input, parse_input);
|
|
||||||
|
|
||||||
let mut cache = Cache::new();
|
|
||||||
|
|
||||||
optimize(0, &steps, digits, 0, &mut cache)
|
|
||||||
.unwrap()
|
|
||||||
.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &mut dyn Read) -> String {
|
|
||||||
let digits = [9, 8, 7, 6, 5, 4, 3, 2, 1];
|
|
||||||
|
|
||||||
parts_common(input, &digits)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &mut dyn Read) -> String {
|
|
||||||
let digits = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
||||||
|
|
||||||
parts_common(input, &digits)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ pub fn get_implementation(day: usize, part2: bool) -> Solution {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn test_implementation(solution: Solution, data: &[u8], answer: impl ToString) {
|
fn test_implementation(solution: Solution, data: &[u8], answer: impl ToString) {
|
||||||
let result = solution(&mut &*data);
|
let result = solution(&mut &data[..]);
|
||||||
|
|
||||||
assert_eq!(answer.to_string(), result);
|
assert_eq!(answer.to_string(), result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "aoc_2022"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
anyhow = "1.0.66"
|
|
||||||
clap = { version = "4.0.19", features = ["derive"] }
|
|
||||||
itertools = "0.10.5"
|
|
||||||
nom = "7.1.1"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
criterion = "0.4.0"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
# Keep debug information in release for better flamegraphs
|
|
||||||
debug = true
|
|
||||||
|
|
||||||
[profile.bench]
|
|
||||||
# And same for benchmarking
|
|
||||||
debug = true
|
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "days"
|
|
||||||
harness = false
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Advent of Code 2022
|
|
||||||
|
|
||||||
Another year and another Advent of Code in Rust. Because last year went so well, this time we'll be
|
|
||||||
aiming for a total time of under 250ms.
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ target/release/aoc_2022 --help
|
|
||||||
Advent of Code 2022 runner
|
|
||||||
|
|
||||||
Usage: aoc_2022 [OPTIONS] <DAY>
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
<DAY> Which day to run
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-t, --time Print time taken
|
|
||||||
-2, --part2 Run part 2 instead of part 1
|
|
||||||
-i, --input <INPUT> Read input from the given file instead of stdin
|
|
||||||
-h, --help Print help information
|
|
||||||
```
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
use std::fs::File;
|
|
||||||
use std::io::Read;
|
|
||||||
|
|
||||||
use aoc_2022::get_implementation;
|
|
||||||
use criterion::criterion_group;
|
|
||||||
use criterion::criterion_main;
|
|
||||||
use criterion::BenchmarkId;
|
|
||||||
use criterion::Criterion;
|
|
||||||
|
|
||||||
/// Number of days we have an implementation to benchmark
|
|
||||||
const DAYS_IMPLEMENTED: u8 = 25;
|
|
||||||
|
|
||||||
fn read_input(day: u8) -> Vec<u8> {
|
|
||||||
let input_path = format!("inputs/{:02}.txt", day);
|
|
||||||
|
|
||||||
let mut buffer = Vec::new();
|
|
||||||
File::open(input_path)
|
|
||||||
.expect("Failed to open input file")
|
|
||||||
.read_to_end(&mut buffer)
|
|
||||||
.expect("Failed to read input file");
|
|
||||||
|
|
||||||
buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn benchmark_days(c: &mut Criterion) {
|
|
||||||
for day in 1..=DAYS_IMPLEMENTED {
|
|
||||||
let input = read_input(day);
|
|
||||||
|
|
||||||
let part1 = get_implementation(day, false).unwrap();
|
|
||||||
|
|
||||||
c.bench_with_input(BenchmarkId::new("part1", day), &input, |b, i| {
|
|
||||||
b.iter(|| part1(i));
|
|
||||||
});
|
|
||||||
|
|
||||||
if day < 25 {
|
|
||||||
let part2 = get_implementation(day, true).unwrap();
|
|
||||||
|
|
||||||
c.bench_with_input(BenchmarkId::new("part2", day), &input, |b, i| {
|
|
||||||
b.iter(|| part2(i));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
criterion_group!(benches, benchmark_days);
|
|
||||||
criterion_main!(benches);
|
|
||||||
2259
2022/inputs/01.txt
2259
2022/inputs/01.txt
File diff suppressed because it is too large
Load Diff
2500
2022/inputs/02.txt
2500
2022/inputs/02.txt
File diff suppressed because it is too large
Load Diff
@@ -1,300 +0,0 @@
|
|||||||
NJvhJcQWTJWTNTFFMTqqGqfTmB
|
|
||||||
VwVzPldRZVLVRmfsvfjvqfmm
|
|
||||||
ZDPDHZHVcvDhbvnv
|
|
||||||
FHHwHBzzVCWWmmCzCPrVmgBwbLTtRFFbbbttRGRLjTcLpbbT
|
|
||||||
vhZZvdsNSdSMdNvjncppCLcLnGnj
|
|
||||||
CDZZsNZMZqdNSdlNZCqrzPHDzgrgzwVVWwmwwm
|
|
||||||
ndlndntsFJntFvccLjjLrjBShcBBfc
|
|
||||||
GpCGHzVwmmzqQWSSSfWHBhQL
|
|
||||||
mpCMGGCZVzVwGGVwmJsZnFtZnTSTJtdsvl
|
|
||||||
nCnPDGmDNmVCsVQDmGSWqvzchWSjjcWGqS
|
|
||||||
gTnBRLpfTRnrTdZgdLfRdrThvqcvWWhFFWvcFSSgjqqzjv
|
|
||||||
pfZfTMwrbLTTfsbmQtlVtHHnbs
|
|
||||||
wNdSdsbTvTZMTvTv
|
|
||||||
rrdRWdWQhFVdHWBGWQmmmnnMvCfmnhvmCmtZ
|
|
||||||
rJrVDRWpGddpbSlNSlspPP
|
|
||||||
chTNrthMMwWMTjfsmRzZszJpwm
|
|
||||||
BLnFFCngbcBnbbldDlpRjGpmsCzGsGsRGmmG
|
|
||||||
dqvnvlgbqtcPPMhH
|
|
||||||
QcLNqZbCzJDQBJJRpwzRpdnRldgnpf
|
|
||||||
GmmmvVGsHrWffrlwdCWd
|
|
||||||
CMsFVVFjCmFStGQbbLZNBbJBcTjc
|
|
||||||
LQVggbQvcLbQLHgvVLhWGGsChssrMWfzGccc
|
|
||||||
qDnRTTRqJttPfWMChJhGslWlzh
|
|
||||||
qRTRwPBTBtRZdnjnqqqnQVbjbNLFbbfLgVmgHLQm
|
|
||||||
cZbzwCwZPlJcMLrNSNfHWNBBNZ
|
|
||||||
vsQsDCqtsDhmtjVrBNWNjBHrhr
|
|
||||||
TtDTGnvTlgbbRCGg
|
|
||||||
BgBlplHlsgNNsJlVpBtPwJhMPRRQSSttRtSP
|
|
||||||
bvhTnmdFTzddStwStQRddt
|
|
||||||
ZnZDLvnvqZzbbhFzzmTbnFsVjVlNgsCCNVsVLpNWVgsB
|
|
||||||
TdptqrrcVGhhzFtw
|
|
||||||
DRnSfwJlDmmDDVGv
|
|
||||||
RCSQNSCQZndwbcMqQrBB
|
|
||||||
wvRlrlwVwwqzgbZRdCJBWfmdzCWfBdhf
|
|
||||||
cFcsQpNtLLsGTtNGpMdPmDdPBmmBvJPWvDtC
|
|
||||||
TpjssTFFvLLLcFFQpwbwwHngjHRrZRqZVH
|
|
||||||
mqqddrPPcPmqPDlrQnjTrbvMvbHzzsjjpTvz
|
|
||||||
gtBWgGgVhLGWHzMDztzstDHj
|
|
||||||
hfWRhBBNBGgLNQDPwdNPcPdw
|
|
||||||
LhQzdhhbTzpMhddhhhTzhnZcBFllHZFtrrHZHMHFjlHr
|
|
||||||
mwwssqDvjptrvplr
|
|
||||||
NCSgVDPDwmDgVJVpLfTznQJdhfLhnhQQ
|
|
||||||
GzjzDhjhhZzcrRgQCBjBPBBjQCgT
|
|
||||||
vHHHmntsbSgLwbsSmNHbwNbvpqPCBVppCpFTpTPTBtqWBCqV
|
|
||||||
NJbwNSwdndvmvwhGhgzcfMcDJfgJ
|
|
||||||
GncgDvvcMGnttjDvrgRRFSZZLZFWdJFJwGQwZBWZ
|
|
||||||
bPqpChPfsshfZZBdZdLTFZ
|
|
||||||
lNqqsClmbsNlPbHqPsmblmsrHdvdMngcVrjggvrvggRDcn
|
|
||||||
bDvtgVVVpMQvjQWmQL
|
|
||||||
rwTflmlfZJBBdQWQWjQqdM
|
|
||||||
HsJJmZZwscHrwTrcRbzpcbPgtCSbgz
|
|
||||||
CsCsRvshMjpbqCqf
|
|
||||||
ncblgDBgtDmmmTlBgwlgbHHqMFHLqPDMHPHHpqWfFM
|
|
||||||
TcBctSmTZTtSTzsZvsvJZRsGVb
|
|
||||||
znznvngttwltzlLwhtThHbqHPvNbNHSSHmmNWHjP
|
|
||||||
FBcLrRMFQpPqpPSpqHHW
|
|
||||||
fRQMJZJfrcMcMVrQJJftnwCzVCltgTnstTVnVL
|
|
||||||
MfLlRfCMrLzRlQgwNqQFcsGd
|
|
||||||
jtTjjBTvbdqcGjqFcj
|
|
||||||
vvShDSBDppzhCmzq
|
|
||||||
plWMptTvfrnncvcRfwqzqLGhzhzThNzNNJqD
|
|
||||||
jSdSHFPQQbdPCQCssjSbBmhJGNZZNGNqqJNBlJqqLh
|
|
||||||
VCCCVCQgjdddjCgljCjbbwgRRttgrpftfWrgvpwpnf
|
|
||||||
MWlbBcPjjvvjPWWMPqgRQZfJZDGGbRZJffQQwh
|
|
||||||
HrHrnncHpzrJQJfVDQVR
|
|
||||||
zzsSTtSTLzsspSdtTmHHmpmtFgqcgPlgFqWBqqqBMdWWvFlg
|
|
||||||
nSqBbJbqlnBBClVZcMgZVgcP
|
|
||||||
FQwrwHrRwWWFBRPNgNgcCGZZZC
|
|
||||||
rWFWFTwpwwWzHrnDbfJDLDbBBbbz
|
|
||||||
BMmNtLMMtFCNFNMvvLmcndpgcdgppPrgrGPPrgJD
|
|
||||||
WVWWhbTtVnGpjrrPhr
|
|
||||||
HWssSTHWfRHRsQQFLvfvFFCLCNMNlt
|
|
||||||
sTmDsQffVrrLCjTFltTFWL
|
|
||||||
BnwwQBJbJndMMRzMwCLlWlLWWCWLLtRlWF
|
|
||||||
cqqBMcMqwnznMGzcvDmQhrvssHmPDVssrP
|
|
||||||
pQGQGJDDrDVJbbfVzvvgPcCZwhZhncscZWWc
|
|
||||||
SqMMlBBljMmRlchhPTqThCZnPs
|
|
||||||
FMjMBmjRNFHQJJpHVhVDhG
|
|
||||||
tHNNdBdNtBBBMgsMpsZm
|
|
||||||
wVPzVvbwqzhrVqvjqzzsZpDsZDsZmsCPCgZgCM
|
|
||||||
bVbvLThvvbrWqHmmnJLdHdJQLn
|
|
||||||
PzTspPZpdLLDZTplPLpPDpvbfhnqNvqzfvNMzQQfNwnQ
|
|
||||||
GWRHmjmFWMMSnhbhHw
|
|
||||||
JWWcmtBrBtWBFWGJpsgTgldhLVLpJl
|
|
||||||
DwLMDzLMhvMcwvgdVqWWlCVgvlqF
|
|
||||||
TTSBBRpbStHZVgjWFldjRVlV
|
|
||||||
SnbTBdJBmnpQzMPDMcMznr
|
|
||||||
nNlMNBPPNtJQnbZhZsgSbh
|
|
||||||
czzCjcwTdvSbgQNcgNQq
|
|
||||||
VTdNdGDTzDTdlFFPtBrtLtDr
|
|
||||||
FMbbfMlzvFsmgVZmmg
|
|
||||||
SrNTHGmdSQDqLhtQhhgggs
|
|
||||||
dRDTSDPPcHRdHGDHlwJBbmwljmMcfjbW
|
|
||||||
sQgWLtqLtWhdqlpNZRpG
|
|
||||||
blTHTjlvTCJnJvRZdGGhHHGZhFGV
|
|
||||||
CCDlJclnCmbrmBMgcwcLWtcBsB
|
|
||||||
vqPWWvqwwCFvFZfZPRFRrcGQrQwsDrNcrwnbDNcQ
|
|
||||||
LVgJLSBBVtzTLzBMmTMJmLnnDNQcrsGbsQbNbrbDjs
|
|
||||||
zggVSmmhVdfqFhvHWG
|
|
||||||
WwdndGGmmmLwwwmRwWSncLRnZqZqhqZthBtqtBqZBgtdtvMH
|
|
||||||
FfHHzlQQDsFzzrNsVTfttZvTvttTqqtbqb
|
|
||||||
lQjFDNQFPjCsVCCDjGCwwSGGnccwcHppGp
|
|
||||||
mrjggcFsFMjdjZRpSZpn
|
|
||||||
NCqfLCFNbQPzPPlPzNfSRTRZdSdWWwndpqRSSd
|
|
||||||
vDvzzbPQFNCFtllLLNMBhMcDHGBGMggMmcBc
|
|
||||||
jhjlBvvnjbtDNPjtSjBDBbDNgHggrQrhghRQrqRrZcRwwqVg
|
|
||||||
pLdTMsWdLLmpMdqZZdPdVqZgHPwH
|
|
||||||
WLTCGmMLfPSlbGjlnnJD
|
|
||||||
gtbwhgHbHgqqbgQthgQLtZZCRjMcjjnRnrRNJmMRJrNhRc
|
|
||||||
bGWVTTvDvfpVFFBpvvVTdRDMJcrccCrJnMRnNnNCcc
|
|
||||||
FVWTBsdvdTzTBFWssVQtLgSQtHqqPzPbqHbw
|
|
||||||
dlzrPTSSjSrllzWhsvVmVtTRTWtf
|
|
||||||
bJMpLGcqGhNbJQttVQmmvRWWsp
|
|
||||||
qLbMwqqbGHFGzrlZrjhPHCrj
|
|
||||||
rNrrffVlqqrfLlPpltcBBTTGRzzZRPRsBTcJ
|
|
||||||
msbsmWSsMmQwjdMbWMhMhQmcRZRzGjTBGTBcBJBjCHJGcC
|
|
||||||
FwWbvdhbmrsFrfrgsN
|
|
||||||
rHjrQHdhdQrvSddcHWLssBSVVpBSWWWWWf
|
|
||||||
JNfTGtqDwVWBMBMpwM
|
|
||||||
qlltZgfJFvcRgcRjvc
|
|
||||||
CqfcwfDqwwmRnnqmRdNRBTRTRrdGdNpTvF
|
|
||||||
WVbzsZszBbrsvpdMpdQM
|
|
||||||
tJhbVZHWLLHDgnSwnSSgHB
|
|
||||||
TZCqqlTsqpZVVsZQJSBSLpLmppnJzmFz
|
|
||||||
brSgNtGjjRjRRjDddDtrRJcJJbJmmwcmBmnPcJFwFB
|
|
||||||
jgdRtMjNNjfqlMvShvSZSZ
|
|
||||||
dJTdqCwMNCgqTQllGBdlGBmmmZ
|
|
||||||
fcVfVcnbVfrwDLWVfncZBQPlBHRGljLZQjHGQl
|
|
||||||
brwnnfSFDvfzCTqFzgMJTh
|
|
||||||
njnsPBjjsrrnGLnbTTjGvcldQPCMllNzMvRQPCdd
|
|
||||||
ggZgfZtmZVpqZqZWDgFmgqfCcQRcRcWhQcccQddMcvRQdQ
|
|
||||||
tfqgggVgHpDwDtfwbGLJRjbLjsrLTj
|
|
||||||
JmrfrmTlDWTfgQCdHCdpqBvQdD
|
|
||||||
jsZtVzNsSNVQQHnBlVQR
|
|
||||||
PljljFjPljSsLPtFLTTgTcFrrfMJmrrmrr
|
|
||||||
hmGcmmndhmGnfmtGnDzFLwrFJQsQFzNFrNJG
|
|
||||||
ZSqPlSWcWlbgqWVTVWRVZPrjQqjzjFNJzLsNJsLJNqNL
|
|
||||||
RHcWTZbSMMMPgZcWgSWPPbVMDnBffmtdpDBddfnnvmCdfC
|
|
||||||
vSJvsbFfJfvqCsTHJswssJnLTZjjhzrrzLrzLMrzhdjM
|
|
||||||
pBNQDPcpmWDcBNgMMnZPVjdddnndhH
|
|
||||||
QWlDgmpmgDBlGRgDDgffSqwSwGCwHfvqwSFJ
|
|
||||||
jvlgvMJclPdGdtdcjMVmMHbFHFVHWHbZHZ
|
|
||||||
CwhLzLhzQpnqfpfqDVHCHbsbDFZDmHmj
|
|
||||||
LnBzfQjSzQrPvJvdSSrr
|
|
||||||
wpcvcsqclDCnVCVvWfnZ
|
|
||||||
BLRMRtbnbbBLNCjNCjVVZhbC
|
|
||||||
rFgMPSRnrRpmqpJwqFDs
|
|
||||||
LZQNQbMrZppLNLQplvlGLNvVmmmfjbwVCfjbwJwCmBCwfj
|
|
||||||
ShTPRFtTHZPCsnwswsFwCF
|
|
||||||
WtHRPdThSqZTRtDqtdRWTdpGDLLzrNczvzMGLlQLGDDM
|
|
||||||
hdcffBvldjhCMljqPwWwWNwWdwqHZr
|
|
||||||
LtQmbQRVsZQZMZPQSN
|
|
||||||
tmMRsJMpDhjJzJhv
|
|
||||||
wNQCMFCDQDBmrHmmRWrrHN
|
|
||||||
SShLnfqpcqpSZSfrzJvRVrvfrrJH
|
|
||||||
cRpqdGclpScltTQQtsFQMQsTCT
|
|
||||||
NCjggZmgfBgnBmgWbcwcTFctcWWfvb
|
|
||||||
HsDGthRGrtppSQpbFFJTVcJdFbTRvd
|
|
||||||
rPDGhDDrSzZLtzBLZMCB
|
|
||||||
RsBBMBsCBlFFCgRsBJzlMjMPNSdPhSrSrzLbmSDrDNmDSd
|
|
||||||
pZHZZJpGHHHpTTHvTncZqVLdqLbhLrDLdhrSLLbLDDdD
|
|
||||||
tGtwnJccvCtCffMBgt
|
|
||||||
wbddvVjfwPhbjjbDbbvbjvTNCNmfHZfpCZRJNzCmJmnJNC
|
|
||||||
BslcLtclZWsZJWNrRRNRpRmR
|
|
||||||
BSLBlScGtFMcssMBBFGLlQZTDZQjPddVwwbTdvvdhTZb
|
|
||||||
NSZHzmLZBnzHmLLzLSntDttDDtddhDtttDWW
|
|
||||||
QgfjsrrvNNJwtMddcvcvtq
|
|
||||||
jrfgfQpQrTTVLSNBClFV
|
|
||||||
GQWcWWPPQRcrJQNDdRcDmmLCFSnqNSmqhCNvFnql
|
|
||||||
zHfwjzpMjwZmCLqvvnlljC
|
|
||||||
ZgtVZBtHHZtgQGgPrbPRJdPv
|
|
||||||
TWdWpJTJTdgLWfWLlLFLrfrgBGsNqhGslBGHqSNqqBNshnws
|
|
||||||
ZpQmjzbZZCjZCCCPZtttRCCwsBnHNssBHbShsshHqsGBqN
|
|
||||||
RDRRPpPCzmZCtRpVVJFrfTfWFLLJggJrDv
|
|
||||||
pDDFlglsvFMgntlTMMqNffmTdfddRM
|
|
||||||
jhGJLVCHQpHGQCCzLjWdTTdZZdNdcRWNccWfNN
|
|
||||||
jQjSGjrjCQLhzVSLSCSHGDpngbrnDFtFBwBglBnBvg
|
|
||||||
wsLzstsgszcpcGLHGpcgcghlDBvQvjQvbFbQCbJBtCCJJv
|
|
||||||
mnSqRSSqSRThWRnmWWRSJDFTFCFCblbBCFQFCjFj
|
|
||||||
rZRRWqSSdZZfMVnZLspPsMgHpzMhHGPg
|
|
||||||
mwHrCLSWWwrsHCHDDsVrsmhfFZFnSSBlFlgZbbgBglbggj
|
|
||||||
GJdpcRtGJvNRdcPtdpJJdbQZfjfQBlnQBjnBtbfFnB
|
|
||||||
qcPpqqzFzJqvPVCCmWrVwhrWrz
|
|
||||||
jjMbvbhDvnRjNRGMmjbMZftSSwwwthJSffStctcwqd
|
|
||||||
lTQrVlpCVvCcfdcSJqLVcw
|
|
||||||
srHFWCHrFlrHlrsBsprljjRmDZZnmbDngNBgbNZv
|
|
||||||
MgTlQJlTQJZWpgLrRssrVqqqpRts
|
|
||||||
bBNbbzSSjMBPjzhMjsPtRVVRVPRqLttGGs
|
|
||||||
SjHBbfjNCDfjZgTlZdMJnDJW
|
|
||||||
lpThgTwtplhghgwhThqnnrdZctSZSjSZcRSRfbdrrc
|
|
||||||
RBVBGvmBmfdrcvrbbr
|
|
||||||
PmVGNGmmGRLLQwwLqTnglQ
|
|
||||||
nHwnBwBTnFHQwRsMhwghmzcm
|
|
||||||
GtprdCpdtqWdbqbrfdnPPszsWmRzRnShPszS
|
|
||||||
dGptbCfCrlnVDBJNLDLLVDLQ
|
|
||||||
CZtCjhTndCzqbCNq
|
|
||||||
dwpGvpsmwGslDszrNNrzqDMzWMgJ
|
|
||||||
vmcGccvpBVPTVTjTdTTTdZ
|
|
||||||
jWZhvZLjZfCZDwrDrSSzJGhVdJccscGsgV
|
|
||||||
blMBlRqqqgSJLBLcsJ
|
|
||||||
blmHLmFMMMnRqLmMMFqHmfPDfjQDnCDDQrZvfCjvDr
|
|
||||||
rnvnHrDLFZmMFLvrHQBMGQggBztzglplRl
|
|
||||||
sbWWhdNzsshsfhcsjJJPPbWdtQGVGllRTRjRRgBgQlpRlppB
|
|
||||||
PPCCwNWhPhNfWCzbqmFnDFFnCDLSrvZS
|
|
||||||
GChNjwWlWJWTJZBggvdgnQgdhdnd
|
|
||||||
HPsHfHHrpHDpFFrcSfsfpCMmQdntLBMgtmtBgDdLLC
|
|
||||||
SqpPscpPzpSWzjlCjjCGjl
|
|
||||||
nvgLvcLgvgvngbLprpJNTDCCRNVJrNPlDDTV
|
|
||||||
WZsMtsffGQtMzWFqFmWmWsVNJNlDwwCDVRTwJlCCDVLz
|
|
||||||
BQfGZGmmsMWFstWFmfMsfBccdncbpbSbvbbvHnLbpc
|
|
||||||
tsmDsvswNZmcZTccfh
|
|
||||||
zCTpGCbWBRWFWHGRFZJbMbJfnrhnhfMnnZ
|
|
||||||
TzFGFBRLdpHHNNQddDQDvwQN
|
|
||||||
fhBBpJgdHddjZQfmVmNzNNLmFN
|
|
||||||
qvMRrvlbwqlbTTMBMvLssFNmVzzwFDmLLzVD
|
|
||||||
TRSRWqRRMcBHhGHcdGgPGp
|
|
||||||
lSjHmtmnpHStblnpSlHSrtmMzLWzqzqCZDDTzTTWqMFqCqVV
|
|
||||||
sLRLLfPPRQfCTqqVVqFT
|
|
||||||
dNJgRPNQNsJJhBRvdJvQvNNsjSrrSmrcctpbpHtBrBjLjmSH
|
|
||||||
nwFwpppjfwSlpLTsqsTgNshhjM
|
|
||||||
ccBRGvtsmgGNPqNNGP
|
|
||||||
BCcJHvssdcWBCVmVHSSrZrwVzblpwbzZnf
|
|
||||||
rcfQRrBPPczjcRBctZDNlnVNHbgZGjVDjN
|
|
||||||
TvMsFJGSFMhJnNZlwVVnDNTZ
|
|
||||||
qhSqqmqLCLhFdJLqSvLhmQRQRWcRPczPtzrCrWGRBp
|
|
||||||
JVhdPhsFPFqLDBHVdHLPvhHDCMwcgJJwbwRgnnCMbwGwcmGC
|
|
||||||
fzjzpTZTQQQLwCbgGgbMmQcR
|
|
||||||
jzNpTzfSZtfNSWZlVVtdFFFDHHqLHVqv
|
|
||||||
TwSNnSnSGVTpNppGlPTlTcVqQrRhVBqdqBRqZqQZqQ
|
|
||||||
DcDCMfDbCMHJdrRBqbdjRBRZ
|
|
||||||
gvftMCJHcHfCDmDLgfMmMmmWlwWnWsTTwlGTlWTwppNlGL
|
|
||||||
pbGMbllDQPhhWWQDpPgVGlMCvRRrQLcCCcfBBQzLBcvQBv
|
|
||||||
wqnJjSmjrstdqwwFBLcRsBRRszzLFC
|
|
||||||
qwdddTJTdHtjndqJqHZHmwVWGpDbGTlbWWpWWrPGhhhM
|
|
||||||
WGllqLjjLCpSffmBmvfpHs
|
|
||||||
dnrQwZzRTdZwnCThdzzFTVmcBHBJBmsHfBPHcfvcSVHs
|
|
||||||
QgQrzCdrTRCZzrZLbjGLqNMWGgNNLt
|
|
||||||
sgPnhPPTTPTTwlJfwNHlqcfs
|
|
||||||
LMCpFbLLbRpMGbMcCFLVlNlNqrHqVfbHHwNDwr
|
|
||||||
GjBcCCtWMtMRZTSvgWQTngvg
|
|
||||||
BCMtJJMpRDlMMvBJBBnfjtcjPhPmZgnhgdcf
|
|
||||||
NrsrsqFNvrVLVGVrsHsqFgfmcPGdcmhfjdPgfjcnZd
|
|
||||||
zFTzsNqHqFssLVLQqNTFbsBDwCCwvWlDwRMRCTRBDMDS
|
|
||||||
zQtLgvggSRtgvVRtLvvnzdnjnGwGdmmrlpnlGz
|
|
||||||
JssBFpqsDqPNnlWWjrrjqrnj
|
|
||||||
DHDFBNDfPbJBsFHNMPvpvStQvMRVTtgVTVtv
|
|
||||||
FvzttFvBTJJzLbvwhCnnVnWwjCnBNC
|
|
||||||
mQdZgZPDPdPPSsMSQPdZgCwVGmnwnWpGnGhqNWjWCG
|
|
||||||
ggdDgfQSdcjtFHjlLJfF
|
|
||||||
ghcgScNNSsCvGSzmpVFlZbrzcFcV
|
|
||||||
MWWRLRqqqdQwTtLjjmqMlFpFlzVnbFVDwplFzlDr
|
|
||||||
LHMHqdHWjdQMdMtLHHLtWjJRsGCGSNghmSvPBJBNhsGfvfGP
|
|
||||||
CbVqqqDbcbMHnnDqcCbrRFCfBvvwGjzrBwQGzrwwBjGwBQ
|
|
||||||
sTPmpNWdWPTJssSSLPfNljjBvflGtjwwBzMG
|
|
||||||
mmWgmgSZLTLMZWpnhqZbhFFCnhqnnn
|
|
||||||
QQmjmZqnmQrfTZlbbcVbBcfbHfzf
|
|
||||||
vpdSNShNppFdSRtdGBqvJBDlDzqbPPHVBH
|
|
||||||
tRNSNRFhNpSRhFRMFtGhRGswLZZsZqWnmrmZwqwsTZmmmQ
|
|
||||||
gGWCllFCGWtGGWdlGlWNZdwpnnSbwpMvpphZpndn
|
|
||||||
RsshDDLcQVMSJQwJwnvw
|
|
||||||
HVPzrPcDNhPFGhPC
|
|
||||||
jtHQGHjGGtdTLjnqTQlmvRPRPBBwRBnFPPWP
|
|
||||||
hZbzNzVrczZzcbNssVspZZVvBwbmPmJPWmvbBRvPlmvRJF
|
|
||||||
fzNVDsZMhzpVhpVhlZcMNfcDDdQTLTjGDTCqGCjtSQHdHL
|
|
||||||
GrbFggGrTrzSrgfwJjdTmwmNJZJd
|
|
||||||
VMPQplPDptchwdsjmlml
|
|
||||||
MqMWtBDPPWDWHQtvqQtWPjbzCGLgSBgGbzgrzFgnnz
|
|
||||||
fcJccCcwcDfcpbRnCfWJnQJqtqtqPQdsGdgPsgTQqg
|
|
||||||
LSjVMhzSFFrljdNbltNGtgdqQq
|
|
||||||
MMhSHFFMLzBWDcHHcfcHwb
|
|
||||||
rwmWtJWMwSNRJMtwNmMrrSsmtTjjlgqnTqZZZPlHnTngTTgn
|
|
||||||
BGqGqqFBFggjjdGHlj
|
|
||||||
QDhhLbDQCDFMNcmhRhqJNW
|
|
||||||
BnRnRvMnLGLSCHvvSnlRfWbbTNQJsJsbNbJTBfQT
|
|
||||||
tzMmmMwjhcpFjDmMcptrcjzFQggfQPTsWsfgNbbgfhJbPhQT
|
|
||||||
FdzcrtDwDMtcwtFGRZdRLvdnHRSZZv
|
|
||||||
HVpsSpvjpNjsBmbGFBnMNnDM
|
|
||||||
WRRWhZtfrVtLJrBZMnDmDbnZBTGF
|
|
||||||
thhPLzWzhzwPtLRLWrQlpPvvClcVcCppSvpl
|
|
||||||
lZPbhnZLRPnnPZZPdlGMBWcBMgMQHBBcvvvzBL
|
|
||||||
jpFjmwwwCDDbsjvjjgcvQgcNBQ
|
|
||||||
rbFmppbwhqhGRGZr
|
|
||||||
ggrLwFgWCBwbMWBbFwLMgNBZdmZHclJPllnJlNRPmSNZRR
|
|
||||||
ppszzDfhDfhsqpnvDVTfGpSPlPmclHcdRcZmmmdPPGSP
|
|
||||||
pvtDDVDVpqDfzDfngBLCwQrgCtCwFwrg
|
|
||||||
pbGjFFGGDjpbsGsmNhNFNRBBBtRhhhHv
|
|
||||||
JnczJVCvwWJvhPgghgNtNtNJ
|
|
||||||
nwVSSzdzzqSpvQSZQG
|
|
||||||
mssLLttQrsMrMzLCRmMmrrSQpvWpDNlBTBDlvNTccDQl
|
|
||||||
HdHJwJqVPwHnqJwbjJbGjnSgSTWPpNgWWpgBBgcvDWWN
|
|
||||||
ZHVwVZGwwdndqJVJqfHbGwnwrRLtLMftMvMMRrhmLMthhLmz
|
|
||||||
RgHGLbTqlZlPRZPHfvvfZttJnvfvjnzr
|
|
||||||
sVcChDVDccwNhhvjTvVzWJjnzFff
|
|
||||||
mpNcCMTCGmLqBLGH
|
|
||||||
wVJwHJHVMtMpBmDDWPQVPWDGDD
|
|
||||||
zCrlZzCblBvnCDWNGLmvGDLPNG
|
|
||||||
dqZglgbzrzbbgZqzTFSBHHFJSSSfjjSMfwhj
|
|
||||||
NMWJSjLMCnHHNMNNHWCHMbVVGBPZTrPVPBVDrBSDGTTr
|
|
||||||
zvttlFpgdtldwwvftPDPTWQdBZrsrWrGBZ
|
|
||||||
hFlFmhRFvfCbmWJWHcnj
|
|
||||||
1000
2022/inputs/04.txt
1000
2022/inputs/04.txt
File diff suppressed because it is too large
Load Diff
@@ -1,514 +0,0 @@
|
|||||||
[G] [D] [Q]
|
|
||||||
[P] [T] [L] [M] [Z]
|
|
||||||
[Z] [Z] [C] [Z] [G] [W]
|
|
||||||
[M] [B] [F] [P] [C] [H] [N]
|
|
||||||
[T] [S] [R] [H] [W] [R] [L] [W]
|
|
||||||
[R] [T] [Q] [Z] [R] [S] [Z] [F] [P]
|
|
||||||
[C] [N] [H] [R] [N] [H] [D] [J] [Q]
|
|
||||||
[N] [D] [M] [G] [Z] [F] [W] [S] [S]
|
|
||||||
1 2 3 4 5 6 7 8 9
|
|
||||||
|
|
||||||
move 7 from 6 to 8
|
|
||||||
move 5 from 2 to 6
|
|
||||||
move 2 from 4 to 1
|
|
||||||
move 1 from 4 to 5
|
|
||||||
move 5 from 7 to 6
|
|
||||||
move 7 from 6 to 3
|
|
||||||
move 5 from 9 to 2
|
|
||||||
move 6 from 2 to 3
|
|
||||||
move 2 from 7 to 9
|
|
||||||
move 20 from 3 to 1
|
|
||||||
move 11 from 1 to 6
|
|
||||||
move 1 from 9 to 8
|
|
||||||
move 3 from 8 to 2
|
|
||||||
move 8 from 1 to 5
|
|
||||||
move 10 from 8 to 4
|
|
||||||
move 7 from 6 to 4
|
|
||||||
move 1 from 8 to 3
|
|
||||||
move 8 from 1 to 7
|
|
||||||
move 16 from 4 to 8
|
|
||||||
move 1 from 9 to 8
|
|
||||||
move 1 from 5 to 2
|
|
||||||
move 4 from 7 to 4
|
|
||||||
move 5 from 6 to 7
|
|
||||||
move 1 from 6 to 1
|
|
||||||
move 8 from 7 to 4
|
|
||||||
move 1 from 6 to 9
|
|
||||||
move 12 from 4 to 5
|
|
||||||
move 3 from 2 to 5
|
|
||||||
move 1 from 6 to 2
|
|
||||||
move 1 from 3 to 7
|
|
||||||
move 1 from 3 to 2
|
|
||||||
move 1 from 9 to 3
|
|
||||||
move 1 from 7 to 8
|
|
||||||
move 1 from 7 to 5
|
|
||||||
move 1 from 3 to 2
|
|
||||||
move 4 from 5 to 7
|
|
||||||
move 5 from 5 to 7
|
|
||||||
move 1 from 4 to 3
|
|
||||||
move 1 from 3 to 9
|
|
||||||
move 3 from 1 to 8
|
|
||||||
move 1 from 9 to 1
|
|
||||||
move 2 from 2 to 1
|
|
||||||
move 2 from 2 to 7
|
|
||||||
move 8 from 8 to 1
|
|
||||||
move 3 from 5 to 2
|
|
||||||
move 8 from 7 to 5
|
|
||||||
move 7 from 1 to 3
|
|
||||||
move 3 from 1 to 7
|
|
||||||
move 1 from 1 to 5
|
|
||||||
move 1 from 3 to 7
|
|
||||||
move 7 from 5 to 8
|
|
||||||
move 2 from 2 to 8
|
|
||||||
move 1 from 3 to 2
|
|
||||||
move 1 from 2 to 4
|
|
||||||
move 1 from 4 to 8
|
|
||||||
move 13 from 8 to 1
|
|
||||||
move 13 from 5 to 9
|
|
||||||
move 2 from 5 to 2
|
|
||||||
move 7 from 9 to 3
|
|
||||||
move 12 from 8 to 3
|
|
||||||
move 4 from 9 to 3
|
|
||||||
move 1 from 3 to 4
|
|
||||||
move 2 from 2 to 3
|
|
||||||
move 1 from 1 to 6
|
|
||||||
move 1 from 2 to 3
|
|
||||||
move 1 from 5 to 9
|
|
||||||
move 7 from 7 to 4
|
|
||||||
move 10 from 1 to 8
|
|
||||||
move 1 from 1 to 4
|
|
||||||
move 1 from 9 to 5
|
|
||||||
move 2 from 5 to 1
|
|
||||||
move 1 from 6 to 5
|
|
||||||
move 3 from 8 to 9
|
|
||||||
move 5 from 4 to 3
|
|
||||||
move 4 from 4 to 1
|
|
||||||
move 7 from 1 to 6
|
|
||||||
move 2 from 5 to 7
|
|
||||||
move 35 from 3 to 4
|
|
||||||
move 4 from 9 to 1
|
|
||||||
move 19 from 4 to 8
|
|
||||||
move 1 from 7 to 6
|
|
||||||
move 1 from 9 to 2
|
|
||||||
move 10 from 4 to 5
|
|
||||||
move 2 from 4 to 7
|
|
||||||
move 3 from 4 to 3
|
|
||||||
move 1 from 2 to 8
|
|
||||||
move 1 from 1 to 9
|
|
||||||
move 3 from 3 to 6
|
|
||||||
move 4 from 8 to 6
|
|
||||||
move 4 from 5 to 2
|
|
||||||
move 2 from 8 to 3
|
|
||||||
move 3 from 5 to 9
|
|
||||||
move 12 from 6 to 1
|
|
||||||
move 8 from 8 to 6
|
|
||||||
move 2 from 9 to 1
|
|
||||||
move 1 from 4 to 1
|
|
||||||
move 1 from 3 to 8
|
|
||||||
move 3 from 7 to 8
|
|
||||||
move 2 from 9 to 7
|
|
||||||
move 1 from 6 to 7
|
|
||||||
move 10 from 6 to 8
|
|
||||||
move 4 from 2 to 5
|
|
||||||
move 1 from 3 to 7
|
|
||||||
move 7 from 5 to 7
|
|
||||||
move 13 from 8 to 1
|
|
||||||
move 29 from 1 to 4
|
|
||||||
move 8 from 7 to 8
|
|
||||||
move 1 from 1 to 3
|
|
||||||
move 3 from 7 to 6
|
|
||||||
move 1 from 1 to 9
|
|
||||||
move 15 from 4 to 1
|
|
||||||
move 1 from 3 to 6
|
|
||||||
move 10 from 1 to 6
|
|
||||||
move 10 from 6 to 7
|
|
||||||
move 1 from 4 to 9
|
|
||||||
move 1 from 9 to 1
|
|
||||||
move 1 from 9 to 7
|
|
||||||
move 6 from 7 to 8
|
|
||||||
move 1 from 1 to 6
|
|
||||||
move 5 from 6 to 5
|
|
||||||
move 21 from 8 to 9
|
|
||||||
move 5 from 1 to 9
|
|
||||||
move 2 from 9 to 5
|
|
||||||
move 3 from 5 to 6
|
|
||||||
move 3 from 7 to 9
|
|
||||||
move 4 from 4 to 6
|
|
||||||
move 6 from 8 to 7
|
|
||||||
move 6 from 6 to 3
|
|
||||||
move 2 from 7 to 9
|
|
||||||
move 1 from 7 to 2
|
|
||||||
move 6 from 3 to 2
|
|
||||||
move 1 from 6 to 4
|
|
||||||
move 4 from 5 to 9
|
|
||||||
move 1 from 4 to 5
|
|
||||||
move 9 from 4 to 6
|
|
||||||
move 7 from 6 to 4
|
|
||||||
move 10 from 9 to 2
|
|
||||||
move 5 from 7 to 5
|
|
||||||
move 10 from 2 to 7
|
|
||||||
move 2 from 5 to 4
|
|
||||||
move 2 from 5 to 9
|
|
||||||
move 4 from 9 to 4
|
|
||||||
move 1 from 8 to 6
|
|
||||||
move 7 from 7 to 2
|
|
||||||
move 1 from 5 to 4
|
|
||||||
move 2 from 7 to 1
|
|
||||||
move 1 from 5 to 7
|
|
||||||
move 3 from 6 to 2
|
|
||||||
move 4 from 4 to 5
|
|
||||||
move 1 from 2 to 7
|
|
||||||
move 10 from 4 to 7
|
|
||||||
move 3 from 7 to 3
|
|
||||||
move 17 from 9 to 4
|
|
||||||
move 1 from 1 to 4
|
|
||||||
move 1 from 1 to 5
|
|
||||||
move 5 from 2 to 7
|
|
||||||
move 1 from 9 to 2
|
|
||||||
move 5 from 4 to 8
|
|
||||||
move 2 from 9 to 7
|
|
||||||
move 4 from 8 to 1
|
|
||||||
move 3 from 4 to 8
|
|
||||||
move 1 from 2 to 5
|
|
||||||
move 1 from 9 to 2
|
|
||||||
move 6 from 4 to 8
|
|
||||||
move 3 from 7 to 5
|
|
||||||
move 1 from 4 to 9
|
|
||||||
move 1 from 9 to 1
|
|
||||||
move 3 from 1 to 9
|
|
||||||
move 4 from 8 to 5
|
|
||||||
move 2 from 9 to 8
|
|
||||||
move 4 from 2 to 5
|
|
||||||
move 8 from 7 to 2
|
|
||||||
move 5 from 8 to 5
|
|
||||||
move 2 from 7 to 8
|
|
||||||
move 1 from 3 to 5
|
|
||||||
move 1 from 1 to 2
|
|
||||||
move 1 from 1 to 6
|
|
||||||
move 2 from 3 to 6
|
|
||||||
move 5 from 2 to 8
|
|
||||||
move 4 from 7 to 1
|
|
||||||
move 7 from 8 to 5
|
|
||||||
move 1 from 1 to 5
|
|
||||||
move 3 from 8 to 3
|
|
||||||
move 1 from 9 to 3
|
|
||||||
move 7 from 2 to 3
|
|
||||||
move 2 from 2 to 8
|
|
||||||
move 2 from 4 to 8
|
|
||||||
move 1 from 8 to 5
|
|
||||||
move 1 from 1 to 4
|
|
||||||
move 2 from 4 to 7
|
|
||||||
move 2 from 7 to 1
|
|
||||||
move 3 from 2 to 3
|
|
||||||
move 3 from 5 to 2
|
|
||||||
move 1 from 8 to 3
|
|
||||||
move 3 from 3 to 2
|
|
||||||
move 5 from 2 to 1
|
|
||||||
move 17 from 5 to 8
|
|
||||||
move 9 from 8 to 1
|
|
||||||
move 11 from 3 to 5
|
|
||||||
move 8 from 8 to 5
|
|
||||||
move 2 from 8 to 5
|
|
||||||
move 16 from 1 to 4
|
|
||||||
move 13 from 4 to 7
|
|
||||||
move 6 from 5 to 2
|
|
||||||
move 2 from 4 to 8
|
|
||||||
move 5 from 7 to 9
|
|
||||||
move 2 from 1 to 2
|
|
||||||
move 7 from 7 to 1
|
|
||||||
move 1 from 1 to 4
|
|
||||||
move 1 from 9 to 8
|
|
||||||
move 7 from 2 to 8
|
|
||||||
move 1 from 4 to 7
|
|
||||||
move 2 from 9 to 4
|
|
||||||
move 1 from 4 to 1
|
|
||||||
move 1 from 3 to 5
|
|
||||||
move 2 from 9 to 8
|
|
||||||
move 11 from 8 to 7
|
|
||||||
move 2 from 6 to 5
|
|
||||||
move 1 from 6 to 9
|
|
||||||
move 1 from 1 to 9
|
|
||||||
move 1 from 9 to 1
|
|
||||||
move 4 from 1 to 4
|
|
||||||
move 2 from 1 to 8
|
|
||||||
move 1 from 1 to 2
|
|
||||||
move 1 from 9 to 5
|
|
||||||
move 2 from 4 to 3
|
|
||||||
move 2 from 2 to 7
|
|
||||||
move 2 from 3 to 9
|
|
||||||
move 1 from 9 to 1
|
|
||||||
move 1 from 9 to 1
|
|
||||||
move 5 from 5 to 1
|
|
||||||
move 19 from 5 to 6
|
|
||||||
move 5 from 1 to 4
|
|
||||||
move 1 from 2 to 9
|
|
||||||
move 1 from 1 to 3
|
|
||||||
move 7 from 5 to 8
|
|
||||||
move 1 from 3 to 6
|
|
||||||
move 8 from 7 to 3
|
|
||||||
move 7 from 4 to 8
|
|
||||||
move 3 from 8 to 5
|
|
||||||
move 1 from 4 to 1
|
|
||||||
move 1 from 9 to 4
|
|
||||||
move 1 from 4 to 9
|
|
||||||
move 1 from 5 to 2
|
|
||||||
move 2 from 5 to 6
|
|
||||||
move 2 from 8 to 2
|
|
||||||
move 7 from 8 to 1
|
|
||||||
move 1 from 1 to 7
|
|
||||||
move 3 from 6 to 9
|
|
||||||
move 2 from 3 to 2
|
|
||||||
move 1 from 2 to 1
|
|
||||||
move 1 from 8 to 7
|
|
||||||
move 2 from 9 to 6
|
|
||||||
move 2 from 9 to 5
|
|
||||||
move 1 from 5 to 6
|
|
||||||
move 1 from 2 to 8
|
|
||||||
move 2 from 1 to 7
|
|
||||||
move 1 from 4 to 3
|
|
||||||
move 3 from 2 to 5
|
|
||||||
move 7 from 1 to 3
|
|
||||||
move 10 from 3 to 4
|
|
||||||
move 3 from 5 to 4
|
|
||||||
move 1 from 3 to 8
|
|
||||||
move 3 from 3 to 2
|
|
||||||
move 1 from 8 to 1
|
|
||||||
move 1 from 1 to 3
|
|
||||||
move 3 from 8 to 3
|
|
||||||
move 5 from 4 to 6
|
|
||||||
move 1 from 2 to 3
|
|
||||||
move 4 from 6 to 4
|
|
||||||
move 1 from 5 to 7
|
|
||||||
move 4 from 3 to 4
|
|
||||||
move 1 from 2 to 8
|
|
||||||
move 12 from 7 to 6
|
|
||||||
move 1 from 8 to 2
|
|
||||||
move 2 from 2 to 7
|
|
||||||
move 1 from 8 to 4
|
|
||||||
move 23 from 6 to 3
|
|
||||||
move 14 from 3 to 6
|
|
||||||
move 15 from 4 to 6
|
|
||||||
move 1 from 8 to 6
|
|
||||||
move 10 from 3 to 7
|
|
||||||
move 2 from 4 to 2
|
|
||||||
move 11 from 7 to 8
|
|
||||||
move 2 from 2 to 6
|
|
||||||
move 44 from 6 to 9
|
|
||||||
move 21 from 9 to 3
|
|
||||||
move 12 from 3 to 6
|
|
||||||
move 1 from 7 to 4
|
|
||||||
move 1 from 4 to 7
|
|
||||||
move 9 from 3 to 2
|
|
||||||
move 2 from 8 to 6
|
|
||||||
move 3 from 2 to 4
|
|
||||||
move 17 from 9 to 1
|
|
||||||
move 3 from 4 to 6
|
|
||||||
move 2 from 2 to 9
|
|
||||||
move 4 from 9 to 2
|
|
||||||
move 10 from 6 to 9
|
|
||||||
move 1 from 7 to 6
|
|
||||||
move 4 from 9 to 5
|
|
||||||
move 4 from 2 to 4
|
|
||||||
move 14 from 1 to 5
|
|
||||||
move 4 from 4 to 3
|
|
||||||
move 3 from 2 to 9
|
|
||||||
move 9 from 9 to 7
|
|
||||||
move 1 from 2 to 5
|
|
||||||
move 9 from 8 to 5
|
|
||||||
move 8 from 7 to 2
|
|
||||||
move 4 from 3 to 8
|
|
||||||
move 5 from 6 to 2
|
|
||||||
move 3 from 1 to 6
|
|
||||||
move 1 from 7 to 1
|
|
||||||
move 4 from 2 to 4
|
|
||||||
move 3 from 6 to 4
|
|
||||||
move 3 from 8 to 3
|
|
||||||
move 13 from 5 to 2
|
|
||||||
move 2 from 3 to 5
|
|
||||||
move 12 from 5 to 9
|
|
||||||
move 1 from 3 to 5
|
|
||||||
move 1 from 5 to 9
|
|
||||||
move 1 from 8 to 3
|
|
||||||
move 4 from 9 to 5
|
|
||||||
move 6 from 4 to 5
|
|
||||||
move 12 from 9 to 7
|
|
||||||
move 1 from 9 to 3
|
|
||||||
move 1 from 3 to 2
|
|
||||||
move 12 from 5 to 6
|
|
||||||
move 12 from 7 to 2
|
|
||||||
move 1 from 3 to 7
|
|
||||||
move 1 from 4 to 8
|
|
||||||
move 33 from 2 to 8
|
|
||||||
move 1 from 7 to 5
|
|
||||||
move 1 from 1 to 2
|
|
||||||
move 4 from 5 to 4
|
|
||||||
move 3 from 2 to 5
|
|
||||||
move 34 from 8 to 6
|
|
||||||
move 1 from 4 to 3
|
|
||||||
move 1 from 5 to 7
|
|
||||||
move 1 from 7 to 5
|
|
||||||
move 3 from 4 to 9
|
|
||||||
move 2 from 9 to 7
|
|
||||||
move 1 from 9 to 4
|
|
||||||
move 1 from 3 to 7
|
|
||||||
move 1 from 5 to 8
|
|
||||||
move 1 from 5 to 1
|
|
||||||
move 1 from 5 to 7
|
|
||||||
move 1 from 4 to 8
|
|
||||||
move 1 from 1 to 4
|
|
||||||
move 1 from 4 to 2
|
|
||||||
move 3 from 7 to 5
|
|
||||||
move 2 from 8 to 5
|
|
||||||
move 1 from 2 to 8
|
|
||||||
move 4 from 6 to 2
|
|
||||||
move 1 from 8 to 6
|
|
||||||
move 1 from 7 to 9
|
|
||||||
move 29 from 6 to 7
|
|
||||||
move 4 from 2 to 3
|
|
||||||
move 2 from 5 to 8
|
|
||||||
move 1 from 9 to 5
|
|
||||||
move 2 from 8 to 1
|
|
||||||
move 23 from 7 to 5
|
|
||||||
move 2 from 6 to 1
|
|
||||||
move 23 from 5 to 6
|
|
||||||
move 1 from 3 to 6
|
|
||||||
move 4 from 5 to 9
|
|
||||||
move 2 from 1 to 3
|
|
||||||
move 5 from 3 to 8
|
|
||||||
move 2 from 6 to 5
|
|
||||||
move 2 from 1 to 4
|
|
||||||
move 1 from 9 to 8
|
|
||||||
move 1 from 9 to 1
|
|
||||||
move 1 from 4 to 6
|
|
||||||
move 2 from 5 to 6
|
|
||||||
move 6 from 7 to 8
|
|
||||||
move 2 from 9 to 2
|
|
||||||
move 18 from 6 to 5
|
|
||||||
move 21 from 6 to 4
|
|
||||||
move 1 from 1 to 6
|
|
||||||
move 2 from 6 to 7
|
|
||||||
move 2 from 7 to 9
|
|
||||||
move 2 from 2 to 8
|
|
||||||
move 7 from 4 to 3
|
|
||||||
move 12 from 5 to 3
|
|
||||||
move 1 from 9 to 5
|
|
||||||
move 1 from 9 to 4
|
|
||||||
move 6 from 5 to 2
|
|
||||||
move 17 from 3 to 4
|
|
||||||
move 3 from 4 to 3
|
|
||||||
move 1 from 2 to 4
|
|
||||||
move 5 from 2 to 8
|
|
||||||
move 1 from 5 to 8
|
|
||||||
move 19 from 8 to 7
|
|
||||||
move 1 from 3 to 6
|
|
||||||
move 1 from 8 to 4
|
|
||||||
move 1 from 6 to 1
|
|
||||||
move 15 from 4 to 6
|
|
||||||
move 1 from 1 to 4
|
|
||||||
move 3 from 3 to 5
|
|
||||||
move 4 from 6 to 7
|
|
||||||
move 1 from 4 to 7
|
|
||||||
move 10 from 6 to 7
|
|
||||||
move 16 from 4 to 5
|
|
||||||
move 24 from 7 to 2
|
|
||||||
move 8 from 7 to 8
|
|
||||||
move 1 from 4 to 2
|
|
||||||
move 6 from 8 to 7
|
|
||||||
move 1 from 8 to 7
|
|
||||||
move 1 from 6 to 9
|
|
||||||
move 14 from 5 to 4
|
|
||||||
move 9 from 7 to 8
|
|
||||||
move 4 from 5 to 1
|
|
||||||
move 2 from 1 to 5
|
|
||||||
move 3 from 8 to 6
|
|
||||||
move 2 from 6 to 9
|
|
||||||
move 2 from 2 to 8
|
|
||||||
move 6 from 2 to 7
|
|
||||||
move 3 from 4 to 6
|
|
||||||
move 1 from 3 to 4
|
|
||||||
move 3 from 5 to 7
|
|
||||||
move 1 from 6 to 9
|
|
||||||
move 5 from 7 to 2
|
|
||||||
move 4 from 9 to 1
|
|
||||||
move 1 from 7 to 9
|
|
||||||
move 9 from 8 to 4
|
|
||||||
move 5 from 1 to 2
|
|
||||||
move 2 from 6 to 1
|
|
||||||
move 6 from 4 to 7
|
|
||||||
move 1 from 7 to 3
|
|
||||||
move 1 from 3 to 9
|
|
||||||
move 1 from 9 to 7
|
|
||||||
move 1 from 6 to 7
|
|
||||||
move 9 from 4 to 5
|
|
||||||
move 7 from 7 to 9
|
|
||||||
move 3 from 7 to 5
|
|
||||||
move 1 from 9 to 2
|
|
||||||
move 6 from 9 to 8
|
|
||||||
move 4 from 4 to 5
|
|
||||||
move 1 from 4 to 2
|
|
||||||
move 1 from 4 to 2
|
|
||||||
move 2 from 1 to 2
|
|
||||||
move 1 from 9 to 8
|
|
||||||
move 10 from 2 to 4
|
|
||||||
move 8 from 2 to 7
|
|
||||||
move 12 from 2 to 9
|
|
||||||
move 6 from 7 to 4
|
|
||||||
move 1 from 1 to 2
|
|
||||||
move 8 from 9 to 8
|
|
||||||
move 7 from 5 to 1
|
|
||||||
move 9 from 4 to 3
|
|
||||||
move 14 from 8 to 4
|
|
||||||
move 1 from 8 to 4
|
|
||||||
move 1 from 1 to 5
|
|
||||||
move 1 from 5 to 2
|
|
||||||
move 3 from 2 to 4
|
|
||||||
move 1 from 7 to 1
|
|
||||||
move 1 from 7 to 3
|
|
||||||
move 2 from 1 to 7
|
|
||||||
move 3 from 5 to 7
|
|
||||||
move 2 from 7 to 6
|
|
||||||
move 1 from 6 to 5
|
|
||||||
move 3 from 7 to 1
|
|
||||||
move 1 from 6 to 8
|
|
||||||
move 1 from 8 to 7
|
|
||||||
move 1 from 3 to 6
|
|
||||||
move 1 from 7 to 1
|
|
||||||
move 4 from 1 to 4
|
|
||||||
move 6 from 3 to 2
|
|
||||||
move 3 from 1 to 2
|
|
||||||
move 3 from 3 to 6
|
|
||||||
move 3 from 2 to 6
|
|
||||||
move 6 from 6 to 5
|
|
||||||
move 1 from 1 to 4
|
|
||||||
move 1 from 9 to 6
|
|
||||||
move 5 from 2 to 1
|
|
||||||
move 3 from 1 to 2
|
|
||||||
move 2 from 9 to 8
|
|
||||||
move 3 from 1 to 5
|
|
||||||
move 1 from 9 to 7
|
|
||||||
move 25 from 4 to 1
|
|
||||||
move 1 from 1 to 7
|
|
||||||
move 2 from 8 to 3
|
|
||||||
move 13 from 1 to 9
|
|
||||||
move 2 from 3 to 5
|
|
||||||
move 8 from 5 to 9
|
|
||||||
move 4 from 2 to 1
|
|
||||||
move 2 from 6 to 7
|
|
||||||
move 10 from 5 to 9
|
|
||||||
move 4 from 7 to 2
|
|
||||||
move 2 from 2 to 3
|
|
||||||
move 9 from 9 to 2
|
|
||||||
move 4 from 4 to 5
|
|
||||||
move 4 from 5 to 4
|
|
||||||
move 5 from 1 to 4
|
|
||||||
move 10 from 4 to 5
|
|
||||||
move 22 from 9 to 1
|
|
||||||
move 2 from 2 to 7
|
|
||||||
move 3 from 2 to 1
|
|
||||||
move 6 from 2 to 6
|
|
||||||
move 1 from 7 to 1
|
|
||||||
move 10 from 5 to 7
|
|
||||||
move 15 from 1 to 4
|
|
||||||
move 13 from 1 to 5
|
|
||||||
move 3 from 6 to 8
|
|
||||||
move 1 from 8 to 9
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
grvrnvrnnjljbjqjpqjjvhhzwwrbwwbblrltrrpbbbbqnnqbbbbsvbvmbvmbbrsrqrzrllwbbbqzqrqnqrnrjnnjccdggwqqhrrjcjmjmllgrlglhlclmlvlvsshwwsggmfmdfddgdfftrrczrcczhzppgdgrdggghmmdwwqgggslglfgfcgccmjcjwjrwjrjcrjjsgjjvddpwpgpbbgwbgwwhnhfftbffhpfphhfqfrqfrfnfpprvrsrhrfrllfhhrsrhssvfsvsnvsnsswtwtlthllrjjwddtggzczgcchwcwppfbbdvdrdzrdrvrwwsbsfbssqfsfjsjcscttlztllgjjlbbdsdtssvvvwlvlqqnhqqtdqtddjcdcjjpbphhgtgtqtzqqzhqqtgtvtmvtvrvqrvvfmfmppzzbwwnddzttfpfrrlddbppfqppnwnswwdhwdwjjqljqqthtnhnddgmgcmgcmgcmmfmfttrzzfdzztllmjlllgcgbbcqcvccpnndbdjbjmmzbztzptzpprpddptpprhhvlvmlmpmmljjnnjsjfjjvgjjvzzfgfzfbftbftttgstgstgtpggflfcfqqtctltgltldlzdlzzmmlddnvddzfddppmnpptzptpvttwstwswvwrvvbfbjjjbmjjdvdvrvdddrwrhrzrqqhghhrwhwhrrmppsgpsgszzdfdfwwmtwtvwvgvffmqqqtqntqnnjcncbnbwnnzggrdrqqjbqjjwjqqqwlqwlwzlljhhfsfsqsrqqhwqqwbbqbvvlflrrlglbbjhhjmhjjcmcjcgczcfcgcqqczcnnvjnnlddmpmcppgvgjgddvrrnsnmnqmqgmmnppwgwcgwgssbddgtdgdgmdgmgvvmjmvmjmvvsfssdgdghdggbfbqbdbjbsbmmrpmrprggbllwrwpwtppzvppzsssdnsdnnvnhvvvzvfzfqqnnmlnltldtdvdbdblddsmmlccmlmvlmvmmcsctctrtsrstsbsrshsddlmddmppgsscttnrtrqqcvcwwlnlznnnvcnvvtnvnbnmbmvmppjgjdjtddmpdmdvvmgvvdqdlqlhhzccsggjdjsdsttctjctjtfjttppdzpzzbjbwwmwbblslzslzszlzrrcbrrfggvcczjjtbbdnnggbwblwlbwlwqqfvfqfddrrfccvlllhmhhhrthrthrrnbnzbbpzplphprrrnbbghhnshnhbblqqqvwwffnmnmhhtccpqpvqvbvnvvfnfsnffdjdllwffcddgcgrgjrggchcpcddtbbdtdmtdmmhhtphtpppclcpcvcjvcjjfqfzqqphpnhnrnhhpdhhtfhhbbmqmfmsmvssgqqfssqgglnnqmnmbnmbbllrdrgdrdvrdvdsvvnddgtgddcdqdsqdqbqqlhhwdhdgdcgcdchchrchhpvvpgvgrrfggwfwgmpddbhfngtrwswfszgsggnpsntjpslrpjqsffzrlnbnzdtqpqtjzwlhhgrsrbvnccnsjmzcbqgcbtbqlzhnpnhhrrvqwjwzzvrlcrmjhcscrqhpqmfzbnvcwwqhcjjlnggmpbwztzfswmsbjshnsgfmdlzvzczhrdwgwbghszpnbfpctrshbfhspsczcqcrrqcpwwpfzhjqtpqgjbztrpzrlgfdjbmlwdvlvnfmdzbwsbbhlbszvwcpztlchjrqbmsftltmqpfgdpmdgjvwqqtjsqlfqrwmsnlqgsbqfwsdnfvzthmbplvszfcmlptlcjpnfpjsphsmmjplwjqphgvzbtbjtpttqhlwtgnrjvmvsfsztmsqszzlhqqhfslsvhzgtsssfctzgsqbgdzlpwbsmpcnjqshhhcwqdsdzdhnjfqzqnqdlrpddcgrgldgqbjmdtwgppdczzrjvmcfqjbpjzbtjmgdphlbwnsnpfdqlhwvvmpwzsrztnwvtlbphljmjwsgbphgmwhdmfhpvsmvsjccjhfvqtvfmmlnggncltvtrgmbtfqsvfnlvcmjnjwzcrpjnsgntvhjbtdlptshbhhchqmsprhqzdnfpjqccdfvnzjtlbsmmwvzlwlvmsbrnhqctvtvbfhntdctjnrbcrrlmsnwbbjbcbbgrrhfqwzwwfgvsvgbwnttghtgpspzwzfhffsqjvwwttntnvlwftsfvtttgnprzrzsghvjrdtsfdvzswhmrfcdqsgvrlhzbnvbmjlqrftnnbtwqtvlvwznfbslhdqjbntdgpprfqchjvgvzjssdztjlzwfljjmfvzrbbtczggzqwrnqqgzzcbqjcpfqfrbwtdjrrvbszsjdjcpdfjscsvnltcgwvqsgnhbfgnfnddnpmbzbptrmvqzpvbdpfdvtlmgnnjwflgdbfnmvsdnmlvgcpwflwvdbtbfwtfpsmqsplnzwlwgvbjrhghwrnrswsggbqpdjcjrgbgnsqdvwzzwftvjqgjzzcdvpbbjzpphmbcqmrjvgqwfgrsnqvhwflmhgrlvbpwdcsrlqwfrwppqbrdhwqtvczpclpsbsjcptgblbbsqmbhjjgzwvlcnhnzcttmpjsgchmppgphqlzlcsqcgbbjgtjjvmttdztfdptzgvmpnqrcmpmcdlpnbztllvqbggqbqhlqvdwsrwzsjwfrqvcbvsgfdptmrzpvdfblmhlzrvpmsljlqqzrhlnmwncpfhvqlsbtrjbfcrnfvjvddrhdbbczjdsrdvzlbqrccssdzcpmdsqbprjppfzdwfdswptgzcmjqfhcwsqfqhvrslffqfbcvhdzljzrmtwmfdwzdhhjcmbjtvjhzzwfqhrcslztdbnlwmmhbbbgdscjcdzftnchqfnflnsdqjscfrqpnfbftpzvtmrwncqfqqflschpfnjsjlqcjdjgtwpqhgcnjdmnnvmmpwdspmnrgqrptqwcvbtdwpqlbtwpqgwgfrzlrhtvrvzhmhmwhfdsrhpcczqfltsgtgrfwcvlcvtlhqqwnrqgzpnzbfmzbdwqwbsfvbshrgzqdbgvrhzhzlbqsfzttmsnmrqmwgtzbvdqdrbgcpclzjrhdbjtpcdbbznjgtbwbqrnpvffdmwtrbhhstcmnjcwbbnmpbvmjprtzgcptmtrffwhvfgdljnrbbrblbfbgdwtjrtgqgrpvpgjqrjzczvvlspgdbzftqgqvgdqlglbgvgjdcztznszcwfqhmwbrbjcfstzdcmdsssqfhtzpdgmzjscvbdzgbhhgdqgvfwrzmhdrhlsvlzjjzbzdljcbhncppwrtptjgszlqsrqpzqcsgvdvzmgvwgsncnbffttslphcstqvfwbwzbflmshcbnhpljgqwmmwwzlgpbcqnrtqlwcjcrclfdrnnmvtbfdztdfvtqrsgdptfcfpzpsldhzmrngggfvdqggtlfqqwsldprcffsstnnpmsbbvghdbpprqbssnprdbqclzqtgsrczwcvqwrrfmmfwsndvtvqljwwglrgbphdvvwgctbbmtrbpzqtspgrlhmnhjcdwhwvssgspzjbcfjttjqbdpdmptfzzjcfqljpqddfssmffqprvbptfvdshsdmfmdtmlbnmbmjjjsgmlmwmgcwhbrbgchrstptvdlqgddfzddlzhwjmsvvcjwvqtzjtsctfmzchlbrvlgdzbvdlbfpvhptpltrdmcgjghcpwvwqqnrzdtnmgdncplhdpsgpnbprbgshffwwsdhpgqsbmwdtpnhhltlcqfrjtswcchzvlhdgrmjwhgwppdjqlgmdhwbllqvzrchgclmqdlghjsvmwlflmhhmdzbfjhjnvwphnjbclmdpgflqgtfsmsjslntfcmtbphnrgpdcqtjzjttdtgjmvhzsrfnrjqssvwpcslpfstbpfsrsntmftmdgsqrrsnddqfmchrhtlhmqndvvllnvltdzfphjqnvmcdsgfpcmjftgdpntjzplqljhtthvnbzbzwvfnqsjvnfwhmtbsspjslgfjvdgfjpwrsgqwntntjcqtdgnhnsfwhhqfwbwhdrftj
|
|
||||||
@@ -1,983 +0,0 @@
|
|||||||
$ cd /
|
|
||||||
$ ls
|
|
||||||
dir gqcclj
|
|
||||||
dir lmtpm
|
|
||||||
dir nhqwt
|
|
||||||
dir qcq
|
|
||||||
dir vwqwlqrt
|
|
||||||
$ cd gqcclj
|
|
||||||
$ ls
|
|
||||||
62425 dqp.gjm
|
|
||||||
174181 hrtw.qsd
|
|
||||||
273712 pflp.mdw
|
|
||||||
169404 zlthnlhf.mtn
|
|
||||||
180878 zprprf
|
|
||||||
$ cd ..
|
|
||||||
$ cd lmtpm
|
|
||||||
$ ls
|
|
||||||
dir clffsvcw
|
|
||||||
163587 cvcl.jqh
|
|
||||||
dir dcqnblb
|
|
||||||
dir dtpwln
|
|
||||||
dir fvt
|
|
||||||
dir hrcrw
|
|
||||||
dir jdqzmqn
|
|
||||||
236754 nrdmlj
|
|
||||||
205959 pflp.mdw
|
|
||||||
dir qcq
|
|
||||||
dir rsn
|
|
||||||
129926 vdgcqdn.sqd
|
|
||||||
dir zprprf
|
|
||||||
$ cd clffsvcw
|
|
||||||
$ ls
|
|
||||||
6997 dcqnblb.wbh
|
|
||||||
145711 dqp
|
|
||||||
159225 pflp.mdw
|
|
||||||
$ cd ..
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
dir dcqnblb
|
|
||||||
dir gfn
|
|
||||||
dir lpswsp
|
|
||||||
dir lvt
|
|
||||||
dir zprprf
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
2020 grpdmd.ggz
|
|
||||||
dir zpswzfvg
|
|
||||||
$ cd zpswzfvg
|
|
||||||
$ ls
|
|
||||||
206998 zprprf.gnw
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd gfn
|
|
||||||
$ ls
|
|
||||||
277530 rhbvtblc.mvw
|
|
||||||
$ cd ..
|
|
||||||
$ cd lpswsp
|
|
||||||
$ ls
|
|
||||||
173180 dcqnblb
|
|
||||||
$ cd ..
|
|
||||||
$ cd lvt
|
|
||||||
$ ls
|
|
||||||
dir hjllwsvl
|
|
||||||
dir ptbt
|
|
||||||
$ cd hjllwsvl
|
|
||||||
$ ls
|
|
||||||
dir wqnc
|
|
||||||
$ cd wqnc
|
|
||||||
$ ls
|
|
||||||
64695 grpdmd.ggz
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ptbt
|
|
||||||
$ ls
|
|
||||||
150880 vvbt.gtp
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd zprprf
|
|
||||||
$ ls
|
|
||||||
dir ldzslndn
|
|
||||||
dir qftt
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
dir bwqqsbhg
|
|
||||||
129454 vbn
|
|
||||||
$ cd bwqqsbhg
|
|
||||||
$ ls
|
|
||||||
108701 zprprf.gss
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd qftt
|
|
||||||
$ ls
|
|
||||||
64268 cvcl.jqh
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dtpwln
|
|
||||||
$ ls
|
|
||||||
196215 cvcl.jqh
|
|
||||||
dir dpwg
|
|
||||||
dir ldzslndn
|
|
||||||
dir znnsqqh
|
|
||||||
$ cd dpwg
|
|
||||||
$ ls
|
|
||||||
192388 gmh
|
|
||||||
47754 grgzh.qdl
|
|
||||||
99449 hqsh
|
|
||||||
dir pbmf
|
|
||||||
50061 pflp.mdw
|
|
||||||
192902 qcq.pgg
|
|
||||||
dir rmpvj
|
|
||||||
dir scgc
|
|
||||||
$ cd pbmf
|
|
||||||
$ ls
|
|
||||||
210083 wpfnwbl.mgf
|
|
||||||
$ cd ..
|
|
||||||
$ cd rmpvj
|
|
||||||
$ ls
|
|
||||||
125738 nmlnbvrd
|
|
||||||
226214 zprprf.jnp
|
|
||||||
114257 zprprf.srs
|
|
||||||
$ cd ..
|
|
||||||
$ cd scgc
|
|
||||||
$ ls
|
|
||||||
182115 rrc.rcc
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
201992 qcrm.cpd
|
|
||||||
$ cd ..
|
|
||||||
$ cd znnsqqh
|
|
||||||
$ ls
|
|
||||||
85635 cvcl.jqh
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd fvt
|
|
||||||
$ ls
|
|
||||||
dir dcqnblb
|
|
||||||
dir gnc
|
|
||||||
75864 vfn
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
dir dcqnblb
|
|
||||||
dir lbnflwsh
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
269901 cvcl.jqh
|
|
||||||
$ cd ..
|
|
||||||
$ cd lbnflwsh
|
|
||||||
$ ls
|
|
||||||
33336 grpdmd.ggz
|
|
||||||
42861 phg.wmc
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd gnc
|
|
||||||
$ ls
|
|
||||||
dir jhjbjsp
|
|
||||||
dir jjppr
|
|
||||||
$ cd jhjbjsp
|
|
||||||
$ ls
|
|
||||||
96177 ldzslndn
|
|
||||||
$ cd ..
|
|
||||||
$ cd jjppr
|
|
||||||
$ ls
|
|
||||||
181016 dqp
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd hrcrw
|
|
||||||
$ ls
|
|
||||||
261376 dtjfpppr.dww
|
|
||||||
54658 vsrgvw.pfn
|
|
||||||
$ cd ..
|
|
||||||
$ cd jdqzmqn
|
|
||||||
$ ls
|
|
||||||
52342 dcpndc.vlg
|
|
||||||
171946 gggpchh.tbb
|
|
||||||
dir ldzslndn
|
|
||||||
11156 nbfrfvv.gzw
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
107873 cvcl.jqh
|
|
||||||
216034 gfdjrbz
|
|
||||||
68844 pqllfrrh.jcf
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
152886 ldzslndn.ltn
|
|
||||||
105125 vwplh.vbf
|
|
||||||
$ cd ..
|
|
||||||
$ cd rsn
|
|
||||||
$ ls
|
|
||||||
15385 hqcmjdgv.jjv
|
|
||||||
105735 qcq.bzg
|
|
||||||
58805 snczcsp
|
|
||||||
26668 vbn
|
|
||||||
$ cd ..
|
|
||||||
$ cd zprprf
|
|
||||||
$ ls
|
|
||||||
dir chbmq
|
|
||||||
dir dcqnblb
|
|
||||||
dir dqp
|
|
||||||
dir nfspb
|
|
||||||
89506 zprprf.hnt
|
|
||||||
$ cd chbmq
|
|
||||||
$ ls
|
|
||||||
dir cnjvw
|
|
||||||
dir dqp
|
|
||||||
151434 frsvrdnt
|
|
||||||
dir msztjvcb
|
|
||||||
240689 qcq.jlh
|
|
||||||
dir sjzrcg
|
|
||||||
97312 vnr.zfr
|
|
||||||
dir zprprf
|
|
||||||
$ cd cnjvw
|
|
||||||
$ ls
|
|
||||||
dir bpbs
|
|
||||||
252403 cqhtshc
|
|
||||||
dir djmjhn
|
|
||||||
10935 fhqmswr
|
|
||||||
6582 pdwml.ldd
|
|
||||||
dir qcq
|
|
||||||
219282 rfmd
|
|
||||||
$ cd bpbs
|
|
||||||
$ ls
|
|
||||||
147582 bnhwsnsj.gdm
|
|
||||||
61362 cvcl.jqh
|
|
||||||
152857 vdgcqdn.sqd
|
|
||||||
$ cd ..
|
|
||||||
$ cd djmjhn
|
|
||||||
$ ls
|
|
||||||
dir bjdbcjbb
|
|
||||||
dir dcqnblb
|
|
||||||
dir dqp
|
|
||||||
dir lgdwtt
|
|
||||||
$ cd bjdbcjbb
|
|
||||||
$ ls
|
|
||||||
110710 cvcl.jqh
|
|
||||||
252792 hmshctr.lgz
|
|
||||||
dir mjhtmbj
|
|
||||||
189745 shsswcgr
|
|
||||||
dir tfnhp
|
|
||||||
194940 vbn
|
|
||||||
dir zprprf
|
|
||||||
$ cd mjhtmbj
|
|
||||||
$ ls
|
|
||||||
dir dqp
|
|
||||||
dir hbthpcmb
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
200832 sbcrz.qgw
|
|
||||||
$ cd ..
|
|
||||||
$ cd hbthpcmb
|
|
||||||
$ ls
|
|
||||||
55191 ffcntg
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd tfnhp
|
|
||||||
$ ls
|
|
||||||
276825 dqp
|
|
||||||
161538 gqmr.wgb
|
|
||||||
$ cd ..
|
|
||||||
$ cd zprprf
|
|
||||||
$ ls
|
|
||||||
287638 dcqnblb.ssp
|
|
||||||
41274 hgmrvj.mwf
|
|
||||||
249118 sbb.gsf
|
|
||||||
105141 wwrg.gqz
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
1957 btmmc
|
|
||||||
32386 dtzbzg.dhm
|
|
||||||
dir mmrbj
|
|
||||||
98283 ntmhfgtl.pmf
|
|
||||||
dir zprprf
|
|
||||||
$ cd mmrbj
|
|
||||||
$ ls
|
|
||||||
273194 wnsq
|
|
||||||
251527 zprprf
|
|
||||||
$ cd ..
|
|
||||||
$ cd zprprf
|
|
||||||
$ ls
|
|
||||||
27678 ldzslndn.rrl
|
|
||||||
62866 ljf.fdj
|
|
||||||
148502 qcq.dlg
|
|
||||||
dir rvgqvm
|
|
||||||
179231 tllnmhn.pjp
|
|
||||||
64033 vbn
|
|
||||||
dir zcdrj
|
|
||||||
$ cd rvgqvm
|
|
||||||
$ ls
|
|
||||||
dir ntbv
|
|
||||||
262324 prhgj.szz
|
|
||||||
dir qbvdh
|
|
||||||
$ cd ntbv
|
|
||||||
$ ls
|
|
||||||
116608 cgv.fvj
|
|
||||||
175200 swpswq.twt
|
|
||||||
$ cd ..
|
|
||||||
$ cd qbvdh
|
|
||||||
$ ls
|
|
||||||
160353 sdhfrb.wjn
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd zcdrj
|
|
||||||
$ ls
|
|
||||||
283262 ctl
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
dir jfzm
|
|
||||||
111438 rdrgb.mjf
|
|
||||||
64194 wgtmqrq
|
|
||||||
dir zprprf
|
|
||||||
$ cd jfzm
|
|
||||||
$ ls
|
|
||||||
158774 pflp.mdw
|
|
||||||
$ cd ..
|
|
||||||
$ cd zprprf
|
|
||||||
$ ls
|
|
||||||
215264 sgsstcp
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd lgdwtt
|
|
||||||
$ ls
|
|
||||||
dir qcq
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
165461 ldzslndn.vvb
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
dir dpd
|
|
||||||
165044 grpdmd.ggz
|
|
||||||
82343 ldzslndn
|
|
||||||
dir mwg
|
|
||||||
176689 psjcwp.wct
|
|
||||||
44404 qcq.zwd
|
|
||||||
$ cd dpd
|
|
||||||
$ ls
|
|
||||||
84087 dqp
|
|
||||||
227386 zprprf.gfs
|
|
||||||
$ cd ..
|
|
||||||
$ cd mwg
|
|
||||||
$ ls
|
|
||||||
214086 pflp.mdw
|
|
||||||
dir sjjsdn
|
|
||||||
225859 wcdt
|
|
||||||
158892 zprprf.frs
|
|
||||||
$ cd sjjsdn
|
|
||||||
$ ls
|
|
||||||
260121 gplgp.dfn
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
dir hcrwclpg
|
|
||||||
dir zphd
|
|
||||||
$ cd hcrwclpg
|
|
||||||
$ ls
|
|
||||||
dir cmqntjj
|
|
||||||
16393 ldzslndn.qbm
|
|
||||||
91152 qqdtc.zdq
|
|
||||||
$ cd cmqntjj
|
|
||||||
$ ls
|
|
||||||
272266 ldzslndn.pll
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd zphd
|
|
||||||
$ ls
|
|
||||||
165711 chftwcsw.fqw
|
|
||||||
256871 cvcl.jqh
|
|
||||||
251168 zprprf.gfv
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd msztjvcb
|
|
||||||
$ ls
|
|
||||||
206231 brzn.lmn
|
|
||||||
dir dcqnblb
|
|
||||||
21571 dqp
|
|
||||||
dir fmn
|
|
||||||
45779 mlfctz.cjr
|
|
||||||
288827 pflp.mdw
|
|
||||||
220578 qcq.fqf
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
198121 ghbwgs
|
|
||||||
93681 nmqhl.vpq
|
|
||||||
$ cd ..
|
|
||||||
$ cd fmn
|
|
||||||
$ ls
|
|
||||||
29407 mdfws.qvs
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd sjzrcg
|
|
||||||
$ ls
|
|
||||||
155120 ddclvsjr.rpq
|
|
||||||
136029 ldzslndn.dcm
|
|
||||||
dir vhzh
|
|
||||||
$ cd vhzh
|
|
||||||
$ ls
|
|
||||||
212446 vbn
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd zprprf
|
|
||||||
$ ls
|
|
||||||
240335 crt.gqh
|
|
||||||
185363 gnmm.qgh
|
|
||||||
dir ldzslndn
|
|
||||||
dir nwl
|
|
||||||
dir qll
|
|
||||||
277043 vbn
|
|
||||||
217796 vtvgpdl.vtm
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
273570 cvcl.jqh
|
|
||||||
68510 fgdmz.hrc
|
|
||||||
dir npq
|
|
||||||
dir swjrzzrm
|
|
||||||
$ cd npq
|
|
||||||
$ ls
|
|
||||||
97923 dzcjsqwt
|
|
||||||
$ cd ..
|
|
||||||
$ cd swjrzzrm
|
|
||||||
$ ls
|
|
||||||
180599 tmpgn.bjf
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd nwl
|
|
||||||
$ ls
|
|
||||||
171833 dlwrfhh.qgn
|
|
||||||
$ cd ..
|
|
||||||
$ cd qll
|
|
||||||
$ ls
|
|
||||||
219926 dcqnblb.bvn
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
dir lvpb
|
|
||||||
276198 tbgcm.qct
|
|
||||||
$ cd lvpb
|
|
||||||
$ ls
|
|
||||||
142590 bvhjlld
|
|
||||||
268259 gnjfg.sgb
|
|
||||||
dir qcq
|
|
||||||
206220 qcq.zsg
|
|
||||||
258137 rrsw.dnb
|
|
||||||
dir tmr
|
|
||||||
215549 vbn
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
dir mmpgd
|
|
||||||
dir tdsz
|
|
||||||
dir tmfvsjwc
|
|
||||||
$ cd mmpgd
|
|
||||||
$ ls
|
|
||||||
70793 jwbnpwnn
|
|
||||||
$ cd ..
|
|
||||||
$ cd tdsz
|
|
||||||
$ ls
|
|
||||||
246310 tdvrhhg.bzq
|
|
||||||
$ cd ..
|
|
||||||
$ cd tmfvsjwc
|
|
||||||
$ ls
|
|
||||||
103899 grpdmd.ggz
|
|
||||||
287850 ldzslndn
|
|
||||||
125930 llhr
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd tmr
|
|
||||||
$ ls
|
|
||||||
83344 fbtfcg.hqp
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
dir lbgmcbv
|
|
||||||
dir nbg
|
|
||||||
$ cd lbgmcbv
|
|
||||||
$ ls
|
|
||||||
81776 wzdzzdp
|
|
||||||
$ cd ..
|
|
||||||
$ cd nbg
|
|
||||||
$ ls
|
|
||||||
dir mfsgjp
|
|
||||||
155574 pflp.mdw
|
|
||||||
$ cd mfsgjp
|
|
||||||
$ ls
|
|
||||||
199400 vdgcqdn.sqd
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd nfspb
|
|
||||||
$ ls
|
|
||||||
262412 csrdtbs
|
|
||||||
73867 vbn
|
|
||||||
136389 zqps.hjt
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd nhqwt
|
|
||||||
$ ls
|
|
||||||
123766 cvcl.jqh
|
|
||||||
dir dhrtvctp
|
|
||||||
222086 grpdmd.ggz
|
|
||||||
dir gzg
|
|
||||||
26005 lhpmz.tgz
|
|
||||||
dir mcnjwwfr
|
|
||||||
117122 msn.gst
|
|
||||||
$ cd dhrtvctp
|
|
||||||
$ ls
|
|
||||||
224079 vdgcqdn.sqd
|
|
||||||
$ cd ..
|
|
||||||
$ cd gzg
|
|
||||||
$ ls
|
|
||||||
124395 dqp
|
|
||||||
dir wqdbtqm
|
|
||||||
$ cd wqdbtqm
|
|
||||||
$ ls
|
|
||||||
237354 pflp.mdw
|
|
||||||
212019 vdgcqdn.sqd
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd mcnjwwfr
|
|
||||||
$ ls
|
|
||||||
92504 cshdztf
|
|
||||||
dir dctl
|
|
||||||
dir dqp
|
|
||||||
dir flcrmhlj
|
|
||||||
161879 grpdmd.ggz
|
|
||||||
dir gtt
|
|
||||||
dir hlbnhchz
|
|
||||||
220093 mdtdsgvm.zgg
|
|
||||||
dir twntr
|
|
||||||
287192 vbn
|
|
||||||
$ cd dctl
|
|
||||||
$ ls
|
|
||||||
dir bbhch
|
|
||||||
155396 hrrj.jzm
|
|
||||||
164971 pblqmwj.vdb
|
|
||||||
dir wnlgfpvf
|
|
||||||
$ cd bbhch
|
|
||||||
$ ls
|
|
||||||
dir dpqtp
|
|
||||||
dir jvdrcw
|
|
||||||
$ cd dpqtp
|
|
||||||
$ ls
|
|
||||||
174135 gwb.qrb
|
|
||||||
$ cd ..
|
|
||||||
$ cd jvdrcw
|
|
||||||
$ ls
|
|
||||||
215993 dcqnblb.cqp
|
|
||||||
200800 stjttf.ngc
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd wnlgfpvf
|
|
||||||
$ ls
|
|
||||||
135978 cvcl.jqh
|
|
||||||
dir dqp
|
|
||||||
54018 lbrfmt
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
270516 dcqnblb.jqw
|
|
||||||
dir dqp
|
|
||||||
144626 grpdmd.ggz
|
|
||||||
157731 hvcv.rhp
|
|
||||||
133773 lnnt
|
|
||||||
76250 vdgcqdn.sqd
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
41504 zprprf.cmc
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
dir dqp
|
|
||||||
dir ldzslndn
|
|
||||||
236737 mqzcvm.fjh
|
|
||||||
239746 nhcdz.ncj
|
|
||||||
dir rpchqq
|
|
||||||
248824 vdgcqdn.sqd
|
|
||||||
250937 zrchht.mwg
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
203381 qcq.djm
|
|
||||||
$ cd ..
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
dir dqp
|
|
||||||
dir fptnzlv
|
|
||||||
dir gmbnpm
|
|
||||||
dir vhvblt
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
19579 qcq.lhg
|
|
||||||
$ cd ..
|
|
||||||
$ cd fptnzlv
|
|
||||||
$ ls
|
|
||||||
209930 dcqnblb
|
|
||||||
$ cd ..
|
|
||||||
$ cd gmbnpm
|
|
||||||
$ ls
|
|
||||||
dir ldzslndn
|
|
||||||
dir qcq
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
11075 pflp.mdw
|
|
||||||
$ cd ..
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
dir tdp
|
|
||||||
$ cd tdp
|
|
||||||
$ ls
|
|
||||||
40741 vdgcqdn.sqd
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd vhvblt
|
|
||||||
$ ls
|
|
||||||
dir lzr
|
|
||||||
$ cd lzr
|
|
||||||
$ ls
|
|
||||||
62245 gbnj.llg
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd rpchqq
|
|
||||||
$ ls
|
|
||||||
dir bcs
|
|
||||||
dir dcqnblb
|
|
||||||
dir fvjzn
|
|
||||||
dir lrphzrv
|
|
||||||
$ cd bcs
|
|
||||||
$ ls
|
|
||||||
179794 bbn.dzb
|
|
||||||
242069 cmjdmzjf.zgf
|
|
||||||
1703 cvcl.jqh
|
|
||||||
dir gnmhwj
|
|
||||||
dir ldzslndn
|
|
||||||
152520 qltpsz.jsj
|
|
||||||
dir sqqjfps
|
|
||||||
$ cd gnmhwj
|
|
||||||
$ ls
|
|
||||||
dir gvs
|
|
||||||
201600 hptn.ftf
|
|
||||||
dir hzrnb
|
|
||||||
dir qcq
|
|
||||||
dir sqhl
|
|
||||||
$ cd gvs
|
|
||||||
$ ls
|
|
||||||
152358 zprprf.mlh
|
|
||||||
$ cd ..
|
|
||||||
$ cd hzrnb
|
|
||||||
$ ls
|
|
||||||
94290 gplsfd
|
|
||||||
$ cd ..
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
91909 vmqd.bmg
|
|
||||||
$ cd ..
|
|
||||||
$ cd sqhl
|
|
||||||
$ ls
|
|
||||||
238673 vdgcqdn.sqd
|
|
||||||
262885 zmdvr.nfg
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
240461 mdz
|
|
||||||
84303 qtj
|
|
||||||
$ cd ..
|
|
||||||
$ cd sqqjfps
|
|
||||||
$ ls
|
|
||||||
88753 fwn.tff
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
dir dqp
|
|
||||||
189996 dqp.pvp
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
dir qvfjz
|
|
||||||
196506 vbn
|
|
||||||
$ cd qvfjz
|
|
||||||
$ ls
|
|
||||||
209316 pflp.mdw
|
|
||||||
107459 rwpbh.vpt
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd fvjzn
|
|
||||||
$ ls
|
|
||||||
241464 cvcl.jqh
|
|
||||||
dir dqp
|
|
||||||
dir ldzslndn
|
|
||||||
dir msp
|
|
||||||
125 pflp.mdw
|
|
||||||
131895 vbn
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
34019 pflp.mdw
|
|
||||||
202957 vbn
|
|
||||||
$ cd ..
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
147492 cvcl.jqh
|
|
||||||
248719 spc.rfv
|
|
||||||
$ cd ..
|
|
||||||
$ cd msp
|
|
||||||
$ ls
|
|
||||||
184407 cvcl.jqh
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd lrphzrv
|
|
||||||
$ ls
|
|
||||||
dir bbwqmbg
|
|
||||||
81858 cvcl.jqh
|
|
||||||
dir dqp
|
|
||||||
248670 gqqsww.tsn
|
|
||||||
199141 grpdmd.ggz
|
|
||||||
dir ldzslndn
|
|
||||||
34514 ldzslndn.ctw
|
|
||||||
dir tln
|
|
||||||
214615 zprprf.fwm
|
|
||||||
$ cd bbwqmbg
|
|
||||||
$ ls
|
|
||||||
129750 flf
|
|
||||||
dir pvlw
|
|
||||||
dir qcq
|
|
||||||
126 sqcqphz.tbm
|
|
||||||
$ cd pvlw
|
|
||||||
$ ls
|
|
||||||
198005 jfvj.hdv
|
|
||||||
$ cd ..
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
dir wgdzws
|
|
||||||
$ cd wgdzws
|
|
||||||
$ ls
|
|
||||||
253522 ldzslndn.qwt
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
281993 cvcl.jqh
|
|
||||||
dir hwqjlwcb
|
|
||||||
50532 msccz.qgm
|
|
||||||
102187 trv.tnq
|
|
||||||
111 wplnmj.bfl
|
|
||||||
$ cd hwqjlwcb
|
|
||||||
$ ls
|
|
||||||
267580 dhjqb.dsb
|
|
||||||
153195 ldzslndn.jqv
|
|
||||||
41526 mvwcwc.zsc
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
58666 cvcl.jqh
|
|
||||||
79950 dqp.tmc
|
|
||||||
242217 hns.lrb
|
|
||||||
dir njswzh
|
|
||||||
240692 vdgcqdn.sqd
|
|
||||||
dir zvmjvcdm
|
|
||||||
52909 zzh
|
|
||||||
$ cd njswzh
|
|
||||||
$ ls
|
|
||||||
149732 cvcl.jqh
|
|
||||||
dir rnmfd
|
|
||||||
$ cd rnmfd
|
|
||||||
$ ls
|
|
||||||
75368 dqp.hmv
|
|
||||||
14350 vbn
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd zvmjvcdm
|
|
||||||
$ ls
|
|
||||||
dir jgczt
|
|
||||||
$ cd jgczt
|
|
||||||
$ ls
|
|
||||||
dir qcq
|
|
||||||
95941 qzvvwshv.jwc
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
273942 pflp.mdw
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd tln
|
|
||||||
$ ls
|
|
||||||
dir bmcng
|
|
||||||
1518 lrg
|
|
||||||
dir vnjfrhp
|
|
||||||
$ cd bmcng
|
|
||||||
$ ls
|
|
||||||
38917 fqcrt
|
|
||||||
$ cd ..
|
|
||||||
$ cd vnjfrhp
|
|
||||||
$ ls
|
|
||||||
dir dcqnblb
|
|
||||||
dir dqp
|
|
||||||
247186 grpdmd.ggz
|
|
||||||
dir ldzslndn
|
|
||||||
169216 pflp.mdw
|
|
||||||
206487 vdgcqdn.sqd
|
|
||||||
16976 vlsrzjmb.mmc
|
|
||||||
257938 wjl
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
dir dqp
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
184133 qcq
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd dqp
|
|
||||||
$ ls
|
|
||||||
dir dcqnblb
|
|
||||||
31612 dqp.pnt
|
|
||||||
212283 ldzslndn
|
|
||||||
61600 vdbfc.ddj
|
|
||||||
197189 wpv.wff
|
|
||||||
$ cd dcqnblb
|
|
||||||
$ ls
|
|
||||||
62412 tfzllmrj
|
|
||||||
dir zprprf
|
|
||||||
$ cd zprprf
|
|
||||||
$ ls
|
|
||||||
dir bqnpsl
|
|
||||||
dir dszrvpzc
|
|
||||||
$ cd bqnpsl
|
|
||||||
$ ls
|
|
||||||
261548 spbsbbsw.cmn
|
|
||||||
$ cd ..
|
|
||||||
$ cd dszrvpzc
|
|
||||||
$ ls
|
|
||||||
188232 sggpqslr.smn
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ldzslndn
|
|
||||||
$ ls
|
|
||||||
dir bgnhd
|
|
||||||
dir pgvcdzwz
|
|
||||||
dir qgzhm
|
|
||||||
$ cd bgnhd
|
|
||||||
$ ls
|
|
||||||
56989 cvcl.jqh
|
|
||||||
$ cd ..
|
|
||||||
$ cd pgvcdzwz
|
|
||||||
$ ls
|
|
||||||
110034 qhgnndv
|
|
||||||
$ cd ..
|
|
||||||
$ cd qgzhm
|
|
||||||
$ ls
|
|
||||||
247232 grpdmd.ggz
|
|
||||||
269292 ldzslndn
|
|
||||||
153843 tpz
|
|
||||||
dir vnschqwr
|
|
||||||
162392 wnq.btb
|
|
||||||
$ cd vnschqwr
|
|
||||||
$ ls
|
|
||||||
43005 fvtvzfqm.jvc
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd flcrmhlj
|
|
||||||
$ ls
|
|
||||||
245668 dcqnblb.sdj
|
|
||||||
dir lffj
|
|
||||||
229909 pflp.mdw
|
|
||||||
280176 vbn
|
|
||||||
$ cd lffj
|
|
||||||
$ ls
|
|
||||||
116451 jmzz.jdd
|
|
||||||
dir pjlwb
|
|
||||||
162815 pmhlqq.snr
|
|
||||||
226183 zffth
|
|
||||||
$ cd pjlwb
|
|
||||||
$ ls
|
|
||||||
67518 qcq.hjq
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd gtt
|
|
||||||
$ ls
|
|
||||||
52105 grpdmd.ggz
|
|
||||||
126869 zprprf.fgj
|
|
||||||
$ cd ..
|
|
||||||
$ cd hlbnhchz
|
|
||||||
$ ls
|
|
||||||
3064 dqp.lrw
|
|
||||||
278756 grpdmd.ggz
|
|
||||||
177208 ldzslndn.wlv
|
|
||||||
141685 vbn
|
|
||||||
$ cd ..
|
|
||||||
$ cd twntr
|
|
||||||
$ ls
|
|
||||||
63747 cvcl.jqh
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd qcq
|
|
||||||
$ ls
|
|
||||||
226858 cwblp.zgp
|
|
||||||
dir jjqsmfhr
|
|
||||||
dir rjbqtrq
|
|
||||||
dir vwmpnbts
|
|
||||||
141715 wdbhdch
|
|
||||||
286381 zprprf
|
|
||||||
$ cd jjqsmfhr
|
|
||||||
$ ls
|
|
||||||
dir btmm
|
|
||||||
dir fqndtlgq
|
|
||||||
$ cd btmm
|
|
||||||
$ ls
|
|
||||||
4031 dqp.lrr
|
|
||||||
dir fzdd
|
|
||||||
$ cd fzdd
|
|
||||||
$ ls
|
|
||||||
dir vnwpn
|
|
||||||
$ cd vnwpn
|
|
||||||
$ ls
|
|
||||||
dir bzlgsl
|
|
||||||
dir ztvzrrbv
|
|
||||||
$ cd bzlgsl
|
|
||||||
$ ls
|
|
||||||
9294 ldzslndn.sqr
|
|
||||||
$ cd ..
|
|
||||||
$ cd ztvzrrbv
|
|
||||||
$ ls
|
|
||||||
256017 cvcl.jqh
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd fqndtlgq
|
|
||||||
$ ls
|
|
||||||
271528 ccbmgp.bwd
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd rjbqtrq
|
|
||||||
$ ls
|
|
||||||
122150 ldzslndn
|
|
||||||
46467 tpdvp.pjf
|
|
||||||
$ cd ..
|
|
||||||
$ cd vwmpnbts
|
|
||||||
$ ls
|
|
||||||
47518 fcrwfzvm
|
|
||||||
263343 gmc.lrt
|
|
||||||
212764 qcq
|
|
||||||
$ cd ..
|
|
||||||
$ cd ..
|
|
||||||
$ cd vwqwlqrt
|
|
||||||
$ ls
|
|
||||||
dir psrs
|
|
||||||
$ cd psrs
|
|
||||||
$ ls
|
|
||||||
281998 zprprf.hml
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
133120320210233440424211425033311533112110111336536142004454550513525522325223123404213204010312200
|
|
||||||
201131111014211324423255354022022243226445013613610423653614522135534505055120330313403031333103010
|
|
||||||
312033232323231244025301315245341424106564334260061464515142114141551050411122254121204214442432210
|
|
||||||
101223224313414001513045124413405604251532415616200623342234245060512030200002055453441222043022132
|
|
||||||
302000022010423415300513533001221654231646352603366222420353100303160621313144421120541324031322221
|
|
||||||
022041343104313414435021243154525050055065506466215004364316065443031303052541012204020300331224312
|
|
||||||
103341401201343234101335152026143021665443260024145323023321363412215203352344024010350241320230403
|
|
||||||
113420142141151035404302242616255522460104100534576523546245441245051223305614204355454223220120301
|
|
||||||
141313120334140413444311032422155464031057323373712672513175353623531154646460010504312302300002224
|
|
||||||
222122233241135333145102102244620325637577115357373355166254434732406430504542404102101335430322111
|
|
||||||
303334221050505214133200215501142243567431213624743475716112467711442460620524310041114411011423020
|
|
||||||
314200333004550151023253063621162447552734266222424315622125733562141045411643325165010440012411104
|
|
||||||
002041023423222500521530364652321342767176666734452465675417573276212213343035032650010252311440041
|
|
||||||
424112310115314154624123026322722176144615437667237551164455332134452657635041110204303331153310423
|
|
||||||
403331525242111322464321027125164326531546671615634451453753666614652523355664316050035035431040223
|
|
||||||
043240150545010061116502263626227235517673287377662722735257631252161774623714640414211242003124031
|
|
||||||
120153432445266666010553121747235535567222344854553227754373283562766712275433030145041514430322020
|
|
||||||
130205252451225625553367153422361135376345652238658565468884466665635712475577163231554521534443142
|
|
||||||
111112125502543266131422234726554665525278247588365447865236325776254766323137341434403365242323513
|
|
||||||
303144132003506154604725457356146262354554756268227328243768455722852644644163423635454133132303535
|
|
||||||
355321430425362320027571672735837582654822875282477453446323242873743335342262324741355251635040132
|
|
||||||
134315335666154514547724226424352647855667536237263286847676436882327536177762242121655513144251300
|
|
||||||
540433012152253201644772517187257277883368828477658659796427367852347254442546347411045431414354124
|
|
||||||
123440236041532033152645165666552487887293658447738333978367787858534683322123676621510536503333401
|
|
||||||
513523462114216537146475772264724378429935336847846348444575554346687726237537112655265045664650022
|
|
||||||
152254463440132245722174776775434287876777476649865634494799993998688326736773121545343121065304241
|
|
||||||
250224151321236513227671833576566739347663376834388478944395578563955424353347453672417622666244155
|
|
||||||
515223301360505722213752783545553644495694566664938776366634393433784855746658113613537562051065554
|
|
||||||
554241245610333147211334537367835857366454575934899676895788946595666473766285253431355325406031452
|
|
||||||
100314521636253352672223432738853968767459797559486648888395749643933624738538781345525612342532041
|
|
||||||
341462234622615555235573736647638675877393747847457878744844899855446378852378466172227414636330202
|
|
||||||
345125124225634624432677378235488673587578945954767695474694483979633396738646725252521775306550112
|
|
||||||
413420352557414334236458423883348897736674897485778466695756868398399557654674634472471146623221025
|
|
||||||
251143521254271126368347667353953675589776644454498798849645686658369675764886773874127564444411365
|
|
||||||
221413142252611772737673846553885549867478965666795885777985495763559573589863845361134756354652555
|
|
||||||
243065641366675316826485533843887969469458797465896675796454946875597936434758642384462157714462066
|
|
||||||
520553502161266638252882759578566955579648578498775589886979787578896857766344736358531725733564135
|
|
||||||
424035430516117723442423478595343855468789497988556567558494878666699996375768427758374271236421335
|
|
||||||
252313015177661777278432468494855844559656687766987679695575558744879656544795683583262246546564621
|
|
||||||
066230444571526644743382974447835556985988567697575656976987588986595376466888728567376162756500435
|
|
||||||
466346066733165454546438886894789699679455689766757985688888664759568963398874674733715475614334101
|
|
||||||
325014552177542688745486585579599747867559596676796865787567755944786444539663262282351475561402534
|
|
||||||
241163303516225237353826934978454869995779765759887659668665685578986859343646684568651136735352562
|
|
||||||
450361264326612736655359595445797648876877955597997887987765775498545883744548752574473726565411112
|
|
||||||
554605215356217343577344399893857478777797855566878769757669857854854856357865565536552164136515351
|
|
||||||
526446641376374684266375494495458695869978975788699978669887967564769488567376982882762633361324360
|
|
||||||
131314671231526545866684867949989786895865986986978678997899677764988874736369482822342624761635224
|
|
||||||
623254034413371684428636874768586849979569867987768799666579796798469744978968758623884477174221325
|
|
||||||
451620621666445477562568544366499474968796999686779676678989576768596484478933764745243527321126622
|
|
||||||
454130052341168772645439448775675586969558878998779766779998798589986885955369648636673756137543515
|
|
||||||
052463667567627485865289577459895546659595768687867979887989666587865576357344373227477771625616331
|
|
||||||
460630633631764266522893997758984967975685969969798677679989558694657986684466928784764257141450213
|
|
||||||
624130637644652532575536775488944945689777797679988979876565896659695947897698966634635115577122034
|
|
||||||
312106635521463635433584476586795448766769568869779667989675669974989668369378542526764316562641343
|
|
||||||
162151455625714643563689555468449898859656786796979798687579985864586658783373657585741615177725655
|
|
||||||
522113305657225658843435489885646557577988797667968888669868768989959977879557377455733555272325032
|
|
||||||
304510566333111422674633384687874565587979787768979689685867565897484896499888736286384551117254613
|
|
||||||
501463041455354857783745556844585568845776985978966685877875599798784456633539465754543114144204310
|
|
||||||
033044042511137887672349889484876755578886688778959586777755687684946795536886522746575472552603266
|
|
||||||
506221035322726455557224463853355996897775558969955685797667999588974556935495475632746634441041151
|
|
||||||
433136161743725565262636565676447685475989796568778598958657768879849778786859753335661722543205305
|
|
||||||
265454361556653132263478888989675487694888975877759959776785674478666588788563747772733262666414514
|
|
||||||
052441631644734262283652379957577654769979687765967795697668686969788694345962866843241632716655446
|
|
||||||
236003436545632166356247457495793686988694668988898785686844466844799668333966735544674562633412352
|
|
||||||
521460600027621624875854349394389587767654998655578976768847769685597639387383648267451531624063352
|
|
||||||
342222114334344716267243334967869638699594976567878976765649455495834476654882454551336614731204621
|
|
||||||
033566313156263553885434364795389663465876465857797479766958478858465479967473865454116236530266023
|
|
||||||
312652012603144155543338267594667756579949844587785799854455597889659839838335338227724422251205254
|
|
||||||
300006533237512225736566526838475448787546947968579975977675656694697397732838257677271224106345603
|
|
||||||
133143326544516157647526755363599347754745759889457964588954897669586537634253625642342472416641244
|
|
||||||
154255220262671713413357272553997888597745494647794956965689397737688378433337485552276212554465555
|
|
||||||
100240040401314462336283253854484757937369955476776566463546476496874852334852883176722554655020500
|
|
||||||
114224164252562264455188387248845988369836588899857935337746669656565572827235667727764740332042104
|
|
||||||
210035410165643165676172383567428973379998596753776399638478657839665546428878531777515004325230423
|
|
||||||
210124643010215635561443542385838474565467799589387569934754637575772733563765332372676641151131504
|
|
||||||
302221012422133674231332744234367852633548864367379437949776375866557752335873376756770315423300102
|
|
||||||
332125266633066263556242566636554222886478446383395355568773939525563625678526672212234343222625410
|
|
||||||
025325451166410144267526457225543863563576656495967865696633785745578788783545643421165350000423343
|
|
||||||
002055431510265615765734547166486528454663847694453963495886284323368575223225414276066312104153401
|
|
||||||
355245141260142612771253626632378444477523462347872628387736452238277834561572523626005254261254042
|
|
||||||
203545210065351052363237141625823577635472367448676276452678742864237273162112414622640501555430121
|
|
||||||
335510044411666505051763342712375473385677658477545568853568734655885763312211631300144242225254322
|
|
||||||
420503535251235101224431771412136627846753333256668624663675776462422374227471570160056336045543305
|
|
||||||
311442220344522144201454355125161416822475756464544562823568565277363143626236634605524051151344323
|
|
||||||
221042430004563020306242752654674353744234455564453257548654537765566764222366445225313642034222311
|
|
||||||
410315020300414623613025143245525766347157877736466252545465214236744364172443246502214503112203230
|
|
||||||
342304354225251006345461616171626576425171512572743837515273314522745717111151266035240243530314400
|
|
||||||
101402542354002125435251304674647534521162334775342133371111747561164265140621412560624450505304430
|
|
||||||
011211315525203435452400223603127166746242764515517634515312173434163762164444142306041434112503201
|
|
||||||
312201041521122523410120106532007714457744313215145447526753371116262403622123305243410143403304001
|
|
||||||
420143230433241404304622552610552657576751252637557577175144676122663421114064036341501055504120312
|
|
||||||
321114124142324224151525015553652243236362311234247651266113535462142056365353412114023231401141232
|
|
||||||
144010233331150422332523034411415500511027722375253755262514425243333354512150011301540445044301243
|
|
||||||
321223141143321313415515024451144622413543514327723454716501265226013550620005111202312303242203422
|
|
||||||
220312222242043544521300416060642531526303363025212311016020154415132623214322110011054242222314401
|
|
||||||
120043213410140522500232142235034335033562221102412305131143065020436150033340525535242031300403012
|
|
||||||
333011210021031104353104420453564321600565055235040060414452305642301521213234000231332120021102311
|
|
||||||
213000422032423433105500120521112552552162045443040565055142555024614151234210022135411312102303010
|
|
||||||
311113213314300134505043355233124354500023350433035532626242646113034040102425400244311432332422101
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
//! Common helper utilities to all days
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use nom::combinator::map;
|
|
||||||
use nom::error::ErrorKind;
|
|
||||||
use nom::error::ParseError;
|
|
||||||
use nom::Finish;
|
|
||||||
use nom::IResult;
|
|
||||||
use nom::InputLength;
|
|
||||||
use nom::Parser;
|
|
||||||
|
|
||||||
/// Parse input from some nom parser and return as an anyhow result
|
|
||||||
///
|
|
||||||
/// This method exists as a convenience because nom's errors cannot otherwise be easily converted to
|
|
||||||
/// an anyhow error, and I don't want to keep track of custom error implementations here.
|
|
||||||
pub fn parse_input<'a, O>(
|
|
||||||
input: &'a [u8],
|
|
||||||
mut parser: impl Parser<&'a [u8], O, nom::error::Error<&'a [u8]>>,
|
|
||||||
) -> Result<O> {
|
|
||||||
let (unparsed, output) = parser.parse(input).finish().map_err(|e| {
|
|
||||||
anyhow::anyhow!(
|
|
||||||
"Parser error {:?} to parse at {}",
|
|
||||||
e.code,
|
|
||||||
String::from_utf8_lossy(e.input)
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if !unparsed.is_empty() {
|
|
||||||
Err(anyhow::anyhow!(
|
|
||||||
"Not all input consumed: {}",
|
|
||||||
String::from_utf8_lossy(unparsed)
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies a parser iteratively and reduces the results using the given function. Fails if the
|
|
||||||
/// embedded parser doesn't return at least one result.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
/// - `f`: the function to apply
|
|
||||||
/// - `g`: the function that combines the result o `f` with previous results
|
|
||||||
///
|
|
||||||
/// This implementation is based on [`nom::multi::fold_many1`] with minor differences. If
|
|
||||||
/// successful, this should probably be upstreamed.
|
|
||||||
pub fn reduce_many1<I, O, E, F>(
|
|
||||||
mut f: F,
|
|
||||||
mut g: impl FnMut(O, O) -> O,
|
|
||||||
) -> impl FnMut(I) -> IResult<I, O, E>
|
|
||||||
where
|
|
||||||
I: Clone + InputLength,
|
|
||||||
E: ParseError<I>,
|
|
||||||
F: Parser<I, O, E>,
|
|
||||||
{
|
|
||||||
// Cannot delegate to fold_many0 because that would make the function FnOnce rather than FnMut,
|
|
||||||
// since it would transfer ownership of the embedded parser to fold_many0.
|
|
||||||
move |i: I| {
|
|
||||||
let _i = i.clone();
|
|
||||||
match f.parse(_i) {
|
|
||||||
Err(nom::Err::Error(_)) => {
|
|
||||||
Err(nom::Err::Error(E::from_error_kind(i, ErrorKind::Many1)))
|
|
||||||
}
|
|
||||||
Err(e) => Err(e),
|
|
||||||
Ok((i1, mut acc)) => {
|
|
||||||
let mut input = i1;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let _input = input.clone();
|
|
||||||
let len = input.input_len();
|
|
||||||
match f.parse(_input) {
|
|
||||||
Err(nom::Err::Error(_)) => {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Err(e) => return Err(e),
|
|
||||||
Ok((i, o)) => {
|
|
||||||
// infinite loop check: the parser must always consume
|
|
||||||
if i.input_len() == len {
|
|
||||||
return Err(nom::Err::Failure(E::from_error_kind(
|
|
||||||
i,
|
|
||||||
ErrorKind::Many1,
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
acc = g(acc, o);
|
|
||||||
input = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((input, acc))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add an index to repeated successful invocations of the embedded parser.
|
|
||||||
pub fn enumerate<I, O, E>(f: impl Parser<I, O, E>) -> impl FnMut(I) -> IResult<I, (usize, O), E> {
|
|
||||||
let mut index = 0usize;
|
|
||||||
|
|
||||||
map(f, move |v| {
|
|
||||||
let res = (index, v);
|
|
||||||
index += 1;
|
|
||||||
res
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the minimum and maximum of two unordered variables
|
|
||||||
pub fn minmax<T>(a: T, b: T) -> (T, T)
|
|
||||||
where
|
|
||||||
T: PartialOrd,
|
|
||||||
{
|
|
||||||
if a < b {
|
|
||||||
(a, b)
|
|
||||||
} else {
|
|
||||||
(b, a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
use std::ops::Add;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use nom::character::complete::newline;
|
|
||||||
use nom::multi::separated_list0;
|
|
||||||
use nom::sequence::terminated;
|
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
use crate::common::parse_input;
|
|
||||||
use crate::common::reduce_many1;
|
|
||||||
|
|
||||||
fn parse_elf(input: &[u8]) -> IResult<&[u8], i32> {
|
|
||||||
reduce_many1(terminated(nom::character::complete::i32, newline), Add::add)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
|
||||||
let elves = parse_input(input, parse_elf_list)?;
|
|
||||||
Ok(elves.into_iter().fold(0, Ord::max).to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_elf_list(input: &[u8]) -> IResult<&[u8], Vec<i32>> {
|
|
||||||
separated_list0(newline, parse_elf)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
let mut elves = parse_input(input, parse_elf_list)?;
|
|
||||||
|
|
||||||
let (first, third, _) = elves.select_nth_unstable_by(2, |a, b| Ord::cmp(b, a));
|
|
||||||
|
|
||||||
let result = first[1] + first[0] + *third;
|
|
||||||
|
|
||||||
Ok(result.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLE: &[u8] = include_bytes!("samples/01.txt");
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part1() {
|
|
||||||
assert_eq!(part1(SAMPLE).unwrap(), "24000");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
assert_eq!(part2(SAMPLE).unwrap(), "45000");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
use nom::character::complete::newline;
|
|
||||||
use nom::combinator::map_res;
|
|
||||||
use nom::multi::many0;
|
|
||||||
use nom::sequence::separated_pair;
|
|
||||||
use nom::sequence::terminated;
|
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
use crate::common::parse_input;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
||||||
enum Rps {
|
|
||||||
Rock,
|
|
||||||
Paper,
|
|
||||||
Scissors,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rps {
|
|
||||||
/// Score we get by playing this move
|
|
||||||
fn score(self) -> u32 {
|
|
||||||
match self {
|
|
||||||
Rps::Rock => 1,
|
|
||||||
Rps::Paper => 2,
|
|
||||||
Rps::Scissors => 3,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Score we get from the result from playing given other
|
|
||||||
fn score_against(self, other: Self) -> u32 {
|
|
||||||
match (self, other) {
|
|
||||||
(a, b) if a == b => 3,
|
|
||||||
(Rps::Rock, Rps::Paper) | (Rps::Paper, Rps::Scissors) | (Rps::Scissors, Rps::Rock) => 0,
|
|
||||||
_ => 6,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Score if the result is according to the instruction
|
|
||||||
fn score_result(self) -> u32 {
|
|
||||||
match self {
|
|
||||||
Rps::Rock => 0, // Rock is lose
|
|
||||||
Rps::Paper => 3, // Paper is draw
|
|
||||||
Rps::Scissors => 6, // Scissors is win
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Move we need to achieve the result indicated by self
|
|
||||||
fn needed(self, other: Self) -> Self {
|
|
||||||
match (self, other) {
|
|
||||||
(Rps::Paper, other) => other,
|
|
||||||
(Rps::Rock, Rps::Rock) => Rps::Scissors,
|
|
||||||
(Rps::Rock, Rps::Paper) => Rps::Rock,
|
|
||||||
(Rps::Rock, Rps::Scissors) => Rps::Paper,
|
|
||||||
(Rps::Scissors, Rps::Rock) => Rps::Paper,
|
|
||||||
(Rps::Scissors, Rps::Paper) => Rps::Scissors,
|
|
||||||
(Rps::Scissors, Rps::Scissors) => Rps::Rock,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<u8> for Rps {
|
|
||||||
type Error = anyhow::Error;
|
|
||||||
|
|
||||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
|
||||||
match value {
|
|
||||||
b'A' | b'X' => Ok(Rps::Rock),
|
|
||||||
b'B' | b'Y' => Ok(Rps::Paper),
|
|
||||||
b'C' | b'Z' => Ok(Rps::Scissors),
|
|
||||||
_ => Err(anyhow::anyhow!("Invalid RPS: {value}")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_plan(input: &[u8]) -> IResult<&[u8], Vec<(Rps, Rps)>> {
|
|
||||||
fn parse_rps(input: &[u8]) -> IResult<&[u8], Rps> {
|
|
||||||
// Note: alpha1 also sort of works but is significantly slower
|
|
||||||
map_res(nom::bytes::complete::take(1usize), |v: &[u8]| {
|
|
||||||
Rps::try_from(v[0])
|
|
||||||
})(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_line(input: &[u8]) -> IResult<&[u8], (Rps, Rps)> {
|
|
||||||
separated_pair(parse_rps, nom::character::complete::char(' '), parse_rps)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
many0(terminated(parse_line, newline))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
|
||||||
let plan = parse_input(input, parse_plan)?;
|
|
||||||
|
|
||||||
let result: u32 = plan
|
|
||||||
.into_iter()
|
|
||||||
.map(|(them, us)| us.score() + us.score_against(them))
|
|
||||||
.sum();
|
|
||||||
|
|
||||||
Ok(result.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
let plan = parse_input(input, parse_plan)?;
|
|
||||||
|
|
||||||
let result: u32 = plan
|
|
||||||
.into_iter()
|
|
||||||
.map(|(them, us)| us.score_result() + us.needed(them).score())
|
|
||||||
.sum();
|
|
||||||
|
|
||||||
Ok(result.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLE: &[u8] = include_bytes!("samples/02.txt");
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part1() {
|
|
||||||
assert_eq!(part1(SAMPLE).unwrap(), "15")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
assert_eq!(part2(SAMPLE).unwrap(), "12")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
fn priority(item: u8) -> u32 {
|
|
||||||
match item {
|
|
||||||
b'a'..=b'z' => item - b'a' + 1,
|
|
||||||
b'A'..=b'Z' => item - b'A' + 27,
|
|
||||||
_ => 0,
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn seen(backpack: &[u8]) -> u64 {
|
|
||||||
let mut seen = 0;
|
|
||||||
|
|
||||||
for &b in backpack {
|
|
||||||
seen |= 1 << priority(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
seen
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
|
||||||
let mut total = 0;
|
|
||||||
|
|
||||||
for line in input.split(|&b| b == b'\n') {
|
|
||||||
let (first, last) = line.split_at(line.len() / 2);
|
|
||||||
|
|
||||||
let seen = seen(first);
|
|
||||||
|
|
||||||
for &b in last {
|
|
||||||
let prio = priority(b);
|
|
||||||
|
|
||||||
if (seen & (1 << prio)) != 0 {
|
|
||||||
total += prio;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(total.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
let mut total = 0;
|
|
||||||
|
|
||||||
for chunk in &input.split(|&b| b == b'\n').chunks(3) {
|
|
||||||
let mut mask = u64::MAX;
|
|
||||||
|
|
||||||
for backpack in chunk {
|
|
||||||
let seen = seen(backpack);
|
|
||||||
mask &= seen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if mask != 0 {
|
|
||||||
debug_assert_eq!(1, mask.count_ones());
|
|
||||||
total += mask.trailing_zeros();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(total.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLE: &[u8] = include_bytes!("samples/03.txt");
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part1() {
|
|
||||||
assert_eq!(part1(SAMPLE).unwrap(), "157")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
assert_eq!(part2(SAMPLE).unwrap(), "70")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
use nom::bytes::complete::tag;
|
|
||||||
use nom::character::complete::newline;
|
|
||||||
use nom::combinator::map;
|
|
||||||
use nom::multi::many0;
|
|
||||||
use nom::sequence::separated_pair;
|
|
||||||
use nom::sequence::terminated;
|
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
use crate::common::minmax;
|
|
||||||
use crate::common::parse_input;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialOrd, PartialEq)]
|
|
||||||
struct Assignment(u32, u32);
|
|
||||||
|
|
||||||
impl Assignment {
|
|
||||||
fn one_contains(self, other: Self) -> bool {
|
|
||||||
let (first, second) = minmax(self, other);
|
|
||||||
|
|
||||||
if second.0 == first.0 {
|
|
||||||
first.1 <= second.1
|
|
||||||
} else {
|
|
||||||
second.0 <= first.1 && second.1 <= first.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn one_overlaps(self, other: Self) -> bool {
|
|
||||||
let (first, second) = minmax(self, other);
|
|
||||||
|
|
||||||
if second.0 == first.0 {
|
|
||||||
first.1 <= second.1
|
|
||||||
} else {
|
|
||||||
second.0 <= first.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_assignments(input: &[u8]) -> IResult<&[u8], Vec<(Assignment, Assignment)>> {
|
|
||||||
use nom::character::complete::u32;
|
|
||||||
|
|
||||||
fn parse_single(input: &[u8]) -> IResult<&[u8], Assignment> {
|
|
||||||
map(separated_pair(u32, tag("-"), u32), |(start, end)| {
|
|
||||||
Assignment(start, end)
|
|
||||||
})(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
let parse_line = separated_pair(parse_single, tag(","), parse_single);
|
|
||||||
|
|
||||||
many0(terminated(parse_line, newline))(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parts_common(input: &[u8], filter: impl Fn(Assignment, Assignment) -> bool) -> Result<String> {
|
|
||||||
let assigments = parse_input(input, parse_assignments)?;
|
|
||||||
|
|
||||||
let overlapping = assigments
|
|
||||||
.into_iter()
|
|
||||||
.filter(|&(a, b)| filter(a, b))
|
|
||||||
.count();
|
|
||||||
|
|
||||||
Ok(overlapping.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
|
||||||
parts_common(input, Assignment::one_contains)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
parts_common(input, Assignment::one_overlaps)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLE: &[u8] = include_bytes!("samples/04.txt");
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part1() {
|
|
||||||
assert_eq!(part1(SAMPLE).unwrap(), "2")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
assert_eq!(part2(SAMPLE).unwrap(), "4")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use nom::branch::alt;
|
|
||||||
use nom::bytes::complete::tag;
|
|
||||||
use nom::bytes::complete::take;
|
|
||||||
use nom::bytes::complete::take_until;
|
|
||||||
use nom::character::complete::newline;
|
|
||||||
use nom::combinator::map;
|
|
||||||
use nom::combinator::opt;
|
|
||||||
use nom::multi::fold_many1;
|
|
||||||
use nom::multi::many1;
|
|
||||||
use nom::sequence::delimited;
|
|
||||||
use nom::sequence::preceded;
|
|
||||||
use nom::sequence::terminated;
|
|
||||||
use nom::sequence::tuple;
|
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
use crate::common::enumerate;
|
|
||||||
use crate::common::parse_input;
|
|
||||||
|
|
||||||
type Move = (usize, usize, usize);
|
|
||||||
type OwnedStacks = Vec<Vec<u8>>;
|
|
||||||
|
|
||||||
fn parse_row<'a>(input: &'a [u8], stacks: &mut OwnedStacks) -> IResult<&'a [u8], ()> {
|
|
||||||
// Forgive me for this crime
|
|
||||||
fold_many1(
|
|
||||||
enumerate(terminated(
|
|
||||||
alt((
|
|
||||||
// Parse a delimited value into a Some(content)
|
|
||||||
map(delimited(tag("["), take(1usize), tag("]")), |v: &[u8]| {
|
|
||||||
Some(v[0])
|
|
||||||
}),
|
|
||||||
// Or an empty stack into a None
|
|
||||||
map(tag(" "), |_| None),
|
|
||||||
)),
|
|
||||||
opt(tag(" ")),
|
|
||||||
)),
|
|
||||||
|| (),
|
|
||||||
move |_, (index, c)| {
|
|
||||||
if let Some(b) = c {
|
|
||||||
if stacks.len() <= index {
|
|
||||||
stacks.resize_with(index + 1, Vec::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
stacks[index].push(b)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_stacks(input: &[u8]) -> IResult<&[u8], OwnedStacks> {
|
|
||||||
let mut stacks = Vec::new();
|
|
||||||
|
|
||||||
let (input, _) = terminated(
|
|
||||||
fold_many1(
|
|
||||||
terminated(|input| parse_row(input, &mut stacks), newline),
|
|
||||||
|| (),
|
|
||||||
|_, _| (),
|
|
||||||
),
|
|
||||||
// Skip the line with the numbers
|
|
||||||
take_until("\n\n"),
|
|
||||||
)(input)?;
|
|
||||||
|
|
||||||
// Reverse the stacks since we parsed them top-down
|
|
||||||
for stack in &mut stacks {
|
|
||||||
stack.reverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((input, stacks))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_task(input: &[u8]) -> IResult<&[u8], (OwnedStacks, Vec<Move>)> {
|
|
||||||
fn parse_usize(input: &[u8]) -> IResult<&[u8], usize> {
|
|
||||||
map(nom::character::complete::u32, |v| v as usize)(input)
|
|
||||||
}
|
|
||||||
let (input, stacks) = parse_stacks(input)?;
|
|
||||||
|
|
||||||
// Consume the double newline
|
|
||||||
let (input, _) = tag("\n\n")(input)?;
|
|
||||||
|
|
||||||
let (input, moves) = many1(terminated(
|
|
||||||
tuple((
|
|
||||||
preceded(tag("move "), parse_usize),
|
|
||||||
preceded(tag(" from "), parse_usize),
|
|
||||||
preceded(tag(" to "), parse_usize),
|
|
||||||
)),
|
|
||||||
newline,
|
|
||||||
))(input)?;
|
|
||||||
|
|
||||||
Ok((input, (stacks, moves)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Some magic to get two mutable references into the same slice
|
|
||||||
fn get_both(stacks: &mut [Vec<u8>], from: usize, to: usize) -> (&mut Vec<u8>, &mut Vec<u8>) {
|
|
||||||
match from.cmp(&to) {
|
|
||||||
Ordering::Greater => {
|
|
||||||
let (begin, end) = stacks.split_at_mut(from);
|
|
||||||
(&mut end[0], &mut begin[to])
|
|
||||||
}
|
|
||||||
Ordering::Less => {
|
|
||||||
let (begin, end) = stacks.split_at_mut(to);
|
|
||||||
(&mut begin[from], &mut end[0])
|
|
||||||
}
|
|
||||||
Ordering::Equal => panic!("Tried to stack from and to {from}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_answer(stacks: &mut [Vec<u8>]) -> Result<String> {
|
|
||||||
let mut result = String::with_capacity(stacks.len());
|
|
||||||
|
|
||||||
for stack in stacks {
|
|
||||||
result.push(
|
|
||||||
*stack
|
|
||||||
.last()
|
|
||||||
.ok_or_else(|| anyhow::anyhow!("Encountered empty stack"))? as char,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
|
||||||
let (mut stacks, moves) = parse_input(input, parse_task)?;
|
|
||||||
|
|
||||||
for (count, from, to) in moves {
|
|
||||||
let (from, to) = get_both(&mut stacks, from - 1, to - 1);
|
|
||||||
|
|
||||||
let drain_start = from.len() - count;
|
|
||||||
|
|
||||||
to.extend(from.drain(drain_start..).rev());
|
|
||||||
}
|
|
||||||
|
|
||||||
compute_answer(&mut stacks)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
let (mut stacks, moves) = parse_input(input, parse_task)?;
|
|
||||||
|
|
||||||
for (count, from, to) in moves {
|
|
||||||
let (from, to) = get_both(&mut stacks, from - 1, to - 1);
|
|
||||||
|
|
||||||
let drain_start = from.len() - count;
|
|
||||||
|
|
||||||
to.extend(from.drain(drain_start..));
|
|
||||||
}
|
|
||||||
|
|
||||||
compute_answer(&mut stacks)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLE: &[u8] = include_bytes!("samples/05.txt");
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part1() {
|
|
||||||
assert_eq!(part1(SAMPLE).unwrap(), "CMZ");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
assert_eq!(part2(SAMPLE).unwrap(), "MCD");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
fn find_first(input: &[u8], unique: usize) -> Result<usize> {
|
|
||||||
let mut seen = [false; 256];
|
|
||||||
|
|
||||||
let mut tail_it = input.iter();
|
|
||||||
|
|
||||||
let mut first = 0;
|
|
||||||
|
|
||||||
// Loop invariant: input[first..last] contains only unique characters
|
|
||||||
for (last, &c) in input.iter().enumerate() {
|
|
||||||
if seen[c as usize] {
|
|
||||||
first += (&mut tail_it)
|
|
||||||
.take_while(|&&b| b != c)
|
|
||||||
.map(|&b| seen[b as usize] = false)
|
|
||||||
.count()
|
|
||||||
+ 1; // +1 because take_while doesn't return the first element that didn't satisfy the condition, while we do need to count it
|
|
||||||
} else {
|
|
||||||
// New unique character found: input[first..=last] contains unique characters
|
|
||||||
if last - first + 1 == unique {
|
|
||||||
return Ok(last + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
seen[c as usize] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
anyhow::bail!("Did not find unique sequence of length {unique}");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
|
||||||
Ok(find_first(input, 4)?.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
Ok(find_first(input, 14)?.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLES: &[&[u8]] = &[
|
|
||||||
b"mjqjpqmgbljsphdztnvjfqwrcgsmlb",
|
|
||||||
b"bvwbjplbgvbhsrlpgdmjqwftvncz",
|
|
||||||
b"nppdvjthqldpwncqszvftbrmjlhg",
|
|
||||||
b"nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg",
|
|
||||||
b"zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw",
|
|
||||||
];
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part1() {
|
|
||||||
const CORRECT: &[usize] = &[7, 5, 6, 10, 11];
|
|
||||||
|
|
||||||
for (&sample, &correct) in SAMPLES.iter().zip(CORRECT) {
|
|
||||||
assert_eq!(find_first(sample, 4).unwrap(), correct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
const CORRECT: &[usize] = &[19, 23, 23, 29, 26];
|
|
||||||
|
|
||||||
for (&sample, &correct) in SAMPLES.iter().zip(CORRECT) {
|
|
||||||
assert_eq!(find_first(sample, 14).unwrap(), correct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
use anyhow::Context;
|
|
||||||
use anyhow::Result;
|
|
||||||
use nom::branch::alt;
|
|
||||||
use nom::bytes::complete::tag;
|
|
||||||
use nom::bytes::complete::take_until;
|
|
||||||
use nom::character::complete::newline;
|
|
||||||
use nom::combinator::map;
|
|
||||||
use nom::combinator::opt;
|
|
||||||
use nom::multi::fold_many0;
|
|
||||||
use nom::sequence::delimited;
|
|
||||||
use nom::sequence::preceded;
|
|
||||||
use nom::sequence::terminated;
|
|
||||||
use nom::sequence::tuple;
|
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
use crate::common::parse_input;
|
|
||||||
|
|
||||||
fn parse_dir<'a>(
|
|
||||||
input: &'a [u8],
|
|
||||||
dirs: &mut Vec<u32>,
|
|
||||||
dir_stack: &mut Vec<&'a [u8]>,
|
|
||||||
) -> IResult<&'a [u8], u32> {
|
|
||||||
use nom::character::complete::u32;
|
|
||||||
|
|
||||||
enum Entry<'a> {
|
|
||||||
File(u32),
|
|
||||||
Dir(&'a [u8]),
|
|
||||||
}
|
|
||||||
let initial_len = dir_stack.len();
|
|
||||||
|
|
||||||
let (mut input, mut size) = preceded(
|
|
||||||
tag("$ ls\n"),
|
|
||||||
fold_many0(
|
|
||||||
// Map many newline-terminated entries
|
|
||||||
terminated(
|
|
||||||
// of either
|
|
||||||
alt((
|
|
||||||
// A size followed by a name
|
|
||||||
map(terminated(u32, take_until("\n")), Entry::File),
|
|
||||||
// Or the word "dir" followed by a name
|
|
||||||
map(preceded(tag("dir "), take_until("\n")), Entry::Dir),
|
|
||||||
)),
|
|
||||||
newline,
|
|
||||||
),
|
|
||||||
|| 0u32,
|
|
||||||
|files_sum, entry| match entry {
|
|
||||||
Entry::File(size) => files_sum + size,
|
|
||||||
Entry::Dir(name) => {
|
|
||||||
dir_stack.push(name);
|
|
||||||
files_sum
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)(input)?;
|
|
||||||
|
|
||||||
for i in initial_len..dir_stack.len() {
|
|
||||||
let (new_input, content_size) = delimited(
|
|
||||||
tuple((tag("$ cd "), tag(dir_stack[i]), newline)),
|
|
||||||
|input| parse_dir(input, dirs, dir_stack),
|
|
||||||
// Optional cd'ing out because the last directory is never exited.
|
|
||||||
opt(tag("$ cd ..\n")),
|
|
||||||
)(input)?;
|
|
||||||
|
|
||||||
input = new_input;
|
|
||||||
size += content_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs.push(size);
|
|
||||||
dir_stack.truncate(initial_len);
|
|
||||||
|
|
||||||
Ok((input, size))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_program(input: &[u8]) -> IResult<&[u8], (u32, Vec<u32>)> {
|
|
||||||
let mut dirs = Vec::new();
|
|
||||||
let mut dirstack = Vec::new();
|
|
||||||
let (input, size) = preceded(tag("$ cd /\n"), |input| {
|
|
||||||
parse_dir(input, &mut dirs, &mut dirstack)
|
|
||||||
})(input)?;
|
|
||||||
|
|
||||||
Ok((input, (size, dirs)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
|
||||||
let (_, sizes) = parse_input(input, parse_program)?;
|
|
||||||
|
|
||||||
let searched_size: u32 = sizes.into_iter().filter(|&size| size <= 100000).sum();
|
|
||||||
|
|
||||||
Ok(searched_size.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
const TARGET: u32 = 30000000;
|
|
||||||
const TOTAL: u32 = 70000000;
|
|
||||||
|
|
||||||
let (used, sizes) = parse_input(input, parse_program)?;
|
|
||||||
|
|
||||||
let required = TARGET - (TOTAL - used);
|
|
||||||
|
|
||||||
let min = sizes
|
|
||||||
.into_iter()
|
|
||||||
.filter(|&size| size >= required)
|
|
||||||
.min()
|
|
||||||
.context("Did not find dir large enough to delete")?;
|
|
||||||
|
|
||||||
Ok(min.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLE: &[u8] = include_bytes!("samples/07.txt");
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part1() {
|
|
||||||
assert_eq!(part1(SAMPLE).unwrap(), "95437");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
assert_eq!(part2(SAMPLE).unwrap(), "24933642");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
use anyhow::Context;
|
|
||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn stripe<'a>(
|
|
||||||
values: impl IntoIterator<Item = &'a u8>,
|
|
||||||
visible: impl IntoIterator<Item = &'a mut bool>,
|
|
||||||
) {
|
|
||||||
let mut max = 0;
|
|
||||||
|
|
||||||
for (&val, visible) in values.into_iter().zip(visible) {
|
|
||||||
if val > max {
|
|
||||||
max = val;
|
|
||||||
*visible = true;
|
|
||||||
|
|
||||||
if val == b'9' {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part1(input: &[u8]) -> Result<String> {
|
|
||||||
let width = input
|
|
||||||
.iter()
|
|
||||||
.position(|&b| b == b'\n')
|
|
||||||
.context("Single row field")?;
|
|
||||||
let height = input.len() / (width + 1); // Include newlines
|
|
||||||
|
|
||||||
let mut visible = vec![false; width * height];
|
|
||||||
|
|
||||||
// Horizontal striping
|
|
||||||
for (y, row) in input.chunks_exact(width + 1).enumerate() {
|
|
||||||
// First, left to right
|
|
||||||
stripe(&row[..width], &mut visible[(y * width)..]);
|
|
||||||
|
|
||||||
// Then right to left
|
|
||||||
stripe(
|
|
||||||
row[..width].iter().rev(),
|
|
||||||
visible[(y * width)..(y * width + width)].iter_mut().rev(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vertical striping
|
|
||||||
for x in 0..width {
|
|
||||||
// Top to bottom
|
|
||||||
stripe(
|
|
||||||
input[x..].iter().step_by(width + 1),
|
|
||||||
visible[x..].iter_mut().step_by(width),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bottom to top
|
|
||||||
stripe(
|
|
||||||
input[x..].iter().step_by(width + 1).rev(),
|
|
||||||
visible[x..].iter_mut().step_by(width).rev(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(visible.into_iter().filter(|&b| b).count().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn scenery<'a>(
|
|
||||||
values: impl IntoIterator<Item = &'a u8>,
|
|
||||||
visible: impl IntoIterator<Item = &'a mut usize>,
|
|
||||||
) {
|
|
||||||
let mut last_seen = [0; 10];
|
|
||||||
|
|
||||||
for (i, (&val, score)) in values.into_iter().zip(visible).enumerate() {
|
|
||||||
let val = val - b'0';
|
|
||||||
let visible = i - last_seen[val as usize];
|
|
||||||
|
|
||||||
if i > 0 {
|
|
||||||
*score *= visible;
|
|
||||||
last_seen[..=(val as usize)].fill(i);
|
|
||||||
} else {
|
|
||||||
*score = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(input: &[u8]) -> Result<String> {
|
|
||||||
let width = input
|
|
||||||
.iter()
|
|
||||||
.position(|&b| b == b'\n')
|
|
||||||
.context("Single row field")?;
|
|
||||||
let height = input.len() / (width + 1); // Include newlines
|
|
||||||
|
|
||||||
let mut score = vec![1; width * height];
|
|
||||||
|
|
||||||
// Horizontal striping
|
|
||||||
for (y, row) in input.chunks_exact(width + 1).enumerate() {
|
|
||||||
// First, left to right
|
|
||||||
scenery(&row[..width], &mut score[(y * width)..]);
|
|
||||||
|
|
||||||
// Then right to left
|
|
||||||
scenery(
|
|
||||||
row[..width].iter().rev(),
|
|
||||||
score[(y * width)..(y * width + width)].iter_mut().rev(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vertical striping
|
|
||||||
for x in 0..width {
|
|
||||||
// Top to bottom
|
|
||||||
scenery(
|
|
||||||
input[x..].iter().step_by(width + 1),
|
|
||||||
score[x..].iter_mut().step_by(width),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Bottom to top
|
|
||||||
scenery(
|
|
||||||
input[x..].iter().step_by(width + 1).rev(),
|
|
||||||
score[x..].iter_mut().step_by(width).rev(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(score.into_iter().max().context("empty field")?.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLE: &[u8] = include_bytes!("samples/08.txt");
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part1() {
|
|
||||||
assert_eq!(part1(SAMPLE).unwrap(), "21");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_part2() {
|
|
||||||
assert_eq!(part2(SAMPLE).unwrap(), "8");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn part2(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
pub fn part1(_input: &[u8]) -> Result<String> {
|
|
||||||
anyhow::bail!("not implemented")
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
use anyhow::Result;
|
|
||||||
|
|
||||||
mod common;
|
|
||||||
mod day01;
|
|
||||||
mod day02;
|
|
||||||
mod day03;
|
|
||||||
mod day04;
|
|
||||||
mod day05;
|
|
||||||
mod day06;
|
|
||||||
mod day07;
|
|
||||||
mod day08;
|
|
||||||
mod day09;
|
|
||||||
mod day10;
|
|
||||||
mod day11;
|
|
||||||
mod day12;
|
|
||||||
mod day13;
|
|
||||||
mod day14;
|
|
||||||
mod day15;
|
|
||||||
mod day16;
|
|
||||||
mod day17;
|
|
||||||
mod day18;
|
|
||||||
mod day19;
|
|
||||||
mod day20;
|
|
||||||
mod day21;
|
|
||||||
mod day22;
|
|
||||||
mod day23;
|
|
||||||
mod day24;
|
|
||||||
mod day25;
|
|
||||||
|
|
||||||
type Solution = fn(&[u8]) -> Result<String>;
|
|
||||||
|
|
||||||
pub fn get_implementation(day: u8, part2: bool) -> Result<Solution> {
|
|
||||||
if !part2 {
|
|
||||||
match day {
|
|
||||||
1 => Ok(day01::part1),
|
|
||||||
2 => Ok(day02::part1),
|
|
||||||
3 => Ok(day03::part1),
|
|
||||||
4 => Ok(day04::part1),
|
|
||||||
5 => Ok(day05::part1),
|
|
||||||
6 => Ok(day06::part1),
|
|
||||||
7 => Ok(day07::part1),
|
|
||||||
8 => Ok(day08::part1),
|
|
||||||
9 => Ok(day09::part1),
|
|
||||||
10 => Ok(day10::part1),
|
|
||||||
11 => Ok(day11::part1),
|
|
||||||
12 => Ok(day12::part1),
|
|
||||||
13 => Ok(day13::part1),
|
|
||||||
14 => Ok(day14::part1),
|
|
||||||
15 => Ok(day15::part1),
|
|
||||||
16 => Ok(day16::part1),
|
|
||||||
17 => Ok(day17::part1),
|
|
||||||
18 => Ok(day18::part1),
|
|
||||||
19 => Ok(day19::part1),
|
|
||||||
20 => Ok(day20::part1),
|
|
||||||
21 => Ok(day21::part1),
|
|
||||||
22 => Ok(day22::part1),
|
|
||||||
23 => Ok(day23::part1),
|
|
||||||
24 => Ok(day24::part1),
|
|
||||||
25 => Ok(day25::part1),
|
|
||||||
_ => anyhow::bail!("Invalid day for part 1: {day}"),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
match day {
|
|
||||||
1 => Ok(day01::part2),
|
|
||||||
2 => Ok(day02::part2),
|
|
||||||
3 => Ok(day03::part2),
|
|
||||||
4 => Ok(day04::part2),
|
|
||||||
5 => Ok(day05::part2),
|
|
||||||
6 => Ok(day06::part2),
|
|
||||||
7 => Ok(day07::part2),
|
|
||||||
8 => Ok(day08::part2),
|
|
||||||
9 => Ok(day09::part2),
|
|
||||||
10 => Ok(day10::part2),
|
|
||||||
11 => Ok(day11::part2),
|
|
||||||
12 => Ok(day12::part2),
|
|
||||||
13 => Ok(day13::part2),
|
|
||||||
14 => Ok(day14::part2),
|
|
||||||
15 => Ok(day15::part2),
|
|
||||||
16 => Ok(day16::part2),
|
|
||||||
17 => Ok(day17::part2),
|
|
||||||
18 => Ok(day18::part2),
|
|
||||||
19 => Ok(day19::part2),
|
|
||||||
20 => Ok(day20::part2),
|
|
||||||
21 => Ok(day21::part2),
|
|
||||||
22 => Ok(day22::part2),
|
|
||||||
23 => Ok(day23::part2),
|
|
||||||
24 => Ok(day24::part2),
|
|
||||||
_ => anyhow::bail!("Invalid day for part 2: {day}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
use std::fs::File;
|
|
||||||
use std::io::Read;
|
|
||||||
use std::num::NonZeroU8;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use clap::Parser;
|
|
||||||
|
|
||||||
use aoc_2022::get_implementation;
|
|
||||||
|
|
||||||
/// Advent of Code 2022 runner
|
|
||||||
#[derive(Parser)]
|
|
||||||
struct Opts {
|
|
||||||
/// Which day to run
|
|
||||||
day: NonZeroU8,
|
|
||||||
|
|
||||||
/// Print time taken
|
|
||||||
#[clap(short, long)]
|
|
||||||
time: bool,
|
|
||||||
|
|
||||||
/// Run part 2 instead of part 1
|
|
||||||
#[clap(short = '2', long)]
|
|
||||||
part2: bool,
|
|
||||||
|
|
||||||
/// Read input from the given file instead of stdin
|
|
||||||
#[clap(short, long)]
|
|
||||||
input: Option<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Opts {
|
|
||||||
fn input_data(&self) -> Result<Vec<u8>> {
|
|
||||||
let mut buffer = Vec::new();
|
|
||||||
|
|
||||||
if let Some(input) = &self.input {
|
|
||||||
File::open(input)?.read_to_end(&mut buffer)?;
|
|
||||||
} else {
|
|
||||||
std::io::stdin().read_to_end(&mut buffer)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(buffer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
|
||||||
let opts: Opts = Opts::parse();
|
|
||||||
|
|
||||||
let input = opts.input_data()?;
|
|
||||||
|
|
||||||
let implementation = get_implementation(opts.day.get(), opts.part2)?;
|
|
||||||
|
|
||||||
let begin = Instant::now();
|
|
||||||
let result = implementation(&input)?;
|
|
||||||
|
|
||||||
if opts.time {
|
|
||||||
eprintln!("Execution time: {:?}", Instant::now().duration_since(begin));
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("{}", result);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
1000
|
|
||||||
2000
|
|
||||||
3000
|
|
||||||
|
|
||||||
4000
|
|
||||||
|
|
||||||
5000
|
|
||||||
6000
|
|
||||||
|
|
||||||
7000
|
|
||||||
8000
|
|
||||||
9000
|
|
||||||
|
|
||||||
10000
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
A Y
|
|
||||||
B X
|
|
||||||
C Z
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
vJrwpWtwJgWrhcsFMMfFFhFp
|
|
||||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
|
||||||
PmmdzqPrVvPwwTWBwg
|
|
||||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
|
||||||
ttgJtRGJQctTZtZT
|
|
||||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
2-4,6-8
|
|
||||||
2-3,4-5
|
|
||||||
5-7,7-9
|
|
||||||
2-8,3-7
|
|
||||||
6-6,4-6
|
|
||||||
2-6,4-8
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
[D]
|
|
||||||
[N] [C]
|
|
||||||
[Z] [M] [P]
|
|
||||||
1 2 3
|
|
||||||
|
|
||||||
move 1 from 2 to 1
|
|
||||||
move 3 from 1 to 3
|
|
||||||
move 2 from 2 to 1
|
|
||||||
move 1 from 1 to 2
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
$ 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
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
30373
|
|
||||||
25512
|
|
||||||
65332
|
|
||||||
33549
|
|
||||||
35390
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Advent of Code
|
# Advent of Code
|
||||||
|
|
||||||
[](https://github.com/bertptrs/adventofcode/actions/workflows/2022.yml)
|
[](https://github.com/bertptrs/adventofcode/actions/workflows/2021.yml)
|
||||||
|
|
||||||
This repository contains my solutions for Advent of Code. See:
|
This repository contains my solutions for Advent of Code. See:
|
||||||
|
|
||||||
@@ -11,4 +11,3 @@ This repository contains my solutions for Advent of Code. See:
|
|||||||
- [2019 edition](./2019)
|
- [2019 edition](./2019)
|
||||||
- [2020 edition](./2020)
|
- [2020 edition](./2020)
|
||||||
- [2021 edition](./2021)
|
- [2021 edition](./2021)
|
||||||
- [2022 edition](./2022)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user