summaryrefslogtreecommitdiff
path: root/2020/src/bin/day_2.rs
blob: 6c26647bea39e2bad0a0fde919642d611bd71d74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use bevy::prelude::*;
use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    App::build()
        .add_resource(WindowDescriptor {
            title: "Advent of Code".to_string(),
            width: 1920,
            height: 1080,
            ..Default::default()
        })
        .add_resource(ClearColor(Color::rgb(0., 0., 0.)))
        .add_startup_system(setup_camera.system())
        .add_startup_system(read_input_file.system())
        .add_stage("mark")
        .add_system_to_stage("mark", validate_sled_passwords.system())
        .add_system_to_stage("mark", validate_toboggan_passwords.system())
        .add_stage("report")
        .add_system_to_stage("report", count_valid_sled_passwords.system())
        .add_system_to_stage("report", count_valid_toboggan_passwords.system())
        //.add_plugins(DefaultPlugins)
        .run();
}

fn setup_camera(mut commands: Commands) {
    commands.spawn(Camera2dComponents::default());
}

struct PasswordRule {
    num_1: usize,
    num_2: usize,
    c: char,
}
struct Password(String);
struct SledPasswordValidation(bool);
struct TobogganPasswordValidation(bool);

fn read_input_file(mut commands: Commands) {
    let f = File::open("./inputs/day_2.txt").expect("Failed to read file"); // TODO: Use the asset loading system to load this rather?
    for line in BufReader::new(f).lines() {
        let line = line.expect("Error reading file");
        let line = line.trim();
        let mut parts = line.split_whitespace();
        let range = parts.next().expect("File was missing a range");
        let chars = parts.next().expect("File was missing chars");
        let password = parts.next().expect("File was missing a password");

        let mut range_parts = range.split('-');

        let rule = PasswordRule {
            num_1: range_parts
                .next()
                .expect("Range did not have a minimum")
                .parse()
                .expect("Minimum was not a number"),
            num_2: range_parts
                .next()
                .expect("Range did not have a maximum")
                .parse()
                .expect("Maximum was not a number"),
            c: chars.chars().next().expect("File was missing chars"),
        };
        let password = Password(password.to_owned());

        commands.spawn((rule, password));
    }
}

fn validate_sled_passwords(
    mut commands: Commands,
    passwords: Query<Without<SledPasswordValidation, (Entity, &PasswordRule, &Password)>>,
) {
    for (entity, rule, password) in passwords.iter() {
        let actual = password.0.chars().filter(|c| c == &rule.c).count();
        let valid = actual >= rule.num_1 && actual <= rule.num_2;
        commands.insert_one(entity, SledPasswordValidation(valid));
    }
}

fn validate_toboggan_passwords(
    mut commands: Commands,
    passwords: Query<Without<TobogganPasswordValidation, (Entity, &PasswordRule, &Password)>>,
) {
    for (entity, rule, password) in passwords.iter() {
        let actual_1 = password.0.chars().nth(rule.num_1 - 1);
        let actual_2 = password.0.chars().nth(rule.num_2 - 1);
        let actual_1_match = actual_1.map_or(false, |c| c == rule.c);
        let actual_2_match = actual_2.map_or(false, |c| c == rule.c);

        let valid = actual_1_match != actual_2_match;
        commands.insert_one(entity, TobogganPasswordValidation(valid));
    }
}

fn count_valid_sled_passwords(validation: Query<&SledPasswordValidation>) {
    let count = validation.iter().filter(|v| v.0).count();
    println!("Valid Sled Passwords: {}", count);
}

fn count_valid_toboggan_passwords(validation: Query<&TobogganPasswordValidation>) {
    let count = validation.iter().filter(|v| v.0).count();
    println!("Valid Toboggan Passwords: {}", count);
}