Compare commits

..

No commits in common. "main" and "b9f4079cd52849310c2b26af4d338cd8c9dab32d" have entirely different histories.

114 changed files with 318 additions and 17733 deletions

View file

@ -2,9 +2,9 @@ name: Rust
on: on:
push: push:
branches: [ main ] branches: [ master ]
pull_request: pull_request:
branches: [ main ] branches: [ master ]
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@ -15,10 +15,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Format - name: Format
run: cargo fmt --all -- --check run: cargo fmt -- --check
- name: Lint - name: Lint
run: cargo clippy --workspace --all-targets --all-features -- -D warnings run: cargo clippy --all --all-targets --all-features -- -D warnings
- name: Run tests - name: Run tests
run: make check-all run: make check-all

2
.gitignore vendored
View file

@ -1,3 +1 @@
target/ target/
/.direnv/
/.envrc

3
.lohr
View file

@ -1,3 +0,0 @@
git@github.com:alarsyo/advent-of-code
git@gitlab.com:alarsyo/advent-of-code
git@git.sr.ht:~alarsyo/advent-of-code

619
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,7 @@
[workspace] [workspace]
members = ["aoc20*", "aoc20*/aoc20*_bench"] members = ["aoc*", "aoc*/aoc*_bench"]
default-members = ["aoc2023"] default-members = ["aoc2020"]
resolver = "2"
[profile.release] [profile.release]
debug = true debug = true

View file

@ -3,9 +3,11 @@ watch:
cargo watch -x clippy cargo watch -x clippy
check: check:
cargo test --workspace --release cargo test --all --release
check-all: # run these in release mode because the reason they're ignored is usually that
cargo test --workspace --release -- --include-ignored # they take a long time to run
check-all: check
cargo test --all --release -- --ignored
.PHONY: watch check check-all .PHONY: watch check check-all

View file

@ -1,53 +0,0 @@
#!/usr/bin/env fish
function usage
printf "Usage: %s [OPTIONS]\n\n" (status -f)
printf "Options:\n"
printf " -h/--help Prints help and exits\n"
printf " -d/--day=NUM Day (minimum 1, maximum 25)\n"
printf " -y/--year=NUM Year (minimum 2015, default current year)\n"
end
set --local options
set --append options (fish_opt --short h --long help)
set --append options (fish_opt --short d --long day --required-val)"!_validate_int --min 1 --max 25"
set --append options (fish_opt --short y --long year --required-val)"!_validate_int --min 2015"
if not argparse $options -- $argv
exit 1
end
if set --query _flag_help
usage
exit 0
end
# automatically set day if we're in December, otherwise require a value
set --local flag_day
if set --query _flag_day
set flag_day $_flag_day
else
set --local month (date +%-m)
if [ $month -eq 12 ]
set flag_day (date +%-d)
else
echo "Please provide a day to fetch"
exit 1
end
end
set --query _flag_year; or set --local _flag_year (date +%Y)
if not set --query AOC_SESSION
echo "Please provide a session cookie via the AOC_SESSION environment variable"
exit 1
end
set --local padded_day (string pad --width 2 --char 0 {$flag_day})
set --local outpath aoc{$_flag_year}/input/day{$padded_day}.txt
echo "Saving input to" {$outpath} "..."
curl https://adventofcode.com/{$_flag_year}/day/{$flag_day}/input \
--cookie "session="{$AOC_SESSION} \
--output {$outpath}

View file

@ -1,34 +0,0 @@
{ lib
, curl
, fish
, makeWrapper
, stdenvNoCC }:
stdenvNoCC.mkDerivation rec {
pname = "aoc-get";
version = "0.1.0";
src = ./aoc-get;
buildInputs = [
makeWrapper
fish
];
dontUnpack = true;
dontBuild = true;
wrapperPath = lib.makeBinPath [
curl
];
fixupPhase = ''
patchShebangs $out/bin/${pname}
wrapProgram $out/bin/${pname} --prefix PATH : "${wrapperPath}"
'';
installPhase = ''
mkdir -p $out/bin
cp $src $out/bin/${pname}
chmod a+x $out/bin/${pname}
'';
}

View file

@ -2,7 +2,7 @@
name = "aoc" name = "aoc"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -2,7 +2,7 @@
name = "aoc2015" name = "aoc2015"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -2,7 +2,7 @@
name = "aoc2015_bench" name = "aoc2015_bench"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -29,7 +29,7 @@ fn wrapping_paper(present: &Present) -> u64 {
} }
fn part1(presents: &[Present]) -> u64 { fn part1(presents: &[Present]) -> u64 {
presents.iter().map(wrapping_paper).sum() presents.iter().map(|p| wrapping_paper(p)).sum()
} }
fn ribbon_bow_length(present: &Present) -> u64 { fn ribbon_bow_length(present: &Present) -> u64 {
@ -49,7 +49,7 @@ fn ribbon_needed(present: &Present) -> u64 {
} }
fn part2(presents: &[Present]) -> u64 { fn part2(presents: &[Present]) -> u64 {
presents.iter().map(ribbon_needed).sum() presents.iter().map(|p| ribbon_needed(p)).sum()
} }
struct Present { struct Present {

View file

@ -41,10 +41,10 @@ fn part1(input: &str) -> usize {
false false
}) })
.filter(|line| !line.contains("ab")) .filter(|line| line.find("ab").is_none())
.filter(|line| !line.contains("cd")) .filter(|line| line.find("cd").is_none())
.filter(|line| !line.contains("pq")) .filter(|line| line.find("pq").is_none())
.filter(|line| !line.contains("xy")) .filter(|line| line.find("xy").is_none())
.count() .count()
} }
@ -56,7 +56,7 @@ fn part2(input: &str) -> usize {
for i in 0..(line.chars().count() - 3) { for i in 0..(line.chars().count() - 3) {
let seq = &line[i..(i + 2)]; let seq = &line[i..(i + 2)];
let line = &line[(i + 2)..]; let line = &line[(i + 2)..];
if line.contains(seq) { if line.find(seq).is_some() {
return true; return true;
} }
} }

View file

@ -2,7 +2,7 @@
name = "aoc2018" name = "aoc2018"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -2,7 +2,7 @@
name = "aoc2018_bench" name = "aoc2018_bench"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -31,11 +31,11 @@ impl FromStr for Event {
type Err = anyhow::Error; type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> { fn from_str(s: &str) -> Result<Self> {
if s.contains("wakes up") { if s.find("wakes up").is_some() {
Ok(Event::WakeUp) Ok(Event::WakeUp)
} else if s.contains("falls asleep") { } else if s.find("falls asleep").is_some() {
Ok(Event::FallAsleep) Ok(Event::FallAsleep)
} else if s.contains("begins shift") { } else if s.find("begins shift").is_some() {
let pound = s.find('#').context("`#` not found")?; let pound = s.find('#').context("`#` not found")?;
let s = &s[(pound + 1)..]; let s = &s[(pound + 1)..];
let space = s.find(' ').context("` ` not found after `#`")?; let space = s.find(' ').context("` ` not found after `#`")?;
@ -49,9 +49,9 @@ impl FromStr for Event {
#[derive(Debug)] #[derive(Debug)]
struct Date { struct Date {
_year: u32, year: u32,
_month: u8, month: u8,
_day: u8, day: u8,
hour: u8, hour: u8,
minute: u8, minute: u8,
@ -84,9 +84,9 @@ impl FromStr for Date {
let minute = s[..r_bracket].parse()?; let minute = s[..r_bracket].parse()?;
Ok(Date { Ok(Date {
_year: year, year,
_month: month, month,
_day: day, day,
hour, hour,
minute, minute,
}) })

View file

@ -2,7 +2,7 @@
name = "aoc2019" name = "aoc2019"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -2,7 +2,7 @@
name = "aoc2019_bench" name = "aoc2019_bench"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -18,7 +18,7 @@ pub fn run() -> Result<String> {
} }
fn manhattan_distance(a: &Point, b: &Point) -> u64 { fn manhattan_distance(a: &Point, b: &Point) -> u64 {
(a.x - b.x).unsigned_abs() + (a.y - b.y).unsigned_abs() (a.x - b.x).abs() as u64 + (a.y - b.y).abs() as u64
} }
fn part1(first_wire: &Wire, second_wire: &Wire) -> Result<u64> { fn part1(first_wire: &Wire, second_wire: &Wire) -> Result<u64> {
@ -48,7 +48,7 @@ fn part2(first_wire: &Wire, second_wire: &Wire) -> Result<u64> {
let mut second_length = 0; let mut second_length = 0;
for seg2 in &second_wire.0 { for seg2 in &second_wire.0 {
if let Some(inter) = seg1.intersection(seg2) { if let Some(inter) = seg1.intersection(&seg2) {
if inter.x == 0 && inter.y == 0 { if inter.x == 0 && inter.y == 0 {
continue; continue;
} }

View file

@ -49,7 +49,7 @@ fn part1(input: &str) -> Result<u64> {
let mut cache = HashMap::new(); let mut cache = HashMap::new();
Ok(orbits Ok(orbits
.keys() .keys()
.map(|k| count_orbits(k, &orbits, &mut cache)) .map(|k| count_orbits(&k, &orbits, &mut cache))
.sum()) .sum())
} }

View file

@ -84,12 +84,12 @@ impl FromStr for Image {
let lines = digits let lines = digits
.chunks(IMG_WIDTH) .chunks(IMG_WIDTH)
.map(<[_]>::to_vec) .map(|chunk| chunk.to_vec())
.collect::<Vec<Vec<u8>>>(); .collect::<Vec<Vec<u8>>>();
let layers = lines let layers = lines
.chunks(IMG_HEIGHT) .chunks(IMG_HEIGHT)
.map(<[_]>::to_vec) .map(|chunk| chunk.to_vec())
.map(|pixels| Layer { pixels }) .map(|pixels| Layer { pixels })
.collect::<Vec<Layer>>(); .collect::<Vec<Layer>>();

View file

@ -233,12 +233,12 @@ impl Planet {
fn potential_energy(&self) -> u64 { fn potential_energy(&self) -> u64 {
let pos = &self.position; let pos = &self.position;
pos.x.unsigned_abs() + pos.y.unsigned_abs() + pos.z.unsigned_abs() pos.x.abs() as u64 + pos.y.abs() as u64 + pos.z.abs() as u64
} }
fn kinetic_energy(&self) -> u64 { fn kinetic_energy(&self) -> u64 {
let vel = &self.velocity; let vel = &self.velocity;
vel.x.unsigned_abs() + vel.y.unsigned_abs() + vel.z.unsigned_abs() vel.x.abs() as u64 + vel.y.abs() as u64 + vel.z.abs() as u64
} }
fn total_energy(&self) -> u64 { fn total_energy(&self) -> u64 {

View file

@ -226,7 +226,7 @@ impl Intcode {
let val1 = op1.get(&mut self.memory, self.relative_base)?; let val1 = op1.get(&mut self.memory, self.relative_base)?;
let val2 = op2.get(&mut self.memory, self.relative_base)?; let val2 = op2.get(&mut self.memory, self.relative_base)?;
let res = i64::from(val1 < val2); let res = if val1 < val2 { 1 } else { 0 };
dst.set(res, &mut self.memory, self.relative_base)?; dst.set(res, &mut self.memory, self.relative_base)?;
self.ip += 4; self.ip += 4;
@ -235,7 +235,7 @@ impl Intcode {
let val1 = op1.get(&mut self.memory, self.relative_base)?; let val1 = op1.get(&mut self.memory, self.relative_base)?;
let val2 = op2.get(&mut self.memory, self.relative_base)?; let val2 = op2.get(&mut self.memory, self.relative_base)?;
let res = i64::from(val1 == val2); let res = if val1 == val2 { 1 } else { 0 };
dst.set(res, &mut self.memory, self.relative_base)?; dst.set(res, &mut self.memory, self.relative_base)?;
self.ip += 4; self.ip += 4;
@ -263,7 +263,7 @@ impl Intcode {
} }
pub fn get_day02_output(&self) -> Option<i64> { pub fn get_day02_output(&self) -> Option<i64> {
self.memory.first().copied() self.memory.get(0).copied()
} }
pub fn get_last_output(&self) -> Option<i64> { pub fn get_last_output(&self) -> Option<i64> {

View file

@ -2,7 +2,7 @@
name = "aoc2020" name = "aoc2020"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -10,7 +10,7 @@ edition = "2021"
aoc = { path = "../aoc" } aoc = { path = "../aoc" }
anyhow = "1.0" anyhow = "1.0"
itertools = "0.9" itertools = "0.9"
nom = "7.0" nom = "6.0"
[lib] [lib]
path = "src/lib.rs" path = "src/lib.rs"

View file

@ -2,7 +2,7 @@
name = "aoc2020_bench" name = "aoc2020_bench"
version = "0.1.0" version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"] authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021" edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View file

@ -154,16 +154,16 @@ impl CompletePassport {
fn hgt_valid(&self) -> bool { fn hgt_valid(&self) -> bool {
if let Some(num) = self.hgt.strip_suffix("in") { if let Some(num) = self.hgt.strip_suffix("in") {
is_number_in_range(num, 59..=76) is_number_in_range(&num, 59..=76)
} else if let Some(num) = self.hgt.strip_suffix("cm") { } else if let Some(num) = self.hgt.strip_suffix("cm") {
is_number_in_range(num, 150..=193) is_number_in_range(&num, 150..=193)
} else { } else {
false false
} }
} }
fn hcl_valid(&self) -> bool { fn hcl_valid(&self) -> bool {
if let Some(rest) = self.hcl.strip_prefix('#') { if let Some(rest) = self.hcl.strip_prefix("#") {
rest.chars().filter(|c| !c.is_ascii_hexdigit()).count() == 0 rest.chars().filter(|c| !c.is_ascii_hexdigit()).count() == 0
} else { } else {
false false

View file

@ -64,13 +64,13 @@ impl Layout {
match cell { match cell {
Cell::EmptySeat => { Cell::EmptySeat => {
if adj_count(self, i, j, Cell::OccupiedSeat) == 0 { if adj_count(&self, i, j, Cell::OccupiedSeat) == 0 {
new[i][j] = Cell::OccupiedSeat; new[i][j] = Cell::OccupiedSeat;
changed = true; changed = true;
} }
} }
Cell::OccupiedSeat => { Cell::OccupiedSeat => {
if adj_count(self, i, j, Cell::OccupiedSeat) >= occupied_threshold { if adj_count(&self, i, j, Cell::OccupiedSeat) >= occupied_threshold {
new[i][j] = Cell::EmptySeat; new[i][j] = Cell::EmptySeat;
changed = true; changed = true;
} }
@ -111,8 +111,9 @@ impl Layout {
count += self count += self
.grid .grid
.get(i) .get(i)
.and_then(|line| line.get(j)) .map(|line| line.get(j))
.map(|&cell| u8::from(cell == value)) .flatten()
.map(|&cell| if cell == value { 1 } else { 0 })
.unwrap_or(0); .unwrap_or(0);
} }
@ -130,7 +131,7 @@ impl Layout {
let (i, j) = (i.wrapping_add(di as usize), j.wrapping_add(dj as usize)); let (i, j) = (i.wrapping_add(di as usize), j.wrapping_add(dj as usize));
let cell = self.grid.get(i).and_then(|line| line.get(j)); let cell = self.grid.get(i).map(|line| line.get(j)).flatten();
match cell { match cell {
// keep going, the next seat is farther away // keep going, the next seat is farther away

View file

@ -286,7 +286,7 @@ impl Program {
} }
fn memory_sum(&self) -> u64 { fn memory_sum(&self) -> u64 {
self.memory.values().sum() self.memory.iter().map(|(_, value)| value).sum()
} }
} }

View file

@ -22,7 +22,8 @@ fn part1(input: &str) -> Result<u64> {
Ok(tickets Ok(tickets
.iter() .iter()
.flat_map(|t| t.invalid_values(&fields_vec)) .map(|t| t.invalid_values(&fields_vec))
.flatten()
.sum()) .sum())
} }
@ -44,6 +45,7 @@ fn assign_field_positions(
.iter() .iter()
.map(|(&name, field)| { .map(|(&name, field)| {
let possibilities = (0..num_values) let possibilities = (0..num_values)
.into_iter()
.filter(|i| tickets.iter().all(|t| t.valid_field(field, *i))) .filter(|i| tickets.iter().all(|t| t.valid_field(field, *i)))
.collect(); .collect();
@ -222,7 +224,7 @@ mod tests {
let matches = assign_field_positions(fields, tickets); let matches = assign_field_positions(fields, tickets);
let expected = ["row", "class", "seat"] let expected = (&["row", "class", "seat"])
.iter() .iter()
.copied() .copied()
.enumerate() .enumerate()

View file

@ -84,7 +84,7 @@ fn operator_expr(input: &str) -> IResult<&str, Expr> {
fold_many0( fold_many0(
pair(delimited(char(' '), operator, char(' ')), term), pair(delimited(char(' '), operator, char(' ')), term),
move || first_term.clone(), first_term,
|acc, (op, val)| Expr::Op(Box::new(acc), op, Box::new(val)), |acc, (op, val)| Expr::Op(Box::new(acc), op, Box::new(val)),
)(i) )(i)
} }
@ -97,7 +97,7 @@ fn plus(input: &str) -> IResult<&str, Expr> {
delimited(char(' '), char('+'), char(' ')), delimited(char(' '), char('+'), char(' ')),
term_plus_priority, term_plus_priority,
), ),
move || first_term.clone(), first_term,
|acc, (_, val)| Expr::Op(Box::new(acc), Operator::Addition, Box::new(val)), |acc, (_, val)| Expr::Op(Box::new(acc), Operator::Addition, Box::new(val)),
)(i) )(i)
} }
@ -107,13 +107,13 @@ fn mul(input: &str) -> IResult<&str, Expr> {
fold_many0( fold_many0(
pair(delimited(char(' '), char('*'), char(' ')), plus), pair(delimited(char(' '), char('*'), char(' ')), plus),
move || first_factor.clone(), first_factor,
|acc, (_, val)| Expr::Op(Box::new(acc), Operator::Multiplication, Box::new(val)), |acc, (_, val)| Expr::Op(Box::new(acc), Operator::Multiplication, Box::new(val)),
)(i) )(i)
} }
fn num(input: &str) -> IResult<&str, Expr> { fn num(input: &str) -> IResult<&str, Expr> {
map_res(take_while1(|c: char| c.is_ascii_digit()), |res: &str| { map_res(take_while1(|c: char| c.is_digit(10)), |res: &str| {
res.parse().map(Expr::Num) res.parse().map(Expr::Num)
})(input) })(input)
} }

View file

@ -59,7 +59,7 @@ enum Rotation {
/// ///
/// Note: we don't need a horizontal and a vertical flip, these result in the same output as a 180 /// Note: we don't need a horizontal and a vertical flip, these result in the same output as a 180
/// degree rotation when combined, so only one is necessary /// degree rotation when combined, so only one is necessary
#[derive(Debug, Default, Clone, Copy)] #[derive(Debug, Clone, Copy)]
struct Transform { struct Transform {
flip: bool, flip: bool,
rotation: Option<Rotation>, rotation: Option<Rotation>,
@ -121,6 +121,15 @@ impl Transform {
} }
} }
impl Default for Transform {
fn default() -> Self {
Self {
flip: false,
rotation: None,
}
}
}
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
enum Position { enum Position {
Down, Down,
@ -307,7 +316,8 @@ impl Image {
image_positions.insert((0, 0), tiles[0].clone()); image_positions.insert((0, 0), tiles[0].clone());
// compute each image position depending on its neighbours // compute each image position depending on its neighbours
while let Some(pos) = todo.pop() { while !todo.is_empty() {
let pos = todo.pop().unwrap();
let tile = &image_positions[&pos]; let tile = &image_positions[&pos];
for (direction, other_tile) in tile.neighbours(tiles) { for (direction, other_tile) in tile.neighbours(tiles) {
@ -338,9 +348,9 @@ impl Image {
const IMAGE_TILE_HEIGHT: usize = TILE_HEIGHT - 2; const IMAGE_TILE_HEIGHT: usize = TILE_HEIGHT - 2;
const IMAGE_TILE_WIDTH: usize = TILE_WIDTH - 2; const IMAGE_TILE_WIDTH: usize = TILE_WIDTH - 2;
let height = *image_positions.iter().map(|((i, _), _)| i).max().unwrap() + 1; let height = *image_positions.iter().map(|((i, _), _)| i).max().unwrap() as usize + 1;
let height = height * IMAGE_TILE_HEIGHT; let height = height * IMAGE_TILE_HEIGHT;
let width = *image_positions.iter().map(|((_, j), _)| j).max().unwrap() + 1; let width = *image_positions.iter().map(|((_, j), _)| j).max().unwrap() as usize + 1;
let width = width * IMAGE_TILE_HEIGHT; let width = width * IMAGE_TILE_HEIGHT;
let mut pixels = Vec::new(); let mut pixels = Vec::new();
@ -351,8 +361,8 @@ impl Image {
} }
for (pos, tile) in image_positions { for (pos, tile) in image_positions {
let begin_i = IMAGE_TILE_HEIGHT * pos.0; let begin_i = IMAGE_TILE_HEIGHT * pos.0 as usize;
let begin_j = IMAGE_TILE_WIDTH * pos.1; let begin_j = IMAGE_TILE_WIDTH * pos.1 as usize;
for i in 0..IMAGE_TILE_HEIGHT { for i in 0..IMAGE_TILE_HEIGHT {
for j in 0..IMAGE_TILE_WIDTH { for j in 0..IMAGE_TILE_WIDTH {

View file

@ -71,6 +71,8 @@ impl CupCircle {
// keep subtracting one until it finds a cup that wasn't just picked up. If at any point in // keep subtracting one until it finds a cup that wasn't just picked up. If at any point in
// this process the value goes below the lowest value on any cup's label, it wraps around to // this process the value goes below the lowest value on any cup's label, it wraps around to
// the highest value on any cup's label instead. // the highest value on any cup's label instead.
//
// TODO: use std::cmp::Ord::clamp when stabilized (Rust 1.50)
let mut destination = if current > 1 { current - 1 } else { self.max() }; let mut destination = if current > 1 { current - 1 } else { self.max() };
while removed_cups.contains(&destination) { while removed_cups.contains(&destination) {
destination = if destination > 1 { destination = if destination > 1 {
@ -191,6 +193,8 @@ impl FastCupCircle {
// keep subtracting one until it finds a cup that wasn't just picked up. If at any point in // keep subtracting one until it finds a cup that wasn't just picked up. If at any point in
// this process the value goes below the lowest value on any cup's label, it wraps around to // this process the value goes below the lowest value on any cup's label, it wraps around to
// the highest value on any cup's label instead. // the highest value on any cup's label instead.
//
// TODO: use std::cmp::Ord::clamp when stabilized (Rust 1.50)
let mut destination = if self.current > 1 { let mut destination = if self.current > 1 {
self.current - 1 self.current - 1
} else { } else {

View file

@ -86,7 +86,9 @@ fn part2(input: &str) -> Result<usize> {
let mut seen = HashSet::new(); let mut seen = HashSet::new();
let mut todo: Vec<HexCoordinates> = black_tiles.iter().copied().collect(); let mut todo: Vec<HexCoordinates> = black_tiles.iter().copied().collect();
while let Some(tile) = todo.pop() { while !todo.is_empty() {
let tile = todo.pop().unwrap();
if seen.contains(&tile) { if seen.contains(&tile) {
continue; continue;
} else { } else {
@ -97,7 +99,7 @@ fn part2(input: &str) -> Result<usize> {
let count = neighbours let count = neighbours
.iter() .iter()
.filter(|tile| black_tiles.contains(tile)) .filter(|tile| black_tiles.contains(&tile))
.count(); .count();
if black_tiles.contains(&tile) { if black_tiles.contains(&tile) {
// Any black tile with zero or more than 2 black tiles immediately adjacent to it is // Any black tile with zero or more than 2 black tiles immediately adjacent to it is
@ -131,7 +133,7 @@ fn part2(input: &str) -> Result<usize> {
/// These use the axial coordinates described here: /// These use the axial coordinates described here:
/// ///
/// https://www.redblobgames.com/grids/hexagons/#coordinates-axial /// https://www.redblobgames.com/grids/hexagons/#coordinates-axial
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
struct HexCoordinates { struct HexCoordinates {
q: i64, q: i64,
r: i64, r: i64,
@ -186,6 +188,12 @@ impl HexCoordinates {
} }
} }
impl Default for HexCoordinates {
fn default() -> Self {
Self { q: 0, r: 0 }
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -1,20 +0,0 @@
[package]
name = "aoc2021"
version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aoc = { path = "../aoc" }
anyhow = "1.0"
rand = "0.8"
bitvec = "1.0"
[lib]
path = "src/lib.rs"
[[bin]]
name = "aoc2021"
path = "src/main.rs"

View file

@ -1,17 +0,0 @@
[package]
name = "aoc2021_bench"
version = "0.1.0"
authors = ["Antoine Martin <antoine97.martin@gmail.com>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aoc2021 = { path = "../" }
[dev-dependencies]
criterion = "0.3"
[[bench]]
name = "aoc2021_bench"
harness = false

View file

@ -1,46 +0,0 @@
use criterion::{criterion_group, criterion_main, Criterion};
use aoc2021::day01;
use aoc2021::day02;
use aoc2021::day03;
use aoc2021::day04;
use aoc2021::day05;
use aoc2021::day06;
use aoc2021::day07;
use aoc2021::day08;
use aoc2021::day09;
use aoc2021::day10;
use aoc2021::day11;
use aoc2021::day12;
use aoc2021::day13;
use aoc2021::day14;
use aoc2021::day15;
use aoc2021::day16;
use aoc2021::day17;
fn aoc2021_all(c: &mut Criterion) {
c.bench_function("day01", |b| b.iter(|| day01::run().unwrap()));
c.bench_function("day02", |b| b.iter(|| day02::run().unwrap()));
c.bench_function("day03", |b| b.iter(|| day03::run().unwrap()));
c.bench_function("day04", |b| b.iter(|| day04::run().unwrap()));
c.bench_function("day05", |b| b.iter(|| day05::run().unwrap()));
c.bench_function("day06", |b| b.iter(|| day06::run().unwrap()));
c.bench_function("day07", |b| b.iter(|| day07::run().unwrap()));
c.bench_function("day08", |b| b.iter(|| day08::run().unwrap()));
c.bench_function("day09", |b| b.iter(|| day09::run().unwrap()));
c.bench_function("day10", |b| b.iter(|| day10::run().unwrap()));
c.bench_function("day11", |b| b.iter(|| day11::run().unwrap()));
c.bench_function("day12", |b| b.iter(|| day12::run().unwrap()));
c.bench_function("day13", |b| b.iter(|| day13::run().unwrap()));
c.bench_function("day14", |b| b.iter(|| day14::run().unwrap()));
c.bench_function("day15", |b| b.iter(|| day15::run().unwrap()));
c.bench_function("day16", |b| b.iter(|| day16::run().unwrap()));
c.bench_function("day17", |b| b.iter(|| day17::run().unwrap()));
}
criterion_group! {
name = all_days;
config = Criterion::default().sample_size(200);
targets = aoc2021_all
}
criterion_main!(all_days);

File diff suppressed because it is too large Load diff

View file

@ -1,10 +0,0 @@
199
200
208
210
200
207
240
269
260
263

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
forward 5
down 5
forward 8
up 3
down 8
forward 2

File diff suppressed because it is too large Load diff

View file

@ -1,12 +0,0 @@
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010

View file

@ -1,601 +0,0 @@
0,56,39,4,52,7,73,57,65,13,3,72,69,96,18,9,49,83,24,31,12,64,29,21,80,71,66,95,2,62,68,46,11,33,74,88,17,15,5,6,98,30,51,78,76,75,28,53,87,48,20,22,55,86,82,90,47,19,25,1,27,60,94,38,97,58,70,10,43,40,89,26,34,32,23,45,50,91,61,44,35,85,63,16,99,92,8,36,81,84,79,37,93,67,59,54,41,77,42,14
63 5 10 69 57
64 88 27 40 76
59 20 58 90 6
74 32 72 16 26
50 17 7 93 94
92 77 33 44 14
35 25 47 91 7
99 6 56 82 10
41 93 70 5 85
81 97 58 96 29
24 53 4 8 23
0 13 48 47 83
55 56 72 50 52
82 33 58 16 11
91 7 89 9 81
86 70 16 4 34
49 69 37 78 11
22 47 59 20 38
33 82 60 63 56
18 74 36 7 99
64 45 72 86 7
34 50 94 0 85
15 69 2 26 32
62 96 41 17 78
63 5 99 79 47
62 63 24 37 50
89 80 40 41 13
32 64 95 93 66
45 3 23 78 48
60 26 31 61 99
6 63 66 67 15
33 43 62 95 89
72 61 60 2 10
29 7 9 50 18
28 36 3 53 30
91 4 57 74 66
49 36 54 7 89
33 65 59 14 92
63 42 0 20 11
64 32 96 18 58
85 59 33 18 99
90 4 1 51 35
2 57 9 5 78
30 53 25 23 80
74 76 20 19 21
5 42 50 72 90
58 63 49 17 31
39 76 8 19 41
9 59 61 23 54
91 57 18 70 69
90 6 36 71 78
73 75 56 43 35
92 31 21 47 86
69 10 52 80 55
68 30 22 45 34
4 15 88 6 38
46 37 34 23 91
50 98 89 3 79
90 93 60 56 20
40 8 30 69 1
13 62 39 56 78
6 7 17 94 5
44 77 76 81 20
91 64 34 99 45
63 37 3 2 66
57 19 63 59 8
83 51 58 21 4
54 61 56 9 95
92 52 84 67 66
80 34 1 97 69
0 95 89 40 51
58 90 97 85 61
64 47 10 37 26
19 63 7 71 81
20 25 57 55 21
72 6 39 97 58
50 63 2 46 86
73 12 59 37 66
93 77 47 34 67
5 4 98 51 48
96 5 17 68 73
55 13 88 3 52
95 62 18 83 63
31 15 99 20 93
29 50 0 74 22
11 84 79 92 67
36 23 76 14 80
82 72 53 3 85
46 71 89 25 40
51 81 29 0 65
68 24 96 87 5
53 10 95 89 81
88 80 23 12 50
65 16 45 29 62
33 97 91 60 43
36 77 68 20 51
93 71 28 70 97
10 9 16 15 67
42 78 62 34 38
60 74 18 91 53
65 35 40 34 71
0 84 13 81 95
2 31 46 24 76
67 28 83 63 25
62 93 10 14 68
17 36 72 65 49
29 9 22 42 58
76 20 57 3 54
13 37 88 62 24
66 78 55 30 48
55 18 97 40 30
76 69 22 86 98
48 96 20 65 1
77 45 91 82 25
56 70 66 34 58
15 59 37 69 66
51 16 25 0 79
76 72 68 70 20
95 33 82 27 52
53 65 40 45 92
65 18 54 9 28
47 11 84 89 71
52 96 83 57 86
55 0 56 72 20
26 19 81 60 64
97 28 89 55 11
33 92 50 86 79
81 37 0 94 64
44 76 68 58 26
57 65 60 78 93
62 4 55 50 74
86 46 89 20 68
1 52 78 73 19
14 10 0 40 28
69 35 26 22 7
29 15 9 27 8
98 22 69 14 44
75 24 66 63 90
62 72 87 32 31
26 59 85 82 77
90 42 40 10 48
73 8 57 18 29
67 76 5 72 93
43 27 28 82 80
62 41 36 61 21
25 64 69 6 65
40 36 16 81 34
63 38 80 55 29
20 50 90 21 72
4 17 83 27 92
96 89 9 62 78
18 47 82 80 73
75 38 51 3 50
48 19 99 54 6
4 28 63 98 43
37 68 13 30 23
82 14 65 60 27
43 74 62 46 99
80 26 15 9 20
58 44 92 76 64
2 80 99 17 43
37 48 65 52 40
81 90 83 78 72
77 21 56 66 68
92 22 10 61 49
72 27 88 7 57
51 73 31 55 23
39 48 12 91 2
92 42 71 93 4
26 38 36 22 75
37 2 9 10 52
33 45 11 67 25
31 6 5 79 14
70 39 99 8 81
65 87 83 68 77
54 89 78 49 63
39 33 27 98 28
79 61 20 2 25
92 12 13 29 30
51 77 94 38 46
28 87 30 75 9
48 8 23 60 89
79 2 21 18 6
25 69 24 15 71
44 36 59 31 68
16 0 69 19 9
68 15 90 8 87
75 21 12 97 39
5 83 55 23 72
43 60 58 13 76
53 29 98 73 13
58 30 10 68 21
32 81 66 6 82
97 45 15 7 92
19 75 90 36 67
66 14 39 62 89
94 42 20 46 48
0 7 92 4 86
3 84 60 37 55
27 64 1 30 82
78 82 57 44 47
86 11 62 52 99
7 70 17 60 15
45 19 4 91 75
3 6 24 94 81
38 2 59 51 17
76 64 19 78 7
55 42 39 47 56
79 65 37 57 40
53 66 73 83 68
38 49 65 79 82
15 63 53 32 21
48 1 3 81 69
94 87 20 6 59
8 50 96 71 76
17 28 41 24 69
20 96 9 57 85
70 15 53 38 52
79 84 37 73 64
40 30 25 56 1
68 11 49 37 46
24 63 72 35 29
92 62 89 73 28
64 58 9 3 39
13 45 10 19 20
54 41 49 33 60
85 56 0 77 51
81 12 13 20 27
36 24 69 39 80
14 83 57 50 91
19 68 61 56 11
3 74 6 25 22
71 10 21 7 29
92 12 51 84 30
41 72 85 36 91
16 86 37 88 22
48 18 4 89 55
58 83 44 7 43
28 76 15 11 35
81 52 29 23 64
52 42 98 0 31
92 47 41 87 33
6 35 69 44 17
91 50 89 75 3
57 61 81 60 21
40 86 78 2 58
76 73 31 19 14
50 21 53 83 45
68 9 22 70 69
54 1 85 90 44
13 20 96 89 22
85 62 19 99 66
18 46 28 14 39
12 21 34 1 81
40 77 25 4 7
21 76 60 10 9
34 29 59 48 40
30 2 36 82 66
12 95 80 72 58
74 3 46 37 49
6 30 25 12 22
33 65 4 89 59
86 94 70 49 16
11 76 66 84 45
50 31 46 73 36
89 4 99 23 84
72 90 83 44 20
33 66 91 35 26
81 85 24 10 55
45 43 7 78 53
55 62 19 44 63
12 90 77 28 7
80 92 15 41 11
58 24 47 66 82
48 88 37 60 46
48 16 86 94 14
22 43 46 67 1
91 88 49 79 28
19 12 35 85 42
13 26 68 95 97
23 67 33 85 82
21 71 84 8 58
20 41 53 22 99
92 89 59 16 19
79 93 39 83 80
98 96 24 47 15
79 97 19 64 84
62 91 38 30 65
74 25 92 16 50
51 41 34 18 35
55 9 27 95 90
31 11 50 84 71
37 61 62 60 88
24 94 29 42 77
17 83 47 74 91
74 19 3 13 29
48 17 26 42 22
9 25 8 55 38
33 52 90 84 39
82 50 60 41 35
33 7 28 66 21
98 32 41 81 19
46 34 10 50 47
20 68 2 93 25
5 85 69 53 39
91 83 59 37 8
51 39 81 48 19
55 86 73 54 20
5 7 18 1 36
44 75 43 76 23
6 38 71 57 77
95 75 0 32 5
64 41 51 91 30
99 79 8 16 55
88 97 53 47 85
58 23 14 93 59
67 47 49 2 24
75 92 31 52 29
30 7 10 40 55
20 19 35 72 84
75 6 67 76 13
18 32 27 17 71
60 4 48 53 84
8 23 33 91 68
24 42 56 50 45
52 55 68 62 89
9 64 14 58 50
46 8 94 12 24
72 47 42 76 61
97 40 25 7 31
13 83 14 29 58
70 33 28 71 9
16 90 45 30 99
84 0 41 79 51
60 55 35 31 57
93 21 42 67 20
88 73 40 9 1
92 58 15 83 57
30 86 36 97 89
38 22 72 37 24
37 38 78 93 50
44 65 52 54 79
73 27 6 35 91
8 26 63 7 12
25 17 60 4 14
0 30 70 99 23
2 75 51 10 87
12 91 4 69 8
81 62 26 72 33
31 17 46 73 96
53 44 78 46 19
40 85 77 98 50
71 30 68 0 73
31 43 83 92 6
52 45 11 37 1
91 67 8 35 36
23 52 51 83 70
92 32 27 72 16
63 54 75 38 97
45 96 11 13 79
2 62 8 53 3
63 94 81 61 25
10 91 9 87 84
85 59 80 54 0
43 77 21 89 75
12 34 29 68 14
77 81 67 15 9
17 85 26 30 86
33 10 31 23 69
59 42 24 88 89
14 80 84 22 23
85 93 83 91 6
57 27 51 95 46
67 1 24 76 86
55 19 94 8 61
87 42 82 81 98
43 8 51 92 60
17 14 96 36 34
2 19 70 15 78
93 35 74 53 3
53 34 22 41 59
58 18 30 71 37
60 8 74 1 5
96 52 87 17 85
57 31 24 72 32
58 51 98 28 29
81 76 49 24 60
3 33 22 57 86
1 67 46 20 56
5 16 2 8 6
67 51 43 89 94
4 96 50 9 8
22 87 77 38 35
39 37 17 59 32
5 25 26 83 81
15 12 6 27 76
80 70 87 36 55
69 35 91 98 18
89 59 92 5 29
84 10 86 63 39
3 94 38 93 28
88 57 42 97 14
89 36 35 85 9
5 29 51 31 69
46 10 25 0 15
87 46 49 60 22
30 64 93 20 66
95 86 71 21 11
0 58 53 18 97
62 63 3 1 96
56 86 71 30 36
19 27 16 94 53
46 81 25 44 55
75 7 97 76 96
93 79 22 78 50
30 14 68 16 59
23 60 77 37 4
22 43 53 34 81
7 54 38 39 96
25 86 64 46 44
2 72 69 90 58
50 77 16 0 14
75 1 92 66 29
71 59 54 67 4
3 53 49 9 46
21 22 25 42 7
4 95 82 91 27
29 33 30 64 61
74 80 26 83 70
31 88 93 52 96
51 45 43 70 87
48 77 27 53 19
41 83 17 99 49
94 59 95 58 55
75 86 44 91 82
64 88 91 68 19
57 60 80 46 98
20 4 38 32 69
8 9 22 70 39
85 28 97 2 71
65 42 46 75 48
26 66 97 16 74
51 67 94 89 4
61 9 54 22 2
82 8 83 5 90
18 51 61 57 11
41 79 30 78 69
75 14 81 40 88
93 76 25 64 47
24 34 94 46 89
74 8 3 64 59
67 49 26 32 83
85 0 5 71 90
16 27 81 98 56
79 23 76 20 43
37 6 24 16 69
41 82 51 4 35
79 94 99 42 12
30 81 60 3 36
8 22 11 32 48
68 9 1 47 21
61 55 5 19 73
29 0 48 4 31
63 50 93 15 72
39 98 57 70 65
34 55 82 26 10
62 85 68 69 36
5 46 54 50 17
86 95 72 49 29
76 91 43 37 97
41 76 5 33 59
81 51 99 86 34
0 39 64 27 83
40 69 37 91 45
55 49 54 9 61
92 34 81 10 80
64 85 69 28 66
89 93 22 45 7
8 35 90 16 87
4 78 44 13 67
30 21 24 26 40
59 17 4 47 73
10 31 88 12 29
56 98 69 2 7
13 58 91 55 36
25 28 69 4 19
45 62 32 16 98
20 88 6 97 18
91 71 10 80 31
1 66 89 12 21
85 34 16 30 71
47 15 46 24 61
79 69 23 38 96
0 14 80 97 86
48 92 22 26 98
96 94 98 27 56
64 83 46 30 5
3 43 70 67 21
62 0 92 1 65
36 26 35 61 76

View file

@ -1,19 +0,0 @@
7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
3 15 0 2 22
9 18 13 17 5
19 8 7 25 23
20 11 10 24 4
14 21 16 12 6
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7

View file

@ -1,500 +0,0 @@
964,133 -> 596,133
920,215 -> 920,976
123,528 -> 123,661
613,13 -> 407,13
373,876 -> 424,876
616,326 -> 120,326
486,335 -> 539,388
104,947 -> 54,947
319,241 -> 282,204
453,175 -> 453,438
485,187 -> 915,617
863,605 -> 603,605
870,524 -> 342,524
967,395 -> 634,62
405,181 -> 807,181
961,363 -> 419,905
89,586 -> 214,461
545,481 -> 731,295
407,678 -> 626,678
421,642 -> 91,312
11,22 -> 935,946
770,208 -> 76,902
668,858 -> 668,890
568,451 -> 574,451
233,56 -> 371,56
233,932 -> 44,932
404,81 -> 796,81
520,77 -> 403,194
296,736 -> 447,887
210,909 -> 16,909
692,483 -> 877,668
777,289 -> 744,289
22,760 -> 652,130
96,360 -> 626,360
101,267 -> 101,783
47,667 -> 660,667
805,682 -> 563,440
112,15 -> 463,366
406,808 -> 430,808
793,767 -> 107,81
560,534 -> 958,534
722,429 -> 722,459
646,889 -> 646,195
433,942 -> 449,958
716,503 -> 716,99
266,450 -> 266,780
316,81 -> 565,81
760,452 -> 687,452
976,983 -> 15,22
499,564 -> 499,909
839,913 -> 38,112
707,333 -> 438,333
47,644 -> 352,644
807,309 -> 807,706
434,686 -> 812,308
559,572 -> 63,76
493,352 -> 581,352
94,88 -> 928,88
898,738 -> 106,738
201,10 -> 564,10
976,914 -> 976,472
836,153 -> 585,153
178,43 -> 17,204
784,967 -> 738,967
370,359 -> 449,359
13,526 -> 637,526
399,158 -> 10,158
572,293 -> 289,293
627,674 -> 895,674
921,402 -> 984,402
907,667 -> 944,704
574,877 -> 882,569
977,977 -> 121,121
550,584 -> 862,584
396,556 -> 396,289
391,33 -> 532,174
12,988 -> 989,11
48,787 -> 48,637
476,638 -> 113,638
985,985 -> 13,13
838,784 -> 198,784
567,195 -> 677,305
174,251 -> 577,654
296,801 -> 53,558
983,899 -> 983,380
507,230 -> 507,929
264,516 -> 668,920
865,952 -> 865,768
522,290 -> 744,512
936,958 -> 936,115
527,871 -> 527,519
944,972 -> 21,49
880,380 -> 695,565
471,374 -> 446,349
503,597 -> 127,221
471,514 -> 30,73
890,232 -> 890,511
14,461 -> 14,853
167,676 -> 148,676
987,230 -> 754,230
797,725 -> 797,847
347,21 -> 84,21
839,274 -> 964,274
607,456 -> 894,456
335,949 -> 301,949
167,236 -> 820,889
87,558 -> 87,917
318,788 -> 622,484
699,583 -> 699,321
971,967 -> 35,31
420,44 -> 420,36
29,484 -> 458,484
768,157 -> 768,30
690,839 -> 317,839
870,578 -> 560,578
697,195 -> 70,822
689,45 -> 689,223
790,724 -> 341,724
694,291 -> 694,507
43,339 -> 43,987
590,733 -> 590,179
751,361 -> 945,361
99,820 -> 450,469
460,696 -> 942,696
783,940 -> 487,644
630,537 -> 48,537
643,856 -> 643,396
558,733 -> 257,432
16,972 -> 570,418
636,188 -> 636,610
868,138 -> 868,407
85,424 -> 85,919
710,932 -> 354,576
356,505 -> 783,505
606,876 -> 606,62
577,431 -> 749,431
108,262 -> 108,145
615,455 -> 264,104
205,754 -> 866,754
189,182 -> 855,848
10,43 -> 925,958
293,773 -> 293,534
746,313 -> 802,369
607,174 -> 211,570
860,840 -> 260,240
879,78 -> 595,78
11,143 -> 449,143
190,983 -> 267,983
912,92 -> 76,928
744,364 -> 744,258
436,417 -> 46,807
629,592 -> 517,592
113,893 -> 113,959
714,213 -> 786,285
868,165 -> 868,731
349,69 -> 491,69
278,430 -> 111,263
593,849 -> 593,203
156,860 -> 876,860
169,615 -> 169,984
983,93 -> 139,937
94,548 -> 18,548
623,72 -> 106,589
530,334 -> 473,334
384,746 -> 925,205
711,74 -> 28,757
850,728 -> 629,949
378,801 -> 228,651
347,968 -> 201,822
82,578 -> 82,555
149,405 -> 707,963
254,169 -> 793,169
443,454 -> 331,454
460,659 -> 608,807
838,807 -> 31,807
561,952 -> 290,952
755,626 -> 204,75
550,424 -> 550,81
772,115 -> 772,600
40,517 -> 40,232
277,841 -> 317,841
899,150 -> 128,921
735,332 -> 465,332
839,254 -> 915,330
959,616 -> 182,616
729,723 -> 487,965
64,838 -> 953,838
689,830 -> 689,982
191,83 -> 191,879
522,833 -> 942,833
877,785 -> 877,346
255,95 -> 556,95
782,491 -> 475,798
268,815 -> 812,271
119,181 -> 905,181
445,457 -> 742,160
973,30 -> 27,976
356,681 -> 356,289
882,279 -> 914,279
672,162 -> 672,153
180,729 -> 357,729
985,716 -> 985,313
191,618 -> 191,963
949,749 -> 636,749
289,902 -> 142,902
923,615 -> 123,615
710,929 -> 541,760
211,402 -> 211,433
515,178 -> 533,178
525,869 -> 525,578
201,569 -> 17,569
629,848 -> 882,848
152,512 -> 152,189
914,723 -> 764,723
218,231 -> 721,734
438,382 -> 846,382
582,475 -> 582,559
529,943 -> 529,683
330,312 -> 59,312
242,900 -> 862,900
271,220 -> 271,118
182,459 -> 182,673
513,265 -> 513,420
918,942 -> 378,942
277,765 -> 812,230
625,874 -> 219,874
737,533 -> 644,626
647,975 -> 152,480
638,284 -> 785,284
549,680 -> 549,877
886,278 -> 372,792
130,560 -> 516,174
186,741 -> 186,555
208,536 -> 469,536
674,906 -> 312,906
934,156 -> 934,322
568,412 -> 214,412
243,19 -> 243,814
861,230 -> 104,987
683,891 -> 683,533
545,740 -> 545,980
343,320 -> 796,320
821,220 -> 821,302
578,741 -> 578,141
633,405 -> 27,405
645,975 -> 225,555
25,527 -> 412,527
378,817 -> 378,913
352,741 -> 352,293
48,986 -> 925,109
506,231 -> 491,231
854,883 -> 48,77
261,221 -> 895,855
902,240 -> 902,943
145,338 -> 770,963
832,216 -> 832,869
480,385 -> 324,385
644,202 -> 433,202
202,176 -> 190,176
668,693 -> 668,349
95,230 -> 143,230
873,144 -> 67,950
232,509 -> 238,509
963,43 -> 133,873
527,631 -> 641,517
363,61 -> 849,61
72,326 -> 72,861
542,801 -> 233,492
247,48 -> 247,785
972,563 -> 480,71
362,870 -> 932,300
263,811 -> 263,584
556,157 -> 417,157
946,900 -> 175,129
790,542 -> 530,542
777,195 -> 154,818
71,764 -> 71,193
197,13 -> 453,13
664,714 -> 158,714
257,819 -> 257,730
796,927 -> 688,927
124,53 -> 954,883
30,16 -> 980,966
84,151 -> 597,151
840,776 -> 684,776
548,460 -> 718,630
291,635 -> 291,151
948,43 -> 58,933
373,483 -> 373,591
309,81 -> 259,81
692,808 -> 692,835
737,112 -> 215,634
808,595 -> 808,115
160,912 -> 973,99
494,191 -> 494,475
713,925 -> 43,255
736,580 -> 290,134
257,679 -> 725,211
464,81 -> 712,81
35,147 -> 35,420
372,159 -> 372,548
508,228 -> 682,402
120,491 -> 518,889
139,948 -> 272,815
398,523 -> 398,818
935,50 -> 40,945
415,959 -> 195,739
250,868 -> 250,930
77,60 -> 917,900
584,389 -> 493,298
362,163 -> 362,704
670,740 -> 670,703
689,297 -> 689,388
988,572 -> 988,340
238,248 -> 238,916
748,753 -> 29,34
184,565 -> 184,486
812,217 -> 812,34
60,140 -> 96,104
826,673 -> 230,673
221,221 -> 207,235
449,483 -> 270,304
805,810 -> 805,564
952,52 -> 139,865
428,967 -> 312,851
854,673 -> 661,673
985,209 -> 853,209
523,365 -> 54,365
492,171 -> 646,171
908,853 -> 69,14
38,698 -> 724,12
400,479 -> 167,479
948,313 -> 948,976
280,145 -> 37,145
206,858 -> 683,381
203,413 -> 545,413
726,173 -> 673,173
30,954 -> 150,954
319,592 -> 870,41
808,91 -> 180,719
845,612 -> 972,485
160,430 -> 160,780
19,339 -> 379,339
476,550 -> 476,291
341,785 -> 229,673
371,476 -> 371,663
509,836 -> 412,933
980,20 -> 31,969
822,526 -> 328,32
859,314 -> 425,314
963,961 -> 963,100
984,978 -> 31,25
659,251 -> 619,211
649,477 -> 846,477
32,259 -> 724,951
468,753 -> 468,91
690,301 -> 690,652
436,912 -> 845,503
32,123 -> 576,667
142,79 -> 741,678
610,228 -> 468,370
172,667 -> 172,736
961,700 -> 132,700
804,875 -> 804,213
71,970 -> 340,970
171,52 -> 149,30
754,604 -> 226,604
485,941 -> 27,941
126,383 -> 328,181
41,39 -> 987,985
128,62 -> 896,830
414,278 -> 923,787
712,15 -> 712,859
794,35 -> 200,629
516,147 -> 402,261
526,862 -> 905,862
721,407 -> 721,887
728,920 -> 339,920
117,417 -> 203,417
291,561 -> 17,835
171,359 -> 837,359
93,125 -> 136,125
220,226 -> 220,177
75,434 -> 75,407
235,664 -> 141,664
553,490 -> 566,477
487,651 -> 487,877
699,150 -> 933,384
73,556 -> 453,556
363,371 -> 363,984
905,106 -> 668,106
139,271 -> 139,125
466,379 -> 466,420
12,935 -> 625,935
89,892 -> 779,892
119,701 -> 270,852
354,886 -> 80,886
917,376 -> 440,376
23,182 -> 794,953
451,718 -> 121,718
62,251 -> 62,451
642,74 -> 642,698
425,200 -> 442,200
828,175 -> 828,405
751,743 -> 591,743
569,681 -> 574,681
329,187 -> 329,837
302,592 -> 302,230
359,135 -> 386,108
44,234 -> 44,731
836,305 -> 836,574
170,512 -> 367,512
576,699 -> 576,44
398,185 -> 821,185
733,78 -> 733,747
141,183 -> 141,787
65,360 -> 65,691
828,780 -> 828,98
776,744 -> 776,751
881,74 -> 481,474
438,642 -> 438,399
676,972 -> 175,972
60,318 -> 56,314
312,169 -> 341,169
736,472 -> 392,128
225,281 -> 164,281
407,799 -> 341,799
458,826 -> 983,301
12,988 -> 987,13
23,854 -> 662,215
82,863 -> 82,416
542,708 -> 542,44
659,51 -> 520,51
353,246 -> 353,90
985,976 -> 77,68
628,493 -> 628,510
51,48 -> 635,48
97,814 -> 828,83
14,44 -> 773,44
603,178 -> 597,178
11,220 -> 783,220
613,39 -> 613,719
68,303 -> 690,925
121,974 -> 896,199
343,54 -> 343,837
744,303 -> 744,942
678,370 -> 246,370
937,134 -> 84,987
357,333 -> 357,516
848,212 -> 429,631
909,244 -> 138,244
122,794 -> 786,130
274,611 -> 57,611
66,337 -> 385,18
847,356 -> 831,356
740,480 -> 740,359
194,443 -> 194,301
50,564 -> 572,42
86,587 -> 774,587
708,258 -> 49,917
420,530 -> 277,387
509,580 -> 509,71
237,196 -> 479,196
442,287 -> 850,287
830,393 -> 532,393
274,720 -> 501,493
610,565 -> 218,957
380,393 -> 380,800
237,847 -> 155,847
267,791 -> 52,791
275,772 -> 275,794
239,238 -> 419,418
200,785 -> 884,101
185,980 -> 185,284
47,46 -> 750,749
724,661 -> 724,337
630,349 -> 666,349
21,911 -> 21,569
661,562 -> 661,925
41,898 -> 41,104
988,67 -> 105,67
739,65 -> 868,65
187,973 -> 809,973
730,211 -> 255,686
254,445 -> 254,872
622,364 -> 235,751
402,980 -> 761,621
46,488 -> 960,488
799,708 -> 799,862
909,181 -> 909,189
450,266 -> 450,304
631,584 -> 631,455
164,830 -> 744,250
679,755 -> 690,744
949,26 -> 190,785
695,783 -> 218,783
269,151 -> 40,151
166,152 -> 22,152
281,819 -> 922,178
956,649 -> 956,593

View file

@ -1,10 +0,0 @@
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2

View file

@ -1 +0,0 @@
4,1,4,1,3,3,1,4,3,3,2,1,1,3,5,1,3,5,2,5,1,5,5,1,3,2,5,3,1,3,4,2,3,2,3,3,2,1,5,4,1,1,1,2,1,4,4,4,2,1,2,1,5,1,5,1,2,1,4,4,5,3,3,4,1,4,4,2,1,4,4,3,5,2,5,4,1,5,1,1,1,4,5,3,4,3,4,2,2,2,2,4,5,3,5,2,4,2,3,4,1,4,4,1,4,5,3,4,2,2,2,4,3,3,3,3,4,2,1,2,5,5,3,2,3,5,5,5,4,4,5,5,4,3,4,1,5,1,3,4,4,1,3,1,3,1,1,2,4,5,3,1,2,4,3,3,5,4,4,5,4,1,3,1,1,4,4,4,4,3,4,3,1,4,5,1,2,4,3,5,1,1,2,1,1,5,4,2,1,5,4,5,2,4,4,1,5,2,2,5,3,3,2,3,1,5,5,5,4,3,1,1,5,1,4,5,2,1,3,1,2,4,4,1,1,2,5,3,1,5,2,4,5,1,2,3,1,2,2,1,2,2,1,4,1,3,4,2,1,1,5,4,1,5,4,4,3,1,3,3,1,1,3,3,4,2,3,4,2,3,1,4,1,5,3,1,1,5,3,2,3,5,1,3,1,1,3,5,1,5,1,1,3,1,1,1,1,3,3,1

View file

@ -1 +0,0 @@
3,4,3,1,2

View file

@ -1 +0,0 @@
1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,848,1174,380,1195,277,353,425,292,225,1521,631,76,692,329,1530,445,1625,561,161,1760,88,129,89,866,133,353,372,1456,888,115,347,291,246,8,57,17,869,1230,1224,681,586,1553,183,508,760,1200,812,634,578,126,147,684,1037,822,217,521,136,438,456,26,258,9,395,1,1398,34,13,40,493,871,154,606,716,649,491,416,293,1,107,21,317,1156,194,179,693,1591,894,845,10,18,1314,11,730,408,365,0,516,192,96,1438,1521,787,503,454,84,478,19,26,109,287,657,216,148,155,816,384,288,1121,39,263,488,348,110,1219,321,1101,51,5,95,147,806,17,207,81,139,686,23,231,1154,36,410,1025,2,327,172,307,232,420,88,129,1507,1028,852,467,46,81,16,64,989,558,919,1301,612,278,306,1500,95,507,1034,272,526,68,41,870,37,78,434,459,268,375,1427,1039,1039,1077,1068,445,482,106,1823,218,76,33,131,934,112,72,404,118,848,99,10,816,527,125,279,200,10,248,243,416,242,639,401,66,110,364,243,550,1289,55,30,1246,72,46,251,1225,264,765,137,94,626,252,18,481,250,55,10,284,247,90,277,34,176,118,1178,554,761,3,938,140,890,109,811,760,179,1084,998,16,338,550,120,190,220,74,846,212,30,1098,455,1110,1662,71,1275,609,47,1239,1050,93,169,383,564,323,134,310,208,685,255,219,369,556,272,1604,562,600,493,178,337,33,949,775,588,288,498,40,1056,483,796,8,1588,463,122,120,26,215,786,525,129,259,346,21,35,247,1564,1094,1013,85,54,193,889,590,908,122,158,363,646,1301,533,73,767,405,89,358,936,737,78,982,163,867,373,1460,492,151,560,371,647,110,1779,802,374,147,1279,252,299,244,568,1014,685,912,942,767,3,76,207,296,40,181,312,192,684,988,490,31,410,928,47,1345,943,1013,705,675,543,446,84,869,1173,393,348,99,25,21,20,132,295,4,1273,800,182,140,593,964,55,167,15,219,269,35,848,324,474,189,4,305,62,7,1145,13,975,55,880,43,368,82,1083,6,969,844,1388,185,818,114,641,151,1006,220,599,143,170,36,631,891,531,871,13,77,1261,340,911,159,258,213,1245,222,200,946,875,301,9,381,69,1152,901,490,207,38,104,103,423,311,1532,536,314,73,314,29,844,141,1191,169,136,42,143,163,277,22,1655,1063,45,774,103,83,1253,121,1473,834,245,143,211,1252,1368,97,4,1188,1102,359,134,298,225,292,101,832,426,1204,652,468,110,529,34,384,663,534,80,1,68,117,419,1321,1729,38,1609,416,554,1047,130,145,267,1382,0,237,32,17,237,803,21,888,185,108,79,1,192,286,1167,86,71,464,122,375,0,186,927,525,1127,442,675,373,53,404,624,65,1157,107,687,98,165,891,1186,513,727,46,148,275,516,1412,17,684,113,246,137,1246,1357,143,307,307,656,1030,198,33,955,1765,314,79,5,385,248,402,75,12,76,325,175,1198,258,38,912,795,296,1931,111,72,1619,1563,8,327,867,293,515,1647,1266,128,44,9,431,300,72,501,1181,147,1330,1446,490,297,436,274,512,107,185,57,112,2,121,472,505,860,1650,411,23,328,119,64,0,1684,249,106,167,55,225,501,36,81,1225,270,186,10,477,783,39,319,1151,264,788,42,521,282,257,721,442,250,642,255,63,1015,241,939,86,997,569,330,189,129,547,1424,446,285,8,288,599,372,56,274,245,3,41,943,353,67,294,32,656,879,918,94,314,767,957,1554,854,610,590,403,139,377,129,930,341,678,577,375,809,490,39,153,3,48,133,54,225,1261,677,267,30,28,115,642,1733,12,297,428,155,812,635,16,634,223,823,261,662,652,71,138,103,220,544,211,313,1298,512,559,1243,1319,427,78,765,343,212,557,275,1,551,234,697,1815,1005,275,179,595,1,1658,204,345,794,36,102,912,657,194,8,2,526,350,399,390,1166,469,324,1497,371,759,621,800,895,235,314,579,863,278,54,239,1275,79,1728,934,1145,1008,748,196,1056,339,569,629,47,1437,416,758,1000,287,592,1057,921,170,273,144,133,0,320,216,216,118,229,4,681,410,1801,34,485,769,839,47,950,1694,1222,1199,411,598,1210,7,1644,245,44,428,49,653,7,1037,310,754,32,476,253,124,809,66,539,434,1142,136,4,344,306,628,1332,15,1523,149,191,498,1480,498,385,562,457,199,201,487,608,172,20,584,7,17,342,167,93,60,589,445,926

View file

@ -1 +0,0 @@
16,1,2,0,4,2,7,1,2,14

View file

@ -1,200 +0,0 @@
beacf afbd bcead cgefa ecdbga efb gbfdeac ecgfbd acbdfe fb | bf efb bgecdfa egcfa
cbdgef cdfageb cegbd fecba edgf dcfbe dbcafg df fcd dbegca | bgcdef dgbec bfeac fdeg
bgdcfa dgabf bfdec baefd abeg eda afcdge ea bfceadg dfegba | efbad fbdea dae fagbd
cfdabe fcgbe gcdeb ecdfgb bdc cdgf cd cfageb bgdae daebfcg | decbaf cdfg deabg cd
eacgdfb fdbeca agedc cbedf dcfgab bgef gdf fdgec fbcged gf | gf acegd fdeabgc gfd
egcd aebdcf gbeca eg edfcbga gbe cfbag bdeca gadbec bdgefa | caegfbd dgcebfa eg bgdfae
fcgab egafb gedbca gfc cf ceagdf cafbdeg gcafbd dbagc cfdb | dbecga dbgcefa cfg fcg
geacd bg cbfead efgabcd fbace ceabg efbadg gfbc gab geabcf | cfbg fabce bg fdgeacb
bfceg ca baefc caedfb acfedgb cfad edacbg eac debaf bdfage | geadbc bfgeacd efagcdb cefbg
fd dcfbge fcad dfg bgaefc fdcgab fgdceab afdbg cbagf gdaeb | aecdgfb dbcfag cdaf gfecba
dabce gceab fegcab fbdca adeg gcabdfe gedbac ed egdfbc deb | fdegcb acbdf ed gdae
bgcea cbfdage egad ecadb beg befdcg fcgba aecbdf ge abedcg | geb gbe deag eg
bfecag egbdfac abecg gcebf efdagc ca acbf cfbegd eac bgaed | bdcegfa gbfce dbgecaf ac
fcbed dbfegca cdafbe edfgc abfde ebc egcfab dbca fdgbea cb | cb fgedc cb cdfeb
fb fdeacb bfe bfdc ebcgda afdeb acbfge agedf ecbad fdagcbe | gfcdbae fb abcefgd bef
egbca cfe eadbfg baedgfc cf bcfd afbde acebf fecdag edafbc | cfe caedfgb fc eadfgc
gfabc fbcaeg bagd cgbfaed dfecb gfdcb fcedga dg dafbgc dgf | abgd bdgcf ebcdfga fcedbga
cdb abce ebgfdc bfagdec abdcef dbfea gfdca facbd dfaebg cb | cdb cb dbc cdafbeg
afdbe dcfegb gedca adcbe ecfgbad fcadge cb acgdeb cbe agcb | dcage bec cb cb
gafdec cbdg fdgbce dce dfegb fceab becagdf dc dfbce agdefb | dgebf dc bfgde cde
bagfc bdef cgeafd eagfbcd afceb fe cfabde agcdeb cef eabdc | fbdgaec ef ef cafbe
fbage cgfba bdcage edagbf fe agcfdeb gfe adfe dgabe egbfdc | fe gfe geabf dgecab
gdfec bgfc dbgafe gfdebc dbfeg fc fabdcge fcd gedac dcbfea | egadc cfd efbdg gcbf
dacgf dfabc ebgcad daegfcb aedfbc dbgf agd aegfc cbfdag gd | agd gbdf bdafcge bcfegad
gdbea ebacdf adebfgc dfb df fbdea gcfebd fceab bfcgea fdac | gfabecd efdgbc fcebgd fbd
fba gbdcf cbae ebfgca fbcegda ab gbedfa gbacf gface gecdfa | ba bacgfde edfgac ab
fgebda bfgae cfdgba agcbe dbaegcf gbfda ef bfe gcbdfe dfea | ebgfdc eagcb eafd bef
agfecb cabef dafgec adfeb fbc gacb cb afbegdc cfaeg cbdefg | aegbfc fcb cgfdbe fcaged
agf eadfc cegabfd eagdf efdgb cgfbde agbfed gfbcae ag abdg | abdegf gbad baecgf afdbeg
gfbdac bd gcaefd bdcegfa gadbce dgb badf gbfdc fgecb cgadf | bgd fcbgd gdb dbfa
cbgf efcgbd aefdcbg feabd dcf cdebf ebcgda cf egcbd fadceg | dcf cf gcedaf bgfc
bacgfe fbc cgfe bcdagf gebfa cafeb bdcafge afdegb caedb cf | befga cbf gcfe bcf
bgdf geacf acedgb gb aecbfd bdcfa abgcf bgc acgefdb cdgabf | cdbgea gcb fdbg adgefcb
bdacgef fadeb abcg gfcebd gbf afbge egacf dgceaf bg aefgcb | gfb fbg dbgecfa bacg
dcegf bg cdafegb cfdebg fagced bge ecfab dbgace cgbef bdgf | gb gbfd adgefc ebg
gbf fbcdega egdafc bg aefgd gbecfd agbe abcdf edgafb fbdag | cgaefbd dfaeg dafgb dfeagc
beaf aed aecdf aebcgd eafdcb cgfabd ea gfcde cbdfa ceagdfb | fabe bafecd fecgdab ae
bdcfe gbdae bcgafd daegfb aecg cdagbe gfbadec gbc gc edcgb | cdbge efbgcda dagcbe agebdf
ec fdcag aegcbf bagfcd cgfade adecg fdaebcg fecd degba egc | deagc ec ebagd cafgeb
dcgaeb egadc agcfde efac beagdfc fcdagb dgcef gbfde dfc cf | cdf cf febadgc ecgfd
afd df gdafecb bdcf fecba acged edcabf egdbfa egfabc acdfe | cgebaf dacge fdbc decga
ga beafc cgbea dceagf feabdc bfagec abgf cga fdeagbc cebdg | cagbe bgfa gbced gabf
edag cdafb ae efacd eacgbf cedgbf afe fbceadg cdgaef egcdf | eaf cdafb efa ae
eagdbfc cagdf badcge fgec cg cdg bdfca feadg fecdga dfbega | abcfd dgc cgd gdc
beadg ca cdeba gcda acfebg dfbce fcbadge dbafge gdabec cae | gcad eca agbced gdbace
agfcde gdceab dbeaf agfed dg acfegb gaedbfc adg aegcf fgcd | bdefa cgebfad gdfc gd
gafcdb bfgaec daecf bcfgdea bged be dcgfb cfebd fbe dfebgc | fcabge dbfagec gebdfca gbfcd
dcaef agfbec gea ge bged cbdfag fgbade gbdefca abfgd faged | bfdcega aeg bdgaf bedg
dcbfa ag fcaegb fcdaegb gebdf adeg bdfga dgfeba ebcdgf gaf | cbgedfa ag egda ga
bcgdaef fcabde dbfage cfdgb daegf bfe dgefb gfadce egab eb | bfe gfeabd gdbef dagfbec
be egb fgcbde agdbcf gcdfb edbf bagecf ecadg bdefgca bdegc | efcdgab edgbcf efabcg dgecb
bcegfd ceafd gbefca eba dacebfg gebfd baegdf dabg dbfae ab | bae abcgef gbdcefa dbga
dceagfb edac ecfba cbgadf dfbge bcdefa fdc cd fcaegb edcbf | bdface cgfabde cdf cdafeb
cgaedbf acd afbdge afdcg bdcaeg gadfb ac gcbdfa abcf cdgef | gdfac cgdef cgfad cfbedga
gaefdcb debga cd aebcd gceafb afdceb cfabe dfcb dca agdcef | dbcafeg dfecag dbfc efgdacb
abdeg eaf cedfba aefdg gcadfe af gdfaecb gcfa gdfec cbgdef | fea cebfda dfceag fadcebg
bcgdfe fbdce fcdbea bcead adc ca bdgcaf edcgbaf baged feac | ecbad bfdec acd ac
bd aecfgb bfad gdb dgbace fbaegdc egbaf ecdgf egbdf fgadeb | fcageb dgb dgfeb bfad
bfcea dfbcea badge bfegdca gac cafdgb gc aecbgf caebg gefc | fegc bcaeg beafc feadbc
cagef fadgebc fd daf dcfbga ebdgfa cbeadg afdeg abegd ebdf | gbafedc daefg fd gbadec
dfaebc bcgaf bcaeg abecgf eagf dgecb cae ae dcgbafe gbadcf | ea gdecb bfacge gbace
dfbec gcbade fadb df badefcg dbeac cfgeb ebafcd fecdga edf | febcg cfadeg ebcgda dbfa
cadgfe bdfea dgbfeca dab dgbaec afdegb fdgb gaefd db cbfae | dgbf edabf bd dfgb
decbga ebfcgd gcebf cabfe aec cbfad ea eafg adbgcef cebfag | efga ea cgafbed acfdb
dcgefb gafc bagfce ca fcaeb aec dfbae ebgcf bcfdega deacgb | begcdfa ace fdegbac ac
gafc dgafecb cdgeba dbgafc fa bacdg fceabd fbgde afb fadgb | cafgdbe fbedagc adefbc gacefdb
dgfe dfa fd agcfbd bedac gfaec bdfcgae ebgcaf edfac acegfd | adf degf fad fedacgb
efgacdb gedfc eadbfg efd dcagf cfdage gdbacf gcbed fe fcae | eafdgb fdcge cafe dfe
aebg gbfdac dcebfga bdcef ebcfag abcfg acfeb dfcaeg ea eca | bega ace bacfg bgadcf
ceag caefgb agb fbgdc ag cafbg becfa cfeabd deafgb eafcgbd | cgadbef gba ag bag
bdge agbec dgcfae agbedcf gdc gbecad dabgc gd fbadc abefcg | gfcbaed dbge dg acfbd
dcef efb dbcfgae gbecfa fe ebcdag cafedb cadbe afdbe badfg | edcf ef fe fe
cdagfeb fgabc cafd fcb bdagc dfcgeb gbfacd cf baefg bdegac | cf acgbd fdac cdbfega
cefbdg debgca abfeg cebgf fdbgac adcgefb fcde cbe ce cdbgf | bgfae bec cfdebga cfegbd
fcbag gcfbed adgbefc afbdeg adbgf dbea ad cefagd daf debfg | da afd baegdfc afd
ba gbcda degcb bad adbegc fgcad eacb adgefb gdfaecb gcbedf | dgbaec gdbcfe dba ba
cdabf cbdgae facgb fadg acg gfbce ag cgdafb edcfab dbcegfa | dafg bdafec cbfeg facbg
edbaf cfebad aec cdaf ca gfabce cbeda afgebd fbdacge bcgde | ac afgbce dacf fcda
egdba bafeg bd gdfeba bcedfa agcde bad fgdb fceabg gabdefc | fbgae efgacb cadfeb bgdf
fdcgae dcefb cdb fecgabd afecb dbcfeg bgceda bd gfdb cdegf | dgabec cbdgae bcd aedcbgf
beg eg bfcea cdfgeb baefg abgdf fgeabd gcfdba agde dgbaefc | cdabgf dbefgc bdgfa facgebd
dbgef bfecgad egfcd agfbce agbde bf gcebdf dagfce cbdf feb | fbe ebfcdg bcfd fgcdabe
abgdec fgd fcgeb gedabf gfbdc dgaecbf afdc dgcafb fd bgcad | fgd adcf bgfcd fdegba
cafdb acdbge acedb dfbcg af ceadfbg adf adfgec faeb dcfeab | gdabfec bdgfc dcfba feab
dbcgae bcdfeg bfceadg bafgcd dacgb dfac cfgba bfc aefgb cf | dcegbf fc becagd fc
geacb gebfda gbcdafe efgc ge ecabd bcefag gfbcda age gafbc | adbfecg acbge cabedfg gea
gabce feagdb dgb fceadb deagb edbfa gd cbfgde agdbfec afdg | gbd begdcf aegbd bgd
afecbg fgeda dfeabgc cdafe adgb dg dbcegf fabged faebg egd | ged abfgced gd afcde
ec badfec cfe befgd gdacfe bace fgedbac gbcadf fdcba cfedb | ecf ec ce efcdb
dacfgb fd gfdbae ecbdgfa ecbdag cbfeg faed gdf aegbd egdfb | eacdbg gbfdea begfd becfdag
faegbd fgdace acbfeg dfgecba ed dabge fdbe dae badcg eagbf | dfeb dfgabe adcgb de
dbe gbcef acdebf defa geabdc de dfcbag dbgaecf cabfd becdf | eadf adcegb efcbg cfabdg
gcaed adgbce abfeg cb egcba cdba cgadef cgbefda fdbegc ebc | gbeaf cb bcad fadcge
cef fbacd gafedc ec gaecbdf bfedg gdcfeb bfdce cegb bfadeg | ec fbceagd fce fec
gfdae adgb cabfde fgdceb dea gafec bdgafec agdebf ad degfb | bcedgf bedacgf cegfa bcfgead
ec cge dagef eacgbf cdafegb cfgadb gbedca ecagd cdeb agcbd | cfagbd dcega gaecdb bgfaecd
ebgac cegbad dfcegb abegdf gbdec bae dcae efabgdc ea cgfba | ea eba deca bea
dcgfba adgbef feac afedgc dcegf egabfdc fc fdaeg bdceg dcf | beagcfd gdbcafe efac cf
cadfg gb cedagf gbd abgcfd fdcebga acgb febgda fdbec bdgcf | cagb cfagd gbd fegcbad
fgdca afcdeg bcdeagf gc fcaed defabc aedcbg bgfad cdg cfge | gc gdeacf agdbce fbacdge
fea adgeb bgfe fe dcfeag bafegd badcf aedbfgc adefb bcdeag | eafbd abfged begf egfb
gace dagcf fedac fbceagd defab cfe gdcfeb cdfgae ec gbfadc | ecf cagefbd befgdac acge
afc gaedf dfecga bafcdge cf bgdac dafcg eacbfd gbdafe gcef | adbcg fca agdbfce acf
cdfebg dcbe fgbdac bfegd be beagfc gfdea gacfbed fbe cgfbd | gedabfc eb eb aegcbfd
afg dfgec gcfeab ebcfagd fa adfe bagcd gdcfa gfbedc gecdfa | fa eacgdbf fa defa
bfdag gbecd cefg efcbdga fbc cf gbcfd badfec bedfcg egcbda | gadefcb bfc bacfde bgedc
cafde dce dcbfa dgcefb cgea dgafceb fgcdae dagfe gfebad ec | fcdae dbgfec gfdea dfcgeba
gcebad cfgdb cfgeab cdb cd egcdbf gbdaf fcde fgdbcae gfbec | cbd geacdb adbcge dc
afegb adbfg becafdg dg bgd gaebfc fdge cdfba gbcead abfdeg | gd gbd dabfc defg
fabeg gd dfebcg dgfae bfgeca fecad adgb efabgd ecfdbag deg | gd cfead dcfea cbefgda
bfceag dafgb fdce fc cfg gcdebf becgfda dgbec aedcgb cbgdf | fc adfgb dgfab cgbedf
bfeg decaf cegfa ecfgab gcf dbfeacg caedgb aegbc dbcafg fg | bgdcfea fg bfdaegc afgcdbe
eac ae cbdfe cbaedf abcfedg bade aefcbg bdcgef cedaf gdfca | efcdbg ae bdfce cdefa
gdebfca bfgca fda bcafd ad gcda cfgdab fadbeg edfcb gcbfae | cgafdb fad fda acdg
gfbdcae afed gedac facegd bgeac de fgbecd cagfd ged bdgfca | bacge egbacfd adgfc deg
gdafbe dbacgf cbefag cbfdg bfdag fcedg cdbgfae adbc cgb cb | bc gadefb bc acbd
fa egcad acfed ebdcfa dgcbef daf bdecf fgadbc fbae gabdecf | cedfa egdcbfa fa afd
cfd fd gbafc dcagf daecg dbfa cbfage egfdbc bfdgcae cbdfga | ecbdgf df dabf fd
eafbdgc baegd fe bagfed aebfg cabedg efg facgb bdgfec fade | defa ef ef fdae
cfdeagb bdeacf eac gcdbfa egab egacfb cdgfe ea ecfga cgfba | aecfg dfbacge cae ea
aefcdgb bacfg cdg afecd gedbcf afgcbe abgd adbfcg fgdac dg | bagfc gbfcdea gfdac bgda
becf baefgd dcafg cb cdbage dcgfb bcg gdbef edbfcg egbcafd | fbce cbg gcbfde gefabd
gb bgedca fedga cfdeag fegb dcbfa gab afgdb acbgefd bdgaef | bga gb gb ebfg
dca cedbf dcfebga ca egbcad cdaefb fedag efdac acbf cfgdbe | fbcade cebfdag adc acd
bgdeafc gaefd fbeagc cdfa fgc degcf dgbafe gcedaf dgcbe fc | gfc egafd cf bcdeg
dfaeb fae ebacfd egadb fe gadbfc febc gbfeacd fagcde dcabf | beadg adefb fcbe dagfcb
fgaed gd dacgfb egcd gdf acfed adbfceg edbfca dcafeg baefg | decaf bacdgf fgd ebgaf
bcfeadg dfagce fdcgba dfcab gabec gcf gf abgfc bacedf bdgf | bcgfeda bdgf fg gf
ceab gafec cef fcdgba cbfeadg bcagf ce ceagbf agdfe degcbf | efgca efgca cef ebac
abgef abf gbeac gabfcde degcfb efdbga aefd bgdcfa af befdg | afbcdg fa bdfgec dfbgae
gdafce cfb agfbc ebaf fcebdg aegfc cbgfea egbfdca dbgac bf | fb abfe aebf dgecbf
ceadf fecag dcgaeb dgbfcea edc bcafd cdabef ed befd gfcdab | badecf ed egfca edfb
gecdbaf dbag bfade gabfed cedfba gfade cfaebg fgdce ag fga | bafgdce gacbef ga dagb
defbcg gbfce beag gacdf cfbaeg dbcfea ea cefga ceafbgd ace | aefcg ae aegcbf ebga
egbdac fgadb cefdbg aceg gc cedba dcbag ecafdb fgeacdb gcd | cg ecbad egdafbc cgd
bdac ac fcdaebg afbdeg dbagf fbcge acf cadgbf afedgc bgfca | cdab fgceb ac fgbac
ba eacfg cab aefcb cdeabgf ecgdbf dcbfe dbfeac acdbeg dfab | bacef adbf bfda cab
gbfca ceafbd geda gcdfae efbcdg fgced da degbcfa adf cdagf | aegd ad da geabcfd
fgdacb dg efagc gcd cgefab edcgfa cbedf gfdce eabgcfd daeg | dgc gdc cfedga cdg
bcadeg fbgaec ecdag gbafced ba bca edab bgadc fdcgae gdbcf | bcadfge edgacf bac dabgce
aedfb dbfcae caefbdg aefcdg gafcb dfcba bgfeda dc fdc edcb | bdfae cd eafdb cdf
cga afdebc gc adcgefb adbgf acgfde gcabd gbedac ecgb acdeb | gbce ecadb daebcg gc
cdf dcafg df cgade cebgad dcgfea fdacbeg dgbfec afbgc fade | bgeafdc feda edaf fbgac
fagbc dbag feadgc gfa dcebfg gbdcf ag gecafbd ceafb bagcfd | fadegcb gacfed defcbg dgcbaef
cadbfeg dbgace fcagd bedfca cfegd afgb bgdfca ga adg fdabc | dfcag gcedf cefabd fbadc
fgeabd egbca dfage fdagec fb dacbfe badgecf baf gfaeb bdgf | bfdg fdbg ebagc beafg
gbdaefc fa dgafb feda fegbdc dfbeg gaf cegfba gacdb badgfe | bagdf fa afg ebgcdf
bedc fbagd bdage cgdeab eba gcabef afcdge edgca be cfbgeda | geadb be dceb ebdgca
fe fceb acegdfb efg fdgce fagbed bedgc fedbgc dagbce agdfc | febcdg egdcfab dcebgf gef
fagdc ebacgd ecgdb decafgb cefbda geba bagcd bad fbdgce ba | ecdbg abeg dfbeac fgdaceb
decgaf cgab aedbc cbaegd ca bdegc fcegdab efabd cda cdbfeg | aedbf ebdaf cda dca
gafbde ecfda afdegc ecdgb ba cbfa cfadeb edabc bea ecbdfga | eab ecdgb bea ab
gbecaf dbgf facbgde cegabd gebdfa fdaec dfage egf adebg fg | gfe egf becafg abfgedc
gfceabd adgcb bcdf afb gafbd becafg bf dagef agbdec fgcdba | cbagfd fdbga dcbega dfgecba
ba afegdb cdab cfgeb facebdg fcabg cdagf fdgcab gab decgfa | cfbdega dacb agdcfb gabfdc
adebgc bdefcga afegdb bcedf bfg fedbg fg efga dbgea facdbg | gf gf debafg fgb
cegfda gfa ecgf gf ebgdac afcbd ecagd afebgd fcdag begcafd | fcabd dfacgbe fcabedg ceadfg
febgcd fcbda cdgab fcgbad bf fdcea dfb egbadfc bgcdae fbag | cedfa fb fb gabf
ebfag fcbade ad adec bgecdfa afd gebfcd bfdec fbade bgcdfa | adf ecad ebadf bdcgafe
cafbgde bdace cefadg gefcbd ag egdcf gae bcfaeg gcdae adfg | egabcdf cedga cedag adgf
agcef egcab fc dfeagb fce gbaefdc ebcadf aefdg adefcg gcfd | dfgc aebcg egdcfba agbec
db fdbcge dgb gfaced bfacgde dfba egdfba cabge edgfa gebda | eafbgdc db db gdafcbe
cad cdfgea caegbf agbd cbdef gbcdaf gadecbf ad bcafg dacbf | fgecba cgbfeda da dbecafg
bdegaf gfde gf bcadeg dafgcb afg bgaef eagdb cfbeadg fbeac | ebgad gfed debfcag fdge
bgac edgacbf dfbea cgebda gea cfedga agedb ag dcgeb fcedgb | dbage bdgacef cfagdeb deabg
caebd edf edgfbc fe abfegdc cdfea gfdac eacfgd gfacbd gaef | fega fgae gafe cabde
bfadegc dafec dbgaec abdcef fdaegc dag cagf ga aedgf fbedg | bcafedg ag ga adg
dcgfa dgcafeb cfb bf cegafb begcda fdgbce dcebg bfed fcgdb | dgcebaf bedf fb bcged
cbegd edfa fdc gadcfb gbcefad bgacef acfbe ebacfd bfecd fd | fdc dbgafc cefbd cdf
fgd dgbfe gf gcef bdecf dgcfba acfbde gdefbc badge facbdeg | dcfaebg fg fgd fbgced
abdeg adebcg ebafdc bgcadfe gedc ega bgdaf cabed efacbg ge | ge gae age afebgdc
debfa dfbga fagdc fbg cadgfe acgfbd efgcab cgfeabd dbcg bg | fgdba bg gfacbed ecabgf
bc egdba ebdacg cgba dabfec bec defcg cdbefga gbfead becdg | bcefagd bec cebfgda cb
deagbfc agebdc fbedca fa edgafc bfac adcbe gfedb afd efdab | fad dbaef cbfdae af
afgdeb beagd daecbfg gbfedc ecd becad egac agecbd ce fbcda | fbadge eacdbg cde ce
fgabec gefb cdagefb fbacgd dgecba adecf eg cefga egc gcfba | dafgbc gec bfeg gefb
gbcf fceag gb bag bdafge gbeac fdegca cfegdab egfacb daceb | bg cagfeb aedbc cbaeg
gbac fedagb gaf adcbf ceabfd abecgfd bfcdga ga edgcf gfcda | badcf fcedg adbcfg agebfd
gdbfc fbaecd gaef ef efb agebc gabdefc ebcgad facegb bgcfe | cfgdbae faeg efga cdegab
fbacge decgba bcafd fedgab fageb ed efgd ebafd gedbcfa bed | de ed bdafe de
bcgdf badgec de fecgd cfeag dfbe dcgafeb gdacfb ced fdbgce | de de edc gafbdc
gebfa fd dgacb dfgba bfdeca daf becfga edfg afgebcd gfadbe | bdcfea bafecgd acdegfb fgbdea
fgdcb efdcg gcfabd gcdbafe gbf acfb aegcdb edfabg fb gbcda | bgafde gfcbd fb cedbfga
de fadcg befcdg fbeac adcef efd ebgfca cbefadg edba dbaecf | eagbfcd beagfc bcefgd beda
ebcfad fbecgd edgba df adgfcbe dfe bcfaeg bedgf bcefg dgfc | df bcagef df aecfgb
acgdb gdc gcebdaf abcge ecgdfa egbd cbaegf gdacbe fcdba dg | egcfda aebgfc aegcbdf cgd
gc cge cgdb deafbgc dageb cbega agbcde cedgfa gbefad cefab | dabfeg gc eabcgdf gabde
abegc agecf adfcbge bcdaeg fbadec bca cb bcgd egdba gbafde | gbdc begad bfecda cb
daecgb abegd bagedf begfcd fe feag abefd bfe fbgceda fbdac | fbdac gcebdaf egfa fe
eafcbdg abcdg acegf dfcga fgaebc defcbg aefd dfc dfgace df | df adef fd dfea
fdecabg ba agebdc adb gcdea befdg gabc egdba badefc ecagdf | bda gcabde gdaec fgdcae
cdfg dbecf dg caebdf gbd beafg cbegfd ebcgdfa gdfeb agdecb | cedfb gd cbgeafd debgacf
bca cadbfeg gabfcd bcgafe caebg adgfec bc bcfe gefac beadg | cgefab cgfae befc acbegf
cabgdef cgabde efcab degcf gcfdeb da fgda cda feagcd aedcf | adc da cgaedf cgdfbe
dagfbe gaefb efcgadb fbcae fg gbf edbag cbgdae gadfbc gfde | bgf gf acgdfb cfgdba
cbedag edgca bfcagde gfbae gfdea df adfc dafceg fedbcg gdf | adecg gbafe acdbfeg df
ebfc ef gecfad gfdcb egbad gfabcd ecgdafb feg bfgdce dbefg | aegdb bfged ef bafdgc
ce cefd cafdg cdgefa geacbd eca gcbfad gebfa afecg bfedcga | ecgfa cea defc ce
ceb edbgafc fabec cb dfagec fgbea daefcb efdca cebgda bfdc | bec eadfgbc degabc adgfce
cgf aefbdgc gf bagf gedacf ecgfb cdfeb acgbe ebcfga cedbga | gf fbgcade cbegfda acbdfeg

View file

@ -1,10 +0,0 @@
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce

View file

@ -1,100 +0,0 @@
8969799987646798965432975435334567987976999867976794468999979759865767896545699865678952123899325456
7658678998434597654321984320123458976765789998965432367998968998754556789434987654489543535698912349
6243457899325679997620195431934569765654667999993101246796856997643245679759865443356954656987894498
4102345678912998789531297659895978954213456899874512659965239876432134578998754321267899877976789987
3212466989109887678942989797659799542102345798765423867894103987543026799989866532345678999765469896
4323487893299795489899978987947689654243496789876864988943212498654135999967987765466789987654398754
5694698999987654398788967895434589879359989999987879999994467598795276789756798876567895699873219865
6788799998998975976567456899598678985498879898798989865879978939876987993145899987879954598765102987
7899899897989989875432345678998789897987968799659197654756899857989899921034999898989433459854213698
8913998766779999964321234569999897789876754678943296543434998769997797892129898789995321298765434569
9101987655767989875732345679987946689654343469764987542127899898765656789298797678976510159977675678
3212396543256878986893478999876434596543212378965698321016789999854245991987664599987621245698789789
5433495432145767897954567896985423689954301299986986432125899998762127892976553469998753457789899892
6567989543023456798966878994597434567896212989897998764234678987654679999897432348999864567997999953
7699978932124569899987989789986545678997329878798969976656789998785793599789645667898965989456789867
8988767993237678998998995678998698789865498765689654399787898999887975987689956788977899992398999879
9976458789398899687899234567999899899978987654569543219899956789998989896579899899866458943989109989
9854345679479976556954346788998999999989876543468965323987548999969498765466788956954367969878998797
8765456796567895434699459899996878998694987742556896439876439999854329654354567899875167898657897656
9896577897679966724978998943985456896513498651345689546989998898765439843212456789984356789346789843
5998678998789653219866987899876368954323489710556898768998787789876898756533568899995679891245898932
4299789349898742109654346798765458976535679921237999879867546678987989987654679978976789910234567891
5989894234969876298743234569878567899796798545346899998653434569399876599785789567987898929345688932
9878943123459865459652127999989678978998987655456789129742129679210997679897995456798987898957899543
4965431012567986798764335679598789469899998767767891019843298999429698789998932348899876767899999654
3986949143479997899865466789409892346789979879878992123969976578998539997899321467999765646978998765
2399898954567898999876567893219921235798766990999789235698895457997623456921932346998654334567899978
1299767895789999999987678999398633896899954321235695476987789598998735797899894459876543212456899899
2988956799899998989998989798976545789999896532346789569986679679439987898986789667987654201268999798
9876545788987887679899897657987656798998789987656799698785458994321299999575678978998764312349987677
8787434867976544556797623546698767987887678999767978988654356789490123985434567899799876543456997536
9643323456895433545679510134599879876765567899878969876543234899989349876423468976567998954567895215
7432102568954321234595431235678998765634345678989456998754345987879956994312469965456899996789954324
6543212349975410123489545676789769874321234789790365679976576896567898984203457896597946987898766534
7695323457897521236679686787896656965454345689621234567987687932498959876412679989989532498939878745
8986445569998934345689899998955549877965678796542347678999798940989942986567897678978901359012999987
9997556978969765456897998899643435988876789898753456789999899759878891987879976564568992459223989999
9998967889349876577896767789532123999998898999897598999988959898767790298989985323456789998939878998
9879878993212987698965656679921039876439967899999979899876545987656689349896546012367899876899767987
8867989854623999999873245567892134965323456789998765789987632496545459998765432123456998765698959876
7656799769539897895482133456954379854212597993987653999898521569632367899979643236567898754987939984
9545678998998765989321012567895459763102379932199654569765437698743458932398654387989987543656898765
8936567897899874578932123456976598765213467891034987698996548899654567891019767898999876521246789897
7623468976799765799543438967898679984324579932123498997989679998765678942423989999978988430134899998
5434578985679878997654567898939789995445698965349569876678989899876789759994596598769877321475678999
6559689643456989298775678999029895987576987896467978965457899782989899998789789429898765432386799989
7798789432345690129976789998939974599999896889878999784346998651296989876598993219989876743457898878
8989895431258789245987899987898953459878784978989989653245696542345679999457894398879987857567947566
9877987646779898659998999876567994979967643467899878964126789655456989998379965976569898967679434345
9965499867895989798999598765476789398756532456798967893235899766967998987567899879456799298989321234
9876789978954878987995459654345891296543101236987656789345678979899896798679998768345692129695433545
1988899989763567896889698743236892989754752345698545678956799998789765698789876753238789234569546656
3499949999874878945779987632123999768969643467899234589999899876578954329999875432124679945698756767
9989237999996989234567976431019888943498955989998545678989906987689965410199764321012989896799999879
8978956789997892146678986542239767832487996792987656789679215698896894321989875754123456797899989992
7867897899989921012349597953398756721276789891098767896598924599965789939878996543254597898998978991
5658998979876432124692398965986543210345996999239878965487895987654597898965987654765678949987959889
4234789767987543235789459896798765321267894878945989874356789998783456987954599875676989657995349778
2123679854987674347896569789999876543458943467956999995245894987632969876843456996787899969986234567
3012568966998989498987998677899987754567892458969899874348943986549898765652345987998999898942123679
6123456799879996579999899576789999869678943467899789965457921098798789854321234598949998677991014589
5434767959767987898998765435699987998789765598923679876767892349987698765210349899659986566789323899
8545679943854598986987654324589996689896986679013459989888999959876579894321235789898975345678946789
7676899892123999875698763215679965456965498793223598794999998799975467965452347999987654234599659899
8989986799019887654679974323467896568942349954334987653234987678894359879643458969876542123689898988
9798865678998765712578985454598987979321257895455798852109895467789234998754569653999892012567987877
7697654367897654323456798579689898989910969999579999743219654347689945679967679999549764123456896556
3598765456998768974567987689795679099899898997678987654498653201567896989898798878934965236587974449
2359987767999899765978998999964589298787656789989398765789765443489989899789897767949874347678953237
1491299879999999987889459329899999987654745894590249876899899865679876784699976456899985678789654126
0989901989789989998991399439777899898543435789931399987934999876898765633987895367899876799896543235
9877899995678978989532578998656998797632124567893989998923498989999874012346789246987989898987655345
8766798989789469878943789879546899654321012978999878999212997796799982178968992134976591997899796656
9954547878992399967899899865434678998732129899998769899929876565689875357899843239899432395698989768
7653235669991987856798999876215789987654239789987657789899765373499876567898765498798954986987878979
8762124456789996543467894989104589998768998678986545678789876212345987688959876569657995999876567999
9989012347899865432356993298913478999879876548995434345678968101356799799545987898745789865985456789
6598924456895996421245689987897567892989998756789621257989543212456893987634598999658999654986687899
7987899568934987840234567896789978921399899987898530968999964566567892396723679998767898953199789989
9876798979924987656495888934567899210198789898987649899999898788689910975435678979878997899019899975
7675356899899898767686789123679954391297698769999789799898789898799921296586789567989876798923989764
6543245698798789879899899019789995989987569543935998689765679909899892397697994345698765867894578953
8432136987657678999910998998998789778943468999899019789954234912998789998998943234989544556895678942
7543239876543457989422997867997643567892979679678929899892123893989689789989432109875432347989989431
8664345975442345678999876656789432456789895434569439998789234679876597678976543499964321235679894320
8798459864321256899987655346896563567898789212497598687679345798765326567897654989984310199998789491
9897568995438767898998643238987678689987679101789987543568996987654215458998775979996532987877578989
9987679986549878987976543129998989799986568932679876542356789099873101299439989868987543976966457577
8998790197678989756797643256899999899865457894569867421867992198764323489321098756597654965452323456
7679891998789691234598765345678923989954366789697654320378943579885654678999987643469869876321012345
4567939879896542456999975457789019878942134898789865621247894567986965699678996532398979876432123456
3459329765998653567895986568993139765899012979899876732456789678987876896599989421297989998673234568
5678909984329764678993497679954397654678923567943987654567997999799987897987678932986794569984545778
8799998965679889889989598989795986543567994578992399876799236789654398999896568943975523679995656789
9989767899789997993978999895689997562456789989989976987890145899876789998768456999854302368987789894
9879356789899876432767898764789775431634578899879765698991236799987896999654397789763213459998993912
8656244678998765321545987653459654320123456789767954019789445678998945898743235678954424668999542103
7542133569899878510126976432398797431835668892456892124689556889329236789655656789765634569987543765
6531012456789996431239954321239986545646799986587893776789678993210127898767787899879745678998955897
6542123568899987544398765510123497656656789987678954567898799654431338999978898910989656789209876789

View file

@ -1,5 +0,0 @@
2199943210
3987894921
9856789892
8767896789
9899965678

View file

@ -1,110 +0,0 @@
<{[[({([{<[[([()<>]<<><>>)<[[]()]{<>()}>][<(()[])<()<>>>]]<(<(<><>)(())>)[<([]()){<><>}>{{()<>}<{}>}]>>[({
<<({<{{{[(<{([{}{}]{{}[]}){({}())}}<<[[][]](()<>)>[{<><>}<{}<>>]>>(<[[()]([]{})]((()<>)[()()
({<<({[<[[<[([()])]<<<{}<>><()[]>>[[()<>]<[]()>]>>([((()[])[()])]{[[()()]<<><>>][{<>[]}(()<>)]})
(([[<<[{(({{{(()<>)[()()]}[({}<>)[[][]]]}([{{}<>}<[]()}]{[[][]][()<>]})})(([({[]{}}{[][]})
({{<[[<<{{[{[<{}{}>{[]{}}]<([]{}){()[]}>}]<{([<><>]([]<>)){({}())({}<>)}}[[<{}<>>([]{})][[()[]]]]>}}>>]]
[(<<<{([[[<{(<()<>>{<><>})(<[]<>>([][]))}[<[{}[]]>{<[]>(<><>)}]>([{{[]()}{[]()}}([<>[]][{}<>
<[{[{{([<(<{{[{}<>]({}{})}{{<>[]}(()())}}(<<<>{}>(<><>)>(<<>{}>[[]<>]))>)>[{[<[[()<>]{{}<>
{(<<[([<{<<<({()()}(<><>)}{((){})([]())}>>[<{<[]<>>{[]{}}}([()()])>]>}>]{{([{<{{[]<>}(<>)}<({}(
((<[{(({([<{(<[][]>)[<<>{}><()<>>]}<{<{}{}>}[{()[]}<{}[]>]>>])})<[{[{([{[]()}((){})][<<>()><()()>])>]}][[({{[
[[{([[<<[({[<<[]{}>{[][]}>(<()<>>[{}()])][([{}[]}[<><>]){[{}()]}]}[<<<{}<>>{()<>}>(<{}()>([]()))>{[[<><>][
{{{<[([[{<[<{([]{}>{<>()}}{<(){}><()()>}>[{[[][]](<>())}[{[]<>}[<>[]]]]]{<{{{}[]}{<><>}}[[()()](<
(([{(({[[[[{(<<>[]>((){})){<()<>><[]{}>}}{[{{}()}(()[])]((()){()<>})}]]]<[<<{(()[])<{}[]>}{
{<<([(<([{{(<(()<>)[[][]]>{[[]{}]{(){}}})[{<(){}>[[]<>]}]}}])[[[([[{()()}{<>[]}]{[()]{[][]}}]<[((
[{<<{<([(<[<{<{}[]>{{}[]}}(([]()))>{([(){}]<()[]>)(<[][]>{[]<>})}]>[{<<{<>()}[{}[]]>{(<><>)}>{[<[]<>>{()[]}]<
<{{<{[[{{([({<()>{(){}}}((<>[])(<><>)))[(<[]<>>[()[]])<<()()>{<>{}}>]])<[{[{[]<>}{()()}][[{}{}]<[]>]}<{{{
[(<[{([{({<<[<<>()>[[]()]]{<<>{}><{}<>>}><{<()()>{{}{}}}(({}<>)<()<>>)>>})({(([<{}<>>{[][]
{(([{[<{{[({{[{}<>][()]}<{{}<>}>}(({<>[]})))]{((<[<>{}][<>[])>[[<>()]{[][]}]))<<<({}<>){{}<>}>(
{[<{({((([[{[(<>{}){<>()}][([]{}}]}]{[<(()()){[]()}>((<>[])<(){}>)]}]){<(<<{{}<>}>>)([[{<><>}<
{<{[(<{<[({<<[<><>]{()()}>[{()<>}<{}>]>[[<[]>][{()[]}{()}]]}(<(({}()){<><>})<(()())[<>()]>>{
<[({[[{<([[{<{{}}>(<<><>>{[]()}}}[{{<>{}}<()<>>}{[[][]]{[]<>}}]]<((([][])<<>{}>)<((){})[{}()
{{[{<[{<<{<<(<{}[]><(){}>)<{<>[]}[{}()]>>[{{[]<>}<()<>>}[{{}<>}(<>())]]><[(({}<>)({}<>))<<{}<>><<
{<<({(<[(<[[{{[][]}{{}}}<[[]()]<<>())>]](<{{{}<>}{()<>}}>)>)]<(({{[[[][]]]}<[[(){}]<[]{}>]>}))>
({{([<<{[(<<{{<>()}<[]()>}<{(){}}{{}{}}>><(<{}[]>{<>{}})<([]<>)([]())>>>)]}>>[[{<{[<<(<>{})
<{({{({<<[{<<{<>}{{}[]}>>[[{[]<>}{()()}]<<[][]>(()())>]}]{<<{[(){}><<><>>}{{<>[]}(()<>)}>[<<(){}>[[]
<({<([[[([({<{(){}}([][])>}<[{[][]}{<>()}]<[(){}][{}<>]>>){<({{}()}{[]{}})>{[{[]{})[()[]]]<[
{([({[(([<{((({}()){{}<>})(<()[]>{()()})){[({}{})<<>[]>]([{}][()])}}>]{<<[<[[][]]{[][]}>({[]{}}<{}()>)
<<{[<({[(<[({<{}{}><()()>})]{<<[<><>]>>}>){{[((<<><>><{}[]>)){<{[]()}(<>())>}]{{{({}<>){[]<>}}{{
<<({<[{(([{({({}())(<>{})}{((){})})[<[[][]]([][])>]}<<[[<>{}][[]<>]]<([]<>)[()()]>><<<{}[]>(()())>>]])[[[
[{<({<(({([([{[]}]<{[]()}[()<>]>]{{(()())<{}()>}{{[]()}<()<>>}}][{(<[]<>>[<>{}])[<[]<>><<><>>]}<(<<
<{{((<<(<{({<{<>{}}[[]{}]>})[[{{[][]}{{}<>}}]]}[(([(()[])<()<>>]((<>[])<<>{}>))<[[<>()][<>
{[([<<<({[{<<[<>{}]<[]<>>>>({<<>{}>((){})}<{[][]}{[]{}}>)}<{(([]{})<<>>><{{}()}(<><>)>}<{<[]
<({[[{{{([(({[{}<>]{[]<>}}[{()<>}<(){}>])<[<{}()>[[]<>]]>)]{{[<{<>()}[{}()]><<<><>>{[][]}>]([[[][]](<>())
[<<{{<[[{[<(<{()[]}[(){}]><[()[]]<<>{}>>)>[[[[[]{}]{[][]}]{<[]{}><(){}>}]({{<>()}<<>{}>}({()<>
[<[[(<[[[[<<<{()<>}[[]()]>>{[[<>[]]{[]{}}]{[<>[]][[]<>]}}>]]({[({[<><>]<{}<>>}<<(){}>[{}()]>)[[<<>
<{{({<([{({({{{}()}((){})})([([][])[[]<>]](([])[{}<>]))}<(([()<>][()[]])[<[]><{}{}>])<{({}<>)<<>()>}
{<[[[([{[<<(({{}<>})(<{}()](<>{}))){[[<>[]]({}<>)]}><[((<>()){[][]})[({}())<{}<>>]]<({<>[]}{{}<>
{<[<[({<({(<(({}[])<{}>)((<>[])({}<>))><(([][])(()()))>)})({{({{<>())}<{<>()}([]{})>)[[(()<>)<<>[]>](<<
{(<(<<{{({{<{(<>[])[[]]}{(<>{})>>{<(()())[{}{}]>{{[]{}}{{}<>}}}}(<{[{}[]]<(){}>}[[{}{}]{()<>}]>([{<>{}}[<>]]
[{[{{[[[{([<(({}{})<[][]>)<([]{})<<>{}>>>[{[[]{}]([]<>)}{(()())[<>[]]}}]((<([]<>)[()<>]>(<{}()>)){<[<>[]](
{<<<<{(({<<({(()())(<>{})}<([][])[[]()]>)[{{[]()}(<>)}]><{[<<>()>]{<[]()>[[]<>]}}>>}>[(<<<[{()<>}{{}<>
[{[(<[<{<[({[{[]<>}<[][]>]{{<>()}}}[({<>[]}{{}{}}){[[]<>](<><>)}])({({{}<>}<{}<>>)}<[((){})[{
{<[[{[(((<({([[]<>](()<>))}[{{()<>}({}())}(<[]{}>{[]{}})])<<(({})[{}{}])[(<>{})<()>]>>>))<[{{<[{{}<>}[[][]
[[<<([{<{((([<{}{}>(<><>)][({}[])])[[(<>{}){{}<>}](<()[]>[[]()])])[{({()}{{}{}})(({}())([]{}))}({[{}[]]{
<<((<[<(([<{[<{}<>>][<{}{}>{{}[]}]}[{<<>()>[[]{}]}{[()[]]([]{})}]><{({()()}{[]})<{[]()}[{}{}]>}{((<>(
({<<{[(({{<<{[[]()]{{}()}}{[<>{}]<[][]>}>{(([]())[<>[]]){<[]{}>{<><>}}}>{{{{<>[]}{{}()]}{{<>{}}[{}{}
{((<<{<<<((<(({}{})(()))[[()()]{{}<>}]>{(<()[]][{}[]])[[<>[]]<<>>]}))>([[{({()[]}{()[]})(<[][]><{}{}>)}[[[[][
[(<<{<[(<([<(<[]()><()()>)>]{({[<><>]{[][]}})}}<[([(()())[{}]]<<(){}>[<><>]>)][<<((){})>>[[{<><>}[{}()]][([]
[<{[<[[(({{{[<{}[]><<>{}}][[{}<>]<<>()>]}{[{[]}[{}[]]]{[()[]]<{}<>>}}}[({<(){}>{{}{}}}<(()[])(
<{([{(<[<<<<[[{}{}]([])](<{}{}>[[][]])>{{(()[]){<>[]}}<[<><>][(){}]>}>(([[{}{}]{{}<>}](<()()>))<<(<>{})<<
[(<[[[[(({[<<<<>{}><<><>>>>]<{[{{}<>}<()>]{{[]{}}[<>[]]}}<<<()[]>([]<>)><(<>{}){[]()}>>>}))[[([{<
[([(({<{([<[({{}{}}<{}{}>)[[[]{}]({}<>)]]<[([]<>)({}[])]{(()[]){[]<>}}>>{[<{[]<>}>{[()[]]<()<>>}][<([
{<[<[[<[{({{<[[]()][{}()]>({()[]}(()[]))}([[<>()]])})}{{<{{[<>]<[]()>}{<{}[]]}}<{{()[]}<[]<>>}([()()]<{}()>)>
[{{(<(([([((<{{}{}}({}())>{{<>[]}<[]{}>})([{<>()}{{}<>}]{<()<>>[{}{}]})>]{{[<(<>){[]{}}>{<<>[]>[()[]]}]
[<<(({[[({({[{[]{}}<<>[]]]{[()()]<<>()>}}{[{<>[]}<()>]}){{<<()[]>{[]{}}><<<>>[[]()]>}}})<[{{[<
<([{{{(<{{{<<({}()){(){})>{<{}{}>{<>()}}>{(<()[]>({}()))<({}())<()()>>}}[(({[]{}}[<>{}])([{}<>])){{{{}}(<
<<{[{[[<([[<(<{}<>><()[]>)<{<>()>[<>()]>>]][{{{{()<>}<{}[]>}[<[]()>[()[]]]}<{[{}](<>{})}>}[<[[<><>]<
[{[([{<<[([[{<<>[]>(<>())}((()())({}{}))>{[({}())<<>()>]<(<><>){()<>}>}]({([(){}]<[]<>>){<[
[{<<[[<((({[<[[]()]>(<<>>(<>{}))]<<([]<>)[<>{}]>{<[][]>(<>())}>}(([{{}<>}{{}[]}]{[()[]]{{}{}}})<
([<<{[([[<{<{({}())}{(()<>)}>[<[{}<>][[]()]><[<>{}]({}[])>]}<[([<>()]){[()<>]([]{})}][[[{}[]]][
<{[[{({<{(<[[(()[])<<>[]>]<<<>()>{[]<>}>]>{[<(<>()){<>[]}>(([][]))]([<[]<>><{}{}>]([<>{}](()()
{[([{{(([[<{<[{}<>]([]{})>[((){})<()[]>]}[[{{}<>}<[][]>]<{[]<>}([]())>]>{<{{{}<>}{(){}}]{{[]
[{{<[([<{[[({[{}[]][(){}]}<{<>()}<[]{}>>)]<<({()<>}[[]()]){[<>[]]<()()>}>>]{[<<(<>[])<[]<>>
<[{<[<((<({[{[{}[])(<>{})}(({}[])[<>])]})>[[([{((){})<<>>}])[<((()<>)[{}{}])[[(){}]]>{<<{}()>{
({[[[[[[[<((<[<><>][()[]]><(<><>)>))>{{<(<<>[]>{{}})[[[]<>]({}())]><{{()<>>[[]<>]}[<{}{}>{<>{}}]>}[{<(<
([([(<[{<[[{<{<>[]}>{{{}()]<{}()>}}<([{}()]{{}<>})[([][]){{}<>}]>]{<{{[]{}}{{}<>}}<[[]()]>>[[{()[]}{(){}}]{[
{<{([([{<<<<{[<>()]<[]>}[[()<>]<()>]>>(([[<>[]][{}{}]])((([][]){<><>})([[]{}]<()<>})))><{<<[()()]<[]()>
[{({[{[(([([{{{}<>}{()<>}}(([]<>){{}{}})][<{()}{{}{}}>(<<>()>[<>()])])]))<<<({((<>()){[]{}})[{
([([(<(({<(<<<{}[]>){{<><>}[[]{}]}>[{{[][]}<<><>>}])<{<<[]>(()[])>[[{}()]<[]<>>]}{({[]()}[<><>]){{{}[]}[{
{{[{<{((<((<<<(){}>>{([]{})[[]()]}>([({}{})]{<()>{[]{}}}))[[(<<><>>)]<<<{}{}><(){}>>[({}[])({}
<{[({{<<((([[[(){}][{}<>]]<(<>[])<[]()>>]<[[{}()]({}())]>)({<[(){}]>{(<><>){[]{}}}})){{{<<[]()>[()<>]>[<
(<[[(<((<[[<{[[]()][()<>]}<[[][]]<[][]>>>((({}())((){}))(<{}<>]{()()}))]]>[[{<{[{}<>]}>([[{}<>](()
<<<{<(<[<{[[([<>()][()<>])(<<>()>[{}()])][<{<>()}>]]}<<<({<>[]}([]{}))<<(){}>>>[[({}())(())]]>{({({}[
([<<<{<{({<[{(()<>)<()()>}]<[({}<>)]>>{[[{<>{}}(()[])](<<>>[[]<>])]}}{<<{<<>()>}><{{<>()}<<><>>}{<(){}>[(){
{{(<<[{{({({({[]()}<{}()>)(([][])[()<>])}<{(<>())[()<>]}>)[[(([]<>)[[]<>])]]}[({[({}()){{}>]})
<((((<{{{{{[{[(){}]([][])}[{<>{}}([]<>)]]([((){})]<[[][]][<><>]>)}}<(<{(()<>)([]{})}><([()<>]{<>()
<{<{<(<(<<<(<[[][]]<<>()>><[<>[]][[]]>)[<[<>{}][<>()]>]>{<{(()){{}()}}[<{}<>><<><>>]>[{<{}[]><<><>>}]}>{(
{[{<<(<([({{<<[]<>>[<>{}]>{<{}<>>([]<>)}}([<<>{}>((){})}<{<>[]}>)}<<({{}()})<(<>[])[[]]>>[[<<>[]>{()[]}][[[]
<<<<[<{<[{{(<[<>]<[]{}>><(<>{}){{}()}>)[[{<>{}}{{}[]}](<[]>[<>{}])]}{{[{{}[]}(()<>)]<([]())(
[([({[[{<{{<<{()()}<{}{}>>({{}{}}[{}{}]>>[{(<>{})<()()>}[[<>[]]<{}()>]]}[<<{<><>}(()[])>(<{}[]>
[<<[[(({<[[([(<>[]){()[]}][(<><>)[<>[]]])]<({<{}{}>(()[])}[<{}<>>({}())])((({}{})<{}[]>)[{{}<>}{{}{}}])
(({({[<<[<[([<<><>){[]{}}][<()<>><[]<>>])({[{}<>]<[]<>>}<({}{})[{}[]]>)][{((<><>)(()[]))}[<<{}()>{<>
<((<[(<(<[[([{(){}}<<>()>]({(){}}{(){}}))]][{{[{[][]]{<>{}}]{[{}<>]([]{})}}}[<{[[]{}][<>()]}[(()[])<
{((<<{({<[([(([]())([]()))(<[][]>{()})])<<[<<>[]>[<>())](<()<>><()()>)>>]>{{[{<[<>{}]<[]<>>>}<{{<><>}<
{<<<<[((<{({<{<>[]}{<>()}><{<><>){<>()}>}([[[]()][(){}]]<<()<>>{<><>}>)){[{{<>[]}{[]()}}{(<>())
({<<<<[{<{<{(<{}{}><()[]>)[{<>{}}]}>(<[([]{}){<><>}]{<<><>>[()[]]}}<[{()[]}{()[]}][{{}[]}{[][]}]>)}>}]
({({{<{{{[<{{(<><>)}({[]()}{<><>})}{<[{}[]]<[]<>>>[(<>[]){()()}]}><[[<<>()><[][]>]]>]<<[{[[]()](
<{[<([<[({([{(<>{}){()}}<([]<>)[{}{}]>)[[<()[]><{}<>>][(<>{})[()()]]]){<{({}){{}{}}}<{<>()}[[
{((({[{<{[<({[{}()]({}{})}<(<>)(()())>)({[[]{}](<><>)}[<<>[]>[<>[]]])><<[{[]<>}][([][])<[]()>]>(
({[((([<[(<{[(<>[])(()[])]}<[([][])([]<>)]<(()())>>>((([(){}])<(<>())<<><>>>)<[[()<>>{{}{}
[{{((<{[(<{[{{[][]}{<><>}}[[()[]]<[][]>]]<<({}[])((){})>>}>[(<([[]()]<{}[]>)([{}<>])>({<<>[]>(<>[])}[(
((<((<[<(<[{(<[]()>[()[]])((())(()[]))}{[[{}<>]([]{})]<[[]()]>}]>)><([<[<{[]<>}<{}[]>>[[(){}]]]({[[][]]{
[(([([(([<<(<{<>}{[][]}>)[{[()<>]{{}{}}}({{}{}}<[]()>)]>>{([({<><>}<[]>){<{}{}>[()<>]}]<<[[]{}]{{
[(<{<[[{[<<{<[[]<>]<[]()>>{{[]<>}}}><[[{{}()}([]<>)]][({{}<>}{{}{}})<[[][]](()())>]>><<({([]{})<<>{}>}){
<{[<[(<<[[[[{<{}[]><[]<>>](<{}[]>{()[]})](<[<>()][[][]]>([()()]<<>()>))]]({([<()[]>[{}()]])<{[[]()]}{<[][
<{{{([[([{{{<({}[])>}}<<({<>{}}{{}()))<({}{}){[]{}}>>[[(<>())[{}[]]]<<[]{}>{<>[]}>]>}([{[<<
[{<(({{<[{[[([<>{}]{<>{}})(((){})[{}[]])][{<{}<>>}[([]{})<{}>]]]}{<<([<>{}][()[]})[{{}}<{}()>]>(
[((<[{<<[<[{[{{}()}[{}[]]]<[<>[]][{}<>]>}]>]{[([([[]<>]{{}[]})[<(){}>[()[]]]]<<({}[])<[]()>>[(
[{([<{([(({(<[[]<>]>{({}()){<><>}})([([]())[[]<>]])}(<[({}())(<>())]<{()<>}[[]<>]>>)){{([[<><>][()[]>](<[][]>
<<(<<<{{{<<(<<[]<>>{<>()}>[<[]>])<{<{}<>>}{[{}{}]<<>[]>}>><{<<<>{}>({}<>)>}{([()[]]<<>()>)(<<><>><[]{}>)}>><
{[<<[{{(<<[((({}{})[{}{}])(({}<>)[{}()]))]>{([[[(){}]<{}<>>][[{}[]]{()[]}]](<{[]{}}(<>[]>>))}>)}[(<
<{{[[<[[[(((({<><>}{{}{}})<[<>()]([]())>)[<{{}<>}>{((){})[[][]]}]))<{<{[[]()]<[][]>}{<[]<>>(<>
{<[<<([[[[{{<({}<>)<{}()>>[(<>())({}[])]}<{([][])({}<>)}>}(({[<>{}]{[]{}}}<(<>{})>)[<{[][]}{[][]}>{({}()){
[[({{[(((({<{{<><>]}{(<><>){<><>}}>(<[()<>]<{}{}>>((<><>){<>[]}))}{<[[{}[]]([][])][{{}[]}[
[{{<([((<<{(((<><>)<(){}>))((({}[]){<>()})(<{}()}({}{})))}><[<<{<>[]}[()<>]>{[<>{}]{[]()}}>{{
[<{<{{({{<<<{[<><>]<[][]>}<<(){}>(<>)>>>([<{[]()}{{}[]}>{<{}()><[]<>>}]([([]())[[]]]([[]()]<<>{}>)))>
<[{<[(<{{([[<[{}{}]><([]<>)(()())>][<((){})[[]()]>[([]<>){<><>}]]]{<{<[]<>><<>>}{<{}<>><[]{}
{[((((((({([([(){}]([]<>)){[{}](<>[])}]{[<<>()>([]<>)]<<[][]>{[]<>}>})<<[{{}[]}(<><>)]<[()<>]
([({(([[[([[((<>{}){{}{}}]{[()<>]((){})}]((({})(<>[])){[{}{}]<<>()>})]{({(())[<>{}]}((<>{})
{<[<{(<[{<[{(<{}()>)[<<>[]>(()<>)]}([{()[]}<{}<>>])}(({<[]{}><{}{}>}([[]<>]{{}()})){[[{}<>]
<<({[[<<[([(<[<><>]{<>{}}>{<(){}>(()())})<{[<>{}]<()[]>}>]<{[{<>{}}<<>()>]<{{}()}[()<>]>}<[[{}<>][{

View file

@ -1,10 +0,0 @@
[({(<(())[]>[[{[]{<()<>>
[(()[<>])]({[<{<<[]>>(
{([(<{}[<>[]}>{[]{[(<()>
(((({<>}<{<{<>}{[]{[]{}
[[<[([]))<([[{}[[()]]]
[{[{({}]{}}([{[{{{}}([]
{<[[]]>}<{[{[{[]{()[[[]
[<(<(<(<{}))><([]([]()
<{([([[(<>()){}]>(<<{{
<{([{{}}[<[[[<>{}]]]>[]]

View file

@ -1,10 +0,0 @@
4764745784
4643457176
8322628477
7617152546
6137518165
1556723176
2187861886
2553422625
4817584638
3754285662

View file

@ -1,10 +0,0 @@
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526

View file

@ -1,22 +0,0 @@
GC-zi
end-zv
lk-ca
lk-zi
GC-ky
zi-ca
end-FU
iv-FU
lk-iv
lk-FU
GC-end
ca-zv
lk-GC
GC-zv
start-iv
zv-QQ
ca-GC
ca-FU
iv-ca
start-lk
zv-FU
start-zi

View file

@ -1,7 +0,0 @@
start-A
start-b
A-c
A-b
b-d
A-end
b-end

View file

@ -1,10 +0,0 @@
dc-end
HN-start
start-kj
dc-start
dc-HN
LN-dc
HN-end
kj-sa
kj-HN
kj-dc

View file

@ -1,18 +0,0 @@
fs-end
he-DX
fs-he
start-DX
pj-DX
end-zg
zg-sl
zg-pj
pj-he
RW-he
fs-DX
pj-RW
zg-RW
start-pj
he-WI
zg-he
pj-fs
start-RW

View file

@ -1,916 +0,0 @@
1213,736
1158,890
626,303
98,10
878,268
1208,143
112,400
865,894
1218,179
1089,418
535,886
726,515
1263,786
589,270
80,518
288,322
1101,483
989,308
1002,707
467,18
1036,364
552,591
445,280
912,40
1268,761
984,47
883,574
815,784
719,236
865,166
836,581
656,735
228,264
23,466
1099,515
1284,665
432,268
195,493
1001,308
430,222
1294,537
427,646
574,381
1116,829
1143,808
950,578
293,579
28,751
169,341
326,159
257,721
773,670
1231,556
306,436
454,520
1267,522
85,309
1273,358
1019,208
870,504
647,175
408,544
1310,386
912,854
512,10
674,770
273,742
626,584
112,10
736,420
1198,884
214,620
139,751
448,782
771,646
709,796
755,460
179,838
360,578
274,364
656,401
810,61
194,310
584,515
773,238
184,241
932,661
105,333
1096,838
959,838
252,341
1237,338
112,884
746,812
735,556
45,75
815,838
654,719
1225,309
1226,892
453,465
783,520
987,446
348,458
976,175
487,392
1307,558
1279,882
145,509
909,444
1310,389
626,527
356,527
363,774
142,130
246,581
1064,581
925,837
166,842
529,877
124,341
709,546
651,490
372,16
537,614
1004,213
1198,661
1240,40
701,504
1103,120
638,462
857,351
269,794
1099,122
624,360
1284,217
902,26
102,672
691,208
850,287
1083,698
636,770
475,539
1280,735
495,712
1273,655
217,854
1109,687
345,565
939,43
902,203
803,241
35,838
169,624
206,236
413,718
617,599
729,786
372,430
467,242
771,324
924,268
574,854
167,502
141,738
166,52
659,336
1240,123
672,462
902,581
883,320
37,655
209,0
897,875
823,630
1074,264
385,794
1131,838
1151,504
1294,357
1260,396
1228,768
209,57
1225,360
1111,710
333,586
996,371
954,140
790,367
843,348
1058,877
252,509
181,385
1218,267
1123,428
191,98
1039,372
214,504
274,260
359,751
1109,753
659,359
10,674
835,56
730,490
378,1
0,539
35,182
276,661
469,626
1061,533
783,432
656,847
281,707
187,428
1275,568
716,143
938,878
663,117
738,254
954,86
467,796
966,761
405,311
209,651
38,98
1233,824
430,837
1290,841
865,280
1123,18
985,170
182,859
1164,245
656,607
979,784
634,10
460,829
768,172
1126,317
1000,805
1198,830
629,536
208,542
1193,747
328,60
1123,751
1004,10
1056,571
254,571
1086,57
192,815
1287,204
1012,754
838,411
1225,361
380,310
616,117
621,243
1165,509
706,781
564,530
905,311
162,763
354,889
975,103
10,226
326,847
184,317
1261,143
1310,65
310,462
1208,672
402,17
85,361
129,847
1020,486
16,462
618,856
440,102
686,381
925,794
453,65
1287,639
180,656
507,91
460,65
893,271
344,581
609,208
246,432
781,246
185,268
311,696
736,488
346,707
875,708
38,565
420,267
433,18
1101,651
159,222
420,627
1245,446
905,361
954,527
909,450
495,392
755,434
179,429
1230,868
1129,621
932,681
211,122
344,313
52,530
602,288
947,326
433,113
634,557
529,17
647,117
1253,324
331,502
580,205
1111,184
359,143
52,36
32,409
1280,584
112,661
1143,392
1228,126
32,485
28,310
768,436
1000,761
281,502
753,214
443,646
1213,680
97,515
939,820
112,172
1068,674
371,43
1089,642
1064,82
1131,429
947,840
684,751
420,264
1082,660
965,553
52,82
795,751
351,98
1143,726
815,224
80,656
900,605
897,360
706,333
880,57
676,841
119,877
938,16
393,176
1001,586
507,388
31,194
405,182
35,470
185,716
1310,57
733,70
391,658
815,182
31,65
868,866
356,140
628,229
841,492
691,712
1195,696
634,287
523,65
345,138
310,49
663,623
474,581
520,639
224,57
1287,428
328,579
323,392
351,504
1287,255
815,360
194,136
207,269
542,436
432,178
110,634
878,716
201,829
897,718
52,726
328,159
1258,502
1307,87
1129,733
979,315
323,427
1002,187
351,639
938,430
527,520
870,176
1069,639
1307,467
36,856
23,31
413,534
402,341
687,65
619,120
634,884
1258,858
18,203
542,885
604,781
1282,758
5,553
1294,385
378,437
1096,56
835,838
23,876
1111,278
1011,33
308,707
117,798
331,763
470,241
830,732
1265,691
982,287
950,709
755,196
691,694
776,12
1290,765
619,40
738,640
1121,88
938,464
951,143
537,208
736,518
405,126
453,543
365,694
157,329
385,57
37,358
482,341
442,28
870,457
984,336
693,239
917,176
45,158
892,264
1258,812
1113,534
303,7
1004,661
569,869
281,158
378,681
569,534
16,509
435,708
373,840
1192,542
721,606
1041,794
1151,392
343,646
684,143
1064,740
552,751
1151,182
1143,616
698,313
1064,812
446,800
564,812
1191,717
452,105
85,360
947,504
380,82
937,483
319,551
922,815
1213,515
984,607
73,556
309,852
50,661
1181,847
1300,535
448,560
291,854
447,8
0,91
1191,625
932,233
371,689
361,131
865,798
1169,738
446,94
966,581
110,309
74,404
1000,49
1,842
798,354
20,884
1233,406
1230,243
492,267
867,248
346,187
1245,472
736,406
656,287
962,590
572,640
544,260
927,522
841,786
1029,392
169,278
378,445
420,630
488,52
626,751
927,372
691,854
803,355
3,87
1230,26
154,341
612,313
823,560
802,245
216,137
987,427
207,120
775,877
897,176
1266,654
541,191
159,110
1275,182
678,268
1153,565
1274,856
991,656
15,696
172,341
691,504
310,705
1275,470
574,243
448,637
1111,262
951,751
619,390
539,324
626,143
733,809
656,281
0,837
529,429
862,180
1279,194
947,568
227,574
378,400
418,364
556,182
969,481
500,61
947,774
761,333
1012,136
1258,530
574,518
666,311
326,558
512,130
870,718
689,682
1104,658
1101,614
187,876
1237,556
313,861
222,716
676,884
201,375
336,28
1058,509
469,492
1081,232
361,763
42,761
1183,462
1148,110
1273,239
905,712
863,438
905,518
736,474
1034,445
1088,716
1022,677
117,224
1265,686
1171,751
862,112
0,165
1123,546
1310,508
49,143
880,837
976,719
684,361
1233,70
28,478
82,126
1053,721
131,625
900,289
1193,278
373,65
1272,796
490,617
1016,633
413,176
82,96
1116,584
469,786
867,646
843,652
1118,815
775,886
624,829
166,500
555,574
385,837
455,278
487,840
65,446
1139,819
1211,460
1169,114
1101,894
624,381
227,250
119,269
1029,56
616,98
905,126
937,449
1096,504
1141,624
1099,772
201,687
1116,65
217,40
708,136
787,65
1273,648
1155,338
659,87
201,207
402,161
1091,708
440,722
447,269
1022,572
939,205
497,329
1058,553
542,661
863,886
155,338
622,857
92,715
612,133
962,458
634,159
28,30
288,677
1028,878
1183,520
169,176
23,428
1292,203
754,182
555,320
35,208
701,75
1022,322
684,533
320,623
857,95
18,770
214,50
7,777
398,406
261,176
783,462
709,98
1123,815
440,457
708,168
447,625
359,418
1278,485
1012,143
159,504
38,796
1230,332
418,530
877,255
654,505
28,136
912,406
1193,320
485,46
351,838
1265,75
758,143
1300,226
1282,527
612,761
575,556
979,763
77,70
654,607
688,261
766,585
145,385
363,504
676,287
788,607
857,465
1128,35
574,513
1200,309
10,668
169,553
654,57
1064,868
191,796
45,686
982,159
795,79
413,361
761,863
473,273
0,401
1017,579
840,808
99,434
79,556
162,784
459,418
798,10
195,418
651,404
520,527
959,887
965,565
288,217
730,404
1282,478
602,364
803,315
962,304
820,617
741,534
549,333
862,714
363,326
102,222
348,436
1156,553
1064,463
97,214
609,691
214,722
827,208
372,688
453,519
385,401
622,633
70,40
455,616
949,763
693,599
194,758
512,541
1169,786
617,536
1086,837
112,494
910,161
984,495
959,56
977,586
454,262
1141,341
609,203
748,19
1143,560
656,508
541,703
1181,495
1183,246
542,102
736,189
433,866
661,756
659,490
331,446
236,630
610,688
3,467
446,268
694,117
308,35
537,350
1101,243
951,418
127,432
979,110
802,705
741,86
787,829
1198,233
808,890
1279,12
50,396
1183,14
23,255
636,124
448,714
1236,205
1193,798
1103,625
945,694
1139,108
522,287
624,513
997,33
1190,658
35,56
1275,406
773,208
1125,716
69,621
1093,518
1310,837
1125,268
865,448
1102,94
306,10
373,483
442,866
858,105
602,168
624,159
334,719
480,162
870,172
602,736
0,508
1064,154
1056,712
582,161
1261,591
661,308
35,200
92,19
214,390
fold along x=655
fold along y=447
fold along x=327
fold along y=223
fold along x=163
fold along y=111
fold along x=81
fold along y=55
fold along x=40
fold along y=27
fold along y=13
fold along y=6

View file

@ -1,21 +0,0 @@
6,10
0,14
9,10
0,3
10,4
4,11
6,0
6,12
4,1
0,13
10,12
3,4
3,0
8,4
1,10
2,14
8,10
9,0
fold along y=7
fold along x=5

View file

@ -1,102 +0,0 @@
CKFFSCFSCBCKBPBCSPKP
NS -> P
KV -> B
FV -> S
BB -> V
CF -> O
CK -> N
BC -> B
PV -> N
KO -> C
CO -> O
HP -> P
HO -> P
OV -> O
VO -> C
SP -> P
BV -> H
CB -> F
SF -> H
ON -> O
KK -> V
HC -> N
FH -> P
OO -> P
VC -> F
VP -> N
FO -> F
CP -> C
SV -> S
PF -> O
OF -> H
BN -> V
SC -> V
SB -> O
NC -> P
CN -> K
BP -> O
PC -> H
PS -> C
NB -> K
VB -> P
HS -> V
BO -> K
NV -> B
PK -> K
SN -> H
OB -> C
BK -> S
KH -> P
BS -> S
HV -> O
FN -> F
FS -> N
FP -> F
PO -> B
NP -> O
FF -> H
PN -> K
HF -> H
VK -> K
NF -> K
PP -> H
PH -> B
SK -> P
HN -> B
VS -> V
VN -> N
KB -> O
KC -> O
KP -> C
OS -> O
SO -> O
VH -> C
OK -> B
HH -> B
OC -> P
CV -> N
SH -> O
HK -> N
NO -> F
VF -> S
NN -> O
FK -> V
HB -> O
SS -> O
FB -> B
KS -> O
CC -> S
KF -> V
VV -> S
OP -> H
KN -> F
CS -> H
CH -> P
BF -> F
NH -> O
NK -> C
OH -> C
BH -> O
FC -> V
PB -> B

View file

@ -1,18 +0,0 @@
NNCB
CH -> B
HH -> N
CB -> H
NH -> C
HB -> C
HC -> B
HN -> C
NN -> C
BH -> H
NC -> B
NB -> B
BN -> B
BB -> N
BC -> B
CC -> N
CN -> C

View file

@ -1,100 +0,0 @@
8656175343119439947311919179279377257689197682985752287249881788527977345924133329967132199899199876
4281288396984115627338957853913949146812568775798196289991176529889498798259196976277683981565984526
8169838335918963371547591999342191683995972519179929683978126291855319511168245582651697938949414963
9911589184911198759466719191189995157885898771177913669999436998997781742478168921196176418888127932
2332856729917591158935782911513226531793881992469468248251991718456991551657621249229316797949388969
6488738222981127824819626661531168733698299313631126969162927725778914183239351484699921454131481322
3456499223985116399353928681116846939429849384129296119943791119497551946593566977823982927391143399
9297612841849646148511299569971197927971682598351883892842936977227795411959211782251399118676896328
1685688918999598249622886442487951289969917848948815999749154287969297396481891239821819247914959943
2855192597719945162116189119381795158862162959133647579913886639586438893695967226719685616432291318
3893139873964939791913261811173979825213968972939996181992593113695976322782892995939891783998623789
5964671772545917912328949994999514157618987654288269789931394913375316999489275494179994919117119365
3216339828898396212733674969295762442389789119366989996931919596282992864471192938639162947919972647
7879826444123912118829914949989194219763533694839431198212319893181151696157671388992581982743988967
7876122492176935838133394839673532581399474449569117478121989273123412313151952891988698552384251637
8786999269197821985731819155537259938991261919979365751539876866146174376911518943778479997131942722
7239919942299391891898171771589178983916281118889294494829292752139999754571391999826947791975394972
2727617215141959982544247383138498917281833932371546394891963994434638187617528821379728933335772342
6712949984729176138535147942577311588399869767114795759883948915177671474313191789814718292236422124
8689792116597916131779139899373471282726812338914773516383771158691551851991689929199689197212298649
6228175894997691471313338136819712699979449476188196729899628851391971728199959981585798691881191415
9491157288112631922166642933446197292729817888649185515198768537925149995158353829229269894798938589
5199389142294542461535132814487861987422485947698739199748986652229272998164982399192268248929567161
6881119581991538187539159493621999896486112182779617795198955921614753699796171837819179999654231813
6996595113784151975521879415898217119639999975184518599369743127684295298268259495226623211591871888
1779949977648145993713949919359399998812143513534984334127763318649997689919849157137418761137512977
9223292971993981422528813498119387921238194638215641911218326517839287886478991147999899894724396962
7451983891767995938972123465939918261682281929689989464297789895588752221375859586787938391672994381
1579954176878141996516584483611183926131694919877929897576151469657864935819598781814826881644187861
8934595321937914584995177237653199951582515953621782173159453287575529819242531191989113518599339361
3214791137819868237121897913928328682928239268681975567994149694512799167598489194267554981611157817
3161289322443822496458312797912957538349962328948955764669152944278622928929944477635195993465821714
3769985892295265479971729196428585411214871889139731131516448815999122871374996159138497416978598848
4926877381218811127939655759733739111889455359949289979523168797571871445191441719179859376969393872
7159871151274214979637977982939997337182139971896511115912187982698278842961545125121242636339621282
8423118867997391616931374681582965659184916625321536161483641999294114251928796446618889979683993218
6824788915976897879897933391998341399228914119912289149511515799142181679965255395897688149876629889
4794395837416911945432167619882718499181629123717219977896911277339851349162195299228963994667691947
1465122112768881153591399679274839985297692314947884169719151181986711822112796246416415955915718319
7114797833579933611249299912348294873921288555119486979959982462111791467394161781467316779796883775
9767795467854144194712742294766968549329117618283754959873952489784997597669593796889571883816748771
1759974879458746414925558868197241214751687661841649999221178613679929261984417289292556869111324941
9557955429999672993612951916598187741611893112948813816999484953994151249931191942493691497559992158
1469791219499218437828194894539893191199115998162227659757698173867329816328599398544492677817272998
6696472832532492295279572315976884291727999732161858916985514872395367168971969865959582923387918951
9722652752119479169481198119314728131429449798379179119171791999189878174319864498112912224658495939
9581794449119116165418178711351481129242636919987948291451161695541253977174231393582734959682898495
4757727865924728111221629983989222587789999361791192917315287219922119718827676188689966872358484669
1982319969915242121935864989286462118395187369193933592791414764965279817872197863615512262358899223
1811379712999278717898361849316989959114612857179582117839285399618929182259624916911439331479239488
1377519658968884779897799292198595917148591218821239614925192183128211371959295299959221257811239131
2627929612263297913663198357736594275199769318118546371628241929618769991214845296132728799271417791
7576972138942696587693261199467749912936563131454674591315468112333812659454789393699615918167338715
1778985995949591574849625759667137792111923771976687288498928179271746938986792658149697999719931492
1497174992519427759719169714342998311421419197412331399469329847692794191181111339933357161599799597
7158163932199423259572847121198873491117119999919996985599149129919588579223518511588378639685891315
6219361855573892912131718991998196749251949481814844299182119621344738991784149679694476483378729929
1398599388779918861183115593522489331874978727922373471991219247115944295163699192776967648639268659
8246143812623927544154898631717811662213981175534335932638718171969421398421692892399791789186618487
4457134139841167885881924949364884427839314973843366971997383189398399657998961185159781215111619878
2889934549617841969369167119338852267887359654637229634658717722728239549585928482358431813296859898
9968328746979669249145999585143117898196251944175462877716129989773292878848966999379983436559934934
6493994193996595991299891992438695916166928199197254269991979292986895799985938128881229638182945947
7266928918675112795879219714929968471352931229592623394713393869269941181318972192169271548316892574
2174196776119149368951321419512925818641848291921584561885586189445194773817792112569311611884895234
5617593683181229369984148191819568774125471789395181874847932736429929334265516997661987796259692831
7882228973393795938729341656949619511272988446634311621871394678132831899299832311614174939261965429
1131881592984545192978449637151892697525357924197922698921549791127287595929496515499876251183628176
9922954913893559597663824459627321943979599969474976998899879429185892995511392872381956558981867119
5166385448694129439797196837181355547743133114829285275149516986685925813416161972979872853196155916
3292899922794159291851551956738911971988929383861879921354871787791695284999126375594873179426338749
3971894752927483651131869717199971871964396958991799413921821198121691265888799954912311963139425236
5778565318498395151591219315499879273943817921588123199611531989674238272218198865913747444419629892
1148956123134785152496887782841669964225944272953163717879528194631986997718971481186872943816456591
5982998155291779554662769986899318991622943125199743569463317913185991442772122148595119965486877247
1592622221626611159996955945922614981222438358385913259412688295754161193293194979914999974739594393
1735995389872189896282749844299933869588931688619645726996959149185997128397635694766944945458588326
8969839951998899979864239155832982419271118982882915197745124695321464198748765361499779978719441246
6625484228731161195646227911299498172947526327866775111148173468799729895761595437743769876911891521
6742199381937628999297557371399872217983581247138899399239252389649491949578491998528132446741686888
9212328164223895178547771855976415127193137191217188318191949238429129518281919843229126971963111111
8589368771155989697277997492471969978917117589192916193887975787949771588121551699971132275182798898
1321997349438946615383211392181979153964221243634922639112684529286794272849757186396714797832698913
5499455959999492339698359789213323519479768626457859213487938838995348379392231623595879353861382977
4612129999347379911982695394862437936254989311441326295994617191963497895691479282499959828989987571
3953949985681978999897341375236798381973326952579319464522624134872231113676167279146985521828793431
2547232255918288952326674861524529119719429148626615319818611241832868529862499874951986568635799957
2181959929952711246913363617991144311613441799129546223661433628933579819732979148127949974997119951
1369158892917379123998253242599392893199998853969933983592129813969821127281951849151627687114757833
9629699176294886577773394197932998769278865351155516385519239971147785457838922269188195227329168368
1788912961677399663173822433232514884848179868666798987368382881226468481869127998236137881926332779
4811241997249159619241887142461943467819366815858371379792287198271563986876852729186927761281942192
2121993996798639492562961751217922319969898368461919218459919713413366292171628639922554153774327219
3489591127775295131639799492971117993637992434115331278511281997587996291111198123428588991837368589
1283798883941983912985615991541417994114453747887836936186431822993881123911799962749981389292178586
8392631553657936578372199916912973193995216848776811924799769959318889717919172521769363698292447429
9587697134368994212916856845984875416273418561198913859115983139967143891991617853289936814265113512
9111571922348271733199797953979536915998195916688317991255916216419817129423728913622269119972958686
9959599568987335314713638999897919449512991684446347789183915679567141547281548619496728636288445972
8391247911139217869276338998734496391173478717461631572924754792241695917352991662734191814376765142

View file

@ -1,10 +0,0 @@
1163751742
1381373672
2136511328
3694931569
7463417111
1319128137
1359912421
3125421639
1293138521
2311944581

View file

@ -1 +0,0 @@
E20D4100AA9C0199CA6A3D9D6352294D47B3AC6A4335FBE3FDD251003873657600B46F8DC600AE80273CCD2D5028B6600AF802B2959524B727D8A8CC3CCEEF3497188C017A005466DAA6FDB3A96D5944C014C006865D5A7255D79926F5E69200A164C1A65E26C867DDE7D7E4794FE72F3100C0159A42952A7008A6A5C189BCD456442E4A0A46008580273ADB3AD1224E600ACD37E802200084C1083F1540010E8D105A371802D3B845A0090E4BD59DE0E52FFC659A5EBE99AC2B7004A3ECC7E58814492C4E2918023379DA96006EC0008545B84B1B00010F8E915E1E20087D3D0E577B1C9A4C93DD233E2ECF65265D800031D97C8ACCCDDE74A64BD4CC284E401444B05F802B3711695C65BCC010A004067D2E7C4208A803F23B139B9470D7333B71240050A20042236C6A834600C4568F5048801098B90B626B00155271573008A4C7A71662848821001093CB4A009C77874200FCE6E7391049EB509FE3E910421924D3006C40198BB11E2A8803B1AE2A4431007A15C6E8F26009E002A725A5292D294FED5500C7170038C00E602A8CC00D60259D008B140201DC00C401B05400E201608804D45003C00393600B94400970020C00F6002127128C0129CDC7B4F46C91A0084E7C6648DC000DC89D341B23B8D95C802D09453A0069263D8219DF680E339003032A6F30F126780002CC333005E8035400042635C578A8200DC198890AA46F394B29C4016A4960C70017D99D7E8AF309CC014FCFDFB0FE0DA490A6F9D490010567A3780549539ED49167BA47338FAAC1F3005255AEC01200043A3E46C84E200CC4E895114C011C0054A522592912C9C8FDE10005D8164026C70066C200C4618BD074401E8C90E23ACDFE5642700A6672D73F285644B237E8CCCCB77738A0801A3CFED364B823334C46303496C940

View file

@ -1 +0,0 @@
target area: x=277..318, y=-92..-53

View file

@ -1 +0,0 @@
target area: x=20..30, y=-10..-5

View file

@ -1,2 +0,0 @@
Player 1 starting position: 4
Player 2 starting position: 2

View file

@ -1,2 +0,0 @@
Player 1 starting position: 4
Player 2 starting position: 8

View file

@ -1,73 +0,0 @@
use std::fmt::Write;
use anyhow::Result;
const INPUT: &str = include_str!("../input/day01.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let measurements = input
.lines()
.map(|line| line.parse::<u64>().map_err(anyhow::Error::new))
.collect::<Result<Vec<_>>>()?;
Ok(count_increases(measurements.iter()))
}
fn count_increases<I, C>(numbers: I) -> usize
where
C: std::cmp::PartialOrd,
I: Iterator<Item = C> + Clone,
{
numbers
.clone()
.zip(numbers.skip(1))
.filter(|(a, b)| a < b)
.count()
}
fn part2(input: &str) -> Result<usize> {
let measurements = input
.lines()
.map(|line| line.parse::<u64>().map_err(anyhow::Error::new))
.collect::<Result<Vec<_>>>()?;
Ok(count_increases(
measurements.windows(3).map(|w| w.iter().sum::<u64>()),
))
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day01_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 7);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 1502);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 5);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 1538);
}
}

View file

@ -1,106 +0,0 @@
use std::fmt::Write;
use anyhow::{bail, Context, Result};
const INPUT: &str = include_str!("../input/day02.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let commands = input
.lines()
.map(str::parse::<Command>)
.collect::<Result<Vec<_>>>()?;
let mut horizontal_pos = 0;
let mut depth = 0;
for c in commands {
match c {
Command::Forward(dx) => horizontal_pos += dx,
Command::Up(dz) => depth -= dz,
Command::Down(dz) => depth += dz,
}
}
Ok(depth * horizontal_pos)
}
fn part2(input: &str) -> Result<u64> {
let commands = input
.lines()
.map(str::parse::<Command>)
.collect::<Result<Vec<_>>>()?;
let mut horizontal_pos = 0;
let mut depth = 0;
let mut aim = 0;
for c in commands {
match c {
Command::Forward(dx) => {
horizontal_pos += dx;
depth += aim * dx;
}
Command::Up(dz) => aim -= dz,
Command::Down(dz) => aim += dz,
}
}
Ok(depth * horizontal_pos)
}
enum Command {
Forward(u64),
Up(u64),
Down(u64),
}
impl std::str::FromStr for Command {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let (word, number) = s.split_once(' ').context("couldn't split command")?;
let number = number.parse()?;
Ok(match word {
"forward" => Self::Forward(number),
"up" => Self::Up(number),
"down" => Self::Down(number),
_ => bail!("unkown command"),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day02_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 150);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 1962940);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 900);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 1813664422);
}
}

View file

@ -1,164 +0,0 @@
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day03.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let binary_numbers: Vec<&str> = input.lines().collect();
// all binary numbers should have the same length
let size = binary_numbers[0].len();
let gamma = compute_gamma(&binary_numbers, size);
let epsilon = compute_epsilon(gamma, size);
Ok(gamma * epsilon)
}
/// Each bit in the gamma rate can be determined by finding the most common bit in the corresponding
/// position of all numbers in the diagnostic report.
fn compute_gamma(binary_numbers: &[&str], size: usize) -> u64 {
let mut gamma = 0;
for pos in 0..size {
let digit = u64::from(count_ones(binary_numbers, pos) > (binary_numbers.len() / 2));
gamma = (gamma << 1) | digit;
}
gamma
}
fn count_ones(binary_numbers: &[&str], pos: usize) -> usize {
binary_numbers
.iter()
.filter(|&&num| num.chars().nth(pos).unwrap() == '1')
.count()
}
/// The epsilon rate is calculated in a similar way; rather than use the most common bit, the least
/// common bit from each position is used.
///
/// We can just use flip every bit in gamma (respecting the size of the input)
fn compute_epsilon(gamma: u64, size: usize) -> u64 {
// mask 0b000000000000000011111111 with `size` 1s.
let shift = u64::BITS - (size as u32);
let mask = (u64::MAX << shift) >> shift;
(!gamma) & mask
}
fn part2(input: &str) -> Result<u64> {
let binary_numbers: Vec<&str> = input.lines().collect();
// all binary numbers should have the same length
let size = binary_numbers[0].len();
#[cfg(debug_assertions)]
binary_numbers.iter().for_each(|num| {
debug_assert_eq!(num.len(), size);
});
let oxygen_generator_rating = compute_oxygen_generator_rating(&binary_numbers, size)?;
let co2_scrubber_rating = compute_co2_scrubber_rating(&binary_numbers, size)?;
Ok(oxygen_generator_rating * co2_scrubber_rating)
}
fn filter_by_strat<Strat>(binary_numbers: &[&str], size: usize, strat: Strat) -> Result<u64>
where
Strat: Fn(bool) -> char,
{
let mut numbers = binary_numbers.to_vec();
for pos in 0..size {
if numbers.len() == 1 {
// only one number left, we're done!
break;
}
let one_is_more_common = count_ones(&numbers, pos) >= ((numbers.len() + 1) / 2);
let digit_of_interest = strat(one_is_more_common);
numbers.retain(|number| number.chars().nth(pos).unwrap() == digit_of_interest);
}
debug_assert_eq!(numbers.len(), 1);
u64::from_str_radix(numbers[0], 2).context("couldn't parse binary number")
}
/// To find oxygen generator rating, determine the most common value (0 or 1) in the current bit
/// position, and keep only numbers with that bit in that position. If 0 and 1 are equally common,
/// keep values with a 1 in the position being considered.
fn compute_oxygen_generator_rating(binary_numbers: &[&str], size: usize) -> Result<u64> {
filter_by_strat(binary_numbers, size, |one_is_more_common| {
if one_is_more_common {
'1'
} else {
'0'
}
})
}
/// To find CO2 scrubber rating, determine the least common value (0 or 1) in the current bit
/// position, and keep only numbers with that bit in that position. If 0 and 1 are equally
/// common, keep values with a 0 in the position being considered.
fn compute_co2_scrubber_rating(binary_numbers: &[&str], size: usize) -> Result<u64> {
filter_by_strat(binary_numbers, size, |one_is_more_common| {
if one_is_more_common {
'0'
} else {
'1'
}
})
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day03_provided.txt");
#[test]
fn part1_provided() {
let binary_numbers: Vec<&str> = PROVIDED.lines().collect();
let size = binary_numbers[0].len();
let gamma = compute_gamma(&binary_numbers, size);
assert_eq!(gamma, 22);
let epsilon = compute_epsilon(gamma, size);
assert_eq!(epsilon, 9);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 3429254);
}
#[test]
fn part2_provided() {
let binary_numbers: Vec<&str> = PROVIDED.lines().collect();
let size = binary_numbers[0].len();
let oxygen_generator_rating =
compute_oxygen_generator_rating(&binary_numbers, size).unwrap();
assert_eq!(oxygen_generator_rating, 23);
let co2_scrubber_rating = compute_co2_scrubber_rating(&binary_numbers, size).unwrap();
assert_eq!(co2_scrubber_rating, 10);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 5410338);
}
}

View file

@ -1,188 +0,0 @@
use std::collections::HashMap;
use std::fmt::Write;
use anyhow::{anyhow, Context, Result};
const INPUT: &str = include_str!("../input/day04.txt");
const GRID_WIDTH: usize = 5;
const GRID_HEIGHT: usize = 5;
const GRID_SIZE: usize = GRID_WIDTH * GRID_HEIGHT;
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let (draws, grids) = input
.split_once("\n\n")
.context("couldn't split draws from grids")?;
let draws = draws
.split(',')
.map(|num| num.parse::<u8>().context("couldn't parse drawn number:"))
.collect::<Result<Vec<_>>>()?;
let mut grids = grids
.split("\n\n")
.map(str::parse::<Grid>)
.collect::<Result<Vec<_>>>()?;
let (mut wdraw, mut wgrid) = (None, None);
'draw_loop: for draw in draws {
for grid in &mut grids {
grid.mark(draw);
if grid.is_winning() {
wgrid = Some(grid.clone());
wdraw = Some(draw);
break 'draw_loop;
}
}
}
match (wdraw, wgrid) {
(Some(draw), Some(grid)) => {
Ok(draw as u64 * grid.unmarked_numbers().map(|n| n as u64).sum::<u64>())
}
_ => Err(anyhow!("couldn't find a winning grid!")),
}
}
fn part2(input: &str) -> Result<u64> {
let (draws, grids) = input
.split_once("\n\n")
.context("couldn't split draws from grids")?;
let draws = draws
.split(',')
.map(|num| num.parse::<u8>().context("couldn't parse drawn number:"))
.collect::<Result<Vec<_>>>()?;
let mut grids = grids
.split("\n\n")
.map(str::parse::<Grid>)
.collect::<Result<Vec<_>>>()?;
let mut draws = draws.into_iter();
while grids.len() > 1 {
let draw = draws
.next()
.context("no draws available, didn't find last grid")?;
// TODO: replace with drain_filter when stabilized
grids.iter_mut().for_each(|grid| grid.mark(draw));
grids.retain(|grid| !grid.is_winning());
}
let last_grid = &mut grids[0];
for draw in draws {
last_grid.mark(draw);
if last_grid.is_winning() {
return Ok(draw as u64 * last_grid.unmarked_numbers().map(|n| n as u64).sum::<u64>());
}
}
Err(anyhow!("last grid never wins, this is not expected"))
}
#[derive(Debug, Clone)]
struct Grid {
number_to_pos: HashMap<u8, (usize, usize)>,
grid: [bool; GRID_SIZE],
rows: [u8; GRID_HEIGHT],
cols: [u8; GRID_WIDTH],
winning: bool,
}
impl Grid {
fn mark(&mut self, draw: u8) {
if let Some(&(x, y)) = self.number_to_pos.get(&draw) {
*self.access_grid_mut(x, y) = true;
self.rows[y] += 1;
self.cols[x] += 1;
self.winning =
self.rows[y] as usize == GRID_WIDTH || self.cols[x] as usize == GRID_HEIGHT;
}
}
fn is_winning(&self) -> bool {
self.winning
}
fn unmarked_numbers(&self) -> impl Iterator<Item = u8> + '_ {
self.number_to_pos
.iter()
.filter_map(|(num, &(x, y))| (!self.access_grid(x, y)).then_some(*num))
}
fn access_grid(&self, x: usize, y: usize) -> bool {
self.grid[y * GRID_HEIGHT + x]
}
fn access_grid_mut(&mut self, x: usize, y: usize) -> &mut bool {
&mut self.grid[y * GRID_HEIGHT + x]
}
}
impl std::str::FromStr for Grid {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut numbers = s.split_whitespace().map(str::parse);
let mut number_to_pos = HashMap::new();
for y in 0..GRID_HEIGHT {
for x in 0..GRID_WIDTH {
let pos = (x, y);
let number: u8 = numbers
.next()
.context("not enough numbers for grid")?
.context("couldn't parse number:")?;
number_to_pos.insert(number, pos);
}
}
Ok(Grid {
number_to_pos,
grid: [false; GRID_SIZE],
rows: [0; GRID_HEIGHT],
cols: [0; GRID_WIDTH],
winning: false,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day04_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 4512);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 45031);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 1924);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 2568);
}
}

View file

@ -1,177 +0,0 @@
use std::cmp::Ordering;
use std::collections::HashMap;
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day05.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let lines = input
.lines()
.map(str::parse::<Line>)
.collect::<Result<Vec<_>>>()?;
let mut grid = HashMap::new();
lines
.iter()
.filter(|l| l.is_horizontal() || l.is_vertical())
.for_each(|l| {
for cell in l.cells() {
*grid.entry(cell).or_insert(0) += 1;
}
});
Ok(grid.into_values().filter(|c| *c > 1).count())
}
fn part2(input: &str) -> Result<usize> {
let lines = input
.lines()
.map(str::parse::<Line>)
.collect::<Result<Vec<_>>>()?;
let mut grid = HashMap::new();
lines.iter().for_each(|l| {
for cell in l.cells() {
*grid.entry(cell).or_insert(0) += 1;
}
});
Ok(grid.into_values().filter(|c| *c > 1).count())
}
struct PointIterator {
current: (usize, usize),
to: (usize, usize),
dx: Ordering,
dy: Ordering,
done: bool,
}
impl PointIterator {
fn new(from: (usize, usize), to: (usize, usize)) -> Self {
Self {
current: from,
to,
dx: from.0.cmp(&to.0),
dy: from.1.cmp(&to.1),
done: false,
}
}
}
impl Iterator for PointIterator {
type Item = (usize, usize);
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let (x, y) = self.current;
if x == self.to.0 && y == self.to.1 {
self.done = true;
return Some((x, y));
}
match self.dx {
Ordering::Less => self.current.0 += 1,
Ordering::Greater => self.current.0 -= 1,
Ordering::Equal => {}
}
match self.dy {
Ordering::Less => self.current.1 += 1,
Ordering::Greater => self.current.1 -= 1,
Ordering::Equal => {}
}
Some((x, y))
}
}
#[derive(Debug)]
struct Line {
from: (usize, usize),
to: (usize, usize),
}
impl Line {
fn is_horizontal(&self) -> bool {
self.to.1 == self.from.1
}
fn is_vertical(&self) -> bool {
self.to.0 == self.from.0
}
fn cells(&self) -> impl Iterator<Item = (usize, usize)> {
PointIterator::new(self.from, self.to)
}
}
impl std::str::FromStr for Line {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let (from, to) = s
.split_once(" -> ")
.context("couldn't parse line: missing ` -> `")?;
let from = {
let (x, y) = from
.split_once(',')
.context("couldn't parse line origin: missing `,`")?;
(x.parse()?, y.parse()?)
};
let to = {
let (x, y) = to
.split_once(',')
.context("couldn't parse line end: missing `,`")?;
(x.parse()?, y.parse()?)
};
Ok(Line { from, to })
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day05_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 5);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 4745);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 12);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 18442);
}
}

View file

@ -1,101 +0,0 @@
use std::collections::VecDeque;
use std::fmt::Write;
use std::str;
use anyhow::Result;
const INPUT: &str = include_str!("../input/day06.txt");
const SPAWNING_DELAY: usize = 7;
const TURNS_PART_1: usize = 80;
const TURNS_PART_2: usize = 256;
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let mut school = input.trim().parse::<School>()?;
Ok(school.grow_for(TURNS_PART_1))
}
fn part2(input: &str) -> Result<usize> {
let mut school = input.trim().parse::<School>()?;
Ok(school.grow_for(TURNS_PART_2))
}
struct School {
fish_timers: VecDeque<usize>,
}
impl School {
fn next_turn(&mut self) {
let newly_spawned = self.fish_timers[0];
self.fish_timers.rotate_left(1);
self.fish_timers[SPAWNING_DELAY - 1] += newly_spawned;
}
fn size(&self) -> usize {
self.fish_timers.iter().sum()
}
fn grow_for(&mut self, turns: usize) -> usize {
for _ in 0..turns {
self.next_turn();
}
self.size()
}
}
impl std::str::FromStr for School {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut fish_timers = [0usize; SPAWNING_DELAY + 2];
for fish in s.split(',').map(str::parse::<usize>) {
fish_timers[fish?] += 1;
}
Ok(School {
fish_timers: fish_timers.into(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day06_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 5934);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 350149);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 26984457539);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 1590327954513);
}
}

View file

@ -1,169 +0,0 @@
use std::fmt::Write;
use anyhow::{Context, Result};
use rand::Rng;
const INPUT: &str = include_str!("../input/day07.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let mut horizontal_positions = input
.trim()
.split(',')
.map(|n| n.parse::<u64>().context("couldn't parse position"))
.collect::<Result<Vec<_>>>()?;
let median_rank = horizontal_positions.len() / 2;
let median = selection(&mut horizontal_positions, median_rank);
Ok(horizontal_positions
.iter()
// TODO: use abs_diff when stabilized
.map(|n| abs_diff(*n, median))
.sum())
}
fn selection<T>(data: &mut [T], i: usize) -> T
where
T: Copy + Ord,
{
if data.len() == 1 {
return data[0];
}
let mid = random_partition(data);
if i < mid {
selection(&mut data[..mid], i)
} else {
selection(&mut data[mid..], i - mid)
}
}
fn random_partition<T>(data: &mut [T]) -> usize
where
T: Copy + Ord,
{
let pivot_index = rand::thread_rng().gen_range(0..data.len());
let pivot = data[pivot_index];
let mut i = 0;
let mut j = data.len() - 1;
loop {
while data[i] < pivot {
i += 1;
}
while data[j] > pivot {
j -= 1;
}
if i >= j {
return usize::max(i, 1);
}
data.swap(i, j);
i += 1;
j -= 1;
}
}
fn part2(input: &str) -> Result<u64> {
let horizontal_positions = input
.trim()
.split(',')
.map(|n| n.parse::<u64>().context("couldn't parse position"))
.collect::<Result<Vec<_>>>()?;
let min = *horizontal_positions.iter().min().unwrap();
let max = *horizontal_positions.iter().max().unwrap();
let optimal_distance = minimize_binary_search(&horizontal_positions, min, max, part2_distance);
let minimum_fuel = horizontal_positions
.iter()
.map(|n| part2_distance(*n, optimal_distance))
.sum::<u64>();
Ok(minimum_fuel)
}
fn minimize_binary_search<F>(positions: &[u64], min: u64, max: u64, distance: F) -> u64
where
F: Fn(u64, u64) -> u64,
{
if min == max {
return min;
}
let mid1 = min + (max - min) / 2;
let mid2 = mid1 + 1;
let (cost1, cost2) = positions
.iter()
.map(|n| (distance(*n, mid1), distance(*n, mid2)))
.reduce(|(sum1, sum2), (x1, x2)| (sum1 + x1, sum2 + x2))
.unwrap();
if cost1 < cost2 {
minimize_binary_search(positions, min, mid1, distance)
} else {
minimize_binary_search(positions, mid2, max, distance)
}
}
fn abs_diff(a: u64, b: u64) -> u64 {
a.max(b) - a.min(b)
}
fn part2_distance(a: u64, b: u64) -> u64 {
let distance = abs_diff(a, b);
distance * (distance + 1) / 2
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day07_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 37);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 340056);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 168);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 96592275);
}
#[test]
fn test_selection() {
for _ in 0..4200 {
for i in 0..=9 {
let mut data = vec![9, 2, 7, 3, 5, 4, 6, 1, 8, 0];
let res = selection(&mut data, i);
assert_eq!(res, i);
}
}
}
}

View file

@ -1,212 +0,0 @@
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day08.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let entries = input
.lines()
.map(TryInto::try_into)
.collect::<Result<Vec<Entry>>>()?;
Ok(entries.iter().map(Entry::count_easy_digits_in_output).sum())
}
fn part2(input: &str) -> Result<u64> {
let entries = input
.lines()
.map(TryInto::try_into)
.collect::<Result<Vec<Entry>>>()?;
let mut sum = 0;
for entry in entries {
let mapping = entry.compute_mapping()?;
sum += entry.decode_output(&mapping)?;
}
Ok(sum)
}
struct Entry<'a> {
four_digits_output: Vec<&'a str>,
unique_signals: Vec<&'a str>,
}
impl<'a> Entry<'a> {
fn count_easy_digits_in_output(&self) -> usize {
self.four_digits_output
.iter()
.filter_map(|digit| Self::translate_easy_digit(digit))
.count()
}
fn translate_easy_digit(digit: &str) -> Option<u64> {
match digit.len() {
2 => Some(1),
3 => Some(7),
4 => Some(4),
7 => Some(8),
_ => None,
}
}
fn compute_mapping(&self) -> Result<Vec<(&'a str, u64)>> {
let mut mapping = Vec::new();
// first, let's get the easy digits
let easy_digits: Vec<(&str, u64)> = self
.unique_signals
.iter()
.filter_map(|signal| Some(*signal).zip(Self::translate_easy_digit(signal)))
.collect();
// now we can get `9` for free: it's the signal that uses 6 segments and has 4 in common
// with the digit `4` (`6` and `0` also use 6 segments, but only have 3 segments in common
// with `4`).
let (four, _) = *easy_digits
.iter()
.find(|(_, translation)| *translation == 4)
.context("no signal found for the digit 4!")?;
let nine = *self
.unique_signals
.iter()
.filter(|signal| signal.len() == 6)
.find(|signal| four.chars().all(|c| signal.contains(c)))
.context("couldn't identify any signal corresponding to the digit 9!")?;
mapping.push((nine, 9));
// `0` has 2 segments in common with `1`, while `6` only has 1.
let (one, _) = *easy_digits
.iter()
.find(|(_, translation)| *translation == 1)
.context("no signal found for the digit 1!")?;
let zero = *self
.unique_signals
.iter()
.filter(|&signal| signal.len() == 6)
.filter(|&signal| *signal != nine)
.find(|signal| one.chars().all(|c| signal.contains(c)))
.context("couldn't identify any signal corresponding to the digit 0!")?;
mapping.push((zero, 0));
// `6` is an easy one now, the only other signal with 6 segments, that isn't nine or zero.
let six = *self
.unique_signals
.iter()
.filter(|signal| signal.len() == 6)
.find(|&signal| *signal != nine && *signal != zero)
.context("couldn't identify any signal corresponding to the digit 6!")?;
mapping.push((six, 6));
// `2`, `3` and `5` have 5 segments each.
//
// `3` has 2 segments in common with `1`.
let three = *self
.unique_signals
.iter()
.filter(|signal| signal.len() == 5)
.find(|signal| one.chars().all(|c| signal.contains(c)))
.context("couldn't identify any signal corresponding to the digit 3!")?;
mapping.push((three, 3));
// `5` has all its segments used in `6`, `2` doesn't.
let five = *self
.unique_signals
.iter()
.filter(|signal| signal.len() == 5)
.find(|signal| signal.chars().all(|c| six.contains(c)))
.context("couldn't identify any signal corresponding to the digit 5!")?;
mapping.push((five, 5));
// `2` is the last one!
let two = self
.unique_signals
.iter()
.filter(|signal| signal.len() == 5)
.find(|&signal| *signal != five && *signal != three)
.context("couldn't identify any signal corresponding to the digit 2!")?;
mapping.push((two, 2));
debug_assert_eq!(mapping.len(), 6);
Ok(mapping)
}
fn decode_output(&self, digit_mapping: &[(&str, u64)]) -> Result<u64> {
let mut res = 0;
for digit in &self.four_digits_output {
// search is kind of ugly, but having to sort everything is probably time consuming as
// well.
let digit = if let Some(translation) = Self::translate_easy_digit(digit) {
translation
} else {
*digit_mapping
.iter()
.find_map(|(signal, translation)| {
if digit.len() == signal.len() && digit.chars().all(|c| signal.contains(c))
{
Some(translation)
} else {
None
}
})
.with_context(|| format!("couldn't translate digit `{}`", digit))?
};
res = (res * 10) + digit;
}
Ok(res)
}
}
impl<'a> TryFrom<&'a str> for Entry<'a> {
type Error = anyhow::Error;
fn try_from(s: &'a str) -> Result<Self, Self::Error> {
let (signals, output) = s.split_once(" | ").context("couldn't split on ` | `")?;
Ok(Self {
four_digits_output: output.trim().split(' ').collect(),
unique_signals: signals.trim().split(' ').collect(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day08_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 26);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 488);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 61229);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 1040429);
}
}

View file

@ -1,184 +0,0 @@
use std::collections::HashSet;
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day09.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let height_map: HeightMap = input.parse()?;
Ok(height_map
.low_points()
.map(|(x, y)| height_map.risk_level(x, y))
.sum())
}
fn part2(input: &str) -> Result<u64> {
let mut height_map: HeightMap = input.parse()?;
let low_points: Vec<_> = height_map.low_points().collect();
let mut bassin_sizes: Vec<_> = low_points
.iter()
.map(|&(x, y)| height_map.fill_basin(x, y))
.collect();
bassin_sizes.sort_unstable();
bassin_sizes
.iter()
.copied()
.skip(bassin_sizes.len() - 3)
.reduce(|acc, elem| acc * elem)
.context("couldn't find 3 bassins")
}
#[derive(Clone, Copy)]
enum Neighbour {
Up,
Down,
Left,
Right,
}
impl Neighbour {
fn apply(&self, x: usize, y: usize, width: usize, height: usize) -> Option<(usize, usize)> {
match self {
Neighbour::Left if x > 0 => Some((x - 1, y)),
Neighbour::Right if x < width - 1 => Some((x + 1, y)),
Neighbour::Up if y > 0 => Some((x, y - 1)),
Neighbour::Down if y < height - 1 => Some((x, y + 1)),
_ => None,
}
}
const ALL: &'static [Self] = &[
Neighbour::Left,
Neighbour::Right,
Neighbour::Up,
Neighbour::Down,
];
}
#[derive(Debug)]
struct HeightMap {
heights: Vec<u8>,
width: usize,
height: usize,
filled_points: HashSet<(usize, usize)>,
}
impl HeightMap {
fn fill_basin(&mut self, x: usize, y: usize) -> u64 {
if self.get(x, y) == 9 {
return 0;
}
if self.filled_points.contains(&(x, y)) {
return 0;
}
self.filled_points.insert((x, y));
self.neighbours(x, y)
.map(|(nx, ny)| self.fill_basin(nx, ny))
.sum::<u64>()
+ 1
}
fn low_points(&self) -> impl Iterator<Item = (usize, usize)> + '_ {
(0..self.height)
.flat_map(|y| (0..self.width).map(move |x| (x, y)))
.filter(|&(x, y)| {
self.neighbours(x, y)
.all(|(nx, ny)| self.get(x, y) < self.get(nx, ny))
})
}
fn neighbours(&self, x: usize, y: usize) -> impl Iterator<Item = (usize, usize)> + 'static {
let width = self.width;
let height = self.height;
Neighbour::ALL
.iter()
.copied()
.filter_map(move |neighbour| neighbour.apply(x, y, width, height))
}
fn risk_level(&self, x: usize, y: usize) -> u64 {
self.get(x, y) as u64 + 1
}
fn get(&self, x: usize, y: usize) -> u8 {
self.heights[y * self.width + x]
}
}
impl std::str::FromStr for HeightMap {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut heights = Vec::new();
let mut height = 0;
let mut width = None;
for line in s.lines().map(str::trim) {
let line = line
.chars()
.map(|chr| {
chr.to_digit(10)
.map(|digit| digit as u8)
.with_context(|| format!("cannot parse char {} to digit", chr))
})
.collect::<Result<Vec<_>>>()?;
if width.is_none() {
width = Some(line.len());
}
height += 1;
heights.extend_from_slice(&line);
}
Ok(HeightMap {
heights,
width: width.context("0 lines parsed, width never computed")?,
height,
filled_points: HashSet::new(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day09_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 15);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 522);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 1134);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 916688);
}
}

View file

@ -1,181 +0,0 @@
use std::fmt::Write;
use anyhow::{bail, Result};
const INPUT: &str = include_str!("../input/day10.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let lines = input
.lines()
.map(str::parse::<Line>)
.collect::<Result<Vec<_>>>()?;
Ok(lines.iter().filter_map(Line::syntax_checking_score).sum())
}
fn part2(input: &str) -> Result<u64> {
let lines = input
.lines()
.map(str::parse::<Line>)
.collect::<Result<Vec<_>>>()?;
let mut scores: Vec<u64> = lines.iter().filter_map(Line::completion_score).collect();
scores.sort_unstable();
debug_assert!(scores.len() % 2 == 1);
Ok(scores[scores.len() / 2])
}
enum SymbolState {
Open(Symbol),
Close(Symbol),
}
impl TryFrom<char> for SymbolState {
type Error = anyhow::Error;
fn try_from(value: char) -> Result<Self> {
match value {
'(' | '[' | '{' | '<' => Ok(SymbolState::Open(value.try_into().unwrap())),
')' | ']' | '}' | '>' => Ok(SymbolState::Close(value.try_into().unwrap())),
_ => bail!("invalid char for symbol"),
}
}
}
#[derive(PartialEq, Eq)]
enum Symbol {
Parenthesis, // ()
Bracket, // []
Brace, // {}
AngleBracket, // <>
}
impl Symbol {
fn syntax_checking_score(&self) -> u64 {
match self {
Symbol::Parenthesis => 3,
Symbol::Bracket => 57,
Symbol::Brace => 1197,
Symbol::AngleBracket => 25137,
}
}
fn completion_score(&self) -> u64 {
match self {
Symbol::Parenthesis => 1,
Symbol::Bracket => 2,
Symbol::Brace => 3,
Symbol::AngleBracket => 4,
}
}
}
impl TryFrom<char> for Symbol {
type Error = anyhow::Error;
fn try_from(value: char) -> Result<Self> {
match value {
'(' | ')' => Ok(Symbol::Parenthesis),
'[' | ']' => Ok(Symbol::Bracket),
'{' | '}' => Ok(Symbol::Brace),
'<' | '>' => Ok(Symbol::AngleBracket),
_ => bail!("invalid char for symbol"),
}
}
}
struct Line {
symbols: Vec<SymbolState>,
}
impl Line {
fn syntax_checking_score(&self) -> Option<u64> {
let mut stack = Vec::new();
for state in &self.symbols {
match state {
SymbolState::Open(symbol) => stack.push(symbol),
SymbolState::Close(symbol) => match stack.pop() {
Some(other_symbol) if symbol == other_symbol => continue,
_ => return Some(symbol.syntax_checking_score()),
},
}
}
None
}
fn completion_score(&self) -> Option<u64> {
let mut stack = Vec::new();
for state in &self.symbols {
match state {
SymbolState::Open(symbol) => stack.push(symbol),
SymbolState::Close(symbol) => match stack.pop() {
Some(other_symbol) if symbol == other_symbol => continue,
_ => return None, // ignore corrupt line
},
}
}
let mut score = 0;
for symbol in stack.into_iter().rev() {
score = score * 5 + symbol.completion_score();
}
Some(score)
}
}
impl std::str::FromStr for Line {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
Ok(Line {
symbols: s
.trim()
.chars()
.map(TryFrom::try_from)
.collect::<Result<Vec<_>>>()?,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day10_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 26397);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 394647);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 288957);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 2380061249);
}
}

View file

@ -1,236 +0,0 @@
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day11.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let mut grid: OctopusGrid = input.parse()?;
Ok((0..100).map(|_| grid.step()).sum())
}
fn part2(input: &str) -> Result<usize> {
let mut grid: OctopusGrid = input.parse()?;
let (_, step) = (0..)
.map(|step| (grid.step(), step))
.find(|(flashes, _)| *flashes == 100)
.context("never reached step where octopuses all flashed simultaneously")?;
Ok(step + 1)
}
#[derive(Clone, Copy, Debug)]
struct Octopus {
energy_level: u8,
has_flashed: bool,
}
impl Octopus {
fn increment_energy_level(&mut self) {
self.energy_level += 1;
}
fn reset_energy_level(&mut self) {
if self.has_flashed {
self.energy_level = 0;
self.has_flashed = false;
}
}
fn flashes(&mut self) -> bool {
if self.energy_level > 9 && !self.has_flashed {
self.has_flashed = true;
return true;
}
false
}
}
impl TryFrom<char> for Octopus {
type Error = anyhow::Error;
fn try_from(value: char) -> Result<Self> {
Ok(Octopus {
energy_level: value
.to_digit(10)
.with_context(|| format!("couldn't convert char `{}` to digit", value))?
as u8,
has_flashed: false,
})
}
}
#[derive(Clone, Copy)]
enum Neighbour {
Up,
Down,
Left,
Right,
UpperLeft,
UpperRight,
LowerLeft,
LowerRight,
}
impl Neighbour {
fn apply(&self, x: usize, y: usize, width: usize, height: usize) -> Option<(usize, usize)> {
match self {
Neighbour::Left if x > 0 => Some((x - 1, y)),
Neighbour::Right if x < width - 1 => Some((x + 1, y)),
Neighbour::Up if y > 0 => Some((x, y - 1)),
Neighbour::Down if y < height - 1 => Some((x, y + 1)),
Neighbour::UpperLeft => Neighbour::Left
.apply(x, y, width, height)
.and_then(|(x, y)| Neighbour::Up.apply(x, y, width, height)),
Neighbour::UpperRight => Neighbour::Right
.apply(x, y, width, height)
.and_then(|(x, y)| Neighbour::Up.apply(x, y, width, height)),
Neighbour::LowerLeft => Neighbour::Left
.apply(x, y, width, height)
.and_then(|(x, y)| Neighbour::Down.apply(x, y, width, height)),
Neighbour::LowerRight => Neighbour::Right
.apply(x, y, width, height)
.and_then(|(x, y)| Neighbour::Down.apply(x, y, width, height)),
_ => None,
}
}
const ALL: &'static [Self] = &[
Neighbour::Left,
Neighbour::Right,
Neighbour::Up,
Neighbour::Down,
Neighbour::UpperLeft,
Neighbour::UpperRight,
Neighbour::LowerLeft,
Neighbour::LowerRight,
];
}
#[derive(Debug)]
struct OctopusGrid {
octopuses: Vec<Octopus>,
width: usize,
height: usize,
}
impl OctopusGrid {
fn neighbours(&self, x: usize, y: usize) -> impl Iterator<Item = (usize, usize)> + 'static {
let width = self.width;
let height = self.height;
Neighbour::ALL
.iter()
.copied()
.filter_map(move |neighbour| neighbour.apply(x, y, width, height))
}
fn get_mut(&mut self, x: usize, y: usize) -> &mut Octopus {
&mut self.octopuses[y * self.width + x]
}
fn step(&mut self) -> usize {
// First, the energy level of each octopus increases by 1.
self.octopuses
.iter_mut()
.for_each(Octopus::increment_energy_level);
// Then, any octopus with an energy level greater than 9 flashes. This increases the energy
// level of all adjacent octopuses by 1, including octopuses that are diagonally adjacent.
// If this causes an octopus to have an energy level greater than 9, it also flashes. This
// process continues as long as new octopuses keep having their energy level increased
// beyond 9. (An octopus can only flash at most once per step.)
let mut flashed = true;
let mut flashes = 0;
while flashed {
flashed = false;
for index in 0..self.octopuses.len() {
if self.octopuses[index].flashes() {
let (x, y) = (index % self.width, index / self.width);
for (x, y) in self.neighbours(x, y) {
self.get_mut(x, y).increment_energy_level();
}
flashed = true;
flashes += 1;
}
}
}
// Finally, any octopus that flashed during this step has its energy level set to 0, as it
// used all of its energy to flash.
self.octopuses
.iter_mut()
.for_each(Octopus::reset_energy_level);
flashes
}
}
impl std::str::FromStr for OctopusGrid {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut octopuses = Vec::new();
let mut height = 0;
let mut width = None;
for line in s.lines().map(str::trim) {
let octopus_line = line
.chars()
.map(TryFrom::try_from)
.collect::<Result<Vec<_>>>()?;
if width.is_none() {
width = Some(octopus_line.len());
}
height += 1;
octopuses.extend_from_slice(&octopus_line);
}
Ok(OctopusGrid {
octopuses,
width: width.context("0 lines parsed, width never computed")?,
height,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day11_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 1656);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 1588);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 195);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 517);
}
}

View file

@ -1,199 +0,0 @@
use std::collections::{HashMap, HashSet};
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day12.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let cave_map: CaveMap = input.try_into()?;
cave_map.count_paths()
}
fn part2(input: &str) -> Result<usize> {
let cave_map: CaveMap = input.try_into()?;
cave_map.count_paths_twice()
}
#[derive(Clone, Copy)]
struct Cave<'a> {
name: &'a str,
small: bool,
}
impl<'a> Cave<'a> {
fn is_end(&self) -> bool {
self.name == "end"
}
fn is_start(&self) -> bool {
self.name == "start"
}
fn is_small(&self) -> bool {
self.small
}
}
impl<'a> From<&'a str> for Cave<'a> {
fn from(s: &'a str) -> Self {
Cave {
name: s,
small: s.chars().all(char::is_lowercase),
}
}
}
impl<'a> std::hash::Hash for Cave<'a> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}
impl<'a> std::cmp::PartialEq for Cave<'a> {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl<'a> std::cmp::Eq for Cave<'a> {}
struct CaveMap<'a> {
connections: HashMap<Cave<'a>, Vec<Cave<'a>>>,
}
impl<'a> CaveMap<'a> {
fn count_paths(&self) -> Result<usize> {
let start = *self
.connections
.keys()
.find(|cave| cave.is_start())
.context("couldn't find starting cave")?;
Ok(self.count_paths_rec(start, HashSet::new()))
}
fn count_paths_rec(&self, from: Cave<'a>, mut small_seen: HashSet<Cave<'a>>) -> usize {
if from.is_end() {
return 1;
}
if from.is_small() {
if small_seen.contains(&from) {
return 0;
}
small_seen.insert(from);
}
let mut paths = 0;
for dst in &self.connections[&from] {
paths += self.count_paths_rec(*dst, small_seen.clone());
}
paths
}
fn count_paths_twice(&self) -> Result<usize> {
let start = *self
.connections
.keys()
.find(|cave| cave.is_start())
.context("couldn't find starting cave")?;
Ok(self.count_paths_twice_rec(start, HashSet::new(), false))
}
fn count_paths_twice_rec(
&self,
from: Cave<'a>,
mut small_seen: HashSet<Cave<'a>>,
visited_twice: bool,
) -> usize {
if from.is_end() {
return 1;
}
if from.is_small() {
small_seen.insert(from);
}
let mut paths = 0;
for dst in &self.connections[&from] {
let will_visit_twice = small_seen.contains(dst) && dst.is_small();
if will_visit_twice && (visited_twice || dst.is_start()) {
continue;
}
paths += self.count_paths_twice_rec(
*dst,
small_seen.clone(),
visited_twice || will_visit_twice,
);
}
paths
}
}
impl<'a> TryFrom<&'a str> for CaveMap<'a> {
type Error = anyhow::Error;
fn try_from(s: &'a str) -> Result<Self> {
let mut map = HashMap::new();
for line in s.lines().map(str::trim) {
let (src, dst) = line
.split_once('-')
.context("couldn't parse cave connection")?;
map.entry(src.into())
.or_insert_with(Vec::new)
.push(dst.into());
map.entry(dst.into())
.or_insert_with(Vec::new)
.push(src.into());
}
Ok(CaveMap { connections: map })
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED1: &str = include_str!("../input/day12_provided1.txt");
const PROVIDED2: &str = include_str!("../input/day12_provided2.txt");
const PROVIDED3: &str = include_str!("../input/day12_provided3.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED1).unwrap(), 10);
assert_eq!(part1(PROVIDED2).unwrap(), 19);
assert_eq!(part1(PROVIDED3).unwrap(), 226);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 5252);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED1).unwrap(), 36);
assert_eq!(part2(PROVIDED2).unwrap(), 103);
assert_eq!(part2(PROVIDED3).unwrap(), 3509);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 147784);
}
}

View file

@ -1,210 +0,0 @@
use std::collections::HashSet;
use std::fmt::Write;
use anyhow::{anyhow, Context, Result};
const INPUT: &str = include_str!("../input/day13.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let (sheet, fold_instructions) = input.split_once("\n\n").context("couldn't split input")?;
let mut sheet: PaperSheet = sheet.parse()?;
let fold_instructions: Vec<FoldInstruction> = fold_instructions
.lines()
.map(|l| l.trim().parse())
.collect::<Result<_>>()?;
sheet.apply(
*fold_instructions
.first()
.context("had 0 fold instructions")?,
);
Ok(sheet.num_points())
}
fn part2(input: &str) -> Result<String> {
let (sheet, fold_instructions) = input.split_once("\n\n").context("couldn't split input")?;
let mut sheet: PaperSheet = sheet.parse()?;
let fold_instructions: Vec<FoldInstruction> = fold_instructions
.lines()
.map(|l| l.trim().parse())
.collect::<Result<_>>()?;
for instr in fold_instructions {
sheet.apply(instr);
}
Ok(format!("{}", sheet))
}
struct PaperSheet {
points: HashSet<(usize, usize)>,
}
impl PaperSheet {
fn apply(&mut self, instr: FoldInstruction) {
let mut to_insert = Vec::new();
let mut to_remove = Vec::new();
for point in &self.points {
match instr {
FoldInstruction::AlongX(x) => {
if point.0 <= x {
continue;
}
let new_point = (x - (point.0 - x), point.1);
to_insert.push(new_point);
to_remove.push(*point);
}
FoldInstruction::AlongY(y) => {
if point.1 <= y {
continue;
}
let new_point = (point.0, y - (point.1 - y));
to_insert.push(new_point);
to_remove.push(*point);
}
}
}
to_remove.iter().for_each(|point| {
self.points.remove(point);
});
to_insert.into_iter().for_each(|point| {
self.points.insert(point);
});
}
fn num_points(&self) -> usize {
self.points.len()
}
}
impl std::fmt::Display for PaperSheet {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// make sure first row appears on its own line
writeln!(f)?;
if self.points.is_empty() {
return writeln!(f, "`empty paper sheet`");
}
let (width, _) = self.points.iter().max_by_key(|point| point.0).unwrap();
let (_, height) = self.points.iter().max_by_key(|point| point.1).unwrap();
for y in 0..=*height {
for x in 0..=*width {
let chr = if self.points.contains(&(x, y)) {
'#'
} else {
'.'
};
f.write_char(chr)?;
}
writeln!(f)?;
}
Ok(())
}
}
impl std::str::FromStr for PaperSheet {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut points = HashSet::new();
for l in s.lines() {
let (x, y) = l
.trim()
.split_once(',')
.context("couldn't parse paper sheet point coordinate")?;
let (x, y) = (x.parse()?, y.parse()?);
points.insert((x, y));
}
Ok(PaperSheet { points })
}
}
#[derive(Clone, Copy)]
enum FoldInstruction {
AlongX(usize),
AlongY(usize),
}
impl std::str::FromStr for FoldInstruction {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let (axis, coord) = s
.split_once('=')
.context("couldn't parse folding instruction")?;
let coord = coord.parse()?;
match axis {
"fold along x" => Ok(FoldInstruction::AlongX(coord)),
"fold along y" => Ok(FoldInstruction::AlongY(coord)),
_ => Err(anyhow!("couldn't parse folding instruction")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day13_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 17);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 753);
}
#[test]
fn part2_provided() {
assert_eq!(
part2(PROVIDED).unwrap(),
"
#####
#...#
#...#
#...#
#####
"
);
}
#[test]
fn part2_real() {
assert_eq!(
part2(INPUT).unwrap(),
"
#..#.####.#....####.#..#...##.###..#..#
#..#....#.#....#....#..#....#.#..#.#.#.
####...#..#....###..####....#.#..#.##..
#..#..#...#....#....#..#....#.###..#.#.
#..#.#....#....#....#..#.#..#.#.#..#.#.
#..#.####.####.####.#..#..##..#..#.#..#
"
);
}
}

View file

@ -1,173 +0,0 @@
use std::collections::HashMap;
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day14.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let (polymer, rules) = input.split_once("\n\n").context("couldn't split input")?;
let mut polymer: Polymer = polymer.parse()?;
let rules: Rules = rules.parse()?;
for _ in 0..10 {
polymer.insert_pairs(&rules.0)?;
}
let occurrences = polymer.compute_occurrences();
let (_, least_common_occurrences) = occurrences
.iter()
.min_by_key(|&(_, occurrences)| occurrences)
.unwrap();
let (_, most_common_occurrences) = occurrences
.iter()
.max_by_key(|&(_, occurrences)| occurrences)
.unwrap();
Ok(most_common_occurrences - least_common_occurrences)
}
fn part2(input: &str) -> Result<usize> {
let (polymer, rules) = input.split_once("\n\n").context("couldn't split input")?;
let mut polymer: Polymer = polymer.parse()?;
let rules: Rules = rules.parse()?;
for _ in 0..40 {
polymer.insert_pairs(&rules.0)?;
}
let occurrences = polymer.compute_occurrences();
let (_, least_common_occurrences) = occurrences
.iter()
.min_by_key(|&(_, occurrences)| occurrences)
.unwrap();
let (_, most_common_occurrences) = occurrences
.iter()
.max_by_key(|&(_, occurrences)| occurrences)
.unwrap();
Ok(most_common_occurrences - least_common_occurrences)
}
struct Rules(HashMap<(u8, u8), u8>);
impl std::str::FromStr for Rules {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
Ok(Self(
s.lines()
.map(str::trim)
.map(|l| {
let (pair, res) = l.split_once(" -> ").context("couldn't parse rule")?;
Ok((
(
*pair.as_bytes().first().context("couldn't parse rule")?,
*pair.as_bytes().get(1).context("couldn't parse rule")?,
),
res.bytes().next().context("couldn't parse rule")?,
))
})
.collect::<Result<_>>()?,
))
}
}
#[derive(Debug)]
struct Polymer {
molecules: HashMap<(u8, u8), usize>,
first: u8,
last: u8,
}
impl Polymer {
fn insert_pairs(&mut self, rules: &HashMap<(u8, u8), u8>) -> Result<()> {
let mut new_molecules = HashMap::new();
for (&(a, b), &count) in &self.molecules {
let middle = *rules
.get(&(a, b))
.with_context(|| format!("couldn't find rule for pair ({}, {})", a, b))?;
*new_molecules.entry((a, middle)).or_insert(0) += count;
*new_molecules.entry((middle, b)).or_insert(0) += count;
}
self.molecules = new_molecules;
Ok(())
}
fn compute_occurrences(&self) -> Vec<(u8, usize)> {
let mut counts = HashMap::new();
for (&(a, b), &count) in &self.molecules {
*counts.entry(a).or_insert(0) += count;
*counts.entry(b).or_insert(0) += count;
}
// the first and last molecule are only counted once, all other molecules are counted twice
*counts.entry(self.first).or_insert(0) += 1;
*counts.entry(self.last).or_insert(0) += 1;
counts
.into_iter()
.map(|(m, count)| (m, count / 2))
.collect()
}
}
impl std::str::FromStr for Polymer {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut molecules = HashMap::new();
s.as_bytes()
.windows(2)
.for_each(|w| *molecules.entry((w[0], w[1])).or_insert(0) += 1);
Ok(Polymer {
molecules,
first: *s.as_bytes().first().context("polymer was empty")?,
last: *s.as_bytes().last().context("polymer was empty")?,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day14_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 1588);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 3247);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 2188189693529);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 4110568157153);
}
}

View file

@ -1,218 +0,0 @@
use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::fmt::Write;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day15.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let cavern: CavernMap = input.parse()?;
let lowest_risk = cavern.lowest_risk_path();
Ok(lowest_risk)
}
fn part2(input: &str) -> Result<u64> {
let cavern: CavernMap = input.parse()?;
let cavern = cavern.bigger();
let lowest_risk = cavern.lowest_risk_path();
Ok(lowest_risk)
}
#[derive(Debug)]
struct CavernMap {
height: usize,
width: usize,
risk: Vec<u64>,
}
impl CavernMap {
// typical Dijkstra implementation, using a binary heap as a priority queue
fn lowest_risk_path(&self) -> u64 {
let mut visited = Vec::new();
visited.resize(self.height * self.width, false);
let mut total_risk = Vec::new();
total_risk.resize(self.height * self.width, u64::MAX);
total_risk[self.index(0, 0)] = 0;
let mut queue = BinaryHeap::new();
queue.push(Reverse((0, (0, 0))));
while !queue.is_empty() {
let Reverse((curr_risk, (x, y))) = queue.pop().unwrap();
debug_assert_eq!(curr_risk, total_risk[self.index(x, y)]);
if (x, y) == (self.width - 1, self.height - 1) {
// reached destination, we're done!
break;
}
if visited[self.index(x, y)] {
// duplicate entry in queue, discard
continue;
}
visited[self.index(x, y)] = true;
for (nx, ny) in self.neighbours(x, y) {
let neighbour_index = self.index(nx, ny);
let old_risk = total_risk[neighbour_index];
let new_risk = curr_risk + self.risk[neighbour_index];
if new_risk < old_risk {
total_risk[neighbour_index] = new_risk;
// we don't delete older queue entries for the same cell, if we find them later
// on we can just skip them because they're marked as visited already
queue.push(Reverse((new_risk, (nx, ny))));
}
}
}
*total_risk.last().unwrap()
}
fn neighbours(&self, x: usize, y: usize) -> impl Iterator<Item = (usize, usize)> + 'static {
let width = self.width;
let height = self.height;
Neighbour::ALL
.iter()
.copied()
.filter_map(move |neighbour| neighbour.apply(x, y, width, height))
}
fn index(&self, x: usize, y: usize) -> usize {
y * self.width + x
}
fn bigger(self) -> Self {
let width = self.width * 5;
let height = self.height * 5;
let mut risk = self.risk.clone();
risk.resize(width * height, 0);
for shift_y in 0..5 {
for shift_x in 0..5 {
for y in 0..self.height {
for x in 0..self.width {
let new_y = shift_y * self.height + y;
let new_x = shift_x * self.width + x;
let new_index = new_y * width + new_x;
let old_risk = self.risk[self.index(x, y)];
let mut new_risk = old_risk + shift_x as u64 + shift_y as u64;
if new_risk > 9 {
new_risk -= 9;
}
risk[new_index] = new_risk;
}
}
}
}
Self {
height,
width,
risk,
}
}
}
impl std::str::FromStr for CavernMap {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut risk = Vec::new();
let mut height = 0;
let mut width = None;
for line in s.lines().map(str::trim) {
let line = line
.chars()
.map(|chr| {
chr.to_digit(10)
.map(|digit| digit as u64)
.with_context(|| format!("cannot parse char {} to digit", chr))
})
.collect::<Result<Vec<_>>>()?;
if width.is_none() {
width = Some(line.len());
}
height += 1;
risk.extend_from_slice(&line);
}
Ok(CavernMap {
height,
width: width.context("0 lines parsed, width never computed")?,
risk,
})
}
}
#[derive(Clone, Copy)]
enum Neighbour {
Up,
Down,
Left,
Right,
}
impl Neighbour {
fn apply(&self, x: usize, y: usize, width: usize, height: usize) -> Option<(usize, usize)> {
match self {
Neighbour::Left if x > 0 => Some((x - 1, y)),
Neighbour::Right if x < width - 1 => Some((x + 1, y)),
Neighbour::Up if y > 0 => Some((x, y - 1)),
Neighbour::Down if y < height - 1 => Some((x, y + 1)),
_ => None,
}
}
const ALL: &'static [Self] = &[
Neighbour::Left,
Neighbour::Right,
Neighbour::Up,
Neighbour::Down,
];
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day15_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 40);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 562);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 315);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 2874);
}
}

View file

@ -1,345 +0,0 @@
use std::fmt::Write;
use std::ops::Range;
use anyhow::{bail, Context, Result};
use bitvec::prelude::*;
const INPUT: &str = include_str!("../input/day16.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let packet: Packet = input.parse()?;
Ok(packet.version_sum())
}
fn part2(input: &str) -> Result<u64> {
let packet: Packet = input.parse()?;
Ok(packet.value())
}
#[derive(PartialEq, Eq, Debug)]
enum PacketType {
Litteral(LitteralPacket),
Operator(OperatorPacket),
}
#[derive(PartialEq, Eq, Debug)]
struct Packet {
version: u8,
type_id: u8,
bits_used: usize,
packet: PacketType,
}
impl Packet {
fn version_sum(&self) -> u64 {
let version = self.version as u64;
match &self.packet {
PacketType::Litteral(_) => version,
PacketType::Operator(op) => {
version + op.sub_packets.iter().map(Packet::version_sum).sum::<u64>()
}
}
}
fn value(&self) -> u64 {
match &self.packet {
PacketType::Litteral(lit) => lit.value,
PacketType::Operator(op) => match op.op_type {
OperatorType::Sum => op.sub_packets.iter().map(Packet::value).sum(),
OperatorType::Product => op.sub_packets.iter().map(Packet::value).product(),
OperatorType::Minimum => op.sub_packets.iter().map(Packet::value).min().unwrap(),
OperatorType::Maximum => op.sub_packets.iter().map(Packet::value).max().unwrap(),
OperatorType::GreaterThan => {
debug_assert_eq!(op.sub_packets.len(), 2);
let pack1 = &op.sub_packets[0];
let pack2 = &op.sub_packets[1];
u64::from(pack1.value() > pack2.value())
}
OperatorType::LessThan => {
debug_assert_eq!(op.sub_packets.len(), 2);
let pack1 = &op.sub_packets[0];
let pack2 = &op.sub_packets[1];
u64::from(pack1.value() < pack2.value())
}
OperatorType::EqualTo => {
debug_assert_eq!(op.sub_packets.len(), 2);
let pack1 = &op.sub_packets[0];
let pack2 = &op.sub_packets[1];
u64::from(pack1.value() == pack2.value())
}
},
}
}
}
#[derive(PartialEq, Eq, Debug)]
struct LitteralPacket {
value: u64,
}
#[derive(PartialEq, Eq, Debug)]
enum OperatorType {
Sum,
Product,
Minimum,
Maximum,
GreaterThan,
LessThan,
EqualTo,
}
#[derive(PartialEq, Eq, Debug)]
struct OperatorPacket {
sub_packets: Vec<Packet>,
op_type: OperatorType,
}
impl std::str::FromStr for Packet {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let s = s.trim();
let mut bits = BitVec::<usize, Msb0>::new();
bits.resize(4 * s.len(), false);
for (i, c) in s.chars().enumerate() {
let bit_index = i * 4;
let digit = c.to_digit(16).context("character wasn't hex digit")?;
bits[bit_index..(bit_index + 4)].store(digit);
}
bits.as_bitslice().try_into()
}
}
const VERSION_RANGE: Range<usize> = 0..3;
const TYPE_ID_RANGE: Range<usize> = 3..6;
const TYPE_LENGTH_ID_INDEX: usize = 6;
const LENGTH_INDEX: usize = 6 + 1;
const TLID0_SUBPACKET_LENGTH_BITS: usize = 15;
const SUBPACKET_START_INDEX_TLID0: usize = LENGTH_INDEX + TLID0_SUBPACKET_LENGTH_BITS;
const SUBPACKETS_BIT_LENGTH_RANGE: Range<usize> = LENGTH_INDEX..SUBPACKET_START_INDEX_TLID0;
const TLID1_SUBPACKET_NUMBER_BITS: usize = 11;
const SUBPACKET_START_INDEX_TLID1: usize = LENGTH_INDEX + TLID1_SUBPACKET_NUMBER_BITS;
const SUBPACKETS_NUMBER_RANGE: Range<usize> = LENGTH_INDEX..SUBPACKET_START_INDEX_TLID1;
impl<'bits, Store> TryFrom<&'bits BitSlice<Store, Msb0>> for Packet
where
Store: BitStore,
{
type Error = anyhow::Error;
fn try_from(bits: &'bits BitSlice<Store, Msb0>) -> Result<Self> {
let version: u8 = bits[VERSION_RANGE].load_be();
let type_id: u8 = bits[TYPE_ID_RANGE].load_be();
match type_id {
// LitteralPacket
4 => {
let mut value = 0;
let mut end = None;
for i in (6..).step_by(5) {
let val = bits[(i + 1)..(i + 5)].load_be::<u64>();
value = (value << 4) + val;
if !bits[i] {
end = Some(i + 5);
break;
}
}
Ok(Packet {
version,
type_id,
bits_used: end.unwrap(),
packet: PacketType::Litteral(LitteralPacket { value }),
})
}
// OperatorPacket
_ => {
let length_type_id = bits[TYPE_LENGTH_ID_INDEX];
let mut sub_packets = Vec::new();
let len = if length_type_id {
let subpacket_num: usize = bits[SUBPACKETS_NUMBER_RANGE].load_be();
let mut start_index = SUBPACKET_START_INDEX_TLID1;
while sub_packets.len() < subpacket_num {
let packet: Packet = bits[start_index..].try_into()?;
start_index += packet.bits_used;
sub_packets.push(packet);
}
start_index
} else {
let length: usize = bits[SUBPACKETS_BIT_LENGTH_RANGE].load_be();
let mut start_index = SUBPACKET_START_INDEX_TLID0;
while start_index != SUBPACKET_START_INDEX_TLID0 + length {
let packet: Packet = bits[start_index..].try_into()?;
start_index += packet.bits_used;
sub_packets.push(packet);
}
SUBPACKET_START_INDEX_TLID0 + length
};
let op_type = match type_id {
0 => OperatorType::Sum,
1 => OperatorType::Product,
2 => OperatorType::Minimum,
3 => OperatorType::Maximum,
4 => unreachable!("impossible, would parse as a litteral packet"),
5 => OperatorType::GreaterThan,
6 => OperatorType::LessThan,
7 => OperatorType::EqualTo,
_ => bail!("unknown type id: {}", type_id),
};
Ok(Packet {
version,
type_id,
bits_used: len,
packet: PacketType::Operator(OperatorPacket {
sub_packets,
op_type,
}),
})
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const PART1_PROVIDED1: &str = "D2FE28";
const PART1_PROVIDED2: &str = "38006F45291200";
const PART1_PROVIDED3: &str = "EE00D40C823060";
const PART1_PROVIDED4: &str = "8A004A801A8002F478";
const PART1_PROVIDED5: &str = "620080001611562C8802118E34";
const PART1_PROVIDED6: &str = "C0015000016115A2E0802F182340";
const PART1_PROVIDED7: &str = "A0016C880162017C3686B18A3D4780";
#[test]
fn part1_provided() {
assert_eq!(
PART1_PROVIDED1.parse::<Packet>().unwrap(),
Packet {
version: 6,
type_id: 4,
bits_used: 21,
packet: PacketType::Litteral(LitteralPacket { value: 2021 }),
}
);
assert_eq!(
PART1_PROVIDED2.parse::<Packet>().unwrap(),
Packet {
version: 1,
type_id: 6,
bits_used: 49,
packet: PacketType::Operator(OperatorPacket {
sub_packets: vec![
Packet {
version: 6,
type_id: 4,
bits_used: 11,
packet: PacketType::Litteral(LitteralPacket { value: 10 })
},
Packet {
version: 2,
type_id: 4,
bits_used: 16,
packet: PacketType::Litteral(LitteralPacket { value: 20 })
},
],
op_type: OperatorType::LessThan,
}),
}
);
assert_eq!(
PART1_PROVIDED3.parse::<Packet>().unwrap(),
Packet {
version: 7,
type_id: 3,
bits_used: 51,
packet: PacketType::Operator(OperatorPacket {
sub_packets: vec![
Packet {
version: 2,
type_id: 4,
bits_used: 11,
packet: PacketType::Litteral(LitteralPacket { value: 1 })
},
Packet {
version: 4,
type_id: 4,
bits_used: 11,
packet: PacketType::Litteral(LitteralPacket { value: 2 })
},
Packet {
version: 1,
type_id: 4,
bits_used: 11,
packet: PacketType::Litteral(LitteralPacket { value: 3 })
},
],
op_type: OperatorType::Maximum,
}),
}
);
assert_eq!(PART1_PROVIDED4.parse::<Packet>().unwrap().version_sum(), 16);
assert_eq!(PART1_PROVIDED5.parse::<Packet>().unwrap().version_sum(), 12);
assert_eq!(PART1_PROVIDED6.parse::<Packet>().unwrap().version_sum(), 23);
assert_eq!(PART1_PROVIDED7.parse::<Packet>().unwrap().version_sum(), 31);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 925);
}
const PART2_PROVIDED1: &str = "C200B40A82";
const PART2_PROVIDED2: &str = "04005AC33890";
const PART2_PROVIDED3: &str = "880086C3E88112";
const PART2_PROVIDED4: &str = "CE00C43D881120";
const PART2_PROVIDED5: &str = "D8005AC2A8F0";
const PART2_PROVIDED6: &str = "F600BC2D8F";
const PART2_PROVIDED7: &str = "9C005AC2F8F0";
const PART2_PROVIDED8: &str = "9C0141080250320F1802104A08";
#[test]
fn part2_provided() {
assert_eq!(part2(PART2_PROVIDED1).unwrap(), 3);
assert_eq!(part2(PART2_PROVIDED2).unwrap(), 54);
assert_eq!(part2(PART2_PROVIDED3).unwrap(), 7);
assert_eq!(part2(PART2_PROVIDED4).unwrap(), 9);
assert_eq!(part2(PART2_PROVIDED5).unwrap(), 1);
assert_eq!(part2(PART2_PROVIDED6).unwrap(), 0);
assert_eq!(part2(PART2_PROVIDED7).unwrap(), 0);
assert_eq!(part2(PART2_PROVIDED8).unwrap(), 1);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 342997120375);
}
}

View file

@ -1,213 +0,0 @@
//! Improvement ideas:
//!
//! X and Y coordinates are independant, so we can compute them separately, and keep track of which
//! values of X and Y can ever reach the target area, and if so, keep the step numbers where they
//! match. Some cross referencing can then isolate the valid trajectories.
//!
//! This already runs in 1ms though so... maybe later
use std::cmp::Ordering;
use std::fmt::Write;
use std::ops::RangeInclusive;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day17.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<isize> {
let area: TargetArea = input
.parse()
.context("couldn't parse input to target area")?;
let min_x_vel = if area.min_x() > 0 {
(0..).find(|x| ((x * (x + 1)) / 2) >= area.min_x()).unwrap()
} else if area.max_x() < 0 {
-(0..)
.find(|x| ((x * (x + 1)) / 2) >= area.max_x().abs())
.unwrap()
} else {
0
};
let max_x_vel = if area.min_x() > 0 {
area.max_x()
} else if area.max_x() < 0 {
area.min_x()
} else {
0
};
// Rust ranges can only be increasing, so swap values around if negative
let (min_x_vel, max_x_vel) = (min_x_vel.min(max_x_vel), min_x_vel.max(max_x_vel));
// we could launch the prob downward, but in that case max Y reached would always be 0
let min_y_vel = 1;
let max_y_vel = area.min_y().abs();
(min_x_vel..=max_x_vel)
.flat_map(|x_vel| (min_y_vel..=max_y_vel).map(move |y_vel| (x_vel, y_vel)))
.filter_map(|(x_vel, y_vel)| throw(x_vel, y_vel, &area))
.max()
.context("couldn't find any trajectory")
}
fn part2(input: &str) -> Result<usize> {
let area: TargetArea = input
.parse()
.context("couldn't parse input to target area")?;
let min_x_vel = if area.min_x() > 0 {
(0..).find(|x| ((x * (x + 1)) / 2) >= area.min_x()).unwrap()
} else if area.max_x() < 0 {
-(0..)
.find(|x| ((x * (x + 1)) / 2) >= area.max_x().abs())
.unwrap()
} else {
0
};
let max_x_vel = if area.min_x() > 0 {
area.max_x()
} else if area.max_x() < 0 {
area.min_x()
} else {
0
};
// Rust ranges can only be increasing, so swap values around if negative
let (min_x_vel, max_x_vel) = (min_x_vel.min(max_x_vel), min_x_vel.max(max_x_vel));
// let's assume that the area is always lower than (0, 0)
let min_y_vel = area.min_y();
let max_y_vel = area.min_y().abs();
Ok((min_x_vel..=max_x_vel)
.flat_map(|x_vel| (min_y_vel..=max_y_vel).map(move |y_vel| (x_vel, y_vel)))
.filter_map(|(x_vel, y_vel)| throw(x_vel, y_vel, &area))
.count())
}
fn throw(mut xvel: isize, mut yvel: isize, area: &TargetArea) -> Option<isize> {
let (mut pos_x, mut pos_y) = (0, 0);
let mut highest_y = 0;
loop {
if area.contains(pos_x, pos_y) {
return Some(highest_y);
}
// Three cases where we can stop here:
// - probe is lower than area, and gravity pulls it even lower
// - probe is on the left, and x velocity goes left
// - probe is on the right, and x velocity goes right
if (pos_y < area.min_y() && yvel <= 0)
|| (xvel <= 0 && pos_x < area.min_x())
|| (xvel >= 0 && pos_x > area.max_x())
{
// the probe will never reach the area, we can stop the simulation here
return None;
}
// - The probe's x position increases by its x velocity.
pos_x += xvel;
// - The probe's y position increases by its y velocity.
pos_y += yvel;
// - Due to drag, the probe's x velocity changes by 1 toward the value 0; that is, it
// decreases by 1 if it is greater than 0, increases by 1 if it is less than 0, or does not
// change if it is already 0.
match xvel.cmp(&0) {
Ordering::Less => xvel += 1,
Ordering::Greater => xvel -= 1,
_ => {}
}
// - Due to gravity, the probe's y velocity decreases by 1.
yvel -= 1;
// update highest seen y
highest_y = highest_y.max(pos_y);
}
}
struct TargetArea {
x_range: RangeInclusive<isize>,
y_range: RangeInclusive<isize>,
}
impl TargetArea {
fn contains(&self, x: isize, y: isize) -> bool {
self.x_range.contains(&x) && self.y_range.contains(&y)
}
fn min_y(&self) -> isize {
*self.y_range.start()
}
fn min_x(&self) -> isize {
*self.x_range.start()
}
fn max_x(&self) -> isize {
*self.x_range.end()
}
}
impl std::str::FromStr for TargetArea {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let s = s
.trim()
.strip_prefix("target area: ")
.context("missing target area while parsing")?;
let (x, y) = s.split_once(", ").context("couldn't split on comma")?;
let x = x.strip_prefix("x=").context("couldn't find `x=`")?;
let (min_x, max_x) = x.split_once("..").context("couldn't split on `..`")?;
let (min_x, max_x) = (min_x.parse()?, max_x.parse()?);
let y = y.strip_prefix("y=").context("couldn't find `y=`")?;
let (min_y, max_y) = y.split_once("..").context("couldn't split on `..`")?;
let (min_y, max_y) = (min_y.parse()?, max_y.parse()?);
Ok(Self {
x_range: min_x..=max_x,
y_range: min_y..=max_y,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day17_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 45);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 4186);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 112);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 2709);
}
}

View file

@ -1,183 +0,0 @@
use std::collections::HashMap;
use std::fmt::Write;
use std::iter;
use std::ops::RangeInclusive;
use anyhow::{Context, Result};
const INPUT: &str = include_str!("../input/day21.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
writeln!(res, "part 2: {}", part2(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<usize> {
let mut lines = input.lines();
let mut player1_pos: PlayerPos = lines
.next()
.and_then(|line| line.trim().strip_prefix("Player 1 starting position: "))
.and_then(|pos| pos.parse().ok())
.map(PlayerPos::new)
.context("couldn't find player 1 pos")?;
let mut player2_pos: PlayerPos = lines
.next()
.and_then(|line| line.trim().strip_prefix("Player 2 starting position: "))
.and_then(|pos| pos.parse().ok())
.map(PlayerPos::new)
.context("couldn't find player 2 pos")?;
let mut player1_score = 0;
let mut player2_score = 0;
let mut dice = DeterministicDice::new();
while player2_score < 1000 {
let mv = dice.next_3_sum();
player1_pos.advance_by(mv);
player1_score += player1_pos.pos();
std::mem::swap(&mut player1_pos, &mut player2_pos);
std::mem::swap(&mut player1_score, &mut player2_score);
}
let loser_score = player1_score;
Ok(loser_score * dice.rolls())
}
fn part2(input: &str) -> Result<usize> {
let mut lines = input.lines();
let player1_pos: PlayerPos = lines
.next()
.and_then(|line| line.trim().strip_prefix("Player 1 starting position: "))
.and_then(|pos| pos.parse().ok())
.map(PlayerPos::new)
.context("couldn't find player 1 pos")?;
let player2_pos: PlayerPos = lines
.next()
.and_then(|line| line.trim().strip_prefix("Player 2 starting position: "))
.and_then(|pos| pos.parse().ok())
.map(PlayerPos::new)
.context("couldn't find player 2 pos")?;
let (player1_score, player2_score) =
quantum_dice_game(player1_pos, player2_pos, 0, 0, &mut HashMap::new());
Ok(player1_score.max(player2_score))
}
type Cache = HashMap<(PlayerPos, PlayerPos, usize, usize), (usize, usize)>;
fn quantum_dice_game(
pos1: PlayerPos,
pos2: PlayerPos,
score1: usize,
score2: usize,
cache: &mut Cache,
) -> (usize, usize) {
// We swap players on each recursive call, so player 2 is the previous player 1. Player 1 is the
// only one who played, so we only need to check his score.
if score2 >= 21 {
return (0, 1);
}
// Memoization
if let Some(wins) = cache.get(&(pos1, pos2, score1, score2)) {
return *wins;
}
let (mut wins1, mut wins2) = (0, 0);
// 3 = 1 + 1 + 1
// 4 = 1 + 1 + 2, 1 + 2 + 1, 2 + 1 + 1
// ...
// 9 = 3 + 3 + 3
for (mv, times) in [(3, 1), (4, 3), (5, 6), (6, 7), (7, 6), (8, 3), (9, 1)] {
let mut pos1 = pos1; // copy
pos1.advance_by(mv);
// We swap out player 1 and 2 for the next recursion
let (w2, w1) = quantum_dice_game(pos2, pos1, score2, score1 + pos1.pos(), cache);
wins1 += w1 * times;
wins2 += w2 * times;
}
cache.insert((pos1, pos2, score1, score2), (wins1, wins2));
(wins1, wins2)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct PlayerPos(usize);
impl PlayerPos {
fn new(pos: usize) -> Self {
debug_assert!((1..=10).contains(&pos));
// represented from 0 to 9 for modulo ease of use
Self(pos - 1)
}
fn advance_by(&mut self, mv: usize) {
self.0 = (self.0 + mv) % 10
}
fn pos(&self) -> usize {
self.0 + 1
}
}
struct DeterministicDice {
iter: iter::Cycle<RangeInclusive<usize>>,
rolls: usize,
}
impl DeterministicDice {
fn new() -> Self {
Self {
iter: (1..=100).cycle(),
rolls: 0,
}
}
fn next_3_sum(&mut self) -> usize {
self.rolls += 3;
self.iter.next().unwrap() + self.iter.next().unwrap() + self.iter.next().unwrap()
}
fn rolls(&self) -> usize {
self.rolls
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day21_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 739785);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 908595);
}
#[test]
fn part2_provided() {
assert_eq!(part2(PROVIDED).unwrap(), 444356092776315);
}
#[test]
fn part2_real() {
assert_eq!(part2(INPUT).unwrap(), 91559198282731);
}
}

View file

@ -1,21 +0,0 @@
#![warn(clippy::explicit_iter_loop, clippy::redundant_closure_for_method_calls)]
pub mod day01;
pub mod day02;
pub mod day03;
pub mod day04;
pub mod day05;
pub mod day06;
pub mod day07;
pub mod day08;
pub mod day09;
pub mod day10;
pub mod day11;
pub mod day12;
pub mod day13;
pub mod day14;
pub mod day15;
pub mod day16;
pub mod day17;
pub mod day21;

View file

@ -1,48 +0,0 @@
use anyhow::Result;
use aoc::DayFunc;
use aoc2021::day01;
use aoc2021::day02;
use aoc2021::day03;
use aoc2021::day04;
use aoc2021::day05;
use aoc2021::day06;
use aoc2021::day07;
use aoc2021::day08;
use aoc2021::day09;
use aoc2021::day10;
use aoc2021::day11;
use aoc2021::day12;
use aoc2021::day13;
use aoc2021::day14;
use aoc2021::day15;
use aoc2021::day16;
use aoc2021::day17;
use aoc2021::day21;
fn main() -> Result<()> {
let days: &[DayFunc] = &[
day01::run,
day02::run,
day03::run,
day04::run,
day05::run,
day06::run,
day07::run,
day08::run,
day09::run,
day10::run,
day11::run,
day12::run,
day13::run,
day14::run,
day15::run,
day16::run,
day17::run,
day21::run,
];
aoc::run(days)
}

View file

@ -1,25 +0,0 @@
[package]
name = "aoc2022"
version = "0.1.0"
authors = ["Antoine Martin <antoine@alarsyo.net>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aoc = { path = "../aoc" }
anyhow = "1.0"
[dev-dependencies]
criterion = { version = "0.4", default-features = false, features = [ "rayon" ] }
[lib]
path = "src/lib.rs"
[[bin]]
name = "aoc2022"
path = "src/main.rs"
[[bench]]
name = "aoc2022_bench"
harness = false

View file

@ -1,18 +0,0 @@
use criterion::{criterion_group, criterion_main, Criterion};
use aoc2022::day01;
use aoc2022::day02;
use aoc2022::day03;
fn aoc2022_all(c: &mut Criterion) {
c.bench_function("day01", |b| b.iter(|| day01::run().unwrap()));
c.bench_function("day02", |b| b.iter(|| day02::run().unwrap()));
c.bench_function("day03", |b| b.iter(|| day03::run().unwrap()));
}
criterion_group! {
name = all_days;
config = Criterion::default().sample_size(200);
targets = aoc2022_all
}
criterion_main!(all_days);

File diff suppressed because it is too large Load diff

View file

@ -1,14 +0,0 @@
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000

File diff suppressed because it is too large Load diff

View file

@ -1,3 +0,0 @@
A Y
B X
C Z

View file

@ -1,300 +0,0 @@
vvMQnwwvrwWNfrtZJfppmSfJSmSg
BzGqjlBqBBmztHNFzDHg
llRCPlTPPqBjPhqhlBRBClhqWcTWrWNcMbQbdrdLccccrnvM
wMhwbTWpQjbpWHMQppzTHhjtlCjPSSJCCtlqRlJVFJFt
ggdvvnvDgdDmNcBrrcDntFRFqHJJtSJqvlVSRlJq
fggNNffGmcBrmBfcDzzzpHbsGTpszwwTbp
BPdPPBggrPtrpbtvPBBdgrFmhhQThGGlbbTZnzZQzZfn
ccjWRJVNcTGmnWWFmh
DMNmsMHwRNBrggdPDPdt
TfsfHLQbBtBFQbQsBmPwwlnPGZFwwdwWFZZw
MRpcvJMJVSMrVMpVSvhhnclwgWwDZgWgWgWglwcG
GCzjRJjVjSSrvfNQtLmQNsQbjB
FrSPFjtVvwsqSwcG
hDHdWDngpgZTDgHzzHwNNqlwNvZJlGqcQGsl
wDzLTDHgFffLtRft
CnCJNVqvCBJBNZmfPcPMcFLVcwmd
HgzjHFghSFtrLfwPchPM
QDpjgDSQlHHlDQQRzRzsBRRvWnWvJvZnqWBJNF
mGHcFPFqzPtcfPwDGVVpgLgSlgBl
rCvddTrnsbDLVSDwjSjd
QWhWQThswssMQMMMvhTzPqJzmzftHccJfHFhFm
cPbNpLVFTPbbFrpTLQBzqqmgnnBhgLMM
vvSwWCZCRZCDZtGwzdgWdQmzqgnQddJn
vCltGltCGmRRmCvDjjtHFpbcFfbbfssbpNPpHFpH
WLLQMWZLSPMPWmrwhnjhZZhpHJHljBDB
csbtCfFgCftGljHwHcBnpnJR
tsvgszNtfMwPzWqPrS
NbDZrbrFQQqqQtQqQDtTcBvCLBLswsZhscCGBZ
ljmWRzVRpbndMWmmfdsTsCBsGwTVVVCGCGws
ffRpnllHRMfdWzdnmRNQNNSFQQFNbrFHHrNH
LccGzWNjcvNLGTmHNsNLMlMwMpMPGlMCwFwDDGCw
fZZtfrZgrfQSnnnSnJRCglHpCwwHwpglDClFMw
SqJQnffJRnfQQVRhrQtrhnThcLhzNzHdTjhsTWzjdmcm
QJQwJMSbtbRgMQMQVZpCZsrrhpZBwrLLvs
qCNPGWdqhpphsWrB
DcNPNnqjdGDqjmPGGJRFMQmgtlQmQJCSgb
blTRbDnHRGGBwnGPCtFPWzVCDvFWtL
pdSJprqhhZSdqSdZNhVzZWtzLVgVPvzjLzWv
rrsqsmrMpPHlwTsRHn
mbNhgbRSLmTwswFm
vHjHBWMHBzMqWZVZBzHzcwwwdcFLcpLspdzwpwQd
HfMWMfvjWtZHqWDlhSnnnJNnbhslDb
lwsvPPnqlwwwsPcHTgqcRcSccmgQ
CVWBWCFpFzWfFjWjhNSQJJmcVcHRZJNTSc
zdhfzBtfLLtfFClbrDvsPvtPbnmv
PntVQbDnQHcDVvhtbtDhcbPcFTrrNfjqmmPTTZqMLZZMjFZm
lgJCpCFCSCGCpllWMfZqTNNZrMjrJTTM
CSzSwgFlzsGBzQcQhsnnDbVdtc
THzqvrVrWzhqhWwqhTbNNDRtFRmmpFDDVsFLLsdddF
MbZSSScZSGCJCjZlCjdPmpRmFLDtctdmFRsp
GfJQlnZjSMnllbJCQbClnZQrhNwwqhBzTNhrffqhqWhTqz
BdBdmDZHFFbrHHStPSRtPCzSRNDS
JGGpwqLJGMTLpLlMpqLhJtzCCSGQSPzNNczVVPVzSV
WwpllfslqfhffLwhfJpJlqlwdBmZnrdFHBFBBmNHFsFmdZmn
jZfQZnZfnbRfjCnfbSSmVpqmNmVpCqlhCqqPpP
MdJMwMvvLDssLtFMsMtLDsvvDRmmmPhWzWzphpmqDVzPDWNp
TsLdMrvRtLJtGdtGRRtFTBjSBrScnSZjnbcgQgHfnB
RZfmlRlWJmWLLRscrslJqvvMdVwmddvPddQPVDdDwz
GStFbFCbntbjNnjFhFvdHfhzHfzzQdMHwPdD
BSGpFbbjbNjnNNFSbRsLlWqgrZrfRgsBlg
ztHczmrmcNNzHsPSTwsPHSQPQT
CFCRjlvbClCjBdPDFQdwBsqn
llbRgjClJCVVMMCssfmNZWszrNgzGL
mmFldllVlmtdWFvPPFBcSSBW
DZzZGzZswQZHwQZjZzWWTSSvjSdvPvvWjJTS
DpQQggwzZGdmbCldgVgf
PJJvhqzVGbTFqzqbbGTlLmrtrZMnnZnntlJnrD
fNwRcQBCRNddNgLtgDnttqrMMtlr
RfRdNWQHcqHscdfRdGPFbFPpvpVWWzPzVS
DRgjZRRDggTfjfRvwWzHGGHPWDswvv
dhbmpcCmchgCpsGzWPdVGvWHwP
hpMMMpCQMnChFgNRQffTRrSN
gfqPCHWtPMMjCtffgjQWGLvGdZcdLLGZcLFGZBWG
pJTDsnnnvBjnFwvj
zJRpTbNrTSppRVblgbljMgMfCfbC
fGrGwqggtbVmtzbf
CTMjNQcJjJTBNCjMNZFNBcCZHbmWZHVLZDDWVtDzzbVmlV
hMvTcNMFMhQjTTBFBNMhwpspwgnGtvtnSgdwrRpG
RfFdqPdMMGPVgWmNVN
QwrTsbnSsSQpwlSSbNNWDmGLVjjmLWwNVB
rpcclTCprmZQSbprSTpRRRfqMfHHCHfhMhvFJM
LnJJsMtLbzsPPVPJbrTBlTWlfRfqnTrrlr
VDHVQNFGgNTrSjSBjq
CHFHGmvDGdZZGCQZVDgDHVbwLLwtMwwmJLJbLPPMbczt
qNNNBllFBzFjjzwGqGgLrWgrtQjdmmtQmQpp
ZMHJCPhMZRsRCsCPsSJZLmQdQgrtQwQwQZwdWg
CnMPbbRbsPhCnbfhMPRPllnFGqwTTFzTzNvBGBGc
wZWlBFZQgBzTzpZwBlVpzWBWnNMmnMvMcMJMmLGnVmqLqGMq
PdSDfJbCHsHHdJjsRRhjjPjmLqnnrLMLcrnLvdLMNccvGn
tSJtSCtbJhDhtzlFQZlTZTFp
TNqZDqmMDZNMFSGHjSGBRBdN
CrrwVwsPjjBHddPf
rpWggQVspQWcgtLwcHZZzDDMLDvvnnMzDM
lWrWmPwmGlZwZjdLZLzV
cFcDJhJnmqBqDCRpZzVLNsFLjLzdds
qJchTDCBHDWglmrfWPHH
RgLRnTJWnfHDcQQBfg
bZpNwdwbdMvVPsHHJMQfSSfP
mVbdNNdrbCzZbdZvbWTGrhqjTJtRWttRjq
TMtqqBJLrwqrZPlHHGhGnlBhzv
bFgNcpDRnpgggjCzvWDWhQhQWQHHvz
jnnVgjcgcTZMJqJVtT
dVSjmdHrfGPddrQgstFgzsQfsMFQ
hvJJCCJDcCtwBVFQzzBD
RWCnTvWTLRnJJLJllWhTLSprVdNZVGHGNGGnrdGSZH
gvMSHFZtBBMBMFZHzjnqLsLGMCzRWWMn
QJmDrhbNDbJfPQhDmQPRLszRlnjCzzWqrRnlsL
PcJVhJbJJNcNDmfDmjJmbhTfBvpwVSdggtgvgSFZwgvtgpdZ
PBClRHHClRlFljllZSBBBllppVGDLpZVVVsGpmGcNDpGLL
MvNwnbMwccVsswDG
MqnNbzMMrQfnqtttqfQWQQnRdCSHgHPglRFBRWlHjWRlCW
lldwdfSBWphHBggZghFs
DjDbDVRzDmLRzRLGJjPssrLZPhdshFHrssTZ
mvddMzvmmDDvvwQqWftCfqWqfM
gpTTwNWGWMSMgJjnvpvvJbJppn
lQvmLFdfrQzRFctlrLdRLVPnhPPbVDPDfjnVbfhJjV
FLFqccvmmtcQtrmQccRFLlRLSSWBSgTWNwsggqMBsqWGHMNG
PjPtVQrPVjrVPLLDQVFLTTWWqbSZwRwzqwSbSbbbwFSq
lBnGJBnfflRRNZwbqb
HJMGgmfpRMHGGdgncJHLDjjtVDQctLCvQCjTtr
VvmvjRGwRwvhmhRvvvVCCTTJjfWqfDMMcJlcCD
NpNbPfpSnngZbbLMFJWTMlLFqJJDMD
bNSfdSHQZgVQzwhhvRmQ
MhmHcDhChhcPVMDPDPQdFhQHnbNpZbZnprnrmNnjNbsllbnp
WWqGCWSCzsGbbGNgjN
LzwqBLSvwJCLPVMVDLdhMP
mNVLLffSLVWdZCcFZCZrSbGr
glvcwszTlsRDrHQCZFCvGH
gTBRlJnwhzgTgsTnggslsJRTpLNmjmNNcdVLdhfpLpdLVmLc
pCgfDrDrgccfppmDnhHMGqGbpHHSqzGLlqHS
tFtjQRPFFZRVNRcQGbLzLFMSGzSbWLqH
QRNTZjvjTTwtwNfmcTgfnCgnnBhm
hcPBhqPzqWPccHWHHWqnPdssPVfFFmZDnVDDms
NSLNCTRQZndRmDfnRD
QSGTGbjTSTJHBlbZZBbh
dgcWgVgWdvZSbbRtjLRZZZ
MMDPPfTnPTQrFDMpHzmmLztLnsszRtwbtS
rDfDqfHTpCSJqlCCGq
bjsgllstBbpNpslBpdBgqljgGwzJzDzwLGGrwLQQdJDwGhQh
nncmnmHHnmWRWmPfJCnvPRMrzvDhZZLGQwhDLhhMzZZZ
mffccVHRRPTTNlpNbNjJVslJ
DgPstgPtgPNNcjQQrtPJJCRSZTwSGJZZCZCJGD
dHVvpzdBBhVqzWqvhvHdzGSZlTRCSRJrwSSCwJCWGT
zpvVVqMBrzqrhFBvjbNPcPLnjcQtMcnj
gBcmTCFghhCCBnBhWWwFbwLdwHFMLMdp
LVzlZzPPMMzWWrwH
ljqjsGlZPPqqlVsPqDVqjQQctNTnRcNLtCNmmnRTRthBGG
LPRrrBNNjLBRJNdrGPRBfBrLwFqmDbdbTbTgmmgwmttFwtmH
QQcVvnQphlWsCQCCVpnvptTJgbtqwHDwbJtJHFsTHw
ppcJVQvpvMVMCvQZQVVZCCSRZPSjNRRZBPPPPzLjSLGf
MLtRnjQsRMJcDQJnSrsfqVVvGwbbbqgggg
WBFCNlFFFhFBlCHbplFWdpWZfVqPPwqTGdqTGvwrPVvTqvTr
HClCHzFzFBhmnjtQzMMSMnbD
sVnMCsdlMRcMFBGz
JvwwgrJDfgDmmggQrhNfhQQftjFrGRRtZFGBRZFHzjGcjrcj
PBJJvgDPNllPddVCPl
fmmRSnfnMnFSmMmmzTDSBFHtlJJqHJJqdHQdTCdtCCdt
WggGpNVVgWdwwHQtlGlC
hjbWppbLbLZLjVPPjPLSRRMvDlmSzDzBSnBFZf
nVttMPnPLjnJLjcnPVCjJJLcssfggBNlffgcNsWTcGcgNsBF
HQbwhmDrRrgFsWlQGNls
pZdbGzGrGpVttPLttv
LLbMrMHLDdWhmgbqqt
jGSQZQTpQGVVRSlQMQRljZmgmJBSvggvBWhJmJWvddmt
VjlQFGMVrFFrDrPw
DZVDwGZlJlVlwZVDzNdqfjMDnjqzNnWf
pmtpLRQFhSFpmpRgRtHNFznNdqWBjzWfnBjMWf
rHRrhStppHdJcGJrrssCsV
pgQqHwgPcPCddCjdWtdp
VfZGVFfNVhZhzjjjLz
fNNBBnGVNfBfRSRjBRQHJQTwJcJTgHPwTngr
MZdlzWzthMgrwmGmqZNqNs
VvJQJPVDBJQThwwNsRqsvRsHHm
BDQQPTnDDBQQBVfTBQPdFctzzdtztMMtnhcWcd
LjWjDShflZRRcZzfHH
srNwQPBsrVRhNmRGHzmM
rBdgQTrhdPndQTrsQQsrPwnTpLLCWDpSCLtCnvtSWpJjDCvl
gSlvDwCvcmcTQTFtRMjWHFVVHwtj
rbsphZZzBshGZssMffTVRFfFpWpfTH
GZNhZBhPBzTPNLDcDlCDCJNmlg
smZjGfvjbWWffQtf
dwRrdlVdDdgDbNtgcgQSNStQ
FdFVwdblFlzVrlwrTlndZHHZGhmLhhssjHhMjnjq
QFvQVFLLgVrFLBVgGhTtllPvmHRRGbTm
hDCCNCNCJNzWDZnqJDzSNCTnbRttHGRnccbPRtmmlmHc
qJshNMCNdVFVfsLB
FcLZZPFjdZcZMPcRjcRTgbpJlwbbTlmdTlGlwD
nrrNrHWBNSWvBqvvrhBqzStrgGnnmbwsbbJbwwJnmwmgJTlD
BCrrNvqWvSQPcCGZZRQQ
vPwcJblJzJbJcJFcwBSvJNdWRLtdsddGWWddWRWsMF
mDZmmDZDHVhfmjZgjVDfhTZHtsNptRsMntnWdsMnGtRntG
mhQrQDDhgqTTNfhmVQVBrPlBczSJbbCbCCPPvb
ZjbjLlbZjGqsgJTfHggrVvlB
tFDRFRnMFnnWtDdMdDRhzHfTJhJhffHvHTBHTgcfJV
nztDtdWzCCMSptSdFRRswZjsLbjwZmwqwGqpQV
vnvmmVnmVbrBJlzgWQWVNFzNHV
MwSjZhSwPjMwfDRzgWlNpWvHlgNNNP
CfSZjSfftwZDChDRSnccnrvBbbGrtBvctr
LCBRQRBQwRrCVLVWSrCSwCptzvhthvGGhdHzwppTTddv
mFnJJmnmFFFfPLNNmqqNJDpGnGtbHTtHvhnHbzvHvpGv
lMMPLqDmNMVSjjgMCS
zzPzbLjHLjfQPQHwwjddFNsNSJjDMsdNMFsC
BqqtmgDhcqdSFCdsqddF
GtcmrvhgcZlvZtBhtVgrvrvtnWzDnQbfnwlfWWRHWbbwzHRL
JfWHWZcMMdDLMPjRnCJjRbFgnblF
ShtBTSmBhTtqtfmqSTNvmjVjnFbFnnlrlqgCnrFnVg
vfzTTthppmdzPLHLWdGZ
tdvrvGgGTSScnHcjcg
zLLVfzPPcDZnPjSPpD
LfffNFLNlNbJwrctthWqNdNq
NdjJtfVNZnnFFdtfGfFNcvpbMDbzdcTbbzpvmcDR
PHMSHCHHWrRCvzDzDChT
BqPWSHwllSQWrLHQHPqlBBNfttZMjFQfjGtZtNjJJjnN
CpZtMCMQQpCVWjMDVjPVQsWWqJJhbTcddPlfhTRqchcJblhh
NwDSGNmGRccqNJfT
SBSSmgrrgGHnvSzwGVWDCzMCpLZtMsstLM
sbjHQsBlBQrrGjQjBqCRSnSCpnfngLnFhJngFfSP
zHVctHDcZtdJffnPpcSpFn
ZdwNMztdvzVdrqblvWsqHvBR
jPdjFPSbVDMMbqZzQWzQ
hFRrJlpprGhtlJGQzmCRmZBWQCHRQR
vThNplJpNhltNNlvcGDvwVFgnPwvSgPSSfjS
DhDTPQpTDmQbDQrrrWtWPJNNrrsJ
qqGjgwCgVRjMSRwMMGRGqjwvsNJJBZtrstvNBvHWHJvL
VqqgfjzfgfFGVjRggCGznhlbTpQchcshpdFlnDbn
DpTQTBbCZQVJQZJjrFllGdlvMPlMLqGBGvLl
hmnWHWWNzzmHsmWRlGGpdLgLHGlqvgqg
RzcWRhRnRnfmswfwtzzRWrDTrrFCQTCpQpcCrjjQCp
HLvpHvGcBTDFznvfqT
hCPQbPZPbjSbwwjCPChSClJJfzqTggTFDfsJngDg
StqmmZbdqrQmhQrrhZWcRcGBpBHWVcLctMWp
dNnRNbRdbRJMBMBVVThn
rNrsLNscFsCDjpwTMgBGWMGjJjWBVJ
wNcLpqHNsCprsfLFsHwRvPSSPRZRtRQSqtQPmP
PPhGfbthhBDVsTDtDqRR
mCmSNmqpcqjjrCScWRsZDpHsDQRZQDZDss
CcWzNmccrjjvqBGzzdPGnv
SDRmCSFfcSFFcfDmDBFSCfdVJhpzZjNJTNzRTvjzjhzNjTtZ
ngGsltrMWrblNpNTJJplJN
PGGnGsWngrGLQHHtHHHgWsHSBLqqfLcqBdVdcCDDBFdCDm
VPjGwhwVPhrnqhzJmQvQTQvmzBzw
ZBDBRbLLdtfRLlddLlCLCZMgmFJQFDcvzMQmgMzzJJFJ
LHLWltHlRZCtBVhVVHPjGSpphp
JqhlhdnnmfRVVSpzWLjzVLGpvB
stQtFTTrsZQPFQNNDtQgLzzSLvjvLGLBGSZGGWJv
DDDFFgDPbTwbTTJMCMcbCqqmmRRCnb
JbDWPDPPJJDMDjHPZHGbHGVZTBhrzBpdzszdTTphdNdWdrpv
RmRRqllqffwFtqwLCsqTNvpCsqCNqvdN
fmfLmStlnnfnRtfcnQbbjPjPPggZGVsMQMbb
WJggvGDJSwWgSfgvfSMGqqQHBcPjcHChcQBCssDHCTTQ
mlRnbrnbnltblwdnnpbLRdCCjCTHTjPTTsQcTrHHhCcj
bFLbdmzRpvSwfFFNWN
BHnDnQHnHMWLwzWPzD
dmlZCrdqLZzZVZJM
tRRtdlLCjLmqCRsrSLrvvRQNFQnbgRTQQNHTBbGQQh
ZrQPQWCrJnPdQSNTmBJNTHGHJN
zhFRfswjwhhsFttfsfvQftRtLTzmBTHGTBmzMLHHLmGHNTTS
hQhwqVjQwsdggrZZCWVl
VjfnQgVQjblChfjVJlbzLtrSLlTGtztHTtsTGH
DDqWQDQMWmDwWNwcqdWvpSrtLpLsptMprMStstMz
vQcddRdRvWcwWRmmmmddZmmfVnnngJJbZnCBnBhhFbhCgJ
gVgDnnmJdQVdJJgtgDjBsBhsBSPRSRRSSwccSbSqwPcCPcSC
HrQHlHFpQfTHzzWzwScPPCRfLbPSfCSR
TTQlZNTzlZNMWvrZMlpnhnVtnDDnVNtVJnjmhg
MCmmssFnZJcNNszfpvvrpvJzvwpp
BRRRWQWbSRGGRTTtZHWSqTrvDfgfdfrrwrDgfbvfzfrd
jRBhWRWTSRttQBZMNchNCsmFMchP
GBDncllqcSlNFZWBFWPjHVbw
LQphJlJzLCwPjHbpHZvV
hzCMJLMzTsrdrszQCCCTCQCDlqqnNmggqfGmgdmGgcmSNt
hFVVbqJsqhcnBRTRGBTh
lwdDpmzdNznzZBgGRRjR
HdmvNvSCmDmwNDFrMJMqJFCRfsbq
ctnbTcFTnbwSSfrrMLRhpJLMRdpwdJJR
vdGCVBmGVHPLBRWhpRLJJZ
VmQPHqvsPdlQsVHDftnlFTbffnbttfTF
LBJZHrhLThHddcMLVtcMcL
CPMNFDDMpGqFjjSPDPDqdvmdtQgVQQcQWcQgQQsj
DzFDFMRSFPSGTJJTJBwwRhBw
dpldqlqlRppFTHpbjbnLRLVnnGfjtG
NNJTcmhzvJQNgMJBwcGtjtGbttfhtsGGnhnt
rzcwmgvcvrBNvvmMgvcBzwHPCTWWprqPHqTFWdPCWDTF
BNllDRTNqDNvNDDLBcDvBCLVJrVdJdtrnrCHggtrdd
mppFMFjpMFZQZQGjFCdgrCrCdrvVGtJJCC
PZsQmfPphvPjSsjmPjfZllBwcNRDNcDqNNWbTclS
fjqZBSDSDwwsQwCDND
rrdMdjVWtTTPslsslFLTLCsJ
rvPWbvcmHjmdPbHvrvBHgqRRgqHGgfZGfHRS
ggTQgsgwFrTrggbMTvSdmjfCmmQDcmqjDjmc
nLZnRhNZnnNHZhZVStCcDqjcqmjSjH
RWGNnhzBnJJRRWNRBNZNLZhFMTFPvrTrTlsggPwSlFMWTw
RNmnPRnLGcQmzBQpHHjTltjtlfgspbsq
CZvCJwZMMCCMdFVcwJJsgTTHfsTlbfbgbT
SSVFhWCZdSCcWCcWdrvhzmnnnLNGDRDNzzLNGz
jPwfPwNfFpFNQpDjdMcjcrdddDHD
tzsRsGRLzhLhvqvhHMlqqV
LRBnRBGSnBSGsGSGmGtBJCmnNWZpPpTNPMwQMPNJFZTTNwWT
PCrStRPSPvZQcZPvqvfjSRWFFNFJFLZTTJTTVZFFGLFF
DlpBzBntHDzhlpGJVHLwTMFLVLTL
gptBBdgzpsBbpQvvPQPRqrdcCC

Some files were not shown because too many files have changed in this diff Show more