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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128use std::fs;
use regex::Regex;
#[derive(Debug)]
pub struct Stack {
crates: Vec<char>,
}
impl Stack {
pub fn new() -> Stack {
Stack { crates: vec![] }
}
pub fn push(&mut self, c: char) {
self.crates.push(c);
}
pub fn extend(&mut self, crates: Vec<char>) {
for c in crates {
self.crates.push(c);
}
}
pub fn pop(&mut self, quantity: usize) -> Vec<char> {
let mut popped = vec![];
for _ in 0..quantity {
popped.push(self.crates.pop().unwrap());
}
popped.reverse();
popped
}
/// For init purpose only
pub fn reverse(&mut self) {
self.crates.reverse();
}
pub fn last(&self) -> char {
match self.crates.last() {
Some(c) => *c,
None => ' '
}
}
}
/// Return the relevant indexes at which the letters will be in the input
/// Let's try without regex first
pub fn relevant_indexes(line_size: usize) -> Vec<usize> {
let mut indexes = vec![1];
let mut last = 1;
while indexes.len() != line_size {
let new = last + 4;
indexes.push(new as usize);
last = new;
}
indexes
}
pub fn message(stacks: &mut Vec<Stack>) -> String {
let mut str = String::from("");
for stack in stacks {
str.push(stack.last());
}
str
}
fn main() {
// read input
let contents = fs::read_to_string("input")
.expect("Should have been able to read the file");
// init
let lines = contents.split("\n").collect::<Vec<&str>>();
let mut line = String::from(lines[0]);
let line_size = line.chars().count();
let stack_number = (line_size + 1) / 4; // always an integer
// Now that we know the number of stacks, we can parse easily
let indexes = relevant_indexes(stack_number);
let mut stacks = vec![];
for _ in 0..stack_number {
stacks.push(Stack::new());
}
let mut line_nbr = 0;
while line != String::from("") {
for (i, index) in indexes.iter().enumerate() {
let c = line.chars().nth(*index).unwrap();
if c == '1' {
// We hit the useless line; skipping
break;
}
if c != ' ' {
stacks[i].push(c);
}
}
line_nbr += 1;
line = String::from(lines[line_nbr]);
}
for i in 0..stack_number {
stacks[i].reverse();
}
//
// now the crates are filled properly
for i in 0..stack_number {
println!("{:?}", stacks[i]);
}
// Fuck #L46
let re = Regex::new(r"move (\d+) from (\d) to (\d)").unwrap();
for line in &lines[line_nbr+1..] {
println!("{line}"); // DEBUG
for cap in re.captures_iter(line) {
println!("{:?}", cap);
let quantity: usize = (&cap[1]).to_string().parse().unwrap();
let from: usize = (&cap[2]).to_string().parse::<usize>().unwrap() - 1;
let to: usize = (&cap[3]).to_string().parse::<usize>().unwrap() - 1;
let moved = stacks[from].pop(quantity);
println!("{:?}", moved);
stacks[to].extend(moved);
for i in 0..stack_number {
println!("{:?}", stacks[i]);
}
}
}
println!("{}@{}@", stacks.len(), message(&mut stacks));
}