upgrade rust, add some execution function & started extending intcode

This commit is contained in:
hendrik 2025-07-17 23:54:40 +02:00
parent 4570a256ce
commit 17be25e607
20 changed files with 152 additions and 59 deletions

View File

@ -1,10 +1,10 @@
[package]
name = "advent_of_code"
version = "0.1.0"
edition = "2021"
edition = "2024"
[dependencies]
anyhow = "1.0"
#2015 - day3
md5 = "0.7.0"
md5 = "0.7.0"

View File

@ -24,6 +24,10 @@ pub fn run() -> (i32, usize) {
(res, going_into_the_basement)
}
#[test]
fn run_pt() {
assert_eq!(run(), (74, 1795));
}
fn test() {
let input = ")())())";
let res = input
@ -31,7 +35,7 @@ fn test() {
.map(|c| if c == '(' { 1 } else { -1 })
.sum::<i32>();
println!("{}", res);
println!("{res}");
}
/*

View File

@ -1,5 +1,9 @@
use core::panic;
#[test]
fn exec() {
assert_eq!(run(), (492982, 6989950));
}
pub fn run() -> (usize, usize) {
test();
let input = "1321131112";

View File

@ -1,3 +1,8 @@
#[test]
fn exec() {
assert_eq!(run(), (String::from("vzbxxyzz"), String::from("vzcaabcc")));
}
pub fn run() -> (String, String) {
let input = "vzbxkghb";
//test();

View File

@ -1,6 +1,10 @@
use std::path::PathBuf;
use crate::helper::file::read_file;
#[test]
fn exec() {
assert_eq!(run(), (1588178, 3783758));
}
pub fn run() -> (usize, usize) {
test();

View File

@ -2,6 +2,10 @@ use std::{collections::HashSet, path::PathBuf};
use crate::helper::file::read_file;
#[test]
fn exec() {
assert_eq!(run(), (2565, 2639));
}
pub fn run() -> (usize, usize) {
test();
let path = PathBuf::from("ressources/2015/day3");

View File

@ -6,6 +6,10 @@ pub fn run() -> (usize, usize) {
)
}
#[test]
fn exec() {
assert_eq!(run(), (346386, 9958218));
}
fn find_witz_leading_zeros(input: &str, zeros: usize) -> usize {
let mut i = 0;
loop {

View File

@ -2,6 +2,10 @@ use std::{collections::HashMap, path::PathBuf};
use crate::helper::file::read_file;
#[test]
fn exec() {
assert_eq!(run(), (258, 53));
}
pub fn run() -> (usize, usize) {
test();
let path = PathBuf::from("ressources/2015/day5");

View File

@ -2,6 +2,10 @@ use std::path::PathBuf;
use crate::helper::file::read_file;
#[test]
fn exec() {
assert_eq!(run(), (569999, 17836115));
}
pub fn run() -> (usize, usize) {
test();
let path = PathBuf::from("ressources/2015/day6");

View File

@ -2,6 +2,10 @@ use std::{collections::HashMap, path::PathBuf};
use crate::helper::file::read_file;
#[test]
fn exec() {
assert_eq!(run(), (956, 40149));
}
pub fn run() -> (u16, u16) {
test();
let path = PathBuf::from("ressources/2015/day7");

View File

@ -2,6 +2,10 @@ use std::path::PathBuf;
use crate::helper::file::read_file;
#[test]
fn exec() {
assert_eq!(run(), (1350, 2085));
}
pub fn run() -> (usize, usize) {
test();
let path = PathBuf::from("ressources/2015/day8");

View File

@ -5,7 +5,10 @@ use std::{
};
use crate::helper::file::read_file;
#[test]
fn exec() {
assert_eq!(run(), (117, 909));
}
pub fn run() -> (usize, usize) {
test();
let path = PathBuf::from("ressources/2015/day9");

View File

@ -35,28 +35,28 @@ enum Cmd {
impl Cmd {
fn toggle(&self) -> Self {
match self {
Cmd::Inc(ref reg) | Cmd::Out(ref reg) => Cmd::Dec(reg.clone()),
Cmd::Dec(ref reg) => Cmd::Inc(reg.clone()),
Cmd::Toggle(ref reg) => Cmd::Inc(reg.clone()),
Cmd::Cpy(ref val, ref reg) => Cmd::Jnz(val.clone(), reg.to_string()),
Cmd::Jnz(ref val, ref reg) => Cmd::Cpy(val.clone(), reg.to_string()),
Cmd::Inc(reg) | Cmd::Out(reg) => Cmd::Dec(reg.clone()),
Cmd::Dec(reg) => Cmd::Inc(reg.clone()),
Cmd::Toggle(reg) => Cmd::Inc(reg.clone()),
Cmd::Cpy(val, reg) => Cmd::Jnz(val.clone(), reg.to_string()),
Cmd::Jnz(val, reg) => Cmd::Cpy(val.clone(), reg.to_string()),
}
}
fn is_valid(&self) -> bool {
match self {
Cmd::Inc(ref reg) => reg
Cmd::Inc(reg) => reg
.chars()
.all(|c| c == 'a' || c == 'b' || c == 'c' || c == 'd'),
Cmd::Dec(ref reg) => reg
Cmd::Dec(reg) => reg
.chars()
.all(|c| c == 'a' || c == 'b' || c == 'c' || c == 'd'),
Cmd::Toggle(ref reg) => true,
Cmd::Cpy(_, ref reg) => reg
Cmd::Toggle(reg) => true,
Cmd::Cpy(_, reg) => reg
.chars()
.all(|c| c == 'a' || c == 'b' || c == 'c' || c == 'd'),
Cmd::Jnz(_, ref reg) => reg
Cmd::Jnz(_, reg) => reg
.chars()
.all(|c| c == 'a' || c == 'b' || c == 'c' || c == 'd'),
Cmd::Out(_) => true,

View File

@ -104,9 +104,9 @@ fn run_part2(start: &str, rulebook: &str, generation: usize, cnt: i64) -> i64 {
let cnt_after_jumps = cnt + number_of_jumps * jump_cnt_change;
if DEBUG {
write_to_file(format!(
"Jumping {} iterations with a change of {} in count, so offset becomes {}. ",
number_of_jumps, jump_cnt_change, cnt_after_jumps
));
"Jumping {} iterations with a change of {} in count, so offset becomes {}. ",
number_of_jumps, jump_cnt_change, cnt_after_jumps
));
}
return iterate(vec, remainder, cnt_after_jumps, rulebook);
}
@ -206,14 +206,14 @@ fn sum_up(vec: &[bool], offset: i64) -> i64 {
"Found number of plants: {:?}",
vec.iter()
.enumerate()
.filter(|(_, &c)| c)
.filter(|(_, c)| **c)
.map(|(i, _)| i as i64 - offset)
.collect::<Vec<_>>()
));
}
vec.iter()
.enumerate()
.filter(|(_, &c)| c)
.filter(|(_, c)| **c)
.map(|(i, _)| i as i64 - offset)
.sum()
}

View File

@ -93,11 +93,7 @@ trait VZ {
impl VZ for bool {
fn vz(&self) -> i32 {
if *self {
1
} else {
-1
}
if *self { 1 } else { -1 }
}
}
fn approx_point_from_clique(
@ -217,7 +213,7 @@ fn bron_kerbosch() {
.map(|c| {
c.iter()
.enumerate()
.filter(|(_, &b)| b)
.filter(|(_, b)| **b)
.map(|(i, _)| i)
.collect::<Vec<_>>()
});
@ -313,7 +309,7 @@ fn kerb2(
.iter()
.zip(x.iter())
.enumerate()
.filter(|(_, (&p, &x))| p || x)
.filter(|(_, (p, x))| **p || **x)
.map(|(i, _)| i)
.max_by_key(|&i| graph[i].iter().filter(|&&b| b).count())
.unwrap();

View File

@ -107,7 +107,7 @@ fn run_from_input(input: &str) -> usize {
graph[next]
.iter()
.enumerate()
.filter(|(i, &x)| x && !used[*i])
.filter(|(i, x)| **x && !used[*i])
.for_each(|(i, _)| {
neig[i] = true;
});

View File

@ -109,7 +109,7 @@ fn find_most_asleep<const K: usize>(events: &[Event]) -> (u32, i32) {
let (id, &duration) = asleep_time
.iter()
.enumerate()
.max_by_key(|&(_, &time)| time)
.max_by_key(|&(_, time)| *time)
.unwrap();
(id as u32, duration)
}
@ -145,7 +145,7 @@ fn find_most_sleep_minute_for_id(events: &[Event], id: u32) -> (u32, u32) {
let (minute, &count) = asleep_time
.iter()
.enumerate()
.max_by_key(|&(_, &time)| time)
.max_by_key(|&(_, time)| *time)
.unwrap();
(minute as u32, count)
}
@ -177,7 +177,7 @@ fn find_most_frequent_minute_per_id<const K: usize>(events: &[Event]) -> Vec<(u3
let (freq_minute, &count) = dat
.iter()
.enumerate()
.max_by_key(|&(_, &time)| time)
.max_by_key(|&(_, time)| *time)
.unwrap();
res[idx] = (freq_minute as u32, count);
}

View File

@ -57,7 +57,7 @@ fn has_no_triple_doble(candidate: &[u8]) -> bool {
let mut last = None;
while let Some((i, j, x)) = last
.or_else(|| iter.next())
.and_then(|(i, &x)| iter.find(|&(_, &y)| y != x).map(|(j, x)| (i, j, x)))
.and_then(|(i, &x)| iter.find(|&(_, y)| *y != x).map(|(j, x)| (i, j, x)))
{
if j - i == 2 {
return true;

View File

@ -12,6 +12,58 @@ enum FnRes<T> {
Map(T),
}
struct Channel<'a, T> {
channel: &'a mut VecDeque<T>,
output: Option<VecDeque<T>>,
}
impl<T> Channel<'_, T> {
fn merge(&mut self) {
if let Some(mut x) = self.output.take() {
self.channel.append(&mut x);
}
}
fn push_back(&mut self, value: T) {
self.output
.as_mut()
.unwrap_or(&mut self.channel)
.push_back(value);
}
fn pop_front(&mut self) -> Option<T> {
self.channel.pop_front()
}
}
impl<'a, T> From<Channel<'a, T>> for &'a mut VecDeque<T> {
fn from(val: Channel<'a, T>) -> Self {
if let Some(mut x) = val.output {
val.channel.append(&mut x)
}
val.channel
}
}
impl<'a, T> From<&'a mut VecDeque<T>> for Channel<'a, T> {
fn from(channel: &'a mut VecDeque<T>) -> Self {
Channel {
channel,
output: None,
}
}
}
impl<'a, T> From<(&'a mut VecDeque<T>, ChannelMode)> for Channel<'a, T> {
fn from((channel, mode): (&'a mut VecDeque<T>, ChannelMode)) -> Self {
let output = if mode.is_dual() {
Some(VecDeque::new())
} else {
None
};
Channel { channel, output }
}
}
#[derive(PartialEq, Debug)]
pub struct State<const K: usize, T> {
prog: [T; K],
@ -40,7 +92,7 @@ fn calc<const K: usize, T: IdxNum>(
mut inv: Vec<T>,
op_code: usize,
fun: impl Fn(usize) -> (fn(T, T) -> (T, Option<usize>)),
msg: &mut VecDeque<T>,
msg: &mut Channel<'_, T>,
) -> Option<FnRes<T>> {
let mut inv_iter = inv.into_iter();
@ -60,7 +112,7 @@ fn op<const K: usize, T>(input: &[T; K], current: usize) -> Option<usize>
where
T: IdxNum,
{
input[current % K].try_into().ok()
input[current].try_into().ok()
}
fn r_op<const K: usize, T>(input: &[T; K], current: usize) -> Option<usize>
@ -85,14 +137,12 @@ fn simulate<const K: usize, T, I: Into<State<K, T>>>(
state: I,
fun: impl Fn(usize) -> (fn(T, T) -> (T, Option<usize>)),
abort: impl Fn(usize) -> bool,
channel: &mut VecDeque<T>,
mode: ChannelMode,
channel: &mut Channel<'_, T>,
) -> Result<[T; K], State<K, T>>
where
T: IdxNum,
{
let State { mut prog, mut pos } = state.into();
let mut out_channel = mode.is_dual().then_some(VecDeque::new());
loop {
if r_op(&prog, pos).is_some_and(&abort) {
break;
@ -105,9 +155,7 @@ where
};
let Some(op_res) = op_res else {
if let Some(mut c) = out_channel {
channel.append(&mut c)
}
// channel.merge();
return Err(State { prog, pos });
};
match op_res {
@ -121,16 +169,13 @@ where
prog[out] = value;
pos += 1;
} else {
out_channel.as_mut().unwrap_or(channel).push_back(value);
channel.push_back(value);
}
}
}
pos += input_incr + 1;
pos %= K;
}
if let Some(mut c) = out_channel {
channel.append(&mut c)
}
// channel.merge();
Ok(prog)
}
@ -145,7 +190,7 @@ fn out_idx<const K: usize, T: IdxNum>(input: &[T; K], current: usize) -> Option<
let mo = (0..input_par_num).fold(100, |acc, _| acc * 10);
let pos_mode = op_as_usize % (mo * 10) == op_as_usize % mo;
let subseq_idx = (current + input_par_num + 1 % K);
let subseq_idx = (current + input_par_num + 1);
let r = pos_mode
.then(|| input.get(subseq_idx))
@ -159,12 +204,12 @@ fn in_values<const K: usize, T: IdxNum>(input: &[T; K], current: usize) -> Vec<T
let op_as_usize: usize = r_op(input, current).unwrap();
(1..3)
.map(|i| (i + current) % K)
.map(|i| (i + current))
.zip(next_value_info(input, current))
.map(|(i, b)| (input.get(i).copied(), b))
.flat_map(|(i, pos_mode)| {
pos_mode.then_some(i).map_or(i, |i| {
i.and_then(|v| v.try_into().ok().map(|v| v % K))
i.and_then(|v| v.try_into().ok())
.and_then(|v| input.get(v))
.copied()
})
@ -199,8 +244,8 @@ fn get_reg_for_args<const K: usize, T>(input: &[T; K], mut operation: [T; 3]) ->
where
T: IdxNum,
{
let dos = input[operation[1].try_into().ok()? % K];
let tres = input[operation[2].try_into().ok()? % K];
let dos = input[operation[1].try_into().ok()?];
let tres = input[operation[2].try_into().ok()?];
operation[1] = dos;
operation[2] = tres;
@ -242,13 +287,7 @@ fn default_no_channel<const K: usize, T>(input: [T; K]) -> Result<[T; K], State<
where
T: IdxNum + std::ops::Mul<Output = T>,
{
simulate(
input,
def_fn,
|x| x == 99,
&mut Default::default(),
ChannelMode::Single,
)
channel_wrapper(input, &mut VecDeque::new(), ChannelMode::Single)
}
pub fn default_single_channel<const K: usize, T, I>(
input: I,
@ -258,7 +297,7 @@ where
T: IdxNum + std::ops::Mul<Output = T>,
I: Into<State<K, T>>,
{
simulate(input, def_fn, |x| x == 99, channel, ChannelMode::Single)
channel_wrapper(input, channel, ChannelMode::Single)
}
pub fn default_dual_channel<const K: usize, T, I>(
@ -269,9 +308,23 @@ where
T: IdxNum + std::ops::Mul<Output = T>,
I: Into<State<K, T>>,
{
simulate(input, def_fn, |x| x == 99, channel, ChannelMode::Dual)
channel_wrapper(input, channel, ChannelMode::Dual)
}
pub fn channel_wrapper<const K: usize, T, I>(
input: I,
channel: &mut VecDeque<T>,
mode: ChannelMode,
) -> Result<[T; K], State<K, T>>
where
T: IdxNum + std::ops::Mul<Output = T>,
I: Into<State<K, T>>,
{
let mut channel = Channel::from((channel, mode));
let res = simulate(input, def_fn, |x| x == 99, &mut channel);
channel.merge();
res
}
#[test]
fn day2_test() {
let first_ex: [usize; 12] = [1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50];

View File

@ -37,7 +37,7 @@ fn find_start_points(input: &[Vec<u8>]) -> Vec<(usize, usize)> {
.flat_map(|(row_idx, row)| {
row.iter()
.enumerate()
.filter(|(_, &el)| el == 0)
.filter(|(_, el)| **el == 0)
.map(|(i, _)| (row_idx, i))
.collect::<Vec<(usize, usize)>>()
})