Skip to content

Commit 1e4bd60

Browse files
committed
Some rewrites, prefer using iters over .collect::<Vec<_>>
An unfortunate find is that .skip(1) is actually slower than .collect::<Vec<_>>[1..].to_vec(), poor performance of .skip() has already been noted here rust-lang/rust/issues/101814.
1 parent 1f23c11 commit 1e4bd60

File tree

6 files changed

+70
-63
lines changed

6 files changed

+70
-63
lines changed

src/01.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,8 @@ fn part1(lines: &Vec::<String>) -> i32 {
8585
nums.push(sum.parse::<i32>().unwrap());
8686
}
8787
}
88-
let sum = nums.iter().sum::<i32>();
8988

90-
return sum
89+
nums.iter().sum()
9190
}
9291

9392
// one, two, three, four, five, six, seven, eight, nine
@@ -138,11 +137,6 @@ fn part2(lines: &Vec::<String>) -> i32 {
138137
let sum = first + &last;
139138
sums.push(sum);
140139
}
141-
let mut nums = Vec::new();
142-
for sum in sums {
143-
nums.push(sum.parse::<i32>().unwrap());
144-
}
145-
let sum = nums.iter().sum::<i32>();
146140

147-
return sum
141+
sums.iter().map(|s| s.parse::<i32>().expect(format!("Incorrect integer value: {}", s).as_str())).sum()
148142
}

src/02.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,11 @@ fn part1(lines: &Vec::<String>) -> i32 {
6262
for i in 0..lines.len() {
6363
let line_id = i as i32 + 1;
6464
let mut line_record: HashMap<String, i32> = HashMap::new();
65-
let line_of_balls = lines[i].split(' ').map(String::from).collect::<Vec<String>>()[2..].join(" ");
65+
let line_of_balls = lines[i]
66+
.split(' ')
67+
.skip(2)
68+
.collect::<Vec<_>>()
69+
.join(" ");
6670
let replaced_line = line_of_balls.replace(";", &",");
6771
let arr_of_balls = replaced_line.split(",").map(|s| s.trim().split(' ')).map(|spl| spl.collect::<Vec<&str>>()).collect::<Vec<Vec<&str>>>();
6872
for arr in arr_of_balls {
@@ -75,9 +79,9 @@ fn part1(lines: &Vec::<String>) -> i32 {
7579
*line_record.get_mut(color).unwrap() = amount;
7680
}
7781
}
78-
if line_record.get("red").unwrap_or(&99) <= &12
79-
&& line_record.get("green").unwrap_or(&99) <= &13
80-
&& line_record.get("blue").unwrap_or(&99) <= &14 {
82+
if line_record.get("red").unwrap_or(&0) <= &12
83+
&& line_record.get("green").unwrap_or(&0) <= &13
84+
&& line_record.get("blue").unwrap_or(&0) <= &14 {
8185
//println!("id: {}, red: {}, green: {}, blue: {}", line_id, line_record.get("red").unwrap(), line_record.get("green").unwrap(), line_record.get("blue").unwrap());
8286
sum_of_ids += line_id;
8387
}
@@ -90,7 +94,11 @@ fn part2(lines: &Vec::<String>) -> i32 {
9094
for i in 0..lines.len() {
9195
//let line_id = i as i32 + 1;
9296
let mut line_record: HashMap<String, i32> = HashMap::new();
93-
let line_of_balls = lines[i].split(' ').map(String::from).collect::<Vec<String>>()[2..].join(" ");
97+
let line_of_balls = lines[i]
98+
.split(' ')
99+
.skip(2)
100+
.collect::<Vec<_>>()
101+
.join(" ");
94102
let replaced_line = line_of_balls.replace(";", &",");
95103
let arr_of_balls = replaced_line.split(",").map(|s| s.trim().split(' ')).map(|spl| spl.collect::<Vec<&str>>()).collect::<Vec<Vec<&str>>>();
96104
for arr in arr_of_balls {
@@ -103,7 +111,7 @@ fn part2(lines: &Vec::<String>) -> i32 {
103111
*line_record.get_mut(color).unwrap() = amount;
104112
}
105113
}
106-
let (red, blue, green) = (line_record.get("red").unwrap_or(&99), line_record.get("green").unwrap_or(&99), line_record.get("blue").unwrap_or(&99));
114+
let (red, blue, green) = (line_record.get("red").unwrap_or(&0), line_record.get("green").unwrap_or(&0), line_record.get("blue").unwrap_or(&0));
107115
//println!("id: {}, red: {}, green: {}, blue: {}, power: {}", line_id, red, blue, green, red * blue * green);
108116

109117
sum_of_powers += red * green * blue;

src/04.rs

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,21 @@ fn main() {
7474
fn part1(lines: &Vec<String>) -> i32 {
7575
let mut sum_of_points = 0;
7676
for line in lines {
77-
let nums_line = line.split(":").collect::<Vec<_>>()[1]
77+
let mut nums_line = line.split(":").nth(1).expect(format!("Improperly formatted line: {}", line).as_str())
7878
.trim()
7979
.split('|')
80-
.map(|s| s.trim())
81-
.collect::<Vec<_>>();
82-
let winning = nums_line[0]
80+
.map(|s| s.trim());
81+
let winning = nums_line.next().expect(format!("Improperly formatted line, missing winning numbers: {}", line).as_str())
8382
.trim()
8483
.split_ascii_whitespace()
8584
.map(|s| s.trim().parse::<i32>().expect(&format!("bad int error num={}", s)))
8685
.collect::<HashSet<_>>();
87-
let scratched = nums_line[1]
86+
let scratched = nums_line.next().expect(format!("Improperly formatted line, missing scratched numbers: {}", line).as_str())
8887
.trim()
8988
.split_ascii_whitespace()
9089
.map(|s| s.parse::<i32>().expect(&format!("bad int error num={}", s)))
9190
.collect::<HashSet<_>>();
92-
let found: HashSet<i32> = winning
93-
.intersection(&scratched)
94-
.copied()
95-
.collect();
91+
let found = &winning & &scratched;
9692
if len!(found) > 0 {
9793
let score = 2_i32.pow(len!(found) as u32 - 1);
9894
sum_of_points += score;
@@ -104,30 +100,27 @@ fn part1(lines: &Vec<String>) -> i32 {
104100
fn part2(lines: &Vec<String>) -> i32 {
105101
let mut total_count = 0;
106102
let lines_parsed = lines.iter().map(|line| {
107-
let split_line = line.split(":").collect::<Vec<_>>();
108-
let nums_line = split_line[1]
103+
let mut split_line = line.split(":");
104+
let game_id = split_line.next().expect(format!("Improperly formatted line, missing game_id: {}", line).as_str())
105+
.split_ascii_whitespace()
106+
.nth(1).unwrap()
107+
.parse::<usize>().expect(&format!("bad int error num={}", line));
108+
let mut nums_line = split_line.next().expect(format!("Improperly formatted line: {}", line).as_str())
109109
.trim()
110110
.split('|')
111-
.map(|s| s.trim())
112-
.collect::<Vec<_>>();
113-
let game_id = split_line[0].split_ascii_whitespace().collect::<Vec<_>>()[1]
114-
.parse::<usize>()
115-
.unwrap();
116-
let winning = nums_line[0]
111+
.map(|s| s.trim());
112+
let winning = nums_line.next().expect(format!("Improperly formatted line, missing winning numbers: {}", line).as_str())
117113
.trim()
118114
.split_ascii_whitespace()
119115
.map(|s| s.trim().parse::<i32>().expect(&format!("bad int error num={}", s)))
120116
.collect::<HashSet<_>>();
121-
let scratched = nums_line[1]
117+
let scratched = nums_line.next().expect(format!("Improperly formatted line, missing scratched numbers: {}", line).as_str())
122118
.trim()
123119
.replace(" ", " ")
124120
.split_ascii_whitespace()
125121
.map(|s| s.parse::<i32>().expect(&format!("bad int error num={}", s)))
126122
.collect::<HashSet<_>>();
127-
let found: HashSet<i32> = winning
128-
.intersection(&scratched)
129-
.copied()
130-
.collect();
123+
let found = &winning & &scratched;
131124
return (game_id - 1, len!(found));
132125
}).collect::<Vec<_>>();
133126

src/05.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ fn part2(lines: &Vec<String>) -> u64 {
222222
let mut num_of_iters: u64 = 0;
223223
return (seed_range
224224
.map(|seed| {
225-
let mut current_val = seed.clone();
225+
let mut current_val = seed;
226226
//print!("{current_val}");
227227
for mapset in &mappings {
228228
let mut found = false;

src/06.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,37 +60,43 @@ fn main() {
6060
}
6161

6262
fn part1(lines: &Vec::<String>) -> u128 {
63-
let mut power = 1;
63+
let power = 1;
6464
let mut counts = Vec::new();
6565

66-
let times = lines[0].split_ascii_whitespace().collect::<Vec<_>>()[1..].iter().map(|s| s.parse::<u128>().unwrap()).collect::<Vec<_>>();
67-
let distances = lines[1].split_ascii_whitespace().collect::<Vec<_>>()[1..].iter().map(|s| s.parse::<u128>().unwrap()).collect::<Vec<_>>();
66+
let times = lines[0].split_ascii_whitespace()
67+
.skip(1)
68+
.map(|s| s.parse::<u128>().unwrap());
69+
let distances = lines[1].split_ascii_whitespace()
70+
.skip(1)
71+
.map(|s| s.parse::<u128>().unwrap());
6872

69-
let zip = times.iter().zip(distances.iter());
73+
let zip = times.zip(distances);
7074

7175
for (time, distance) in zip {
72-
let mut vec = Vec::with_capacity(*time as usize);
76+
let mut vec = Vec::with_capacity(time as usize);
7377

74-
for delay in 1..*time {
75-
let val = delay * (*time - delay);
78+
for delay in 1..time {
79+
let val = delay * (time - delay);
7680
vec.push(val)
7781
}
7882

79-
vec = vec.iter().filter(|res| *res > distance).copied().collect::<Vec<_>>();
83+
vec = vec.iter().filter(|res| **res > distance).copied().collect::<Vec<_>>();
8084
counts.push(len!(vec) as u128);
8185
}
8286

83-
counts.iter().for_each(|count| {
84-
power *= count;
85-
});
86-
87-
return power;
87+
counts.iter().fold(power, |cur_power, count| {
88+
cur_power * count
89+
})
8890
}
8991

9092
fn part2(lines: &Vec::<String>) -> u128 {
9193
let mut newlines = lines.clone();
92-
newlines[0] = "Time: ".to_owned() + &newlines[0].split_ascii_whitespace().collect::<Vec<_>>()[1..].to_vec().join("");
93-
newlines[1] = "Distance: ".to_owned() + &newlines[1].split_ascii_whitespace().collect::<Vec<_>>()[1..].to_vec().join("");
94+
newlines[0] = "Time: ".to_owned() + &newlines[0].split_ascii_whitespace()
95+
.collect::<Vec<_>>()[1..].to_vec() // Somehow faster than using .skip(1) on the iter
96+
.join("");
97+
newlines[1] = "Distance: ".to_owned() + &newlines[1].split_ascii_whitespace()
98+
.collect::<Vec<_>>()[1..].to_vec()
99+
.join("");
94100
println!("{}", newlines[0]);
95101
println!("{}", newlines[1]);
96102
return part1(&newlines);

src/18.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ fn part2(lines: &Vec<String>) -> i64 {
226226
},
227227
"L" => {
228228
if grid_lines.contains_key(&y_pointer) {
229-
grid_lines.get_mut(&y_pointer).unwrap().push((x_pointer, x_pointer - count));
229+
grid_lines.get_mut(&y_pointer).unwrap().push((x_pointer - count, x_pointer));
230230
} else {
231-
grid_lines.insert(y_pointer, vec![((x_pointer, x_pointer - count))]);
231+
grid_lines.insert(y_pointer, vec![((x_pointer - count, x_pointer))]);
232232
}
233233
x_pointer -= count;
234234
},
@@ -242,35 +242,41 @@ fn part2(lines: &Vec<String>) -> i64 {
242242
}
243243

244244
let mut counter: i64 = 0;
245-
let mut line_iter = vec.iter();
245+
let line_iter = vec.iter();
246246

247247
// These correspond to each other
248248
let mut pointers: Vec<(i64, i64)> = Vec::new();
249249
let mut prev_lens: Vec<i64> = Vec::new();
250250
let mut prev_line_num = i64::MIN;
251251

252-
for (line_num, line) in line_iter {
252+
for (&line_num, ref line) in line_iter {
253253
if prev_line_num == i64::MIN {
254-
let mut cloned = (*line).clone();
254+
let mut cloned = (**line).clone();
255255
let mut lens: Vec<i64> = line.iter().map(|(_x1, _x2)| _x2 - _x1 + 1).collect();
256256
lens.iter().for_each(|&length| {counter += length});
257257
//debugln!("{cloned:?}\n{lens:?}");
258258
prev_lens.append(&mut lens);
259259
pointers.append(&mut cloned);
260-
prev_line_num = **line_num;
260+
prev_line_num = line_num;
261+
continue;
261262
}
262-
for ((x1, x2), lines_count) in pointers.iter().zip(prev_lens.iter()) {
263-
263+
for (&(x1, x2), &lines_count) in pointers.iter().zip(prev_lens.iter()) {
264+
264265
}
265-
for (x1, x2) in line.clone() {
266-
let found_matches = pointers.iter().filter(|l| (**l).0 == *x1 || (**l).1 == *x2).collect::<Vec<_>>();
266+
for (x1, x2) in (*line).clone() {
267+
let found_matches = pointers.iter().enumerate().filter(|(_, &l)| l.0 == x1 || l.1 == x2).collect::<Vec<_>>();
267268
match found_matches.len() {
268269
2 => todo!(),
269270
1 => todo!(),
270-
0 => todo!(),
271+
0 => {
272+
pointers.push((x1, x2));
273+
prev_lens.push(x2 - x1 + 1);
274+
counter += x2 - x1 + 1 //no need for abs, it's ordered properly
275+
},
271276
_ => unreachable!()
272277
}
273278
}
279+
prev_line_num = line_num
274280
}
275281

276282
return counter;

0 commit comments

Comments
 (0)