Skip to content

Commit 757c6cf

Browse files
committed
feat(07/2015): solve first part for example, too slow for input
1 parent 4014206 commit 757c6cf

File tree

2 files changed

+201
-3
lines changed

2 files changed

+201
-3
lines changed

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
| [Day 4: The Ideal Stocking Stuffer](src/solutions/year2015/day04.rs) | ⭐⭐ | 66.769 | 1931.428 |
9494
| [Day 5: Doesn't He Have Intern-Elves For This?](src/solutions/year2015/day05.rs) | ⭐⭐ | 0.261 | 0.987 |
9595
| [Day 6: Probably a Fire Hazard](src/solutions/year2015/day06.rs) | ⭐⭐ | 871.538 | 817.533 |
96+
| [Day 7: Some Assembly Required](src/solutions/year2015/day07.rs) | | - | - |
9697

9798
# TODO
9899

src/solutions/year2015/day07.rs

Lines changed: 200 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,220 @@
11
use crate::solutions::Solution;
2+
use std::collections::HashMap;
3+
use std::str::FromStr;
4+
5+
type Wires = HashMap<String, Instruction>;
26

37
pub struct Day07;
48

59
impl Solution for Day07 {
6-
fn part_one(&self, _input: &str) -> String {
7-
String::from("0")
10+
fn part_one(&self, input: &str) -> String {
11+
self.signal(input, "a")
812
}
913

1014
fn part_two(&self, _input: &str) -> String {
1115
String::from("0")
1216
}
1317
}
1418

19+
impl Day07 {
20+
fn signal(&self, input: &str, wire: &str) -> String {
21+
let instructions = self.parse(input);
22+
let main = instructions.get(wire).unwrap();
23+
24+
main.calculate(&instructions).to_string()
25+
}
26+
27+
fn parse(&self, input: &str) -> Wires {
28+
input
29+
.lines()
30+
.map(|line| {
31+
let (instruction, output) = line.split_once(" -> ").unwrap();
32+
(
33+
output.to_string(),
34+
Instruction::from_str(instruction).unwrap(),
35+
)
36+
})
37+
.collect()
38+
}
39+
}
40+
41+
#[derive(Debug, PartialEq, Clone)]
42+
enum Instruction {
43+
Value(Value),
44+
And(Value, Value),
45+
Or(Value, Value),
46+
LShift(Value, u64),
47+
RShift(Value, u64),
48+
Not(Value),
49+
}
50+
51+
impl Instruction {
52+
fn calculate(&self, wires: &Wires) -> u16 {
53+
match self {
54+
Instruction::Value(value) => match value {
55+
Value::Numeric(number) => *number,
56+
Value::Variable(s) => wires.get(s).unwrap().calculate(wires),
57+
},
58+
Instruction::And(a, b) => {
59+
let left = Instruction::Value(a.clone()).calculate(wires);
60+
let right = Instruction::Value(b.clone()).calculate(wires);
61+
62+
left & right
63+
}
64+
Instruction::Or(a, b) => {
65+
let left = Instruction::Value(a.clone()).calculate(wires);
66+
let right = Instruction::Value(b.clone()).calculate(wires);
67+
68+
left | right
69+
}
70+
Instruction::LShift(a, b) => {
71+
let left = Instruction::Value(a.clone()).calculate(wires);
72+
73+
left << b
74+
}
75+
Instruction::RShift(a, b) => {
76+
let left = Instruction::Value(a.clone()).calculate(wires);
77+
78+
left >> b
79+
}
80+
Instruction::Not(a) => {
81+
let value = Instruction::Value(a.clone()).calculate(wires);
82+
83+
!value
84+
}
85+
}
86+
}
87+
}
88+
89+
impl FromStr for Instruction {
90+
type Err = ();
91+
92+
fn from_str(s: &str) -> Result<Self, Self::Err> {
93+
let parse_variable = |variable: &str| {
94+
if let Ok(number) = variable.parse::<u16>() {
95+
Ok(Value::Numeric(number))
96+
} else {
97+
Ok(Value::Variable(variable.to_string()))
98+
}
99+
};
100+
101+
if let Ok(number) = s.parse::<u16>() {
102+
return Ok(Instruction::Value(Value::Numeric(number)));
103+
}
104+
105+
if let Some((left, right)) = s.split_once(" AND ") {
106+
return Ok(Instruction::And(
107+
parse_variable(left)?,
108+
parse_variable(right)?,
109+
));
110+
}
111+
112+
if let Some((left, right)) = s.split_once(" OR ") {
113+
return Ok(Instruction::Or(
114+
parse_variable(left)?,
115+
parse_variable(right)?,
116+
));
117+
}
118+
119+
if let Some((left, right)) = s.split_once(" LSHIFT ") {
120+
return Ok(Instruction::LShift(
121+
parse_variable(left)?,
122+
right.parse().map_err(|_| ())?,
123+
));
124+
}
125+
126+
if let Some((left, right)) = s.split_once(" RSHIFT ") {
127+
return Ok(Instruction::RShift(
128+
parse_variable(left)?,
129+
right.parse().map_err(|_| ())?,
130+
));
131+
}
132+
133+
if let Some(not) = s.strip_prefix("NOT ") {
134+
return Ok(Instruction::Not(parse_variable(not)?));
135+
}
136+
137+
Ok(Instruction::Value(Value::Variable(s.to_string())))
138+
}
139+
}
140+
141+
#[derive(Debug, PartialEq, Clone)]
142+
enum Value {
143+
Numeric(u16),
144+
Variable(String),
145+
}
146+
15147
#[cfg(test)]
16148
mod tests {
17149
use super::*;
18150

151+
const EXAMPLE: &str = r#"123 -> x
152+
456 -> y
153+
y -> z
154+
x AND y -> d
155+
x OR y -> e
156+
x LSHIFT 2 -> f
157+
y RSHIFT 2 -> g
158+
NOT x -> h
159+
NOT y -> i"#;
160+
19161
#[test]
20162
fn part_one_example_test() {
21-
assert_eq!("0", Day07.part_one(""));
163+
assert_eq!("123", Day07.signal(EXAMPLE, "x"));
164+
assert_eq!("456", Day07.signal(EXAMPLE, "y"));
165+
assert_eq!("456", Day07.signal(EXAMPLE, "z"));
166+
assert_eq!("72", Day07.signal(EXAMPLE, "d"));
167+
assert_eq!("507", Day07.signal(EXAMPLE, "e"));
168+
assert_eq!("492", Day07.signal(EXAMPLE, "f"));
169+
assert_eq!("114", Day07.signal(EXAMPLE, "g"));
170+
assert_eq!("65412", Day07.signal(EXAMPLE, "h"));
171+
assert_eq!("65079", Day07.signal(EXAMPLE, "i"));
172+
}
173+
174+
#[test]
175+
fn instruction_parse() {
176+
assert_eq!(
177+
Ok(Instruction::Value(Value::Numeric(456))),
178+
Instruction::from_str("456")
179+
);
180+
181+
assert_eq!(
182+
Ok(Instruction::And(
183+
Value::Variable("x".to_string()),
184+
Value::Variable("y".to_string())
185+
)),
186+
Instruction::from_str("x AND y")
187+
);
188+
189+
assert_eq!(
190+
Ok(Instruction::And(
191+
Value::Variable("x".to_string()),
192+
Value::Numeric(2)
193+
)),
194+
Instruction::from_str("x AND 2")
195+
);
196+
197+
assert_eq!(
198+
Ok(Instruction::Or(
199+
Value::Variable("x".to_string()),
200+
Value::Variable("y".to_string())
201+
)),
202+
Instruction::from_str("x OR y")
203+
);
204+
205+
assert_eq!(
206+
Ok(Instruction::LShift(Value::Variable("x".to_string()), 2)),
207+
Instruction::from_str("x LSHIFT 2")
208+
);
209+
210+
assert_eq!(
211+
Ok(Instruction::RShift(Value::Variable("x".to_string()), 3)),
212+
Instruction::from_str("x RSHIFT 3")
213+
);
214+
215+
assert_eq!(
216+
Ok(Instruction::Not(Value::Variable("y".to_string()),)),
217+
Instruction::from_str("NOT y")
218+
);
22219
}
23220
}

0 commit comments

Comments
 (0)