Compare commits
3 Commits
78df584c4d
...
6a204e5f59
Author | SHA1 | Date | |
---|---|---|---|
6a204e5f59 | |||
00ae1c3f7d | |||
085a02b2d5 |
26
test.py
Normal file
26
test.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# JS sucks
|
||||||
|
for line in open('./y2024/resources/17_input.txt'):
|
||||||
|
if line.startswith('Program:'):
|
||||||
|
instructions = list(map(int, line.split(': ')[1].split(',')))
|
||||||
|
|
||||||
|
def outFromA(a):
|
||||||
|
interim = (a % 8) ^ 3
|
||||||
|
c = a // (2 ** interim)
|
||||||
|
postC = c ^ 6
|
||||||
|
return (postC ^ (a % 8)) % 8
|
||||||
|
|
||||||
|
candidates = [0]
|
||||||
|
for i in range(len(instructions) - 1, -1, -1):
|
||||||
|
newCandidates = []
|
||||||
|
# print(f'Instruction: {instructions[i]}, candidates: {candidates}')
|
||||||
|
for c in candidates:
|
||||||
|
for j in range(8):
|
||||||
|
num = (c << 3) + j
|
||||||
|
out = outFromA(num)
|
||||||
|
# print(f'Num: {num}, Out: {out}, Instruction: {instructions[i]}')
|
||||||
|
if out == instructions[i]:
|
||||||
|
newCandidates.append(num)
|
||||||
|
candidates = newCandidates
|
||||||
|
|
||||||
|
# print(candidates)
|
||||||
|
print(min(candidates))
|
3450
y2024/resources/18_input.txt
Normal file
3450
y2024/resources/18_input.txt
Normal file
File diff suppressed because it is too large
Load Diff
27
y2024/src/bin/d18.rs
Normal file
27
y2024/src/bin/d18.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use std::{fs, time::Instant};
|
||||||
|
|
||||||
|
use utils::time::get_elapsed_string;
|
||||||
|
use y2024::days::d18;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let now = Instant::now();
|
||||||
|
println!("Part 1:");
|
||||||
|
part1();
|
||||||
|
println!("Ran in {}", get_elapsed_string(now.elapsed()));
|
||||||
|
let now = Instant::now();
|
||||||
|
println!("Part 2:");
|
||||||
|
part2();
|
||||||
|
println!("Ran in {}", get_elapsed_string(now.elapsed()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/18_input.txt")).unwrap();
|
||||||
|
println!("{}", d18::process_part1(&content));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/18_input.txt")).unwrap();
|
||||||
|
println!("{}", d18::process_part2(&content));
|
||||||
|
}
|
@ -2,7 +2,7 @@ use std::{collections::HashMap, error::Error};
|
|||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
pub fn process_part1(input: &str) -> (String, HashMap<&str, u32>) {
|
pub fn process_part1(input: &str) -> (String, HashMap<&str, u64>) {
|
||||||
let (registers, program) = input.split_once("\n\n").unwrap();
|
let (registers, program) = input.split_once("\n\n").unwrap();
|
||||||
let mut registers = parse_registers(registers);
|
let mut registers = parse_registers(registers);
|
||||||
let (_, instructions) = program.split_once(": ").unwrap();
|
let (_, instructions) = program.split_once(": ").unwrap();
|
||||||
@ -19,7 +19,7 @@ pub fn process_part1(input: &str) -> (String, HashMap<&str, u32>) {
|
|||||||
.collect_vec()
|
.collect_vec()
|
||||||
.concat();
|
.concat();
|
||||||
|
|
||||||
let mut instruction_pointer: u32 = 0;
|
let mut instruction_pointer: u64 = 0;
|
||||||
|
|
||||||
while let Some((opcode, operand)) = instructions.get(instruction_pointer as usize) {
|
while let Some((opcode, operand)) = instructions.get(instruction_pointer as usize) {
|
||||||
let opcode = OpCodes::try_from(*opcode).unwrap();
|
let opcode = OpCodes::try_from(*opcode).unwrap();
|
||||||
@ -37,7 +37,7 @@ pub fn process_part1(input: &str) -> (String, HashMap<&str, u32>) {
|
|||||||
(out.into_iter().join(","), registers)
|
(out.into_iter().join(","), registers)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_part2(input: &str) -> u32 {
|
pub fn process_part2(input: &str) -> u64 {
|
||||||
let (registers, program) = input.split_once("\n\n").unwrap();
|
let (registers, program) = input.split_once("\n\n").unwrap();
|
||||||
let mut registers = parse_registers(registers);
|
let mut registers = parse_registers(registers);
|
||||||
let (_, instructions) = program.split_once(": ").unwrap();
|
let (_, instructions) = program.split_once(": ").unwrap();
|
||||||
@ -56,30 +56,35 @@ pub fn process_part2(input: &str) -> u32 {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(opcode, operand)| {
|
.map(|(opcode, operand)| {
|
||||||
[
|
[
|
||||||
opcode.parse::<u32>().unwrap(),
|
opcode.parse::<u64>().unwrap(),
|
||||||
operand.parse::<u32>().unwrap(),
|
operand.parse::<u64>().unwrap(),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.collect_vec()
|
.collect_vec()
|
||||||
.concat();
|
.concat();
|
||||||
let mut a = 0;
|
let mut a = 0;
|
||||||
|
for idx in 1..=orig.len() {
|
||||||
|
let target = orig[orig.len() - idx..].to_vec();
|
||||||
|
|
||||||
|
let mut new_a = a << 3;
|
||||||
loop {
|
loop {
|
||||||
registers.insert("A", a);
|
registers.insert("A", new_a);
|
||||||
let out = exec_program(instructions.clone(), &mut registers);
|
let out = exec_program(instructions.clone(), &mut registers);
|
||||||
if out == orig {
|
//println!("target {target:?}");
|
||||||
println!("{orig:?}");
|
//println!("output {out:?}");
|
||||||
println!("{out:?}");
|
if out == target {
|
||||||
|
a = new_a;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
a += 1;
|
new_a += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec_program(instructions: Vec<(&str, &str)>, registers: &mut HashMap<&str, u32>) -> Vec<u32> {
|
fn exec_program(instructions: Vec<(&str, &str)>, registers: &mut HashMap<&str, u64>) -> Vec<u64> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
let mut instruction_pointer: u32 = 0;
|
let mut instruction_pointer: u64 = 0;
|
||||||
|
|
||||||
while let Some((opcode, operand)) = instructions.get(instruction_pointer as usize) {
|
while let Some((opcode, operand)) = instructions.get(instruction_pointer as usize) {
|
||||||
let opcode = OpCodes::try_from(*opcode).unwrap();
|
let opcode = OpCodes::try_from(*opcode).unwrap();
|
||||||
@ -97,7 +102,7 @@ fn exec_program(instructions: Vec<(&str, &str)>, registers: &mut HashMap<&str, u
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_registers(input: &str) -> HashMap<&str, u32> {
|
fn parse_registers(input: &str) -> HashMap<&str, u64> {
|
||||||
let mut registers = HashMap::new();
|
let mut registers = HashMap::new();
|
||||||
input.lines().for_each(|line| {
|
input.lines().for_each(|line| {
|
||||||
let (register, value) = line.split_once(": ").unwrap();
|
let (register, value) = line.split_once(": ").unwrap();
|
||||||
@ -121,11 +126,11 @@ enum OpCodes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OpCodes {
|
impl OpCodes {
|
||||||
fn exec(&self, operand: &str, registers: &mut HashMap<&str, u32>) -> Option<(u32, bool)> {
|
fn exec(&self, operand: &str, registers: &mut HashMap<&str, u64>) -> Option<(u64, bool)> {
|
||||||
let a = *registers.get("A").unwrap();
|
let a = *registers.get("A").unwrap();
|
||||||
let b = *registers.get("B").unwrap();
|
let b = *registers.get("B").unwrap();
|
||||||
let c = *registers.get("C").unwrap();
|
let c = *registers.get("C").unwrap();
|
||||||
let operand: u32 = operand.parse().unwrap();
|
let operand: u64 = operand.parse().unwrap();
|
||||||
let combo = if operand <= 3 {
|
let combo = if operand <= 3 {
|
||||||
operand
|
operand
|
||||||
} else if operand == 4 {
|
} else if operand == 4 {
|
||||||
@ -141,9 +146,9 @@ impl OpCodes {
|
|||||||
OpCodes::Adv => {
|
OpCodes::Adv => {
|
||||||
//println!(
|
//println!(
|
||||||
// "a = a / 2 ** combo = {a} / 2 ** {combo} = {}",
|
// "a = a / 2 ** combo = {a} / 2 ** {combo} = {}",
|
||||||
// a / 2_u32.pow(combo)
|
// a / 2_u64.pow(combo)
|
||||||
//);
|
//);
|
||||||
registers.insert("A", a / 2_u32.pow(combo));
|
registers.insert("A", a / 2_u64.pow(combo as u32));
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
OpCodes::Bxl => {
|
OpCodes::Bxl => {
|
||||||
@ -177,17 +182,17 @@ impl OpCodes {
|
|||||||
OpCodes::Bdv => {
|
OpCodes::Bdv => {
|
||||||
//println!(
|
//println!(
|
||||||
// "b = a / 2 ** combo = {a} / 2 ** {combo} = {}",
|
// "b = a / 2 ** combo = {a} / 2 ** {combo} = {}",
|
||||||
// a / 2_u32.pow(combo)
|
// a / 2_u64.pow(combo)
|
||||||
//);
|
//);
|
||||||
registers.insert("B", a / 2_u32.pow(combo));
|
registers.insert("B", a / 2_u64.pow(combo as u32));
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
OpCodes::Cdv => {
|
OpCodes::Cdv => {
|
||||||
//println!(
|
//println!(
|
||||||
// "c = a / 2 ** combo = {a} / 2 ** {combo} = {}",
|
// "c = a / 2 ** combo = {a} / 2 ** {combo} = {}",
|
||||||
// a / 2_u32.pow(combo)
|
// a / 2_u64.pow(combo)
|
||||||
//);
|
//);
|
||||||
registers.insert("C", a / 2_u32.pow(combo));
|
registers.insert("C", a / 2_u64.pow(combo as u32));
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
294
y2024/src/days/d18.rs
Normal file
294
y2024/src/days/d18.rs
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
use std::{collections::HashSet, error::Error};
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
pub fn process_part1(input: &str) -> u32 {
|
||||||
|
let falling_bytes = &input
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
let (x, y) = line.split_once(",").unwrap();
|
||||||
|
(x.parse().unwrap(), y.parse().unwrap())
|
||||||
|
})
|
||||||
|
.collect_vec()[..1024];
|
||||||
|
let y_walls = vec![GridTile::Wall; 73];
|
||||||
|
let mut inner_rows = vec![GridTile::Path; 71];
|
||||||
|
inner_rows.insert(0, GridTile::Wall);
|
||||||
|
inner_rows.push(GridTile::Wall);
|
||||||
|
let mut grid = vec![inner_rows; 71];
|
||||||
|
grid.insert(0, y_walls.clone());
|
||||||
|
grid.push(y_walls);
|
||||||
|
simulate(grid, falling_bytes).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simulate(mut grid: Vec<Vec<GridTile>>, falling_bytes: &[(usize, usize)]) -> Option<u32> {
|
||||||
|
grid[1][1] = GridTile::Start;
|
||||||
|
let height = grid.len();
|
||||||
|
let width = grid[0].len();
|
||||||
|
grid[height - 2][width - 2] = GridTile::End;
|
||||||
|
falling_bytes.iter().for_each(|(x, y)| {
|
||||||
|
grid[*y + 1][*x + 1] = GridTile::Wall;
|
||||||
|
});
|
||||||
|
let mut visited = HashSet::new();
|
||||||
|
visited.insert((1, 1));
|
||||||
|
let mut next_paths = vec![MazeRunner {
|
||||||
|
coords: (1, 1),
|
||||||
|
visited: visited.clone(),
|
||||||
|
..Default::default()
|
||||||
|
}];
|
||||||
|
let mut arrived: Vec<MazeRunner> = Vec::new();
|
||||||
|
while !next_paths.is_empty() {
|
||||||
|
next_paths = next_paths
|
||||||
|
.iter()
|
||||||
|
.map(|maze_runner| {
|
||||||
|
let mut paths = Vec::new();
|
||||||
|
if let Some(path) = maze_runner.get_next(&grid, Direction::Up) {
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
if let Some(path) = maze_runner.get_next(&grid, Direction::Down) {
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
if let Some(path) = maze_runner.get_next(&grid, Direction::Left) {
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
if let Some(path) = maze_runner.get_next(&grid, Direction::Right) {
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
paths
|
||||||
|
})
|
||||||
|
.collect_vec()
|
||||||
|
.concat();
|
||||||
|
for (idx, maze_runner) in next_paths.clone().iter().enumerate().rev() {
|
||||||
|
if maze_runner.visited.contains(&maze_runner.coords)
|
||||||
|
|| visited.contains(&maze_runner.coords)
|
||||||
|
{
|
||||||
|
next_paths.remove(idx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
visited.insert(maze_runner.coords);
|
||||||
|
next_paths[idx].visited.insert(maze_runner.coords);
|
||||||
|
if maze_runner.state == State::Arrived {
|
||||||
|
let arrived_reindeer = next_paths.remove(idx);
|
||||||
|
arrived.push(arrived_reindeer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//let visited = arrived
|
||||||
|
// .iter()
|
||||||
|
// .map(|reindeer| {
|
||||||
|
// reindeer
|
||||||
|
// .visited
|
||||||
|
// .iter()
|
||||||
|
// .map(|(coords, _)| coords)
|
||||||
|
// .collect_vec()
|
||||||
|
// })
|
||||||
|
// .collect_vec()
|
||||||
|
// .concat();
|
||||||
|
//visited.iter().unique().count()
|
||||||
|
arrived.sort_by(|a_runner, b_runner| a_runner.visited.len().cmp(&b_runner.visited.len()));
|
||||||
|
if let Some(arrived) = arrived.first() {
|
||||||
|
log_maze(&grid, arrived);
|
||||||
|
Some(arrived.visited.len() as u32 - 1)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_part2(input: &str) -> String {
|
||||||
|
let falling_bytes = &input
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
let (x, y) = line.split_once(",").unwrap();
|
||||||
|
(x.parse::<usize>().unwrap(), y.parse::<usize>().unwrap())
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
let y_walls = vec![GridTile::Wall; 73];
|
||||||
|
let mut inner_rows = vec![GridTile::Path; 71];
|
||||||
|
inner_rows.insert(0, GridTile::Wall);
|
||||||
|
inner_rows.push(GridTile::Wall);
|
||||||
|
let mut grid = vec![inner_rows; 71];
|
||||||
|
grid.insert(0, y_walls.clone());
|
||||||
|
grid.push(y_walls);
|
||||||
|
let mut num_bytes = 1025;
|
||||||
|
while simulate(grid.clone(), &falling_bytes[..num_bytes]).is_some() {
|
||||||
|
num_bytes += 1;
|
||||||
|
}
|
||||||
|
let (x, y) = falling_bytes[num_bytes - 1];
|
||||||
|
format!("{x},{y}")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
enum Direction {
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||||
|
enum State {
|
||||||
|
#[default]
|
||||||
|
Going,
|
||||||
|
Arrived,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||||
|
struct MazeRunner {
|
||||||
|
coords: (usize, usize),
|
||||||
|
visited: HashSet<(usize, usize)>,
|
||||||
|
state: State,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MazeRunner {
|
||||||
|
fn get_next(&self, grid: &[Vec<GridTile>], direction: Direction) -> Option<MazeRunner> {
|
||||||
|
let tile = match direction {
|
||||||
|
Direction::Up => grid[self.coords.1 - 1][self.coords.0],
|
||||||
|
Direction::Down => grid[self.coords.1 + 1][self.coords.0],
|
||||||
|
Direction::Right => grid[self.coords.1][self.coords.0 + 1],
|
||||||
|
Direction::Left => grid[self.coords.1][self.coords.0 - 1],
|
||||||
|
};
|
||||||
|
let coords = match direction {
|
||||||
|
Direction::Up => (self.coords.0, self.coords.1 - 1),
|
||||||
|
Direction::Down => (self.coords.0, self.coords.1 + 1),
|
||||||
|
Direction::Left => (self.coords.0 - 1, self.coords.1),
|
||||||
|
Direction::Right => (self.coords.0 + 1, self.coords.1),
|
||||||
|
};
|
||||||
|
if tile == GridTile::Wall {
|
||||||
|
None
|
||||||
|
} else if tile == GridTile::End {
|
||||||
|
Some(MazeRunner {
|
||||||
|
state: State::Arrived,
|
||||||
|
coords,
|
||||||
|
..self.clone()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Some(MazeRunner {
|
||||||
|
coords,
|
||||||
|
..self.clone()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq)]
|
||||||
|
enum GridTile {
|
||||||
|
Wall,
|
||||||
|
#[default]
|
||||||
|
Path,
|
||||||
|
Start,
|
||||||
|
End,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<char> for GridTile {
|
||||||
|
type Error = Box<dyn Error>;
|
||||||
|
|
||||||
|
fn try_from(value: char) -> std::result::Result<GridTile, Box<dyn Error>> {
|
||||||
|
match value {
|
||||||
|
'#' => Ok(Self::Wall),
|
||||||
|
'.' => Ok(Self::Path),
|
||||||
|
'S' => Ok(Self::Start),
|
||||||
|
'E' => Ok(Self::End),
|
||||||
|
_ => Err(Box::from(format!("{value} is not a valid tile"))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_maze(grid: &[Vec<GridTile>], maze_runner: &MazeRunner) {
|
||||||
|
for (yidx, row) in grid.iter().enumerate() {
|
||||||
|
for (xidx, tile) in row.iter().enumerate() {
|
||||||
|
let contains = {
|
||||||
|
maze_runner.visited.contains(&(xidx, yidx))
|
||||||
|
|| maze_runner.visited.contains(&(xidx, yidx))
|
||||||
|
|| maze_runner.visited.contains(&(xidx, yidx))
|
||||||
|
|| maze_runner.visited.contains(&(xidx, yidx))
|
||||||
|
};
|
||||||
|
if contains && !(*tile == GridTile::Start || *tile == GridTile::End) {
|
||||||
|
print!("O");
|
||||||
|
} else if *tile == GridTile::Wall {
|
||||||
|
print!("#");
|
||||||
|
} else if *tile == GridTile::Path {
|
||||||
|
print!(".");
|
||||||
|
} else if *tile == GridTile::Start {
|
||||||
|
print!("S");
|
||||||
|
} else if *tile == GridTile::End {
|
||||||
|
print!("E");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT: &str = "5,4
|
||||||
|
4,2
|
||||||
|
4,5
|
||||||
|
3,0
|
||||||
|
2,1
|
||||||
|
6,3
|
||||||
|
2,4
|
||||||
|
1,5
|
||||||
|
0,6
|
||||||
|
3,3
|
||||||
|
2,6
|
||||||
|
5,1
|
||||||
|
1,2
|
||||||
|
5,5
|
||||||
|
2,5
|
||||||
|
6,5
|
||||||
|
1,4
|
||||||
|
0,4
|
||||||
|
6,4
|
||||||
|
1,1
|
||||||
|
6,1
|
||||||
|
1,0
|
||||||
|
0,5
|
||||||
|
1,6
|
||||||
|
2,0";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1() {
|
||||||
|
let falling_bytes = &INPUT
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
let (x, y) = line.split_once(",").unwrap();
|
||||||
|
(x.parse().unwrap(), y.parse().unwrap())
|
||||||
|
})
|
||||||
|
.collect_vec()[..12];
|
||||||
|
let y_walls = vec![GridTile::Wall; 9];
|
||||||
|
let mut inner_rows = vec![GridTile::Path; 7];
|
||||||
|
inner_rows.insert(0, GridTile::Wall);
|
||||||
|
inner_rows.push(GridTile::Wall);
|
||||||
|
let mut grid = vec![inner_rows; 7];
|
||||||
|
grid.insert(0, y_walls.clone());
|
||||||
|
grid.push(y_walls);
|
||||||
|
let result = simulate(grid, falling_bytes);
|
||||||
|
assert_eq!(result, Some(22));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2() {
|
||||||
|
let falling_bytes = INPUT
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
let (x, y) = line.split_once(",").unwrap();
|
||||||
|
(x.parse::<usize>().unwrap(), y.parse::<usize>().unwrap())
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
let y_walls = vec![GridTile::Wall; 9];
|
||||||
|
let mut inner_rows = vec![GridTile::Path; 7];
|
||||||
|
inner_rows.insert(0, GridTile::Wall);
|
||||||
|
inner_rows.push(GridTile::Wall);
|
||||||
|
let mut grid = vec![inner_rows; 7];
|
||||||
|
grid.insert(0, y_walls.clone());
|
||||||
|
grid.push(y_walls);
|
||||||
|
let mut num_bytes = 12;
|
||||||
|
while simulate(grid.clone(), &falling_bytes[..num_bytes]).is_some() {
|
||||||
|
num_bytes += 1;
|
||||||
|
}
|
||||||
|
let (x, y) = falling_bytes[num_bytes - 1];
|
||||||
|
let result = format!("{x},{y}");
|
||||||
|
assert_eq!(result, "6,1".to_string());
|
||||||
|
}
|
||||||
|
}
|
@ -23,3 +23,5 @@ pub mod d15;
|
|||||||
pub mod d16;
|
pub mod d16;
|
||||||
|
|
||||||
pub mod d17;
|
pub mod d17;
|
||||||
|
|
||||||
|
pub mod d18;
|
||||||
|
Loading…
Reference in New Issue
Block a user