This commit is contained in:
JonOfUs 2022-12-20 17:35:25 +01:00
parent 69a51e6299
commit c9808224ec
7 changed files with 5254 additions and 113 deletions

5000
res/20/input.txt Normal file

File diff suppressed because it is too large Load diff

7
res/20/test-input.txt Normal file
View file

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

View file

@ -14,7 +14,7 @@ pub fn solve() {
vec![(0, 1), (1, 0), (1, 1), (1, 2), (2, 1)],
vec![(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)],
vec![(0, 0), (1, 0), (2, 0), (3, 0)],
vec![(0,0),(0,1),(1,0),(1,1)]
vec![(0, 0), (0, 1), (1, 0), (1, 1)],
];
let directions: Vec<Dir> = contents
@ -36,7 +36,6 @@ pub fn solve() {
let mut heights = Vec::<i64>::new();
/*
51 rocks
@ -47,14 +46,11 @@ pub fn solve() {
%
*/
for i in 0..2344 {
// spawn new rock
let r_index = i as usize % rocks.len(); // get current rock index
let mut rock = Rock::new(&rocks[r_index], highest_rock);
while chamber.iter().filter(|row| !row.contains(&true)).count() < 7 {
chamber.push(vec![false; WIDTH])
}
@ -63,7 +59,7 @@ pub fn solve() {
// move to left or right
let next_dir = dir_iter.next();
let dir = match next_dir {
Some(x) => { x },
Some(x) => x,
None => {
dir_iter = directions.iter();
dir_iter.next().unwrap()
@ -75,7 +71,7 @@ pub fn solve() {
if rock.left().valid_pos(&chamber) {
rock = rock.left()
}
},
}
Dir::Right => {
if rock.right().valid_pos(&chamber) {
rock = rock.right()
@ -86,16 +82,17 @@ pub fn solve() {
if rock.down().valid_pos(&chamber) {
rock = rock.down();
} else {
rock.pos.iter().for_each(|coord| {
chamber[coord.0 as usize][coord.1 as usize] = true
});
rock.pos
.iter()
.for_each(|coord| chamber[coord.0 as usize][coord.1 as usize] = true);
highest_rock = match chamber
.iter()
.enumerate()
.filter(|row| row.1.contains(&true))
.last() {
.last()
{
Some(x) => x.0 as i64,
None => -1
None => -1,
};
// find recurring patterns in amount of rocks and height
heights.push(highest_rock);
@ -111,22 +108,33 @@ pub fn solve() {
fn _test(n: usize, heights: &Vec<i64>) {
if heights.len() % n == 0
&& heights[heights.len()/n-1]*n as i64+n as i64 == heights[heights.len()-1]+1 {
&& heights[heights.len() / n - 1] * n as i64 + n as i64 == heights[heights.len() - 1] + 1
{
println!("{}: {}", n, heights.len() / n)
}
}
fn _print_chamber(chamber: &Vec<Vec<bool>>, curr_rock: &Rock) {
let mut str_chamber: Vec<Vec<char>> = chamber.iter().map(|line| line.iter().map(|elem|
match *elem {
let mut str_chamber: Vec<Vec<char>> = chamber
.iter()
.map(|line| {
line.iter()
.map(|elem| match *elem {
true => '#',
false => '.'
}
).collect()).collect();
false => '.',
})
.collect()
})
.collect();
curr_rock.pos.iter().for_each(|pos| { str_chamber[pos.0 as usize][pos.1 as usize] = '@'; });
curr_rock.pos.iter().for_each(|pos| {
str_chamber[pos.0 as usize][pos.1 as usize] = '@';
});
str_chamber.iter().rev().for_each(|str| println!("{}",str.iter().collect::<String>()))
str_chamber
.iter()
.rev()
.for_each(|str| println!("{}", str.iter().collect::<String>()))
}
#[derive(Clone, Debug)]
@ -137,7 +145,7 @@ enum Dir {
#[derive(Clone, Debug)]
struct Rock {
pos: Vec<(i64,i64)>
pos: Vec<(i64, i64)>,
}
impl Rock {
@ -145,7 +153,10 @@ impl Rock {
let pos: Vec<(i64, i64)> = rock
.iter()
.map(|coord| {
(coord.0 as i64 + (highest_rock + 4) as i64, coord.1 as i64 + 2)
(
coord.0 as i64 + (highest_rock + 4) as i64,
coord.1 as i64 + 2,
)
})
.collect();
Rock { pos }
@ -154,44 +165,56 @@ impl Rock {
pub fn right(&self) -> Self {
for coord in self.pos.iter() {
if coord.1 >= (WIDTH - 1) as i64 {
return self.clone()
return self.clone();
}
}
Rock {
pos: self.pos.iter().map(|coord| {
pos: self
.pos
.iter()
.map(|coord| {
(coord.0, coord.1 + 1) // move right, only check for wall !
}).collect()
})
.collect(),
}
}
pub fn left(&self) -> Self {
for coord in self.pos.iter() {
if coord.1 <= 0 {
return self.clone()
return self.clone();
}
}
Rock {
pos: self.pos.iter().map(|coord| {
pos: self
.pos
.iter()
.map(|coord| {
(coord.0, coord.1 - 1) // move left, only check for wall !
}).collect()
})
.collect(),
}
}
pub fn down(&self) -> Self {
Rock {
pos: self.pos.iter().map(|coord| {
pos: self
.pos
.iter()
.map(|coord| {
(coord.0 - 1, coord.1) // move down
}).collect()
})
.collect(),
}
}
pub fn valid_pos(&self, chamber: &Vec<Vec<bool>>) -> bool {
for coord in &self.pos {
if coord.0 < 0 || coord.1 < 0 {
return false
return false;
}
if chamber[coord.0 as usize][coord.1 as usize] {
return false
return false;
}
}

View file

@ -1,4 +1,7 @@
use std::{fs, collections::{HashMap, HashSet, VecDeque}};
use std::{
collections::{HashMap, HashSet, VecDeque},
fs,
};
pub fn solve() {
let path = "res/18/input.txt";
@ -13,18 +16,14 @@ pub fn solve() {
(
vals[0].parse::<usize>().unwrap(),
vals[1].parse::<usize>().unwrap(),
vals[2].parse::<usize>().unwrap()
vals[2].parse::<usize>().unwrap(),
)
})
.collect();
let max: usize = coords
.iter()
.map(|coord|
coord.0.max(
coord.1.max(coord.2)
)
)
.map(|coord| coord.0.max(coord.1.max(coord.2)))
.max()
.unwrap();
@ -47,7 +46,9 @@ pub fn solve() {
// x-1
if x == 0 || !world[x - 1][y][z] {
surfaces += 1;
if x != 0 { insert_or_increase((x-1,y,z), &mut surface_blocks) }
if x != 0 {
insert_or_increase((x - 1, y, z), &mut surface_blocks)
}
}
// x+1
if !world[x + 1][y][z] {
@ -57,7 +58,9 @@ pub fn solve() {
// y-1
if y == 0 || !world[x][y - 1][z] {
surfaces += 1;
if y != 0 { insert_or_increase((x,y-1,z), &mut surface_blocks) }
if y != 0 {
insert_or_increase((x, y - 1, z), &mut surface_blocks)
}
}
// y+1
if !world[x][y + 1][z] {
@ -67,7 +70,9 @@ pub fn solve() {
// z-1
if z == 0 || !world[x][y][z - 1] {
surfaces += 1;
if z != 0 { insert_or_increase((x,y,z-1), &mut surface_blocks) }
if z != 0 {
insert_or_increase((x, y, z - 1), &mut surface_blocks)
}
}
// z+1
if !world[x][y][z + 1] {
@ -87,10 +92,9 @@ pub fn solve() {
}
println!("Result 2: {surfaces}");
}
fn insert_or_increase(p: (usize,usize,usize), map: &mut HashMap::<(usize,usize,usize), usize>) {
fn insert_or_increase(p: (usize, usize, usize), map: &mut HashMap<(usize, usize, usize), usize>) {
if map.contains_key(&p) {
*map.get_mut(&p).unwrap() += 1;
} else {
@ -98,7 +102,11 @@ fn insert_or_increase(p: (usize,usize,usize), map: &mut HashMap::<(usize,usize,u
}
}
fn bfs_reachable(s: (usize, usize, usize), e: (usize, usize, usize), world: &Vec<Vec<Vec<bool>>>) -> bool {
fn bfs_reachable(
s: (usize, usize, usize),
e: (usize, usize, usize),
world: &Vec<Vec<Vec<bool>>>,
) -> bool {
let mut queue = VecDeque::<(usize, usize, usize)>::new();
let mut seen_nodes = HashSet::<(usize, usize, usize)>::new();
@ -121,7 +129,10 @@ fn bfs_reachable(s: (usize, usize, usize), e: (usize, usize, usize), world: &Vec
false
}
fn get_adjacents(p: (usize, usize, usize), world: &Vec<Vec<Vec<bool>>>) -> Vec<(usize,usize,usize)> {
fn get_adjacents(
p: (usize, usize, usize),
world: &Vec<Vec<Vec<bool>>>,
) -> Vec<(usize, usize, usize)> {
let mut adj = Vec::<(usize, usize, usize)>::new();
let (x, y, z) = p;

View file

@ -1,16 +1,17 @@
use std::{fs, collections::{HashMap, HashSet, VecDeque}};
use std::fs;
use scan_fmt::scan_fmt;
#[allow(dead_code)]
const MINUTES: u32 = 24;
#[allow(dead_code)]
pub fn solve() {
let path = "res/19/input.txt";
let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
// parse blueprints
let blueprints: Vec<Blueprint> = contents
let _blueprints: Vec<Blueprint> = contents
.lines()
.filter(|line| *line != "")
.map(|line| {
@ -30,11 +31,9 @@ pub fn solve() {
})
.collect();
}
#[allow(dead_code)]
#[derive(Debug)]
struct Blueprint {
id: u32,
@ -44,12 +43,11 @@ struct Blueprint {
geode_bot: (u32, u32), // (ore, obsidian)
}
#[allow(dead_code)]
impl Blueprint {
pub fn quality_level(&self) -> u32 {
// TODO dynamic programming?
return self.id * 1; // TODO largest number of geodes that can be opened
}
}

102
src/days/d20.rs Normal file
View file

@ -0,0 +1,102 @@
use std::fs;
const DECRYPTION_KEY: i64 = 811_589_153;
pub fn solve() {
let path = "res/20/input.txt";
let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
let initial_arrangement: Vec<i64> = contents
.lines()
.filter(|line| *line != "")
.map(|line| line.parse::<i64>().unwrap())
.collect();
let size = initial_arrangement.len();
// list of indices
let mut work_arrangement: Vec<usize> = initial_arrangement
.iter()
.enumerate()
.map(|(i, _)| i)
.collect();
for (i, &n) in initial_arrangement.iter().enumerate() {
// position in current state
let work_i = work_arrangement.iter().position(|&elem| elem == i).unwrap();
mv(work_i, n, &mut work_arrangement);
//println!("{}\n", work_arrangement.iter().map(|i| initial_arrangement[*i].to_string()).collect::<Vec::<String>>().join(", "));
}
let offset = work_arrangement
.iter()
.position(|i| initial_arrangement[*i] == 0)
.unwrap();
let coord_1 = initial_arrangement[work_arrangement[(1000 + offset) % size]];
let coord_2 = initial_arrangement[work_arrangement[(2000 + offset) % size]];
let coord_3 = initial_arrangement[work_arrangement[(3000 + offset) % size]];
println!("Result 1: {}", coord_1 + coord_2 + coord_3);
// task 2
let decrypted_arrangement: Vec<i64> = initial_arrangement
.iter()
.map(|i| i * DECRYPTION_KEY)
.collect();
// list of indices
let mut work_arrangement: Vec<usize> = decrypted_arrangement
.iter()
.enumerate()
.map(|(i, _)| i)
.collect();
// do the whole thing 10x
for _ in 0..10 {
for (i, &n) in decrypted_arrangement.iter().enumerate() {
// position in current state
let work_i = work_arrangement.iter().position(|&elem| elem == i).unwrap();
mv(work_i, n, &mut work_arrangement);
//println!("{}\n", work_arrangement.iter().map(|i| decrypted_arrangement[*i].to_string()).collect::<Vec::<String>>().join(", "));
}
}
let offset = work_arrangement
.iter()
.position(|i| initial_arrangement[*i] == 0)
.unwrap();
let coord_1 = decrypted_arrangement[work_arrangement[(1000 + offset) % size]];
let coord_2 = decrypted_arrangement[work_arrangement[(2000 + offset) % size]];
let coord_3 = decrypted_arrangement[work_arrangement[(3000 + offset) % size]];
println!("Result 2: {}", coord_1 + coord_2 + coord_3);
}
fn mv(pos: usize, move_by: i64, arr: &mut Vec<usize>) {
// reduce move_by to modulo
let move_by = if move_by < 0 {
(move_by.abs() % (arr.len() as i64 - 1)) * -1
} else {
move_by % (arr.len() as i64 - 1)
};
let move_by = if pos as i64 + move_by <= 0 {
move_by + arr.len() as i64 - 1
} else if pos as i64 + move_by >= arr.len() as i64 - 1 {
move_by - arr.len() as i64 + 1
} else {
move_by
};
let mut curr_pos = pos;
let change = if move_by < 0 { -1 } else { 1 };
for _ in 0..move_by.abs() {
let other_pos = ((curr_pos + arr.len()) as i64 + change) as usize % arr.len();
let val = arr[curr_pos];
arr[curr_pos] = arr[other_pos];
arr[other_pos] = val;
curr_pos = other_pos;
}
}

View file

@ -1,7 +1,7 @@
pub mod days;
fn main() {
days::d19::solve()
days::d20::solve()
//_all_days()
}