Advent of Code solutions
1use std::env::args;
2use std::fs;
3use std::io::{stdin, Read};
4
5#[derive(Clone, Debug)]
6pub enum Selection {
7 All,
8 Single(usize), // TODO: Add range maybe?
9}
10
11impl Selection {
12 fn parse(input: &str) -> Self {
13 if input == "*" {
14 Self::All
15 } else {
16 let input = input.parse::<usize>().unwrap();
17 Self::Single(input)
18 }
19 }
20}
21
22#[derive(Clone, Debug)]
23pub struct DP {
24 pub day: Selection,
25 pub part: Selection,
26}
27
28const DP_ALL: DP = DP {
29 day: Selection::All,
30 part: Selection::All,
31};
32
33impl DP {
34 fn parse(input: &str) -> Self {
35 let mut split = input.split(':');
36
37 let day = split.next().map(Selection::parse).unwrap_or(Selection::All);
38 let part = split.next().map(Selection::parse).unwrap_or(Selection::All);
39
40 Self { day, part }
41 }
42}
43
44#[derive(Clone, Debug)]
45pub struct YDP {
46 pub year: Selection,
47 pub day: Selection,
48 pub part: Selection,
49}
50
51impl YDP {
52 fn parse(input: &str) -> Self {
53 let mut split = input.split(':');
54
55 let year = split.next().map(Selection::parse).unwrap_or(Selection::All);
56 let day = split.next().map(Selection::parse).unwrap_or(Selection::All);
57 let part = split.next().map(Selection::parse).unwrap_or(Selection::All);
58
59 Self { year, day, part }
60 }
61
62 pub fn to_dp(&self) -> DP {
63 DP {
64 day: self.day.clone(),
65 part: self.part.clone(),
66 }
67 }
68}
69
70pub fn get_dp_and_input() -> (DP, Option<String>) {
71 let mut args = args().skip(1);
72
73 let dp = args.next().map(|s| DP::parse(s.trim())).unwrap_or(DP_ALL);
74
75 let input = args.next().map(|s| s.trim().to_string()).map(|i| {
76 if i == "-" {
77 let mut input = String::new();
78 stdin()
79 .read_to_string(&mut input)
80 .expect("Failed to read input");
81 input.trim().to_string()
82 } else {
83 i
84 }
85 });
86
87 (dp, input)
88}
89
90pub fn get_ydp_and_input(args: Vec<String>) -> (YDP, Option<String>) {
91 let mut args = args.into_iter();
92
93 let ydp = args.next().map(|s| YDP::parse(s.trim())).unwrap_or(YDP {
94 year: Selection::All,
95 day: Selection::All,
96 part: Selection::All,
97 });
98
99 let input = args.next().map(|s| s.trim().to_string()).map(|i| {
100 if i == "-" {
101 let mut input = String::new();
102 stdin()
103 .read_to_string(&mut input)
104 .expect("Failed to read input");
105 input.trim().to_string()
106 } else {
107 fs::read_to_string(i).expect("Failed to read input file")
108 }
109 });
110
111 (ydp, input)
112}