more progress.
over 40 stars!
This commit is contained in:
@@ -5,3 +5,4 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
core = { path = "../core" }
|
||||
regex = "1.11.2"
|
||||
|
||||
@@ -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.
|
||||
@@ -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}");
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user