10-25 fin
This commit is contained in:
parent
c6ab61674c
commit
b08b39a16a
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
||||
mod day1;
|
||||
mod day10;
|
||||
mod day2;
|
||||
mod day3;
|
||||
mod day4;
|
||||
|
||||
@ -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
207
src/helper/lgs.rs
Normal 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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user