more successes.

This commit is contained in:
Trevor Merritt 2025-09-19 10:40:28 -04:00
parent 7c3186abcf
commit af075edb24
25 changed files with 3425 additions and 145 deletions

View File

@ -23,63 +23,60 @@ fn identify_wires(input: &str) -> Vec<String> {
working
}
fn parse_instruction(input: &str) -> Option<Actions> {
fn parse_instruction(input: &str) -> 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() })
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()} ) },
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() })
unreachable!("UNHANDLED 4 PART -> {input}");
}
}
}
5 => {
match parts[1] {
"RSHIFT" => {
Some(Actions::RSHIFT {
Actions::RSHIFT {
a: parts[0].to_string(),
d: parts[2].parse::<u32>().unwrap(),
z: parts[4].to_string(),
})
}
},
"LSHIFT" => {
Some(Actions::LSHIFT {
Actions::LSHIFT {
a: parts[0].to_string(),
d: parts[2].parse::<u32>().unwrap(),
z: parts[4].to_string()
})
}
},
"AND" => {
Some(Actions::AND {
Actions::AND {
a: parts[0].to_string(),
b: parts[2].to_string(),
z: parts[4].to_string(),
})
}
},
"OR" => {
Some(Actions::OR {
Actions::OR {
a: parts[0].to_string(),
b: parts[2].to_string(),
z: parts[4].to_string(),
})
}
},
_ => {
println!("UNHANDLED 5 PART -> {input}");
None
unreachable!("UNHANDLED 5 PART -> {input}");
}
}
},
_ => {
println!("Unhandled {} part -> {input}", parts.len());
None
unreachable!("Unhandled {} part -> {input}", parts.len());
}
}
}
@ -92,8 +89,6 @@ fn main() {
for line in lines {
let parsed = parse_instruction(line);
if parsed.is_some() {
println!("PARSED [[{line}]] into [[{parsed:?}]]");
}
}
}

View File

@ -5,11 +5,11 @@ use core::read_data;
enum Expr {
Value(u16),
Wire(String),
Not(Box<Expr>),
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 {

View File

@ -1,55 +1,51 @@
use core::read_data;
use std::fs;
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'),
// Skip the surrounding quotes
let mut chars = input[1..input.len() - 1].chars().peekable();
while let Some(ch) = chars.next() {
match ch {
'\\' => match chars.next() {
Some('\\') => output.push('\\'),
Some('"') => output.push('"'),
Some('n') => output.push('\n'),
Some('t') => output.push('\t'),
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)
// Must be exactly two hex digits
let hi = chars.next().expect("Incomplete \\x escape");
let lo = chars.next().expect("Incomplete \\x escape");
let hex = format!("{hi}{lo}");
let value = u8::from_str_radix(&hex, 16)
.expect("Invalid hex escape in input");
output.push(value as char);
}
Some(other) => output.push(other),
None => {}
}
}
'"' => {}
_ => output.push(char)
Some(other) => panic!("Invalid escape: \\{other}"),
None => panic!("Dangling backslash"),
},
_ => output.push(ch),
}
}
output
}
use core::read_data;
fn main() {
let mut char_count = 0;
let mut mem_count = 0;
// Read your puzzle input file
let input = read_data("2015_08_data.txt");
let binding = read_data("2015_08_data.txt");
let lines = binding.lines();
let binding = vec![
r#""""#,
r#""abc""#,
r#""aaa\"aaa""#,
r#"\x27"#
].join("\n");
let lines = binding.lines();
let mut raw_total = 0;
let mut mem_total = 0;
for line in lines {
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;
for line in input.lines() {
let raw_len = line.len();
let mem_len = parsed_string(line).len();
raw_total += raw_len;
mem_total += mem_len;
}
println!("{} - {} = {}", char_count, mem_count, 0);
println!("{}", mem_count - char_count);
println!("Part 1: {} - {} = {}", raw_total, mem_total, raw_total - mem_total);
}

View File

@ -1,3 +1,19 @@
fn next_password(input: &str) -> Vec<char> {
// increment the last character.
let mut work: Vec<_> = input.clone().chars().collect();
let wlen = input.len();
print!("[[{work:?}]] ");
if work[wlen - 1] == 'z' {
} else {
work[wlen - 1] = (work[wlen - 1] as u8 + 1) as char;
}
println!(" became {work:?}");
work
}
fn includes_straight(input: &str) -> bool {
true
}
@ -19,8 +35,10 @@ fn includes_pair(input: &str) -> bool {
false
}
fn find_next_password(input: &str) -> String {}
fn find_next_password(input: &str) -> String {
let next_password = next_password(input).join("");
next_password
}
fn main() {
let params = vec![

View File

@ -43,37 +43,52 @@ struct Location {
fn main() {
let mut current_position = Location { x: 1, y: 1 };
// let directions = read_data("2016_02_data.txt");
let directions = "ULL\nRRDDD\nLURDL\nUUUUUD";
for next_direction in directions.chars() {
match next_direction {
'R' => {
if current_position.x < 3 {
current_position.x += 1;
let directions = read_data("2016_02_data.txt");
//let directions = "ULL\nRRDDD\nLURDL\nUUUUUD";
for line_of_directions in directions.lines() {
println!("Processing directions of {line_of_directions} starting at {}x{}", current_position.x, current_position.y);
for current_direction in line_of_directions.chars() {
// print!(" [{current_direction}] ");
match current_direction {
'U' => {
if current_position.y > 0 {
current_position.y -= 1;
//println!("Moving up.")
} else {
//println!("At Edge");
}
},
'D' => {
if current_position.y < 2 {
current_position.y += 1;
//println!("Moving down.");
} else {
//println!("At Edge");
}
},
'L' => {
if current_position.x > 0 {
current_position.x -= 1;
//println!("Moving left.");
} else {
//println!("At Edge");
}
},
'U' => {
if current_position.y < 3 {
current_position.y += 1;
}
},
'D' => {
if current_position.y > 0 {
current_position.y -= 1;
}
},
'\n' => {
println!("At {current_position:?}");
7 },
_ => { unreachable!("Invalid direction"); }
'R' => {
if current_position.x < 2 {
current_position.x += 1;
//println!("Moving right.");
} else {
//println!("At Edge");
}
}
_ => { unreachable!("invalid direction.") }
}
// 2445 is wrong.
// 3775 is wrong.
// println!("Ending line at {}x{}", current_position.x, current_position.y);
//
}
println!("CELL = {}", (current_position.x + 1) + (current_position.y * 3));
}
println!("Ending at {}x{}", current_position.x, current_position.y);
}
// 84452

View File

@ -9,6 +9,7 @@ struct EncryptedRoom {
fn main() {
let binding = read_data("2016_04_data.txt");
let inputs = binding.lines();
for line in inputs {
@ -40,6 +41,8 @@ fn main() {
println!("HASH: {hash:?}");
// now find the 5 most frequently occurring characters in alphabetical order
// once we have the new value, compare it to the checksum
for (k, v) in hash {
}
}
}

View File

@ -1,23 +1,5 @@
// While snooping around the local network of EBHQ, you compile a list of IP addresses (they're
// IPv7, of course; IPv6 is much too limited). You'd like to figure out which IPs support TLS
// (transport-layer snooping).
//
// An IP supports TLS if it has an Autonomous Bridge Bypass Annotation, or ABBA. An ABBA is any
// four-character sequence which consists of a pair of two different characters followed by the
// reverse of that pair, such as xyyx or abba. However, the IP also must not have an ABBA within
// any hypernet sequences, which are contained by square brackets.
//
// For example:
//
// abba[mnop]qrst supports TLS (abba outside square brackets).
// abcd[bddb]xyyx does not support TLS (bddb is within square brackets, even though xyyx is outside
// square brackets).
// aaaa[qwer]tyui does not support TLS (aaaa is invalid; the interior characters must be different).
// ioxxoj[asdfgh]zxcvbn supports TLS (oxxo is outside square brackets, even though it's within a
// larger string).
// How many IPs in your puzzle input support TLS?
use core::read_data;
fn has_abba(input: &str) -> bool {
let chars: Vec<char> = input.chars().collect();
@ -31,24 +13,29 @@ fn has_abba(input: &str) -> bool {
false
}
fn extract_hypernet(input: &str) -> (String, String) {
let mut payload = String::new();
let mut real_balance = String::from(input);
while real_balance.contains('[') {
let (prefix, balance) = real_balance.split_once('[').unwrap();
let (tmp, t_balance) = balance.split_once(']').unwrap();
payload = format!("{}{}", payload, tmp.to_string());
real_balance = format!("{}{}", prefix, t_balance);
// extract the text between the '[' and ']' characters
/// Split the address into supernet (outside brackets) and hypernet (inside brackets) parts.
fn split_address(input: &str) -> (Vec<String>, Vec<String>) {
let mut supernets = Vec::new();
let mut hypernets = Vec::new();
let mut rest = input;
while let Some((prefix, balance)) = rest.split_once('[') {
let (inside, suffix) = balance.split_once(']').unwrap();
supernets.push(prefix.to_string());
hypernets.push(inside.to_string());
rest = suffix;
}
(real_balance, payload.to_string())
if !rest.is_empty() {
supernets.push(rest.to_string());
}
fn has_tls(address: &str, hypernet: &str) -> bool {
let abba = has_abba(address);
let noabba = !has_abba(hypernet);
println!("[{address}] ABBA: {abba} [{hypernet}] NOABBA: {noabba}");
abba && noabba
(supernets, hypernets)
}
fn has_tls(supernets: &[String], hypernets: &[String]) -> bool {
let has_outside = supernets.iter().any(|s| has_abba(s));
let has_inside = hypernets.iter().any(|h| has_abba(h));
has_outside && !has_inside
}
fn main() {
@ -57,27 +44,64 @@ fn main() {
("abba[mnop]qrst", true),
("abcd[bddb]xyyx", false),
("aaaa[qwer]tyui", false),
("ioxxoj[asdfgh]zxcvbn", true)
("ioxxoj[asdfgh]zxcvbn", true),
("aaa[qwer]abba", true), // tricky case: should be valid
];
for (input, expected) in params {
println!("------------------Testing [[{input}]]");
let (address, hypernet) = extract_hypernet(input);
println!("[[{input}]] = ADD: {address} HN: {hypernet}");
assert_eq!(has_tls(address.as_str(), hypernet.as_str()), expected)
let (supernets, hypernets) = split_address(input);
println!(
"[[{input}]] = SUPERNETS: {:?} HYPERNETS: {:?}",
supernets, hypernets
);
assert_eq!(has_tls(&supernets, &hypernets), expected)
}
let binding = read_data("2016_07_data.txt");
let lines = binding.lines();
for line in lines {
let (address, hypernet) = extract_hypernet(line);
println!("Processing ||||{line}|||| -> {}/{}", address, hypernet);
if has_tls(address.as_str(), hypernet.as_str()) {
let (supernets, hypernets) = split_address(line);
if has_tls(&supernets, &hypernets) {
num_good += 1;
}
}
println!("Found {num_good} good addresses.");
}
#[cfg(test)]
mod test {
use crate::{has_abba, split_address, has_tls};
// 132 too high
#[test]
fn abba_tests() {
let params = vec![
("abba", true),
("aabb", false),
("ioxxoj", true),
("aaaa", false),
];
for (input, result) in params {
assert_eq!(has_abba(input), result, "failed on {input}");
}
}
#[test]
fn split_and_tls_tests() {
let cases = vec![
("abba[mnop]qrst", true),
("abcd[bddb]xyyx", false),
("aaaa[qwer]tyui", false),
("ioxxoj[asdfgh]zxcvbn", true),
("aaa[qwer]abba", true), // confirms split works
];
for (input, expected) in cases {
let (sup, hyp) = split_address(input);
assert_eq!(has_tls(&sup, &hyp), expected, "failed on {input}");
}
}
}
// 118 with ChatGPT to explain how merging the hypernet sections cause problems.

View File

@ -1,5 +1,5 @@
const SCREEN_COLS: usize = 50;
const SCREEN_ROWS: usize = 6;
const SCREEN_COLS: usize = 8;
const SCREEN_ROWS: usize = 3;
const SCREEN_SIZE: usize = SCREEN_COLS * SCREEN_ROWS;
#[derive(Debug, Copy, Clone)]
@ -9,20 +9,31 @@ enum Actions {
RotateColumn(u32, u32)
}
struct World {
width: u32,
height: u32,
memory: Box<[bool]>
}
impl Actions {
// rotate a column 1 time.
fn rotate_column(&self, column_index: u32, target: &mut [bool; SCREEN_SIZE]) {
let first_value = target[column_index as usize];
for index in (SCREEN_COLS..0).rev() {
let mut last_value = false;
for index in (0..SCREEN_COLS).rev() {
let offset = index as u32 * SCREEN_COLS as u32 + column_index;
println!("index = {index} offset = {offset}");
let next_offset = offset + SCREEN_COLS as u32;
println!("index: {} offset: {} next_offset: {}",
index, offset, next_offset);
last_value = target[offset as usize];
target[offset as usize] = last_value;
}
}
// rotate a row 1 time.
fn rotate_row(&self, row_index: u32, target: &mut [bool; SCREEN_SIZE]) {
for index in (SCREEN_ROWS..0).rev() {
let offset = index as u32 * SCREEN_COLS as u32 + index;
let offset = index as u32 * SCREEN_COLS as u32 + index as u32;
println!("index = {index} offset = {offset}");
}
}
@ -95,6 +106,13 @@ fn dump_screen(to_display: &[bool; SCREEN_SIZE]) {
fn main() {
let mut screen_space:[bool; SCREEN_SIZE] = [false; SCREEN_SIZE];
let mut world = World {
width: 8,
height: 3,
memory: Box::new([false; 8*3]),
};
let directions = vec![
"rect 3x2",
"rotate column x=1 by 1",
@ -109,3 +127,5 @@ fn main() {
dump_screen(&screen_space);
}
}

View File

@ -1,3 +1,59 @@
use std::ptr::hash;
use core::read_data;
/// Calculate the decompressed length of a string.
/// If `recursive` is true, markers are expanded recursively (Part 2).
/// If `recursive` is false, markers are expanded only once (Part 1).
fn decompressed_len(input: &str, recursive: bool) -> usize {
let mut total = 0;
let mut i = 0;
let binding = input.to_ascii_uppercase();
let bytes = binding.as_bytes();
while i < bytes.len() {
if bytes[i] == b'(' {
// find end of marker
let end = input[i..].find(')').unwrap() + i;
let marker = &input[i + 1..end];
let (a, b) = marker.split_once('x').unwrap();
let a: usize = a.parse().unwrap();
let b: usize = b.parse().unwrap();
i = end + 1;
let segment = &input[i..i + a];
let seg_len = if recursive {
decompressed_len(segment, true)
} else {
segment.len()
};
total += seg_len * b;
i += a;
} else {
total += 1;
i += 1;
}
}
total
}
fn main() {
let puzzle_input = read_data("2016_09_data.txt");
let params = vec![
("ADVENT", 6),
("A(1x5)BC", 7),
("(3x3)XYZ", 9),
("A(2x2)BCD(2x2)EFG", 11),
("(6x1)(1x3)A", 6),
("X(8x2)(3x3)ABCY", 18),
(puzzle_input.as_str(), 100)
];
for (input, size) in params {
let decompressed_size = decompressed_len(input, false);
println!("Tested {} char string for expanded size of {} -> Calculated {}", input.len(), size, decompressed_size);
}
}
// 138735 ChatGPT held my hand through this as parsing text is not my strong point.

54
2016/src/bin/2016_15a.rs Normal file
View File

@ -0,0 +1,54 @@
use core::read_data;
struct Disc {
pub id: u32,
pub num_slots: u32,
pub current_slot: u32,
}
fn parse_disc(input: &str) -> Disc {
// Example line:
// "Disc #1 has 5 positions; at time=0, it is at position 4."
let parts: Vec<&str> = input
.trim_end_matches('.')
.split_whitespace()
.collect();
let id = parts[1][1..].parse::<u32>().unwrap(); // "#1" → "1"
let num_slots = parts[3].parse::<u32>().unwrap(); // "5"
let current_slot = parts[11].parse::<u32>().unwrap(); // "4"
Disc { id, num_slots, current_slot }
}
fn holes_line_up(discs: &Vec<Disc>, time: u32) -> bool {
for disc in discs {
// Puzzle logic: capsule reaches disc `id` at time + id
if (disc.current_slot + time + disc.id) % disc.num_slots != 0 {
return false;
}
}
true
}
fn main() {
let binding = read_data("2016_15_data.txt");
let inputs = binding.lines();
let mut discs = vec![];
for line in inputs {
let new_disc = parse_disc(line);
discs.push(new_disc);
}
println!("Discs loaded. Searching for the correct release time...");
let mut time = 0;
while !holes_line_up(&discs, time) {
time += 1;
}
println!("Capsule falls through at time {time}.");
}
// 317371

57
2016/src/bin/2016_15b.rs Normal file
View File

@ -0,0 +1,57 @@
use core::read_data;
struct Disc {
pub id: u32,
pub num_slots: u32,
pub current_slot: u32,
}
fn parse_disc(input: &str) -> Disc {
// Example line:
// "Disc #1 has 5 positions; at time=0, it is at position 4."
let parts: Vec<&str> = input
.trim_end_matches('.')
.split_whitespace()
.collect();
let id = parts[1][1..].parse::<u32>().unwrap(); // "#1" → "1"
let num_slots = parts[3].parse::<u32>().unwrap(); // "5"
let current_slot = parts[11].parse::<u32>().unwrap(); // "4"
Disc { id, num_slots, current_slot }
}
fn holes_line_up(discs: &Vec<Disc>, time: u32) -> bool {
for disc in discs {
// Puzzle logic: capsule reaches disc `id` at time + id
if (disc.current_slot + time + disc.id) % disc.num_slots != 0 {
return false;
}
}
true
}
fn main() {
let binding = read_data("2016_15_data.txt");
let inputs = binding.lines();
let mut discs = vec![];
for line in inputs {
let new_disc = parse_disc(line);
discs.push(new_disc);
}
println!("Discs loaded. Searching for the correct release time...");
discs.push(Disc { id: 7, num_slots: 11, current_slot: 0 });
let mut time = 0;
while !holes_line_up(&discs, time) {
time += 1;
}
println!("Capsule falls through at time {time}.");
}
// 2080951 help from ChatGPT to understand
// that each disc ticks 1/time unit, but they dont all tick at that second,
// they cascade.

0
2016/src/bin/2016_17a.rs Normal file
View File

View File

@ -5,3 +5,4 @@ edition = "2024"
[dependencies]
core = { path = "../core" }
chrono = "0.4"

View File

@ -32,3 +32,4 @@ fn main() {
}
println!("Found {num_good} good boxes? / Checksum {}", num_two * num_three);
}
// Checksum 5434

111
2018/src/bin/2018_03a.rs Normal file
View File

@ -0,0 +1,111 @@
use core::read_data;
pub const WORLD_WIDTH: u32 = 1000;
pub const WORLD_HEIGHT: u32 = 1000;
pub const WORLD_SIZE: u32 = WORLD_WIDTH * WORLD_HEIGHT;
#[derive(Debug)]
struct Point {
pub x: u32,
pub y: u32
}
#[derive(Debug)]
struct Region {
pub elf: u32,
pub start: Point,
pub end: Point,
pub size: Point
}
impl Region {
fn new_with_size(start: Point, size: Point) -> Region {
Region {
elf: 0,
end: Point { x: start.x + size.x, y: start.y + size.y },
start,
size
}
}
// fn new_with_end(start: Point, end: Point) -> Region {
//
// }
}
fn apply_region(to_claim: &Region, world: &mut [u32; WORLD_SIZE as usize]) {
println!("Claiming from {}x{} to {}x{}",
to_claim.start.x,
to_claim.start.y,
to_claim.end.x,
to_claim.end.y
);
for y in to_claim.start.y..to_claim.end.y {
for x in to_claim.start.x..to_claim.end.x {
let offset = y * WORLD_WIDTH + x;
world[offset as usize] += 1;
}
}
}
/// convert a single line of input into a region claim.
fn line_to_region(input: &str) -> Region {
// [[#<elf> @ <start.x, start.y>: <width.x, width.y>
let (elf, balance) = input.split_once("@").unwrap();
let (_, elf_id) = elf.split_once('#').unwrap();
let (start_point, size_point) = balance.split_once(": ").unwrap();
let (start_x, start_y) = start_point.trim().split_once(',').unwrap();
let (size_x, size_y) =size_point.trim().split_once('x').unwrap();
let start = Point {
x: start_x.parse().unwrap(),
y: start_y.parse().unwrap()
};
let size = Point {
x: size_x.parse().unwrap(),
y: size_y.parse().unwrap()
};
let end = Point {
x: start.x + size.x,
y: start.y + size.y,
};
println!("ELF: [[{elf_id}]] START_POINT: [[{start_x}x{start_y}]] SIZE: [[{size_x}x{size_y}]] END: [[{}x{}]]",
end.x, end.y
);
let mut working = Region {
elf: elf_id.trim().parse().unwrap(),
start,
end,
size,
};
println!("Decoded [[{input}]] to [[{working:?}]]");
working
}
fn main() {
let binding = read_data("2018_03_data.txt");
let lines = binding.lines();
let mut world = [0x00u32; WORLD_SIZE as usize];
for line in lines {
apply_region(
&line_to_region(
line
), &mut world
);
}
// now count the areas with a value >=2
let mut num_multiclaimed = 0;
for offset in 0..WORLD_SIZE {
if world[offset as usize] >= 2 {
num_multiclaimed += 1;
}
}
println!("There are {num_multiclaimed} multi-claimed squares.");
}
// 120419 too high

89
2018/src/bin/2018_04a.rs Normal file
View File

@ -0,0 +1,89 @@
use std::collections::HashMap;
use chrono::{NaiveDateTime, Timelike};
use core::read_data;
use crate::WorkEvent::*;
#[derive(Debug)]
enum WorkEvent {
// [1518-09-07 00:00] Guard #2383 begins shift
StartShift(u32),
// [1518-08-20 00:17] falls asleep
FallAsleep,
// [1518-05-09 00:58] wakes up
WakeUp
}
fn parse_line(input: &str) -> (WorkEvent, NaiveDateTime) {
let (mut date, balance) = input.split_once("] ").unwrap();
let mut event = FallAsleep;
if balance.contains('#') {
let (_, guard_id_plus_junk) = balance.split_once("#").unwrap();
let (guard_id, _) = guard_id_plus_junk.split_once(" ").unwrap();
event = StartShift(guard_id.parse().unwrap());
} else {
if !balance.contains("falls") {
event = WakeUp
}
}
let parsed = NaiveDateTime::parse_from_str(date.strip_prefix('[').unwrap(), "%Y-%m-%d %H:%M").unwrap();
(event, parsed)
}
fn main() {
let binding = read_data("2018_04_data.txt");
let lines = binding.lines();
let mut worklog = HashMap::new();
for line in lines {
// println!("-- LINE = __{line}__ --");
let (event, when) = parse_line(line);
worklog.insert(when, event);
// println!("--");
}
println!("Loaded {} work events. Sorting...", worklog.len());
let mut items: Vec<_> = worklog.iter().collect();
items.sort_by(|a, b| a.0.cmp(& b.0));
let mut sleeping_guard = 0;
let mut sleep_time = NaiveDateTime::default();
let mut working_guard = 0;
let mut guard_sleep_log = HashMap::new();
let mut minute_sleep_log: HashMap<u32, HashMap<i32, i32>> = HashMap::new();
for index in 0..=60 {
minute_sleep_log.insert(index, HashMap::new());
}
for (k, v) in items {
println!("K: {k} V: {v:?}");
match v {
StartShift(guard_id) => {
working_guard = *guard_id;
// println!("Guard {guard_id} started at {k:?}");
}
FallAsleep => {
// println!("Guard {working_guard} is now sleeping at {k:?}");
sleeping_guard = working_guard;
sleep_time = *k;
}
WakeUp => {
let sleep_duration = k.signed_duration_since(sleep_time);
// println!("Guard {sleeping_guard} is now waking up at {k:?}, was sleeping for {} minutes.", sleep_duration.num_minutes());
*guard_sleep_log.entry(sleeping_guard).or_insert(0) += sleep_duration.num_minutes();
sleeping_guard = 0;
// println!("Sleep from {} to {} for {}", sleep_time.minute(), k.minute(), working_guard);
for minute in sleep_time.minute()..=k.minute() {
println!("Marking sleep at {minute} for {working_guard}");
minute_sleep_log.entry(minute).or_insert(HashMap::from((working_guard, 1)));
println!("MSL has {} entries.", minute_sleep_log.len());
}
}
}
// println!("--");
}
println!("Guard Sleep Log:");
println!("{guard_sleep_log:?}");
}

26
2018/src/bin/2018_05a.rs Normal file
View File

@ -0,0 +1,26 @@
fn process(input: &str) -> (String, u32) {
let num_changes = 0;
let mut peekables = input.chars().peekable();
while let Some(current_char) = peekables.next() {
println!("Checking {current_char} and {}", peekables.next().unwrap());
}
(String::new(), num_changes)
}
fn process_recursively(input: &str) -> String {
let mut working_str = input;
println!("RECURSIVE START: {}", input.len());
let mut need_again = true;
while need_again {
let (working, last_count) = process(working_str);
if last_count > 0 { need_again = true; }
let w2 = working.clone();
working_str = w2.as_str();
}
"dabCBAcaDA".to_string()
}
fn main() {
assert_eq!(process_recursively("dabAcCaCBAcCcaDA"), "dabCBAcaDA");
}

289
Cargo.lock generated
View File

@ -11,6 +11,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "aoc2015"
version = "0.1.0"
@ -38,6 +47,7 @@ dependencies = [
name = "aoc2018"
version = "0.1.0"
dependencies = [
"chrono",
"core",
]
@ -84,6 +94,12 @@ dependencies = [
"regex",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "block-buffer"
version = "0.10.4"
@ -93,16 +109,51 @@ dependencies = [
"generic-array",
]
[[package]]
name = "bumpalo"
version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
[[package]]
name = "cc"
version = "1.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "chrono"
version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-link 0.2.0",
]
[[package]]
name = "core"
version = "0.1.0"
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -123,6 +174,12 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
[[package]]
name = "generic-array"
version = "0.14.7"
@ -133,6 +190,52 @@ dependencies = [
"version_check",
]
[[package]]
name = "iana-time-zone"
version = "0.1.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "js-sys"
version = "0.3.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "log"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
name = "md-5"
version = "0.10.6"
@ -149,6 +252,39 @@ version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.11.2"
@ -178,14 +314,167 @@ version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "typenum"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "unicode-ident"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasm-bindgen"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1"
dependencies = [
"unicode-ident",
]
[[package]]
name = "windows-core"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link 0.1.3",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]]
name = "windows-result"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
"windows-link 0.1.3",
]
[[package]]
name = "windows-strings"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
"windows-link 0.1.3",
]

2
README
View File

@ -1,4 +1,4 @@
Trevors AOC workspace.
Trevor's AOC workspace.
This is not for the public. If you aren't Trevor, please go away now.

1
data/2016_09_data.txt Normal file

File diff suppressed because one or more lines are too long

6
data/2016_15_data.txt Normal file
View File

@ -0,0 +1,6 @@
Disc #1 has 17 positions; at time=0, it is at position 1.
Disc #2 has 7 positions; at time=0, it is at position 0.
Disc #3 has 19 positions; at time=0, it is at position 2.
Disc #4 has 5 positions; at time=0, it is at position 0.
Disc #5 has 3 positions; at time=0, it is at position 0.
Disc #6 has 13 positions; at time=0, it is at position 5.

1407
data/2018_03_data.txt Normal file

File diff suppressed because it is too large Load Diff

1110
data/2018_04_data.txt Normal file

File diff suppressed because it is too large Load Diff

1
data/2018_05_data.txt Normal file

File diff suppressed because one or more lines are too long