more progress.

over 40 stars!
This commit is contained in:
2025-09-11 11:11:13 -04:00
parent 1776ed8f57
commit 7c3186abcf
37 changed files with 4116 additions and 68 deletions
+1
View File
@@ -5,3 +5,4 @@ edition = "2024"
[dependencies]
core = { path = "../core" }
regex = "1.11.2"
+107
View File
@@ -0,0 +1,107 @@
// now exclude 1 bad report and see if its still valid
use std::{env, fs};
use core::read_data;
fn min_max(num1: u32, num2: u32) -> (u32, u32) {
(num1.min(num2), num1.max(num2))
}
fn in_range(min: u32, max: u32, target: u32) -> bool {
min <= target && target <= max
}
fn parse_numbers(s: &str) -> Vec<u32> {
s.split_whitespace() // split on whitespace
.filter_map(|num| num.parse::<u32>().ok()) // try to parse each piece
.collect()
}
fn is_safe(report: &str) -> bool {
let mut is_safe = true;
let numbers = parse_numbers(report);
println!("*******************************************************\nnumbers: {:?}", numbers);
let mut is_increasing = numbers[0] < numbers[1];
for index in 0..numbers.len() - 1 {
let first = numbers[index];
let second = numbers[index + 1];
if first.abs_diff(second) > 3 || first.abs_diff(second) < 1 {
is_safe = false;
}
if is_increasing && first >= second {
is_safe = false;
}
if !is_increasing && first <= second {
is_safe = false;
}
}
is_safe
}
fn is_safe_numbers(numbers: &[u32]) -> bool {
if numbers.len() < 2 {
return true;
}
let is_increasing = numbers[0] < numbers[1];
for i in 0..numbers.len() - 1 {
let first = numbers[i];
let second = numbers[i + 1];
let diff = first.abs_diff(second);
if diff < 1 || diff > 3 {
return false;
}
if is_increasing && first >= second {
return false;
}
if !is_increasing && first <= second {
return false;
}
}
true
}
fn is_safe_less_one(report: &str) -> bool {
let numbers = parse_numbers(report);
// Already safe?
if is_safe_numbers(&numbers) {
return true;
}
// Try removing each element
for i in 0..numbers.len() {
let mut variant = numbers.clone();
variant.remove(i);
if is_safe_numbers(&variant) {
return true;
}
}
false
}
fn main() {
let input_file = read_data("2024_02_data.txt");
let mut num_safe = 0;
// let input_file = "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9";
let reports = input_file.lines();
for report in reports {
let is_safe = is_safe_less_one(report);
println!("Handling report of {report} -> Safe: {}",is_safe);
if is_safe {
num_safe += 1;
}
}
println!("Found {num_safe} safe readings.");
}
// 644
// Chatgpt used to understand why my previous code didnt work. i was counting errors, not removing
// an element and testing again.
+19
View File
@@ -0,0 +1,19 @@
use core::read_data;
use regex::Regex;
fn main() {
let binding = read_data("2024_03_data.txt");
// use Regex to pull out the parts we want...
let re = Regex::new(r"mul\((\d{1,3}),(\d{1,3})\)").unwrap();
let sum: u32 = re.find_iter(&binding)
.filter_map(|m| {
let caps = re.captures(m.as_str()).unwrap();
let x: u32 = caps.get(1).unwrap().as_str().parse().ok().unwrap();
let y: u32 = caps.get(2).unwrap().as_str().parse().ok().unwrap();
Some(x * y)
}).sum();
println!("Sum = {sum}");
}
+31
View File
@@ -0,0 +1,31 @@
// load data to array.
// look for 'xmas'
fn main() {
let params = "MMMSXXMASM\nMSAMXMSMSA\nAMXSXMAAMM\nMSAMASMSMX\nXMASAMXAMM\nXXAMMXXAMA\nSMSMSASXSS\nSAXAMASAAA\nMAMMMXMMMM\nMXMXAXMASX";
let mut running_total = 0;
let params_chars: Vec<char> = params.chars().collect();
let lines = params.lines();
let lines_num = lines.clone().count();
let line_len = lines.last().unwrap().len();
for column_index in 0..line_len {
for row_index in 0..lines_num {
let current_offset = column_index * line_len + row_index;
let this_box: [char; 9] = [
params_chars[current_offset - line_len - 1],
params_chars[current_offset - line_len],
params_chars[current_offset - line_len + 1],
params_chars[current_offset - 1],
params_chars[current_offset],
params_chars[current_offset + 1],
params_chars[current_offset + line_len - 1],
params_chars[current_offset + line_len],
params_chars[current_offset + line_len + 1]
];
let new_total = 0; // find_xmas(this_box, column_index, row_index);
running_total += new_total;
println!("Checking for XMAS at {}x{} -> {}", column_index, row_index, new_total);
}
}
}
+110
View File
@@ -0,0 +1,110 @@
use std::io::{self, Read};
fn main() {
// Read the whole input
let mut s = String::new();
io::stdin().read_to_string(&mut s).unwrap();
// Build grid of chars (skip any completely empty lines)
let grid: Vec<Vec<char>> = s
.lines()
.filter(|ln| !ln.trim().is_empty())
.map(|ln| ln.chars().collect())
.collect();
let h = grid.len();
let w = grid.get(0).map(|r| r.len()).unwrap_or(0);
if h == 0 || w == 0 {
println!("0");
return;
}
let word: [char; 4] = ['X', 'M', 'A', 'S'];
let dirs: [(isize, isize); 8] = [
(-1, -1), (-1, 0), (-1, 1),
( 0, -1), ( 0, 1),
( 1, -1), ( 1, 0), ( 1, 1),
];
let mut count = 0usize;
for y in 0..h {
for x in 0..w {
if grid[y][x] != 'X' { continue; }
for (dy, dx) in dirs {
let mut ok = true;
for k in 0..word.len() {
let ny = y as isize + dy * k as isize;
let nx = x as isize + dx * k as isize;
if ny < 0 || nx < 0 || ny >= h as isize || nx >= w as isize {
ok = false;
break;
}
if grid[ny as usize][nx as usize] != word[k] {
ok = false;
break;
}
}
if ok { count += 1; }
}
}
}
println!("{}", count);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example_counts_18() {
let input = "\
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
";
// Re-run main logic here for the sample
let grid: Vec<Vec<char>> = input
.lines()
.filter(|ln| !ln.trim().is_empty())
.map(|ln| ln.chars().collect())
.collect();
let h = grid.len();
let w = grid[0].len();
let word: [char; 4] = ['X', 'M', 'A', 'S'];
let dirs: [(isize, isize); 8] = [
(-1, -1), (-1, 0), (-1, 1),
( 0, -1), ( 0, 1),
( 1, -1), ( 1, 0), ( 1, 1),
];
let mut count = 0usize;
for y in 0..h {
for x in 0..w {
if grid[y][x] != 'X' { continue; }
for (dy, dx) in dirs {
let mut ok = true;
for k in 0..word.len() {
let ny = y as isize + dy * k as isize;
let nx = x as isize + dx * k as isize;
if ny < 0 || nx < 0 || ny >= h as isize || nx >= w as isize {
ok = false; break;
}
if grid[ny as usize][nx as usize] != word[k] {
ok = false; break;
}
}
if ok { count += 1; }
}
}
}
assert_eq!(count, 18);
}
}