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
#[derive(Clone, Debug, PartialEq)]
pub enum Operation<'a> {
Append(&'a str),
Delete(usize),
Print(usize),
Undo,
Invalid,
}
impl<'a> From<&'a str> for Operation<'a> {
fn from(input: &'a str) -> Self {
let input = input.trim_start();
if input.is_empty() {
return Operation::Invalid;
}
let mut chars = input.chars();
match chars.next().map(|c| (c, chars.as_str())) {
Some(('1', val)) => Operation::Append(remove_sep_space(val)),
Some((op @ '2', val)) | Some((op @ '3', val)) => parse_delete_or_print(op, remove_sep_space(val)),
Some(('4', _)) => Operation::Undo,
_ => {
Operation::Invalid
}
}
}
}
fn remove_sep_space(val: &str) -> &str {
let mut chars = val.chars();
if let Some((_, rest)) = chars.next().map(|c| (c, chars.as_str())) {
return rest;
} else {
return val;
}
}
fn parse_delete_or_print(op: char, value_to_parse: &str) -> Operation {
if let Ok(val) = value_to_parse.trim().parse::<usize>() {
return match op {
'2' => Operation::Delete(val),
'3' => Operation::Print(val),
_ => Operation::Invalid
};
} else {
return Operation::Invalid
}
}
pub fn parse(input: &str) -> Option<(usize, Vec<Operation>)>{
let lines = input.lines();
let num_ops = lines.clone().take(1).next().unwrap_or_default().parse();
if num_ops.is_err() {
return None
}
let ops = lines.skip(1).map(|line| { line.into() }).collect();
Some((num_ops.unwrap(), ops))
}
#[derive(Debug)]
pub enum UndoableOperation {
Append(usize),
Delete(String),
}