mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-26 05:10:32 +01:00
Compare commits
116 Commits
2021-day23
...
4ee6a82056
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ee6a82056 | |||
| 5517662ae2 | |||
| 2a419bb468 | |||
| bf953b7980 | |||
| 033625f041 | |||
| 524527dbd1 | |||
| 1541b82c11 | |||
| 28178c8a73 | |||
| 98559e2010 | |||
| de2ffae641 | |||
| e57d775414 | |||
| 4785d71e0c | |||
| 0a22995055 | |||
| ce008e47da | |||
| 542a8143e2 | |||
| 10174a2915 | |||
| 3522b38394 | |||
| 8c2c3be40c | |||
| 983bc6af26 | |||
| aacbc0e94a | |||
| 722f5205ff | |||
| 01300de076 | |||
| d5d9b1c192 | |||
| e914c17f81 | |||
| c35858239f | |||
| 5ea0f6fa6f | |||
| 5045f83df8 | |||
| 787e215f84 | |||
| 286fc3dd7f | |||
| 4044af4d8d | |||
| 93c1d8f957 | |||
| dcc387ef2c | |||
| 2d3f55097c | |||
| 72504d71ef | |||
| 45e0cd6273 | |||
| a8752ad7a4 | |||
| 06a61ab62c | |||
| 6c58a3ba69 | |||
| b1d9314bc7 | |||
| abde2ae548 | |||
| 24c03ae241 | |||
| a3f9edd48d | |||
| 483aeb7e4d | |||
| 0c183b316e | |||
| 594226320d | |||
| a713d8690a | |||
| f8fcc8ebba | |||
| 1f9915e79d | |||
| 96c411126c | |||
| 9aad6fe511 | |||
| 84110350ff | |||
| 0f64ec4e8f | |||
| 065fa9cda8 | |||
| 7de23c3b24 | |||
| c66fb86ef9 | |||
| 64757031fb | |||
| f48a02c81c | |||
| 4b18a733c9 | |||
| 796c638300 | |||
| f8c6f4e01f | |||
| e2d1ec8c91 | |||
| d92e77cb88 | |||
| a4b5390f80 | |||
| 6d9defce42 | |||
| 92db6e56c9 | |||
| 6a51f123ab | |||
| 9a63adc355 | |||
| a7188186c3 | |||
| a79eb70581 | |||
| fbfcfa65fb | |||
| 20b2fe7684 | |||
| e45aaad1c4 | |||
| a44420cbe7 | |||
| 44b7b6b1b2 | |||
| 79387b5f14 | |||
| a05dc588db | |||
| b080859356 | |||
| fead587b2a | |||
| eec886b5e2 | |||
| 45a6c78d77 | |||
| e80b5bde68 | |||
| 1cd5579bf6 | |||
| 7c7c69255d | |||
| 391bba24c5 | |||
| e887a8ad0d | |||
| 38a024d095 | |||
| 6802a7bf33 | |||
| 9d23e80256 | |||
| e1b3b9d179 | |||
| 30d1a16075 | |||
| 256d351f8e | |||
| 48594a75e6 | |||
| 85a51b13c1 | |||
| 2ae2d6baa8 | |||
| 4a55e53182 | |||
| af0897300d | |||
| cabae7b1fd | |||
| 0635141ac6 | |||
| d9d5947c3b | |||
| cc8b4ce353 | |||
| 0b91da04b3 | |||
| dba146b299 | |||
| 33111615be | |||
| 04e8a41d98 | |||
| 36d76018ba | |||
| 4172fd0463 | |||
| ad0b4a4659 | |||
| 2dab7342f8 | |||
| edd14a0e3d | |||
| 4d7188e1ff | |||
| 255edaca79 | |||
| 8ea716cba8 | |||
| 601de2c565 | |||
| 894524bc81 | |||
| f19bf28f34 | |||
| de3a24a87c |
@@ -1,7 +1,7 @@
|
||||
on:
|
||||
- push
|
||||
|
||||
name: Advent of Code 2021
|
||||
name: Advent of Code 2023
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
@@ -20,27 +20,33 @@ jobs:
|
||||
continue-on-error: ${{ matrix.experimental }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
uses: dtolnay/rust-toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
components: rustfmt
|
||||
|
||||
- name: Set up caching
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: >
|
||||
2023 -> target
|
||||
|
||||
- name: Build binaries
|
||||
working-directory: 2021
|
||||
working-directory: 2023
|
||||
run: >
|
||||
cargo build --all-targets
|
||||
|
||||
- name: Run tests
|
||||
working-directory: 2021
|
||||
working-directory: 2023
|
||||
run: >
|
||||
cargo test
|
||||
|
||||
- name: Run clippy
|
||||
working-directory: 2021
|
||||
- name: Check formatting
|
||||
working-directory: 2023
|
||||
run: >
|
||||
cargo clippy -- --deny warnings
|
||||
cargo fmt --check
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -64,3 +64,6 @@ target/
|
||||
perf.data
|
||||
perf.data.old
|
||||
flamegraph.svg
|
||||
|
||||
# Ignore saved inputs
|
||||
inputs/
|
||||
|
||||
@@ -4,4 +4,4 @@ version = "0.1.0"
|
||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
regex = "0.1"
|
||||
regex = "1"
|
||||
|
||||
@@ -73,10 +73,10 @@ fn main() {
|
||||
let door_label = line.unwrap();
|
||||
let caps = room_pattern.captures(&door_label).unwrap();
|
||||
|
||||
let name = caps.at(1).unwrap();
|
||||
let checksum = caps.at(4).unwrap();
|
||||
let name = caps.get(1).unwrap().as_str();
|
||||
let checksum = caps.get(4).unwrap().as_str();
|
||||
if is_valid(name, checksum) {
|
||||
let sector_id = caps.at(3).unwrap().parse().unwrap();
|
||||
let sector_id = caps.get(3).unwrap().as_str().parse().unwrap();
|
||||
cur_sum += sector_id;
|
||||
|
||||
let decoded: String = name.chars()
|
||||
|
||||
@@ -4,5 +4,5 @@ version = "0.1.0"
|
||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
regex = "^0.1"
|
||||
lazy_static = "^0.2"
|
||||
regex = "1"
|
||||
lazy_static = "1"
|
||||
|
||||
@@ -4,4 +4,4 @@ version = "0.1.0"
|
||||
authors = ["Bert Peters <bert.ljpeters@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
regex="^0.1"
|
||||
regex="1"
|
||||
|
||||
@@ -5,7 +5,7 @@ edition = "2021"
|
||||
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "3.0.0-rc.0", features = ["derive"] }
|
||||
clap = { version = "3", features = ["derive"] }
|
||||
itertools = "0.10"
|
||||
nom = "7"
|
||||
|
||||
|
||||
@@ -20,3 +20,15 @@ OPTIONS:
|
||||
-i, --input <INPUT> Read input from the given file instead of stdin
|
||||
-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
|
||||
|
||||
97
2021/create_timing_plots.py
Executable file
97
2021/create_timing_plots.py
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/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()
|
||||
1
2021/cumulative-time.svg
Normal file
1
2021/cumulative-time.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 16 KiB |
1
2021/individual-time.svg
Normal file
1
2021/individual-time.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 32 KiB |
@@ -90,7 +90,65 @@ where
|
||||
let mut buffer = Vec::new();
|
||||
input.read_to_end(&mut buffer).unwrap();
|
||||
|
||||
let (_, output) = parser(&buffer).finish().unwrap();
|
||||
|
||||
output
|
||||
match parser(&buffer).finish() {
|
||||
Ok((_, output)) => output,
|
||||
Err(err) => {
|
||||
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,69 +1,95 @@
|
||||
use std::collections::HashMap;
|
||||
use std::io::Read;
|
||||
use std::iter::repeat;
|
||||
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::sequence::tuple;
|
||||
use nom::Finish;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::sequence::separated_pair;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::ordered;
|
||||
use crate::common::LineIter;
|
||||
use crate::common::read_input;
|
||||
use crate::common::BitSet;
|
||||
|
||||
type Coord = (u16, u16);
|
||||
|
||||
fn coordinates(input: &str) -> IResult<&str, Coord> {
|
||||
use nom::character::complete;
|
||||
fn coordinates(input: &[u8]) -> IResult<&[u8], Coord> {
|
||||
use nom::character::complete::char;
|
||||
use nom::character::complete::u16;
|
||||
|
||||
let (input, (x, _, y)) = tuple((complete::u16, complete::char(','), complete::u16))(input)?;
|
||||
|
||||
Ok((input, (x, y)))
|
||||
separated_pair(u16, char(','), u16)(input)
|
||||
}
|
||||
|
||||
fn line_definition(input: &str) -> IResult<&str, (Coord, Coord)> {
|
||||
let (input, (begin, _, end)) = tuple((coordinates, tag(" -> "), coordinates))(input)?;
|
||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<(Coord, Coord)>> {
|
||||
let read_line = map(
|
||||
separated_pair(coordinates, tag(" -> "), coordinates),
|
||||
|(begin, end)| ordered(begin, end),
|
||||
);
|
||||
|
||||
// Sorting the coordinates saves trouble later
|
||||
Ok((input, ordered(begin, end)))
|
||||
separated_list1(newline, read_line)(input)
|
||||
}
|
||||
|
||||
fn stripe(
|
||||
map: &mut HashMap<Coord, u16>,
|
||||
once: &mut BitSet,
|
||||
twice: &mut BitSet,
|
||||
width: usize,
|
||||
xs: impl Iterator<Item = u16>,
|
||||
ys: impl Iterator<Item = u16>,
|
||||
) {
|
||||
for (x, y) in xs.zip(ys) {
|
||||
*map.entry((x, y)).or_default() += 1;
|
||||
let index = x as usize + y as usize * width;
|
||||
if !once.insert(index) {
|
||||
twice.insert(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn part_common(input: &mut dyn Read, diagonals: bool) -> String {
|
||||
let mut reader = LineIter::new(input);
|
||||
let mut map = HashMap::new();
|
||||
let lines = read_input(input, parse_input);
|
||||
|
||||
while let Some(line) = reader.next() {
|
||||
let (begin, end) = line_definition(line).finish().unwrap().1;
|
||||
let width = lines
|
||||
.iter()
|
||||
.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 {
|
||||
let y_range = begin.1..=end.1;
|
||||
stripe(&mut map, repeat(begin.0), y_range);
|
||||
stripe(
|
||||
&mut once_map,
|
||||
&mut twice_map,
|
||||
width,
|
||||
repeat(begin.0),
|
||||
y_range,
|
||||
);
|
||||
} else if begin.1 == end.1 {
|
||||
let x_range = begin.0..=end.0;
|
||||
stripe(&mut map, x_range, repeat(begin.1));
|
||||
stripe(
|
||||
&mut once_map,
|
||||
&mut twice_map,
|
||||
width,
|
||||
x_range,
|
||||
repeat(begin.1),
|
||||
);
|
||||
} else if diagonals {
|
||||
let x_range = begin.0..=end.0;
|
||||
let y_range = (begin.1.min(end.1))..=(begin.1.max(end.1));
|
||||
|
||||
if begin.1 > end.1 {
|
||||
// For a downward slope we need to reverse Y
|
||||
stripe(&mut map, x_range, y_range.rev());
|
||||
stripe(&mut once_map, &mut twice_map, width, x_range, y_range.rev());
|
||||
} else {
|
||||
stripe(&mut map, x_range, y_range);
|
||||
stripe(&mut once_map, &mut twice_map, width, x_range, y_range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map.values().filter(|&&v| v > 1).count().to_string()
|
||||
twice_map.len().to_string()
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
@@ -82,11 +108,6 @@ mod tests {
|
||||
|
||||
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]
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE, 5)
|
||||
|
||||
@@ -48,7 +48,7 @@ fn parse_fold(input: &[u8]) -> IResult<&[u8], Fold> {
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn apply_fold(dots: &mut Vec<Coords>, fold: Fold) {
|
||||
fn apply_fold(dots: &mut [Coords], fold: Fold) {
|
||||
match fold {
|
||||
Fold::X(coord) => dots.iter_mut().for_each(|(x, _)| {
|
||||
if *x >= coord {
|
||||
|
||||
@@ -182,7 +182,7 @@ mod tests {
|
||||
fn sample_part1() {
|
||||
let answers = [16, 12, 23, 31];
|
||||
|
||||
for (&sample, answer) in SAMPLE.into_iter().zip(answers) {
|
||||
for (&sample, answer) in SAMPLE.iter().zip(answers) {
|
||||
test_implementation(part1, sample, answer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::io::Read;
|
||||
use std::ops::Add;
|
||||
use std::ops::Deref;
|
||||
use std::ops::Sub;
|
||||
|
||||
use nom::bytes::complete::tag;
|
||||
@@ -23,6 +25,10 @@ impl Point3 {
|
||||
pub fn manhattan(&self) -> i32 {
|
||||
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 {
|
||||
@@ -49,6 +55,44 @@ 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> {
|
||||
points: &'a [Point3],
|
||||
axes: [usize; 3],
|
||||
@@ -119,32 +163,56 @@ fn parse_point(input: &[u8]) -> IResult<&[u8], Point3> {
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Vec<Point3>>> {
|
||||
fn parse_input(input: &[u8]) -> IResult<&[u8], Vec<Scanner>> {
|
||||
use nom::character::complete::i32;
|
||||
let parse_header = delimited(tag("--- scanner "), i32, tag(" ---\n"));
|
||||
|
||||
let parse_scanner = preceded(parse_header, many1(terminated(parse_point, newline)));
|
||||
let parse_scanner = map(
|
||||
preceded(parse_header, many1(terminated(parse_point, newline))),
|
||||
Scanner::new,
|
||||
);
|
||||
separated_list1(newline, parse_scanner)(input)
|
||||
}
|
||||
|
||||
fn try_overlap(
|
||||
correct: &[(Point3, HashSet<Point3>)],
|
||||
candidate: &[Point3],
|
||||
) -> Option<(Point3, Vec<Point3>)> {
|
||||
let mut relative = HashSet::new();
|
||||
fn find_pivot(group: &Scanner, related: &Scanner) -> Option<Point3> {
|
||||
let mut counter = HashMap::new();
|
||||
|
||||
for (distance, &(a, b)) in &group.distances {
|
||||
if related.distances.contains_key(distance) {
|
||||
*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 &start in &rot {
|
||||
relative.clear();
|
||||
let translated_iter = rot.iter().map(|&other| other - start);
|
||||
|
||||
relative.extend(rot.iter().map(|&other| other - start));
|
||||
|
||||
if let Some((base, _)) = correct.iter().find(|(_, correct_relative)| {
|
||||
correct_relative.intersection(&relative).count() >= 12
|
||||
}) {
|
||||
if translated_iter
|
||||
.clone()
|
||||
.filter(|p| correct.contains(p))
|
||||
.count()
|
||||
>= 12
|
||||
{
|
||||
// Found a solution, build the correct output
|
||||
let translated = relative.drain().map(|point| point + *base).collect();
|
||||
let translated = translated_iter.map(|point| point + matched_pivot).collect();
|
||||
|
||||
return Some((start - *base, translated));
|
||||
return Some((start - matched_pivot, Scanner::new(translated)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,33 +225,30 @@ fn parts_common(input: &mut dyn Read) -> (HashSet<Point3>, Vec<Point3>) {
|
||||
|
||||
let mut points: HashSet<_> = scanners[0].iter().copied().collect();
|
||||
|
||||
let mut todo = vec![std::mem::take(&mut scanners[0])];
|
||||
let mut todo = vec![scanners.remove(0)];
|
||||
let mut scanners_found = vec![Point3::default()];
|
||||
|
||||
while let Some(matched) = todo.pop() {
|
||||
if scanners.iter().all(Vec::is_empty) {
|
||||
if scanners.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
let relative: Vec<(Point3, HashSet<Point3>)> = matched
|
||||
.iter()
|
||||
.map(|&base| (base, matched.iter().map(|&other| (other - base)).collect()))
|
||||
.collect();
|
||||
let mut i = 0;
|
||||
|
||||
for candidate in &mut scanners {
|
||||
if candidate.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some((scanner, result)) = try_overlap(&relative, candidate) {
|
||||
while i < scanners.len() {
|
||||
if let Some((scanner, result)) = try_overlap(&matched, &scanners[i]) {
|
||||
scanners.remove(i);
|
||||
scanners_found.push(scanner);
|
||||
points.extend(result.iter().copied());
|
||||
todo.push(result);
|
||||
candidate.clear();
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert!(scanners.is_empty());
|
||||
|
||||
(points, scanners_found)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,124 @@
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::Display;
|
||||
use std::io::Read;
|
||||
use std::mem::swap;
|
||||
use std::ops::Index;
|
||||
|
||||
use crate::common::BitSet;
|
||||
|
||||
type Translation = [bool; 512];
|
||||
type Point = (i32, i32);
|
||||
type Field = HashSet<Point>;
|
||||
|
||||
struct Field {
|
||||
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) {
|
||||
let mut buffer = Vec::new();
|
||||
@@ -19,67 +133,16 @@ fn read_input(input: &mut dyn Read) -> (Translation, Field) {
|
||||
.zip(it.next().unwrap())
|
||||
.for_each(|(t, &c)| *t = c == b'#');
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
let field = Field::from_input(it.skip(1));
|
||||
|
||||
(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 {
|
||||
let (translation, mut field) = read_input(input);
|
||||
let mut new_field = Field::new();
|
||||
let mut infinity = false;
|
||||
|
||||
for _ in 0..count {
|
||||
advance(&translation, &field, &mut new_field, &mut infinity);
|
||||
swap(&mut field, &mut new_field);
|
||||
field.advance(&translation);
|
||||
}
|
||||
|
||||
field.len().to_string()
|
||||
|
||||
@@ -1,9 +1,451 @@
|
||||
use std::cmp::Reverse;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::BinaryHeap;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::io::Read;
|
||||
use std::mem::swap;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
use crate::common::LineIter;
|
||||
|
||||
type Item<const S: usize> = (u32, State<S>);
|
||||
type Todo<const S: usize> = BinaryHeap<Reverse<Item<S>>>;
|
||||
type Visited<const S: usize> = HashMap<State<S>, u32>;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
|
||||
enum Pod {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
}
|
||||
|
||||
pub fn part2(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
impl Pod {
|
||||
pub fn cost(self) -> u32 {
|
||||
match self {
|
||||
Pod::A => 1,
|
||||
Pod::B => 10,
|
||||
Pod::C => 100,
|
||||
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 {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(c: char) -> Result<Self, Self::Error> {
|
||||
match c {
|
||||
'A' => Ok(Pod::A),
|
||||
'B' => Ok(Pod::B),
|
||||
'C' => Ok(Pod::C),
|
||||
'D' => Ok(Pod::D),
|
||||
_ => Err("Invalid pod"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
|
||||
struct State<const S: usize> {
|
||||
hallway: [Option<Pod>; 11],
|
||||
rooms: [[Option<Pod>; S]; 4],
|
||||
}
|
||||
|
||||
fn room_hallway_pos(room: usize) -> usize {
|
||||
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 {
|
||||
self == &State {
|
||||
hallway: Default::default(),
|
||||
rooms: [
|
||||
[Some(Pod::A); S],
|
||||
[Some(Pod::B); S],
|
||||
[Some(Pod::C); S],
|
||||
[Some(Pod::D); S],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
fn add_to_queue(self, cost: u32, todo: &mut Todo<S>, visited: &mut Visited<S>) {
|
||||
let entry = visited.entry(self.clone());
|
||||
|
||||
if matches!(&entry, Entry::Occupied(entry) if *entry.get() <= cost) {
|
||||
// Already got a better one
|
||||
return;
|
||||
}
|
||||
|
||||
// nightly only :'(
|
||||
// entry.insert(cost);
|
||||
*entry.or_default() = cost;
|
||||
|
||||
todo.push(Reverse((cost + self.estimate(), self)))
|
||||
}
|
||||
|
||||
fn estimate(&self) -> u32 {
|
||||
// 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.
|
||||
|
||||
// Cost to enter the hole for all pods that still need to
|
||||
let enter_estimate: u32 = self
|
||||
.rooms
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, room)| {
|
||||
let pod = Pod::try_from(index).unwrap();
|
||||
|
||||
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() {
|
||||
// Check if we even want to move anything out of this room
|
||||
if room
|
||||
.iter()
|
||||
.all(|entry| entry.map(|pod| pod.dest() == index).unwrap_or(true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let (pos, pod) = room
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(pos, entry)| entry.map(|pod| (pos, pod)))
|
||||
.unwrap(); // Safe unwrap, we know it exists from above.
|
||||
|
||||
let base_cost = 1 + pos;
|
||||
let hallway_pos = room_hallway_pos(index);
|
||||
|
||||
let mut queue_new = |new_pos, new_cost| {
|
||||
let mut new_state = self.clone();
|
||||
swap(
|
||||
&mut new_state.hallway[new_pos],
|
||||
&mut new_state.rooms[index][pos],
|
||||
);
|
||||
|
||||
new_state.add_to_queue(new_cost + 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
|
||||
for new_pos in hallway_pos..self.hallway.len() {
|
||||
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 + 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> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let helper = |opt_pod| match opt_pod {
|
||||
Some(Pod::A) => 'A',
|
||||
Some(Pod::B) => 'B',
|
||||
Some(Pod::C) => 'C',
|
||||
Some(Pod::D) => 'D',
|
||||
None => '.',
|
||||
};
|
||||
writeln!(f, "#############")?;
|
||||
write!(f, "#")?;
|
||||
|
||||
for entry in self.hallway {
|
||||
write!(f, "{}", helper(entry))?;
|
||||
}
|
||||
writeln!(f, "#")?;
|
||||
|
||||
for i in 0..S {
|
||||
writeln!(
|
||||
f,
|
||||
" #{}#{}#{}#{}#",
|
||||
helper(self.rooms[0][i]),
|
||||
helper(self.rooms[1][i]),
|
||||
helper(self.rooms[2][i]),
|
||||
helper(self.rooms[3][i])
|
||||
)?;
|
||||
}
|
||||
|
||||
write!(f, " #########")
|
||||
}
|
||||
}
|
||||
|
||||
fn read_input(input: &mut dyn Read) -> State<2> {
|
||||
let mut reader = LineIter::new(input);
|
||||
let mut state = State {
|
||||
hallway: Default::default(),
|
||||
rooms: Default::default(),
|
||||
};
|
||||
|
||||
let _ = reader.next();
|
||||
let _ = reader.next();
|
||||
|
||||
let mut helper = |idx: usize| {
|
||||
reader
|
||||
.next()
|
||||
.unwrap()
|
||||
.chars()
|
||||
.filter_map(|c| Pod::try_from(c).ok())
|
||||
.zip(&mut state.rooms)
|
||||
.for_each(|(pod, room)| room[idx] = Some(pod))
|
||||
};
|
||||
|
||||
helper(0);
|
||||
helper(1);
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
pub fn part1(input: &mut dyn Read) -> String {
|
||||
let state = read_input(input);
|
||||
|
||||
state.solve().to_string()
|
||||
}
|
||||
|
||||
pub fn part2(input: &mut dyn Read) -> String {
|
||||
let state2 = read_input(input);
|
||||
|
||||
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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::test_implementation;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/23.txt");
|
||||
|
||||
#[test]
|
||||
fn test_is_done() {
|
||||
let state = State {
|
||||
hallway: Default::default(),
|
||||
rooms: [
|
||||
[Some(Pod::A); 2],
|
||||
[Some(Pod::B); 2],
|
||||
[Some(Pod::C); 2],
|
||||
[Some(Pod::D); 2],
|
||||
],
|
||||
};
|
||||
|
||||
assert!(state.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
test_implementation(part1, SAMPLE, 12521);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
test_implementation(part2, SAMPLE, 44169);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,159 @@
|
||||
//! 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;
|
||||
|
||||
pub fn part1(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn part2(_input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
fn parse_step(input: &[u8]) -> IResult<&[u8], Step> {
|
||||
use nom::character::complete::i32;
|
||||
|
||||
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)]
|
||||
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);
|
||||
}
|
||||
|
||||
5
2021/src/samples/23.txt
Normal file
5
2021/src/samples/23.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
#############
|
||||
#...........#
|
||||
###B#C#B#D###
|
||||
#A#D#C#A#
|
||||
#########
|
||||
30
2022/Cargo.toml
Normal file
30
2022/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
||||
[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]
|
||||
ahash = "0.8.2"
|
||||
anyhow = "1.0.66"
|
||||
clap = { version = "4.0.19", features = ["derive"] }
|
||||
itertools = "0.11"
|
||||
ndarray = "0.15.6"
|
||||
nom = "7.1.1"
|
||||
strength_reduce = "0.2.4"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.5.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
|
||||
20
2022/README.md
Normal file
20
2022/README.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# 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
|
||||
```
|
||||
43
2022/benches/days.rs
Normal file
43
2022/benches/days.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
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) -> std::io::Result<Vec<u8>> {
|
||||
let input_path = format!("inputs/{day:02}.txt");
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
File::open(input_path)?.read_to_end(&mut buffer)?;
|
||||
|
||||
Ok(buffer)
|
||||
}
|
||||
|
||||
pub fn benchmark_days(c: &mut Criterion) {
|
||||
for day in 1..=DAYS_IMPLEMENTED {
|
||||
if let Ok(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);
|
||||
0
2022/inputs/.gitkeep
Normal file
0
2022/inputs/.gitkeep
Normal file
2259
2022/inputs/01.txt
Normal file
2259
2022/inputs/01.txt
Normal file
File diff suppressed because it is too large
Load Diff
2500
2022/inputs/02.txt
Normal file
2500
2022/inputs/02.txt
Normal file
File diff suppressed because it is too large
Load Diff
300
2022/inputs/03.txt
Normal file
300
2022/inputs/03.txt
Normal file
@@ -0,0 +1,300 @@
|
||||
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
Normal file
1000
2022/inputs/04.txt
Normal file
File diff suppressed because it is too large
Load Diff
514
2022/inputs/05.txt
Normal file
514
2022/inputs/05.txt
Normal file
@@ -0,0 +1,514 @@
|
||||
[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
2022/inputs/06.txt
Normal file
1
2022/inputs/06.txt
Normal file
@@ -0,0 +1 @@
|
||||
grvrnvrnnjljbjqjpqjjvhhzwwrbwwbblrltrrpbbbbqnnqbbbbsvbvmbvmbbrsrqrzrllwbbbqzqrqnqrnrjnnjccdggwqqhrrjcjmjmllgrlglhlclmlvlvsshwwsggmfmdfddgdfftrrczrcczhzppgdgrdggghmmdwwqgggslglfgfcgccmjcjwjrwjrjcrjjsgjjvddpwpgpbbgwbgwwhnhfftbffhpfphhfqfrqfrfnfpprvrsrhrfrllfhhrsrhssvfsvsnvsnsswtwtlthllrjjwddtggzczgcchwcwppfbbdvdrdzrdrvrwwsbsfbssqfsfjsjcscttlztllgjjlbbdsdtssvvvwlvlqqnhqqtdqtddjcdcjjpbphhgtgtqtzqqzhqqtgtvtmvtvrvqrvvfmfmppzzbwwnddzttfpfrrlddbppfqppnwnswwdhwdwjjqljqqthtnhnddgmgcmgcmgcmmfmfttrzzfdzztllmjlllgcgbbcqcvccpnndbdjbjmmzbztzptzpprpddptpprhhvlvmlmpmmljjnnjsjfjjvgjjvzzfgfzfbftbftttgstgstgtpggflfcfqqtctltgltldlzdlzzmmlddnvddzfddppmnpptzptpvttwstwswvwrvvbfbjjjbmjjdvdvrvdddrwrhrzrqqhghhrwhwhrrmppsgpsgszzdfdfwwmtwtvwvgvffmqqqtqntqnnjcncbnbwnnzggrdrqqjbqjjwjqqqwlqwlwzlljhhfsfsqsrqqhwqqwbbqbvvlflrrlglbbjhhjmhjjcmcjcgczcfcgcqqczcnnvjnnlddmpmcppgvgjgddvrrnsnmnqmqgmmnppwgwcgwgssbddgtdgdgmdgmgvvmjmvmjmvvsfssdgdghdggbfbqbdbjbsbmmrpmrprggbllwrwpwtppzvppzsssdnsdnnvnhvvvzvfzfqqnnmlnltldtdvdbdblddsmmlccmlmvlmvmmcsctctrtsrstsbsrshsddlmddmppgsscttnrtrqqcvcwwlnlznnnvcnvvtnvnbnmbmvmppjgjdjtddmpdmdvvmgvvdqdlqlhhzccsggjdjsdsttctjctjtfjttppdzpzzbjbwwmwbblslzslzszlzrrcbrrfggvcczjjtbbdnnggbwblwlbwlwqqfvfqfddrrfccvlllhmhhhrthrthrrnbnzbbpzplphprrrnbbghhnshnhbblqqqvwwffnmnmhhtccpqpvqvbvnvvfnfsnffdjdllwffcddgcgrgjrggchcpcddtbbdtdmtdmmhhtphtpppclcpcvcjvcjjfqfzqqphpnhnrnhhpdhhtfhhbbmqmfmsmvssgqqfssqgglnnqmnmbnmbbllrdrgdrdvrdvdsvvnddgtgddcdqdsqdqbqqlhhwdhdgdcgcdchchrchhpvvpgvgrrfggwfwgmpddbhfngtrwswfszgsggnpsntjpslrpjqsffzrlnbnzdtqpqtjzwlhhgrsrbvnccnsjmzcbqgcbtbqlzhnpnhhrrvqwjwzzvrlcrmjhcscrqhpqmfzbnvcwwqhcjjlnggmpbwztzfswmsbjshnsgfmdlzvzczhrdwgwbghszpnbfpctrshbfhspsczcqcrrqcpwwpfzhjqtpqgjbztrpzrlgfdjbmlwdvlvnfmdzbwsbbhlbszvwcpztlchjrqbmsftltmqpfgdpmdgjvwqqtjsqlfqrwmsnlqgsbqfwsdnfvzthmbplvszfcmlptlcjpnfpjsphsmmjplwjqphgvzbtbjtpttqhlwtgnrjvmvsfsztmsqszzlhqqhfslsvhzgtsssfctzgsqbgdzlpwbsmpcnjqshhhcwqdsdzdhnjfqzqnqdlrpddcgrgldgqbjmdtwgppdczzrjvmcfqjbpjzbtjmgdphlbwnsnpfdqlhwvvmpwzsrztnwvtlbphljmjwsgbphgmwhdmfhpvsmvsjccjhfvqtvfmmlnggncltvtrgmbtfqsvfnlvcmjnjwzcrpjnsgntvhjbtdlptshbhhchqmsprhqzdnfpjqccdfvnzjtlbsmmwvzlwlvmsbrnhqctvtvbfhntdctjnrbcrrlmsnwbbjbcbbgrrhfqwzwwfgvsvgbwnttghtgpspzwzfhffsqjvwwttntnvlwftsfvtttgnprzrzsghvjrdtsfdvzswhmrfcdqsgvrlhzbnvbmjlqrftnnbtwqtvlvwznfbslhdqjbntdgpprfqchjvgvzjssdztjlzwfljjmfvzrbbtczggzqwrnqqgzzcbqjcpfqfrbwtdjrrvbszsjdjcpdfjscsvnltcgwvqsgnhbfgnfnddnpmbzbptrmvqzpvbdpfdvtlmgnnjwflgdbfnmvsdnmlvgcpwflwvdbtbfwtfpsmqsplnzwlwgvbjrhghwrnrswsggbqpdjcjrgbgnsqdvwzzwftvjqgjzzcdvpbbjzpphmbcqmrjvgqwfgrsnqvhwflmhgrlvbpwdcsrlqwfrwppqbrdhwqtvczpclpsbsjcptgblbbsqmbhjjgzwvlcnhnzcttmpjsgchmppgphqlzlcsqcgbbjgtjjvmttdztfdptzgvmpnqrcmpmcdlpnbztllvqbggqbqhlqvdwsrwzsjwfrqvcbvsgfdptmrzpvdfblmhlzrvpmsljlqqzrhlnmwncpfhvqlsbtrjbfcrnfvjvddrhdbbczjdsrdvzlbqrccssdzcpmdsqbprjppfzdwfdswptgzcmjqfhcwsqfqhvrslffqfbcvhdzljzrmtwmfdwzdhhjcmbjtvjhzzwfqhrcslztdbnlwmmhbbbgdscjcdzftnchqfnflnsdqjscfrqpnfbftpzvtmrwncqfqqflschpfnjsjlqcjdjgtwpqhgcnjdmnnvmmpwdspmnrgqrptqwcvbtdwpqlbtwpqgwgfrzlrhtvrvzhmhmwhfdsrhpcczqfltsgtgrfwcvlcvtlhqqwnrqgzpnzbfmzbdwqwbsfvbshrgzqdbgvrhzhzlbqsfzttmsnmrqmwgtzbvdqdrbgcpclzjrhdbjtpcdbbznjgtbwbqrnpvffdmwtrbhhstcmnjcwbbnmpbvmjprtzgcptmtrffwhvfgdljnrbbrblbfbgdwtjrtgqgrpvpgjqrjzczvvlspgdbzftqgqvgdqlglbgvgjdcztznszcwfqhmwbrbjcfstzdcmdsssqfhtzpdgmzjscvbdzgbhhgdqgvfwrzmhdrhlsvlzjjzbzdljcbhncppwrtptjgszlqsrqpzqcsgvdvzmgvwgsncnbffttslphcstqvfwbwzbflmshcbnhpljgqwmmwwzlgpbcqnrtqlwcjcrclfdrnnmvtbfdztdfvtqrsgdptfcfpzpsldhzmrngggfvdqggtlfqqwsldprcffsstnnpmsbbvghdbpprqbssnprdbqclzqtgsrczwcvqwrrfmmfwsndvtvqljwwglrgbphdvvwgctbbmtrbpzqtspgrlhmnhjcdwhwvssgspzjbcfjttjqbdpdmptfzzjcfqljpqddfssmffqprvbptfvdshsdmfmdtmlbnmbmjjjsgmlmwmgcwhbrbgchrstptvdlqgddfzddlzhwjmsvvcjwvqtzjtsctfmzchlbrvlgdzbvdlbfpvhptpltrdmcgjghcpwvwqqnrzdtnmgdncplhdpsgpnbprbgshffwwsdhpgqsbmwdtpnhhltlcqfrjtswcchzvlhdgrmjwhgwppdjqlgmdhwbllqvzrchgclmqdlghjsvmwlflmhhmdzbfjhjnvwphnjbclmdpgflqgtfsmsjslntfcmtbphnrgpdcqtjzjttdtgjmvhzsrfnrjqssvwpcslpfstbpfsrsntmftmdgsqrrsnddqfmchrhtlhmqndvvllnvltdzfphjqnvmcdsgfpcmjftgdpntjzplqljhtthvnbzbzwvfnqsjvnfwhmtbsspjslgfjvdgfjpwrsgqwntntjcqtdgnhnsfwhhqfwbwhdrftj
|
||||
983
2022/inputs/07.txt
Normal file
983
2022/inputs/07.txt
Normal file
@@ -0,0 +1,983 @@
|
||||
$ 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
|
||||
99
2022/inputs/08.txt
Normal file
99
2022/inputs/08.txt
Normal file
@@ -0,0 +1,99 @@
|
||||
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
|
||||
2000
2022/inputs/09.txt
Normal file
2000
2022/inputs/09.txt
Normal file
File diff suppressed because it is too large
Load Diff
140
2022/inputs/10.txt
Normal file
140
2022/inputs/10.txt
Normal file
@@ -0,0 +1,140 @@
|
||||
noop
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -12
|
||||
addx 18
|
||||
addx -1
|
||||
noop
|
||||
addx 3
|
||||
addx 5
|
||||
addx -5
|
||||
addx 7
|
||||
noop
|
||||
addx -36
|
||||
addx 18
|
||||
addx -16
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx 13
|
||||
addx -6
|
||||
addx -4
|
||||
addx 5
|
||||
addx 2
|
||||
addx 4
|
||||
addx -3
|
||||
addx 2
|
||||
noop
|
||||
addx 3
|
||||
addx 2
|
||||
addx 5
|
||||
addx -40
|
||||
addx 25
|
||||
addx -22
|
||||
addx 25
|
||||
addx -21
|
||||
addx 5
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx 19
|
||||
addx -10
|
||||
addx -4
|
||||
noop
|
||||
addx -4
|
||||
addx 7
|
||||
noop
|
||||
addx 3
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx -26
|
||||
addx 27
|
||||
addx -36
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 4
|
||||
addx 6
|
||||
noop
|
||||
addx 12
|
||||
addx -11
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 5
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx -38
|
||||
noop
|
||||
addx 9
|
||||
addx -4
|
||||
noop
|
||||
noop
|
||||
addx 7
|
||||
addx 10
|
||||
addx -9
|
||||
addx 2
|
||||
noop
|
||||
addx -9
|
||||
addx 14
|
||||
addx 5
|
||||
addx 2
|
||||
addx -24
|
||||
addx 25
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx -30
|
||||
addx 31
|
||||
addx -38
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
addx 21
|
||||
addx -16
|
||||
addx 8
|
||||
addx -4
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx -2
|
||||
addx 5
|
||||
addx 3
|
||||
addx -1
|
||||
addx -1
|
||||
addx 4
|
||||
addx 5
|
||||
addx -38
|
||||
noop
|
||||
55
2022/inputs/11.txt
Normal file
55
2022/inputs/11.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
Monkey 0:
|
||||
Starting items: 84, 66, 62, 69, 88, 91, 91
|
||||
Operation: new = old * 11
|
||||
Test: divisible by 2
|
||||
If true: throw to monkey 4
|
||||
If false: throw to monkey 7
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 98, 50, 76, 99
|
||||
Operation: new = old * old
|
||||
Test: divisible by 7
|
||||
If true: throw to monkey 3
|
||||
If false: throw to monkey 6
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 72, 56, 94
|
||||
Operation: new = old + 1
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 4
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 55, 88, 90, 77, 60, 67
|
||||
Operation: new = old + 2
|
||||
Test: divisible by 3
|
||||
If true: throw to monkey 6
|
||||
If false: throw to monkey 5
|
||||
|
||||
Monkey 4:
|
||||
Starting items: 69, 72, 63, 60, 72, 52, 63, 78
|
||||
Operation: new = old * 13
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 7
|
||||
|
||||
Monkey 5:
|
||||
Starting items: 89, 73
|
||||
Operation: new = old + 5
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 6:
|
||||
Starting items: 78, 68, 98, 88, 66
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 11
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 5
|
||||
|
||||
Monkey 7:
|
||||
Starting items: 70
|
||||
Operation: new = old + 7
|
||||
Test: divisible by 5
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 3
|
||||
41
2022/inputs/12.txt
Normal file
41
2022/inputs/12.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
abcccccccaaaaaccccaaaaaaaccccccccccccccccccccccccccccccccccccaaaaa
|
||||
abaacccaaaaaaccccccaaaaaaaaaaaaaccccccccccccccccccccccccccccaaaaaa
|
||||
abaacccaaaaaaaccccaaaaaaaaaaaaaacccccccccccccaacccccccccccccaaaaaa
|
||||
abaacccccaaaaaacaaaaaaaaaaaaaaaacccccccccccccaacccccccccccccacacaa
|
||||
abaccccccaaccaacaaaaaaaaaacccaacccccccccccccaaacccccccccccccccccaa
|
||||
abcccccccaaaacccaaaaaaaaacccccccccccccaaacccaaacccccccccccccccccaa
|
||||
abccccccccaaaccccccccaaaacccccccccccccaaaaacaaaccacacccccccccccccc
|
||||
abccccccccaaacaaacccccaaacccccccccccccaaaaaaajjjjjkkkcccccaacccccc
|
||||
abcccccaaaaaaaaaacccccaaccccccccccciiiiiijjjjjjjjjkkkcaaaaaacccccc
|
||||
abcccccaaaaaaaaacccccccccccccccccciiiiiiijjjjjjjrrkkkkaaaaaaaacccc
|
||||
abcccccccaaaaaccccccccccccccccccciiiiiiiijjjjrrrrrppkkkaaaaaaacccc
|
||||
abcccaaccaaaaaacccccccccccaacaaciiiiqqqqqrrrrrrrrpppkkkaaaaaaacccc
|
||||
abccaaaaaaaaaaaaccccacccccaaaaaciiiqqqqqqrrrrrruuppppkkaaaaacccccc
|
||||
abcccaaaaaaacaaaacaaacccccaaaaaahiiqqqqtttrrruuuuupppkkaaaaacccccc
|
||||
abcaaaaaaaccccaaaaaaacccccaaaaaahhqqqtttttuuuuuuuuuppkkkccaacccccc
|
||||
abcaaaaaaaaccccaaaaaacccccaaaaaahhqqqtttttuuuuxxuuuppkklcccccccccc
|
||||
abcaaaaaaaacaaaaaaaaaaacccccaaachhhqqtttxxxuuxxyyuuppllllccccccccc
|
||||
abcccaaacaccaaaaaaaaaaaccccccccchhhqqtttxxxxxxxyuupppplllccccccccc
|
||||
abaacaacccccaaaaaaaaaaaccccccccchhhqqtttxxxxxxyyvvvpppplllcccccccc
|
||||
abaacccccccccaaaaaaacccccccccccchhhpppttxxxxxyyyvvvvpqqqlllccccccc
|
||||
SbaaccccccaaaaaaaaaaccccccccccchhhppptttxxxEzzyyyyvvvqqqlllccccccc
|
||||
abaaaaccccaaaaaaaaacccccccccccchhhpppsssxxxyyyyyyyyvvvqqqlllcccccc
|
||||
abaaaacccccaaaaaaaacccccccccccgggpppsssxxyyyyyyyyyvvvvqqqlllcccccc
|
||||
abaaacccaaaacaaaaaaaccccccccccgggpppsswwwwwwyyyvvvvvvqqqllllcccccc
|
||||
abaaccccaaaacaaccaaaacccccccccgggppssswwwwwwyyywvvvvqqqqmmmccccccc
|
||||
abaaccccaaaacaaccaaaaccaaaccccggpppssssswwswwyywvqqqqqqmmmmccccccc
|
||||
abcccccccaaacccccaaacccaaacaccgggpppssssssswwwwwwrqqmmmmmccccccccc
|
||||
abcccccccccccccccccccaacaaaaacgggppooosssssrwwwwrrrmmmmmcccccccccc
|
||||
abcccccccccccccccccccaaaaaaaacggggoooooooorrrwwwrrnmmmdddccaaccccc
|
||||
abaccccccccccccaacccccaaaaaccccggggoooooooorrrrrrrnmmddddcaaaccccc
|
||||
abaccccccccaaaaaaccccccaaaaaccccggfffffooooorrrrrnnndddddaaaaccccc
|
||||
abaacccccccaaaaaacccccaaaaaacccccffffffffoonrrrrrnnndddaaaaaaacccc
|
||||
abaaccccccccaaaaaaaccacaaaacccccccccffffffonnnnnnnndddaaaaaaaacccc
|
||||
abccccccccccaaaaaaaaaaaaaaaccccccccccccfffennnnnnnddddccaaaccccccc
|
||||
abcccccccccaaaaaaacaaaaaaaaaacccccccccccffeennnnnedddccccaaccccccc
|
||||
abcccccccccaaaaaaccaaaaaaaaaaaccccccccccaeeeeeeeeeedcccccccccccccc
|
||||
abccccccccccccaaaccaaaaaaaaaaaccccccccccaaaeeeeeeeecccccccccccccaa
|
||||
abcccccccaaccccccccaaaaaaaacccccccccccccaaaceeeeecccccccccccccccaa
|
||||
abaaccaaaaaaccccccccaaaaaaaacccccccccccccaccccaaacccccccccccaaacaa
|
||||
abaaccaaaaacccccaaaaaaaaaaacccccccccccccccccccccacccccccccccaaaaaa
|
||||
abaccaaaaaaaaccaaaaaaaaaaaaaacccccccccccccccccccccccccccccccaaaaaa
|
||||
449
2022/inputs/13.txt
Normal file
449
2022/inputs/13.txt
Normal file
@@ -0,0 +1,449 @@
|
||||
[[[],[],8,3],[10]]
|
||||
[[[[7],[0,4,6,1]],[[2,1,5,3,6],[]],[3,[10,9,1],2,[10,6,10],7],2,7],[5,[3],7,10,[8,[4,7,1,7,8],[],1,[8,6]]],[5,7,[[5,5,7,2,10],[8,7,10,4,7],[9,4,9,9,1]],[[8],8,5,[7,3,4,6,1],1]]]
|
||||
|
||||
[[[5,5,[0,7,6,6,0]],[],0,9],[[[0,7,3,10,5],5],7],[10,[],1,[],5]]
|
||||
[[4],[2,[10,[5,7,8,7,0]],[4,8,[1,2],[5]],3,9],[[[3,3,3,5,4],5,[],7,[7,3,10,4,0]],9,[3]],[2,0,6,[9,5],8],[[4,[9,8,6],[],5],3,[7,7,[3,3,6],7,[9,4,0,10,6]],10,[]]]
|
||||
|
||||
[[2],[3,[[],[1]],[],[0,[10,7]]],[[]],[7,[6],8,[9,0],[2]]]
|
||||
[[[[],7,8]]]
|
||||
|
||||
[[],[[],8,5],[4,9,[[8,4,7,6,9],[4]],3,[[0,3,4,3,1]]],[3,5,[[0,6,4],5,[1,5,6],6,[8,7,1,7]]],[1]]
|
||||
[[8]]
|
||||
|
||||
[[],[[3,3,[7,0,9],1],3],[[[10,7,6],8,0,0],10],[[3,4],[0,10,[1,6,1,5,1],[]]],[[[10,10],[9,7,3]],2]]
|
||||
[[10,0,4,[1,1,[4,10,5,7],10]],[[],[3,5,[5,5],[],[1,0,4,9]],0],[[]]]
|
||||
|
||||
[[[[10,7,1],0],[7,[4,9,3],[0],[]],[],8],[[[6,3,2],[4,6,0]],[4,2,[0,2]]],[[],1,6,2,[2,[10,10,4,9],0,[7,1,0,7,6]]],[9,3]]
|
||||
[[[[4,4,2,2],[5,0]]],[5]]
|
||||
|
||||
[[],[[5,6,[],[7]]],[7]]
|
||||
[[10,6,9],[[9,4],[5,4,4,[2,2,8],5],10,[[]],9],[]]
|
||||
|
||||
[[[],[2,6,[],[4],[0,5,6,7,4]],4,9,3],[],[[[6],7,9],[],9],[[[1,5,0,4],4,[2,9,3,3,7]],1],[10,2,2,[[0,6,8,4],[9,3,8,5],3,5,3]]]
|
||||
[[],[3],[[[],[],[10,1,2],[],[1]],0,9,[]]]
|
||||
|
||||
[[0,[6,[10,0,0,4],[6,6]],[],7,[8,[2,6,8,6,10],5,7,0]]]
|
||||
[[[6,[7,6,9]],8,[4,1,[4,7,2]]],[[],8],[[2,[0],0,8],1,8,[6,4,1,[3,3],6],[[9,8,4,1],[5,7],9]],[[[3],5],2,5],[9,[[8],3]]]
|
||||
|
||||
[[],[2,[4,[6,2,10,7,7],[]]],[7,[7,[1,7]],[[9,2,8,10,8]]],[5,[[0,10,10]],[1],1,[[],10,0,[]]]]
|
||||
[[[[1],[7,10]],5,9,[[],[1,8,7],0,[2],6]],[],[[7,[],6,[],6],[[1],8,0],[[3,0],[0,7],[2,0,3,6],[9,6,0]],[[0,1,7]]],[0,[7,[1],1],4,10]]
|
||||
|
||||
[[7,7,[[],[7]],1,[0,10]],[10,4,8,6,5],[7],[[[2,4,8,7]],[[10,1,6],[6],[5,5,6,8],7,[0,5,2,3,4]]]]
|
||||
[[[8],[[4,7],[8,10,0,10,8]],0,8,3],[[9],[8],[[1,2],5,0,[7,0],[1,3,10,8]],[0,4,[3,10,0]],[10,[],[]]]]
|
||||
|
||||
[[],[8,[9],9,3,7]]
|
||||
[[6,8,[5,4,[],[8],3]],[],[8,[4,[9,3,7,1],[7,1,9,5,7],[7,4,5],2],[9]]]
|
||||
|
||||
[[[[0,7],1,2,[7],10]],[6,7,6,[[3,7,2,7],[10]],[2,[9,9,5,7],[0,4,4],[5,8,2]]],[2,2,8,2],[[]]]
|
||||
[[],[10,[[0,10,1],7,0,9],6],[[4,6,[1,7,9],7,[5,3]]],[2,[[10,10],[8,0,3,8,2],[6]],2,7],[[6,3,4,1,[4,7,7,2]],0,[[1,3]],[[0,9,3,6],0,[5,6,6,0],10]]]
|
||||
|
||||
[[[3],0],[1,1,4]]
|
||||
[[6,[8,[2,5,2],[6],2],[1,8]],[3,3,7,[[2,10,1,5],[]],1],[[9,[8,6,7,3],[9,9,6]]],[[[],[9],9,6,2],1,[8,10,2],[],3]]
|
||||
|
||||
[[[[1],[3],7,[8,0,7],6],3],[],[8]]
|
||||
[[6,7,[4,[8,2,1,5],8]]]
|
||||
|
||||
[[8,[[],9,[4,6]]],[9,[10,[8,7,4,1,2],[3,3,2,10,7]]],[4,[[4,5,2],8,3,[3,4,10,5]],10,10,[[1,10,4,10]]],[[8],[[5],[6,1,0],2,10,2],3]]
|
||||
[[[10,5],[[0],[7,9,3],[2,7,5,2]],[7,10,[8],6],[[6,6,4,5,9],[3],4]]]
|
||||
|
||||
[[3,6],[1,[],3,9,[]]]
|
||||
[[9,[],6,[],[[3,8],[6],7]],[[],[0,9,5,[9,1,9]]],[[9,10,[8,3,7]]]]
|
||||
|
||||
[[],[1]]
|
||||
[[0,[],[5,[],5],[[]],2],[5,7,9],[1]]
|
||||
|
||||
[[[[9,9,2,9],[0,6,4,5,2],[8,2,2]],[0,7,4]],[5,9,[0]],[[10,[9,5,10,4],5,0]]]
|
||||
[[[[9,6]],[],[[9],10,7,4,[9,0]],5]]
|
||||
|
||||
[[[[7,2,1,6,6],9,[1,7,8],8],[5,[3,8,8]],[[5,0],[2,1],[3,0],5,[7,7]],[[],[4,6],[4,6,5,4]]]]
|
||||
[[7,7]]
|
||||
|
||||
[[9,1,[[5,10,6,7],[4,6,5,10,1]],[[4,7,9],5,[6]]],[4,[2,[2,2,5,3]]],[[3,[4]],[],2]]
|
||||
[[7,[0,8,0,[10,8,10]],[1],5]]
|
||||
|
||||
[[3,6,6,5],[8,[[4,5,6],5,[8,3,0,1],[10,5,2],[5,0,7]],[],4,[[0],[]]],[2,[4,[6,5,6,9,0],[],[3,0,2,9,8],[10,4,9,5,1]],7],[[[7,3,5,2,7],[2,2,5,6,9],[6],0],[8,8,7,[2,1,3,9]]]]
|
||||
[[[8,7,[7,4,8]],[]],[],[],[],[2,[[1,8,5,0]]]]
|
||||
|
||||
[3,3,5,9]
|
||||
[3,3,5,9,6]
|
||||
|
||||
[[],[[[],[3,4,0],9,[],1],0,2,[0,[5,2,6,8],[9,4,8,8]]],[[[10,6],[5,6,4,3],[],5,[4]]],[0],[]]
|
||||
[[[5,9,7],2,[[2,0,7],[2]],10],[[[9,6],[3],4,[],[9]],0,[[9,5]]],[1,[[10,4,6,9],5,3],1,[10,[9,7,0],[8]]],[[0,[9,7,5,10,4]],0,0,2],[[[]],7,2]]
|
||||
|
||||
[[[1,6,2,5,4],7,[8,8,9,9,[6]],[[],7,[],[10]]],[[[1,0,0,5,5],8,5],[[],1]]]
|
||||
[[5],[],[[[7,4,8],9,8],2],[10]]
|
||||
|
||||
[[10,1],[[[0]],[]],[[5,[9,1,0],[],8,4],1]]
|
||||
[[[[10,0],6,[8,6,7],1,2]],[[[7,3,8],[],[],3,[4,0,6]],[10,[6],9],[[9,1],[],[5,1,3],[],2]],[[1,[2,8,6,6],[6,9],[3,8],[4,10,8]]]]
|
||||
|
||||
[[[4,10,8,6],5],[8,[[3,4],[2,0,1,10,9],6,[4,10,10,8]],[9,[2,9,7]],[7,[0,9,6,1,0],6,5]],[]]
|
||||
[[3,[[1,10,1,1,8],8,[7,6,0],[6,10,5,3],[2,3,2,2,6]]],[]]
|
||||
|
||||
[[[],[[1,6,3,8,9],[7,0,2,4,3],[4,5,3,6],3,[2,2,10,9,0]],3]]
|
||||
[[],[[[8,8,10],[10,2,7,8],[1,0,7,4],[2,8,8,2],9],8,10,10,1],[[[3,2,6],[0,2,9,9,10]],[6,[],4,0,[5,4]],[[4,1],0,[],3,5],7,2],[]]
|
||||
|
||||
[[[0,[7,1,6,4],[2,3,4]],[],[]],[[1,[8,4,2,9],8,9],6,[8,10]],[5,[[3,10]],5,[]]]
|
||||
[[0,10,[],1],[],[4,8],[],[]]
|
||||
|
||||
[[[5,3,[0,10,1,1],[],[]]],[6,8,[]],[4,2,[2,0,[1],1]],[],[[[4,8,0],[0,7,9,8,6]],[[0,0],[9,10,3]],[[2,4,2],0,2,10],6,[5,[4],[4,2],[2,4,4,0,10]]]]
|
||||
[[[[1,9],[10,2,9,2,3],[8,7,4,8,4]],2,[7],[[0,1,5,2],5,5,10,10]],[[1,10,4]],[5,[],[[3,1,3,6],[7,1,9,1],[0,3,8],6,3]]]
|
||||
|
||||
[[2,[]],[[[9,0],[3,9,6,10,9],3,3,5]]]
|
||||
[[[0,1,[3,9],9]],[[7,[1,10,3,3,3],2,5],2,8],[10,10,[[0,3,8,0],10,[2,4,0,4],3],[[2,6,4,3,1],4,[8,9],[]],[[],[1,5]]]]
|
||||
|
||||
[[[],9]]
|
||||
[[],[0,5],[[4,8,[10],3,[8,9,4,4,4]]]]
|
||||
|
||||
[[[6,[3,1,1,4]]],[0,[9,[9],6],[[],9,[],0,[6]]],[8,[0,9],[2,10],9],[[8,[1,10],[9,0],[6],9],[4,[],[10,10]],[[4,2,8,8,10]]],[[7,[4],[3,8,0,3,0]],1,[8,[2,8,5,2],[0]],[10,[2,0,2,4,6],2],[1]]]
|
||||
[[[7,[],5,[8,8,10]],4,[1]],[[7,10,0],3,[7,[3,10],[3,8,5,0,7]]],[6,[[2,5],8,10,[2,8,5,1],[4,7,2,4,0]],2]]
|
||||
|
||||
[[4,0,10,1,[[1,6],2,9,10]],[[[3],[3,0,8,9,7],[5,6]],[[4,2,10,8],[1,9,10,6],6],6,[[5],4,[],[],1]]]
|
||||
[[4,[],[8,3],9],[[],[0,8,[6,9,6],[10,6]],4]]
|
||||
|
||||
[[5,9],[1,5,6]]
|
||||
[[3,[8,[0,5,7,4,2],[4,4],[7,10,3,1]],0,4],[[7,[0,8,6]],[[3],[7,9],[],[3,6,4]],2,4]]
|
||||
|
||||
[[10,[]]]
|
||||
[[],[7,[[0],[10,4,0,1]],3,[[7,0],[1,3],8,[6,0,3,1],1],[10,5,10,9,[]]],[3,6,4,5,3]]
|
||||
|
||||
[[],[[[2,8,1,9,8],[7,0,1,10],[9,0,4,7,6],5],4,[]],[]]
|
||||
[[0,5,5],[2],[[]],[7,[[1,0],[4,9],5]]]
|
||||
|
||||
[[10,5],[],[4,[],3,0],[3,3,9,[]],[]]
|
||||
[[],[[[8],[1],7],4,2,[1]],[1,10,5,[2,3]],[[8],[[5,6,6,3,0],[2,1]],3],[2,7,[10,[],[0]]]]
|
||||
|
||||
[[[3,5,[5],[8,8,3,7],9]],[],[0,[],0,3,7],[1]]
|
||||
[[2],[[[9,9],[0,7],8,[]],5]]
|
||||
|
||||
[[4,8,6],[[5,10],[[2],8,[],4],[[10,7,6,5,10],[3,8,7],[3,1,0,2],[8,8,7,1,5],8]],[6,8,0,[[8],4,[1,0,0],2],[[2,7,6,10,1]]],[1,[0,5]],[2,[],[],4,[[4,5,9],[5],4,[1,1,9]]]]
|
||||
[[[4,8,4,[5,0,8],10],0,[[10,2]],4,0],[[5],4,5,[[2],[5,6],[1,2],5,6]],[[[3,5,2,8],[7]],[3,[6],[1,4,6,5],[3,0,6,8,2]],9,2,7]]
|
||||
|
||||
[[],[],[7,2],[[]]]
|
||||
[[6,[[8,6,4,9,0]]],[[5,[9,6,2,4],[],2],5,7,[[1],10,[0],[8,5,4]]]]
|
||||
|
||||
[[],[[[7,8,4,9]],[2,[10,5]]]]
|
||||
[[0,2,2],[[[8,6,0,9],[],6,8,[6,1,5]],4,4]]
|
||||
|
||||
[[7,7,[4,[2,7,6,8,4],[5,9],8,[6]],[1,1,0,2],1]]
|
||||
[[[6,1],[],[]],[[5,9,[0]],[[2,7,6],4,[5,10,1,5],[],7]],[[2,[9,0,9,10]]],[6]]
|
||||
|
||||
[[3,[3,3,6,[8,0],[6,4]],2,0,[[5,0,4,1],1,[0,7,6,6,7]]]]
|
||||
[[],[5]]
|
||||
|
||||
[[[[1,10,1,5],[2,1,0,4,10],[4]],[[0,6,3],[4,1,6],9,7],[[7],[5,6,8],5,4,[10]],1,[0,[9,4],9]]]
|
||||
[[],[3,[],5],[]]
|
||||
|
||||
[[],[[],[3,5,0,7],[1],2,10],[3,[],0,[[9,0],[0,0,2,5,9],[1,6,2,6]]]]
|
||||
[[5,[7,7,[1]],[[],3,[2,8,7],[3,9,6]]],[0,[[7,10,1,3,8],5,[5,4,3,1,9],[2]],2,[[5,10]]]]
|
||||
|
||||
[[[[10,3,8],8,3,2,[7]],2,[[5,5,2,4],7],6],[7,0,[6,[4,9,9,5],[3,1,6,2,6],5],[1,4,2,9],[8,8,[10,4,10,9],[3],[2]]],[]]
|
||||
[[],[[4,6,[7,6]],[],[]],[[[],0,2,[7,4,0,9],[4]],[],0],[]]
|
||||
|
||||
[[5,6,[10,[8,10],[],10,[10,0]],[1,[8,4,6,2]]],[],[[[8,10,10,1]],[],[4,[10,9,7],10]],[[],[[1,10,4,0],[]],[6,9,[4,2,4],7,0],[7,[4],[8,0,7,8,4],[3,5,5,3]]]]
|
||||
[[[],[[10,0,3,2]],7]]
|
||||
|
||||
[[[[],1,[8,5,9]],2,[[1],[9,3,1,2,2],5,2,[]],9,[3,[],[2,1,7],8,[0,1]]],[[[1,6,1,6,5],[2,10,2,1,7],[0,6,0,4,2]],[],3],[8,10],[[[10,2,7],2,7,[]],5],[[6,1],[8,[],[3],[4]],6,8]]
|
||||
[[[],10,6,7,[4,9,[9],6]],[[]],[[],[6],8,0],[[[10],[8,8,3,8],8],[7,[]],[]]]
|
||||
|
||||
[[[[10,0,8,1],[7,6,6],[6,9,9,0,10],[7,4,3]],[[9,10,3,4]]],[[1,[0,3]]],[5,1,2,[9,[],[0,4,10,10]],9],[[9]],[7,6,8,0]]
|
||||
[[[[4],3,2,[]],[9,[],4,6,[5,1]],2,[]],[[6,[6,10],[],[],[6,6,10]],7,[5,7],[[9],4,[6,10,0,3],[]]],[[2,[1,8]],3,[9,[0,6,10]],[],3]]
|
||||
|
||||
[[7],[7,[[7,8],[0,7,1,4]]],[10],[10]]
|
||||
[[],[],[[[9,3,4,2],[4,5],1,[8,0,7,8,4]],6]]
|
||||
|
||||
[[[4,[],[0,0,3,6],2],9,[],7,0],[[],9,[],[],[0,0,1,1,[5,5]]],[3,10,[8],2,[5,[],5,[2,3],5]],[[[10,4,9],[10,9,10,0],[4,7],[10,2]],3,[0,2],10,1]]
|
||||
[[[],6,[],[2,5]],[[[7],[6,6],0,5],[4,4,[8],2,[0]],8,[4],1],[],[8,1,9,[10,[9,7,2,0]],[]],[10]]
|
||||
|
||||
[[8,[],2],[[[3,9,5,9,2],[2,3,10,6]],[5,[6,5,10,1],[7,9],[2,10,3,7,10],[4,0,9]],9,0],[1,[[7,6,1,4]],10,9],[],[[[3,8,7,7,6],[2,9,4,5],[10,1,5]],3,[6,8]]]
|
||||
[[5]]
|
||||
|
||||
[[8,0,3],[[[],[2,5,7],3,7,[5,10]],[8,5],0],[7,[[3],[9],0,9],[],[[],8]]]
|
||||
[[8,[4,[2,6],2]],[],[[[5,3,7,8,6],[2,9],2,[],[9,4,8]],5],[9,[[7,10,3,10,1]],10,9,0],[[3,7,[0,5],3,3],0]]
|
||||
|
||||
[[],[],[1]]
|
||||
[[[2,[9,8,0,1,7]],[9,10]],[10,[[],[9,5],10],7,2,1]]
|
||||
|
||||
[[4,[7,8,7,[5,5,1,1],0]],[[1,[9],[0,3,0,8],[5,2],1],1],[[[4,5,3],[3,10,3]],5,5,[[8,0]]],[[[],5,[0],3,7]],[[2,[5,4,1,3],[0,7,4,10,2],1,7]]]
|
||||
[[0,[[4,0,8,0]],[[2,2,9,4,2],[],[5,4,3,1],6]],[],[8,8,10,10,3],[[2]],[[9,4,10]]]
|
||||
|
||||
[[5,[2,0],10],[9,7,[[],8,[8,1,2]]],[[],[[5,10,7,4],[3,1],[7]],7],[7,8,10,2],[[],[]]]
|
||||
[[[7,2],10,2]]
|
||||
|
||||
[[1],[[5,2],[[10,3,3,8,7],[],2,5]],[],[[[7,4,8],0,[1],8,6]]]
|
||||
[[7,10,[9,[0,5],0,[8],0],4,[[6],0]],[],[],[[0,2,[7,4,9]],[3,6,8,[1]],10]]
|
||||
|
||||
[[[6,3],[[7],[1,6,3,5],3,[]],[[10,1,1,5],3,[]]],[[[3,4,6,0],[1],[1,10,4]],[],5]]
|
||||
[[],[[],[5],[[]],3,6]]
|
||||
|
||||
[[4,[1,0],[[10,2],4,[6,1,0],[4,4,3]],[[10,9,4],4,4,[1,9],[7,0,0]],[]],[[8,3,[8,10],4]],[[1,[],0,9,4],3,5,[]]]
|
||||
[[[[7,10,0],8],5,[4]],[],[[6,[10],[6,10,7,5,9],7]],[]]
|
||||
|
||||
[[],[2,7,[5,[5,7],[3,8,4,3,7],[]]]]
|
||||
[[],[7,9]]
|
||||
|
||||
[[3,[],[[5,9,7,2,3]],3,3],[[],9,[4,[7,6,9,5,8],7],9,2],[],[[7,[8,9,7,5],3,[5,2,5,9,1],[7,4,3,10]]]]
|
||||
[[[[8,5,6,0,0],[9,7],9],[[1],3,1,4,0]]]
|
||||
|
||||
[[2],[0,1,0,4,[10,[1,8,7,5],[2,9,3],5]],[0]]
|
||||
[[],[[[9,2,9,0,0],[2,9,1,9],[8,4,4]],[[6,5,8],0,[0]],[10,8,[9,9,4,6],8]]]
|
||||
|
||||
[[[4]],[5,[9,[6],[0,2],[],0],[[3,4],[3,6],[7,3]],[[9,7,4,7,6],[8,4,1],[8]],[]],[],[6,2,[[5],9,10],8,0]]
|
||||
[[7],[5]]
|
||||
|
||||
[[5],[[[8,4,7,2,8],[8,7,3],6,[],6],1,[5,[6,5]],7,7],[[10],[],7,[8],[0]]]
|
||||
[[[]],[6],[[],8,7,[3],[4]]]
|
||||
|
||||
[]
|
||||
[[],[[[6,8,0,8],[],8],[[5,1],7,8],1,10,[8]],[3,5,[[9,6,3]]],[[2],3,[[4,9],3,6,2,[1,0,8,5,4]],7]]
|
||||
|
||||
[[[8,[7,9,7,4],4],3,[7]],[[[10,2]],4,4,[4,[7,4],[4],1],5]]
|
||||
[[[],[[8,3,5,2,7]],[[],5],[],[9,2]],[5,[5,5,[5]],[]],[0,9,9,[]],[[5,4]],[]]
|
||||
|
||||
[[0,1,[1],10,4],[[[10,1,8]],9,0],[3,[0,2],0],[9,0,10],[]]
|
||||
[[[[2,1,0,0,4],[],0]],[],[0]]
|
||||
|
||||
[[7,7,10,[]],[3,[],[[6,10,7,4],0,9,[0]],[[10,2,7,6],[9],8,4,[3,5,6,0]]]]
|
||||
[[],[4,[9,6,6,[0,3,1]]]]
|
||||
|
||||
[[0,4,[[0,8,6,4],4,7,10],[8,[10],2,8],2],[6,[[6,3,6]],4,10],[2,6],[],[[],[[2,7,1,1],[10,4,7,1],[6,10,4,0]],6]]
|
||||
[[[2]],[[[9,4,5,2],5,7,[],[]]],[10,8],[3,8,[6,[0,10,10,0,2]],[[5,6,6,10],7]]]
|
||||
|
||||
[[8,[[7,6],[8,1,7]],[],5,2]]
|
||||
[[6,7,[2,7,[7,1,8,5,1],1,5],9]]
|
||||
|
||||
[[1,[],1],[],[7,[[2,10],8,[8],[10,1,9,4,10],[1,9,5]],[[9,4,9],[2,2,1,3,4],0,[8,3]],7]]
|
||||
[[[4,[10,9,9,2],3,9,4],[1,10,4,8,4],6,4],[7,1,[3,3,9]]]
|
||||
|
||||
[[[[2],[6,7,4,1],[9,3],1,[5,0,9,4]]],[[[2,5,0,0,1],[3,3],[9,1],9,1],9]]
|
||||
[[],[[1,[3,6,7,4,10],[7,2,6,0,6],[7],6],5,5],[[[5]],2],[[[3,9,4,9,4]]]]
|
||||
|
||||
[[[3,[3,0,9],9],[[10,9,1,8]],[6,8,[6,7,5,10,4]]],[[[],2,[],[9,3,8],8],[5,0,2,[],[0,9,4,3]],[[],1,8,1,0],[]],[[[4,7,8,6,2],6,9,[1]]],[4]]
|
||||
[[[[],8,10,[6,6]],0,0,[10,[],[0,2,8,3,7],[7,5]],[[0,4,0],3,10,2]],[4,[],0,[],6],[[[7,8,0],[7,5,7],[10,4,3],[1,5,2],9]]]
|
||||
|
||||
[[],[[[6,10],7,1,0,[]],[[9],[8,9,9,10,8],0,8],2]]
|
||||
[[10,0,4,[[0,2,10],[9,2,4,7,7],[5],[9]],[[3,2],[2,9,10],[3]]],[2,1],[10,[5,[2,8,2,4],6,4],4]]
|
||||
|
||||
[[8,[[4],[2,9,10,6],0,4,6],[[7,5,3,0],[9],4,[7,5,10,10]],[]],[]]
|
||||
[[[[]],1,[[],[10,7,2,1],[6]],6]]
|
||||
|
||||
[[[[1,6,7,3],3],[1,[7,0,6],7,4,[7]],[2,5],0],[[],[[4,5,3,4],5],[7]]]
|
||||
[[5],[[],[],5,[[8,3,3]],[[],3,8,9]],[[0,[0,2,9],[2]],[[8],4],[[0,3]],[[6,4,4,3,2]],[[0],[],[0,9,10,1],8,8]],[2,[[],[7,7,0]],[[5,7],[8,2,8,1,5]],[[9,2,6],[1,5,9,1]]],[[[2],[]],[8,7,5,[2]],[[2,1,8,1],5,4,6,[0,5,6]]]]
|
||||
|
||||
[[],[1,6,10,1],[[8,9,[3,8]],10,7,[[0,8,6,7,10],[7],[1,0],2],9],[[[4,1,0,10],1,4,[8]],0,[4,10,9]],[8]]
|
||||
[[[[4,8,9,3],6],5,[],5],[]]
|
||||
|
||||
[[[10]],[[],8],[[[6],7,9,[6,6],10],[8,4]]]
|
||||
[[8,5,3,[],2],[8,[8,[0,0],5]]]
|
||||
|
||||
[[[1,0,[],[8,8,3,2],0],2,2,[10,[7],[2],7]],[10]]
|
||||
[[1],[0,[[6,7],[1,10,7,6],[1,8,7,4],10,5],5],[[4,0,[7,0],[8,3,8,6]],[[2,4,10,8,6],3],8,[]],[[4,[9],[7,4,10],[4]],[3,[6,6],[],5],9,[]],[[[6],[2,1,1,3,5],[2,9,3]],6,[[1],[5,7,5]],[[4,3],[8,2,6,4,6],0,5,[5,8]]]]
|
||||
|
||||
[[],[[6,[1,0,0,9],1,6],[[4,9],0,1,7,[2,2,10,7,3]],1]]
|
||||
[[],[[[4],1,10],[],4,[[9,4],0],[[9],[10,1,10],10,2]],[8,7]]
|
||||
|
||||
[[[],7,[[8,4,9,2],[2],4,9]],[[[0],5,[],10,[]],[3,[1,9,9,2],[9,10,0,0]],[7,9,[8,7],2],[9]],[9,[[9,4,6,8,10],8]],[[[0],5],10]]
|
||||
[[7],[0,6,[[6],[],3,[3,8,6,2,8],6]],[9,6,0]]
|
||||
|
||||
[[[[4,4,7],[6,7,2,2],[]],1,[[],7,0]],[[5],[2,2,[3]],[6,2,4,[]],[[3,8],1,[8,6,0,10,5],[8,10,6,1]],3],[8]]
|
||||
[[0],[[10,[],[10,4,7,3,10]],[[5,9],7,5,8],9],[9,0,5,1],[]]
|
||||
|
||||
[[0,0,[[6,10,1,5],[8,0,4],10,[10,9,1,5]]],[[4,[2,1,1,5,4],[5],[]]],[3,7,0,[],10]]
|
||||
[[3],[4,5],[6,[4,5,[]],5,4]]
|
||||
|
||||
[[[[6],6],10],[]]
|
||||
[[[],7,[[4,3],[7,3],1],[4,[7,6,6,3,9],[2,2,0,8],2]],[1,5,[[5]],[[0,2,5,2]]],[[[4,8,10,0,3],[6,1,8,1,4]]],[],[1,[[],[],2]]]
|
||||
|
||||
[[9,[]],[7,[[3,0,2],[],10,6,[10,7,8,4,6]]]]
|
||||
[[7,6]]
|
||||
|
||||
[[8],[2],[6,1],[6,[4],[],[4,8,[5,2],5]]]
|
||||
[[],[[[1,9,0,1]],3,5,[6,[3,4,3],5,[6,3,7],[2]]],[5,[[3],0],5,[],5],[7,[[9],10],4,9],[]]
|
||||
|
||||
[[[9,[8,5,4,8]]],[3,[7,[6],3],2,[5]],[[[1,8],[6,6,5]],6]]
|
||||
[[2,[[2]]],[10,6,3],[[[10,4],0],[],[5],[],[0,[10],[1],[1,2,7]]]]
|
||||
|
||||
[[[[],[],6,[10]],[],7],[3,[10,9,2,[]]],[5,[[10,10,2,7,0],6,[]],[8,[0,7]],[[0],1,[9,10],4,2],[]],[]]
|
||||
[[[9,[5,4,6,9,5],[10]],[[5,9],0,6,5,10],[5,[2],[4,9,4,9,0],[5,4],[0,1,3,6]],3,[[3,9,7],[6,10,0,0]]],[[7,8,10]]]
|
||||
|
||||
[[[3,[4,0,0,9,8]],2,0,[6,[5,7]]],[[9],[],4,0],[6,2,[9],[10,[5,4,9,10],6,4]],[9],[6,6,[[7],[6]],[[8,0],5,10]]]
|
||||
[[],[8,1,0],[5],[9,5,[6,[6,10,6]]],[]]
|
||||
|
||||
[[8,7,[5,1,[4,1,3],[8,1,0,8,2]],3,0],[[[0,1,3,1,1],[9,7,2,4],4,6,4]],[10,5,7,4]]
|
||||
[[7,[]]]
|
||||
|
||||
[[0,7],[],[],[0,2],[0,2,[5,5,[4,6,3,10,0],0],[[5,1],[8,0],[5,7,5,0],2,4],[8,[],[10,2,3,4,8]]]]
|
||||
[[[8],[2,10,6],9,2,[5,[],5,[6,0,4,5,7],5]],[7,1]]
|
||||
|
||||
[[[],[[9,7,1,3],[6,3,2,7,6]],[7,[6,9,5,0,9],3],5,[]],[],[[[3],[0,7,1,7]],[0,[10,6,2,10,4],[5,8,0,6,7],0,[]],6,9],[[[4,6,0,0,2],7,[9,7,7,7,0],8],6,[[],[0,3]],8],[[9,[1,10],2],4,[[0,4,10],[4,7,8]],[[2,0,0,9,8],[4,2,9],[5,10],1,[8,4]],3]]
|
||||
[[]]
|
||||
|
||||
[[[[6]],4,8,[],6]]
|
||||
[[],[1,9,[[],9,[10,7,10,9,9],6,[0,10,1,4]]],[3,[8],2,9],[5,[4,7],[4,[8]],5,6],[[0],[10],[]]]
|
||||
|
||||
[[[[5,1,10,5],[2,10,6],1,0,1],[[1],3,[],2,7],4,4,6]]
|
||||
[[3,[[7,3,0,6],7,[1,4,5]],[[4,7],[0,6,10,2,9],[],[4,2,1,9,7]],[9,10,[10],1,9],[]],[8,[],[3]],[[[3,2,6,1,0],4,[4,9],[3,1],3],[],[[0,4],[4,2]]]]
|
||||
|
||||
[[7,5,1,10],[2],[]]
|
||||
[[],[[],7,[],9,[[0,9,4],[8,0]]]]
|
||||
|
||||
[[3,9,0],[[[9,0,7,4],[1,6],9],10,[3],9,[0,[4,7,4]]]]
|
||||
[[5,3,[1,[8],0,9],1],[[[8],8,8,8,[6,7]],4,0,[4,0,9,[3,8,8,8],10]],[[[],7,[8,8,1,5]],8,3,4]]
|
||||
|
||||
[[[9,[8],[10,3,10],7],4,3,6,[8]],[[]],[8,[10,10,[]],[4,[6,9,3,10,6],8,10,2]]]
|
||||
[[[[3],[5,0,9],[],2,[4,1]],[7,8,3],[10,[1,4]],[[0,7],[6,4],7,[10,0,0,1]]],[[[5,2],1,[10],10,[3,5,6]],[[],[0,6,2],[0,10,0,1,3]],[[],[1,7]],[1]],[],[],[9,[7],2,[[4,5,4,0],[8,1,1]]]]
|
||||
|
||||
[[[],3],[3,[],4],[5,4,6,[]]]
|
||||
[[2,[8,2,[4]],5,[5,[9,1],[10,6,10]],9],[10,[5,8,[],[5],[]]],[[],1,[1,[7,6,5,0,4],[6],[5,5,10,5,2]],0]]
|
||||
|
||||
[3,9,10,6,3]
|
||||
[3,9,10,6]
|
||||
|
||||
[[1]]
|
||||
[[[[],[],[10,8,6]]]]
|
||||
|
||||
[[[5],[10,[3,10,4,1],7],5,[3],[]]]
|
||||
[[],[[7],[[7,8,5],[6,10,4],9,[0,10,6]]],[[[8]],[5,[],[2],[6,5,0]],[[10,1],10,[],[9,1]],[5,4,[4],[],10],[5,[7],[10],[2,10]]]]
|
||||
|
||||
[[2,9,[[9,7],[],[4,6,3],[0,6,10,2,10]],[[6,1,1,1,4]]],[10,4]]
|
||||
[[[],[6,8,1]],[[[7]],5,6,[0,2,2,6],[]],[3],[[4],4,5],[1,[[9,10],[1,5],4,[6,7]],0,6]]
|
||||
|
||||
[[[7,9],5],[2,[5,9,7,[7,2,9]],[9,[8,7]]],[3,[[],10,4,[7],3]],[1,[[],5,0],5],[[],[[],5,0,4],2]]
|
||||
[[[[4,3,0,10,3],[6,1,10],4,8],[8,[],[8,0],10,[]]],[],[1,9,4],[10,8,[5,[9,8]],3]]
|
||||
|
||||
[[6,8,[[1,4,10],0,7,[10,5,10]],[[10,8,9]]],[9,[9]],[9,[3,1,[],[1,1],8],7]]
|
||||
[[],[5,8],[7,[7],[[3,6,2],6,0,[2,7],[6]],[10,[2,10,8,6],[2],[],[8,10,10,3,4]],[[8,5,8,8,10],7,1,[10,10,8],[3,5,4,3,3]]],[[[],5,10,[1]],4]]
|
||||
|
||||
[[4],[10,6]]
|
||||
[[0,10,4,[9,10]],[],[1,8],[9,7,[2,[5,4],[10],[7,1]],0]]
|
||||
|
||||
[[[],[5,[4,10,2],4,[10,8,10]],[]],[],[4,[4,6]],[[],[2]]]
|
||||
[[1,5,[[4,2,5],[],[1,9,4,7],[10,6,2,3]],[[9,2,0]],0]]
|
||||
|
||||
[[2,[8,7,[9,0,0,9],[0,8]]],[],[[3,6],[[1,8,0,5,6],5,2],0,6]]
|
||||
[[[3],[[1,6,1,10,0],[7],[9,2,0,5,9],[1,10,5,8],[8,6,2,6,5]],5,1],[]]
|
||||
|
||||
[[[1],8,3,7,10]]
|
||||
[[[[1],[9,2,0,6],6,[5,4,7],[1,9,4]],7,0,[]],[2,4],[[9,9,[10,5,5],6],3,0,[[1,8],[],10,0],10]]
|
||||
|
||||
[[10,4,[8,[3,6,1,1],7,10],[],[[2,6,6]]]]
|
||||
[[2,4],[[[2,0,8],[2,0,6,8,3]]],[[[5,1],9,[0,4,6,4,4],8,1],[1],9,[],5],[6,4,[[1,5,7],3],[[9]]],[]]
|
||||
|
||||
[[],[[[],4,[9,2,9]],[[4,6,3,6]],[1,8,2],7],[[[3,1,5,5],[]],9,6],[0,4,1,6,0]]
|
||||
[[[[0,10,1],[2]],2]]
|
||||
|
||||
[[[3],[[],4],1,8,2],[[2,[6,10,1,8,0]],0,[8,[],[10,9,7],[]],2],[[[4,4,2,6],[],7],3,8,10,3],[]]
|
||||
[[1,[6,3,[8,6,4,4],7],[7,8,[3]],1,2]]
|
||||
|
||||
[[2,[0,8],9],[[[0,3,0,4,8],[2],[10,4,1,4]],[],[5],8,5],[0,[6],10,2,[1]]]
|
||||
[[9,10,2,[[0,7,5,0],2,[2,10,9,8]],[[6]]]]
|
||||
|
||||
[[[4,3]]]
|
||||
[[[[8,9,3,3],[],[10,1,3,1,8],8,7]]]
|
||||
|
||||
[[[9,[0,1,7,3,4],9,9],[],[8]],[[0,[9],[3,6,3,0],7],[9,4,0,[8,1,2,8],8],[2,8,[4,5]],[8,0,[9,9,7]]],[[0,[8,6,7,7,4],2],[7,[1,2,7],[7]],9,[[4,3,4,2],[1,7,3,1],9],[7,[5],[9,5,10]]],[]]
|
||||
[[8,[0,[3,0],4],6,[[8,6,5,3],[4,7],0]],[[3,[7,0,7,2,6]],[[0,0],[],[0,5,0,9,8]]],[]]
|
||||
|
||||
[[4,7,[7],6,[8,[]]],[]]
|
||||
[[],[[9,[10]],[10]],[9,1,5,[0,7],[9,6,[6,0,4],[10]]],[[[4],[1,0],1],9,3],[[[9],1,[],[7,0],2],3,[[5,10,9],0,3,[7,9,10,5,0],6],[6,3,[],6,[3,3,6]],[[9],[2,1,7]]]]
|
||||
|
||||
[[[[0,5,8,5],[5,5,6,3,6],[]]],[5,4,[],[],[[6,4,3,4]]],[[[9,3],[]]],[]]
|
||||
[[[7,[3,6,3,8,2]],6,7,9],[6]]
|
||||
|
||||
[[5,[[1],[7,4,10,4],4,[8,3,0,2],[]],5,[9,[8,2,10,4,3],5,6,3],6],[[],[3,7,[5,1,2,1]]],[[[2,3,8,5],[0,4,4],10],2,[[1,4,2],5,8,2,3]]]
|
||||
[[[[8,6,8,2],[1,8,4,4],7,[5,4,10,7,4]],[[7,2,5]]],[3,10,[6,[1],[]]],[6,[],3],[[[7,0,0],9,4,3]],[0,[1,[],8],7,3]]
|
||||
|
||||
[[[1,6,[7,1,3]],[[8],[8,8,9,1,1]],[[6,6,1,3],[2]]],[[],8,[],3],[],[6],[6]]
|
||||
[[[[],[],7],[[9,8,7],3],4]]
|
||||
|
||||
[[],[9]]
|
||||
[[10,[[10,9,9,1,9]],[[5,5,7,0,4]],9,1],[],[[],5,[6,[3],[1],[1,8],[6,3,3,6]],2],[[[3,1,4,3,2]]],[3,[2,[10]]]]
|
||||
|
||||
[[1],[[[0,0,10],[9,1,1,1,4],[7,0,5,3],[2,2],8],[[0,4,6,9,5],8],[6,[6,8],7,[],[8,0,6]],[],[[],7]]]
|
||||
[[],[[[6,1,9,8,5]],[[1,0,1,4],2,[],3]],[0,2,0,[[8,5,7,4,6],[5],4,[6,5,6,2,0]],10],[6,7]]
|
||||
|
||||
[[[],3,6,[4,1,[5,0,5,3],[3,0],5],[1,1,2]],[3,2,[[1,3,7,9],[5]],6],[6,[],5,2],[3]]
|
||||
[[[[0,4,5,0],9,3,10,3],[[4,3,4,9,10],[6,1],[8,10,10,4,3],0]]]
|
||||
|
||||
[[3,6,4,7],[5,8,0,[[0,6]]],[],[]]
|
||||
[[[[],[3,1,0,7,2],3,[10,3,0,2,8]],3],[0,9,0],[[[8,8,0,9,0],[6,0,5]],[[3,4,9],7]],[],[0]]
|
||||
|
||||
[[],[[0,1,[4,1,4,2],[6,5,3],[]],1,[9,3,[10,4,5,0,4]],[[5,7],2],[[8,7]]],[8,4,9]]
|
||||
[[8,[7,[10],[2,8,10,9,3],[6,5],3]],[5,5,[[3],[]],6,[1,0,7,8]],[7,[6,5]],[],[10,5,4,[2,0,4,[6,10,4,4],[3,3]],8]]
|
||||
|
||||
[[[6],[10,[0,2,5,10,9],2],[[],[0],9,[1,0,5,8]]],[3,[[4],[3],3,[1,4,2,0,0],[]],[[8,3,6,10,7],1],[2,2,5,[6],[0,7]]]]
|
||||
[[7],[1,3,[1,2,2],2,3],[5]]
|
||||
|
||||
[[[[]],0,[[4,6,4]],0],[],[3,[],[1],[10]],[[1,[2,5]],[[7],[6,10,6,6,6],6],[[0,8,5],[4,0,9]]]]
|
||||
[[5,8,2,[0,3]],[6,[[6,4],[7,10,9,10,3],2],2,6],[1,[9,[6,4,1,2],8,[10,2,5,9,8],[]],[]],[],[[[8,2,3],9,[5,6,3,3],4,[4,10]],7]]
|
||||
|
||||
[[8,[2,0],[10],2,3],[[3]],[[9,[10,9,9,5,7],2],[[],9,[6,8,5]],[10],8,[]]]
|
||||
[[7,10,[2,[0,6,4,0,5]],[4]],[[],[],4],[7,[5,10,2,[0,7,3,9,7]],[[7,2,1,3,5],[7,5,3,1,6],3]],[[[1],6]]]
|
||||
|
||||
[[],[[7,[],[5,7]],1,7]]
|
||||
[[7,5,4,9],[[5],[[8,2],[1,5],3,4,1],[7,10,4,[],0]]]
|
||||
|
||||
[[[8,6,[6,3]]],[9,[],[[5,6,0]],[2,[1,10,10,6]]]]
|
||||
[[0,0,[[1,1,10,1,3],2,[7,0,6],3]],[],[0,2],[[3],3,5]]
|
||||
|
||||
[[[4,7,[10]],[1,4]],[[2,[4,1,6,0,4]],2,[[],[]],9],[6],[[],[9],7,5],[9,10,[7,[6,0,5,1,3]],2,[]]]
|
||||
[[4,[],[[5,4],[6,2,3,4],8,[4,3],7],[9,3,3,0],[[],1,6,2,9]]]
|
||||
|
||||
[[5],[6,[]],[]]
|
||||
[[],[[1,5,[7,0],[2,7,6,1],10]],[]]
|
||||
|
||||
[[5,10,3]]
|
||||
[[[7,1],[1,[7,5,9,7]],[0,[7,1,7,9,1],[9,2,9,9,1],5,[9]],[[]],[]],[0,[[9,0,3],[3],1,[1],1],9,[10,6,[],[10,9,1,10,10],[2,2,8]]],[[1,7,4],6]]
|
||||
|
||||
[[],[]]
|
||||
[[[[6,3,9],[5,5,8,10,4],[7,4,9,1,3]],1,6],[[[8,2,4,5],[],[1,7,7]],0]]
|
||||
|
||||
[[0,10,[[4,0],4]],[9,[],[4,9,[10,5,8]],7],[10,[]]]
|
||||
[[],[[],7]]
|
||||
|
||||
[[[6,5],2,8,7,[[6,2,10,1],1,[2,5,10,7],1,[2,10,7,5]]],[6,9,8],[4,[],[[1,8]],1,[7,[1,0,6,8],[8]]],[[],6,1,[7,[],0,[6,7,8,10,5]]],[[],[],[7,9,[5,10,6,3],[2,10,3],8],7,[9,[0,10],[8,2,6,0,1],[10,1]]]]
|
||||
[[[9,[0,9,10,7,4]],6,[6,[8,5,9,6,8],[4,10,6],4,[]],[4,9,7,2,7]],[4],[[],[[4,2,5]],[4,[7],[9,5,8,7,7],[],[10,9,6]]],[10,[],10,[4]],[6,1,3,[[2,1],[1,9,7,3],5,[2,3,5,4,9],6],1]]
|
||||
|
||||
[[6],[8,5,[4,[1,10]]]]
|
||||
[[1,7,5,9],[],[],[0,9,1],[0,[2,6,10,[10,7,3,5,3]]]]
|
||||
|
||||
[[3],[1],[]]
|
||||
[[0],[8,[[6,7,6],3,7,[4,5,6,10,1],0]],[[[4],[6,0],0,[8],[8,1]],[[1],4,8]],[8]]
|
||||
|
||||
[[[[2,3],5],[[4,2,4,10,3],[4,0,9,4,2],4],[2,[1,5,2,6,7],8,[0,5,1,4,8]],[[3,6,7,10],[6,7,4,7],[9,4,10]],[[9],[4,2]]],[]]
|
||||
[[[7,8,[8,2,10,2],[],[2]],3,9,0,1],[[[5]],0,7,[[7],2]],[[2,[],[8,5,4,1],9],5,6,[[1,2,8,0],4],[]],[2,[9,[],[10,10],8,[]],1]]
|
||||
|
||||
[[],[],[[[5],[9],5,7],5,[]],[[3,[1,2,6,3],9,[3,2,7],0]],[[[5,9],5,[8,1,7]],[1,1,[7,7,8,10]]]]
|
||||
[[[[10,0],[0,7,2]],3,[0,3,2,[7,1,9]],[[10],0,[5]],[[2,8,0,5],[7,3],4,10]],[9,[[]],[[],[1,4,4],7,[0,1,6,7,2],[6,9,0,4,4]],[9,[9]],[6,[4,5,0,8],1,[8,3,1,10],[9]]],[7,[[]],[5,[1,9,6]]]]
|
||||
|
||||
[[4]]
|
||||
[[5],[[2,[10,7,10,9,10],0]]]
|
||||
|
||||
[[[],[[1,8,6,1,6],[3,2,1],2,[10,3,7,1,4],0],3,[3]],[9]]
|
||||
[[],[],[[8],[[],5,[1,8,7],9,1],[[7,1,2,4,3],7,[5,7,1,6,6],8,2],10],[4,[6,[8,8,6,7]],1,[[],[5,10,3,2,7]]],[1,[],[1,[0],7,[9,0]]]]
|
||||
|
||||
[[8],[2,[[9,2,9,9,10],[3,5,3,4]]],[10,[[10,7,10,0]],10,[[2,6],[4,9,6],[3,4,5,0,2],[]],7]]
|
||||
[[4],[3],[],[10]]
|
||||
|
||||
[[[[0],7,[1,1,10,2,0]],2,[[10,5,10]]],[[[6],[4,4,6]],[3,[]],9,[[8,3,3],[6],[9,5,7,7],8],10],[]]
|
||||
[[6],[[[3,10]],[]],[8,10,[],9]]
|
||||
|
||||
[[5,5,[],9]]
|
||||
[[[[5,6,6,3]],2,[[4],0,7,2]],[[],[[10,5],[],[5],[8,1,0,3,2],3],[[7,3,0],5,0,4,[9,1]]]]
|
||||
|
||||
[[],[[2],7,4],[2,9,10],[[[],[7,4,4,7,3]],[]]]
|
||||
[[9],[]]
|
||||
|
||||
[[[10,5,4,1,8],7,[5],[8]]]
|
||||
[[0,10,[]],[],[0,6,[7,[4],[],[9]]],[4]]
|
||||
|
||||
[[[8],[10],9,9]]
|
||||
[[3,[[1,0,5,1,5]]]]
|
||||
|
||||
[[[4,5,10],[7,[10,3,1],[2,6],10],[[6,0,8,9,6],4,[]],[]],[9,[],10]]
|
||||
[[],[7],[10,10,[6]],[[[2,4],[6,2,2],0],6],[[[2,3,0,0,2],[6,5,7,2],2,4],6,6]]
|
||||
|
||||
[[1],[[]],[[[9,1,9,5],[6],[9,3,5,2,6],9,[]],6,[],[[2],9,[8,3,1,3,1],[3,10,6]],[[0,9,1,8,2]]]]
|
||||
[[[8],[[7],[7],5],5,5],[4,[[5,9,10],[]],[[4,7,5,1]],[[10,1,7]],4],[5,[[4,8,4],7,0],[2],[],[8,0,[5,8],[8,5,7,2,8],4]]]
|
||||
|
||||
[[[0,[3,3,10],[],[0,9],5]],[[4,[],[7,2,5],[0,7],[0,10]]],[],[[[1,8]],[[9,7]],5,[[9,1,0,1],5,5,5,[10]],[[9,4,6,6],4,4,[2,6,9,4,7]]],[4]]
|
||||
[[[[10,8,4,0],[9,10,1]],[],[],[[9,8,4,6],2,9],4],[[2,[6,7,8],10,[],[10,4,3,9]],[5,[9]],5,[6,[10],[7,3,6]],[]],[],[[[5,7],[9,7,7,6,9],[9,10,5],8],[[],3,[0,5,0]],3,6,6],[9,[7]]]
|
||||
147
2022/inputs/14.txt
Normal file
147
2022/inputs/14.txt
Normal file
@@ -0,0 +1,147 @@
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
527,102 -> 527,106 -> 523,106 -> 523,111 -> 540,111 -> 540,106 -> 533,106 -> 533,102
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
541,165 -> 541,166 -> 551,166 -> 551,165
|
||||
506,68 -> 506,70 -> 502,70 -> 502,77 -> 513,77 -> 513,70 -> 512,70 -> 512,68
|
||||
541,165 -> 541,166 -> 551,166 -> 551,165
|
||||
565,161 -> 569,161
|
||||
483,51 -> 483,52 -> 500,52 -> 500,51
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
538,114 -> 538,116 -> 536,116 -> 536,122 -> 552,122 -> 552,116 -> 544,116 -> 544,114
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
499,13 -> 499,15 -> 495,15 -> 495,22 -> 506,22 -> 506,15 -> 501,15 -> 501,13
|
||||
506,84 -> 510,84
|
||||
499,13 -> 499,15 -> 495,15 -> 495,22 -> 506,22 -> 506,15 -> 501,15 -> 501,13
|
||||
512,80 -> 516,80
|
||||
499,13 -> 499,15 -> 495,15 -> 495,22 -> 506,22 -> 506,15 -> 501,15 -> 501,13
|
||||
512,84 -> 516,84
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
538,114 -> 538,116 -> 536,116 -> 536,122 -> 552,122 -> 552,116 -> 544,116 -> 544,114
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
506,68 -> 506,70 -> 502,70 -> 502,77 -> 513,77 -> 513,70 -> 512,70 -> 512,68
|
||||
509,82 -> 513,82
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
538,114 -> 538,116 -> 536,116 -> 536,122 -> 552,122 -> 552,116 -> 544,116 -> 544,114
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
553,161 -> 557,161
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
554,133 -> 558,133
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
551,136 -> 555,136
|
||||
563,136 -> 567,136
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
527,102 -> 527,106 -> 523,106 -> 523,111 -> 540,111 -> 540,106 -> 533,106 -> 533,102
|
||||
499,13 -> 499,15 -> 495,15 -> 495,22 -> 506,22 -> 506,15 -> 501,15 -> 501,13
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
499,13 -> 499,15 -> 495,15 -> 495,22 -> 506,22 -> 506,15 -> 501,15 -> 501,13
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
517,95 -> 522,95
|
||||
503,86 -> 507,86
|
||||
506,68 -> 506,70 -> 502,70 -> 502,77 -> 513,77 -> 513,70 -> 512,70 -> 512,68
|
||||
559,155 -> 563,155
|
||||
521,86 -> 525,86
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
519,98 -> 519,99 -> 529,99 -> 529,98
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
527,102 -> 527,106 -> 523,106 -> 523,111 -> 540,111 -> 540,106 -> 533,106 -> 533,102
|
||||
483,51 -> 483,52 -> 500,52 -> 500,51
|
||||
515,86 -> 519,86
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
483,51 -> 483,52 -> 500,52 -> 500,51
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
519,98 -> 519,99 -> 529,99 -> 529,98
|
||||
506,68 -> 506,70 -> 502,70 -> 502,77 -> 513,77 -> 513,70 -> 512,70 -> 512,68
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
527,102 -> 527,106 -> 523,106 -> 523,111 -> 540,111 -> 540,106 -> 533,106 -> 533,102
|
||||
519,98 -> 519,99 -> 529,99 -> 529,98
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
557,130 -> 561,130
|
||||
518,84 -> 522,84
|
||||
545,127 -> 558,127
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
556,152 -> 560,152
|
||||
506,68 -> 506,70 -> 502,70 -> 502,77 -> 513,77 -> 513,70 -> 512,70 -> 512,68
|
||||
559,161 -> 563,161
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
541,165 -> 541,166 -> 551,166 -> 551,165
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
538,114 -> 538,116 -> 536,116 -> 536,122 -> 552,122 -> 552,116 -> 544,116 -> 544,114
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
527,102 -> 527,106 -> 523,106 -> 523,111 -> 540,111 -> 540,106 -> 533,106 -> 533,102
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
509,86 -> 513,86
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
484,48 -> 484,43 -> 484,48 -> 486,48 -> 486,38 -> 486,48 -> 488,48 -> 488,43 -> 488,48 -> 490,48 -> 490,45 -> 490,48 -> 492,48 -> 492,40 -> 492,48
|
||||
520,92 -> 525,92
|
||||
556,158 -> 560,158
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
553,155 -> 557,155
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
538,114 -> 538,116 -> 536,116 -> 536,122 -> 552,122 -> 552,116 -> 544,116 -> 544,114
|
||||
538,114 -> 538,116 -> 536,116 -> 536,122 -> 552,122 -> 552,116 -> 544,116 -> 544,114
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
499,13 -> 499,15 -> 495,15 -> 495,22 -> 506,22 -> 506,15 -> 501,15 -> 501,13
|
||||
562,158 -> 566,158
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
550,158 -> 554,158
|
||||
515,82 -> 519,82
|
||||
557,136 -> 561,136
|
||||
506,68 -> 506,70 -> 502,70 -> 502,77 -> 513,77 -> 513,70 -> 512,70 -> 512,68
|
||||
547,161 -> 551,161
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
531,95 -> 536,95
|
||||
527,102 -> 527,106 -> 523,106 -> 523,111 -> 540,111 -> 540,106 -> 533,106 -> 533,102
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
527,92 -> 532,92
|
||||
523,89 -> 528,89
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
499,13 -> 499,15 -> 495,15 -> 495,22 -> 506,22 -> 506,15 -> 501,15 -> 501,13
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
541,149 -> 541,141 -> 541,149 -> 543,149 -> 543,144 -> 543,149 -> 545,149 -> 545,144 -> 545,149 -> 547,149 -> 547,148 -> 547,149 -> 549,149 -> 549,144 -> 549,149 -> 551,149 -> 551,141 -> 551,149 -> 553,149 -> 553,147 -> 553,149 -> 555,149 -> 555,146 -> 555,149 -> 557,149 -> 557,147 -> 557,149
|
||||
527,102 -> 527,106 -> 523,106 -> 523,111 -> 540,111 -> 540,106 -> 533,106 -> 533,102
|
||||
490,35 -> 490,31 -> 490,35 -> 492,35 -> 492,31 -> 492,35 -> 494,35 -> 494,29 -> 494,35 -> 496,35 -> 496,26 -> 496,35
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
560,133 -> 564,133
|
||||
506,68 -> 506,70 -> 502,70 -> 502,77 -> 513,77 -> 513,70 -> 512,70 -> 512,68
|
||||
538,114 -> 538,116 -> 536,116 -> 536,122 -> 552,122 -> 552,116 -> 544,116 -> 544,114
|
||||
524,95 -> 529,95
|
||||
492,65 -> 492,64 -> 492,65 -> 494,65 -> 494,59 -> 494,65 -> 496,65 -> 496,64 -> 496,65 -> 498,65 -> 498,62 -> 498,65 -> 500,65 -> 500,63 -> 500,65 -> 502,65 -> 502,59 -> 502,65 -> 504,65 -> 504,64 -> 504,65 -> 506,65 -> 506,63 -> 506,65 -> 508,65 -> 508,63 -> 508,65
|
||||
24
2022/inputs/15.txt
Normal file
24
2022/inputs/15.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
Sensor at x=3988693, y=3986119: closest beacon is at x=3979063, y=3856315
|
||||
Sensor at x=1129181, y=241785: closest beacon is at x=1973630, y=-98830
|
||||
Sensor at x=2761889, y=2453622: closest beacon is at x=2803715, y=2643139
|
||||
Sensor at x=3805407, y=3099635: closest beacon is at x=3744251, y=2600851
|
||||
Sensor at x=3835655, y=3999745: closest beacon is at x=3979063, y=3856315
|
||||
Sensor at x=3468377, y=3661078: closest beacon is at x=3979063, y=3856315
|
||||
Sensor at x=1807102, y=3829998: closest beacon is at x=2445544, y=3467698
|
||||
Sensor at x=2774374, y=551040: closest beacon is at x=1973630, y=-98830
|
||||
Sensor at x=2004588, y=2577348: closest beacon is at x=2803715, y=2643139
|
||||
Sensor at x=2949255, y=3611925: closest beacon is at x=2445544, y=3467698
|
||||
Sensor at x=2645982, y=3991988: closest beacon is at x=2445544, y=3467698
|
||||
Sensor at x=3444780, y=2880445: closest beacon is at x=3744251, y=2600851
|
||||
Sensor at x=3926452, y=2231046: closest beacon is at x=3744251, y=2600851
|
||||
Sensor at x=3052632, y=2882560: closest beacon is at x=2803715, y=2643139
|
||||
Sensor at x=3994992, y=2720288: closest beacon is at x=3744251, y=2600851
|
||||
Sensor at x=3368581, y=1443706: closest beacon is at x=3744251, y=2600851
|
||||
Sensor at x=2161363, y=1856161: closest beacon is at x=1163688, y=2000000
|
||||
Sensor at x=3994153, y=3414445: closest beacon is at x=3979063, y=3856315
|
||||
Sensor at x=2541906, y=2965730: closest beacon is at x=2803715, y=2643139
|
||||
Sensor at x=600169, y=3131140: closest beacon is at x=1163688, y=2000000
|
||||
Sensor at x=163617, y=1082438: closest beacon is at x=1163688, y=2000000
|
||||
Sensor at x=3728368, y=140105: closest beacon is at x=3732654, y=-724773
|
||||
Sensor at x=1187681, y=2105247: closest beacon is at x=1163688, y=2000000
|
||||
Sensor at x=2327144, y=3342616: closest beacon is at x=2445544, y=3467698
|
||||
50
2022/inputs/16.txt
Normal file
50
2022/inputs/16.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
Valve QJ has flow rate=11; tunnels lead to valves HB, GL
|
||||
Valve VZ has flow rate=10; tunnel leads to valve NE
|
||||
Valve TX has flow rate=19; tunnels lead to valves MG, OQ, HM
|
||||
Valve ZI has flow rate=5; tunnels lead to valves BY, ON, RU, LF, JR
|
||||
Valve IH has flow rate=0; tunnels lead to valves YB, QS
|
||||
Valve QS has flow rate=22; tunnel leads to valve IH
|
||||
Valve QB has flow rate=0; tunnels lead to valves QX, ES
|
||||
Valve NX has flow rate=0; tunnels lead to valves UH, OP
|
||||
Valve PJ has flow rate=0; tunnels lead to valves OC, UH
|
||||
Valve OR has flow rate=6; tunnels lead to valves QH, BH, HB, JD
|
||||
Valve OC has flow rate=7; tunnels lead to valves IZ, JR, TA, ZH, PJ
|
||||
Valve UC has flow rate=0; tunnels lead to valves AA, BY
|
||||
Valve QX has flow rate=0; tunnels lead to valves AA, QB
|
||||
Valve IZ has flow rate=0; tunnels lead to valves OC, SX
|
||||
Valve AG has flow rate=13; tunnels lead to valves NW, GL, SM
|
||||
Valve ON has flow rate=0; tunnels lead to valves MO, ZI
|
||||
Valve XT has flow rate=18; tunnels lead to valves QZ, PG
|
||||
Valve AX has flow rate=0; tunnels lead to valves UH, MO
|
||||
Valve JD has flow rate=0; tunnels lead to valves OR, SM
|
||||
Valve HM has flow rate=0; tunnels lead to valves TX, QH
|
||||
Valve LF has flow rate=0; tunnels lead to valves ZI, UH
|
||||
Valve QH has flow rate=0; tunnels lead to valves OR, HM
|
||||
Valve RT has flow rate=21; tunnel leads to valve PG
|
||||
Valve NE has flow rate=0; tunnels lead to valves VZ, TA
|
||||
Valve OQ has flow rate=0; tunnels lead to valves TX, GE
|
||||
Valve AA has flow rate=0; tunnels lead to valves QZ, UC, OP, QX, EH
|
||||
Valve UH has flow rate=17; tunnels lead to valves PJ, NX, AX, LF
|
||||
Valve GE has flow rate=0; tunnels lead to valves YB, OQ
|
||||
Valve EH has flow rate=0; tunnels lead to valves AA, MO
|
||||
Valve MG has flow rate=0; tunnels lead to valves TX, NW
|
||||
Valve YB has flow rate=20; tunnels lead to valves IH, GE, XG
|
||||
Valve MO has flow rate=15; tunnels lead to valves EH, ON, AX, ZH, CB
|
||||
Valve JR has flow rate=0; tunnels lead to valves ZI, OC
|
||||
Valve GL has flow rate=0; tunnels lead to valves AG, QJ
|
||||
Valve SM has flow rate=0; tunnels lead to valves JD, AG
|
||||
Valve HB has flow rate=0; tunnels lead to valves OR, QJ
|
||||
Valve TA has flow rate=0; tunnels lead to valves OC, NE
|
||||
Valve PG has flow rate=0; tunnels lead to valves RT, XT
|
||||
Valve XG has flow rate=0; tunnels lead to valves CB, YB
|
||||
Valve ES has flow rate=9; tunnels lead to valves QB, FL
|
||||
Valve BH has flow rate=0; tunnels lead to valves RU, OR
|
||||
Valve FL has flow rate=0; tunnels lead to valves SX, ES
|
||||
Valve CB has flow rate=0; tunnels lead to valves MO, XG
|
||||
Valve QZ has flow rate=0; tunnels lead to valves AA, XT
|
||||
Valve BY has flow rate=0; tunnels lead to valves UC, ZI
|
||||
Valve ZH has flow rate=0; tunnels lead to valves MO, OC
|
||||
Valve OP has flow rate=0; tunnels lead to valves NX, AA
|
||||
Valve NW has flow rate=0; tunnels lead to valves MG, AG
|
||||
Valve RU has flow rate=0; tunnels lead to valves ZI, BH
|
||||
Valve SX has flow rate=16; tunnels lead to valves IZ, FL
|
||||
1
2022/inputs/17.txt
Normal file
1
2022/inputs/17.txt
Normal file
File diff suppressed because one or more lines are too long
2893
2022/inputs/18.txt
Normal file
2893
2022/inputs/18.txt
Normal file
File diff suppressed because it is too large
Load Diff
30
2022/inputs/19.txt
Normal file
30
2022/inputs/19.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
Blueprint 1: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 16 clay. Each geode robot costs 3 ore and 20 obsidian.
|
||||
Blueprint 2: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 2 ore and 15 obsidian.
|
||||
Blueprint 3: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 3 ore and 8 obsidian.
|
||||
Blueprint 4: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 2 ore and 13 obsidian.
|
||||
Blueprint 5: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 12 clay. Each geode robot costs 3 ore and 15 obsidian.
|
||||
Blueprint 6: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 2 ore and 16 obsidian.
|
||||
Blueprint 7: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 2 ore and 15 obsidian.
|
||||
Blueprint 8: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 2 ore and 10 obsidian.
|
||||
Blueprint 9: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 16 clay. Each geode robot costs 3 ore and 9 obsidian.
|
||||
Blueprint 10: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 2 ore and 8 obsidian.
|
||||
Blueprint 11: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 12 obsidian.
|
||||
Blueprint 12: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 4 ore and 20 obsidian.
|
||||
Blueprint 13: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 2 ore and 11 obsidian.
|
||||
Blueprint 14: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 2 ore and 8 obsidian.
|
||||
Blueprint 15: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 10 clay. Each geode robot costs 2 ore and 7 obsidian.
|
||||
Blueprint 16: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 9 clay. Each geode robot costs 2 ore and 20 obsidian.
|
||||
Blueprint 17: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 17 clay. Each geode robot costs 2 ore and 13 obsidian.
|
||||
Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 16 clay. Each geode robot costs 4 ore and 16 obsidian.
|
||||
Blueprint 19: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 4 ore and 13 obsidian.
|
||||
Blueprint 20: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 17 obsidian.
|
||||
Blueprint 21: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 19 obsidian.
|
||||
Blueprint 22: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 7 clay. Each geode robot costs 2 ore and 16 obsidian.
|
||||
Blueprint 23: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 17 obsidian.
|
||||
Blueprint 24: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 20 clay. Each geode robot costs 2 ore and 20 obsidian.
|
||||
Blueprint 25: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 14 clay. Each geode robot costs 3 ore and 16 obsidian.
|
||||
Blueprint 26: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 5 clay. Each geode robot costs 3 ore and 18 obsidian.
|
||||
Blueprint 27: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 19 clay. Each geode robot costs 2 ore and 12 obsidian.
|
||||
Blueprint 28: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 2 ore and 20 obsidian.
|
||||
Blueprint 29: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 6 clay. Each geode robot costs 2 ore and 10 obsidian.
|
||||
Blueprint 30: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 3 ore and 9 obsidian.
|
||||
5000
2022/inputs/20.txt
Normal file
5000
2022/inputs/20.txt
Normal file
File diff suppressed because it is too large
Load Diff
2755
2022/inputs/21.txt
Normal file
2755
2022/inputs/21.txt
Normal file
File diff suppressed because it is too large
Load Diff
202
2022/inputs/22.txt
Normal file
202
2022/inputs/22.txt
Normal file
File diff suppressed because one or more lines are too long
73
2022/inputs/23.txt
Normal file
73
2022/inputs/23.txt
Normal file
@@ -0,0 +1,73 @@
|
||||
#.##.##...####..#.##.##....###....##...#..#####..#.##.##.#...###.##..#.##
|
||||
.#....#..#.##..#.#.#...#..#..####..#.#.##.#.#..#.#..#.#..##.#..........#.
|
||||
##.#####.###.#...######..###.#.#..##.#.##.#......#..##.....###.#.##.##.##
|
||||
..#######.####.#..###...####..####....#.####.#.#..#.#.###.##.###.##..#...
|
||||
.#..#.##...#...####.....##.#.#..#...###.....##..#.##..#.#.#.##.##.#.#.#..
|
||||
####.#...#.#..##..###.####.#######.....#.##.#..#.#...#.##.#....#.........
|
||||
..#.#.####...###.##.#..#.....#.##...#.#.####.....#..##....#..#####...##..
|
||||
#####..##.....#.##..#.####....#.#....#.##....#.#....##.#####.#...####..##
|
||||
#.#..#####.###..####..#.##..#######....##..#.###.#.#....##.#..##.##..#..#
|
||||
..##.#.##.....###..#..#..#.####....#..####..##.###...#..#..#...##..##..##
|
||||
#.###.##.#...##.##.#.##..####.##.#.#.###...##.#....#.#.#.##.##...#.##.#.#
|
||||
.#####..###.#.###.###....#..#..#....#.##.#.###.#.####..###.#####.#.#####.
|
||||
...#..##.##.#.#.###.#######.##.#...##..##...#......#..####.#.#...#.#####.
|
||||
.#..###..######..#.#.##.##.#.##....##.#...#...#..#.#.##.#...#.#..#...#.##
|
||||
##..#.#...#.###.#..#..#.###.###..###.#.......#####.##.####..#...#..#....#
|
||||
...#..###...#...###.#.....#.###.##.###.####.##.....##..##.#.##.#.#...#.##
|
||||
####.#......#..###..#.#...##.#.##..#...#.###...#..##.#..#.....####.##.###
|
||||
##....#..#####..#####....##.#####.##.###..#.#####..###.##..#.#..###.#.###
|
||||
##.##...##.###.#.#..#####...#..#...#....#..#.#.#.......##..#...#..######.
|
||||
......#.###.#.##..####..#..##..##.###.#..##...#...#...#...#.###.#.#.##.##
|
||||
....##..#...##.##.#.#.#..#..#.#...####.#.....#.#.#.##.#.....##.#...#.#.##
|
||||
..#..###.#..###.####..#.#....#..##.#.##..###...#.##.#.####.##.#.#.#.#...#
|
||||
...###.....####.######...####.....#.#.#.#...#..##.##...#.###..###.#.#####
|
||||
#.##..#.##.#......#####..#...####.#...###...###.##...##.##...###.###.##.#
|
||||
###....#..#.###..#.####.##.#...##..#..#..#....###...#......#..#..##.#.###
|
||||
.####.#.###..#########...#.##############.##...#.##.##.#..#.#.##.#.#.###.
|
||||
.#.##...#...###..#..#.#.#..#.#.#.#.##........#.##.#.#.##.##.#.#.##.######
|
||||
##.#.#.###..###.###.#.#.....#.###..####.#.#..##.#.##..#.####..#.......##.
|
||||
.#.#####.#..###..##.#..#...#.#.##..#..#..#..##.####.##.#..###.#......#...
|
||||
.##..##..#..#.#..###...#.#.##.###..#..#...#.##.#.##..#.#.##..#....#...#..
|
||||
..#......###..###..##...##.###..##.#.....#.###...##.##..#...#..#.#..#....
|
||||
.#.#.#.#.#...###.#######..#..###...#.###.#.###.##....#...#.##......####..
|
||||
#...#.##.#...#.#.#.###.#..#.#..##.###.######.#.#....###.##...#....#....#.
|
||||
.###....#..####.#..#....##.#..##..#..#.#####.#.#...##.##...####.###.##..#
|
||||
#...#.#...#...##.#####.#.#...##..#..##.#...#...###....##.######.#..#.##.#
|
||||
#...##...##..#......####.#.#.##.##.#.......####...####...#..#..#.#..#.##.
|
||||
.###....#.####..##.###..#....#...##.###..#...#.##.#...#####.###..#..#..##
|
||||
##.#..##..###.#..#..####...#.##.##..#......####....#....#.###..##......##
|
||||
##.##....#####.##.###.######..#..####..##.#.####.#..####.##...##....#####
|
||||
.##.#..##..#.##..###.....#..#.##..####...#.##...#.#.#.#..##.###.....##...
|
||||
.##.#...#...####..##.#....##...#..###.#.#..#....##.######.#...##.###..##.
|
||||
##.##.###..#.##.#..#....#.##.#.##..#...#..##.#.####..##.##...#..##.##..##
|
||||
.#..###.#.#.##..#..#.####.#.##.#..##.#....#.###.##..#.###...#..#....###..
|
||||
####..#.#..###..#...##.##.###.##...#.##.##...##..#.##.##...#.#..#.#.#.#..
|
||||
..###...#..#...........#.###.##..#..###..##.#.##.#...#.#..#.....##..#####
|
||||
.....##....###..###.###..#..#...##..#......#.##..#.#.#..##..#.###.....#.#
|
||||
..####.#......#...#.#.#.#..#..##....##..#.#...##.##.##.###.###...###...#.
|
||||
##..#.#.#.##.###########.#.###....####.##.#.#...####..#.##.#...##...#....
|
||||
##...#..#...####.#.####....#.########.######..###....###..##..#...#.###..
|
||||
##.###.####..#.##.#.#####.##.###..#.#.#.##.##.##.####.##.#...#..#..##....
|
||||
.#..#.#.##..##...#....#.#....#....###..#..##..###.##.####.##.####.##.#...
|
||||
##.#.##.##...#.#..#.#...##...#...#..#......#.###......###.....#.#.#####.#
|
||||
..#.##.##.###....#.#..###..#..##.####.###.##..##.##....#...##.#..#..##.##
|
||||
#####.#...#..##..##.#.#.....##..#..##.##.##.####..#####.#..###..#.##..##.
|
||||
####.##..........###.###.#####.#.#..##...##.....#..###..##..#.####..#.##.
|
||||
#.....##.####...#..##.##..#..#....##..#...#..#.#.....#..#...#.###.##.#..#
|
||||
#.#.##..###.#...##.#...###.#......#....##..##.##.###.#.#.#..#.##.####..##
|
||||
##..###.#.#......##.##.##.#.#####.#.#.###...###.##.#......#.##########..#
|
||||
.####....#..#...###.#..##.#.####..#.#..######.#.####..##....###..##..#..#
|
||||
#..##.#.#...##.#.#.########.....#.##...#....#.####.###.########.#.##.#...
|
||||
#.#######..#.##.#.#.#..####..##.#..###.####.#..#########....####....###..
|
||||
..##.#...##...#..###.#..##.#..#...##.####.######.####.#..##.#...#.#..###.
|
||||
.#..##.#.##..#......##.#.#.##.#####.#.###....#...###...#....#.###.....###
|
||||
#......#.#..##....##.########.#..#..##.##......#.#..######..##.##..##.###
|
||||
..##...#...#.#..#.#########..##..#####..#..#..##.#....##...#.#....##.#.#.
|
||||
.##..###.####.#..#####.###..###..#......##...#.....####..###..#..##.#.##.
|
||||
......###.#..#...#..#.#.##.#.###...##.#.#....####.#..#.######.#.#...####.
|
||||
...#.##.####....##..##.#.###.###.....#..###...####..##..######.#..##.....
|
||||
.....####.....###.#.#.......#####.#.#....##...#####..#..#.#..#.#.#..##.##
|
||||
##..##.#..##..#..#.#####..##.####.#...#.#..#..###..#..#....#...#.###.##..
|
||||
#.#..#.#########.####..#####..####.#.#####....#.#..##...#..####.#..###.#.
|
||||
#..##.###.##..#....#...#..#.##..#..###..#####..#######.#####....#.##.....
|
||||
####.####.########.#.###....#.#..#..#.#.#.#..#....#..#.....#..##..#.##.#.
|
||||
27
2022/inputs/24.txt
Normal file
27
2022/inputs/24.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
#.########################################################################################################################
|
||||
#<^^^^v^><<v<v.v<>><^><v<vv^vv<^^.^v^.v.<<<<v.vv<.>^^><v.^>v^>^>^^v>>v^^^.<v<>v<>.<>v^^^^^^>>^^.^^>>vv><^v<^.<v><^^v^<<<>#
|
||||
#<>>>^^v^>v>v>^^^^.<<<>><^^>>^^<>v^v^v>^v>v>^vv.vvv>v<^^<<v>v^^><^>.>^^^.><^^<v.<^^>.v<vv<^>^<<<<v^vv>>>>v^.^v.>>>^v.>.v>#
|
||||
#.v^v>vv.v<<^v>^<^v<.v<<.>>^vv<.^v^<^^>^<vv^vv>><^vv<<v>^^^vvv<v.><^.<v<^>>>.^<^<.v<^<^v>><^^^><^>>v^<^<v>^>>v^v<><^vv<v<#
|
||||
#>.>>^<^v>v^.><^^.>.^>v>^^><vv>v><.^v<>^<<vvvv.<>>>^v.v<vv>.v..v^>><<v.^.^^v>^^v<v>>>^v<vvv.<^^<<>^>^.>v^^>^v<^v^v<>.<v<<#
|
||||
#<v^^>v>vvvv<^^.^<^v><v<>v^>v<^<^^^<>^<<v<^>^^.<^v^^<<>.>vvv^^^v<v.^^^^<<<>^v^><^>v>><^.<^^^<>^v^v>^^v>>v>v<v><>v.^><v>>>#
|
||||
#<^v>..>^>vv>v<<v>.v>vv>v^v<<<<<<<<v^^<v<.v.^<>>^>^^<>^^<>v<v.<^<.vvvvv>v^.^><<v>v<>>v.v.v^^>v<^v<^>v^v><<.<^^>v^vv<^^vv>#
|
||||
#>v^^v^v>.<.^vv.^<<<<.<v>>v>>v^<.<><>v><<<^.<>v><.v^<v><<.><<<^^vv>^>v<<<>^<.^v>vv^<<^.>^<^^v<<vvvvv><^>v>^.>>>.v^.v^vv<>#
|
||||
#<<<>>...v^^>^v<^v>>><<<>>vv^^<^^>^v<.>v^.>>v<<v>>>>^><.>v^.^vv><v^<.^v<^v<<<.^v^^^^<>^v>^>>>vv^<<.^>>v><vvvv<>v^<>><v<v>#
|
||||
#>.>><vvv<<>v<><^><v>>.^<>.>^v^.<^.<>^>v^.><<^>><v><>..v<>^^<^.>><<^<<^<.^>^.vv^^>^.^>^.v^>v<>^^vv<.<>>><<^v>v<<>>v><^^<>#
|
||||
#<<>.v<<<>^.vv<^v>.>^<><>v^.v<>v<>>vv<<.^^<<>^>>.><v<^<v^.>^vvv<vv.^^.^><v^v^v^<>v.vv>v>.>v.vv<<v^<>^^^^<v^^^.>v.vv^<..><#
|
||||
#>.<<<v<>vv>>^v>vvv<^<>.vvv^<^>v<>^^<v^..><.<^<><>^^^^<^>.<v^>>v>^>v>^<><<v>v>v<^^<v>v>v>><>^v<.^v^><v^^<v^>v><..^.v<^<v>#
|
||||
#>>^<^<v<<^vv>^^<>^<<>.<<v<^v^^v>.vv<><<v>^<>^><v^>.>>v^^<^^^^>v^^^^vv<>>><<^^<<><<<>v^<v^v<^.<>>>>^v>^><<<^^><vv<<<^<.<>#
|
||||
#<^>.vv>>^.v.>^^v>.^<>>^<<..<v><^><><^v<v<^v^>^^^>v<^^.<>v.<<v<vv.>v^^<^<>>>vvv<^<^v><v>v>v^>..^<v<vv<<^^^v>.^><v<>^>><>>#
|
||||
#>^<><<>^<<v><^>v^.v><>.<<^>>.<^^<v<<^>.>v.>v>><^^<>vv<<<>v.<vv><v<<.<>v<<.vv<><>>^vv<>v>vv^.<v<v<>><.v^v><.v^.v^v>>v>>v<#
|
||||
#<<>><^^<v.v<<vv>>.<>v>>^^<^v.<v^<vv.vvv<><<<^v.^^<.><v<v<..v^>v^.^v^>v<>^v<<^<>vvv><>>v^^^>v<<<>.^<vv^>^>v^v^^.><<.>>^^>#
|
||||
#<^.v^>^v>^<^><<^v^>v^<><<^^^v<<^.v^v<>^.>.v<<<v^vv^^v.<v<^^<^v^.><^^>v.<v<<^^<vv<>>>.<>^.^v>v>v><^><<<>.^^<>v.<.v><><v><#
|
||||
#><<^>^<v<>^^^vv^>>.vv>vvv^v^>^^>v<<>^^^^>^>v<>>v^v>v><>.^vv^<>>>><<<>^>^.>..vv>^^^<^>v<>>^v><v<>^vv>v>^^vv<><^>^^^..>>>>#
|
||||
#><vv^<v^^>><<v<v.<.v^..v><^v<<>^v>.^><v><^^v^<^<v><vvv^^v^><^v.><vv><^>^<v^v><v<.>^><^<<<v>>>v<><.^<^>^v<<^^>.<>vv<^.<v>#
|
||||
#<.^^>><>><>><><>^.^>.vv^>>><<><vvvvv^v<<^^>.^..>><<<v>>.<>v<^<vv<^^.v^>>v<>vv^>vv<^<><<.vv><.<^^><>.vv<<><v>><>v<vvvv^.>#
|
||||
#<v<<.^..v<>v><v<>>^<<.><^<v<^vv>vv>>v>^^<^^^>v^^>><^v<^.<<^^v<^v>>^.^<v.<>^v<^v^>v><v<>>^.>v.>>v>.>^v<>v<v>v<v<.>vv><.>>#
|
||||
#<v^vv>>v<<.<v^<<.>^<^v<>v^^<>.v^>^v<v>>>vv>^^>>>v<<<><<^^.>>^><>^<v<>>.v>^>v^^>^^>>>v>v^>>v>^^.v>.vvv>.v<>.^^<<<^vv^>^^>#
|
||||
#>v^^.v^<.<^v<>.^<><>^^^.v.<<.^<^v<vv^v^>v^>^v.^.v^>vvv<^<>^>^^v>v>v^.v^^>^>>^>^v^>^v^^.><^.^^>^^<^><>>^>.>.^^^v<<<v.>v>.#
|
||||
#<v><>v<^^<><<vv.v><v>.vv^><.v^.<v^v.><>^<>.^<<vvv^vv^>v.^v>.><^^<.>>vvv><^<^<v>v<^v.^^><>>>.<^^<v<v^^.^v<^>^<v^<>>v>>>><#
|
||||
#><^^v>>>vv>^<<<<>>v>vv<vv<>>>><v>.v<<.<>><v^.<>.<<^vv>^><v<^>^<<v^<^><>>.v<^vv<vv<><^<>.vv^v^^<>>vvv<>^<v<<v<<v^<v<^>^^>#
|
||||
#<v..<.vv<v<>vvv^..v>^v^><^<^>>^.v^^<><>>v^>><><<v<v>><^^^v>vv><<^<.>>>v<v.><>v><>>^^<<.>>.><>vv>.^^vv>>>^vv^<^>^<^<^<<^>#
|
||||
########################################################################################################################.#
|
||||
126
2022/inputs/25.txt
Normal file
126
2022/inputs/25.txt
Normal file
@@ -0,0 +1,126 @@
|
||||
2=1
|
||||
2=-02211=
|
||||
2=-1111=2-0-20=
|
||||
2=2-=12
|
||||
1--2-=2211-221
|
||||
1=20011
|
||||
1221=021-0=2011-1
|
||||
1=00=202011=
|
||||
200=121-=2-11=21
|
||||
2-21002021202
|
||||
1-11=12011112
|
||||
1==2-=0-=2-0-0
|
||||
20=-12--12
|
||||
101122=222021221-
|
||||
12=2200-1==1=12=1=1
|
||||
2==-21=-=2
|
||||
1==-1222-1==2-
|
||||
111-2-2=0
|
||||
1=2
|
||||
1=20=-00=22
|
||||
1=2=0-2101=2
|
||||
10=
|
||||
10-=12101-102=1=
|
||||
12=11=-
|
||||
1202=0--0-2==0
|
||||
1-0--
|
||||
10210210-10021=2-2
|
||||
22=
|
||||
12-110101
|
||||
2=-===0=0=11--
|
||||
2=21022-00-
|
||||
2-111102102--201=0
|
||||
2=-2=
|
||||
12=22=11-1000=121
|
||||
11=10-02111211
|
||||
20210121--0=1=-=
|
||||
1=-
|
||||
10=-==02-20-0=01
|
||||
21=0=-=
|
||||
2=10002
|
||||
1-0102-020201121
|
||||
11---01101=--
|
||||
1=-1=-=-011
|
||||
211-00-2==21==
|
||||
21
|
||||
1201-1202=2-0
|
||||
21000=2=1-=10--2
|
||||
1=0=
|
||||
1-1
|
||||
1-2---=1====-0210=-0
|
||||
2-220-=
|
||||
122-
|
||||
110200-0
|
||||
2=--2
|
||||
20112=0-2022-
|
||||
1=-0--
|
||||
1=-01-0-10=2=0===-
|
||||
1=22=2=--11=-0-2111
|
||||
1==00-1=00=0-
|
||||
1=2212-1-=201
|
||||
2-200=2001
|
||||
2222012-10-0=-0=
|
||||
1-====
|
||||
100=2200
|
||||
1-11==0
|
||||
1--2111-1
|
||||
1---2121-202210=2
|
||||
11222=
|
||||
1=2102-2221-111-
|
||||
111
|
||||
1=
|
||||
1--0=-1
|
||||
10=00=10=---1=-
|
||||
1=0==-2
|
||||
220002
|
||||
1==211-0=222102-
|
||||
1-==-121021
|
||||
1202-1=01--202
|
||||
12=-0===11=0
|
||||
20-001=
|
||||
1000-2-==2=-
|
||||
1=01--
|
||||
10=--01221
|
||||
1-=2-=0=-0==10-22-
|
||||
2021212-1020=002
|
||||
11===1==-2-01-21
|
||||
2-00-10-
|
||||
12-0221212000
|
||||
201==
|
||||
20011
|
||||
2---0=1222--02
|
||||
20-
|
||||
10-=02010
|
||||
101--0202=-2=1==01
|
||||
2=0121-02112-0=
|
||||
2-=-=1011
|
||||
11-=02
|
||||
110-2001
|
||||
1==011-12000101-11
|
||||
2=
|
||||
1-11-=--=
|
||||
110
|
||||
101=21
|
||||
1=11
|
||||
212-10020-212111-2
|
||||
102=22
|
||||
1-
|
||||
1-02=22-=1==2
|
||||
11=10-00-=00-00=-
|
||||
220200-=2
|
||||
1-0=----
|
||||
1022=0-2--==--1
|
||||
1-=201-1021
|
||||
2=-1-10=1=-2020=00
|
||||
12201=0102-0110=-
|
||||
20=2
|
||||
2020=-===1==-212
|
||||
1=0-222-2=22=-=
|
||||
1=--12==0100=-21
|
||||
1=1-2
|
||||
1=-220001=1
|
||||
20
|
||||
1=1
|
||||
1=0=-=1=0-=01
|
||||
202102-200
|
||||
2-=2-110012
|
||||
236
2022/src/common.rs
Normal file
236
2022/src/common.rs
Normal file
@@ -0,0 +1,236 @@
|
||||
//! Common helper utilities to all days
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::ops::Add;
|
||||
use std::ops::Div;
|
||||
use std::ops::Index;
|
||||
use std::ops::IndexMut;
|
||||
use std::ops::Sub;
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
/// Some magic to get two mutable references into the same slice
|
||||
pub fn get_both<T>(slice: &mut [T], first: usize, second: usize) -> (&mut T, &mut T) {
|
||||
match first.cmp(&second) {
|
||||
Ordering::Greater => {
|
||||
let (begin, end) = slice.split_at_mut(first);
|
||||
(&mut end[0], &mut begin[second])
|
||||
}
|
||||
Ordering::Less => {
|
||||
let (begin, end) = slice.split_at_mut(second);
|
||||
(&mut begin[first], &mut end[0])
|
||||
}
|
||||
Ordering::Equal => panic!("Tried to get the same index twice {first}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct IndexSet(Vec<u32>);
|
||||
|
||||
impl IndexSet {
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self(Vec::with_capacity(
|
||||
capacity / std::mem::size_of::<u32>() / 8,
|
||||
))
|
||||
}
|
||||
|
||||
fn ensure_item(&mut self, item: usize) -> &mut u32 {
|
||||
if self.0.len() <= item {
|
||||
self.0.resize(item + 1, 0);
|
||||
}
|
||||
|
||||
&mut self.0[item]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn index(index: usize) -> (usize, u8) {
|
||||
const PER_ENTRY: usize = 8 * std::mem::size_of::<u32>();
|
||||
|
||||
(index / PER_ENTRY, (index % PER_ENTRY) as u8)
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, index: usize) -> bool {
|
||||
let (entry, pos) = Self::index(index);
|
||||
|
||||
let item = self.ensure_item(entry);
|
||||
|
||||
if *item & (1 << pos) != 0 {
|
||||
false
|
||||
} else {
|
||||
*item |= 1 << pos;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains(&self, index: usize) -> bool {
|
||||
let (entry, pos) = Self::index(index);
|
||||
|
||||
self.0
|
||||
.get(entry)
|
||||
.map_or(false, |&entry| (entry & (1 << pos) != 0))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Vec2(pub [i32; 2]);
|
||||
|
||||
impl Vec2 {
|
||||
pub fn l1(self) -> i32 {
|
||||
self.0.into_iter().map(i32::abs).sum()
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Self> for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self([self[0] + rhs[0], self[1] + rhs[1]])
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Self> for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self([self[0] - rhs[0], self[1] - rhs[1]])
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<i32> for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
fn div(self, rhs: i32) -> Self::Output {
|
||||
Self(self.0.map(|v| v / rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for Vec2 {
|
||||
type Output = i32;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
&self.0[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<usize> for Vec2 {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
&mut self.0[index]
|
||||
}
|
||||
}
|
||||
50
2022/src/day01.rs
Normal file
50
2022/src/day01.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
125
2022/src/day02.rs
Normal file
125
2022/src/day02.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
79
2022/src/day03.rs
Normal file
79
2022/src/day03.rs
Normal file
@@ -0,0 +1,79 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
86
2022/src/day04.rs
Normal file
86
2022/src/day04.rs
Normal file
@@ -0,0 +1,86 @@
|
||||
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")
|
||||
}
|
||||
}
|
||||
151
2022/src/day05.rs
Normal file
151
2022/src/day05.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
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::combinator::value;
|
||||
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::get_both;
|
||||
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
|
||||
value(None, tag(" ")),
|
||||
)),
|
||||
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)))
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
68
2022/src/day06.rs
Normal file
68
2022/src/day06.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
124
2022/src/day07.rs
Normal file
124
2022/src/day07.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
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 <= 100_000).sum();
|
||||
|
||||
Ok(searched_size.to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
const TARGET: u32 = 30_000_000;
|
||||
const TOTAL: u32 = 70_000_000;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
136
2022/src/day08.rs
Normal file
136
2022/src/day08.rs
Normal file
@@ -0,0 +1,136 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
122
2022/src/day09.rs
Normal file
122
2022/src/day09.rs
Normal file
@@ -0,0 +1,122 @@
|
||||
use ahash::AHashSet;
|
||||
use anyhow::Result;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::take;
|
||||
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;
|
||||
use crate::common::Vec2;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Direction {
|
||||
Up,
|
||||
Left,
|
||||
Right,
|
||||
Down,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
fn vec_for(self) -> Vec2 {
|
||||
Vec2(match self {
|
||||
Direction::Up => [0, -1],
|
||||
Direction::Left => [1, 0],
|
||||
Direction::Right => [-1, 0],
|
||||
Direction::Down => [0, 1],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for Direction {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
b'U' => Ok(Direction::Up),
|
||||
b'L' => Ok(Direction::Left),
|
||||
b'R' => Ok(Direction::Right),
|
||||
b'D' => Ok(Direction::Down),
|
||||
b => anyhow::bail!("Invalid direction '{b}'"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_moves(input: &[u8]) -> IResult<&[u8], Vec<(Direction, u32)>> {
|
||||
many0(terminated(
|
||||
separated_pair(
|
||||
map_res(take(1usize), |bs: &[u8]| Direction::try_from(bs[0])),
|
||||
tag(" "),
|
||||
nom::character::complete::u32,
|
||||
),
|
||||
newline,
|
||||
))(input)
|
||||
}
|
||||
|
||||
fn part_generic<const N: usize>(input: &[u8]) -> Result<String> {
|
||||
let moves = parse_input(input, parse_moves)?;
|
||||
|
||||
let mut head_pos = Vec2([0, 0]);
|
||||
let mut tails = [head_pos; N];
|
||||
|
||||
let mut visited = AHashSet::new();
|
||||
visited.insert(head_pos);
|
||||
|
||||
for (direction, steps) in moves {
|
||||
let step = direction.vec_for();
|
||||
|
||||
for _ in 0..steps {
|
||||
head_pos = head_pos + step;
|
||||
|
||||
let mut ref_pos = head_pos;
|
||||
|
||||
for tail_pos in &mut tails {
|
||||
let delta = ref_pos - *tail_pos;
|
||||
|
||||
if delta[0].abs() <= 1 && delta[1].abs() <= 1 {
|
||||
break;
|
||||
}
|
||||
|
||||
let step = Vec2([delta[0].signum(), delta[1].signum()]);
|
||||
|
||||
*tail_pos = *tail_pos + step;
|
||||
|
||||
ref_pos = *tail_pos;
|
||||
}
|
||||
|
||||
visited.insert(*tails.last().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(visited.len().to_string())
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
part_generic::<1>(input)
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
part_generic::<9>(input)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/09.txt");
|
||||
const SAMPLE_LARGE: &[u8] = include_bytes!("samples/09.large.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "13");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "1");
|
||||
assert_eq!(part2(SAMPLE_LARGE).unwrap(), "36");
|
||||
}
|
||||
}
|
||||
131
2022/src/day10.rs
Normal file
131
2022/src/day10.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
use anyhow::Result;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::iterator;
|
||||
use nom::combinator::map;
|
||||
use nom::combinator::value;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Instruction {
|
||||
AddX(i32),
|
||||
Noop,
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
#[inline]
|
||||
pub fn cycles(self) -> i32 {
|
||||
match self {
|
||||
Instruction::AddX(_) => 2,
|
||||
Instruction::Noop => 1,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn execute(self, x: &mut i32, cycle: &mut i32) {
|
||||
*cycle += self.cycles();
|
||||
|
||||
if let Instruction::AddX(v) = self {
|
||||
*x += v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_instruction(input: &[u8]) -> IResult<&[u8], Instruction> {
|
||||
terminated(
|
||||
alt((
|
||||
value(Instruction::Noop, tag("noop")),
|
||||
map(preceded(tag("addx "), nom::character::complete::i32), |v| {
|
||||
Instruction::AddX(v)
|
||||
}),
|
||||
)),
|
||||
newline,
|
||||
)(input)
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let mut x = 1;
|
||||
// Count from one like a scrub
|
||||
let mut cycle = 1;
|
||||
|
||||
let mut input_it = iterator(input, parse_instruction);
|
||||
|
||||
let mut total = 0;
|
||||
|
||||
for instruction in &mut input_it {
|
||||
let old_cycle = cycle;
|
||||
let old_x = x;
|
||||
|
||||
instruction.execute(&mut x, &mut cycle);
|
||||
|
||||
if old_cycle % 40 < 20 && cycle % 40 >= 20 {
|
||||
let to_report = if cycle % 40 == 20 { x } else { old_x };
|
||||
|
||||
let checkpoint = cycle / 20 * 20;
|
||||
total += to_report * checkpoint;
|
||||
}
|
||||
|
||||
if cycle >= 220 {
|
||||
return Ok(total.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
anyhow::bail!("out of instructions")
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let mut x = 1;
|
||||
let mut input_it = iterator(input, parse_instruction);
|
||||
let mut input_it = (&mut input_it).peekable();
|
||||
|
||||
let mut output = String::with_capacity(6 * (40 + 1));
|
||||
|
||||
let mut cpu_cycle = 0;
|
||||
|
||||
for crt_cycle in 1..=240 {
|
||||
if let Some(instruction) = input_it.next_if(|i| cpu_cycle + i.cycles() < crt_cycle) {
|
||||
instruction.execute(&mut x, &mut cpu_cycle);
|
||||
}
|
||||
|
||||
let beam_pos = (crt_cycle + 39) % 40;
|
||||
|
||||
if (beam_pos - x).abs() <= 1 {
|
||||
output.push('#');
|
||||
} else {
|
||||
output.push(' ');
|
||||
}
|
||||
|
||||
if crt_cycle % 40 == 0 {
|
||||
output.push('\n');
|
||||
}
|
||||
}
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/10.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "13140");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
let answer = "## ## ## ## ## ## ## ## ## ##
|
||||
### ### ### ### ### ### ###
|
||||
#### #### #### #### ####
|
||||
##### ##### ##### #####
|
||||
###### ###### ###### ####
|
||||
####### ####### ####### \n";
|
||||
|
||||
assert_eq!(part2(SAMPLE).unwrap(), answer);
|
||||
}
|
||||
}
|
||||
189
2022/src/day11.rs
Normal file
189
2022/src/day11.rs
Normal file
@@ -0,0 +1,189 @@
|
||||
use anyhow::Result;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::take;
|
||||
use nom::character::complete::digit1;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::combinator::map_res;
|
||||
use nom::combinator::value;
|
||||
use nom::multi::separated_list0;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::sequence::delimited;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::separated_pair;
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
use strength_reduce::StrengthReducedU64;
|
||||
|
||||
use crate::common::parse_input;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum Operation {
|
||||
Mul(u64),
|
||||
Add(u64),
|
||||
Square,
|
||||
}
|
||||
|
||||
impl Operation {
|
||||
fn transform(self, worry: u64) -> u64 {
|
||||
match self {
|
||||
Operation::Mul(val) => worry * val,
|
||||
Operation::Add(val) => worry + val,
|
||||
Operation::Square => worry * worry,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Monkey {
|
||||
items: Vec<u64>,
|
||||
operation: Operation,
|
||||
test_mod: StrengthReducedU64,
|
||||
targets: [usize; 2],
|
||||
inspected: usize,
|
||||
}
|
||||
|
||||
impl Monkey {
|
||||
fn handle_items(&mut self, drains: &mut [Vec<u64>; 2]) {
|
||||
self.inspected += self.items.len();
|
||||
|
||||
for item in self.items.drain(..) {
|
||||
let mut new_val = self.operation.transform(item);
|
||||
// Miraculously get less worried
|
||||
new_val /= 3;
|
||||
|
||||
drains[usize::from(new_val % self.test_mod == 0)].push(new_val);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_items2(&mut self, drains: &mut [Vec<u64>], mod_base: StrengthReducedU64) {
|
||||
self.inspected += self.items.len();
|
||||
|
||||
for item in self.items.drain(..) {
|
||||
let mut new_val = self.operation.transform(item);
|
||||
// Modular arithmetic is a good way to get less worried
|
||||
new_val = new_val % mod_base;
|
||||
|
||||
drains[usize::from(new_val % self.test_mod == 0)].push(new_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_operation(input: &[u8]) -> IResult<&[u8], Operation> {
|
||||
preceded(
|
||||
tag("new = old "),
|
||||
alt((
|
||||
map_res(
|
||||
separated_pair(take(1usize), tag(" "), nom::character::complete::u64),
|
||||
|(op, val): (&[u8], u64)| match op[0] {
|
||||
b'*' => Ok(Operation::Mul(val)),
|
||||
b'+' => Ok(Operation::Add(val)),
|
||||
_ => Err(anyhow::anyhow!("Invalid operation {op:?}")),
|
||||
},
|
||||
),
|
||||
value(Operation::Square, tag("* old")),
|
||||
)),
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_monkey(input: &[u8]) -> IResult<&[u8], Monkey> {
|
||||
use nom::character::complete::u64;
|
||||
|
||||
map(
|
||||
preceded(
|
||||
// Skip the useless header line
|
||||
tuple((tag("Monkey "), digit1, tag(":\n"))),
|
||||
// Parse the actual interesting bits of the monkey
|
||||
tuple((
|
||||
// Parse the starting items
|
||||
delimited(
|
||||
tag(" Starting items: "),
|
||||
separated_list1(tag(", "), u64),
|
||||
newline,
|
||||
),
|
||||
// Parse operation
|
||||
delimited(tag(" Operation: "), parse_operation, newline),
|
||||
// Parse the test
|
||||
delimited(tag(" Test: divisible by "), u64, newline),
|
||||
// Parse both cases
|
||||
delimited(tag(" If true: throw to monkey "), u64, newline),
|
||||
delimited(tag(" If false: throw to monkey "), u64, newline),
|
||||
)),
|
||||
),
|
||||
|(items, operation, test_mod, if_true, if_false)| Monkey {
|
||||
items,
|
||||
operation,
|
||||
test_mod: StrengthReducedU64::new(test_mod),
|
||||
targets: [if_false as usize, if_true as usize],
|
||||
inspected: 0,
|
||||
},
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_monkeys(input: &[u8]) -> IResult<&[u8], Vec<Monkey>> {
|
||||
separated_list0(newline, parse_monkey)(input)
|
||||
}
|
||||
|
||||
fn format_result(mut monkeys: Vec<Monkey>) -> Result<String> {
|
||||
monkeys.sort_by(|a, b| b.inspected.cmp(&a.inspected));
|
||||
|
||||
let result: usize = monkeys[0].inspected * monkeys[1].inspected;
|
||||
|
||||
Ok(result.to_string())
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let mut monkeys = parse_input(input, parse_monkeys)?;
|
||||
let mut drains = [Vec::new(), Vec::new()];
|
||||
|
||||
for _ in 0..20 {
|
||||
for i in 0..monkeys.len() {
|
||||
monkeys[i].handle_items(&mut drains);
|
||||
|
||||
for (j, drain) in drains.iter_mut().enumerate() {
|
||||
let target = monkeys[i].targets[j];
|
||||
monkeys[target].items.append(drain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
format_result(monkeys)
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let mut monkeys = parse_input(input, parse_monkeys)?;
|
||||
let mut drains = [Vec::new(), Vec::new()];
|
||||
|
||||
let mod_base = StrengthReducedU64::new(monkeys.iter().map(|m| m.test_mod.get()).product());
|
||||
|
||||
for _ in 0..10000 {
|
||||
for i in 0..monkeys.len() {
|
||||
monkeys[i].handle_items2(&mut drains, mod_base);
|
||||
|
||||
for (j, drain) in drains.iter_mut().enumerate() {
|
||||
let target = monkeys[i].targets[j];
|
||||
monkeys[target].items.append(drain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
format_result(monkeys)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/11.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "10605");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "2713310158");
|
||||
}
|
||||
}
|
||||
109
2022/src/day12.rs
Normal file
109
2022/src/day12.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::common::IndexSet;
|
||||
|
||||
fn can_travel(from: u8, to: u8) -> bool {
|
||||
match (from, to) {
|
||||
(b'S', b'a'..=b'b') => true,
|
||||
(b'y'..=b'z', b'E') => true,
|
||||
(b'a'..=b'z', b'a'..=b'z') => to <= from || to - from == 1,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn parts_common(
|
||||
input: &[u8],
|
||||
starting_symbol: u8,
|
||||
// Neither of these functions needs to be generic closures; function pointers would do as well.
|
||||
// However, doing so causes the compiler not to inline them which in turn hurts performance by
|
||||
// about 25%. I would have hoped the reduced code size would make up for it, but it seems that
|
||||
// doesn't quite work for this particular benchmark.
|
||||
is_end: impl Fn(u8) -> bool,
|
||||
accessible: impl Fn(u8, u8) -> bool,
|
||||
) -> Result<String> {
|
||||
let width = input
|
||||
.iter()
|
||||
.position(|&c| c == b'\n')
|
||||
.context("No newlines in input")?
|
||||
+ 1;
|
||||
|
||||
let starting_pos = input
|
||||
.iter()
|
||||
.position(|&c| c == starting_symbol)
|
||||
.context("Could not find starting position")?;
|
||||
|
||||
let mut visited = IndexSet::with_capacity(input.len());
|
||||
|
||||
let mut todo = VecDeque::new();
|
||||
todo.push_back((0, starting_pos));
|
||||
|
||||
while let Some((dist, pos)) = todo.pop_front() {
|
||||
// Implementing an early exit doesn't appear to be helpful; the additional branching appears
|
||||
// to throw off the performance by 35%. Instead, we can simply wait for the destination to
|
||||
// pop off of the todo queue.
|
||||
//
|
||||
// For reference, by the time we find the exit, the queue is roughly two dozen entries long,
|
||||
// so the potential benefits of skipping it are minimal compared to the additional branching
|
||||
// code involved.
|
||||
if is_end(input[pos]) {
|
||||
return Ok(dist.to_string());
|
||||
}
|
||||
|
||||
let mut add_todo = |new: usize| {
|
||||
if accessible(input[pos], input[new]) && visited.insert(new) {
|
||||
todo.push_back((dist + 1, new));
|
||||
}
|
||||
};
|
||||
|
||||
if pos % width != 0 {
|
||||
add_todo(pos - 1);
|
||||
}
|
||||
|
||||
if pos % width != width - 1 {
|
||||
add_todo(pos + 1)
|
||||
}
|
||||
|
||||
if pos >= width {
|
||||
add_todo(pos - width);
|
||||
}
|
||||
|
||||
if pos + width < input.len() {
|
||||
add_todo(pos + width);
|
||||
}
|
||||
}
|
||||
|
||||
anyhow::bail!("Did not find a valid route")
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
parts_common(input, b'S', |b| b == b'E', can_travel)
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
parts_common(
|
||||
input,
|
||||
b'E',
|
||||
|b| b == b'a' || b == b'S',
|
||||
|a, b| can_travel(b, a),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/12.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "31")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "29")
|
||||
}
|
||||
}
|
||||
135
2022/src/day13.rs
Normal file
135
2022/src/day13.rs
Normal file
@@ -0,0 +1,135 @@
|
||||
use core::slice;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use anyhow::Result;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::multispace1;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::iterator;
|
||||
use nom::combinator::map;
|
||||
use nom::multi::separated_list0;
|
||||
use nom::sequence::delimited;
|
||||
use nom::sequence::pair;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
enum Signal {
|
||||
Number(u32),
|
||||
List(Vec<Signal>),
|
||||
}
|
||||
|
||||
impl Ord for Signal {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
fn list_cmp(a: &[Signal], b: &[Signal]) -> Ordering {
|
||||
a.cmp(b)
|
||||
}
|
||||
|
||||
match (self, other) {
|
||||
(Signal::Number(first), Signal::Number(second)) => first.cmp(second),
|
||||
(first @ Signal::Number(_), Signal::List(second)) => {
|
||||
list_cmp(slice::from_ref(first), second)
|
||||
}
|
||||
(Signal::List(first), second @ Signal::Number(_)) => {
|
||||
list_cmp(first, slice::from_ref(second))
|
||||
}
|
||||
(Signal::List(first), Signal::List(second)) => list_cmp(first, second),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Signal {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Signal {
|
||||
fn from(val: u32) -> Self {
|
||||
Signal::Number(val)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Vec<T>> for Signal
|
||||
where
|
||||
Signal: From<T>,
|
||||
{
|
||||
fn from(vec: Vec<T>) -> Self {
|
||||
Signal::List(vec.into_iter().map(Signal::from).collect())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_signal(input: &[u8]) -> IResult<&[u8], Signal> {
|
||||
alt((
|
||||
map(nom::character::complete::u32, Signal::Number),
|
||||
map(
|
||||
delimited(tag("["), separated_list0(tag(","), parse_signal), tag("]")),
|
||||
Signal::List,
|
||||
),
|
||||
))(input)
|
||||
}
|
||||
|
||||
fn parse_signal_pair(input: &[u8]) -> IResult<&[u8], (Signal, Signal)> {
|
||||
pair(
|
||||
terminated(parse_signal, newline),
|
||||
terminated(parse_signal, multispace1),
|
||||
)(input)
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let mut iterator = iterator(input, parse_signal_pair);
|
||||
|
||||
let result: usize = (&mut iterator)
|
||||
.enumerate()
|
||||
.filter_map(|(i, (first, second))| (first < second).then_some(i + 1))
|
||||
.sum();
|
||||
|
||||
Ok(result.to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let marker1 = Signal::Number(2);
|
||||
let marker2 = Signal::Number(6);
|
||||
|
||||
let mut iterator = iterator(input, terminated(parse_signal, multispace1));
|
||||
|
||||
let mut pos1 = 1;
|
||||
let mut pos2 = 2;
|
||||
|
||||
for signal in &mut iterator {
|
||||
if signal < marker1 {
|
||||
pos1 += 1;
|
||||
pos2 += 1;
|
||||
} else if signal < marker2 {
|
||||
pos2 += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Ok((pos1 * pos2).to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/13.txt");
|
||||
|
||||
#[test]
|
||||
fn test_parse_signal() {
|
||||
assert_eq!(
|
||||
parse_signal(b"[1,1,3,1,1]").unwrap(),
|
||||
(&[][..], Signal::from(vec![1, 1, 3, 1, 1]))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "13");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "140");
|
||||
}
|
||||
}
|
||||
155
2022/src/day14.rs
Normal file
155
2022/src/day14.rs
Normal file
@@ -0,0 +1,155 @@
|
||||
use anyhow::Result;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map_res;
|
||||
use nom::combinator::opt;
|
||||
use nom::sequence::separated_pair;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
use crate::common::reduce_many1;
|
||||
use crate::common::IndexSet;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Cave {
|
||||
width: usize,
|
||||
height: usize,
|
||||
occupied: IndexSet,
|
||||
floor: usize,
|
||||
}
|
||||
|
||||
impl Cave {
|
||||
pub fn insert(&mut self, x: usize, y: usize) -> bool {
|
||||
// Note: we're indexing column major for better cache locality
|
||||
self.occupied.insert(self.floor * x + y)
|
||||
}
|
||||
|
||||
pub fn drop(&mut self, x: usize, y: usize, total: &mut usize) -> bool {
|
||||
if x >= self.width || y >= self.height {
|
||||
return false;
|
||||
} else if !self.insert(x, y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// x + usize::MAX is used to compute x - 1 because usize - isize doesn't exist in stable yet.
|
||||
let supported = [0, usize::MAX, 1]
|
||||
.into_iter()
|
||||
.all(|dx| self.drop(x.wrapping_add(dx), y + 1, total));
|
||||
|
||||
if supported {
|
||||
*total += 1;
|
||||
}
|
||||
|
||||
supported
|
||||
}
|
||||
|
||||
fn drop2(&mut self, x: usize, y: usize, total: &mut usize) {
|
||||
if y >= self.floor || !self.insert(x, y) {
|
||||
return;
|
||||
}
|
||||
|
||||
*total += 1;
|
||||
|
||||
for dx in [0, usize::MAX, 1] {
|
||||
self.drop2(x.wrapping_add(dx), y + 1, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_pair(input: &[u8]) -> IResult<&[u8], (usize, usize)> {
|
||||
fn parse_usize(input: &[u8]) -> IResult<&[u8], usize> {
|
||||
map_res(nom::character::complete::u32, usize::try_from)(input)
|
||||
}
|
||||
|
||||
separated_pair(parse_usize, tag(","), parse_usize)(input)
|
||||
}
|
||||
|
||||
fn find_dimensions(input: &[u8]) -> IResult<&[u8], (usize, usize)> {
|
||||
reduce_many1(
|
||||
terminated(parse_pair, alt((tag(" -> "), tag("\n")))), // Somehow this cant be `newline` because type deduction goes awry
|
||||
|(width, height), (x, y)| (width.max(x + 1), height.max(y + 1)),
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_cave(input: &[u8]) -> IResult<&[u8], Cave> {
|
||||
let (width, height) = find_dimensions(input)?.1;
|
||||
|
||||
let floor = height + 1;
|
||||
|
||||
// Assume parsing went somewhat right
|
||||
debug_assert_ne!(width, 0);
|
||||
debug_assert_ne!(height, 0);
|
||||
|
||||
let mut cave = Cave {
|
||||
width,
|
||||
height,
|
||||
occupied: IndexSet::with_capacity(width * floor),
|
||||
floor,
|
||||
};
|
||||
|
||||
let mut input = input;
|
||||
|
||||
while input != &b""[..] {
|
||||
let new_input = terminated(
|
||||
reduce_many1(
|
||||
terminated(parse_pair, opt(tag(" -> "))),
|
||||
|(x_old, y_old), (x_prime, y_prime)| {
|
||||
if x_prime == x_old {
|
||||
for y in (y_old.min(y_prime))..=(y_old.max(y_prime)) {
|
||||
cave.insert(x_old, y);
|
||||
}
|
||||
} else {
|
||||
for x in (x_old.min(x_prime))..=(x_old.max(x_prime)) {
|
||||
cave.insert(x, y_old);
|
||||
}
|
||||
}
|
||||
(x_prime, y_prime)
|
||||
},
|
||||
),
|
||||
newline,
|
||||
)(input)?
|
||||
.0;
|
||||
|
||||
input = new_input;
|
||||
}
|
||||
|
||||
Ok((input, cave))
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let mut cave = parse_input(input, parse_cave)?;
|
||||
|
||||
let mut total = 0;
|
||||
|
||||
cave.drop(500, 0, &mut total);
|
||||
|
||||
Ok(total.to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let mut cave = parse_input(input, parse_cave)?;
|
||||
|
||||
let mut total = 0;
|
||||
cave.drop2(500, 0, &mut total);
|
||||
|
||||
Ok(total.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/14.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "24");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "93")
|
||||
}
|
||||
}
|
||||
178
2022/src/day15.rs
Normal file
178
2022/src/day15.rs
Normal file
@@ -0,0 +1,178 @@
|
||||
use std::cmp::Reverse;
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
use ahash::AHashSet;
|
||||
use anyhow::Result;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::multi::many0;
|
||||
use nom::sequence::pair;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
use crate::common::Vec2;
|
||||
|
||||
struct Beacon {
|
||||
pos: Vec2,
|
||||
closest: Vec2,
|
||||
range: i32,
|
||||
}
|
||||
|
||||
impl Beacon {
|
||||
pub fn can_contain_unseen(&self, lower: Vec2, upper: Vec2) -> bool {
|
||||
let corners = [
|
||||
lower,
|
||||
upper,
|
||||
Vec2([lower[0], upper[1]]),
|
||||
Vec2([upper[0], lower[1]]),
|
||||
];
|
||||
|
||||
corners
|
||||
.into_iter()
|
||||
.any(|c| (c - self.pos).l1() > self.range)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_pos(input: &[u8]) -> IResult<&[u8], Vec2> {
|
||||
use nom::character::complete::i32;
|
||||
map(
|
||||
pair(preceded(tag("x="), i32), preceded(tag(", y="), i32)),
|
||||
|(x, y)| Vec2([x, y]),
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_beacons(input: &[u8]) -> IResult<&[u8], Vec<Beacon>> {
|
||||
let parse_beacon = map(
|
||||
pair(
|
||||
preceded(tag("Sensor at "), parse_pos),
|
||||
preceded(tag(": closest beacon is at "), parse_pos),
|
||||
),
|
||||
|(pos, closest)| Beacon {
|
||||
pos,
|
||||
closest,
|
||||
range: (pos - closest).l1(),
|
||||
},
|
||||
);
|
||||
|
||||
many0(terminated(parse_beacon, newline))(input)
|
||||
}
|
||||
|
||||
fn part1_generic<const Y: i32>(input: &[u8]) -> Result<String> {
|
||||
let beacons = parse_input(input, parse_beacons)?;
|
||||
|
||||
let mut not_blocking_yet = BinaryHeap::new();
|
||||
let mut blocking = BinaryHeap::new();
|
||||
|
||||
let mut total = 0;
|
||||
|
||||
let mut on_line = AHashSet::new();
|
||||
|
||||
for beacon in beacons {
|
||||
let horizontal_distance = beacon.range - (beacon.pos[1] - Y).abs();
|
||||
|
||||
if horizontal_distance >= 0 {
|
||||
not_blocking_yet.push(Reverse((
|
||||
beacon.pos[0] - horizontal_distance,
|
||||
beacon.pos[0] + horizontal_distance + 1,
|
||||
)))
|
||||
}
|
||||
|
||||
// Beacons can be beacons, so we should uncount them
|
||||
if beacon.closest[1] == Y {
|
||||
on_line.insert(beacon.closest);
|
||||
}
|
||||
}
|
||||
|
||||
while let Some(Reverse((block_from, mut block_until))) = not_blocking_yet.pop() {
|
||||
blocking.push(Reverse(block_until));
|
||||
|
||||
while let Some(Reverse(block_end)) = blocking.pop() {
|
||||
block_until = block_until.max(block_end);
|
||||
|
||||
while matches!(not_blocking_yet.peek(), Some(Reverse((block_from, _))) if block_from < &block_end)
|
||||
{
|
||||
let Reverse((_, additional_block_until)) = not_blocking_yet.pop().unwrap();
|
||||
blocking.push(Reverse(additional_block_until));
|
||||
}
|
||||
}
|
||||
|
||||
total += block_until - block_from;
|
||||
}
|
||||
|
||||
total -= on_line.len() as i32;
|
||||
|
||||
Ok(total.to_string())
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
part1_generic::<2_000_000>(input)
|
||||
}
|
||||
|
||||
fn part2_generic<const MAX: i32>(input: &[u8]) -> Result<String> {
|
||||
let beacons = parse_input(input, parse_beacons)?;
|
||||
|
||||
fn find_unseen<const MAX: i32>(beacons: &[Beacon]) -> Result<Vec2> {
|
||||
let mut todo = vec![(Vec2([0, 0]), Vec2([MAX, MAX]))];
|
||||
|
||||
while let Some((lower, upper)) = todo.pop() {
|
||||
if lower == upper {
|
||||
if beacons
|
||||
.iter()
|
||||
.all(|beacon| (beacon.pos - lower).l1() > beacon.range)
|
||||
{
|
||||
return Ok(lower);
|
||||
}
|
||||
} else {
|
||||
let mid = (lower + upper) / 2;
|
||||
|
||||
let quads = [
|
||||
(lower, mid),
|
||||
(Vec2([lower[0], mid[1] + 1]), Vec2([mid[0], upper[1]])),
|
||||
(Vec2([mid[0] + 1, lower[1]]), Vec2([upper[0], mid[1]])),
|
||||
(Vec2([mid[0] + 1, mid[1] + 1]), upper),
|
||||
];
|
||||
|
||||
for (lower_new, upper_new) in quads {
|
||||
if lower_new[0] > upper_new[0] || lower_new[1] > upper_new[1] {
|
||||
// Empty quad in quad tree, skip
|
||||
} else if beacons
|
||||
.iter()
|
||||
.all(|beacon| beacon.can_contain_unseen(lower_new, upper_new))
|
||||
{
|
||||
todo.push((lower_new, upper_new));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
anyhow::bail!("Did not find position")
|
||||
}
|
||||
|
||||
let Vec2([x, y]) = find_unseen::<MAX>(&beacons)?;
|
||||
|
||||
Ok((i64::from(x) * 4_000_000 + i64::from(y)).to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
part2_generic::<4_000_000>(input)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/15.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1_generic::<10>(SAMPLE).unwrap(), "26");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2_generic::<20>(SAMPLE).unwrap(), "56000011");
|
||||
}
|
||||
}
|
||||
166
2022/src/day16.rs
Normal file
166
2022/src/day16.rs
Normal file
@@ -0,0 +1,166 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use ahash::AHashMap;
|
||||
use anyhow::Result;
|
||||
use ndarray::Array2;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::alpha1;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::into;
|
||||
use nom::multi::many1;
|
||||
use nom::multi::separated_list1;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::terminated;
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
|
||||
type ParsedValve<'a> = (&'a [u8], u16, Vec<&'a [u8]>);
|
||||
|
||||
type ParsedNetwork<'a> = Vec<ParsedValve<'a>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SimpleNetwork {
|
||||
valves: Vec<SimpleValve>,
|
||||
start: usize,
|
||||
useful: usize,
|
||||
}
|
||||
|
||||
impl Deref for SimpleNetwork {
|
||||
type Target = [SimpleValve];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.valves
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SimpleValve {
|
||||
connected: Vec<usize>,
|
||||
flow: u16,
|
||||
}
|
||||
|
||||
impl From<ParsedNetwork<'_>> for SimpleNetwork {
|
||||
fn from(mut parsed: ParsedNetwork) -> Self {
|
||||
// Make sure the positive numbers are in the front
|
||||
parsed.sort_by(|a, b| b.1.cmp(&a.1));
|
||||
|
||||
let mapping: AHashMap<_, _> = parsed
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, (name, _, _))| (*name, index))
|
||||
.collect();
|
||||
|
||||
let useful = parsed.iter().filter(|(_, flow, _)| *flow > 0).count();
|
||||
|
||||
Self {
|
||||
valves: parsed
|
||||
.into_iter()
|
||||
.map(|(_, flow, connected)| {
|
||||
let connected = connected.into_iter().map(|name| mapping[&name]).collect();
|
||||
|
||||
SimpleValve { connected, flow }
|
||||
})
|
||||
.collect(),
|
||||
start: mapping[&b"AA"[..]],
|
||||
useful,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_network(input: &[u8]) -> IResult<&[u8], ParsedNetwork> {
|
||||
let parse_network = terminated(
|
||||
tuple((
|
||||
// Parse the name of the valve
|
||||
preceded(tag("Valve "), alpha1),
|
||||
// Parse the flow of the valve
|
||||
preceded(tag(" has flow rate="), nom::character::complete::u16),
|
||||
// Parse the connections
|
||||
preceded(
|
||||
// Did you really have to distinguish plural
|
||||
alt((
|
||||
tag("; tunnels lead to valves "),
|
||||
tag("; tunnel leads to valve "),
|
||||
)),
|
||||
separated_list1(tag(", "), alpha1),
|
||||
),
|
||||
)),
|
||||
newline,
|
||||
);
|
||||
|
||||
many1(parse_network)(input)
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let network: SimpleNetwork = parse_input(input, into(parse_network))?;
|
||||
|
||||
let (valves_available, dp) = run_optimization(&network, 30);
|
||||
|
||||
Ok(dp[(network.start, valves_available)].to_string())
|
||||
}
|
||||
|
||||
fn run_optimization(network: &SimpleNetwork, time: usize) -> (usize, Array2<u16>) {
|
||||
let valves_available = (1 << network.useful) - 1;
|
||||
let mut cur = Array2::zeros((network.len(), valves_available + 1));
|
||||
let mut prev = cur.clone();
|
||||
|
||||
for time_remaining in 1..time {
|
||||
for pos in 0..network.len() {
|
||||
let bit = 1 << pos;
|
||||
for open_valves in 0..=valves_available {
|
||||
let optimal = if (bit & open_valves) != 0 && time_remaining > 2 {
|
||||
prev[(pos, open_valves - bit)] + time_remaining as u16 * network[pos].flow
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
cur[(pos, open_valves)] = network[pos]
|
||||
.connected
|
||||
.iter()
|
||||
.map(|&other| prev[(other, open_valves)])
|
||||
.fold(optimal, Ord::max);
|
||||
}
|
||||
}
|
||||
|
||||
std::mem::swap(&mut prev, &mut cur);
|
||||
}
|
||||
(valves_available, prev)
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let network: SimpleNetwork = parse_input(input, into(parse_network))?;
|
||||
|
||||
let (valves_available, dp) = run_optimization(&network, 26);
|
||||
|
||||
// Find the minimum of all combinations of your work/elephant's work
|
||||
let best = (0..=valves_available)
|
||||
.map(|my_valves| {
|
||||
let elephant_valves = valves_available - my_valves;
|
||||
|
||||
dp[(network.start, my_valves)] + dp[(network.start, elephant_valves)]
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
|
||||
// Guesses: 1802 (too low)
|
||||
Ok(best.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/16.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "1651");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "1707");
|
||||
}
|
||||
}
|
||||
239
2022/src/day17.rs
Normal file
239
2022/src/day17.rs
Normal file
@@ -0,0 +1,239 @@
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::common::IndexSet;
|
||||
|
||||
const SHAPES: [&[&[bool]]; 5] = [
|
||||
&[&[true; 4]],
|
||||
&[&[false, true, false], &[true; 3], &[false, true, false]],
|
||||
&[&[false, false, true], &[false, false, true], &[true; 3]],
|
||||
&[&[true], &[true], &[true], &[true]],
|
||||
&[&[true; 2], &[true; 2]],
|
||||
];
|
||||
|
||||
const WIDTH: usize = 7;
|
||||
|
||||
#[allow(unused)]
|
||||
fn print_cavern(cavern: &IndexSet, max_height: usize) {
|
||||
for y in (0..=max_height).rev() {
|
||||
for x in 0..7 {
|
||||
print!(
|
||||
"{}",
|
||||
if cavern.contains(y * WIDTH + x) {
|
||||
'#'
|
||||
} else {
|
||||
'.'
|
||||
}
|
||||
);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
fn collides(shape: &[&[bool]], cavern: &IndexSet, x: usize, y: usize) -> bool {
|
||||
for (row, line) in shape.iter().enumerate() {
|
||||
if x + line.len() > WIDTH {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (col, &on) in line.iter().enumerate().rev() {
|
||||
if on && cavern.contains((y - row) * WIDTH + x + col) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn simulate(
|
||||
mut cavern: IndexSet,
|
||||
shapes: impl Iterator<Item = &'static &'static [&'static [bool]]>,
|
||||
mut gusts: impl Iterator<Item = isize>,
|
||||
mut max_height: usize,
|
||||
) -> usize {
|
||||
for &shape in shapes {
|
||||
let mut x = 2usize;
|
||||
let mut y = max_height + shape.len() + 2;
|
||||
|
||||
// Acquire gust of wind
|
||||
for offset in gusts.by_ref() {
|
||||
if let Some(nx) = x.checked_add_signed(offset) {
|
||||
if !collides(shape, &cavern, nx, y) {
|
||||
x = nx;
|
||||
}
|
||||
} else {
|
||||
// Hit the left wall
|
||||
}
|
||||
|
||||
// Move down if possible
|
||||
if y >= shape.len() && !collides(shape, &cavern, x, y - 1) {
|
||||
y -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here we've successfully stopped falling
|
||||
max_height = max_height.max(y + 1);
|
||||
|
||||
for (row, line) in shape.iter().enumerate() {
|
||||
for (col, &on) in line.iter().enumerate() {
|
||||
if on {
|
||||
cavern.insert((y - row) * WIDTH + x + col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
max_height
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
// Poor man's trim()
|
||||
let input = if input[input.len() - 1] == b'\n' {
|
||||
&input[..input.len() - 1]
|
||||
} else {
|
||||
input
|
||||
};
|
||||
|
||||
let gusts = input
|
||||
.iter()
|
||||
.cycle()
|
||||
.map(|&b| if b == b'<' { -1 } else { 1 });
|
||||
|
||||
Ok(simulate(
|
||||
IndexSet::default(),
|
||||
SHAPES.iter().cycle().take(2022),
|
||||
gusts,
|
||||
0,
|
||||
)
|
||||
.to_string())
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct HeightMap([usize; 7]);
|
||||
|
||||
impl HeightMap {
|
||||
fn max(&self) -> &usize {
|
||||
self.0.iter().max().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for HeightMap {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
let self_min = *self.0.iter().min().unwrap();
|
||||
let other_min = *other.0.iter().min().unwrap();
|
||||
|
||||
self.0
|
||||
.iter()
|
||||
.zip(&other.0)
|
||||
.all(|(&a, &b)| a - self_min == b - other_min)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
// Poor man's trim()
|
||||
let input = if input[input.len() - 1] == b'\n' {
|
||||
&input[..input.len() - 1]
|
||||
} else {
|
||||
input
|
||||
};
|
||||
|
||||
let mut cavern = IndexSet::default();
|
||||
|
||||
let mut height_map = HeightMap([0; 7]);
|
||||
|
||||
let mut shapes = SHAPES.iter().enumerate().cycle();
|
||||
let mut gusts = input
|
||||
.iter()
|
||||
.map(|&b| if b == b'<' { -1 } else { 1 })
|
||||
.enumerate()
|
||||
.cycle();
|
||||
|
||||
let mut tortoise = (0, 0, height_map);
|
||||
let mut tortoise_time = 0;
|
||||
let mut last_gust = 0;
|
||||
|
||||
const TARGET: usize = 1_000_000_000_000;
|
||||
|
||||
for (it, (shape_id, &shape)) in shapes.by_ref().enumerate() {
|
||||
let mut x = 2usize;
|
||||
let mut y = height_map.max() + shape.len() + 2;
|
||||
|
||||
// Acquire gust of wind
|
||||
for (gust_id, offset) in gusts.by_ref() {
|
||||
last_gust = gust_id;
|
||||
if let Some(nx) = x.checked_add_signed(offset) {
|
||||
if !collides(shape, &cavern, nx, y) {
|
||||
x = nx;
|
||||
}
|
||||
} else {
|
||||
// Hit the left wall
|
||||
}
|
||||
|
||||
// Move down if possible
|
||||
if y >= shape.len() && !collides(shape, &cavern, x, y - 1) {
|
||||
y -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here we've successfully stopped falling
|
||||
for (row, line) in shape.iter().enumerate() {
|
||||
for (col, &on) in line.iter().enumerate() {
|
||||
if on {
|
||||
height_map.0[x + col] = height_map.0[x + col].max(y - row + 1);
|
||||
cavern.insert((y - row) * WIDTH + x + col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if we found a circle
|
||||
let hare_time = it + 1;
|
||||
let hare = (shape_id, last_gust, height_map);
|
||||
|
||||
if hare == tortoise {
|
||||
let cycle_len = hare_time - tortoise_time;
|
||||
let remaining = TARGET - hare_time;
|
||||
let to_skip = remaining / cycle_len;
|
||||
let remainder = remaining % cycle_len;
|
||||
|
||||
let current_max = *height_map.max();
|
||||
|
||||
// All of them rose by the same amount so we just need to compare the first one
|
||||
let delta = height_map.0[0] - tortoise.2 .0[0];
|
||||
|
||||
let result = simulate(
|
||||
cavern,
|
||||
shapes.map(|(_, shape)| shape).take(remainder),
|
||||
gusts.map(|(_, offset)| offset),
|
||||
current_max,
|
||||
) + delta * to_skip;
|
||||
|
||||
return Ok(result.to_string());
|
||||
} else if it.count_ones() == 1 {
|
||||
tortoise = hare;
|
||||
tortoise_time = hare_time;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(height_map.max().to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/17.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "3068");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "1514285714288");
|
||||
}
|
||||
}
|
||||
148
2022/src/day18.rs
Normal file
148
2022/src/day18.rs
Normal file
@@ -0,0 +1,148 @@
|
||||
use ahash::AHashMap;
|
||||
use ahash::AHashSet;
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::multi::fold_many1;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::terminated;
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
|
||||
fn parse_voxels(input: &[u8]) -> IResult<&[u8], AHashSet<[u8; 3]>> {
|
||||
use nom::character::complete::u8;
|
||||
|
||||
fold_many1(
|
||||
terminated(
|
||||
map(
|
||||
tuple((u8, preceded(tag(","), u8), preceded(tag(","), u8))),
|
||||
|(x, y, z)| [x, y, z],
|
||||
),
|
||||
newline,
|
||||
),
|
||||
AHashSet::new,
|
||||
|mut set, coord| {
|
||||
set.insert(coord);
|
||||
set
|
||||
},
|
||||
)(input)
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let voxels = parse_input(input, parse_voxels)?;
|
||||
|
||||
let mut faces = 0;
|
||||
|
||||
for &voxel in &voxels {
|
||||
for axis in 0..3 {
|
||||
for offset in [-1, 1] {
|
||||
let mut to_search = voxel;
|
||||
to_search[axis] = to_search[axis].wrapping_add_signed(offset);
|
||||
|
||||
if !voxels.contains(&to_search) {
|
||||
faces += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(faces.to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let voxels = parse_input(input, parse_voxels)?;
|
||||
let max = voxels
|
||||
.iter()
|
||||
.copied()
|
||||
.flatten()
|
||||
.max()
|
||||
.context("No voxels?")?;
|
||||
|
||||
let mut outside = AHashMap::new();
|
||||
let mut outside_candidates = AHashSet::new();
|
||||
let mut todo = Vec::new();
|
||||
|
||||
let mut is_outside = |voxel: [u8; 3]| {
|
||||
if let Some(&state) = outside.get(&voxel) {
|
||||
return state;
|
||||
}
|
||||
|
||||
let mut is_outside = false;
|
||||
|
||||
todo.push(voxel);
|
||||
outside_candidates.insert(voxel);
|
||||
|
||||
'outer: while let Some(voxel) = todo.pop() {
|
||||
for axis in 0..3 {
|
||||
for offset in [-1, 1] {
|
||||
let mut to_search = voxel;
|
||||
if let Some(new_coord) = to_search[axis].checked_add_signed(offset) {
|
||||
to_search[axis] = new_coord;
|
||||
|
||||
if voxels.contains(&to_search) {
|
||||
// Filled voxels cannot lead outside
|
||||
continue;
|
||||
} else if new_coord >= max {
|
||||
is_outside = true;
|
||||
break 'outer;
|
||||
} else if let Some(&state) = outside.get(&to_search) {
|
||||
is_outside = state;
|
||||
break 'outer;
|
||||
} else if outside_candidates.insert(to_search) {
|
||||
todo.push(to_search);
|
||||
}
|
||||
} else {
|
||||
// Managed to get below zero, which is outside
|
||||
is_outside = true;
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let map = |voxel| (voxel, is_outside);
|
||||
|
||||
outside.extend(todo.drain(..).map(map));
|
||||
outside.extend(outside_candidates.drain().map(map));
|
||||
|
||||
is_outside
|
||||
};
|
||||
|
||||
let mut faces = 0;
|
||||
|
||||
for &voxel in &voxels {
|
||||
for axis in 0..3 {
|
||||
for offset in [-1, 1] {
|
||||
let mut to_search = voxel;
|
||||
to_search[axis] = to_search[axis].wrapping_add_signed(offset);
|
||||
|
||||
if !voxels.contains(&to_search) && is_outside(to_search) {
|
||||
faces += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(faces.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/18.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "64");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "58");
|
||||
}
|
||||
}
|
||||
297
2022/src/day19.rs
Normal file
297
2022/src/day19.rs
Normal file
@@ -0,0 +1,297 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
use anyhow::Result;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::character::complete::multispace1;
|
||||
use nom::character::streaming::alpha1;
|
||||
use nom::combinator::map_res;
|
||||
use nom::combinator::opt;
|
||||
use nom::multi::many1;
|
||||
use nom::sequence::delimited;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::separated_pair;
|
||||
use nom::sequence::terminated;
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
|
||||
#[repr(usize)]
|
||||
#[derive(Clone, Copy)]
|
||||
enum Mineral {
|
||||
Ore,
|
||||
Clay,
|
||||
Obsidian,
|
||||
Geode,
|
||||
}
|
||||
|
||||
impl TryFrom<&'_ [u8]> for Mineral {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: &'_ [u8]) -> std::result::Result<Self, Self::Error> {
|
||||
match value {
|
||||
b"ore" => Ok(Self::Ore),
|
||||
b"clay" => Ok(Self::Clay),
|
||||
b"obsidian" => Ok(Self::Obsidian),
|
||||
b"geode" => Ok(Self::Geode),
|
||||
other => Err(format!(
|
||||
"Invalid mineral '{}'",
|
||||
String::from_utf8_lossy(other)
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct BluePrint {
|
||||
id: u32,
|
||||
costs: [[u8; 3]; 4],
|
||||
}
|
||||
|
||||
impl BluePrint {
|
||||
pub fn max_geodes(&self, time: u8) -> u8 {
|
||||
/// How much would we produce if all we did was produce geode robots for the remaining time
|
||||
fn ideal(remaining: u32) -> u32 {
|
||||
if remaining <= 1 {
|
||||
0
|
||||
} else {
|
||||
(remaining - 1) * remaining / 2
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
struct State {
|
||||
missed: u32,
|
||||
got: u8,
|
||||
time_left: u8,
|
||||
resources: [u8; 3],
|
||||
machines: [u8; 3],
|
||||
}
|
||||
|
||||
impl Ord for State {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
Ordering::Equal
|
||||
.then(other.missed.cmp(&self.missed))
|
||||
.then(self.got.cmp(&other.got))
|
||||
.then(self.time_left.cmp(&other.time_left))
|
||||
.then(self.machines.cmp(&other.machines))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for State {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
let max_needed = self.max_needed();
|
||||
let mut todo = BinaryHeap::new();
|
||||
let mut best = 0;
|
||||
|
||||
todo.push(State {
|
||||
missed: 0,
|
||||
got: 0,
|
||||
time_left: time,
|
||||
resources: [0; 3],
|
||||
machines: [1, 0, 0],
|
||||
});
|
||||
|
||||
while let Some(State {
|
||||
missed,
|
||||
got,
|
||||
time_left,
|
||||
resources,
|
||||
machines,
|
||||
}) = todo.pop()
|
||||
{
|
||||
let ideal_from_now = ideal(u32::from(time_left));
|
||||
// Need to check again because we might've gotten a better result in the meantime.
|
||||
if u32::from(best - got) >= ideal_from_now {
|
||||
continue;
|
||||
}
|
||||
assert!(
|
||||
todo.len() <= 1_000_000,
|
||||
"Safety: got a todo list of len {}, best: {best}",
|
||||
todo.len()
|
||||
);
|
||||
for (element, &costs) in self.costs.iter().enumerate() {
|
||||
let Some(min_to_build) = self.until_buildable(costs, resources, machines) else {
|
||||
break;
|
||||
};
|
||||
|
||||
// +1 because we need a turn to build
|
||||
let built_after = min_to_build + 1;
|
||||
if built_after >= time_left {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ideally, would be written as a nice `array::from_fn`. It turns out that codegen
|
||||
// for `array::from_fn` is very bad, and writing it out into this for loop reduces
|
||||
// time taken by approximately 100%.
|
||||
let mut resources_after = [0; 3];
|
||||
for i in 0..3 {
|
||||
resources_after[i] = resources[i] + machines[i] * built_after - costs[i];
|
||||
}
|
||||
|
||||
let time_after = time_left - built_after;
|
||||
|
||||
if element == Mineral::Geode as usize {
|
||||
let new_got = got + time_after;
|
||||
best = best.max(new_got);
|
||||
|
||||
if u32::from(best - new_got) >= ideal(time_after.into()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
todo.push(State {
|
||||
missed,
|
||||
got: new_got,
|
||||
time_left: time_after,
|
||||
resources: resources_after,
|
||||
machines,
|
||||
});
|
||||
|
||||
best = best.max(new_got);
|
||||
} else {
|
||||
if machines[element] >= max_needed[element]
|
||||
|| u32::from(best - got) >= ideal(time_after.into())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut new_machines = machines;
|
||||
new_machines[element] += 1;
|
||||
let new_missed = ideal_from_now - ideal(u32::from(time_after));
|
||||
todo.push(State {
|
||||
missed: new_missed,
|
||||
got,
|
||||
time_left: time_after,
|
||||
resources: resources_after,
|
||||
machines: new_machines,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
best
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn until_buildable(&self, costs: [u8; 3], resources: [u8; 3], machines: [u8; 3]) -> Option<u8> {
|
||||
let mut min_to_build = 0;
|
||||
for ((&cost, &avail), &machine) in costs.iter().zip(&resources).zip(&machines) {
|
||||
if cost > avail {
|
||||
if machine == 0 {
|
||||
return None;
|
||||
} else {
|
||||
min_to_build = min_to_build.max((cost - avail + machine - 1) / machine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(min_to_build)
|
||||
}
|
||||
|
||||
fn max_needed(&self) -> [u8; 3] {
|
||||
let mut max_needed = [0; 3];
|
||||
|
||||
for cost in &self.costs {
|
||||
for (max, &new) in max_needed.iter_mut().zip(cost) {
|
||||
*max = (*max).max(new);
|
||||
}
|
||||
}
|
||||
|
||||
max_needed
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_blueprint(input: &[u8]) -> IResult<&[u8], BluePrint> {
|
||||
use nom::character::complete::u32;
|
||||
|
||||
fn parse_mineral(input: &[u8]) -> IResult<&[u8], Mineral> {
|
||||
map_res(alpha1, Mineral::try_from)(input)
|
||||
}
|
||||
|
||||
fn parse_cost(input: &[u8]) -> IResult<&[u8], (u8, Mineral)> {
|
||||
separated_pair(nom::character::complete::u8, tag(" "), parse_mineral)(input)
|
||||
}
|
||||
|
||||
let (mut input, id) =
|
||||
terminated(delimited(tag("Blueprint "), u32, tag(":")), multispace1)(input)?;
|
||||
|
||||
let mut costs: [[u8; 3]; 4] = Default::default();
|
||||
|
||||
let mut parse_robot = terminated(
|
||||
tuple((
|
||||
preceded(tag("Each "), parse_mineral),
|
||||
preceded(tag(" robot costs "), parse_cost),
|
||||
terminated(opt(preceded(tag(" and "), parse_cost)), tag(".")),
|
||||
)),
|
||||
multispace1,
|
||||
);
|
||||
|
||||
for _ in 0..4 {
|
||||
let (remaining, (element, (amount1, req1), cost2)) = parse_robot(input)?;
|
||||
input = remaining;
|
||||
|
||||
costs[element as usize][req1 as usize] = amount1;
|
||||
|
||||
if let Some((amount2, req2)) = cost2 {
|
||||
costs[element as usize][req2 as usize] = amount2;
|
||||
}
|
||||
}
|
||||
|
||||
Ok((input, BluePrint { id, costs }))
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let blueprints = parse_input(input, many1(parse_blueprint))?;
|
||||
|
||||
Ok(blueprints
|
||||
.into_iter()
|
||||
.map(|bp| u32::from(bp.max_geodes(24)) * bp.id)
|
||||
.sum::<u32>()
|
||||
.to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let blueprints = parse_input(input, many1(parse_blueprint))?;
|
||||
|
||||
let result: u32 = blueprints
|
||||
.iter()
|
||||
.take(3)
|
||||
.map(|bp| u32::from(bp.max_geodes(32)))
|
||||
.product();
|
||||
|
||||
Ok(result.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("./samples/19.txt");
|
||||
|
||||
fn get_samples() -> Vec<BluePrint> {
|
||||
parse_input(SAMPLE, many1(parse_blueprint)).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
let samples = get_samples();
|
||||
|
||||
assert_eq!(samples[0].max_geodes(24), 9);
|
||||
assert_eq!(samples[1].max_geodes(24), 12);
|
||||
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "33");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
let samples = get_samples();
|
||||
|
||||
assert_eq!(samples[0].max_geodes(32), 56);
|
||||
assert_eq!(samples[1].max_geodes(32), 62);
|
||||
}
|
||||
}
|
||||
133
2022/src/day20.rs
Normal file
133
2022/src/day20.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::iter::once;
|
||||
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use nom::character::complete::newline;
|
||||
use nom::multi::many0;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
|
||||
fn parse_encrypted(input: &[u8]) -> IResult<&[u8], Vec<i64>> {
|
||||
many0(terminated(nom::character::complete::i64, newline))(input)
|
||||
}
|
||||
|
||||
// While looping around to find a spot to move to, you must ignore the piece itself, but for
|
||||
// computing the answer, you shouldn't. This function does the latter.
|
||||
fn step(steps: &[usize], mut start: usize, count: usize) -> usize {
|
||||
for _ in 0..(count % steps.len()) {
|
||||
start = steps[start];
|
||||
}
|
||||
|
||||
start
|
||||
}
|
||||
|
||||
fn move_between(prev: &mut [usize], next: &mut [usize], i: usize, before: usize, after: usize) {
|
||||
if before == i || after == i {
|
||||
return;
|
||||
}
|
||||
|
||||
let before_i = prev[i];
|
||||
let after_i = next[i];
|
||||
|
||||
// Remove i from its original place
|
||||
prev[after_i] = before_i;
|
||||
next[before_i] = after_i;
|
||||
|
||||
// Connect i properly to before
|
||||
prev[before] = i;
|
||||
next[i] = before;
|
||||
|
||||
// Connect i properly to after
|
||||
prev[i] = after;
|
||||
next[after] = i;
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let encrypted = parse_input(input, parse_encrypted)?;
|
||||
|
||||
shuffle(&encrypted, 1)
|
||||
}
|
||||
|
||||
fn shuffle(encrypted: &[i64], times: usize) -> Result<String> {
|
||||
let mut next: Vec<_> = (1..encrypted.len()).chain(once(0)).collect();
|
||||
let mut prev: Vec<_> = once(encrypted.len() - 1)
|
||||
.chain(0..(encrypted.len() - 1))
|
||||
.collect();
|
||||
|
||||
let len = encrypted.len() as i64;
|
||||
let half_len = len / 2;
|
||||
|
||||
for _ in 0..times {
|
||||
for (i, &value) in encrypted.iter().enumerate() {
|
||||
let mut value = value % (len - 1);
|
||||
|
||||
if value < -half_len {
|
||||
value += len - 1;
|
||||
} else if value > half_len {
|
||||
value -= len - 1;
|
||||
}
|
||||
|
||||
match value.cmp(&0) {
|
||||
Ordering::Less => {
|
||||
let before = step(&prev, i, (-value) as usize);
|
||||
let after = prev[before];
|
||||
|
||||
move_between(&mut prev, &mut next, i, before, after);
|
||||
}
|
||||
Ordering::Equal => continue,
|
||||
Ordering::Greater => {
|
||||
let after = step(&next, i, value as usize);
|
||||
let before = next[after];
|
||||
|
||||
move_between(&mut prev, &mut next, i, before, after);
|
||||
}
|
||||
}
|
||||
|
||||
// print(&encrypted, &next);
|
||||
}
|
||||
}
|
||||
|
||||
let mut start = encrypted
|
||||
.iter()
|
||||
.position(|&v| v == 0)
|
||||
.context("Could not find zero")?;
|
||||
|
||||
let mut sum = 0;
|
||||
|
||||
for _ in 0..3 {
|
||||
start = step(&next, start, 1000);
|
||||
sum += encrypted[start];
|
||||
}
|
||||
|
||||
Ok(sum.to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
const ENCRYPTION_KEY: i64 = 811_589_153;
|
||||
|
||||
let mut encrypted = parse_input(input, parse_encrypted)?;
|
||||
|
||||
encrypted.iter_mut().for_each(|v| *v *= ENCRYPTION_KEY);
|
||||
|
||||
shuffle(&encrypted, 10)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/20.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "1623178306");
|
||||
}
|
||||
}
|
||||
191
2022/src/day21.rs
Normal file
191
2022/src/day21.rs
Normal file
@@ -0,0 +1,191 @@
|
||||
use ahash::AHashMap;
|
||||
use anyhow::Result;
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::complete::take;
|
||||
use nom::character::complete::alpha1;
|
||||
use nom::character::complete::newline;
|
||||
use nom::combinator::map;
|
||||
use nom::combinator::map_res;
|
||||
use nom::multi::fold_many1;
|
||||
use nom::sequence::preceded;
|
||||
use nom::sequence::terminated;
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
|
||||
type Input<'a> = AHashMap<&'a [u8], Monkey<'a>>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Operation {
|
||||
Mul,
|
||||
Div,
|
||||
Add,
|
||||
Sub,
|
||||
}
|
||||
|
||||
impl Operation {
|
||||
pub fn apply(self, first: i64, second: i64) -> i64 {
|
||||
match self {
|
||||
Operation::Mul => first * second,
|
||||
Operation::Div => first / second,
|
||||
Operation::Add => first + second,
|
||||
Operation::Sub => first - second,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for Operation {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
Ok(match value {
|
||||
b'*' => Operation::Mul,
|
||||
b'/' => Operation::Div,
|
||||
b'+' => Operation::Add,
|
||||
b'-' => Operation::Sub,
|
||||
other => anyhow::bail!("Invalid operation: {other}"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
enum Monkey<'a> {
|
||||
Operation(&'a [u8], &'a [u8], Operation),
|
||||
Literal(i64),
|
||||
}
|
||||
|
||||
fn parse_monkeys(input: &[u8]) -> IResult<&[u8], Input> {
|
||||
let parse_monkey = terminated(
|
||||
tuple((
|
||||
alpha1,
|
||||
preceded(
|
||||
tag(": "),
|
||||
alt((
|
||||
map(nom::character::complete::i64, Monkey::Literal),
|
||||
map(
|
||||
tuple((
|
||||
terminated(alpha1, tag(" ")),
|
||||
map_res(take(1usize), |v: &[u8]| Operation::try_from(v[0])),
|
||||
preceded(tag(" "), alpha1),
|
||||
)),
|
||||
|(first, operation, second)| Monkey::Operation(first, second, operation),
|
||||
),
|
||||
)),
|
||||
),
|
||||
)),
|
||||
newline,
|
||||
);
|
||||
|
||||
fold_many1(parse_monkey, AHashMap::new, |mut map, (name, monkey)| {
|
||||
map.insert(name, monkey);
|
||||
map
|
||||
})(input)
|
||||
}
|
||||
|
||||
fn evaluate(monkeys: &Input, start: &[u8]) -> i64 {
|
||||
match &monkeys[start] {
|
||||
Monkey::Operation(first, second, op) => {
|
||||
let first = evaluate(monkeys, first);
|
||||
let second = evaluate(monkeys, second);
|
||||
|
||||
op.apply(first, second)
|
||||
}
|
||||
Monkey::Literal(value) => *value,
|
||||
}
|
||||
}
|
||||
|
||||
enum IncompleteSide {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
fn evaluate2(
|
||||
monkeys: &Input,
|
||||
start: &[u8],
|
||||
) -> std::result::Result<i64, Vec<(i64, IncompleteSide, Operation)>> {
|
||||
if start == b"humn" {
|
||||
return Err(Vec::new());
|
||||
}
|
||||
|
||||
match &monkeys[start] {
|
||||
Monkey::Operation(first, second, op) => {
|
||||
match (evaluate2(monkeys, first), evaluate2(monkeys, second)) {
|
||||
(Ok(first), Ok(second)) => Ok(op.apply(first, second)),
|
||||
(Ok(first), Err(mut incomplete)) => {
|
||||
incomplete.push((first, IncompleteSide::Right, *op));
|
||||
Err(incomplete)
|
||||
}
|
||||
(Err(mut incomplete), Ok(second)) => {
|
||||
incomplete.push((second, IncompleteSide::Left, *op));
|
||||
Err(incomplete)
|
||||
}
|
||||
(Err(_), Err(_)) => unreachable!("Should not happen on fair input"),
|
||||
}
|
||||
}
|
||||
Monkey::Literal(val) => Ok(*val),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let monkeys = parse_input(input, parse_monkeys)?;
|
||||
|
||||
Ok(evaluate(&monkeys, b"root").to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let monkeys = parse_input(input, parse_monkeys)?;
|
||||
|
||||
let Monkey::Operation(first, second, _) = &monkeys[&b"root"[..]] else {
|
||||
anyhow::bail!("root is a literal somehow")
|
||||
};
|
||||
|
||||
let result = match (evaluate2(&monkeys, first), evaluate2(&monkeys, second)) {
|
||||
(Ok(_), Ok(_)) => anyhow::bail!("both arms succeeded"),
|
||||
(Ok(goal), Err(incomplete)) | (Err(incomplete), Ok(goal)) => incomplete
|
||||
.into_iter()
|
||||
.rev()
|
||||
.fold(goal, |next, (complete, arm, op)| match (op, arm) {
|
||||
// Multiplication and addition are commutative so the arm doesn't matter
|
||||
(Operation::Mul, _) => {
|
||||
// This was a very useful sanity check
|
||||
debug_assert_eq!(next % complete, 0);
|
||||
next / complete
|
||||
}
|
||||
|
||||
(Operation::Add, _) => next - complete,
|
||||
|
||||
// The other operations need some tweaking. x: unknown quantity. c: known quantity. n: current value
|
||||
// x - c = n -> x = n + c
|
||||
(Operation::Sub, IncompleteSide::Left) => next + complete,
|
||||
// c - x = n -> c = n + x -> c - n = x
|
||||
(Operation::Sub, IncompleteSide::Right) => complete - next,
|
||||
|
||||
// Similarly for division, if we miss the left arm we can undo the division and multiply instead
|
||||
// x / c = n -> x = n * c
|
||||
(Operation::Div, IncompleteSide::Left) => next * complete,
|
||||
// c / x = n -> c = n * x -> c / n = x
|
||||
(Operation::Div, IncompleteSide::Right) => complete / next,
|
||||
}),
|
||||
(Err(_), Err(_)) => anyhow::bail!("both arms failed"),
|
||||
};
|
||||
|
||||
Ok(result.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/21.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "152");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "301");
|
||||
}
|
||||
}
|
||||
456
2022/src/day22.rs
Normal file
456
2022/src/day22.rs
Normal file
@@ -0,0 +1,456 @@
|
||||
use std::mem;
|
||||
|
||||
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::value;
|
||||
use nom::multi::many1;
|
||||
use nom::sequence::separated_pair;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::parse_input;
|
||||
|
||||
// This describes the transitions between the different squares.
|
||||
//
|
||||
// For every direction, write down which direction you end up going, in which square, and
|
||||
// whether you should flip the axis.
|
||||
//
|
||||
// The squares are laid out as follows:
|
||||
//
|
||||
// #01
|
||||
// #2#
|
||||
// 34#
|
||||
// 5##
|
||||
//
|
||||
// Entries are specified right, down, left, up.
|
||||
#[allow(dead_code)]
|
||||
const TRANSITIONS: [[(Direction, usize, bool); 4]; 6] = [
|
||||
// Square 0
|
||||
[
|
||||
(Direction::Right, 1, false),
|
||||
(Direction::Down, 2, false),
|
||||
(Direction::Right, 3, true),
|
||||
(Direction::Right, 5, false),
|
||||
],
|
||||
// Square 1
|
||||
[
|
||||
(Direction::Left, 4, true),
|
||||
(Direction::Left, 2, false),
|
||||
(Direction::Left, 0, false),
|
||||
(Direction::Up, 5, false),
|
||||
],
|
||||
// Square 2
|
||||
[
|
||||
(Direction::Up, 1, false),
|
||||
(Direction::Down, 4, false),
|
||||
(Direction::Down, 3, false),
|
||||
(Direction::Up, 0, false),
|
||||
],
|
||||
// Square 3
|
||||
[
|
||||
(Direction::Right, 4, false),
|
||||
(Direction::Down, 5, false),
|
||||
(Direction::Right, 0, true),
|
||||
(Direction::Right, 2, false),
|
||||
],
|
||||
// Square 4
|
||||
[
|
||||
(Direction::Left, 1, true),
|
||||
(Direction::Left, 5, false),
|
||||
(Direction::Left, 3, false),
|
||||
(Direction::Up, 2, false),
|
||||
],
|
||||
// Square 5
|
||||
[
|
||||
(Direction::Up, 4, false),
|
||||
(Direction::Down, 1, false),
|
||||
(Direction::Down, 0, false),
|
||||
(Direction::Up, 3, false),
|
||||
],
|
||||
];
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum Step {
|
||||
Forward(u32),
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum Direction {
|
||||
Up = 3,
|
||||
Down = 1,
|
||||
Left = 2,
|
||||
Right = 0,
|
||||
}
|
||||
|
||||
type Map<'a> = Vec<&'a [u8]>;
|
||||
|
||||
impl Direction {
|
||||
fn turn_left(self) -> Self {
|
||||
match self {
|
||||
Direction::Up => Direction::Left,
|
||||
Direction::Down => Direction::Right,
|
||||
Direction::Left => Direction::Down,
|
||||
Direction::Right => Direction::Up,
|
||||
}
|
||||
}
|
||||
|
||||
fn turn_right(self) -> Self {
|
||||
match self {
|
||||
Direction::Up => Direction::Right,
|
||||
Direction::Down => Direction::Left,
|
||||
Direction::Left => Direction::Up,
|
||||
Direction::Right => Direction::Down,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_map(input: &[u8]) -> IResult<&[u8], (Map, Vec<Step>)> {
|
||||
separated_pair(
|
||||
map(take_until("\n\n"), |map: &[u8]| {
|
||||
map.split(|&b| b == b'\n').collect()
|
||||
}),
|
||||
tag("\n\n"),
|
||||
terminated(
|
||||
many1(alt((
|
||||
map(nom::character::complete::u32, Step::Forward),
|
||||
value(Step::Right, tag("R")),
|
||||
value(Step::Left, tag("L")),
|
||||
))),
|
||||
newline,
|
||||
),
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn find_starting_x(top_row: &[u8]) -> Result<usize> {
|
||||
top_row
|
||||
.iter()
|
||||
.position(|&b| b == b'.')
|
||||
.context("Could not find starting position")
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let (map, steps) = parse_input(input, parse_map)?;
|
||||
let mut dir = Direction::Right;
|
||||
let mut y = 0;
|
||||
let mut x = find_starting_x(map[y])?;
|
||||
|
||||
for step in steps {
|
||||
match step {
|
||||
Step::Forward(amount) => match dir {
|
||||
Direction::Up => {
|
||||
for _ in 0..amount {
|
||||
if y == 0 || map[y - 1].get(x).map_or(true, |&b| b == b' ') {
|
||||
let new_y = map
|
||||
.iter()
|
||||
.rposition(|line| {
|
||||
line.get(x).map_or(false, |&b| b == b'.' || b == b'#')
|
||||
})
|
||||
.unwrap();
|
||||
if map[new_y][x] == b'#' {
|
||||
break;
|
||||
} else {
|
||||
y = new_y;
|
||||
}
|
||||
} else if map[y - 1][x] == b'#' {
|
||||
break;
|
||||
} else {
|
||||
y -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Down => {
|
||||
for _ in 0..amount {
|
||||
if y + 1 >= map.len() || map[y + 1].get(x).map_or(true, |&b| b == b' ') {
|
||||
let new_y = map
|
||||
.iter()
|
||||
.position(|line| {
|
||||
line.get(x).map_or(false, |&b| b == b'.' || b == b'#')
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
if map[new_y][x] == b'#' {
|
||||
break;
|
||||
} else {
|
||||
y = new_y;
|
||||
}
|
||||
} else if map[y + 1][x] == b'#' {
|
||||
break;
|
||||
} else {
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Left => {
|
||||
for _ in 0..amount {
|
||||
if x == 0 || map[y][x - 1] == b' ' {
|
||||
let new_x = map[y]
|
||||
.iter()
|
||||
.rposition(|&b| b == b'.' || b == b'#')
|
||||
.unwrap();
|
||||
if map[y][new_x] == b'.' {
|
||||
x = new_x;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if map[y][x - 1] == b'#' {
|
||||
break;
|
||||
} else {
|
||||
x -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Right => {
|
||||
for _ in 0..amount {
|
||||
if x + 1 >= map[y].len() || map[y][x + 1] == b' ' {
|
||||
let new_x =
|
||||
map[y].iter().position(|&b| b == b'.' || b == b'#').unwrap();
|
||||
if map[y][new_x] == b'.' {
|
||||
x = new_x;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if map[y][x + 1] == b'#' {
|
||||
break;
|
||||
} else {
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Step::Left => dir = dir.turn_left(),
|
||||
Step::Right => dir = dir.turn_right(),
|
||||
}
|
||||
}
|
||||
|
||||
Ok((1000 * (y + 1) + 4 * (x + 1) + dir as usize).to_string())
|
||||
}
|
||||
|
||||
fn side_length_of(map: &[&[u8]]) -> usize {
|
||||
let taken_tiles = map
|
||||
.iter()
|
||||
.flat_map(|r| r.iter())
|
||||
.filter(|c| !c.is_ascii_whitespace())
|
||||
.count();
|
||||
|
||||
// Future Bert: this needs to be an integer square root.
|
||||
((taken_tiles / 6) as f64).sqrt() as usize
|
||||
}
|
||||
|
||||
fn break_squares<'a>(map: &[&'a [u8]], side_length: usize) -> [(Map<'a>, usize, usize); 6] {
|
||||
let mut result: [(Map<'a>, usize, usize); 6] = Default::default();
|
||||
|
||||
let mut row_holder = [(); 4].map(|_| Map::new());
|
||||
let mut index = 0;
|
||||
|
||||
for (y, block_row) in map.chunks_exact(side_length).enumerate() {
|
||||
for row in block_row {
|
||||
for (i, segment) in row.chunks_exact(side_length).enumerate() {
|
||||
if segment[0] != b' ' {
|
||||
row_holder[i].push(segment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (x, potential_side) in row_holder.iter_mut().enumerate() {
|
||||
if !potential_side.is_empty() {
|
||||
mem::swap(potential_side, &mut result[index].0);
|
||||
result[index].1 = x;
|
||||
result[index].2 = y;
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let (map, steps) = parse_input(input, parse_map)?;
|
||||
|
||||
let side_length = side_length_of(&map);
|
||||
|
||||
let squares = break_squares(&map, side_length);
|
||||
|
||||
let convert_coords = |square: usize, x: usize, y: usize| {
|
||||
let offset_x = squares[square].1 * side_length + x + 1;
|
||||
let offset_y = squares[square].2 * side_length + y + 1;
|
||||
|
||||
(offset_x, offset_y)
|
||||
};
|
||||
|
||||
let mut current_square = 0;
|
||||
let mut y = 0;
|
||||
let mut x = find_starting_x(squares[current_square].0[y])?;
|
||||
let mut dir = Direction::Right;
|
||||
|
||||
for step in steps {
|
||||
match step {
|
||||
Step::Left => dir = dir.turn_left(),
|
||||
Step::Right => dir = dir.turn_right(),
|
||||
Step::Forward(mut amount) => {
|
||||
'outer: while amount > 0 {
|
||||
let map = &squares[current_square].0;
|
||||
let coord = match dir {
|
||||
Direction::Up => {
|
||||
while amount > 0 {
|
||||
if y == 0 {
|
||||
break;
|
||||
} else if map[y - 1][x] == b'#' {
|
||||
break 'outer;
|
||||
} else {
|
||||
y -= 1;
|
||||
amount -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
x
|
||||
}
|
||||
Direction::Down => {
|
||||
while amount > 0 {
|
||||
if y + 1 >= side_length {
|
||||
break;
|
||||
} else if map[y + 1][x] == b'#' {
|
||||
break 'outer;
|
||||
} else {
|
||||
amount -= 1;
|
||||
y += 1;
|
||||
}
|
||||
}
|
||||
|
||||
x
|
||||
}
|
||||
Direction::Left => {
|
||||
while amount > 0 {
|
||||
if x == 0 {
|
||||
break;
|
||||
} else if map[y][x - 1] == b'#' {
|
||||
break 'outer;
|
||||
} else {
|
||||
x -= 1;
|
||||
amount -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
y
|
||||
}
|
||||
Direction::Right => {
|
||||
while amount > 0 {
|
||||
if x + 1 >= side_length {
|
||||
break;
|
||||
} else if map[y][x + 1] == b'#' {
|
||||
break 'outer;
|
||||
} else {
|
||||
amount -= 1;
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
y
|
||||
}
|
||||
};
|
||||
|
||||
if amount > 0 {
|
||||
let (new_dir, new_square, invert) =
|
||||
TRANSITIONS[current_square][dir as usize];
|
||||
|
||||
let flipped_coord = if invert {
|
||||
side_length - 1 - coord
|
||||
} else {
|
||||
coord
|
||||
};
|
||||
|
||||
let (new_x, new_y) = match new_dir {
|
||||
Direction::Up => (flipped_coord, side_length - 1),
|
||||
Direction::Down => (flipped_coord, 0),
|
||||
Direction::Left => (side_length - 1, flipped_coord),
|
||||
Direction::Right => (0, flipped_coord),
|
||||
};
|
||||
|
||||
if squares[new_square].0[new_y][new_x] == b'#' {
|
||||
break 'outer;
|
||||
}
|
||||
|
||||
x = new_x;
|
||||
y = new_y;
|
||||
current_square = new_square;
|
||||
dir = new_dir;
|
||||
amount -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (real_x, real_y) = convert_coords(current_square, x, y);
|
||||
|
||||
Ok((1000 * real_y + 4 * real_x + dir as usize).to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("samples/22.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "6032");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_side_length() {
|
||||
let (map, _) = parse_input(SAMPLE, parse_map).unwrap();
|
||||
|
||||
assert_eq!(side_length_of(&map), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_break_squares() {
|
||||
let (map, _) = parse_input(SAMPLE, parse_map).unwrap();
|
||||
|
||||
let side_length = side_length_of(&map);
|
||||
let squares = break_squares(&map, side_length);
|
||||
|
||||
assert_eq!(squares[0].1, 2);
|
||||
assert_eq!(squares[0].2, 0);
|
||||
|
||||
assert_eq!(squares[5].1, 3);
|
||||
assert_eq!(squares[5].2, 2);
|
||||
|
||||
for square in squares {
|
||||
assert_eq!(square.0.len(), side_length);
|
||||
|
||||
for row in square.0 {
|
||||
assert_eq!(row.len(), side_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sanity_transitions() {
|
||||
for (cur_face, &face) in TRANSITIONS.iter().enumerate() {
|
||||
for (dir, (arrive_dir, arrive_face, invert)) in face.into_iter().enumerate() {
|
||||
let inverse_dir = (arrive_dir as usize + 2) % 4;
|
||||
let (back_dir, back_face, back_invert) = TRANSITIONS[arrive_face][inverse_dir];
|
||||
|
||||
assert_eq!(
|
||||
invert, back_invert,
|
||||
"Reciprocal invert failed: face {cur_face} dir {dir} to face {arrive_face} arrives as {arrive_dir:?}"
|
||||
);
|
||||
|
||||
assert_eq!(back_face, cur_face, "Reciprocal transition failed: face {cur_face} dir {dir} arrives at {arrive_face} but returns at {back_face}");
|
||||
|
||||
let correct_back_dir = (dir + 2) % 4;
|
||||
|
||||
assert_eq!(back_dir as usize, correct_back_dir, "Reciprocal direction failed: face {cur_face} dir {dir} did not arrive the opposite direction from {arrive_face}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
205
2022/src/day23.rs
Normal file
205
2022/src/day23.rs
Normal file
@@ -0,0 +1,205 @@
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use ahash::AHashMap;
|
||||
use ahash::AHashSet;
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use itertools::Itertools;
|
||||
use nom::bytes::complete::take_until;
|
||||
use nom::character::complete::newline;
|
||||
use nom::multi::fold_many1;
|
||||
use nom::sequence::terminated;
|
||||
use nom::IResult;
|
||||
|
||||
use crate::common::enumerate;
|
||||
use crate::common::parse_input;
|
||||
use crate::common::Vec2;
|
||||
|
||||
const OPTIONS: [[Vec2; 3]; 4] = [
|
||||
// North
|
||||
[Vec2([0, -1]), Vec2([-1, -1]), Vec2([1, -1])],
|
||||
// South
|
||||
[Vec2([0, 1]), Vec2([-1, 1]), Vec2([1, 1])],
|
||||
// West
|
||||
[Vec2([-1, 0]), Vec2([-1, -1]), Vec2([-1, 1])],
|
||||
// East
|
||||
[Vec2([1, 0]), Vec2([1, -1]), Vec2([1, 1])],
|
||||
];
|
||||
|
||||
fn parse_elves(input: &[u8]) -> IResult<&[u8], AHashSet<Vec2>> {
|
||||
fold_many1(
|
||||
enumerate(terminated(take_until("\n"), newline)),
|
||||
AHashSet::new,
|
||||
|mut elves, (y, line): (usize, &[u8])| {
|
||||
let y = y as i32;
|
||||
|
||||
elves.extend(
|
||||
line.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(x, &val)| (val == b'#').then_some(Vec2([x as i32, y]))),
|
||||
);
|
||||
|
||||
elves
|
||||
},
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn determine_bounding_box(
|
||||
elves: &AHashSet<Vec2>,
|
||||
) -> Result<(RangeInclusive<i32>, RangeInclusive<i32>)> {
|
||||
let (x_min, x_max) = elves
|
||||
.iter()
|
||||
.map(|&Vec2([x, _])| x)
|
||||
.minmax()
|
||||
.into_option()
|
||||
.context("Could not determine x range")?;
|
||||
|
||||
let (y_min, y_max) = elves
|
||||
.iter()
|
||||
.map(|&Vec2([_, y])| y)
|
||||
.minmax()
|
||||
.into_option()
|
||||
.context("Could not determine y range")?;
|
||||
|
||||
Ok((x_min..=x_max, y_min..=y_max))
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn print(elves: &AHashSet<Vec2>) -> Result<()> {
|
||||
let (x_bounds, y_bounds) = determine_bounding_box(elves)?;
|
||||
|
||||
for y in y_bounds {
|
||||
for x in x_bounds.clone() {
|
||||
print!(
|
||||
"{}",
|
||||
if elves.contains(&Vec2([x, y])) {
|
||||
'#'
|
||||
} else {
|
||||
'.'
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
println!();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let mut elves = parse_input(input, parse_elves)?;
|
||||
|
||||
simulate(&mut elves, 10);
|
||||
|
||||
let (x_bounds, y_bounds) = determine_bounding_box(&elves)?;
|
||||
|
||||
let area = (x_bounds.end() - x_bounds.start() + 1) * (y_bounds.end() - y_bounds.start() + 1);
|
||||
|
||||
let free = area - elves.len() as i32;
|
||||
|
||||
Ok(free.to_string())
|
||||
}
|
||||
|
||||
fn simulate(elves: &mut AHashSet<Vec2>, max: usize) -> Option<usize> {
|
||||
let mut todo = Vec::new();
|
||||
let mut to_return = Vec::new();
|
||||
let mut origin = AHashMap::new();
|
||||
|
||||
for it in 0..max {
|
||||
// Remove all todos from a previous iteration
|
||||
todo.clear();
|
||||
|
||||
// Find all the elves with at least one neighbour
|
||||
todo.extend(elves.iter().copied().filter(|&Vec2([x, y])| {
|
||||
for dx in [-1, 0, 1] {
|
||||
for dy in [-1, 0, 1] {
|
||||
if dx == 0 && dy == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if elves.contains(&Vec2([x + dx, y + dy])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}));
|
||||
|
||||
for &elf in &todo {
|
||||
let mut moved = false;
|
||||
|
||||
for &deltas in OPTIONS[(it % 4)..].iter().chain(&OPTIONS[..(it % 4)]) {
|
||||
if deltas
|
||||
.into_iter()
|
||||
.all(|delta| !elves.contains(&(elf + delta)))
|
||||
{
|
||||
// Observation: any collision will only happen between opposite pairs of elves,
|
||||
// not three. Otherwise they wouldn't have chosen to move this direction.
|
||||
|
||||
// Somewhat messy but it avoids computing the hash more than once per elf
|
||||
match origin.entry(deltas[0] + elf) {
|
||||
Entry::Occupied(entry) => {
|
||||
to_return.push(elf);
|
||||
to_return.push(entry.remove());
|
||||
}
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(elf);
|
||||
}
|
||||
};
|
||||
|
||||
// We moved, or collided, but we shouldn't look other directions any more
|
||||
moved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if !moved {
|
||||
to_return.push(elf);
|
||||
}
|
||||
}
|
||||
|
||||
if origin.is_empty() {
|
||||
return Some(it + 1);
|
||||
}
|
||||
|
||||
// Remove entries we processed
|
||||
for elf in &todo {
|
||||
elves.remove(elf);
|
||||
}
|
||||
|
||||
// Add back any entries we ended up not moving
|
||||
elves.extend(to_return.drain(..));
|
||||
|
||||
// Add all the elves in their new positions
|
||||
elves.extend(origin.drain().map(|(dest, _)| dest));
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let mut elves = parse_input(input, parse_elves)?;
|
||||
|
||||
let first_non_moved = simulate(&mut elves, usize::MAX).context("Elves didn't stop moving?")?;
|
||||
|
||||
Ok(first_non_moved.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("./samples/23.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "110");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "20");
|
||||
}
|
||||
}
|
||||
214
2022/src/day24.rs
Normal file
214
2022/src/day24.rs
Normal file
@@ -0,0 +1,214 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::mem;
|
||||
|
||||
use ahash::AHashSet;
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use strength_reduce::StrengthReducedUsize;
|
||||
|
||||
fn gcd(mut a: usize, mut b: usize) -> usize {
|
||||
while a % b != 0 {
|
||||
b = a % b;
|
||||
mem::swap(&mut a, &mut b);
|
||||
}
|
||||
|
||||
b
|
||||
}
|
||||
|
||||
fn lcm(a: usize, b: usize) -> usize {
|
||||
a * b / gcd(a, b)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Storm {
|
||||
// Dimensions of the entire area. Includes the wall
|
||||
width: usize,
|
||||
height: usize,
|
||||
|
||||
// Periods of repetition. Basically the dimensions without the wall
|
||||
width_period: StrengthReducedUsize,
|
||||
height_period: StrengthReducedUsize,
|
||||
combined_period: StrengthReducedUsize,
|
||||
|
||||
// Flying blizzards by direction and starting point
|
||||
left_right: AHashSet<(usize, usize)>,
|
||||
right_left: AHashSet<(usize, usize)>,
|
||||
top_bottom: AHashSet<(usize, usize)>,
|
||||
bottom_top: AHashSet<(usize, usize)>,
|
||||
}
|
||||
|
||||
impl Storm {
|
||||
/// Whether you can stand in the given position at the given time
|
||||
fn can_stand(&self, time: usize, (x, y): (usize, usize)) -> bool {
|
||||
!self
|
||||
.right_left
|
||||
.contains(&((x + time) % self.width_period, y))
|
||||
&& !self
|
||||
.bottom_top
|
||||
.contains(&(x, (y + time) % self.height_period))
|
||||
&& !self.left_right.contains(&(
|
||||
(self.width_period.get() - time % self.width_period + x) % self.width_period,
|
||||
y,
|
||||
))
|
||||
&& !self.top_bottom.contains(&(
|
||||
x,
|
||||
(self.height_period.get() - time % self.height_period + y) % self.height_period,
|
||||
))
|
||||
}
|
||||
|
||||
fn dist(&self, from: (usize, usize), goal: (usize, usize), start: usize) -> Result<usize> {
|
||||
let mut todo = VecDeque::new();
|
||||
todo.push_back((start, from));
|
||||
|
||||
let mut visited = AHashSet::new();
|
||||
|
||||
while let Some((time, pos)) = todo.pop_front() {
|
||||
let mut enqueue = |pos| {
|
||||
let new_time = time + 1;
|
||||
|
||||
if self.can_stand(new_time, pos)
|
||||
&& visited.insert((new_time % self.combined_period, pos))
|
||||
{
|
||||
todo.push_back((new_time, pos));
|
||||
}
|
||||
};
|
||||
|
||||
// Waiting is perhaps an option
|
||||
enqueue(pos);
|
||||
|
||||
// If not in the starting position or the right edge
|
||||
if pos.0 > 1 && pos.1 < self.height - 1 {
|
||||
enqueue((pos.0 - 1, pos.1));
|
||||
}
|
||||
|
||||
if pos.1 > 0 && pos.0 < self.width - 2 {
|
||||
enqueue((pos.0 + 1, pos.1));
|
||||
}
|
||||
|
||||
if pos.1 > 1 {
|
||||
enqueue((pos.0, pos.1 - 1));
|
||||
}
|
||||
|
||||
if pos.0 > 0 && pos.1 < self.height - 2 {
|
||||
enqueue((pos.0, pos.1 + 1));
|
||||
}
|
||||
|
||||
if pos.1 >= 1 && (pos.0, pos.1 - 1) == goal {
|
||||
return Ok(time + 1);
|
||||
}
|
||||
|
||||
if (pos.0, pos.1 + 1) == goal {
|
||||
return Ok(time + 1);
|
||||
}
|
||||
}
|
||||
|
||||
anyhow::bail!("Did not find a route to {goal:?}")
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&'_ [u8]> for Storm {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: &'_ [u8]) -> Result<Self, Self::Error> {
|
||||
let width = value
|
||||
.iter()
|
||||
.position(|&b| b == b'\n')
|
||||
.context("Could not find end of line")?;
|
||||
let height = value.len() / (width + 1);
|
||||
|
||||
let width_period = StrengthReducedUsize::new(width - 2);
|
||||
let height_period = StrengthReducedUsize::new(height - 2);
|
||||
let combined_period = StrengthReducedUsize::new(lcm(width - 2, height - 2));
|
||||
|
||||
let mut left_right = AHashSet::new();
|
||||
let mut right_left = AHashSet::new();
|
||||
let mut top_bottom = AHashSet::new();
|
||||
let mut bottom_top = AHashSet::new();
|
||||
|
||||
for (y, line) in value
|
||||
.split(|&b| b == b'\n')
|
||||
.enumerate()
|
||||
.skip(1)
|
||||
.take(height - 2)
|
||||
{
|
||||
for (x, &c) in line.iter().enumerate() {
|
||||
match c {
|
||||
b'>' => left_right.insert((x % width_period, y)),
|
||||
b'<' => right_left.insert((x % width_period, y)),
|
||||
b'v' => top_bottom.insert((x, y % height_period)),
|
||||
b'^' => bottom_top.insert((x, y % height_period)),
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Storm {
|
||||
width,
|
||||
height,
|
||||
width_period,
|
||||
height_period,
|
||||
combined_period,
|
||||
left_right,
|
||||
right_left,
|
||||
top_bottom,
|
||||
bottom_top,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let storm = Storm::try_from(input)?;
|
||||
let goal = (storm.width - 2, storm.height - 1);
|
||||
|
||||
storm.dist((1, 0), goal, 0).map(|d| d.to_string())
|
||||
}
|
||||
|
||||
pub fn part2(input: &[u8]) -> Result<String> {
|
||||
let storm = Storm::try_from(input)?;
|
||||
let goal = (storm.width - 2, storm.height - 1);
|
||||
|
||||
let there = storm.dist((1, 0), goal, 0)?;
|
||||
let back_again = storm.dist(goal, (1, 0), there)?;
|
||||
|
||||
storm.dist((1, 0), goal, back_again).map(|s| s.to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("./samples/24.txt");
|
||||
|
||||
#[test]
|
||||
fn test_can_stand() {
|
||||
let storm = Storm::try_from(SAMPLE).unwrap();
|
||||
dbg!(&storm);
|
||||
|
||||
// Test a storm moving right to left
|
||||
assert!(storm.can_stand(0, (4, 2)));
|
||||
assert!(!storm.can_stand(1, (4, 2)));
|
||||
assert!(!storm.can_stand(0, (6, 2)));
|
||||
assert!(storm.can_stand(1, (6, 2)));
|
||||
|
||||
// Test a storm moving bottom to top
|
||||
assert!(!storm.can_stand(0, (4, 4)));
|
||||
assert!(storm.can_stand(1, (4, 4)));
|
||||
|
||||
// Simple moving to the right
|
||||
assert!(!storm.can_stand(0, (1, 1)));
|
||||
assert!(storm.can_stand(1, (1, 1)));
|
||||
|
||||
assert!(storm.can_stand(0, (1, 2)));
|
||||
assert!(!storm.can_stand(1, (1, 2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "18");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sample_part2() {
|
||||
assert_eq!(part2(SAMPLE).unwrap(), "54");
|
||||
}
|
||||
}
|
||||
71
2022/src/day25.rs
Normal file
71
2022/src/day25.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use anyhow::Result;
|
||||
|
||||
fn parse_num(num: &[u8]) -> Result<i64> {
|
||||
let mut total = 0;
|
||||
let mut factor = 1;
|
||||
|
||||
for &b in num.iter().rev() {
|
||||
match b {
|
||||
b'0' => (),
|
||||
b'1' => total += factor,
|
||||
b'2' => total += 2 * factor,
|
||||
b'-' => total -= factor,
|
||||
b'=' => total -= 2 * factor,
|
||||
other => anyhow::bail!("Invalid digit {other}"),
|
||||
}
|
||||
|
||||
factor *= 5;
|
||||
}
|
||||
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn encode(mut num: i64) -> String {
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
while num > 0 {
|
||||
match num % 5 {
|
||||
0 => buffer.push(b'0'),
|
||||
1 => buffer.push(b'1'),
|
||||
2 => buffer.push(b'2'),
|
||||
3 => {
|
||||
buffer.push(b'=');
|
||||
num += 2
|
||||
}
|
||||
4 => {
|
||||
buffer.push(b'-');
|
||||
num += 1;
|
||||
}
|
||||
_ => unreachable!("math"),
|
||||
}
|
||||
|
||||
num /= 5;
|
||||
}
|
||||
|
||||
// We've built the string right to left, to print we must reverse
|
||||
buffer.reverse();
|
||||
|
||||
// Safe unwrap as we've only pushed valid ascii characters
|
||||
String::from_utf8(buffer).unwrap()
|
||||
}
|
||||
|
||||
pub fn part1(input: &[u8]) -> Result<String> {
|
||||
let total = input
|
||||
.split(|&b| b == b'\n')
|
||||
.map(parse_num)
|
||||
.try_fold(0, |acc, val| val.map(|val| val + acc))?;
|
||||
|
||||
Ok(encode(total))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const SAMPLE: &[u8] = include_bytes!("./samples/25.txt");
|
||||
|
||||
#[test]
|
||||
fn sample_part1() {
|
||||
assert_eq!(part1(SAMPLE).unwrap(), "2=-1=0");
|
||||
}
|
||||
}
|
||||
91
2022/src/lib.rs
Normal file
91
2022/src/lib.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
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}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
61
2022/src/main.rs
Normal file
61
2022/src/main.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
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(())
|
||||
}
|
||||
0
2022/src/samples/.gitkeep
Normal file
0
2022/src/samples/.gitkeep
Normal file
14
2022/src/samples/01.txt
Normal file
14
2022/src/samples/01.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
1000
|
||||
2000
|
||||
3000
|
||||
|
||||
4000
|
||||
|
||||
5000
|
||||
6000
|
||||
|
||||
7000
|
||||
8000
|
||||
9000
|
||||
|
||||
10000
|
||||
3
2022/src/samples/02.txt
Normal file
3
2022/src/samples/02.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
A Y
|
||||
B X
|
||||
C Z
|
||||
6
2022/src/samples/03.txt
Normal file
6
2022/src/samples/03.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw
|
||||
6
2022/src/samples/04.txt
Normal file
6
2022/src/samples/04.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
||||
9
2022/src/samples/05.txt
Normal file
9
2022/src/samples/05.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
[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
|
||||
23
2022/src/samples/07.txt
Normal file
23
2022/src/samples/07.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
$ cd /
|
||||
$ ls
|
||||
dir a
|
||||
14848514 b.txt
|
||||
8504156 c.dat
|
||||
dir d
|
||||
$ cd a
|
||||
$ ls
|
||||
dir e
|
||||
29116 f
|
||||
2557 g
|
||||
62596 h.lst
|
||||
$ cd e
|
||||
$ ls
|
||||
584 i
|
||||
$ cd ..
|
||||
$ cd ..
|
||||
$ cd d
|
||||
$ ls
|
||||
4060174 j
|
||||
8033020 d.log
|
||||
5626152 d.ext
|
||||
7214296 k
|
||||
5
2022/src/samples/08.txt
Normal file
5
2022/src/samples/08.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
30373
|
||||
25512
|
||||
65332
|
||||
33549
|
||||
35390
|
||||
8
2022/src/samples/09.large.txt
Normal file
8
2022/src/samples/09.large.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
R 5
|
||||
U 8
|
||||
L 8
|
||||
D 3
|
||||
R 17
|
||||
D 10
|
||||
L 25
|
||||
U 20
|
||||
8
2022/src/samples/09.txt
Normal file
8
2022/src/samples/09.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
R 4
|
||||
U 4
|
||||
L 3
|
||||
D 1
|
||||
R 4
|
||||
D 1
|
||||
L 5
|
||||
R 2
|
||||
146
2022/src/samples/10.txt
Normal file
146
2022/src/samples/10.txt
Normal file
@@ -0,0 +1,146 @@
|
||||
addx 15
|
||||
addx -11
|
||||
addx 6
|
||||
addx -3
|
||||
addx 5
|
||||
addx -1
|
||||
addx -8
|
||||
addx 13
|
||||
addx 4
|
||||
noop
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx 5
|
||||
addx -1
|
||||
addx -35
|
||||
addx 1
|
||||
addx 24
|
||||
addx -19
|
||||
addx 1
|
||||
addx 16
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
addx 21
|
||||
addx -15
|
||||
noop
|
||||
noop
|
||||
addx -3
|
||||
addx 9
|
||||
addx 1
|
||||
addx -3
|
||||
addx 8
|
||||
addx 1
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -36
|
||||
noop
|
||||
addx 1
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
addx 6
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx 7
|
||||
addx 1
|
||||
noop
|
||||
addx -13
|
||||
addx 13
|
||||
addx 7
|
||||
noop
|
||||
addx 1
|
||||
addx -33
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 8
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx 17
|
||||
addx -9
|
||||
addx 1
|
||||
addx 1
|
||||
addx -3
|
||||
addx 11
|
||||
noop
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
addx -13
|
||||
addx -19
|
||||
addx 1
|
||||
addx 3
|
||||
addx 26
|
||||
addx -30
|
||||
addx 12
|
||||
addx -1
|
||||
addx 3
|
||||
addx 1
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -9
|
||||
addx 18
|
||||
addx 1
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
addx 9
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx -1
|
||||
addx 2
|
||||
addx -37
|
||||
addx 1
|
||||
addx 3
|
||||
noop
|
||||
addx 15
|
||||
addx -21
|
||||
addx 22
|
||||
addx -6
|
||||
addx 1
|
||||
noop
|
||||
addx 2
|
||||
addx 1
|
||||
noop
|
||||
addx -10
|
||||
noop
|
||||
noop
|
||||
addx 20
|
||||
addx 1
|
||||
addx 2
|
||||
addx 2
|
||||
addx -6
|
||||
addx -11
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
27
2022/src/samples/11.txt
Normal file
27
2022/src/samples/11.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
Monkey 0:
|
||||
Starting items: 79, 98
|
||||
Operation: new = old * 19
|
||||
Test: divisible by 23
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 1:
|
||||
Starting items: 54, 65, 75, 74
|
||||
Operation: new = old + 6
|
||||
Test: divisible by 19
|
||||
If true: throw to monkey 2
|
||||
If false: throw to monkey 0
|
||||
|
||||
Monkey 2:
|
||||
Starting items: 79, 60, 97
|
||||
Operation: new = old * old
|
||||
Test: divisible by 13
|
||||
If true: throw to monkey 1
|
||||
If false: throw to monkey 3
|
||||
|
||||
Monkey 3:
|
||||
Starting items: 74
|
||||
Operation: new = old + 3
|
||||
Test: divisible by 17
|
||||
If true: throw to monkey 0
|
||||
If false: throw to monkey 1
|
||||
5
2022/src/samples/12.txt
Normal file
5
2022/src/samples/12.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Sabqponm
|
||||
abcryxxl
|
||||
accszExk
|
||||
acctuvwj
|
||||
abdefghi
|
||||
23
2022/src/samples/13.txt
Normal file
23
2022/src/samples/13.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
[1,1,3,1,1]
|
||||
[1,1,5,1,1]
|
||||
|
||||
[[1],[2,3,4]]
|
||||
[[1],4]
|
||||
|
||||
[9]
|
||||
[[8,7,6]]
|
||||
|
||||
[[4,4],4,4]
|
||||
[[4,4],4,4,4]
|
||||
|
||||
[7,7,7,7]
|
||||
[7,7,7]
|
||||
|
||||
[]
|
||||
[3]
|
||||
|
||||
[[[]]]
|
||||
[[]]
|
||||
|
||||
[1,[2,[3,[4,[5,6,7]]]],8,9]
|
||||
[1,[2,[3,[4,[5,6,0]]]],8,9]
|
||||
2
2022/src/samples/14.txt
Normal file
2
2022/src/samples/14.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
498,4 -> 498,6 -> 496,6
|
||||
503,4 -> 502,4 -> 502,9 -> 494,9
|
||||
14
2022/src/samples/15.txt
Normal file
14
2022/src/samples/15.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Sensor at x=2, y=18: closest beacon is at x=-2, y=15
|
||||
Sensor at x=9, y=16: closest beacon is at x=10, y=16
|
||||
Sensor at x=13, y=2: closest beacon is at x=15, y=3
|
||||
Sensor at x=12, y=14: closest beacon is at x=10, y=16
|
||||
Sensor at x=10, y=20: closest beacon is at x=10, y=16
|
||||
Sensor at x=14, y=17: closest beacon is at x=10, y=16
|
||||
Sensor at x=8, y=7: closest beacon is at x=2, y=10
|
||||
Sensor at x=2, y=0: closest beacon is at x=2, y=10
|
||||
Sensor at x=0, y=11: closest beacon is at x=2, y=10
|
||||
Sensor at x=20, y=14: closest beacon is at x=25, y=17
|
||||
Sensor at x=17, y=20: closest beacon is at x=21, y=22
|
||||
Sensor at x=16, y=7: closest beacon is at x=15, y=3
|
||||
Sensor at x=14, y=3: closest beacon is at x=15, y=3
|
||||
Sensor at x=20, y=1: closest beacon is at x=15, y=3
|
||||
10
2022/src/samples/16.txt
Normal file
10
2022/src/samples/16.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Valve AA has flow rate=0; tunnels lead to valves DD, II, BB
|
||||
Valve BB has flow rate=13; tunnels lead to valves CC, AA
|
||||
Valve CC has flow rate=2; tunnels lead to valves DD, BB
|
||||
Valve DD has flow rate=20; tunnels lead to valves CC, AA, EE
|
||||
Valve EE has flow rate=3; tunnels lead to valves FF, DD
|
||||
Valve FF has flow rate=0; tunnels lead to valves EE, GG
|
||||
Valve GG has flow rate=0; tunnels lead to valves FF, HH
|
||||
Valve HH has flow rate=22; tunnel leads to valve GG
|
||||
Valve II has flow rate=0; tunnels lead to valves AA, JJ
|
||||
Valve JJ has flow rate=21; tunnel leads to valve II
|
||||
1
2022/src/samples/17.txt
Normal file
1
2022/src/samples/17.txt
Normal file
@@ -0,0 +1 @@
|
||||
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
||||
13
2022/src/samples/18.txt
Normal file
13
2022/src/samples/18.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
2,2,2
|
||||
1,2,2
|
||||
3,2,2
|
||||
2,1,2
|
||||
2,3,2
|
||||
2,2,1
|
||||
2,2,3
|
||||
2,2,4
|
||||
2,2,6
|
||||
1,2,5
|
||||
3,2,5
|
||||
2,1,5
|
||||
2,3,5
|
||||
11
2022/src/samples/19.txt
Normal file
11
2022/src/samples/19.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Blueprint 1:
|
||||
Each ore robot costs 4 ore.
|
||||
Each clay robot costs 2 ore.
|
||||
Each obsidian robot costs 3 ore and 14 clay.
|
||||
Each geode robot costs 2 ore and 7 obsidian.
|
||||
|
||||
Blueprint 2:
|
||||
Each ore robot costs 2 ore.
|
||||
Each clay robot costs 3 ore.
|
||||
Each obsidian robot costs 3 ore and 8 clay.
|
||||
Each geode robot costs 3 ore and 12 obsidian.
|
||||
7
2022/src/samples/20.txt
Normal file
7
2022/src/samples/20.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
1
|
||||
2
|
||||
-3
|
||||
3
|
||||
-2
|
||||
0
|
||||
4
|
||||
15
2022/src/samples/21.txt
Normal file
15
2022/src/samples/21.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
root: pppw + sjmn
|
||||
dbpl: 5
|
||||
cczh: sllz + lgvd
|
||||
zczc: 2
|
||||
ptdq: humn - dvpt
|
||||
dvpt: 3
|
||||
lfqf: 4
|
||||
humn: 5
|
||||
ljgn: 2
|
||||
sjmn: drzm * dbpl
|
||||
sllz: 4
|
||||
pppw: cczh / lfqf
|
||||
lgvd: ljgn * ptdq
|
||||
drzm: hmdt - zczc
|
||||
hmdt: 32
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user