From 71db7682271acfddd4b54b6188d9a7a97839bc5e Mon Sep 17 00:00:00 2001 From: Andre Henriques Date: Fri, 12 Dec 2025 20:58:10 +0000 Subject: [PATCH] Day 12 --- Cargo.toml | 3 + a | 22 + src/day10/main.rs | 534 +++++++++-------------- src/day12/act.txt | 1030 ++++++++++++++++++++++++++++++++++++++++++++ src/day12/main.rs | 448 +++++++++++++++++++ src/day12/test.txt | 33 ++ 6 files changed, 1734 insertions(+), 336 deletions(-) create mode 100644 a create mode 100644 src/day12/act.txt create mode 100644 src/day12/main.rs create mode 100644 src/day12/test.txt diff --git a/Cargo.toml b/Cargo.toml index 2ecdeb4..8016af0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,9 @@ path = "src/day10/main.rs" name = "day11" path = "src/day11/main.rs" +[[bin]] +name = "day12" +path = "src/day12/main.rs" [dependencies] anyhow = "1.0.100" diff --git a/a b/a new file mode 100644 index 0000000..c2e80af --- /dev/null +++ b/a @@ -0,0 +1,22 @@ +Found Valid ans 0 + + + + + + +Could not Find valid answer 1 + + + + + + +Could not Find valid answer 2 + + + + + + +sol1: 1 diff --git a/src/day10/main.rs b/src/day10/main.rs index ac4b79a..c27ddd7 100644 --- a/src/day10/main.rs +++ b/src/day10/main.rs @@ -1,11 +1,10 @@ use anyhow::{Ok, Result}; use core::panic; -use rand::seq::{IteratorRandom, SliceRandom}; +use rand::seq::SliceRandom; use std::{ collections::{HashMap, HashSet, VecDeque}, fmt::Debug, fs, - io::{self, prelude::*}, ops::RangeInclusive, u64, vec, }; @@ -292,7 +291,6 @@ impl Simplyfy for Vec { trait EqSystem { fn cleanup(&mut self) -> Option; fn cleanup_quiet(&mut self, allow_vars: bool) -> Option; - fn apply(&mut self, var: u64, replc: Vec) -> &mut Self; fn apply_num(&mut self, var: u64, replc: i64) -> &mut Self; // Return true if success fn find_1_coe_on_other_side_and_swap(&mut self, k: EqPart) -> bool; @@ -304,10 +302,12 @@ impl EqSystem for HashMap> { let mut new_values = 0; let mut to_delete = Vec::new(); for (k, v) in self.iter() { - println!("{:?} = {:?}", k, v); let idx = match k { EqPart::Var(idx, _) => idx, - _ => continue, + _ => { + println!("{:?} = {:?}", k, v); + continue; + } }; if v.len() == 1 { if let EqPart::Num(v) = v[0] { @@ -315,18 +315,19 @@ impl EqSystem for HashMap> { println!("\t Invalid state {}! applying", idx); return None; } - println!("\t Found part sol for {}! applying", idx); to_delete.push(*k); new_values += v as u64; } } else if v.len() == 0 { - println!("\t Found part sol for {} it's 0!", idx); to_delete.push(*k); } } + print!("Found: "); for i in to_delete { - self.remove(&i); + let r = self.remove(&i); + print!("{:?} {:?} ", i, r.unwrap()); } + print!("\n"); return Some(new_values); } @@ -334,7 +335,7 @@ impl EqSystem for HashMap> { let mut new_values = 0; let mut to_delete = Vec::new(); for (k, v) in self.iter() { - let idx = match k { + let _ = match k { EqPart::Var(idx, _) => idx, EqPart::Num(n) => { if allow_vars { @@ -368,13 +369,6 @@ impl EqSystem for HashMap> { return Some(new_values); } - fn apply(&mut self, var: u64, replc: Vec) -> &mut Self { - for v in self.values_mut() { - v.smart_insert(EqPart::Var(var, 1), replc.clone()); - } - self - } - fn apply_num(&mut self, var: u64, replc: i64) -> &mut Self { for v in self.values_mut() { if replc == 0 { @@ -517,34 +511,6 @@ impl EqSystem for HashMap> { } } -fn get_presses_for_m(target: &Vec, buttons: &Vec>, i: usize) -> Option { - if i >= buttons.len() { - return None; - } - let button: &Vec = buttons[i].as_ref(); - - let max_can_add = button - .iter() - .fold(u64::MAX, |m, i| m.min(target[*i as usize])); - if max_can_add == 0 { - return get_presses_for_m(target, &buttons, i + 1); - } - for to_remove in (0..=max_can_add).rev() { - let mut n_target = target.clone(); - for i in button.iter() { - n_target[*i as usize] -= to_remove; - } - // println!("max {:?}: {} - {:?}", button, to_remove, n_target); - if n_target.iter().all(|a| *a == 0) { - return Some(to_remove); - } - if let Some(v) = get_presses_for_m(&n_target, &buttons, i + 1) { - return Some(to_remove + v); - } - } - return None; -} - fn main() -> Result<()> { let text = fs::read_to_string("src/day10/act.txt")?; @@ -698,221 +664,215 @@ fn main() -> Result<()> { } } - // if try_later.len() >= 1 { - // fn try_later_mult( - // hash_t: &mut HashMap>, - // machine: &Machine, - // try_later: Vec, - // ) -> (u64, Vec) { - // let mut sol2 = hash_t.cleanup().unwrap(); + if try_later.len() >= 1 { + fn try_later_mult( + hash_t: &mut HashMap>, + machine: &Machine, + try_later: Vec, + ) -> (u64, Vec) { + let mut sol2 = hash_t.cleanup().unwrap(); - // println!("Something failed to get need to try later"); - // for (k, v) in hash_t.iter() { - // println!("{:?} = {:?}", k, v) - // } + println!("Something failed to get need to try later"); + for (k, v) in hash_t.iter() { + println!("{:?} = {:?}", k, v) + } - // let mut try_later_2 = Vec::new(); - // 'try_later: for i in try_later { - // // Get the one based on the index - // let cur_options = hash_t.remove(&EqPart::Index(i)).unwrap(); - // // Insert the actual value one - // let k = EqPart::Num(machine.req[i] as i64); - // hash_t.insert(k, cur_options); + let mut try_later_2 = Vec::new(); + 'try_later: for i in try_later { + // Get the one based on the index + let cur_options = hash_t.remove(&EqPart::Index(i)).unwrap(); + // Insert the actual value one + let k = EqPart::Num(machine.req[i] as i64); + hash_t.insert(k, cur_options); - // if !hash_t.find_1_coe_on_other_side_and_swap(k) { - // // removed value based one not to screw with next step - // let cur_options = hash_t.remove(&k).unwrap(); - // hash_t.insert(EqPart::Index(i), cur_options.clone()); + if !hash_t.find_1_coe_on_other_side_and_swap(k) { + // removed value based one not to screw with next step + let cur_options = hash_t.remove(&k).unwrap(); + hash_t.insert(EqPart::Index(i), cur_options.clone()); - // // Ok maybe we can swap some things around - // let vars: Vec = cur_options - // .iter() - // .filter(|a| a.is_var()) - // .map(|a| { - // let (idx, _) = a.to_var(); - // idx - // }) - // .collect(); + // Ok maybe we can swap some things around + let vars: Vec = cur_options + .iter() + .filter(|a| a.is_var()) + .map(|a| { + let (idx, _) = a.to_var(); + idx + }) + .collect(); - // let mut possible_swap = Vec::new(); + let mut possible_swap = Vec::new(); - // for (k, v) in hash_t.clone() { - // if k.is_var() { - // let mut count_exact = 0; - // for i in v.iter() { - // if i.is_var() { - // let (_id, c) = i.to_var(); - // if c.abs() == 1 { - // count_exact += 1; - // } - // } - // } - // println!( - // "Trying to find swap on {:?} = {:?} =====> {} {}({:?})", - // k, - // v, - // count_exact, - // vars.len(), - // vars - // ); - // if count_exact >= 1 { - // possible_swap.push(k.clone()); - // } - // } - // } + for (k, v) in hash_t.clone() { + if k.is_var() { + let mut count_exact = 0; + for i in v.iter() { + if i.is_var() { + let (_id, c) = i.to_var(); + if c.abs() == 1 { + count_exact += 1; + } + } + } + println!( + "Trying to find swap on {:?} = {:?} =====> {} {}({:?})", + k, + v, + count_exact, + vars.len(), + vars + ); + if count_exact >= 1 { + possible_swap.push(k.clone()); + } + } + } - // if possible_swap.len() >= 1 { - // println!("We can swap! picking randomly from {:?}", possible_swap); + if possible_swap.len() >= 1 { + println!("We can swap! picking randomly from {:?}", possible_swap); - // let k = *possible_swap.choose(&mut rand::thread_rng()).unwrap(); + let k = *possible_swap.choose(&mut rand::thread_rng()).unwrap(); - // if !hash_t.find_1_coe_on_other_side_and_swap(k) { - // panic!("unrechable"); - // } + if !hash_t.find_1_coe_on_other_side_and_swap(k) { + panic!("unrechable"); + } - // sol2 += hash_t.cleanup().unwrap(); + sol2 += hash_t.cleanup().unwrap(); - // println!("Swapped!"); - // // Get the one based on the index - // let cur_options = hash_t.remove(&EqPart::Index(i)).unwrap(); - // // Insert the actual value one - // let k = EqPart::Num(machine.req[i] as i64); - // hash_t.insert(k, cur_options.clone()); + println!("Swapped!"); + // Get the one based on the index + let cur_options = hash_t.remove(&EqPart::Index(i)).unwrap(); + // Insert the actual value one + let k = EqPart::Num(machine.req[i] as i64); + hash_t.insert(k, cur_options.clone()); - // if !hash_t.find_1_coe_on_other_side_and_swap(k) { - // println!( - // "Failed trying later {:?} try_ing one more time even with swap", - // cur_options - // ); - // let cur_options = hash_t.remove(&k).unwrap(); - // hash_t.insert(EqPart::Index(i), cur_options); - // // In this case we don't restore to the index based one - // try_later_2.push(i); - // continue 'try_later; - // } + if !hash_t.find_1_coe_on_other_side_and_swap(k) { + println!( + "Failed trying later {:?} try_ing one more time even with swap", + cur_options + ); + let cur_options = hash_t.remove(&k).unwrap(); + hash_t.insert(EqPart::Index(i), cur_options); + // In this case we don't restore to the index based one + try_later_2.push(i); + continue 'try_later; + } - // continue 'try_later; - // } - // println!( - // "Failed trying later {:?} try_ing one more time", - // cur_options - // ); - // try_later_2.push(i); - // continue; - // } - // } + continue 'try_later; + } + println!( + "Failed trying later {:?} try_ing one more time", + cur_options + ); + try_later_2.push(i); + continue; + } + } - // let mut try_later_3 = Vec::new(); - // if try_later_2.len() > 0 { - // println!("!!!Still some failirues last try!!!"); - // sol2 += hash_t.cleanup().unwrap(); - // for i in try_later_2 { - // let k_org = EqPart::Index(i); - // println!("Trying to find divisors for {:?}", k_org); - // if !k_org.is_var() { - // let mut ops = hash_t.remove(&k_org).unwrap(); - // let org = ops.clone(); - // let num = ops.pop_num().unwrap_or(0); - // let k = machine.req[i] as i64 + -num; - // if ops.len() == 0 && k == 0 { - // println!("Found inline sol for {}", i); - // continue; - // } - // let div = if ops.len() > 1 { - // // - // // Check to see if everyone is div by min - // // - // let vars: Vec = ops - // .clone() - // .into_iter() - // .filter(|a| a.is_var()) - // .map(|a| a.to_var()) - // .collect(); + let mut try_later_3 = Vec::new(); + if try_later_2.len() > 0 { + println!("!!!Still some failirues last try!!!"); + sol2 += hash_t.cleanup().unwrap(); + for i in try_later_2 { + let k_org = EqPart::Index(i); + println!("Trying to find divisors for {:?}", k_org); + if !k_org.is_var() { + let mut ops = hash_t.remove(&k_org).unwrap(); + let org = ops.clone(); + let num = ops.pop_num().unwrap_or(0); + let k = machine.req[i] as i64 + -num; + if ops.len() == 0 && k == 0 { + println!("Found inline sol for {}", i); + continue; + } + let div = if ops.len() > 1 { + // + // Check to see if everyone is div by min + // + let vars: Vec = ops + .clone() + .into_iter() + .filter(|a| a.is_var()) + .map(|a| a.to_var()) + .collect(); - // let min = vars.iter().fold(i64::MAX, |m, (_, c)| m.min(c.abs())); + let min = vars.iter().fold(i64::MAX, |m, (_, c)| m.min(c.abs())); - // if !(k.abs() % min == 0 - // && vars.iter().all(|(_, v)| v.abs() % min == 0)) - // { - // println!( - // "--Could not find eql divisor for {} = {:?}", - // machine.req[i] as i64, org - // ); - // hash_t.insert(EqPart::Index(i), org); - // try_later_3.push(i); - // continue; - // } + if !(k.abs() % min == 0 + && vars.iter().all(|(_, v)| v.abs() % min == 0)) + { + println!( + "--Could not find eql divisor for {} = {:?}", + machine.req[i] as i64, org + ); + hash_t.insert(EqPart::Index(i), org); + try_later_3.push(i); + continue; + } - // min - // } else { - // let (_id, v) = ops[0].to_var(); - // if k.abs() % v.abs() != 0 { - // println!( - // "Could not find eql divisor for {} = {:?}", - // machine.req[i], org - // ); - // hash_t.insert(EqPart::Index(i), org); - // try_later_3.push(i); - // continue; - // } - // v.abs() - // }; + min + } else { + let (_id, v) = ops[0].to_var(); + if k.abs() % v.abs() != 0 { + println!( + "Could not find eql divisor for {} = {:?}", + machine.req[i], org + ); + hash_t.insert(EqPart::Index(i), org); + try_later_3.push(i); + continue; + } + v.abs() + }; - // println!( - // "Found divisor for {:?} => {} = {:?} at {}", - // k_org, machine.req[i], org, div, - // ); + println!( + "Found divisor for {:?} => {} = {:?} at {}", + k_org, machine.req[i], org, div, + ); - // let k = k / div; - // let ops: Vec = ops - // .into_iter() - // .map(|mut m| { - // m.i_div(div); - // m - // }) - // .collect(); + let k = k / div; + let ops: Vec = ops + .into_iter() + .map(|mut m| { + m.i_div(div); + m + }) + .collect(); - // let k = EqPart::Num(k); - // hash_t.insert(k, ops); - // if !hash_t.find_1_coe_on_other_side_and_swap(k) { - // panic!( - // "this should be impossilbe we kinda of grarantee that there will always a div" - // ); - // } - // } - // } + let k = EqPart::Num(k); + hash_t.insert(k, ops); + if !hash_t.find_1_coe_on_other_side_and_swap(k) { + panic!( + "this should be impossilbe we kinda of grarantee that there will always a div" + ); + } + } + } - // sol2 += hash_t.cleanup().unwrap(); - // } - // return (sol2, try_later_3); - // } + sol2 += hash_t.cleanup().unwrap(); + } + return (sol2, try_later_3); + } - // let mut loop_c = 1; - // loop { - // let (t_sol2, t2) = try_later_mult(&mut hash_t, &machine, try_later); - // sol2 += t_sol2; - // if t2.len() == 0 { - // break; - // } - // if loop_c % 1000 == 0 { - // println!("Could not simply any fruther"); - // for i in t2 { - // let mut to_r = hash_t.remove(&EqPart::Index(i)).unwrap(); - // let num = to_r.pop_num().unwrap_or(0); - // hash_t.insert(EqPart::Num(machine.req[i] as i64 - num), to_r); - // } - // sol2 += hash_t.cleanup().unwrap(); - // break; - // } - // try_later = t2; - // loop_c += 1; - // } - // } - - for i in try_later { - let mut to_r = hash_t.remove(&EqPart::Index(i)).unwrap(); - let num = to_r.pop_num().unwrap_or(0); - hash_t.insert(EqPart::Num(machine.req[i] as i64 - num), to_r); + let mut loop_c = 1; + loop { + let (t_sol2, t2) = try_later_mult(&mut hash_t, &machine, try_later); + sol2 += t_sol2; + if t2.len() == 0 { + break; + } + if loop_c % 50 == 0 { + println!("Could not simply any fruther"); + for i in t2 { + let mut to_r = hash_t.remove(&EqPart::Index(i)).unwrap(); + let num = to_r.pop_num().unwrap_or(0); + hash_t.insert(EqPart::Num(machine.req[i] as i64 - num), to_r); + } + sol2 += hash_t.cleanup().unwrap(); + break; + } + try_later = t2; + loop_c += 1; + } } sol2 += hash_t.cleanup().unwrap(); @@ -929,90 +889,6 @@ fn main() -> Result<()> { println!("colected vars {:?}", vars); - // loop { - // let mut cleanup: Vec = Vec::new(); - // 'vars: for v in vars.iter() { - // let mut neg_one_count = 0; - // 'part: for part in hash_t.values() { - // let n = match part - // .iter() - // .find(|a| if let EqPart::Num(_) = *a { true } else { false }) - // { - // Some(EqPart::Num(v)) => v, - // None => &0, - // a => panic!("not sure what to do here {:?} -> {:?}", part, a), - // }; - // let mut other_vars = 0; - // let mut our_found = false; - // for item in part.iter() { - // if let EqPart::Var(idx, v_value) = item { - // if *idx != *v { - // other_vars += 1; - // } else { - // our_found = true; - // // If the value is negative one it does not change the number - // // of clicks so we can remove if all other parts are also right - // if *v_value == -1 { - // if neg_one_count == 0 { - // neg_one_count += 1; - // continue 'part; - // } - // } - // // If the number is positive and our value - // // is negative we can not skip it because this means - // // that we might be able to lower the num - // if *n > 0 && *v_value < 0 { - // println!( - // "cannot clean up {} because number is positive and we are negative", - // (v + 97) as u8 as char - // ); - // continue 'vars; - // } - - // // If the number is negative and our value - // // is positive we can not skip it because this means - // // that we MUST be able to raise the num - // if *n < 0 && *v_value > 0 { - // println!( - // "cannot clean up {} because number is negative and we are positive", - // (v + 97) as u8 as char - // ); - // continue 'vars; - // } - // } - // } - // } - // // If our is not found then we can just skip this part - // if !our_found { - // continue 'part; - // } - // // If one of the other checks did not catch here - // // but we have other vars we cannot really clean it up - // if other_vars > 0 { - // println!( - // "cannot clean up {} because there are other var", - // (v + 97) as u8 as char - // ); - // continue 'vars; - // } - // } - // // If were able pass through all the parts that - // // means we are able to clean up - // println!("Clearning up {}", (v + 97) as u8 as char); - // cleanup.push(*v); - // } - // if cleanup.len() == 0 { - // break; - // } - // for var in cleanup { - // for v in hash_t.values_mut() { - // v.smart_insert(EqPart::Var(var, 1), Vec::new()); - // } - // vars.remove(&var); - // } - // sol2 += hash_t.cleanup().unwrap(); - // } - if vars.len() == 0 { println!("finsihed machine with {}", sol2); sol2_main += sol2; @@ -1031,24 +907,12 @@ fn main() -> Result<()> { if var.is_none() { continue 'part; } - let (idx, var) = var.unwrap(); + let (_, var) = var.unwrap(); - // n is positive and we are negative then - // we can only really go up to the n if n > 0 && var < 0 && part.len() == 2 { max = max.min(n / var.abs()); } - // n is positive and we are negative and we are the - // only things here - // then we have a min - // println!( - // "h: {} {} {} {}", - // (idx + 97) as u8 as char, - // n, - // var, - // part.len() - // ); if n < 0 && var > 0 && part.len() == 2 { min = min.max(((n.abs() as f64) / var as f64).ceil() as i64); } @@ -1130,8 +994,6 @@ fn main() -> Result<()> { println!("finsihed machine with {}", sol2); sol2_main += sol2; - - // panic!("todo"); } println!("Sol2: {}", sol2_main); diff --git a/src/day12/act.txt b/src/day12/act.txt new file mode 100644 index 0000000..39f2f06 --- /dev/null +++ b/src/day12/act.txt @@ -0,0 +1,1030 @@ +0: +#.# +### +#.# + +1: +#.. +##. +### + +2: +.## +### +#.# + +3: +### +#.# +#.# + +4: +##. +##. +### + +5: +.## +##. +#.. + +41x38: 19 31 25 29 22 29 +36x43: 23 27 31 27 29 30 +44x48: 56 54 46 78 43 46 +37x39: 42 32 34 40 36 38 +35x37: 40 31 30 30 35 33 +43x44: 47 33 35 34 22 24 +38x37: 23 21 25 23 24 27 +39x39: 33 33 48 42 40 37 +36x50: 31 29 32 43 29 28 +38x48: 45 39 47 49 52 48 +47x50: 60 53 62 61 59 68 +47x49: 57 64 62 70 47 54 +48x39: 36 33 36 31 35 37 +37x42: 26 28 25 31 30 28 +48x48: 65 50 51 54 71 64 +43x46: 51 54 49 47 54 50 +50x38: 36 30 29 24 41 32 +50x44: 49 51 75 50 56 57 +37x37: 31 36 30 36 41 38 +40x46: 40 55 48 47 48 46 +38x50: 46 32 27 26 28 32 +48x47: 59 51 53 66 60 57 +50x43: 58 52 62 53 62 39 +48x42: 44 35 39 38 32 35 +37x43: 33 47 42 44 37 44 +45x45: 36 35 33 38 44 39 +44x35: 27 29 15 20 30 33 +38x46: 21 32 28 38 33 27 +50x43: 36 46 27 39 38 38 +37x43: 38 40 48 36 39 45 +43x40: 23 33 35 29 27 34 +49x36: 25 30 32 29 34 42 +46x48: 55 61 48 63 54 61 +48x42: 34 38 37 32 41 42 +38x42: 40 42 35 49 34 48 +48x47: 40 37 42 48 37 35 +38x39: 25 23 24 30 24 29 +50x36: 38 38 24 31 26 34 +50x47: 35 29 49 45 49 32 +37x35: 21 37 36 43 33 29 +47x49: 32 43 39 35 34 56 +36x47: 24 36 26 38 30 26 +43x38: 25 21 28 24 41 29 +43x38: 39 53 44 40 36 41 +39x46: 44 38 39 48 56 52 +43x43: 48 46 39 56 49 46 +45x37: 34 29 31 26 32 28 +42x48: 56 36 47 63 50 58 +37x46: 35 25 19 28 42 30 +49x50: 51 40 36 49 43 37 +43x48: 54 63 61 39 52 49 +36x35: 40 24 23 38 31 39 +39x49: 41 60 53 47 46 49 +37x43: 26 21 23 32 29 36 +48x43: 35 31 43 46 30 39 +36x44: 25 20 31 35 29 27 +39x43: 39 44 36 47 48 45 +49x37: 29 38 36 37 29 22 +50x44: 38 33 44 35 37 36 +48x37: 38 36 49 44 63 41 +44x35: 28 26 25 31 22 22 +48x37: 50 40 50 55 37 39 +42x40: 22 27 31 25 35 41 +44x41: 31 27 38 26 32 28 +50x44: 58 59 55 56 55 56 +44x36: 36 43 38 48 39 40 +37x44: 40 40 40 45 52 30 +36x47: 22 31 28 27 38 34 +36x49: 41 29 26 26 42 28 +35x41: 22 26 30 17 27 21 +35x39: 17 29 29 16 23 28 +48x41: 45 49 41 58 49 65 +42x35: 39 40 31 39 37 42 +41x47: 30 38 36 37 20 33 +39x40: 41 39 41 38 41 40 +47x41: 57 60 42 43 42 56 +38x48: 46 38 52 55 48 38 +45x46: 54 52 61 50 58 40 +35x46: 21 29 35 25 21 33 +46x42: 36 39 36 42 25 32 +42x36: 35 23 32 29 22 27 +39x49: 38 40 31 42 31 26 +39x44: 28 33 29 24 31 36 +44x47: 55 38 64 57 47 56 +46x42: 38 45 53 44 62 57 +48x45: 50 57 38 58 72 59 +46x45: 47 47 60 55 63 43 +46x45: 56 53 51 48 57 54 +46x41: 27 28 40 40 29 31 +49x49: 53 69 50 72 62 66 +47x38: 25 34 25 25 36 35 +46x47: 47 60 62 53 57 54 +36x50: 35 28 39 29 27 33 +48x44: 49 48 69 53 55 49 +35x35: 30 31 30 29 34 36 +38x49: 36 30 33 28 37 27 +44x47: 51 51 55 64 52 42 +47x37: 28 25 26 33 31 36 +38x50: 48 51 52 41 54 46 +38x39: 27 25 28 22 26 27 +45x47: 51 50 49 64 47 68 +37x49: 43 54 50 42 45 46 +39x43: 36 28 32 33 28 25 +43x40: 37 41 35 47 54 53 +48x48: 55 72 62 55 55 57 +39x46: 24 30 44 27 39 31 +43x47: 27 32 46 44 28 32 +48x45: 45 45 37 37 35 40 +41x40: 28 30 38 18 33 22 +35x42: 42 31 35 36 40 43 +42x47: 54 49 52 53 44 52 +46x38: 46 48 47 49 37 42 +38x42: 46 34 37 51 28 52 +39x39: 23 38 34 58 40 42 +49x48: 58 58 69 58 60 58 +46x48: 64 60 50 50 58 59 +49x44: 64 47 44 59 61 56 +49x43: 42 41 77 49 54 62 +39x47: 44 42 38 56 54 48 +47x45: 51 49 56 61 48 62 +39x42: 51 40 38 32 49 42 +36x43: 25 27 35 29 20 31 +38x49: 51 40 51 54 49 38 +41x37: 21 26 26 26 29 27 +39x50: 39 52 60 38 53 62 +37x49: 54 38 47 49 44 46 +45x48: 62 66 41 53 52 62 +39x39: 37 37 42 33 41 46 +40x40: 27 35 25 29 35 17 +44x42: 49 37 51 48 53 44 +46x41: 39 56 47 49 54 46 +37x43: 49 36 41 49 29 40 +43x43: 52 50 35 55 44 50 +42x43: 51 36 44 43 55 48 +41x41: 24 30 31 24 26 34 +44x42: 44 41 54 45 56 42 +46x46: 57 52 59 50 59 46 +46x35: 31 26 26 23 27 31 +39x36: 35 29 35 43 26 52 +44x50: 59 58 55 56 65 42 +41x37: 37 24 21 18 26 30 +48x38: 49 50 37 51 48 46 +46x36: 26 36 28 30 33 26 +46x38: 27 28 36 33 22 33 +49x48: 40 49 40 35 33 59 +41x36: 31 25 28 19 27 26 +47x43: 38 33 44 33 25 36 +40x35: 27 25 26 18 25 21 +46x47: 38 46 41 34 38 27 +48x38: 24 31 30 33 41 33 +40x38: 23 22 34 26 23 27 +38x44: 37 44 58 34 46 37 +47x49: 56 53 60 64 68 50 +42x40: 38 30 28 35 22 28 +50x49: 39 39 51 40 38 48 +38x46: 38 33 31 27 27 24 +44x50: 55 50 70 60 46 57 +47x41: 45 52 44 50 55 52 +38x35: 33 35 23 48 30 37 +40x40: 31 61 36 50 31 40 +41x36: 39 36 38 34 40 41 +40x39: 39 40 43 42 42 32 +37x43: 40 27 23 28 30 19 +37x45: 50 47 42 35 43 39 +42x42: 37 53 45 45 49 43 +45x47: 33 40 33 44 34 41 +47x40: 31 38 34 30 32 29 +47x37: 41 53 46 35 44 52 +40x50: 56 65 47 43 45 55 +39x47: 40 49 60 48 35 52 +47x50: 46 38 31 39 45 40 +38x47: 26 27 30 43 34 19 +37x44: 44 36 48 37 41 45 +43x48: 42 57 52 58 43 72 +46x50: 37 36 44 54 35 33 +40x39: 24 23 26 30 36 29 +49x36: 29 32 40 33 34 24 +48x50: 38 35 43 41 43 55 +44x41: 21 37 33 36 25 29 +50x37: 35 31 40 33 23 30 +45x43: 57 45 41 46 50 62 +50x37: 31 37 31 24 33 35 +36x41: 23 36 21 29 24 23 +46x50: 46 43 42 33 41 34 +46x49: 39 46 37 37 39 41 +45x44: 30 30 38 35 42 34 +39x49: 49 50 43 57 53 40 +49x39: 51 58 46 50 45 44 +42x36: 37 35 38 37 40 48 +35x42: 45 49 29 39 31 34 +46x40: 38 25 37 26 37 32 +44x37: 27 26 21 37 29 27 +36x45: 22 28 45 29 27 29 +35x44: 44 44 42 36 35 36 +45x39: 31 23 34 33 41 33 +48x44: 51 46 63 48 49 72 +35x42: 39 45 29 38 32 47 +48x47: 39 43 39 32 37 50 +38x47: 47 52 45 48 36 49 +36x50: 28 28 31 37 30 37 +50x46: 57 58 42 83 65 45 +47x50: 53 68 61 58 62 61 +44x36: 22 35 24 23 33 31 +35x47: 49 44 46 26 46 43 +44x45: 46 44 51 66 44 54 +40x48: 39 38 28 37 29 37 +43x38: 47 34 53 38 41 36 +44x44: 26 37 26 37 36 34 +46x44: 28 43 31 37 38 32 +42x49: 34 48 23 38 43 37 +38x44: 28 44 22 26 21 27 +38x40: 32 20 26 23 29 26 +40x35: 33 31 35 42 36 39 +37x49: 63 44 46 41 36 50 +47x35: 47 43 41 37 44 41 +35x37: 28 19 19 23 25 18 +47x35: 38 31 19 23 29 25 +38x37: 35 44 37 31 29 44 +44x36: 36 38 45 46 44 32 +45x39: 46 40 49 55 33 47 +40x46: 42 48 48 47 52 46 +50x48: 50 38 40 37 58 32 +35x46: 39 37 43 42 39 50 +40x38: 48 35 35 33 38 47 +42x46: 53 37 69 42 40 57 +35x44: 43 42 35 40 37 41 +44x40: 26 38 22 27 29 40 +36x42: 51 34 38 30 33 49 +48x41: 53 49 68 42 43 47 +36x47: 47 45 38 32 47 55 +42x50: 39 38 38 40 41 27 +45x36: 31 36 25 23 33 32 +44x45: 55 58 53 42 52 44 +45x44: 37 33 36 43 30 31 +42x48: 45 51 57 53 48 58 +36x38: 41 36 30 31 37 36 +49x45: 62 70 56 52 44 58 +41x49: 66 50 50 45 42 58 +46x45: 53 45 53 60 52 55 +41x35: 40 35 36 37 40 31 +45x45: 58 55 44 57 47 51 +45x44: 59 34 54 55 54 45 +41x46: 53 41 40 57 54 43 +38x40: 35 48 35 44 33 41 +50x37: 29 33 39 27 36 27 +46x40: 51 46 54 45 41 46 +46x42: 54 59 41 46 46 54 +44x48: 52 61 55 58 44 57 +42x47: 44 55 44 49 59 55 +36x45: 49 32 34 48 41 45 +44x46: 33 37 31 42 33 33 +37x41: 40 41 35 38 38 43 +43x41: 48 47 44 46 41 46 +43x44: 39 22 42 29 29 34 +48x36: 37 25 38 25 40 26 +44x42: 44 54 53 42 47 45 +50x41: 64 59 57 53 33 50 +49x49: 54 74 66 63 59 53 +47x48: 52 51 55 70 64 53 +39x36: 40 29 32 38 41 35 +47x45: 53 52 58 55 52 56 +44x38: 22 27 35 26 27 30 +43x40: 32 27 25 28 37 32 +45x41: 30 27 26 30 38 44 +37x49: 36 32 24 33 37 29 +49x37: 27 32 43 30 32 27 +49x45: 43 34 50 36 41 35 +35x38: 30 41 28 34 33 42 +47x41: 34 62 43 56 53 51 +49x37: 42 25 39 29 24 32 +36x48: 42 32 29 29 34 26 +48x38: 34 31 28 33 37 28 +36x50: 37 53 45 51 49 42 +35x48: 25 28 36 37 20 29 +37x36: 38 43 31 28 31 36 +40x40: 25 23 31 31 23 35 +40x45: 33 37 26 31 34 33 +49x50: 68 66 54 63 65 61 +35x46: 34 18 30 29 30 23 +43x49: 51 36 41 32 33 31 +40x43: 40 42 49 51 42 39 +39x45: 48 48 43 49 44 36 +46x43: 28 32 43 29 40 37 +36x43: 18 30 25 22 35 37 +48x50: 41 45 39 41 41 49 +35x46: 31 26 31 22 26 28 +50x41: 47 54 64 56 49 43 +46x37: 39 28 25 36 30 22 +42x45: 29 39 35 37 37 33 +35x45: 26 24 25 29 24 36 +40x35: 23 31 11 28 26 24 +45x37: 39 44 51 36 51 33 +50x45: 29 41 43 42 42 42 +41x46: 35 52 50 44 57 55 +45x38: 30 32 36 31 22 29 +47x47: 61 58 56 55 47 66 +35x50: 40 52 52 43 40 43 +38x50: 44 43 56 59 38 53 +37x43: 45 43 40 34 46 36 +50x39: 40 33 33 36 33 32 +46x42: 50 53 66 37 43 49 +44x38: 40 35 48 38 54 41 +38x41: 35 45 38 39 40 45 +43x38: 33 50 40 40 50 39 +49x49: 71 40 60 60 71 66 +35x41: 35 32 39 47 42 21 +42x40: 46 40 42 37 44 52 +40x37: 28 22 25 30 38 12 +46x37: 28 22 36 31 34 29 +49x50: 70 62 59 69 55 62 +43x49: 56 57 57 51 49 55 +37x49: 42 48 51 49 46 42 +38x37: 25 26 20 28 29 16 +36x37: 38 28 36 36 28 40 +50x48: 69 67 64 50 64 54 +38x45: 36 24 33 30 32 24 +50x49: 64 49 67 70 55 73 +38x49: 29 27 36 29 37 33 +37x39: 29 18 27 26 25 31 +42x47: 49 40 42 57 58 59 +37x49: 44 54 48 44 49 39 +49x42: 70 41 53 56 45 49 +40x36: 34 29 45 49 31 31 +35x37: 27 39 32 37 31 35 +48x35: 44 49 39 42 44 41 +37x37: 34 25 36 39 39 37 +50x40: 51 45 52 54 52 54 +43x39: 38 43 47 46 37 49 +46x46: 47 58 59 52 55 56 +36x46: 33 33 29 25 31 28 +48x42: 52 44 68 44 53 47 +40x47: 46 64 43 45 48 45 +49x42: 38 38 35 37 35 40 +41x40: 29 24 25 31 33 27 +45x39: 48 50 44 42 45 41 +36x35: 31 29 34 33 33 34 +48x35: 32 23 28 36 32 25 +37x36: 24 19 23 27 22 28 +43x46: 46 32 30 39 37 25 +41x50: 49 54 47 58 60 46 +46x46: 44 66 55 56 46 63 +39x40: 22 36 39 22 21 29 +50x42: 51 49 47 54 64 59 +40x36: 35 50 32 36 41 27 +36x39: 27 27 20 28 25 29 +45x40: 25 43 36 24 40 26 +41x48: 29 40 34 30 38 36 +36x47: 36 50 48 41 47 38 +37x35: 31 38 32 33 33 33 +46x38: 46 40 47 41 48 47 +47x40: 27 34 34 31 28 40 +46x41: 38 35 28 31 33 30 +39x42: 34 33 27 30 25 32 +37x43: 27 31 30 31 21 27 +43x47: 49 44 60 52 59 44 +38x45: 50 44 48 36 43 42 +39x36: 21 33 20 30 23 29 +45x39: 26 29 29 38 33 39 +38x47: 24 26 38 30 31 31 +46x38: 41 47 36 52 45 50 +49x44: 37 46 30 34 35 41 +50x49: 58 68 58 72 62 59 +47x35: 38 29 29 24 22 22 +41x42: 30 52 36 57 45 47 +46x44: 39 34 27 43 25 42 +40x49: 45 56 60 52 38 52 +45x49: 59 50 51 58 55 69 +46x36: 38 52 41 30 51 45 +50x36: 31 36 30 33 27 34 +47x47: 36 45 29 40 41 33 +38x49: 27 37 31 39 28 30 +50x47: 46 38 43 29 45 39 +37x42: 36 36 39 38 45 47 +44x45: 47 56 60 44 54 42 +42x37: 25 24 20 32 37 30 +46x45: 47 35 37 32 34 40 +40x39: 23 27 31 35 25 27 +39x40: 32 28 30 27 24 27 +45x41: 45 52 44 40 53 52 +44x41: 56 37 38 55 38 55 +42x50: 44 33 36 37 43 30 +42x37: 42 43 31 38 38 51 +43x48: 54 59 63 50 44 47 +38x47: 24 34 40 24 36 22 +45x44: 61 41 52 49 53 46 +43x40: 55 40 33 49 39 50 +46x43: 53 46 40 52 54 62 +49x39: 30 37 37 37 29 38 +37x46: 41 51 45 43 38 46 +50x46: 47 31 44 39 45 34 +44x49: 32 39 44 41 35 33 +42x38: 48 38 32 44 41 43 +38x45: 26 27 34 36 35 22 +50x42: 40 54 56 61 60 52 +37x37: 22 23 25 26 21 26 +42x35: 43 30 34 36 43 40 +41x40: 51 49 37 40 39 36 +50x47: 60 56 58 64 48 81 +35x43: 23 27 34 21 28 21 +44x36: 27 26 31 22 34 27 +48x39: 50 34 53 34 60 58 +41x43: 34 30 31 27 32 27 +44x50: 34 40 32 43 34 40 +43x46: 31 28 32 36 27 55 +50x37: 24 28 40 27 37 36 +38x47: 26 27 35 33 30 29 +36x42: 39 47 31 37 42 38 +40x48: 53 35 54 52 45 57 +48x48: 46 38 39 39 48 46 +42x50: 29 40 37 42 39 36 +40x46: 38 26 31 30 42 27 +42x36: 43 33 41 40 44 28 +43x36: 46 31 40 33 45 43 +44x45: 32 36 29 32 40 41 +47x48: 60 60 57 53 54 66 +49x48: 77 49 70 53 55 55 +45x35: 45 43 32 48 37 37 +48x40: 34 33 37 42 19 42 +50x48: 44 43 47 41 35 46 +39x46: 45 50 34 53 44 53 +49x48: 40 45 37 41 59 33 +40x37: 45 39 36 30 41 37 +43x48: 44 41 33 32 38 35 +47x41: 50 49 55 44 54 43 +46x47: 42 35 42 35 42 29 +42x50: 37 37 41 32 43 34 +45x36: 32 22 34 26 39 26 +47x44: 33 32 44 36 29 36 +44x47: 42 37 24 25 43 39 +48x50: 64 55 63 70 59 56 +37x39: 37 39 37 31 38 42 +46x36: 38 43 37 50 43 45 +44x47: 26 40 38 41 32 33 +48x41: 44 35 22 28 40 39 +43x36: 38 39 31 41 35 60 +50x39: 50 42 47 53 48 63 +43x38: 48 41 36 46 42 37 +36x45: 45 39 46 36 42 41 +38x49: 31 32 35 28 33 33 +44x39: 34 24 25 27 39 33 +48x44: 58 46 56 63 49 51 +47x41: 27 34 43 32 33 25 +37x47: 48 39 42 43 48 48 +39x37: 54 33 34 31 29 42 +43x41: 25 25 37 24 38 33 +45x35: 30 27 31 22 26 28 +40x38: 13 22 31 33 26 30 +45x42: 53 56 50 46 42 44 +40x49: 31 36 28 40 39 33 +48x40: 38 44 25 40 30 30 +40x50: 27 44 31 33 31 42 +35x42: 18 24 31 26 29 26 +38x38: 31 40 39 42 33 38 +44x40: 37 25 29 35 32 23 +48x49: 37 36 39 43 55 46 +43x38: 31 35 39 42 54 53 +47x43: 46 59 55 50 58 41 +38x37: 25 39 36 37 54 22 +47x41: 22 43 35 27 36 31 +35x38: 34 37 39 34 33 26 +42x40: 32 39 52 53 42 39 +41x44: 48 59 42 42 41 48 +46x48: 39 42 40 53 34 31 +46x47: 44 38 29 46 40 27 +46x41: 26 29 37 33 41 29 +45x47: 50 52 50 56 62 56 +36x44: 27 28 28 21 36 27 +38x42: 37 39 40 47 41 42 +50x36: 29 34 28 33 36 32 +44x35: 43 41 49 37 34 31 +44x38: 57 34 43 37 43 42 +41x47: 49 43 51 54 51 47 +41x48: 43 35 37 30 31 32 +50x48: 63 68 53 54 64 71 +47x40: 51 39 58 50 43 47 +39x36: 41 34 39 34 34 33 +41x36: 43 55 36 28 37 28 +49x42: 36 42 35 40 40 30 +37x48: 37 53 50 47 41 47 +44x35: 45 41 40 40 36 34 +35x39: 33 28 48 29 44 24 +43x42: 43 49 55 46 40 45 +38x49: 59 37 35 59 56 36 +40x42: 28 46 38 49 50 50 +40x43: 46 34 40 46 50 49 +37x44: 39 45 47 39 38 44 +48x37: 44 45 49 48 38 51 +43x40: 29 30 37 28 27 30 +47x48: 36 44 43 44 42 31 +41x50: 38 39 33 35 33 30 +38x47: 32 28 32 27 31 30 +48x40: 56 51 39 53 45 53 +48x40: 49 52 33 50 58 56 +38x39: 46 41 37 28 36 42 +36x45: 28 36 20 36 35 25 +48x39: 59 42 51 43 41 53 +49x38: 54 55 48 46 39 45 +44x36: 27 36 30 16 27 32 +46x36: 41 36 40 37 55 46 +48x40: 50 34 49 64 48 48 +40x35: 33 40 29 35 37 45 +41x37: 37 33 50 34 37 43 +39x45: 38 21 39 27 42 27 +37x41: 22 29 29 29 17 29 +38x49: 55 43 36 50 49 55 +43x43: 51 38 45 51 45 56 +40x44: 34 31 21 30 31 35 +41x35: 28 23 21 21 30 20 +43x38: 39 35 54 43 30 53 +46x46: 36 42 44 35 33 34 +48x41: 54 57 36 52 52 54 +41x36: 16 28 27 25 25 34 +47x42: 32 37 38 43 35 25 +49x42: 33 33 40 42 35 40 +41x46: 45 48 49 55 48 44 +48x48: 56 51 57 68 59 64 +36x50: 44 49 33 54 48 51 +35x45: 31 45 39 42 47 39 +44x40: 31 35 27 24 31 33 +35x35: 13 19 28 17 25 18 +47x43: 36 36 39 34 35 30 +44x35: 24 22 21 33 27 27 +39x38: 20 21 21 27 36 31 +40x47: 32 34 29 30 36 33 +42x48: 40 40 35 39 31 38 +44x38: 37 49 36 46 41 52 +50x44: 47 51 58 55 61 70 +43x46: 38 30 32 42 32 35 +48x45: 40 33 44 40 39 43 +42x44: 46 54 45 36 56 49 +43x39: 52 29 51 43 41 39 +38x48: 54 48 37 48 48 46 +44x44: 30 36 39 31 30 30 +47x41: 31 28 29 38 37 32 +44x47: 46 31 27 40 34 31 +38x38: 34 22 37 36 45 50 +35x39: 26 23 25 29 23 17 +37x35: 22 21 23 30 18 17 +36x36: 25 22 19 25 26 27 +46x41: 39 24 28 29 44 30 +37x38: 31 24 25 19 21 24 +38x45: 33 26 33 32 26 30 +48x39: 43 53 51 45 51 45 +47x39: 53 38 50 42 54 43 +50x41: 48 63 48 55 49 55 +36x42: 34 48 40 33 38 42 +39x36: 29 19 37 20 27 23 +50x44: 61 58 62 59 47 50 +44x39: 48 38 43 39 45 53 +46x50: 67 66 65 54 47 55 +48x40: 38 22 45 32 35 35 +39x50: 25 32 32 35 41 42 +45x36: 34 29 30 26 39 22 +48x41: 46 64 40 52 57 44 +43x46: 49 49 37 58 57 56 +40x45: 33 31 27 36 21 47 +50x45: 42 39 38 42 36 43 +48x36: 42 40 40 45 50 50 +44x49: 33 33 46 43 36 33 +36x36: 24 38 38 33 33 35 +42x36: 36 35 41 43 35 44 +42x46: 33 34 35 32 24 51 +47x47: 30 40 41 36 50 28 +48x48: 67 53 63 46 70 53 +49x43: 45 53 54 58 61 53 +48x49: 49 44 52 34 34 42 +47x36: 34 24 26 27 39 29 +45x48: 42 44 35 42 37 39 +47x39: 43 24 34 33 39 21 +35x39: 35 45 31 31 37 32 +43x43: 50 48 41 50 43 55 +50x35: 30 29 28 27 32 29 +46x49: 53 55 40 72 61 69 +45x44: 54 53 46 49 55 47 +42x36: 45 31 37 38 32 53 +36x47: 43 34 51 45 46 39 +38x36: 42 28 44 35 23 39 +35x43: 40 34 54 33 39 28 +44x37: 17 41 27 27 30 25 +42x47: 47 48 41 56 57 56 +50x48: 67 53 54 69 65 60 +47x35: 21 21 22 35 37 29 +39x43: 43 45 39 47 46 37 +50x43: 37 33 36 41 37 39 +47x40: 24 34 30 36 36 35 +48x37: 23 32 26 33 27 50 +45x44: 35 34 39 33 34 35 +50x50: 40 41 52 31 39 52 +40x40: 35 30 48 53 40 38 +39x36: 37 33 37 25 45 40 +41x40: 30 28 26 27 32 26 +49x49: 51 70 66 60 57 69 +41x46: 56 57 46 52 37 42 +38x39: 34 51 38 37 25 48 +41x50: 34 34 37 40 29 34 +42x35: 33 27 21 27 22 24 +38x50: 32 24 28 31 31 46 +42x50: 60 50 59 54 48 51 +41x50: 47 49 55 51 56 59 +43x44: 38 42 54 51 55 51 +47x45: 61 47 46 56 65 48 +48x44: 28 30 42 42 38 43 +44x38: 34 31 30 22 18 33 +47x40: 42 38 54 52 56 45 +44x39: 39 45 55 35 43 49 +38x40: 26 27 18 25 24 36 +43x35: 33 31 35 57 38 36 +42x41: 47 52 34 43 49 40 +47x47: 61 55 58 50 56 61 +44x39: 28 23 34 32 39 26 +37x50: 47 48 45 41 46 62 +50x36: 31 41 30 29 33 28 +38x36: 24 33 40 36 44 33 +38x38: 26 24 17 22 23 31 +46x36: 24 22 36 33 32 32 +35x40: 43 38 38 35 33 26 +50x41: 36 43 34 28 28 38 +45x36: 34 26 29 24 34 32 +46x40: 46 29 28 35 22 35 +49x36: 30 41 34 28 33 25 +35x37: 26 20 24 20 23 19 +42x42: 45 36 43 43 49 58 +35x39: 40 26 46 35 37 21 +43x49: 25 44 31 47 32 44 +37x40: 27 30 27 27 22 22 +42x37: 26 23 31 32 28 27 +37x44: 29 33 30 32 30 14 +43x47: 53 59 48 52 44 58 +43x43: 41 51 31 57 53 54 +36x36: 21 27 29 27 24 15 +50x39: 34 31 39 25 42 37 +48x50: 47 39 34 37 50 48 +40x48: 34 36 33 31 40 33 +46x38: 31 31 27 34 28 29 +37x49: 32 30 31 39 25 35 +36x44: 44 40 38 44 42 34 +41x37: 30 28 23 29 20 25 +49x50: 58 33 41 35 47 42 +40x43: 45 44 41 40 53 41 +41x42: 33 32 30 29 33 24 +38x41: 33 56 33 33 43 46 +45x39: 30 31 38 28 37 30 +44x37: 34 28 28 27 19 31 +50x45: 53 56 57 62 51 71 +45x41: 52 47 35 49 54 47 +40x43: 31 30 32 32 35 21 +42x40: 28 37 34 31 26 25 +36x46: 40 53 32 40 53 37 +47x40: 49 44 44 51 52 49 +48x35: 42 35 47 50 42 41 +42x46: 48 53 45 63 45 42 +49x40: 56 54 48 56 41 46 +48x39: 52 44 45 47 41 63 +35x49: 29 32 22 34 32 26 +45x47: 47 65 49 49 63 54 +49x48: 49 44 40 46 40 37 +44x47: 34 46 34 31 36 28 +39x44: 33 26 22 35 37 28 +35x42: 29 22 27 25 31 20 +38x46: 31 25 37 16 35 36 +48x40: 49 46 50 57 40 55 +38x41: 30 26 28 26 18 27 +37x46: 34 37 24 26 26 32 +36x45: 47 33 41 41 50 34 +48x48: 58 63 49 66 61 58 +37x44: 28 17 28 32 30 32 +39x47: 52 45 49 45 36 58 +47x45: 37 49 61 55 54 75 +47x40: 49 50 40 41 59 52 +37x36: 26 19 29 22 26 22 +43x40: 43 52 41 42 46 41 +39x45: 36 31 26 27 37 38 +47x44: 45 54 55 51 55 61 +37x36: 25 21 28 29 25 15 +42x43: 32 28 30 29 43 34 +41x44: 23 32 30 33 29 35 +40x47: 60 53 46 34 40 61 +38x49: 51 39 42 51 51 53 +46x50: 58 65 51 59 58 66 +35x35: 23 15 13 19 27 23 +46x44: 50 46 45 45 62 67 +38x46: 30 28 40 30 27 25 +41x50: 42 44 29 29 32 32 +50x39: 29 35 42 38 26 37 +42x44: 39 21 36 32 40 28 +45x36: 52 50 28 44 37 39 +44x49: 61 45 55 58 58 53 +49x46: 48 61 74 53 53 59 +47x37: 34 33 31 30 22 29 +36x35: 35 33 28 31 31 38 +37x37: 33 36 34 37 33 39 +35x37: 24 23 11 19 28 26 +40x44: 34 29 31 35 21 32 +37x36: 19 32 25 23 28 17 +35x45: 19 36 21 28 33 27 +50x37: 33 30 32 30 37 30 +44x38: 32 42 46 43 48 48 +35x35: 33 30 29 28 34 36 +35x36: 18 18 27 28 24 16 +47x38: 35 39 53 53 53 39 +41x48: 31 40 36 43 31 27 +42x42: 45 44 38 44 52 50 +38x48: 46 40 47 39 61 47 +50x38: 46 53 53 47 41 55 +36x36: 17 21 26 23 31 26 +45x47: 30 33 45 38 39 40 +36x37: 26 21 33 25 15 24 +43x38: 44 42 45 36 42 43 +44x42: 40 30 27 34 28 37 +47x47: 34 35 41 44 31 39 +41x41: 54 38 50 41 38 35 +48x37: 35 32 33 33 21 38 +35x39: 45 23 29 36 45 29 +41x35: 20 26 21 18 38 19 +44x48: 57 64 50 59 44 52 +41x48: 29 42 28 41 32 36 +45x50: 55 64 59 48 64 57 +38x36: 22 27 22 26 24 23 +50x43: 38 34 32 40 42 37 +37x37: 34 35 35 35 31 43 +45x45: 62 53 53 45 57 38 +43x43: 40 35 36 26 30 28 +35x42: 21 33 9 28 28 35 +45x35: 25 28 28 25 30 28 +45x44: 40 35 31 43 26 34 +35x47: 30 29 19 27 30 30 +47x42: 41 31 37 37 32 31 +40x39: 48 49 35 39 34 35 +40x35: 34 33 38 39 39 31 +45x50: 43 40 44 41 32 39 +50x45: 63 62 51 58 51 64 +49x44: 56 54 55 56 55 56 +44x45: 50 63 52 59 39 41 +50x49: 32 41 49 47 43 43 +39x44: 35 31 26 27 35 27 +49x35: 17 30 42 27 31 28 +38x39: 30 25 29 23 24 25 +48x38: 55 47 50 39 41 50 +36x46: 37 35 49 33 48 56 +39x39: 39 33 34 44 41 44 +40x49: 54 48 36 49 50 70 +46x50: 55 60 62 67 52 58 +39x36: 26 34 28 19 23 25 +47x40: 39 26 35 34 31 30 +48x44: 33 40 28 40 47 35 +39x43: 26 30 33 38 18 37 +35x35: 25 30 33 33 37 30 +36x37: 20 39 19 23 25 17 +35x43: 36 46 31 45 39 35 +39x40: 34 36 36 40 43 55 +50x46: 43 35 46 35 41 40 +38x42: 35 46 37 47 39 43 +37x45: 46 40 39 35 56 39 +42x38: 45 36 42 34 50 37 +40x49: 44 65 40 57 45 54 +47x42: 47 50 59 54 53 37 +45x50: 33 39 44 33 38 52 +47x38: 26 30 31 27 35 30 +37x36: 37 28 27 38 44 29 +43x35: 30 24 19 28 30 22 +37x48: 45 48 45 49 41 46 +38x36: 37 34 40 33 38 26 +45x46: 64 47 55 48 53 50 +37x35: 27 22 24 15 17 26 +47x39: 33 33 24 34 38 32 +46x46: 34 44 33 42 41 31 +37x49: 45 36 33 24 22 31 +36x39: 28 28 30 22 31 17 +49x35: 49 37 47 39 47 44 +47x35: 48 40 41 47 33 45 +48x37: 52 49 41 42 47 42 +46x39: 49 48 38 48 51 41 +46x37: 40 50 53 46 38 33 +36x43: 29 28 24 27 29 31 +41x38: 47 39 39 38 32 47 +39x48: 39 38 24 28 35 43 +37x44: 28 38 25 24 20 32 +48x42: 55 49 46 57 51 52 +38x35: 20 22 19 22 16 32 +47x42: 32 33 39 36 27 43 +49x46: 60 51 56 55 56 72 +50x48: 73 66 73 51 51 54 +36x45: 37 46 53 45 35 31 +37x49: 34 35 31 26 32 34 +44x46: 58 46 45 46 58 60 +39x49: 50 41 47 47 60 48 +43x50: 47 30 46 39 29 33 +43x50: 34 48 34 29 52 26 +45x45: 38 38 43 37 38 30 +36x37: 34 37 36 36 25 39 +40x47: 58 50 45 39 49 49 +44x42: 35 34 36 30 30 30 +44x43: 30 35 33 35 28 34 +50x42: 34 42 34 37 39 37 +46x36: 40 58 51 39 32 35 +40x37: 34 40 37 40 35 44 +47x48: 67 63 52 55 58 51 +49x35: 35 53 41 49 42 46 +38x49: 33 31 41 35 29 23 +40x39: 48 32 46 35 46 29 +45x39: 50 43 42 43 45 48 +46x36: 41 35 49 48 41 39 +43x43: 38 31 40 25 33 29 +47x41: 36 54 59 50 55 41 +40x44: 42 44 46 50 41 49 +41x41: 47 49 39 46 35 44 +41x50: 33 40 42 31 31 31 +50x39: 42 33 35 32 29 36 +50x50: 65 61 55 62 68 77 +50x39: 35 44 36 33 28 32 +45x38: 38 17 31 21 40 32 +43x41: 25 25 38 35 31 28 +44x40: 35 23 28 34 33 28 +35x35: 18 19 21 20 19 24 +46x46: 45 70 51 60 56 43 +35x47: 27 20 37 26 30 25 +40x36: 22 17 33 20 34 29 +48x46: 58 56 61 51 62 50 +36x49: 34 29 36 24 42 27 +41x36: 30 26 21 22 32 25 +46x41: 27 32 32 23 45 36 +49x37: 35 27 23 40 33 33 +36x36: 35 36 24 38 26 44 +43x36: 29 25 31 38 24 20 +41x42: 43 40 44 44 46 49 +47x44: 33 43 36 33 33 32 +44x42: 33 31 30 35 32 34 +45x47: 43 34 34 32 40 41 +49x46: 45 31 42 32 45 45 +48x39: 47 56 50 42 48 46 +49x49: 48 35 51 47 39 36 +39x35: 31 34 31 42 38 34 +45x49: 42 41 42 39 32 43 +44x46: 36 28 34 34 33 45 +35x45: 53 41 32 37 36 45 +47x37: 29 36 28 24 35 27 +43x47: 35 40 32 33 30 40 +44x42: 33 26 29 35 35 37 +50x37: 23 36 35 33 42 22 +41x50: 28 40 23 28 41 48 +39x40: 32 45 39 37 51 36 +39x41: 53 33 41 43 42 30 +42x49: 50 56 48 46 63 55 +49x48: 39 40 50 42 41 44 +45x41: 35 32 32 33 39 24 +42x48: 32 36 33 36 44 42 +45x49: 46 59 50 78 55 50 +38x36: 20 21 22 28 25 27 +45x49: 35 36 45 33 46 44 +44x48: 52 58 53 54 57 51 +50x42: 61 55 58 44 55 49 +41x44: 21 30 25 33 38 35 +38x44: 49 35 43 41 52 34 +50x42: 64 53 52 43 53 60 +40x43: 33 24 40 33 25 26 +49x36: 38 51 31 49 57 47 +39x43: 42 45 42 35 46 51 +40x38: 35 28 24 21 25 23 +46x48: 37 35 34 42 50 41 +45x49: 44 35 46 39 39 36 +36x43: 30 28 29 30 20 31 +42x45: 43 60 58 45 38 49 +36x36: 17 29 21 25 30 21 +50x46: 56 66 61 54 59 59 +44x37: 49 29 48 48 30 46 +44x50: 36 38 31 36 35 48 +42x49: 49 47 59 59 54 46 +36x45: 23 28 31 29 34 35 +41x35: 27 26 19 20 23 27 +44x45: 27 38 37 41 25 41 +39x43: 44 53 45 35 39 44 +37x38: 19 26 23 24 30 22 +35x40: 26 45 38 36 34 39 +46x44: 25 24 42 46 38 35 +40x39: 27 25 41 20 30 26 +44x39: 35 34 38 57 50 51 +46x49: 35 52 35 47 32 39 +47x37: 45 56 44 43 40 40 +49x45: 47 30 32 52 48 31 +37x48: 30 31 37 24 37 32 +50x44: 59 59 63 53 51 53 +46x37: 28 30 33 28 18 42 +44x43: 42 18 40 30 38 27 +43x50: 62 57 53 59 44 57 +39x49: 38 42 40 29 32 26 +49x46: 41 42 41 40 42 33 +42x44: 36 37 32 28 31 32 +37x36: 23 24 27 23 23 24 +39x39: 33 44 39 36 44 39 +47x39: 33 38 30 33 40 20 +45x36: 27 33 33 30 23 33 +45x40: 42 54 46 50 38 49 +44x47: 42 53 56 57 51 62 +37x36: 19 27 20 22 22 33 +38x35: 34 26 40 32 39 32 +40x50: 38 30 43 37 36 23 +35x43: 34 46 44 42 33 32 +35x43: 37 47 40 27 33 53 +44x44: 40 58 42 60 46 55 +45x46: 39 34 38 32 41 41 +49x47: 36 33 52 43 37 39 +40x42: 31 51 50 47 40 40 +41x39: 29 25 27 32 24 32 +50x45: 45 54 48 45 78 83 +36x37: 34 46 34 31 30 31 +45x39: 58 26 46 49 48 39 +37x39: 38 34 40 43 34 31 +49x36: 36 54 43 48 49 42 +43x44: 49 42 50 55 50 43 +45x40: 35 31 26 30 43 30 +45x45: 36 36 33 39 42 38 +49x50: 56 67 63 53 66 77 +50x48: 39 47 36 46 45 43 +41x40: 30 24 24 33 28 29 +40x43: 35 54 47 46 31 57 +46x46: 44 63 49 59 51 64 +35x43: 43 30 36 30 49 44 +39x44: 32 35 30 28 27 29 +39x47: 30 37 27 34 28 38 +47x40: 42 40 56 48 48 57 +43x36: 45 35 45 34 39 40 +35x50: 45 48 44 51 34 49 +46x40: 37 31 38 32 33 24 +35x44: 40 38 44 42 34 39 +46x36: 36 29 31 27 24 33 +35x39: 31 20 24 20 27 20 +41x39: 38 41 40 47 33 50 +43x44: 48 45 42 58 47 52 +48x40: 44 45 36 56 55 63 +48x49: 37 46 52 49 35 37 +37x47: 31 53 47 43 51 44 +44x49: 57 61 48 55 58 53 +42x36: 24 36 57 39 39 37 +35x43: 41 40 33 35 42 42 +43x41: 54 36 38 46 51 45 +39x44: 29 31 29 26 26 40 +37x49: 46 49 49 52 41 41 +40x49: 28 44 47 35 26 27 +48x48: 56 64 56 64 58 57 +42x40: 27 27 29 34 26 38 +40x48: 38 31 35 44 29 30 +36x49: 29 29 33 30 29 41 +49x50: 50 75 57 78 59 59 +43x44: 33 29 28 41 39 26 +41x44: 47 31 36 58 47 61 +41x40: 19 27 27 33 29 33 +42x38: 40 39 33 41 48 46 +48x41: 42 33 32 34 32 34 +43x50: 36 41 41 35 26 45 +44x40: 43 42 54 47 48 33 +38x35: 32 22 12 24 16 26 +37x49: 31 43 28 31 29 29 +40x48: 48 55 39 57 42 58 +44x47: 37 33 35 42 24 38 +43x38: 43 38 42 43 38 49 +50x38: 46 30 54 52 54 56 +50x44: 47 57 52 59 64 61 +43x43: 45 30 28 35 28 30 +46x38: 38 35 26 32 28 21 +49x47: 38 52 40 37 33 40 +37x41: 37 33 43 41 39 40 +45x38: 45 49 41 44 42 43 +46x42: 43 55 42 41 58 63 +42x41: 41 41 41 48 49 45 +41x42: 37 50 42 45 55 34 +45x36: 41 46 41 47 47 23 +37x40: 22 20 27 22 33 31 +41x44: 47 44 38 44 54 52 +46x42: 32 43 34 31 34 36 +44x48: 32 37 36 46 40 33 +40x36: 25 22 25 20 36 27 +38x42: 28 27 27 32 32 22 +37x36: 20 26 24 20 27 26 +50x37: 45 42 58 61 39 36 +37x42: 24 24 25 37 28 30 +47x42: 39 42 32 25 33 39 +37x44: 32 47 38 38 48 51 +49x37: 48 43 43 50 50 44 +43x39: 25 32 35 35 25 29 +44x45: 56 43 53 53 47 52 +49x40: 50 47 49 45 58 53 +47x44: 24 35 43 35 38 34 +42x41: 32 39 24 27 30 29 +42x41: 21 32 31 31 37 30 +36x37: 39 35 27 37 31 37 +43x41: 26 33 27 30 28 37 +36x49: 46 43 39 46 56 40 +37x43: 16 32 30 32 30 28 +43x40: 47 40 45 40 42 53 +49x37: 47 52 47 46 41 47 +48x35: 42 25 33 22 30 24 +40x36: 40 28 36 35 38 46 +48x47: 32 35 51 45 36 40 +45x41: 47 53 42 51 52 37 +35x36: 21 27 18 17 23 25 +36x50: 42 49 49 42 53 41 +50x45: 30 44 42 37 44 43 +44x48: 56 55 54 66 46 46 +35x38: 19 25 26 24 18 19 +36x48: 31 35 28 36 29 32 diff --git a/src/day12/main.rs b/src/day12/main.rs new file mode 100644 index 0000000..1607b8c --- /dev/null +++ b/src/day12/main.rs @@ -0,0 +1,448 @@ +use anyhow::Result; +use std::{ + collections::{HashMap, HashSet}, + fmt::Debug, + fs, +}; + +#[derive(Debug)] +struct Area { + width: u64, + height: u64, + reqs: Vec, + hash: HashMap, +} + +impl Into for &str { + fn into(self) -> Area { + let mut niter = self.split(":"); + let mut positer = niter.next().unwrap().split("x"); + let width: u64 = positer.next().unwrap().parse().unwrap(); + let height: u64 = positer.next().unwrap().parse().unwrap(); + let (reqs, hash) = niter.next().unwrap().trim().split(" ").enumerate().fold( + (Vec::new(), HashMap::new()), + |(mut v, mut h), (i, to_num)| { + h.insert(i, to_num.parse().unwrap()); + for _ in 0..to_num.parse().unwrap() { + v.push(i); + } + (v, h) + }, + ); + Area { + width, + height, + reqs, + hash, + } + } +} + +fn try_all_vars( + area: &Area, + shapes: &HashMap>, + list_of_reqs: Vec, + cur_shape: StrictShape, +) -> bool { + if list_of_reqs.len() == 0 { + return true; + } + let mut reqs = list_of_reqs.clone().into_iter(); + let cur_idx = reqs.next().unwrap(); + let reqs: Vec = reqs.collect(); + + // TODO check if the current shape fits in the box + + // We don't have to loop because if we can not fit the first + // we will never be able to fit any way + for s in shapes.get(&cur_idx).unwrap().iter() { + let possibles = cur_shape.try_to_attach_all(area, &s); + for p in possibles { + if try_all_vars(area, shapes, reqs.clone(), p) { + return true; + } + } + } + false +} + +impl Area { + fn valid(&self, shapes: &HashMap>) -> bool { + let mut reqs = self.reqs.clone().into_iter(); + let cur_idx = reqs.next().unwrap(); + let reqs: Vec = reqs.collect(); + + // TODO check if the current shape fits in the box + + // We don't have to loop because if we can not fit the first + // we will never be able to fit any way + // also we only need to test one here and this one "sets" the orientaion of the world + if try_all_vars( + self, + shapes, + reqs.clone(), + shapes.get(&cur_idx).unwrap().iter().next().unwrap().clone(), + ) { + return true; + } + + false + } +} + +#[derive(Eq, PartialEq, Clone, Hash)] +struct Shape { + lines: Vec>, +} + +#[derive(Eq, PartialEq, Clone, Hash)] +// It can not rotate or flip but it's faster for comparions +struct StrictShape { + lines: Vec, + width: i64, +} + +const ALL_ONES: u64 = 0b1111111111111111111111111111111111111111111111111111111111111111; + +impl StrictShape { + fn get_attach_poins(&self) -> Vec<(i64, i64)> { + let mut attach_points = Vec::new(); + for (y, line) in self.lines.iter().enumerate() { + let mut line = *line ^ ALL_ONES; + while line != 0 { + let i = line.trailing_zeros(); + line ^= 1 << i; + if 64 - i < self.width as u32 { + attach_points.push((y as i64, 64 - i as i64)); + } + } + } + + attach_points + } + + fn get_size(&self) -> (i64, i64) { + (self.lines.len() as i64, self.width) + } + + fn try_to_attach(&self, to_attach: &StrictShape, y: i64, x: i64) -> Option { + // Calculate the matrix + let (s_h, s_w) = self.get_size(); + let (a_h, a_w) = to_attach.get_size(); + let height = if y < 0 { + (y.abs() + s_h).max(a_h + y) + } else { + s_h.max(a_h + y) + }; + let width = if x < 0 { + (x.abs() + s_w).max(a_w + x) + } else { + s_w.max(a_w + x) + }; + + let mut lines = Vec::new(); + // i_<> is the offset into the to_attach shape it can go out of bounds on the positive side + // o_<> is the offset into the self shape it can go out of bound both sides + for i_y in 0..height { + let self_y = i_y + y.min(0); + let to_y = i_y - y.max(0); + + if (self_y < 0 || self_y >= s_h) && (to_y < 0 || to_y >= a_h) { + lines.push(0); + } else if self_y < 0 || self_y >= s_h { + lines.push(to_attach.lines[to_y as usize] >> x.max(0)); + } else if to_y < 0 || to_y >= a_h { + lines.push(self.lines[self_y as usize] >> x.min(0).abs()); + } else { + let a_line = to_attach.lines[to_y as usize] >> x.max(0); + let self_line = self.lines[self_y as usize] >> x.min(0).abs(); + // There is an itersection + if a_line & self_line > 0 { + return None; + } + lines.push(a_line | self_line); + } + } + + Some(StrictShape { lines, width }) + } + + fn try_to_attach_all(&self, area: &Area, to_attach: &StrictShape) -> Vec { + // println!( + // "Trying to attach {:?} \n{:?}\n with \n{:?}\n", + // area, self, to_attach + // ); + let (s_y, s_x) = self.get_size(); + let (a_y, a_x) = to_attach.get_size(); + + let min_x = (-(a_x as i64)).max(-(area.width as i64 - s_x)); + let max_x = (s_x + a_x).min(area.width as i64 - a_x as i64); + + let min_y = (-(a_y as i64)).max(-(area.height as i64 - s_y)); + let max_y = (s_y + a_y).min(area.height as i64 - a_y as i64); + + if min_x > max_x || min_y > max_y { + //println!("Could never attach"); + return Vec::new(); + } + + // println!("found bounds {} {} -> {} {}", min_y, min_x, max_y, max_x); + // Try edges + let mut new_possible_shapes = Vec::new(); + for y in min_y..0 { + for x in min_x..=max_x { + if let Some(merged) = self.try_to_attach(to_attach, y, x) { + // println!("Found shape {y} {x} {merged:?} "); + new_possible_shapes.push(merged); + } else { + // println!("Could not find shape {y} {x}"); + } + } + } + + for y in s_y..=max_y { + for x in min_x..max_x { + if let Some(merged) = self.try_to_attach(to_attach, y, x) { + // println!("Found shape {y} {x} {merged:?} "); + new_possible_shapes.push(merged); + } else { + // println!("Could not find shape {y} {x}"); + } + } + } + + for y in 0..=(s_y).min(max_y) { + for x in min_x..0 { + if let Some(merged) = self.try_to_attach(to_attach, y, x) { + // println!("Found shape {y} {x} {merged:?} "); + new_possible_shapes.push(merged); + } else { + // println!("Could not find shape {y} {x}"); + } + } + for x in s_x..max_x { + if let Some(merged) = self.try_to_attach(to_attach, y, x) { + // println!("Found shape {y} {x} {merged:?} "); + new_possible_shapes.push(merged); + } else { + // println!("Could not find shape {y} {x}"); + } + } + } + + let r_y = min_y..=max_y; + let r_x = min_x..=max_x; + + for (p_y, p_x) in self.get_attach_poins() { + // println!("in {p_y} {p_x}"); + if r_y.contains(&p_y) && r_x.contains(&p_x) { + if let Some(merged) = self.try_to_attach(to_attach, p_y, p_x) { + // println!("Found shape {p_y} {p_x}{merged:?}"); + new_possible_shapes.push(merged); + } else { + // println!("Could not find shape {p_y} {p_x}"); + } + } + } + + new_possible_shapes.sort_by(|a, b| { + (a.width * a.lines.len() as i64).cmp(&(b.width * b.lines.len() as i64)) + }); + + // if new_possible_shapes > 0 { + // println!("Best shape {:?}", new_possible_shapes[0]); + // } + + new_possible_shapes + } +} + +impl Debug for StrictShape { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "\n")?; + for line in self.lines.iter() { + let line = format!("{line:064b}"); + let line = line[0..(self.width as usize)] + .to_string() + .replace("0", ".") + .replace("1", "#"); + write!(f, "{}\n", line)?; + } + write!(f, "") + } +} + +impl Shape { + fn new() -> Shape { + Shape { lines: Vec::new() } + } + + fn add_line(&mut self, text: &str) { + let mut line = Vec::new(); + for c in text.chars() { + match c { + '#' => line.push(true), + '.' => line.push(false), + c => panic!("Not sure what to do {}", c), + } + } + self.lines.push(line); + } + + fn rotate_right(&self) -> Self { + let mut lines = Vec::new(); + let height = self.lines.len(); + assert!(height > 0, "Something is wrong {:?}", self); + let width = self.lines[0].len(); + for x in (0..width).rev() { + let mut new_line = Vec::new(); + for y in 0..height { + new_line.push(self.lines[y][x]); + } + lines.push(new_line); + } + Self { lines } + } + + fn flip(&self) -> Self { + let mut lines = Vec::new(); + let height = self.lines.len(); + let width = self.lines[0].len(); + for y in (0..height).rev() { + let mut new_line = Vec::new(); + for x in (0..width).rev() { + new_line.push(self.lines[y][x]); + } + lines.push(new_line); + } + Self { lines } + } + + fn to_strict(self) -> StrictShape { + let mut lines = Vec::new(); + for line in self.lines.iter() { + let mut n_line = 0; + for (i, c) in line.iter().enumerate() { + n_line = n_line | (*c as u64) << 63 - i; + } + lines.push(n_line); + } + + StrictShape { + lines, + width: self.lines[0].len() as i64, + } + } + + fn get_varients(self) -> Vec { + let mut shapes_list = HashSet::new(); + let shape1 = self.rotate_right(); + let shape2 = shape1.rotate_right(); + let shape3 = shape2.rotate_right(); + shapes_list.insert(shape1.to_strict()); + shapes_list.insert(shape2.to_strict()); + shapes_list.insert(shape3.to_strict()); + let fliped = self.flip(); + let shape1 = fliped.rotate_right(); + let shape2 = shape1.rotate_right(); + let shape3 = shape2.rotate_right(); + shapes_list.insert(self.to_strict()); + shapes_list.insert(fliped.to_strict()); + shapes_list.insert(shape1.to_strict()); + shapes_list.insert(shape2.to_strict()); + shapes_list.insert(shape3.to_strict()); + shapes_list.into_iter().collect() + } +} + +impl Debug for Shape { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "\n")?; + for line in self.lines.iter() { + for c in line { + write!(f, "{}", if *c { "#" } else { "." })?; + } + write!(f, "\n")?; + } + write!(f, "") + } +} + +fn main() -> Result<()> { + let text = fs::read_to_string("src/day12/act.txt")?; + + let mut areas: Vec = Vec::new(); + let mut shapes = HashMap::new(); + let mut cur_shape = Shape::new(); + + for line in text.split("\n") { + if line == "" { + continue; + } else if line.contains("x") { + if cur_shape.lines.len() != 0 { + let vars = cur_shape.get_varients(); + println!("Shape: {:?} {}", vars[0], vars.len()); + shapes.insert(shapes.values().len(), vars); + cur_shape = Shape::new(); + } + areas.push(line.into()); + } else if line.contains(":") { + if cur_shape.lines.len() == 0 { + continue; + } + let vars = cur_shape.get_varients(); + println!("Shape: {:?} {}", vars[0], vars.len()); + shapes.insert(shapes.values().len(), vars); + cur_shape = Shape::new(); + } else { + cur_shape.add_line(line); + } + } + + let mut valid = 0; + for a in areas.iter() { + let mut count_of_1 = *a.hash.get(&1).unwrap(); + let by_6 = count_of_1 / 6; + let left_over = count_of_1 % 6; + + let mut area = a.width / 3 * a.height / 3; + if (a.width / 12 * a.height / 3) as usize > by_6 + || (a.width / 3 * a.height / 12) as usize > by_6 + { + count_of_1 = left_over; + area -= (by_6 * 4) as u64; + } + + let mut sum: u64 = 0; + for (i, v) in a.hash.iter() { + if *i == 1 { + sum += count_of_1 as u64; + } else { + sum += *v as u64; + } + } + + if area >= sum { + valid += 1; + } + } + println!("sol1: {}", valid); + + panic!("mad"); + + // We know that 3 only nicly packs with itself + + let mut valid = 0; + for (i, a) in areas.iter().enumerate() { + if a.valid(&shapes) { + println!("Found Valid ans {i}\n\n\n\n\n\n"); + valid += 1; + } else { + println!("Could not Find valid answer {i}\n\n\n\n\n\n"); + } + } + + println!("sol1: {}", valid); + + Ok(()) +} diff --git a/src/day12/test.txt b/src/day12/test.txt new file mode 100644 index 0000000..e5e1b3d --- /dev/null +++ b/src/day12/test.txt @@ -0,0 +1,33 @@ +0: +### +##. +##. + +1: +### +##. +.## + +2: +.## +### +##. + +3: +##. +### +##. + +4: +### +#.. +### + +5: +### +.#. +### + +4x4: 0 0 0 0 2 0 +12x5: 1 0 1 0 2 2 +12x5: 1 0 1 0 3 2