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);
}
|