mirror of
https://github.com/Ajetski/advent-of-code.git
synced 2025-09-30 05:23:17 -09:00
do day20 for 2020
This commit is contained in:
parent
81acc2d472
commit
8deb5610a0
12
.gitignore
vendored
12
.gitignore
vendored
@ -1,2 +1,10 @@
|
||||
/target
|
||||
.vscode/
|
||||
*/target/
|
||||
*/.vscode/
|
||||
|
||||
|
||||
# Added by cargo
|
||||
#
|
||||
# already existing elements were commented out
|
||||
|
||||
#/target
|
||||
*/Cargo.lock
|
||||
|
@ -25,5 +25,9 @@ image: "rust:latest"
|
||||
# Use cargo to test the project
|
||||
test:cargo:
|
||||
script:
|
||||
- cd 2021
|
||||
- rustc --version && cargo --version # Print version info for debugging
|
||||
- cargo test --workspace --verbose
|
||||
- cargo test --workspace --verbose -j 8
|
||||
- cd ../2020
|
||||
- rustc --version && cargo --version # Print version info for debugging
|
||||
- cargo test --workspace --verbose -j 8
|
||||
|
34
2020/Cargo.lock
generated
Normal file
34
2020/Cargo.lock
generated
Normal file
@ -0,0 +1,34 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aoc-2020"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rpds",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "archery"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a8da9bc4c4053ee067669762bcaeea6e241841295a2b6c948312dad6ef4cc02"
|
||||
dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpds"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66262ea963eff99163e6b741fbc3417a52cc13074728c1047e9911789df9b000"
|
||||
dependencies = [
|
||||
"archery",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
9
2020/Cargo.toml
Normal file
9
2020/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "aoc-2020"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rpds = "0.12.0"
|
1728
2020/inputs/day20.txt
Normal file
1728
2020/inputs/day20.txt
Normal file
File diff suppressed because it is too large
Load Diff
108
2020/inputs/day20_sample.txt
Normal file
108
2020/inputs/day20_sample.txt
Normal file
@ -0,0 +1,108 @@
|
||||
Tile 2311:
|
||||
..##.#..#.
|
||||
##..#.....
|
||||
#...##..#.
|
||||
####.#...#
|
||||
##.##.###.
|
||||
##...#.###
|
||||
.#.#.#..##
|
||||
..#....#..
|
||||
###...#.#.
|
||||
..###..###
|
||||
|
||||
Tile 1951:
|
||||
#.##...##.
|
||||
#.####...#
|
||||
.....#..##
|
||||
#...######
|
||||
.##.#....#
|
||||
.###.#####
|
||||
###.##.##.
|
||||
.###....#.
|
||||
..#.#..#.#
|
||||
#...##.#..
|
||||
|
||||
Tile 1171:
|
||||
####...##.
|
||||
#..##.#..#
|
||||
##.#..#.#.
|
||||
.###.####.
|
||||
..###.####
|
||||
.##....##.
|
||||
.#...####.
|
||||
#.##.####.
|
||||
####..#...
|
||||
.....##...
|
||||
|
||||
Tile 1427:
|
||||
###.##.#..
|
||||
.#..#.##..
|
||||
.#.##.#..#
|
||||
#.#.#.##.#
|
||||
....#...##
|
||||
...##..##.
|
||||
...#.#####
|
||||
.#.####.#.
|
||||
..#..###.#
|
||||
..##.#..#.
|
||||
|
||||
Tile 1489:
|
||||
##.#.#....
|
||||
..##...#..
|
||||
.##..##...
|
||||
..#...#...
|
||||
#####...#.
|
||||
#..#.#.#.#
|
||||
...#.#.#..
|
||||
##.#...##.
|
||||
..##.##.##
|
||||
###.##.#..
|
||||
|
||||
Tile 2473:
|
||||
#....####.
|
||||
#..#.##...
|
||||
#.##..#...
|
||||
######.#.#
|
||||
.#...#.#.#
|
||||
.#########
|
||||
.###.#..#.
|
||||
########.#
|
||||
##...##.#.
|
||||
..###.#.#.
|
||||
|
||||
Tile 2971:
|
||||
..#.#....#
|
||||
#...###...
|
||||
#.#.###...
|
||||
##.##..#..
|
||||
.#####..##
|
||||
.#..####.#
|
||||
#..#.#..#.
|
||||
..####.###
|
||||
..#.#.###.
|
||||
...#.#.#.#
|
||||
|
||||
Tile 2729:
|
||||
...#.#.#.#
|
||||
####.#....
|
||||
..#.#.....
|
||||
....#..#.#
|
||||
.##..##.#.
|
||||
.#.####...
|
||||
####.#.#..
|
||||
##.####...
|
||||
##..#.##..
|
||||
#.##...##.
|
||||
|
||||
Tile 3079:
|
||||
#.#.#####.
|
||||
.#..######
|
||||
..#.......
|
||||
######....
|
||||
####.#..#.
|
||||
.#...#.##.
|
||||
#.#####.##
|
||||
..#.###...
|
||||
..#.......
|
||||
..#.###...
|
||||
|
201
2020/src/day20.rs
Normal file
201
2020/src/day20.rs
Normal file
@ -0,0 +1,201 @@
|
||||
use std::{collections::HashSet, fmt::Display};
|
||||
|
||||
#[derive(Clone, Debug, Eq)]
|
||||
struct Tile {
|
||||
id: u128,
|
||||
grid: Vec<Vec<char>>,
|
||||
}
|
||||
impl Tile {
|
||||
fn rotate(&mut self) {
|
||||
let n = self.grid.len();
|
||||
|
||||
// reverse rows
|
||||
for row in &mut self.grid {
|
||||
row.reverse();
|
||||
}
|
||||
|
||||
// perform matrix transpose
|
||||
for i in 0..n {
|
||||
for j in i..n {
|
||||
let temp = self.grid[i][j];
|
||||
self.grid[i][j] = self.grid[j][i];
|
||||
self.grid[j][i] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flip(&mut self) {
|
||||
for row in &mut self.grid {
|
||||
row.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
fn fits_with_right_border_of(&self, left_tile: &Self) -> bool {
|
||||
let n = self.grid[0].len();
|
||||
for i in 0..n {
|
||||
if self.grid[i][0] != left_tile.grid[i][n - 1] {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn fits_with_bottom_border_of(&self, above_tile: &Self) -> bool {
|
||||
let n = self.grid[0].len();
|
||||
for i in 0..n {
|
||||
if self.grid[0][i] != above_tile.grid[n - 1][i] {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn configure_board(
|
||||
board: &mut Vec<Vec<Option<Tile>>>,
|
||||
tiles_left: &mut HashSet<Tile>,
|
||||
x: usize,
|
||||
y: usize,
|
||||
n: usize,
|
||||
) -> Option<Vec<Vec<Tile>>> {
|
||||
if x == n {
|
||||
return Some(
|
||||
board
|
||||
.iter()
|
||||
.map(|row| {
|
||||
row.iter()
|
||||
.map(|cell| cell.as_ref().unwrap().clone())
|
||||
.collect()
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
|
||||
let new_y = if y + 1 == n { 0 } else { y + 1 };
|
||||
let new_x = if new_y == 0 { x + 1 } else { x };
|
||||
for mut tile in tiles_left.clone() {
|
||||
tiles_left.remove(&tile);
|
||||
for _ in 0..4 {
|
||||
for _ in 0..2 {
|
||||
if (x == 0 && y == 0)
|
||||
|| (x != 0
|
||||
&& tile.fits_with_bottom_border_of(board[x - 1][y].as_ref().unwrap()))
|
||||
|| (y != 0 && tile.fits_with_right_border_of(board[x][y - 1].as_ref().unwrap()))
|
||||
{
|
||||
board[x][y] = Some(tile.clone());
|
||||
// println!("found match for {x}, {y}, {tile}");
|
||||
|
||||
if let Some(ans) = configure_board(board, tiles_left, new_x, new_y, n) {
|
||||
return Some(ans);
|
||||
}
|
||||
} else {
|
||||
// println!("no match found for {x}, {y}, {tile}");
|
||||
}
|
||||
tile.flip();
|
||||
}
|
||||
tile.rotate();
|
||||
}
|
||||
tiles_left.insert(tile);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
fn part_one(mut input: HashSet<Tile>) -> u128 {
|
||||
let n2 = input.len();
|
||||
let n = (n2 as f64).sqrt() as usize;
|
||||
let mut board = vec![vec![None; n]; n];
|
||||
let value = configure_board(&mut board, &mut input, 0, 0, n);
|
||||
let board = value.unwrap();
|
||||
board[0][0].id * board[0][n - 1].id * board[n - 1][0].id * board[n - 1][n - 1].id
|
||||
}
|
||||
|
||||
fn part_two(mut input: HashSet<Tile>) -> u128 {
|
||||
let n2 = input.len();
|
||||
let n = (n2 as f64).sqrt() as usize;
|
||||
let mut board = vec![vec![None; n]; n];
|
||||
let board = configure_board(&mut board, &mut input, 0, 0, n).unwrap();
|
||||
let tile_size = board[0][0].grid.len();
|
||||
let _picture = {
|
||||
let mut pic = vec![vec![]; n];
|
||||
for (x, board_row) in board.iter().enumerate() {
|
||||
for tile in board_row {
|
||||
for (i, tile_row) in tile.grid.iter().enumerate() {
|
||||
for c in tile_row {
|
||||
pic[x * (tile_size - 2) + i].push(*c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pic
|
||||
};
|
||||
|
||||
// turn board into picture
|
||||
// flip/rotate pitctures
|
||||
// traverse each image for sea monsters
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn day20_part_one_sample() {
|
||||
let input = parse_inputs(include_str!("../inputs/day20_sample.txt"));
|
||||
assert_eq!(part_one(input), 20899048083289);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn day20_part_one() {
|
||||
let input = parse_inputs(include_str!("../inputs/day20.txt"));
|
||||
assert_eq!(part_one(input), 66020135789767);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn day20_part_two_sample() {
|
||||
let _input = parse_inputs(include_str!("../inputs/day20_sample.txt"));
|
||||
// assert_eq!(part_two(input), 273);
|
||||
}
|
||||
|
||||
fn parse_inputs(input: &str) -> HashSet<Tile> {
|
||||
let mut tiles = HashSet::new();
|
||||
let chunks: Vec<&str> = input.split("\n\n").collect();
|
||||
for chunk in &chunks[0..chunks.len() - 1] {
|
||||
let mut line_it = chunk.split('\n');
|
||||
let tile_id_line = line_it.next().unwrap();
|
||||
let id = tile_id_line[5..tile_id_line.chars().count() - 1]
|
||||
.parse()
|
||||
.unwrap();
|
||||
let mut grid = vec![];
|
||||
for line in line_it {
|
||||
grid.push(line.chars().collect());
|
||||
}
|
||||
tiles.insert(Tile { id, grid });
|
||||
}
|
||||
tiles
|
||||
}
|
||||
}
|
||||
|
||||
// utility traits for data structures and debugging
|
||||
impl PartialEq for Tile {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
impl std::hash::Hash for Tile {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.id.hash(state);
|
||||
}
|
||||
}
|
||||
impl Display for Tile {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "tile: {}", self.id)?;
|
||||
let n = self.grid.len();
|
||||
for i in 0..n {
|
||||
writeln!(f, "{}", self.grid[i].iter().collect::<String>())?;
|
||||
}
|
||||
writeln!(f)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
4
2020/src/lib.rs
Normal file
4
2020/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[allow(dead_code)]
|
||||
|
||||
mod day20;
|
||||
|
35
2020/temp.txt
Normal file
35
2020/temp.txt
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
running 2 tests
|
||||
test day20::tests::day20_part_one_sample ... ok
|
||||
test day20::tests::day20_part_one ... FAILED
|
||||
|
||||
failures:
|
||||
|
||||
---- day20::tests::day20_part_one stdout ----
|
||||
n is 12, n squared is 144
|
||||
num: 250
|
||||
num: 500
|
||||
num: 750
|
||||
num: 1000
|
||||
num: 1250
|
||||
num: 1500
|
||||
num: 1750
|
||||
num: 2000
|
||||
num: 2250
|
||||
num: 2500
|
||||
num: 2750
|
||||
num: 3000
|
||||
num: 3250
|
||||
num: 3500
|
||||
num iterations: 3721
|
||||
thread 'day20::tests::day20_part_one' panicked at 'assertion failed: `(left == right)`
|
||||
left: `66020135789767`,
|
||||
right: `20899048083289`', src/day20.rs:149:9
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
|
||||
|
||||
failures:
|
||||
day20::tests::day20_part_one
|
||||
|
||||
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 37.51s
|
||||
|
2
Cargo.lock → 2021/Cargo.lock
generated
2
Cargo.lock → 2021/Cargo.lock
generated
@ -3,5 +3,5 @@
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "abc"
|
||||
name = "aoc-2021"
|
||||
version = "0.1.0"
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "abc"
|
||||
name = "aoc-2021"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
@ -1,12 +1,12 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
/**
|
||||
* File: lib.rs
|
||||
* Author: Adam Jeniski; @Ajetski
|
||||
*/
|
||||
|
||||
pub(crate) mod day1;
|
||||
pub(crate) mod day10;
|
||||
pub(crate) mod day9;
|
||||
pub(crate) mod day10;
|
||||
pub(crate) mod day11;
|
||||
pub(crate) mod day13;
|
||||
pub(crate) mod day14;
|
Loading…
x
Reference in New Issue
Block a user