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
+4
View File
@@ -0,0 +1,4 @@
07 requires some type of tree traversal that I don't know.
08 requires text processing that is beyond me right now
09 requires tree traversal and tsp solution.
+1
View File
@@ -69,3 +69,4 @@ fn main() {
println!("Found {num_lines} good passwords.");
}
// 51
+99
View File
@@ -0,0 +1,99 @@
/// Actions in the processor
#[derive(Debug)]
enum Actions {
NOT { a: String, z: String },
OR { a: String, b: String, z: String },
AND { a: String, b: String, z: String },
RSHIFT { a: String, d: u32, z: String },
LSHIFT { a: String, d: u32, z: String },
Connection { a: String, z: String }
}
struct Wire {
pub connections: Vec<Actions>
}
fn identify_wires(input: &str) -> Vec<String> {
let mut working = vec![];
for line in input.lines() {
println!("Identifying wires in [[{line}]]");
}
working
}
fn parse_instruction(input: &str) -> Option<Actions> {
let parts : Vec<_> = input.split_whitespace().collect();
match parts.len() {
3 => {
Some(Actions::Connection { a: parts[0].to_string(), z: parts[2].to_string() })
},
4 => {
// NOT
match parts[0] {
"NOT" => {
Some(Actions::NOT { a: parts[1].to_string(), z: parts[3].to_string()} ) },
_ => {
println!("UNHANDLED 4 PART -> {input}");
Some(Actions::Connection { a: "__".to_string(), z: "__".to_string() })
}
}
}
5 => {
match parts[1] {
"RSHIFT" => {
Some(Actions::RSHIFT {
a: parts[0].to_string(),
d: parts[2].parse::<u32>().unwrap(),
z: parts[4].to_string(),
})
},
"LSHIFT" => {
Some(Actions::LSHIFT {
a: parts[0].to_string(),
d: parts[2].parse::<u32>().unwrap(),
z: parts[4].to_string()
})
},
"AND" => {
Some(Actions::AND {
a: parts[0].to_string(),
b: parts[2].to_string(),
z: parts[4].to_string(),
})
},
"OR" => {
Some(Actions::OR {
a: parts[0].to_string(),
b: parts[2].to_string(),
z: parts[4].to_string(),
})
},
_ => {
println!("UNHANDLED 5 PART -> {input}");
None
}
}
},
_ => {
println!("Unhandled {} part -> {input}", parts.len());
None
}
}
}
use core::read_data;
fn main() {
let binding = read_data("2015_07_data.txt");
let lines = binding.lines();
for line in lines {
let parsed = parse_instruction(line);
if parsed.is_some() {
println!("PARSED [[{line}]] into [[{parsed:?}]]");
}
}
}
+87
View File
@@ -0,0 +1,87 @@
use std::collections::HashMap;
use core::read_data;
#[derive(Debug, Clone)]
enum Expr {
Value(u16),
Wire(String),
And(Box<Expr>, Box<Expr>),
Or(Box<Expr>, Box<Expr>),
LShift(Box<Expr>, u8),
RShift(Box<Expr>, u8),
Not(Box<Expr>),
}
fn parse_expr(token: &str) -> Expr {
if let Ok(num) = token.parse::<u16>() {
Expr::Value(num)
} else {
Expr::Wire(token.to_string())
}
}
fn parse_line(line: &str) -> (String, Expr) {
let parts: Vec<&str> = line.split(" -> ").collect();
let expr_str = parts[0];
let target = parts[1].to_string();
let tokens: Vec<&str> = expr_str.split_whitespace().collect();
let expr = match tokens.as_slice() {
[a] => parse_expr(a),
["NOT", a] => Expr::Not(Box::new(parse_expr(a))),
[a, "AND", b] => Expr::And(Box::new(parse_expr(a)), Box::new(parse_expr(b))),
[a, "OR", b] => Expr::Or(Box::new(parse_expr(a)), Box::new(parse_expr(b))),
[a, "LSHIFT", n] => Expr::LShift(Box::new(parse_expr(a)), n.parse().unwrap()),
[a, "RSHIFT", n] => Expr::RShift(Box::new(parse_expr(a)), n.parse().unwrap()),
_ => panic!("Unrecognized expression: {}", expr_str),
};
(target, expr)
}
fn eval(
expr: &Expr,
circuit: &HashMap<String, Expr>,
cache: &mut HashMap<String, u16>,
) -> u16 {
match expr {
Expr::Value(v) => *v,
Expr::Wire(w) => {
if let Some(&v) = cache.get(w) {
return v;
}
let e = circuit.get(w).unwrap_or_else(|| panic!("Unknown wire {}", w));
let v = eval(e, circuit, cache);
cache.insert(w.clone(), v);
v
}
Expr::And(a, b) => eval(a, circuit, cache) & eval(b, circuit, cache),
Expr::Or(a, b) => eval(a, circuit, cache) | eval(b, circuit, cache),
Expr::LShift(a, n) => eval(a, circuit, cache) << n,
Expr::RShift(a, n) => eval(a, circuit, cache) >> n,
Expr::Not(a) => !eval(a, circuit, cache),
}
}
fn main() {
//let args: Vec<String> = env::args().collect();
//let filename = args.get(1).expect("Usage: day7 <input_file>");
//let input = fs::read_to_string(filename).expect("Failed to read file");
let binding = read_data("2015_07_data.txt");
let input = binding.to_string();
let mut circuit = HashMap::new();
for line in input.lines() {
let (target, expr) = parse_line(line);
println!("target -> {target}");
circuit.insert(target, expr);
}
let mut cache = HashMap::new();
let a_val = eval(&Expr::Wire("a".to_string()), &circuit, &mut cache);
println!("Signal on wire a: {}", a_val);
}
+44 -29
View File
@@ -1,40 +1,55 @@
use core::read_data;
fn parsed_string(input: &str) -> String {
let mut output = String::new();
let mut chars = input.chars().peekable();
while let Some(char) = chars.next() {
match char {
'\\' => {
match chars.next() {
Some('n') => output.push('\n'),
Some('t') => output.push('\t'),
Some('\\') => output.push('\\'),
Some('"') => output.push('"'),
Some('x') => {
let hi = chars.next().unwrap();
let lo = chars.next().unwrap();
let value = u8::from_str_radix(&format!("{hi}{lo}"), 16).unwrap();
output.push(value as char)
}
Some(other) => output.push(other),
None => {}
}
}
'"' => {}
_ => output.push(char)
}
}
output
}
fn main() {
let mut char_count = 0;
let mut mem_count = 0;
let binding = read_data("2015_08_data.txt");
let lines = binding.lines();
let binding = vec![
"\"\"",
"\"abc\"",
"\"abc\\\"abc\"",
"\"\\x27\""
r#""""#,
r#""abc""#,
r#""aaa\"aaa""#,
r#"\x27"#
].join("\n");
let lines = binding.lines();
for line in lines {
let mut num_bytes = 0;
let mut num_chars = 0;
let mut next_char_to_watch = 0;
let mut line_chars = line.chars();
for (current_index, current_char) in line_chars.clone().enumerate() {
if current_index > next_char_to_watch {
match current_char {
'"' => {
num_bytes += 1;
},
'\\' => {
println!("Found slash at {current_index}");
let x = line_chars.nth(current_index).unwrap();
// println!("{}", line_chars.colle
}
_ => {
num_bytes += 1;
num_chars += 1;
}
}
}
}
println!("[{line}] = B:{num_bytes} C:{num_chars}");
let raw_size = line.len();
let parsed = parsed_string(line).len();
println!("||{line}|| -> raw: {raw_size} parsed: {parsed}");
char_count += parsed;
mem_count += raw_size;
}
}
println!("{} - {} = {}", char_count, mem_count, 0);
println!("{}", mem_count - char_count);
}
+28 -28
View File
@@ -20,27 +20,22 @@
// 5: 1321132132211331232123222113
// 6: ...
fn num_to_change(input: &str) -> usize {
let mut return_value = 0;
let mut last_char = '\0';
fn look_and_say(input: String) -> String {
let mut working = String::new();
let mut chars = input.chars().peekable();
for (index, current_char) in input.chars().enumerate() {
if index != 0 {
if last_char != current_char {
return_value = index;
break
while let Some(current) = chars.next() {
let mut count = 1;
while let Some(&next) = chars.peek() {
if next == current {
count += 1;
chars.next();
} else {
break;
}
}
last_char = current_char
working.push_str(&format!("{}{}", count, current));
}
return_value
}
fn look_and_say(input: &str) -> String {
let mut working = String::new();
working
}
@@ -49,22 +44,27 @@ fn main() {
("1", "11"),
("11", "21"),
("21", "1211"),
// ("1211", "111221"),
// ("111221", "31221")
("1211", "111221"),
("111221", "312211")
];
for (input, output) in params {
let result = look_and_say(input);
let result = look_and_say(input.to_string());
println!("**** {input} processed to {result} expecting {output}");
assert_eq!(result, output);
}
let mut working_input = "";
let mut working_output = "";
// // puzzle time
// let mut current_input = "1113122113";
// for _ in 0..40 {
// let next_input = current_input.clone();
// let next_output = look_and_say(next_input);
// current_input = next_output.as_str();
// }
// println!("final -> {current_input}");
}
let mut current_input = String::from("1113122113");
let mut tmp_input = String::new();
for _ in 0..40 {
tmp_input = look_and_say(current_input.clone());
println!("[[{current_input}]] became [[{tmp_input}]]");
current_input = tmp_input;
}
println!("final -> {}", current_input.len());
}
// 360154
+54
View File
@@ -0,0 +1,54 @@
// Look-and-say sequences are generated iteratively, using the previous value as input for the next
// step. For each step, take the previous value, and replace each run of digits (like 111) with the
// number of digits (3) followed by the digit itself (1).
//
// For example:
//
// 1 becomes 11 (1 copy of digit 1).
// 11 becomes 21 (2 copies of digit 1).
// 21 becomes 1211 (one 2 followed by one 1).
// 1211 becomes 111221 (one 1, one 2, and two 1s).
// 111221 becomes 312211 (three 1s, two 2s, and one 1).
// Starting with the digits in your puzzle input, apply this process 40 times. What is the length
// of the result?
//
// Your puzzle input is 1113122113.
// 1: 311311222113
// 2: 13211321322113
// 3: 1113122113121113222113
// 4: 31131122211311133113322113
// 5: 1321132132211331232123222113
// 6: ...
fn look_and_say(input: String) -> String {
let mut working = String::new();
let mut chars = input.chars().peekable();
while let Some(current) = chars.next() {
let mut count = 1;
while let Some(&next) = chars.peek() {
if next == current {
count += 1;
chars.next();
} else {
break;
}
}
working.push_str(&format!("{}{}", count, current));
}
working
}
fn main() {
// // puzzle time
let mut current_input = String::from("1113122113");
let mut tmp_input = String::new();
for _ in 0..50 {
tmp_input = look_and_say(current_input.clone());
// println!("[[{current_input}]] became [[{tmp_input}]]");
current_input = tmp_input;
}
println!("final -> {}", current_input.len());
}
// 5103798
+34
View File
@@ -0,0 +1,34 @@
fn includes_straight(input: &str) -> bool {
true
}
fn excludes_forbidden(input: &str) -> bool {
!(
input.contains('i') ||
input.contains('o') ||
input.contains('l')
)
}
fn includes_pair(input: &str) -> bool {
let mut chars = input.chars().peekable();
while let Some(next) = chars.next() {
}
false
}
fn find_next_password(input: &str) -> String {}
fn main() {
let params = vec![
("abcdefgh", "abcdffaa"),
("ghijklmn", "ghjaabcc")
];
for (input, output) in params {
assert_eq!(find_next_password(input), output.to_string());
}
}
+29 -2
View File
@@ -22,10 +22,37 @@
// Given the descriptions of each reindeer (in your puzzle input), after exactly 2503 seconds, what
// distance has the winning reindeer traveled?
fn tick_world() {
struct Reindeer {
pub name: String,
pub is_flying: bool,
pub speed: u32,
pub duration: u32,
pub stop_time: u32,
pub next_change: u32
}
impl Reindeer {
/// Tick the reindeer telling it what time the world thinks it is.
pub fn tick(&mut self, world_time: u32) {
}
}
fn tick_world() {
}
fn main() {
let reindeer = vec![
Reindeer {
name: "Vixen".to_string(),
is_flying: false,
speed: 19,
duration: 7,
stop_time: 124,
next_change: 0,
},
Reindeer {},
Reindeer {},
Reindeer {}
];
}
+134
View File
@@ -0,0 +1,134 @@
use core::read_data;
#[derive(Debug)]
struct AuntSue {
pub id: i32,
pub children: i32,
pub cats: i32,
pub samoyeds: i32,
pub pomeranians: i32,
pub akitas: i32,
pub vizslas: i32,
pub goldfish: i32,
pub trees: i32,
pub cars: i32,
pub perfumes: i32
}
impl Default for AuntSue {
fn default() -> Self {
AuntSue {
id: -1,
children: -1,
cats: -1,
samoyeds: -1,
pomeranians: -1,
akitas: -1,
vizslas: -1,
goldfish: -1,
trees: -1,
cars: -1,
perfumes: -1,
}
}
}
fn parse_aunt(input: &str) -> AuntSue {
let mut working_sue = AuntSue::default();
let (sue_id, balance) = input.split_once(':').unwrap();
let (_, sue_id) = sue_id.trim().split_once(' ').unwrap();
// println!("SUE ID = [[{sue_id}]]");
let sue_id = sue_id.trim().parse::<i32>().unwrap();
working_sue.id = sue_id;
// println!("PARSING AUNT [[{input}]] / {sue_id}");
let sues_quirks = balance.split(", ");
for quirk in sues_quirks {
let (quirk_type, quirk_count) = quirk.trim().split_once(':').unwrap();
let quirk_count = quirk_count.trim().parse::<i32>().unwrap();
// println!("Sues Quirk is [[{quirk_type}]] with [[{quirk_count}]] instances.");
match quirk_type {
"vizslas" => {
working_sue.vizslas = quirk_count;
},
"perfumes" => {
working_sue.perfumes = quirk_count;
},
"akitas" => {
working_sue.akitas = quirk_count;
},
"cars" => {
working_sue.cars = quirk_count;
},
"trees" => {
working_sue.trees = quirk_count;
},
"cats" => {
working_sue.cats = quirk_count;
},
"goldfish" => {
working_sue.goldfish = quirk_count;
},
"pomeranians" => {
working_sue.pomeranians = quirk_count;
},
"samoyeds" => {
working_sue.samoyeds = quirk_count;
},
"children" => {
working_sue.children = quirk_count;
},
_ => {
println!("UNKNOWN TYPE OF QUIRK -> {quirk_type}");
}
}
}
// println!("Aunt Sue ID = {}")
// println!("** Aunt Done ** -> {working_sue:?}");
working_sue
}
fn is_the_sue_were_looking_for(input: &AuntSue) -> bool {
let target_sue= AuntSue {
id: 0,
children: 3,
cats: 7,
samoyeds: 2,
pomeranians: 3,
akitas: 0,
vizslas: 0,
goldfish: 5,
trees: 3,
cars: 2,
perfumes: 1,
};
let mut num_matches = 0;
if target_sue.children == input.children { num_matches += 1; };
if target_sue.cars == input.cats { num_matches += 1; }
if target_sue.samoyeds == input.samoyeds { num_matches += 1; };
if target_sue.pomeranians == input.pomeranians { num_matches += 1 };
if target_sue.akitas == input.akitas { num_matches += 1; };
if target_sue.vizslas == input.vizslas { num_matches += 1; };
if target_sue.goldfish == input.goldfish { num_matches += 1; };
if target_sue.trees == input.trees { num_matches += 1; };
if target_sue.cars == input.cars { num_matches += 1; };
if target_sue.perfumes == input.perfumes { num_matches += 1; };
num_matches == 3
}
fn main() {
let binding = read_data("2015_16_data.txt");
let lines = binding.lines();
for line in lines {
let parsed_aunt = parse_aunt(line);
if is_the_sue_were_looking_for(&parsed_aunt) {
println!("Aunt Sue {} is the aunt we want.", parsed_aunt.id);
break;
}
}
}
// 103
+133
View File
@@ -0,0 +1,133 @@
use core::read_data;
#[derive(Debug)]
struct AuntSue {
pub id: i32,
pub children: i32,
pub cats: i32,
pub samoyeds: i32,
pub pomeranians: i32,
pub akitas: i32,
pub vizslas: i32,
pub goldfish: i32,
pub trees: i32,
pub cars: i32,
pub perfumes: i32
}
impl Default for AuntSue {
fn default() -> Self {
AuntSue {
id: -1,
children: -1,
cats: -1,
samoyeds: -1,
pomeranians: -1,
akitas: -1,
vizslas: -1,
goldfish: -1,
trees: -1,
cars: -1,
perfumes: -1,
}
}
}
fn parse_aunt(input: &str) -> AuntSue {
let mut working_sue = AuntSue::default();
let (sue_id, balance) = input.split_once(':').unwrap();
let (_, sue_id) = sue_id.trim().split_once(' ').unwrap();
let sue_id = sue_id.trim().parse::<i32>().unwrap();
working_sue.id = sue_id;
// println!("PARSING AUNT [[{input}]] / {sue_id}");
let sues_quirks = balance.split(", ");
for quirk in sues_quirks {
let (quirk_type, quirk_count) = quirk.trim().split_once(':').unwrap();
let quirk_count = quirk_count.trim().parse::<i32>().unwrap();
// println!("Sues Quirk is [[{quirk_type}]] with [[{quirk_count}]] instances.");
match quirk_type {
"vizslas" => {
working_sue.vizslas = quirk_count;
},
"perfumes" => {
working_sue.perfumes = quirk_count;
},
"akitas" => {
working_sue.akitas = quirk_count;
},
"cars" => {
working_sue.cars = quirk_count;
},
"trees" => {
working_sue.trees = quirk_count;
},
"cats" => {
working_sue.cats = quirk_count;
},
"goldfish" => {
working_sue.goldfish = quirk_count;
},
"pomeranians" => {
working_sue.pomeranians = quirk_count;
},
"samoyeds" => {
working_sue.samoyeds = quirk_count;
},
"children" => {
working_sue.children = quirk_count;
},
_ => {
unreachable!("UNKNOWN TYPE OF QUIRK -> {}", quirk_type);
}
}
}
// println!("Aunt Sue ID = {}")
// println!("** Aunt Done ** -> {working_sue:?}");
working_sue
}
fn is_the_sue_were_looking_for(input: &AuntSue) -> bool {
let target_sue= AuntSue {
id: 0,
children: 3,
cats: 7,
samoyeds: 2,
pomeranians: 3,
akitas: 0,
vizslas: 0,
goldfish: 5,
trees: 3,
cars: 2,
perfumes: 1,
};
let mut num_matches = 0;
if target_sue.children == input.children { num_matches += 1; };
if target_sue.cats < input.cats && input.cats > -1 { num_matches += 1; }
if target_sue.samoyeds == input.samoyeds { num_matches += 1; };
if target_sue.pomeranians > input.pomeranians && input.pomeranians > -1 { num_matches += 1 };
if target_sue.akitas == input.akitas { num_matches += 1; };
if target_sue.vizslas == input.vizslas { num_matches += 1; };
if target_sue.goldfish > input.goldfish && input.goldfish > -1 { num_matches += 1; };
if target_sue.trees < input.trees && input.trees > -1 { num_matches += 1; };
if target_sue.cars == input.cars { num_matches += 1; };
if target_sue.perfumes == input.perfumes { num_matches += 1; };
num_matches == 3
}
fn main() {
let binding = read_data("2015_16_data.txt");
let lines = binding.lines();
for line in lines {
let parsed_aunt = parse_aunt(line);
if is_the_sue_were_looking_for(&parsed_aunt) {
println!("Aunt Sue {} is the aunt we want.", parsed_aunt.id);
break;
}
}
}
// 405
+9
View File
@@ -0,0 +1,9 @@
// this is the game of life.
fn tick_world(input: &mut [bool; 100*100]) {
}
fn main() {
let mut world = [true; 100*100];
}
+3
View File
@@ -0,0 +1,3 @@
fn main() {}
+108
View File
@@ -0,0 +1,108 @@
use core::read_data;
#[derive(Default)]
struct Computer {
pub a: u32,
pub b: u32,
pub pc: i32,
}
impl Computer {
fn dump(&self) {
println!("DUMPING COMPUTER");
println!("A: {}\tB: {}\tPC: {}",
self.a, self.b, self.pc
);
}
}
fn main() {
let mut computer = Computer::default();
let binding = read_data("2015_23_data.txt");
let lines = binding.lines();
for (index, line) in lines.enumerate() {
println!("Line {index} = [[{line}]]");
let (instruction, params) = line.split_once(" ").unwrap();
match instruction {
"inc" => {
match params.trim().chars().next().unwrap() {
'a' => {
computer.a += 1;
},
'b' => {
computer.b += 1;
},
_ => { unreachable!("Invalid Register"); }
}
},
"tpl" => {
match params.trim().chars().next().unwrap() {
'a' => {
computer.a = computer.a * 3;
},
'b' => {
computer.b = computer.b * 3;
},
_ => { unreachable!("Invalid Register") }
}
},
"hlf" => {
println!("HLF");
match params.trim().chars().next().unwrap() {
'a' => {
computer.a = computer.a / 2;
}
'b' => {
computer.b = computer.b / 2;
}
_ => { unreachable!("Invalid Register"); }
}
},
"jmp" => {
println!("JMP Parse from [[{params}]]");
let offset = params.trim().parse::<i32>().unwrap();
computer.pc += offset;
},
"jie" => {
let (register, offset) = params.trim().split_once(' ').unwrap();
let offset = offset.parse::<i32>().unwrap();
match register.trim().chars().next().unwrap() {
'a' => {
if computer.a.is_multiple_of(2) {
computer.pc += offset;
}
},
'b' => {
if computer.b.is_multiple_of(2) {
computer.pc += offset;
}
},
_ => { unreachable!("Invalid Register"); }
}
},
"jio" => {
let (register, offset) = params.trim().split_once(' ').unwrap();
let offset = offset.parse::<i32>().unwrap();
match register.trim().chars().next().unwrap() {
'a' => {
if !computer.a.is_multiple_of(2) {
computer.pc += offset;
}
},
'b' => {
if !computer.b.is_multiple_of(2) {
computer.pc += offset;
}
},
_ => { unreachable!("Invalid Register"); }
} },
_ => {
println!("Unhandled -> {instruction}");
}
}
computer.dump();
}
println!("Program loaded...");
computer.dump();
}