10-25 fin

This commit is contained in:
hendrik 2026-01-10 13:13:42 +01:00
parent c6ab61674c
commit b08b39a16a
5 changed files with 492 additions and 1599 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
mod day1;
mod day10;
mod day2;
mod day3;
mod day4;

View File

@ -511,6 +511,7 @@ macro_rules! impl_bit_type_selector {
};
}
// TODO: last neeeds to go in next line -> for 16 we consider 17 digits in clip
impl_bit_type_selector!(Bits8 => [0, 1, 2, 3, 4, 5, 6, 7, 8]);
impl_bit_type_selector!(Bits16 => [9, 10, 11, 12, 13, 14, 15, 16]);
impl_bit_type_selector!(Bits32 => [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]);
@ -564,6 +565,12 @@ where
BitMapSized { inner: bitmap }
}
pub fn from_value(value: <<() as BitTypeSelector<X>>::Marker as BitType>::Type) -> Self {
let mut bitmap = BitMap::from_value(value);
bitmap.clip_to(X as u32);
BitMapSized { inner: bitmap }
}
pub fn set(&mut self, index: u32) {
// TBD: or rather just ignore this?
if index >= X {

207
src/helper/lgs.rs Normal file
View File

@ -0,0 +1,207 @@
use crate::helper::num::gcd;
#[derive(Debug, Clone)]
struct Lgs<T>(Vec<Vec<isize>>, Vec<T>);
trait Comb {
fn multiply(&self, fac: isize) -> Self;
fn add(&self, other: &Self, fac: isize) -> Self;
fn sgn(&self) -> isize;
fn reduce(&self, fac: isize) -> Self;
}
impl<T: Comb + std::fmt::Debug + Default + PartialEq + Clone> Lgs<T> {
fn swap(&mut self, i: usize, j: usize) {
if i != j {
self.0.swap(i, j);
self.1.swap(i, j);
}
}
fn print_mat(&self) {
for i in 0..self.0.len() {
println!("{:?} | {:?}", self.0[i], self.1[i]);
}
}
fn write_mat(&self) -> String {
let mut res = String::new();
for i in 0..self.0.len() {
res.push_str(&format!("{:?} | {:?}\n", self.0[i], self.1[i]));
}
res
}
fn enusure_diag(&mut self, i: usize, k: usize) -> Result<(), ()> {
for j in i..self.0.len() {
if self.0.len() <= j {
panic!("Index out of bounds - {i}");
}
if self.0[j][k] != 0 {
self.swap(i, j);
return Ok(());
}
}
Err(())
}
fn combine(&mut self, i: usize, j: usize, fac_i: isize, fac_j: isize) {
for col in 0..self.0[j].len() {
self.0[j][col] = self.0[j][col] * fac_j + self.0[i][col] * fac_i;
}
self.1[j] = self.1[j].multiply(fac_j).add(&self.1[i].multiply(fac_i), 1);
}
fn scale_row(&mut self, i: usize, fac: isize) {
for col in 0..self.0[i].len() {
self.0[i][col] = self.0[i][col] * fac;
}
self.1[i] = self.1[i].multiply(fac);
}
fn add_row(&mut self, i: usize) {
self.0.insert(i, vec![0isize; self.0[0].len()]);
self.1.insert(i, T::default());
}
fn add_neg_unit_row(&mut self, i: usize) {
self.0.insert(i, vec![0isize; self.0[0].len()]);
self.0[i][i] = -1;
self.1.insert(i, T::default());
}
fn pivot_i(&mut self, i: usize, k: usize) -> Result<(), ()> {
self.enusure_diag(i, k)?;
let diag = self.0[i][k];
assert!(
diag != 0,
"Diagonal element is zero after enusure_dia {i} {k}g"
);
for j in 0..self.0.len() {
if i == j || self.0[j][k] == 0 {
continue;
}
let fac_i = -self.0[j][k];
self.combine(i, j, fac_i, diag);
}
Ok(())
}
fn diagonalize(&mut self) {
let row_dim = self.0.len();
let col_dim = self.0[0].len();
let mut row = 0;
let mut pivot_r = None;
let mut pivot_c = 0;
for i in 0..col_dim {
if let Ok(()) = self.pivot_i(pivot_c, i) {
pivot_r = Some(i);
pivot_c += 1;
}
println!("After pivoting col {}:", i);
self.print_mat();
}
}
fn rm_null_rows(&mut self) {
let mut r = 0;
while r < self.0.len() {
if self.0[r].iter().all(|&x| x == 0) && self.1[r] == T::default() {
self.0.remove(r);
self.1.remove(r);
} else {
r += 1;
}
}
}
fn reduce(&mut self, row: usize) {
let i = row;
let mut div = None;
for x in self.0[i].iter().filter(|x| **x != 0) {
if x.abs() == 1 {
div = Some(1);
break;
}
div = Some(div.map_or(x.abs(), |d| gcd(d, x.abs())));
}
let div = div.unwrap_or(1);
if div > 1 {
for num in self.0[i].iter_mut() {
*num /= div;
}
self.1[i] = self.1[i].reduce(div);
}
}
fn normalize_sq(&mut self) -> Result<Vec<usize>, ()> {
let mut col = 0;
self.rm_null_rows();
let mut pivot_rows = Vec::new();
let mut r = 0;
loop {
if self.0.get(r).and_then(|r| r.get(col)).is_none() {
break;
}
self.reduce(r);
if self.0[r][col] != 0 {
if self.0[r][col].signum() < 0 {
self.scale_row(r, -1);
}
pivot_rows.push(col);
} else if self.0[r].iter().all(|&x| x == 0) && self.1[r] != T::default() {
return Err(());
} else {
self.add_neg_unit_row(r);
self.print_mat();
}
col += 1;
r += 1;
}
while self.0.len() < self.0[0].len() {
self.add_neg_unit_row(self.0.len());
}
self.print_mat();
Ok(pivot_rows)
}
fn normalize(&mut self) -> Result<Vec<usize>, ()> {
let mut col = 0;
self.rm_null_rows();
let mut pic_rows = Vec::new();
let mut r = 0;
loop {
if self.0.get(r).and_then(|r| r.get(col)).is_none() {
break;
}
// println!("Reducing row {} {col}- {:?}", r, self.0[r]);
self.reduce(r);
if self.0[r][col] != 0 {
if self.0[r][col].signum() < 0 {
self.scale_row(r, -1);
}
pic_rows.push(col);
r += 1;
} else if self.0[r].iter().all(|&x| x == 0) && self.1[r] != T::default() {
return Err(());
}
col += 1;
}
Ok(pic_rows)
}
fn col(&self, i: usize) -> Vec<isize> {
self.0.iter().map(|row| row[i]).collect()
}
fn current_sol_space(&mut self) -> (Vec<Vec<isize>>, Vec<T>) {
let piv_pos = self.normalize_sq().unwrap();
(
(0..self.0[0].len())
.filter(|&i| !piv_pos.contains(&i))
.map(|i| self.col(i))
.collect(),
self.1.clone(),
)
}
}

View File

@ -2,6 +2,18 @@ use std::ops::{Add, Sub};
use crate::helper::inv::{BitMap0, UInt};
pub fn gcd<T>(a: T, b: T) -> T
where
T: Copy + PartialOrd + std::ops::Rem<Output = T> + Num,
{
if a == T::zero() || b == T::zero() || a == b {
a.max(b)
} else if a > b {
gcd(a % b, b)
} else {
gcd(a, b % a)
}
}
pub trait Num:
UnitNum + Ord + Eq + std::fmt::Debug + Add<Self, Output = Self> + Sub<Self, Output = Self>
{