Skip to content

Instantly share code, notes, and snippets.

@oisin
Created December 6, 2023 18:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oisin/bd8c24fde4d2cce5b3faf4e1018636b3 to your computer and use it in GitHub Desktop.
Save oisin/bd8c24fde4d2cce5b3faf4e1018636b3 to your computer and use it in GitHub Desktop.
AOC 23 Day 4 Part 1
#![allow(dead_code, unused_variables, unused_mut)]
use std::env;
use std::fs::File;
use std::io::{self, BufRead};
use std::collections::HashSet;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: {} <filename>", args[0]);
std::process::exit(1);
}
let filename = &args[1];
let file = match File::open(filename) {
Ok(file) => file,
Err(error) => {
eprintln!("Error opening file {}: {}", filename, error);
std::process::exit(1);
}
};
let reader = io::BufReader::new(file);
let mut accum = 0;
for (line_number, line) in reader.lines().enumerate() {
match line {
Ok(line_content) => {
let row = parse(line_number + 1, line_content);
// println!("Row: {:?} ", row.numbers);
// First 10 numbers are the winning numbers, rest are the guess numbers
let mut winners: HashSet<u32> = row.numbers.clone().into_iter().take(10).collect();
let mut guesses: HashSet<u32> = row.numbers.clone().into_iter().skip(10).collect();
let wins = winners.intersection(&guesses).count() as u32;
if wins > 0 {
accum += u32::pow(2, wins - 1);
}
},
Err(error) => {
eprintln!("Error reading line {}: {}", line_number + 1, error);
}
}
}
println!("Total = {}", accum);
}
#[derive(PartialEq)]
enum ParseState {
Ignore,
Start,
Number
}
#[derive(Clone, Copy)]
struct ParserContext {
value: u32
}
struct Row {
numbers: Vec<u32>
}
fn parse(line_number: usize, line_content: String) -> Row {
let mut state = ParseState::Ignore;
let mut row = Row {
numbers: Vec::new()
};
let mut context = ParserContext{
value: 0
};
for (pos, c) in line_content.chars().enumerate() {
match c {
':' => {
state = ParseState::Start;
}
('0'..='9') => {
match state {
ParseState::Start => {
context = ParserContext {
value: c.to_digit(10).expect("Bum not a digit"),
};
state = ParseState::Number;
}
ParseState::Number => {
context.value = context.value * 10 + c.to_digit(10).expect("Bum not a digit")
}
_ => ()
}
},
_ => {
if state == ParseState::Number {
row.numbers.push(context.value);
}
state = ParseState::Start;
}
}
}
if state == ParseState::Number {
row.numbers.push(context.value);
}
row
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment