Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What I learned by solving 50 Advent of Code challenges in Rust - RustNation UK 2023

What I learned by solving 50 Advent of Code challenges in Rust - RustNation UK 2023

In 2020 I started to be a bit more serious about learning Rust. After having read a few books and having done some coding challenges, I decided to start live-streaming my attempts to solve Advent of Code challenges using Rust. Fast forward to 2022 I completed 50 challenges and learned a lot about how to use Rust to solve specific programming challenges. In this talk, I’ll be sharing some common tips and tricks that I discovered while live-coding also thanks to the beautiful Rust community that gave me tons of suggestions! Some topics I’ll be covering in this talk: parsing input, data structures, error handling, iterators, performance, allocating and manipulating 2d matrices, etc.

Luciano Mammino

February 17, 2023
Tweet

More Decks by Luciano Mammino

Other Decks in Technology

Transcript

  1. 👋 I'm Luciano ( 🍕🍝) Senior Architect @ fourTheorem nodejsdp.link

    📔 Co-Author of Node.js Design Patterns 👉 Let's connect! (blog) (twitter) (twitch) (github) loige.co @loige loige lmammino Grab the slides 4
  2. Always re-imagining We are a pioneering technology consultancy focused on

    AWS and serverless | | Accelerated Serverless AI as a Service Platform Modernisation loige ✉ Reach out to us at 😇 We are always looking for talent: [email protected] fth.link/careers 5
  3. Why am I learning Rust 🦀 Full-stack Web Developer turning

    Cloud Architect loige Experience with dynamic scripting languages (JavaScript, Python, Php) Looked into Go for performance-sensitive applications Rust seemed like the natural next step ... and it's fun! 7
  4. How it is going loige error[E0382]: borrow of moved value:

    `v` --> src/main.rs:6:19 | 4 | let v = vec![2, 3, 5, 7, 11, 13, 17]; | - move occurs because `v` has type `Vec<i32>`, whic 5 | hold_my_vec(v); | - value moved here 6 | let element = v.get(3); | ^^^^^^^^ value borrowed here after move | 1 2 3 4 5 6 7 8 9 10 #[stable(feature = "future_poll_fn", since = "1.64.0")] impl<T, F> Future for PollFn<F> where F: FnMut(&mut Context<'_>) -> Poll<T>, { type Output = T; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> P // SAFETY: We are not moving out of the pinned field (unsafe { &mut self.get_unchecked_mut().f })(cx) } } 1 2 3 4 5 6 7 8 9 10 11 12 How it started 8
  5. How it started -> How it is going loige 2019:

    Ported some JS code to Rust (resulted in ) jwtinfo 2020-2022: Live streamed solving Advent of Code in Rust + some other small side-projects and coding challenges Nothing "production ready" as of today 🤷 Excited about Serverless Rust on AWS 9
  6. 🔥 Hot take If you are struggling to learn Rust

    (or anything else, really)... Find a learning buddy! loige 14
  7. loige Valve NV has flow rate=5; tunnels lead to valves

    ZV, CG, YB, HX, OY Valve NU has flow rate=6; tunnels lead to valves DA, MA, OA, DK Valve VU has flow rate=0; tunnels lead to valves PS, FX Valve JW has flow rate=0; tunnels lead to valves AA, MD Valve RI has flow rate=0; tunnels lead to valves OY, DG Valve DG has flow rate=9; tunnels lead to valves TG, RI, DF, EV, KW Valve PH has flow rate=7; tunnels lead to valves KW, OW, LT, LZ Valve KZ has flow rate=12; tunnels lead to valves ET, QV, CK, MS Valve IX has flow rate=0; tunnels lead to valves TS, DO Valve MS has flow rate=0; tunnels lead to valves LZ, KZ Valve IL has flow rate=0; tunnels lead to valves DO, ET Valve EJ has flow rate=20; tunnels lead to valves AV, JY Valve DK has flow rate=0; tunnels lead to valves NU, CG Valve YB has flow rate=0; tunnels lead to valves NV, PS Valve OA has flow rate=0; tunnels lead to valves YA, NU Valve DA has flow rate=0; tunnels lead to valves NU, RG Valve KO has flow rate=0; tunnels lead to valves AA, TG Valve RG has flow rate=4; tunnels lead to valves DF, DA, ZV, MD, LB Valve MA has flow rate=0; tunnels lead to valves AA, NU Valve OW has flow rate=0; tunnels lead to valves DO, PH Valve KW has flow rate=0; tunnels lead to valves DG, PH Valve DO has flow rate=14; tunnels lead to valves IX, IL, CZ, OW Valve DF has flow rate=0; tunnels lead to valves RG, DG Valve TG has flow rate=0; tunnels lead to valves DG, KO Valve LB has flow rate=0; tunnels lead to valves RG, FX Valve HX has flow rate=0; tunnels lead to valves AA, NV Valve GB has flow rate=0; tunnels lead to valves AV, XK Valve CG has flow rate=0; tunnels lead to valves DK, NV Valve LT has flow rate=0; tunnels lead to valves AO, PH Valve FX has flow rate=23; tunnels lead to valves LB, HY, VU Valve ET has flow rate=0; tunnels lead to valves IL, KZ Valve CK has flow rate=0; tunnels lead to valves UX, KZ Valve LZ has flow rate=0; tunnels lead to valves PH, MS Valve YA has flow rate=17; tunnels lead to valves JY, OA Valve TS has flow rate=0; tunnels lead to valves NO, IX Valve NO has flow rate=8; tunnel leads to valve TS Valve XK has flow rate=24; tunnel leads to valve GB 1. Read & understand the puzzle 2. Parse the input 3. Write some code 4. Find solution 5. Submit your solution (unlocks part 2) 6. Repeat from point 1 for part 2 18
  8. 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000

    y2022 - Day 1: Calorie Counting loige sum sum sum sum sum max 6000 4000 11000 24000 20 10000 24000
  9. fn classic(input: &str) -> u64 { let mut max =

    0; let batches = input.split("\n\n"); for batch in batches { let lines = batch.lines(); let mut total = 0; for line in lines { let value = line.parse::<u64>().unwrap(); total += value; } if total > max { max = total; } } max } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 let mut max = 0; max fn classic(input: &str) -> u64 { 1 2 let batches = input.split("\n\n"); 3 for batch in batches { 4 let lines = batch.lines(); 5 let mut total = 0; 6 for line in lines { 7 let value = line.parse::<u64>().unwrap(); 8 total += value; 9 } 10 if total > max { 11 max = total; 12 } 13 } 14 15 } 16 let batches = input.split("\n\n"); fn classic(input: &str) -> u64 { 1 let mut max = 0; 2 3 for batch in batches { 4 let lines = batch.lines(); 5 let mut total = 0; 6 for line in lines { 7 let value = line.parse::<u64>().unwrap(); 8 total += value; 9 } 10 if total > max { 11 max = total; 12 } 13 } 14 max 15 } 16 for batch in batches { } fn classic(input: &str) -> u64 { 1 let mut max = 0; 2 let batches = input.split("\n\n"); 3 4 let lines = batch.lines(); 5 let mut total = 0; 6 for line in lines { 7 let value = line.parse::<u64>().unwrap(); 8 total += value; 9 } 10 if total > max { 11 max = total; 12 } 13 14 max 15 } 16 let lines = batch.lines(); let mut total = 0; fn classic(input: &str) -> u64 { 1 let mut max = 0; 2 let batches = input.split("\n\n"); 3 for batch in batches { 4 5 6 for line in lines { 7 let value = line.parse::<u64>().unwrap(); 8 total += value; 9 } 10 if total > max { 11 max = total; 12 } 13 } 14 max 15 } 16 for line in lines { } fn classic(input: &str) -> u64 { 1 let mut max = 0; 2 let batches = input.split("\n\n"); 3 for batch in batches { 4 let lines = batch.lines(); 5 let mut total = 0; 6 7 let value = line.parse::<u64>().unwrap(); 8 total += value; 9 10 if total > max { 11 max = total; 12 } 13 } 14 max 15 } 16 let value = line.parse::<u64>().unwrap(); fn classic(input: &str) -> u64 { 1 let mut max = 0; 2 let batches = input.split("\n\n"); 3 for batch in batches { 4 let lines = batch.lines(); 5 let mut total = 0; 6 for line in lines { 7 8 total += value; 9 } 10 if total > max { 11 max = total; 12 } 13 } 14 max 15 } 16 total += value; fn classic(input: &str) -> u64 { 1 let mut max = 0; 2 let batches = input.split("\n\n"); 3 for batch in batches { 4 let lines = batch.lines(); 5 let mut total = 0; 6 for line in lines { 7 let value = line.parse::<u64>().unwrap(); 8 9 } 10 if total > max { 11 max = total; 12 } 13 } 14 max 15 } 16 if total > max { max = total; } fn classic(input: &str) -> u64 { 1 let mut max = 0; 2 let batches = input.split("\n\n"); 3 for batch in batches { 4 let lines = batch.lines(); 5 let mut total = 0; 6 for line in lines { 7 let value = line.parse::<u64>().unwrap(); 8 total += value; 9 } 10 11 12 13 } 14 max 15 } 16 fn classic(input: &str) -> u64 { let mut max = 0; let batches = input.split("\n\n"); for batch in batches { let lines = batch.lines(); let mut total = 0; for line in lines { let value = line.parse::<u64>().unwrap(); total += value; } if total > max { max = total; } } max } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Classic noob approach loige 21
  10. fn combinators(input: &str) -> u64 { input .split("\n\n") .map(|batch| {

    batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() }) .max() .unwrap() } 1 2 3 4 5 6 7 8 9 10 11 12 input .split("\n\n") fn combinators(input: &str) -> u64 { 1 2 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 .max() 10 .unwrap() 11 } 12 .map(|batch| { }) fn combinators(input: &str) -> u64 { 1 input 2 .split("\n\n") 3 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 9 .max() 10 .unwrap() 11 } 12 batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() fn combinators(input: &str) -> u64 { 1 input 2 .split("\n\n") 3 .map(|batch| { 4 5 6 7 8 }) 9 .max() 10 .unwrap() 11 } 12 .max() .unwrap() fn combinators(input: &str) -> u64 { 1 input 2 .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 10 11 } 12 fn combinators(input: &str) -> u64 { input .split("\n\n") .map(|batch| { batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() }) .max() .unwrap() } 1 2 3 4 5 6 7 8 9 10 11 12 Combinators approach loige 22
  11. Yeah, but I am sure that iterator combinators are not

    always flexible enough, right? 🤔 loige 25
  12. 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000

    y2022 Day 1: Calorie Counting (part 2) loige sum sum sum sum sum top 3 6000 4000 11000 24000 26 10000 24000 11000 10000 sum 45000
  13. fn combinators(input: &str) -> u64 { input .split("\n\n") .map(|batch| {

    batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() }) .sort_descending() .take(3) .sum() } 1 2 3 4 5 6 7 8 9 10 11 12 13 .sort_descending() fn combinators(input: &str) -> u64 { 1 input 2 .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 10 .take(3) 11 .sum() 12 } 13 .take(3) fn combinators(input: &str) -> u64 { 1 input 2 .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 .sort_descending() 10 11 .sum() 12 } 13 .sum() fn combinators(input: &str) -> u64 { 1 input 2 .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 .sort_descending() 10 .take(3) 11 12 } 13 fn combinators(input: &str) -> u64 { input .split("\n\n") .map(|batch| { batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() }) .sort_descending() .take(3) .sum() } 1 2 3 4 5 6 7 8 9 10 11 12 13 loige 27
  14. .sort_descending() fn combinators(input: &str) -> u64 { 1 input 2

    .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 10 .take(3) 11 .sum() 12 } 13 loige 🤷 28
  15. use itertools::Itertools; fn combinators(input: &str) -> u64 { input .split("\n\n")

    .map(|batch| { batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() }) .sorted() .rev() .take(3) .sum() } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 use itertools::Itertools; 1 2 fn combinators(input: &str) -> u64 { 3 input 4 .split("\n\n") 5 .map(|batch| { 6 batch 7 .lines() 8 .map(|line| line.parse::<u64>().unwrap()) 9 .sum::<u64>() 10 }) 11 .sorted() 12 .rev() 13 .take(3) 14 .sum() 15 } 16 .sorted() .rev() use itertools::Itertools; 1 2 fn combinators(input: &str) -> u64 { 3 input 4 .split("\n\n") 5 .map(|batch| { 6 batch 7 .lines() 8 .map(|line| line.parse::<u64>().unwrap()) 9 .sum::<u64>() 10 }) 11 12 13 .take(3) 14 .sum() 15 } 16 use itertools::Itertools; fn combinators(input: &str) -> u64 { input .split("\n\n") .map(|batch| { batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() }) .sorted() .rev() .take(3) .sum() } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 loige 30
  16. .sorted() use itertools::Itertools; 1 2 fn combinators(input: &str) -> u64

    { 3 input 4 .split("\n\n") 5 .map(|batch| { 6 batch 7 .lines() 8 .map(|line| line.parse::<u64>().unwrap()) 9 .sum::<u64>() 10 }) 11 12 .rev() 13 .take(3) 14 .sum() 15 } 16 loige 🤩 added by itertools 31
  17. 💡IDEA: Consume the iterator and, as you go, keep the

    current top 3 in a vec... loige 33
  18. 💡IDEA: Consume the iterator and, as you go, keep the

    current top 3 in a vec... loige 100 22 44 1 120 top3 = [] 34
  19. loige 100 22 44 1 120 top3 = [] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 35
  20. loige 100 22 44 1 120 top3 = [100] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 36
  21. loige 100 22 44 1 120 top3 = [100] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 37
  22. loige 100 22 44 1 120 top3 = [100,22] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 38
  23. loige 100 22 44 1 120 top3 = [100,22] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 39
  24. loige 100 22 44 1 120 top3 = [100,44,22] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 40
  25. loige 100 22 44 1 120 top3 = [100,44,22] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 41
  26. loige 100 22 44 1 120 top3 = [100,44,22] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 42
  27. loige 100 22 44 1 120 top3 = [120,100,44] 👉

    💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 43
  28. loige 100 22 44 1 120 top3 = [120,100,44] This

    is O(n*m) vs sorting O(n*logn) ⚡ * indulge me and let's ignore we could have used radix sort here... ** O(n) for very small m, top100 would be expensive! 💡IDEA: Consume the iterator and, as you go, keep the current top 3 in a vec... 44
  29. trait TopN { fn top_n(self, n: usize) -> Vec<u64>; }

    1 2 3 loige That's what we want for now, but can it be more "generic"? 🧐 45
  30. trait TopN<T> { fn top_n(self, n: usize) -> Vec<T>; }

    1 2 3 loige Makes the trait "generic" over any type T T is used as part of the return type of the function 46
  31. That's a cool trait indeed... but I am sure we

    cannot implement it for "all" iterators, right?! 🤷 loige 47
  32. impl<T, U: Iterator<Item = T>> TopN<T> for U { fn

    top_n(self, n: usize) -> Vec<T> { } } 1 2 // TODO: 3 unimplemented!(); 4 5 6 loige All types U that implements the Iterator trait producing Items of type T We implement TopN<T> for all types U (iterators producing T)! 49
  33. impl<T, U: Iterator<Item = T>> TopN<T> for U { fn

    top_n(self, n: usize) -> Vec<T> { let mut top = Vec::with_capacity(n); for value in self { for i in 0..n { if let Some(top_value) = top.get(i) { if value > *top_value { top[i..].rotate_right(1); top[i] = value; break; } } else { top.push(value); break; } } } top } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 let mut top = Vec::with_capacity(n); impl<T, U: Iterator<Item = T>> TopN<T> for U { 1 fn top_n(self, n: usize) -> Vec<T> { 2 3 for value in self { 4 for i in 0..n { 5 if let Some(top_value) = top.get(i) { 6 if value > *top_value { 7 top[i..].rotate_right(1); 8 top[i] = value; 9 break; 10 } 11 } else { 12 top.push(value); 13 break; 14 } 15 } 16 } 17 top 18 } 19 } 20 if value > *top_value { impl<T, U: Iterator<Item = T>> TopN<T> for U { 1 fn top_n(self, n: usize) -> Vec<T> { 2 let mut top = Vec::with_capacity(n); 3 for value in self { 4 for i in 0..n { 5 if let Some(top_value) = top.get(i) { 6 7 top[i..].rotate_right(1); 8 top[i] = value; 9 break; 10 } 11 } else { 12 top.push(value); 13 break; 14 } 15 } 16 } 17 top 18 } 19 } 20 loige 50
  34. if value > *top_value { impl<T, U: Iterator<Item = T>>

    TopN<T> for U { 1 fn top_n(self, n: usize) -> Vec<T> { 2 let mut top = Vec::with_capacity(n); 3 for value in self { 4 for i in 0..n { 5 if let Some(top_value) = top.get(i) { 6 7 top[i..].rotate_right(1); 8 top[i] = value; 9 break; 10 } 11 } else { 12 top.push(value); 13 break; 14 } 15 } 16 } 17 top 18 } 19 } 20 loige 51
  35. impl<T: PartialOrd, U: Iterator<Item = T>> TopN<T> for U {

    1 fn top_n(self, n: usize) -> Vec<T> { 2 let mut top = Vec::with_capacity(n); 3 for value in self { 4 for i in 0..n { 5 if let Some(top_value) = top.get(i) { 6 if value > *top_value { 7 top[i..].rotate_right(1); 8 top[i] = value; 9 break; 10 } 11 } else { 12 top.push(value); 13 break; 14 } 15 } 16 } 17 top 18 } 19 } 20 loige Restricting T only to types that can be compared! 👍 52
  36. fn combinators_no_sort(input: &str) -> u64 { input .split("\n\n") .map(|batch| {

    batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() }) .top_n(3) .iter() .sum() } 1 2 3 4 5 6 7 8 9 10 11 12 13 .top_n(3) .iter() .sum() fn combinators_no_sort(input: &str) -> u64 { 1 input 2 .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 10 11 12 } 13 loige 53
  37. .top_n(3) fn combinators_no_sort(input: &str) -> u64 { 1 input 2

    .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 10 .iter() 11 .sum() 12 } 13 loige 😍 OMG, we added this! 54
  38. OK, but you used a Vec there... I heard rustaceans

    don't like unnecessary allocations, right?! 🤷 loige 55
  39. trait Top<T> { fn top(self, n: usize) -> Vec<T>; }

    impl<T: PartialOrd, U: Iterator<Item = T>> Top<T> for U { fn top(self, n: usize) -> Vec<T> { let mut top = Vec::with_capacity(n); // ... top } } 1 2 3 4 5 6 7 8 9 10 11 loige We want to replace these with an array... 56
  40. trait Top<T> { fn top(self, n: usize) -> [T;n]; }

    impl<T: PartialOrd, U: Iterator<Item = T>> Top<T> for U { fn top(self, n: usize) -> [T;n] { let mut top = [T;n]; // ... top } } 1 2 3 4 5 6 7 8 9 10 11 fn top(self, n: usize) -> [T;n]; trait Top<T> { 1 2 } 3 4 impl<T: PartialOrd, U: Iterator<Item = T>> Top<T> for U { 5 fn top(self, n: usize) -> [T;n] { 6 let mut top = [T;n]; 7 // ... 8 top 9 } 10 } 11 loige 57
  41. fn top<const N: usize>(self) -> [T; N]; trait Top<T> {

    1 2 } 3 4 impl<T: PartialOrd, U: Iterator<Item = T>> Top<T> for U { 5 fn top<const N: usize>(self) -> [T; N] { 6 let mut top = [T;N]; 7 // ... 8 top 9 } 10 } 11 loige const generics syntax 58
  42. let mut top = [T;N]; trait Top<T> { 1 fn

    top<const N: usize>(self) -> [T; N]; 2 } 3 4 impl<T: PartialOrd, U: Iterator<Item = T>> Top<T> for U { 5 fn top<const N: usize>(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige 59
  43. let mut top = [Default::default(); N]; trait Top<T> { 1

    fn top<const N: usize>(self) -> [T; N]; 2 } 3 4 impl<T: PartialOrd, U: Iterator<Item = T>> Top<T> for U { 5 fn top<const N: usize>(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige 60
  44. impl<T: Default + Copy + PartialOrd, U: Iterator<Item = T>>

    Top<T> for let mut top = [Default::default(); N]; trait Top<T> { 1 fn top<const N: usize>(self) -> [T; N]; 2 } 3 4 5 fn top<const N: usize>(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige 61
  45. impl<T: Default + Copy + PartialOrd, U: Iterator<Item = T>>

    Top<T> for let mut top = [Default::default(); N]; trait Top<T> { 1 fn top<const N: usize>(self) -> [T; N]; 2 } 3 4 5 fn top<const N: usize>(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige Do we really need this? 62
  46. impl<T: Default + PartialOrd, U: Iterator<Item = T>> Top<T> for

    U { let mut top = core::array::from_fn(|_| Default::default()); trait Top<T> { 1 fn top<const N: usize>(self) -> [T; N]; 2 } 3 4 5 fn top<const N: usize>(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige Allows us to avoid Copy 63
  47. impl<T: Default + PartialOrd, U: Iterator<Item = T>> Top<T> for

    U { let mut top = core::array::from_fn(|_| Default::default()); trait Top<T> { 1 fn top<const N: usize>(self) -> [T; N]; 2 } 3 4 5 fn top<const N: usize>(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige Note: This works for now, but it's not a perfect solution 😥 (e.g. what if there are fewer than N items?) 64
  48. fn combinators_no_sort_const(input: &str) -> u64 { input .split("\n\n") .map(|batch| {

    batch .lines() .map(|line| line.parse::<u64>().unwrap()) .sum::<u64>() }) .top::<3>() .iter() .sum() } 1 2 3 4 5 6 7 8 9 10 11 12 13 .top::<3>() fn combinators_no_sort_const(input: &str) -> u64 { 1 input 2 .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 10 .iter() 11 .sum() 12 } 13 loige 65
  49. .top::<3>() fn combinators_no_sort_const(input: &str) -> u64 { 1 input 2

    .split("\n\n") 3 .map(|batch| { 4 batch 5 .lines() 6 .map(|line| line.parse::<u64>().unwrap()) 7 .sum::<u64>() 8 }) 9 10 .iter() 11 .sum() 12 } 13 loige Slightly different syntax 🐟 Phew... we did it! 😮 💨 66
  50. Which one do you think is faster? 🧐 loige Itertools

    no_sort_vec no_sort_array 1. 2. 3. 67
  51. Which one do you think is faster? 🧐 loige Itertools

    no_sort_vec no_sort_array 1. 2. 3. 37.517 µs 33.284 µs 32.957 µs BTW, is awesome! cargo bench ⭐ 68
  52. struct Point<const D: usize>([i32; D]); fn make_2d_point(x: i32, y: i32)

    -> Point<2> { Point([x, y]) } fn make_3d_point(x: i32, y: i32, z: i32) -> Point<3> { Point([x, y, z]) } fn make_4d_point(x: i32, y: i32, z: i32, w: i32) -> Point<4> { Point([x, y, z, w]) } 1 2 3 4 5 6 7 8 9 10 11 12 13 struct Point<const D: usize>([i32; D]); 1 2 fn make_2d_point(x: i32, y: i32) -> Point<2> { 3 Point([x, y]) 4 } 5 6 fn make_3d_point(x: i32, y: i32, z: i32) -> Point<3> { 7 Point([x, y, z]) 8 } 9 10 fn make_4d_point(x: i32, y: i32, z: i32, w: i32) -> Point<4> { 11 Point([x, y, z, w]) 12 } 13 struct Point<const D: usize>([i32; D]); fn make_2d_point(x: i32, y: i32) -> Point<2> { Point([x, y]) } 1 2 3 4 5 6 fn make_3d_point(x: i32, y: i32, z: i32) -> Point<3> { 7 Point([x, y, z]) 8 } 9 10 fn make_4d_point(x: i32, y: i32, z: i32, w: i32) -> Point<4> { 11 Point([x, y, z, w]) 12 } 13 struct Point<const D: usize>([i32; D]); fn make_3d_point(x: i32, y: i32, z: i32) -> Point<3> { Point([x, y, z]) } 1 2 fn make_2d_point(x: i32, y: i32) -> Point<2> { 3 Point([x, y]) 4 } 5 6 7 8 9 10 fn make_4d_point(x: i32, y: i32, z: i32, w: i32) -> Point<4> { 11 Point([x, y, z, w]) 12 } 13 struct Point<const D: usize>([i32; D]); fn make_4d_point(x: i32, y: i32, z: i32, w: i32) -> Point<4> { Point([x, y, z, w]) } 1 2 fn make_2d_point(x: i32, y: i32) -> Point<2> { 3 Point([x, y]) 4 } 5 6 fn make_3d_point(x: i32, y: i32, z: i32) -> Point<3> { 7 Point([x, y, z]) 8 } 9 10 11 12 13 struct Point<const D: usize>([i32; D]); fn make_2d_point(x: i32, y: i32) -> Point<2> { Point([x, y]) } fn make_3d_point(x: i32, y: i32, z: i32) -> Point<3> { Point([x, y, z]) } fn make_4d_point(x: i32, y: i32, z: i32, w: i32) -> Point<4> { Point([x, y, z, w]) } 1 2 3 4 5 6 7 8 9 10 11 12 13 y2020 - Day 17: Conway Cubes loige 70
  53. let p5d = Point([1, 2, 3, 4, 5]); fn some_func()

    { 1 // ... 2 3 // ... 4 } 5 y2020 - Day 17: Conway Cubes loige No need to specify the type, Rust will infer Point<5> based on the length of the passed array! 71
  54. v...>>.vv> .vv>>.vv.. >>.>v>...v >>v>>.>.v. v>v.vv.v.. >.>>..v... .vv..>.>v. v.v..>>v.v ....v..v.> y2021

    - Day 25: Sea Cucumber loige Sometimes you have to handle grids of variable sizes. README example (10x9) 72
  55. .v.v.v>...>vv>v>>>.v>..v>.v.>.>v>.v.v.>>v...>.>....>.>vv>>>.....>>...v.>>v..>..vvv.>v...vv...>..>....>.>.>.>vvv....>..vv>v....>v...>>....v. >.v>..v.>>vv.>>v...v.>.>..v.>.>.>vvv..>>>.>...>v>.>>v....>>>>...>v.v>.v>....>>>v.>>>....vv.....vvv.v.v..>.>..v>>.>.v>.>v>.vvvv.v..v>>..>>vv .vv>>...v>..v..v>v.>vvv.v.v>>.....v>>.......>...v>.v>.v.vv.v.>v>v.v......>>......>.v...v........v.v........>.v.vv.>>.v.>>.>.>...v....v>>>.. .>.>v.>vv.v...v.>>v>.>v..vv>..v.v.>...v....>vvvvvv>>>v..vv.v.v>>.>>.>>v>v>>..>.v...v.v.>v..>...v.>.>>.v...v>..v...vv.>v.....vvv.v>.v>..>>v. ..>.....v.>>..>>.v>v.>.>>.>..vv.v>>.>..>.>..v>>...>.>>.vv>>>..>>>>.v.>....>>.>..v>>vv>.>>v>vvvv>vv..v.v.>.v>..v>.vvv>>.v.......>>.>...>>.>. v...>..>..v>.vv.>>.>...>>....v.......v>...v.vvvvv>..v...>.v.>.>>v>v.>....v>...>...v.>.vv>......vv>.v>vv>>....v>.v>.>..>v.v..>>>.>>>..v..>vv v>v>.v>..v..v.>..>...>v.>..>.>vvvv...v.v>v....>.>v.vvvv....>...v.v..vvvvvv..v.v..v>v....>v....>v.>>.v>.>v..>...v.vv...>v>>..>.>.....v.v..v. .......v.....v>v.vv.>.v>.>>.>v.....>>..v.v.v>v>.....v...>v.vv>>.vv>>>>.>>.v.>v>..v.v..>v.vv....>>.vv.>v...>>v....v.v.>.vvvv.v....>v>>>>v.>. v>.v>..v...vv.>vv.v...v.v>.>........>.vv>>..........v...>vv....>.>v>v..>..>>>v.>>..v.>.>...v.v.>..v>>>..>v.....v.>>>>...v>>v...vv>..>>.v.>> .v>>>>>>v.>.>...>.>>.>.>>v>.........v..>.v>>>v>.....>...>>.>.v..>.vvv.>..v.v..>.>..>v>v.>v......>>...>>v.vv.....>.>...>.....>v.v..>>v.vvvv.

    v......>.......>>..>.v.>..v..>>v..>>......v>v.vvv.>...>>>...v..v>vv.....v.v>v>>v..v.v..v.......v.>v>.v.v..>.>..>v.v>>>v..v.>.>.>>v.>..v.v>. >.v..>>....>.v.>...>>>..>.v..v>v..>>>.v..v....vv>vv.v.v..v...>>..>......>>..v.....v.v>>.v....v>>....>..>v.vv.>.>..v...v>>.>.>v.v.vv>.v..v.> ..v...>...v..v.v...>...>.v..>...v...vv>..v....v>>>v.v..v.v>v..>v..v..v>>vv.v>..v..v...>.......>..>.>v>v..>...>v.....v..>v>v...v>..>.>...vvv .vv>.>.v...>>...v.>.>v.v.>>v..v.>v.>>vv.v>.>..>....v.>v>vv>..v>v>v.>>v>v.>...v>vvv..>>.v.>v.>vv.>..v>...>.v..>.>>>v>>...v>.>>v..v....v>v..v ..>.>>>...>........>.vvv>>.>v..v.>v..v..>v.>>.>.v..>.v...v>>.>v..vv...v.v>.vvv...vv>vv>v>.>vv>.>v.vv..v.v...v.>>..v...v>...v..vv..v..>.>>>> ..>.>.>v.v.>.....>vv.vvv>.>..v>>>v.>vv.>.v.>.....v>>.....>v..vvv....v.>.v>.v.vv>v.>vv.v..>v>>...v>v....v>>v>....v..>vvvv>..>v>.v..v.....>.. .vv>.....v>.>>>.>>v>>>v>>>v>.v>>.>v..>>v.vvv...>vv.v.v.v.....>>vv..v.>>>>v.>....v>v.>..>..vv>>>....vv.vvvvv>v....v...>.>.vv...v...>vv...>.. >...v.vv.vv.vvv..>v.>.......v...v.>v.>..>.v>..v...>v..>..>v.v..>.v>.>>.v>.>v...v>>.>v.v.v.v>.>..v.>vv.v>>>.>vv.vvv.>vv>>v>..v>>.vvv>v..v.v> >v.>...>v.vv..vv>..v.v..>..v.>v>>>..vv...>.>.v.v...>>.>v.vv..>.v.>>.>.>.v>..>.>..v>..v>>.v.v.v>.>...v.v.vv.>>>.v>...v.v>..>>..v.v>vv>vv>>vv vv.vv>....>..>...>>..v.v..v..v....v.>.vvv>>.v.v>.>.vv.>v......>vv>>.>>.....>>....>..v.v..v.v...>>v.>>>v.....v.>......v>v>v>>.v.vv...>.v.... .>v>....vv.v>>...>>....>>>.>.v>...vv.v.>vv>.....v>v.v....v..v.>v>.....>...>v>>....v.vv.v>>.>..v>.v.v...v..>..>>v.v>....v.>....v>......>v... ..vvvv>.>.>.v.>.vv....>>>v..>..v..v>vvv.>v.>>.>v.>.vv>vv.>......v...vv>v..v.v.vv>v.v..vvv>v..>>...>..>.>....>>v>....v.>vvv>>..>>>..v..v.>.. >.....>>..v>.vv.v>..>..v.>vv>>vv>.v>v..vv......>....>.....>.>v.vv.vvv.v..>.vv..>>...>vvvv>..>..>.>>.>v.vv>...>>vvvv.>.v.v...>...>v>..>v.... .v.>v..>vv.>v...>vv.v..vv>.>>.......>v>.vv..v.vv>v..>.>vv.v>>>.>>v>.>...v...vv.>>>v...>>..v>v>v.v.v>..>.v....>.v.v.>vvv.v.vv.>.v..vv.>>v>>. ....v...vvv>>>.>>.>v>...>.>v.v.>.vv>...v...>>v.v.>.v>..>...vvv....v..vv>vv>>>..>.>.>v....>..v.vv.v..v...>>>v..v.>.....v>>v>vvvv.>.>.v.>vv.. .>.>v..v>.v.v.v>v.>.vv...vv.>.>v>....v>>v..>....>>>.v>v.v>>..>.>vv..>.>..>.>>.........>>>>..>...vvv>.>.v.>v.v>...v.>vv..>.>v.>>vv.>>>v>.vvv >..>>..>.>>>vvv.>....>>v.>..v>v>v....vv.>.>>>v..v..v>.v....v>>...>>v...vvvv>>>>.>.....v>v.v.v..>v.v..>.v.>v>>....>>>v>.v>v.>.v...>>>.>vv.>> ...>>..>..>.>v.v..vv>.>.>vv.v>>.>....>.v>..>.v>>.....v.v.v.v..>...>>v.>.v.v.>>.>v....>..v..v>>..>>.>.v..>>..>vv..vv>v.v.v..v.vv.vv>....vv.. .v.v>..>.>.v..v>>....v>....>v>>>....>......v..v.......>vvvv.vvv.v..>.>..>.>>v.v..>...>>vv>.v..v.v..>vv>..>>.>v.>.v...vvv>>..>.vv..v.>v.v>v> v>.>.>.v>>v.>>v>.>.vv>.>>...>..>>>.v....>>>v>.v>v.>.v.>..>vvv>.v.>>....>v....v.vvv>..>.>.vv>>..>>v...vv.>.>>.v..v>.v.>.v..>.v>.v....v...>.> >vvv>.v>..>>..>.vv>>>...>>v.>v..>v....v>vv.>..>.v.>....vv....v....>....vv.v...vv>>>.>..>>>.v....>>vv.vv>vv>>.v...>>>v.v...v.vv..v>.vv..>v>. v.>...>>..>>v>..v.vvvv..>>.v>.v.>.vvvvv>v..v.v>....v..>>.>>..v.>.v>..v.>.v.vv>.>.>v.v....>v.vvv>>>.v>>.vvv..v..>.>...>.>..>.>...v..>>v..... .>v.>>v>..vv.>.vv.>>...v.v....>>>v....vvv>.v.>v.>v.vv.>.....>..>>.vv.v.v.>..v.>...>>.>.....>>.>........v>...>.>>>.>v.>.v.>>.....vvvv.v.>v>. >..v..>.>>>..>vv..v..>.v.v....v>...v>....>>...>v.>v...v..v...>.v>.>.>.vv...v....>>....vv.v>>....v.v.v....>v.....>.v.v...v>..>>..>..>>..>>v> .>vvv.v>.>vvv>>vv>v>v..>...>vv.>..v>.....>.vv....>>...>>.>>>v..vv.>>.....>>.v..v.v>>.vv>..v.vvv...>>.>..v.v>.v......v...>.>..>..>v....vv>.v .>v>...>...v..v>.v..v>v.v.>>.>vvv...v.>..............vv..vvvv>.>....>.>>..v.vv.>>.>.vv>...>>v.>.>.v..v>..v..>v...>.>..v.......>.>v.....>... ..v.>v>vv....v>>.v>vv....>.v>.>v.vvv>vv>>vv>..v>.vvv>.v.>v.>....v.>..v>v........v.>>>v..>>.>v>v...>>vv.>.v.>>.>..>..>vvv>.v.>vvvv.v>v.>v..> .vv>>v......>...v>.vv>..v>>.v>v>>v>...>.>>.>.>...v...>>>>>vv>.>v....>v..v>>.>.vv>..v>>v>.v..v.v..v>......>.vv>....>v>..v>>.>.>>.v>v>v>>>v.. >v.v>.>...vv.>..>.v.>>.vv....>.....>v.v..v.>..>...>.v>v.......vv.v>.>vvv...>..>.>....>v...>..v...>v.......vv..>....v...>v.....>>v.>vv>.v.v> v>..vv>.vv.v...vv...>......>v..>>.v>vv.v>>v..>v>..vvvv..>.>>.v..vv>.v>.>......>......>vv.v..vv>>..>..v..>v..>..>...>...>.>.........v.vv>v.v .v>.>.......>.v.>.v..>>.>.v>...>..vv......v.v...>..v>>v..v..v...>>vv..v.v...v.v...v>vv>..v.>>>v.v.v>v..>vv>..v..>>>>...>.>..>.>>>.>>vv>>..v .>..vvv.v>.v..>..v>>..v>v>>.>.>..v.>vv>.v.>>v>v.vv.....v.>v.>>>>vv>>>..>>...vv>v..vvvv>>>..v.v.>...v.....>>...>>..>.>.>v..>..>...>..v.v>..> vv..v>.v....v..v>.......>vv..>vv>...vv...v>>vvv>v...v.>v.v>v.>.v.v.>.>.>....v.>>>..>.v.......vv..v.vv>.v...v...>....vvvv>....>.v..v.>v..v.. >.vvv.>v....vv>>v.>..>.vv.>v>.v.>..>>v......vv>>>vv.v..vv.v.vvvvv>>.>>.>>v...v..v.>..>...>v>.v.v>vv>>.v.vv>>..v.>>>...>>.>v.v.>>..vv>..>.v. ..v.v>..>v>..>.......>>.>>>v..v.>....>.v..v>...>v>v.>.v.>.v...>....vv..>..v.>......v...>vvv>..v..v....v>...v.>.v......v>vv..>.vv...vvv.>vv. vv......vvvv.>>.>v>.>.v>.vv>v>.vv>....v....v.v.>vv>vv.>>.>.v>v...v.....v.>..>....v.>..>..v.....v.v>>v>.v.>..v>..vv.v.>>...>.vv>....>v.v>>.. v>.>>.>.....vv.>v>>.v>..>v.>..>>.v..v.>.>.>>.vv>..v..vv.>>v..>.>........v....v>>v.v.>v..>.>v......>..>.>.v.>...v>..>v>..v.>v>v..>vv>..v.>>> v..v..>...>.v..>>...>.>v..>v.v.vv.v..>..v..>.v.>>v.>..v.>..v>..>.>vvv..v.>.>>.v.v..v>.>v.>..>v..v>>v>>......vv.>.>.v.>>v......>v...>v...>>. .>..>...>...v.....>.....vv.v.>v.>.>..v....v>>...>.>.v..>>>...>v.v..>...>vv>..>v>.v.>>.vvv>>v>v.......v.vv...>>>..v...v.>v..v.>..>vv>..>.v>. ....>vv.>..>.>>.v..>.v.>..v..>..v.>>.>v..vv.v>>>v.....>>...>v>......>.>v>.v.>.vv>.vv>.v.>>..v>..>vv.v..v...>vvvv>>..>..v......v>..v.v.v>.>. ....vv>....v....>...v>..v>.>.>.>v..>.v>.......v>..v.vvv.v.>..v.>v>.>vv.v.>vv>.>>v.v..v.v...>vvv.......>v>v.v..>.v>.v>vvvv.>.>>>.>..vv.>v..> ..>.vvv>.>vvv>>>vv.>..>v.v.vvv>..vv.....>v>>..vv>.....>...>.v>.v>>.>.>vv..v...v..>.>>..>>.>.vv>v>>>vv....v>.>>..>..vv>.>>..>v>.v.v.v..>...v .>.v>............v>v.v......vvv>.vvv>v.v.>vv..>>....v.>.vv.vv..>..>>>>v.....>.>.>..v.>.>..>.vv.v.v......>>.>>>.>>.v..>v>v...v...v>...vv>.>. >>.v....v..>..v>>v....>...v.v....v.>..>.v>v.>v>.>>v.....>.v.>>.>>>..>.v.v.>>vv>>.>..>>v...>.>.v.vvv>>vv.vv>.v.>.>.>vv.v..>v>.>.vv>>>v..v>.v >v..v.v.>..>>>>..>>v.v>.v>..>>....v.....>..>.>v>...>>.v>....vvv>....>v.>.v.>.>v>.>v>>.>v>v..>.....v>.vv..v>>...>>v....>v..v>....>...vvv.v>. .>.v.....>..>.>vvv.>v.>vv.>..v..v.v.>vv>.>..>.>>>.....>v......>v.>....v..>.>..v>v.>..>.>v..>.v.>v>v>...v.v.>.v.>vvv>vv..>.v..v>..vv..>..v>. .v>.v>v>.v..v>.v..v.>............>v.>..>..>>.v..v>v>vv>>.>v.>>.v..v...v....>.v..>vv.>.....>.>>.vvv..>>..vv>>v>.....>>.v>...v.vvv>>..>..v.v> v...>..>...v.>>.v...>..v>v...>vv.v..>vv>..vv>>.v..vv.v>v.>>..v>v.v..>.......v...v.v>...>v.v......v.vv>...v.>..>vv>v.v....v.v.vv.vv.vvvv.>v. .>.v>>....>....vv..>vv>.>..vv.>>...>....>vv.vv...>.vv>v...>>..v...>..v....>v.vvv...v>>.>>>>>v>..v>>vv>vv.>vv..v...v.vv..v>v.>.v.v>..v..v.>v .>.v.v...v.....>..v>..v>.vv.v>...vv.....>v..>..>..>v.>.v...>.vv.....>.>.v.v>v....>..>>.vv.>vvvv..>>>.v...v...>v.vv>>.v..>v..>..>>.>..v>v..> >..vv>>v..>.v>>>v>>.v..vv>....v.>vvvv.>...vv...>.v..>v.>v>.>v>v>>v.>.>...>>>.....v.v....v>...>..>.>v.>.vv.....>.>>vv.....>......>.v..>v>.>. v.......>>.>..v>.v.>.>v..>>.>.>vv..>v.v...>.v>..v....v..v..>.>>...v..v>.vv.>v>>.>....>vv>.v.v.>..vvv.v.>.v>.v>v..>.>>.>.>..>.>...vvvvv.v>.. >..v.v>.>>v.>>...v.>v.....>.v.>.v>v.>v>.vvv>.>>..>v..v.v.>...>v....>v.v.v>>...>.vv>.>v.vv....v>..v>>v.>.>..v>v..>v>..>.>>.v>.>..>..>..v.... .>vv.>.v>>>.>.>.v>v.>..vv>..>>>.>>...v.....>v.v..>.>.>>.v.>.>v>.>v.v..vvvv>.....v.v..vv....v.>...>.vv.>>v.....>.>vv>...v....>v..>v..vv.>>>v v..>>>v.>..v>.v.v.>.>..>..>>..vv.vv.>.v.v..>v>v.>>>.>.>>.>>.vvv..>...>>..>.>..vvv>.>..v.>.>.v>v>.>v..>.>.v>....v..>..v.>v.>>.v.v..v>v..>v.. ....>v...>....>.v>>vv.....vv>..vv.v....vvv>>...vv.v.v.>......v.v>>v..>.v>..v>v.v..>....>....v.vvvv>v..v>v>v>v.>>v....v.>vv>>v>vv>>>.>..>.v> ...>>>.v.v.....v>vv>>v>.>..v.v>v>....v>>vv..vv>v>..vv...>.>v>.>v..v...>.>vv..v.>.v..v...>...v>...v.vv>vv>..v....>.v....v.v>..>.....v..v..v. .>vv.v..v>..vv....>.>>>>..>>>>..v....>.>v.vv.v.>>.>vvv..vv..>vv.>>v>>v.v..>.....>>v>..v..>>v>vvvv...>.>v>..v..>v>...>>.>vvv.v.>vv.>..v>>... >>.>...>v.>vv>v>.>.....>.vv.>.vv>.>>.>.>...........v>.>..>>.>.>>..v.v>>v.vv>v>.>v.>..v>vv>.>>.v>>.>.v>v.v..>v.v>.v>v>>.v.>v.>>vv...vv.vv... >vv>>.>...>v.>v>...>v>.v.>...vv....vv>v>.>..>.v.v.vv.v.>v......>..>.vv..v>.>>.>v>...v.vv..v...>vv.v.v...>>.>.>.v..v..>.vvvvv>>>>v>vv.v.v... >v>>>.v>..vvvv..vv>...>.>.v>>>..v.v>>.v..v>.v.....>v>>.v..>..>.....>v....>.>..>......>v>.>.v.>..v..vvv>>v.v..v>..v.v.>>>>>>>vvvv.vv.>vv..v> ..v..vv>v>v...v...>.vvvv.v.....v..>.>..>....v.....v>.>>..v.v.vv..>....vv>vv>v>>.>>v>>.>.vv.>..>>v.v>...v>.v...vv.>v....v.>>...>v.>.vv.>.vv. .v>v..>vvv.vv>v>>>..v..>v>.vvvv.>.>.vvv>.>..vv.>v...>...>v..>..>......v...>.v..v>>.>v...>>>>.....>>>..>vv.>>>v.>v..v>>vv.>....>..>>vv.>.>.. v.>...>vvv>...>.>.v>.v..v..v>.v.>.v>.v...vvv..>.>>v>...>.>>v>>.v.>v...>>.v.v..vv..vv.>.>v.>.v.>>>.>.vv...v.v>.v.>>>>>>..vvvv..>....>..>.v.. >v..>v....v.v....>vv.>.>.>v>.>v>v.v>>>.>v...>>>.v..v.v.v>v......>vv.v..>......>v>.v>>.vv>>>...vvv.v..>.>.........v.vv>.>vv.vv>v.v.>.>vv..v. >.v>.v.v>v..vv.v>v>.>>....vv..>.vvv>v..>>>>vv.v>....>.vv.>...>>>...>v>.>...v..v>v...>..v...>.v..v>.v...v.....>vv........>....v>v..v.>..>v.. >...>v......v>.>v...>.v...>>v.v>..>v...v.v..v>.>.v>.>...>vv.v>vvv.>..>..>...v...>>..>.>v.>vv.v..>>.v.v.v..>.v>..v.>..v...>>v.>v>v.v.v.>..>. ..v>.>>v>>..>..vv>>..>.>>vv..>..vv....v.>v>.....>v>..v.v>.v..>...vv..v.>>vvv...v>v>.>.v.>>>.v>...v>.>v.v>v>..>...>....>>>v..v..>>...>.v.... ....>...vv.>...vvv>v..>vvv>>..>>>>......>>>.v..v>vv>v>.>....>.....v.v..v.v.....v.v..v.v..v>.>v>v>.>.v.>v>....vv.v..>.vv..>..vv>.>v.>....... vv.>.>...>vvv.>v.>v>.>.>.v..v>..>.>>.v>.v>.v.v..v>v...v..>>.>>.>.>....v.>..>>vv>....>..>>...>>v.>.v>>..>>...vv.v.v.>>..v.v...v.v>..v.v..vv. .>v.v..v.v.>.v.....>.v...>.vv>.>....vv.v.v..v>.v>v>>>.v..vv.>vv.v....vv..vv.>>>v>.v.......>.vv.v..>v>v...v...>..>vv....>.>.>.>>v...v..v>>.v ...>v.>>.vv...>v.v.v>...v.>vv..v.v...>>>>..>.....>.>v.v.v>.v.v>.>>.>...vv..v....v>.v.vv..>.v>...>>..v.v.v.v>.v.v>v.>..v.>v..>>..>vv.......v >....v..>..vv.>.v>..>.>.>.>>v..vv.>vv...>>v.>.vv.v.>.v..>vvv>.v...vvvv>vv.>>>.>>..v.>v>>>..>>.>.v>>>v>>>..v>>.>.v.>...v.....v..>..>>.>v>..v >..vvvv>>..v>v>......>...v>...>>>...>.v>.>.v>.>>....vv..v>>>vv..>>>v.v>.>.v..>.v>..v>....vv>.>.v.....>v>.>.>.v>v.>.>v>v....v.>...>.v....... .v...v.....>>v.>vv.>v.>>.>.v>>.v...>>.v..v.vv>>.v...>>>v.>v>>..>>...vv.v>v.>..>v>.>v>>..>>.v...>..>.>..vv.....>>.>.vv>v>>.>..vv>.v.>v.>.v>v .vv>...v.>.vv.>>...v..>.vv...>.v.....>>..v..>v.>.>...v>..>v.v>.v.>v....>..>..>..>.>.>.>.>..>.>.>.>..v..v>>v.>.v>>.....v..>.v.....v>..v....v .....v>v..vvvv...v>..>.v.vv.>.>.......v.>..v..vvv.....vvv..>...>.v.>v.>v..>....v>.>>...v>...v>..v>v....v...v.v.>.>v>...v.vv.>...v.>>v>v>..> >v...>...>..>.v.>>>>.>v.vv>vv>.>.>.......v>>v.>vv...>>.>..v..v>vv..>.>..>v..>v>>>.v>>v.>.>..>...>>..v..v>>v.>vv>>.vvv>..v.>vvv..>..v>vv..vv ..vv.>v...>>........v.....>>..>>..>........>>vv.>.>.....vvv.vvvv>>.>..v.>v>...v.v..vv...v.v..v..>>v...v.>>>>...vvv>>>v>...>vv>v>.vvv..>v..> ..>.........vv.>....v>>.>>vv....>>vv....>..>.>...v..vv.v>..>v>.>v>>.>>>...vv>.......v..v>v>.>.>vvv.>...>.v.>>v>.v>>....v..v........vv.>>.vv ..v.>>v.v..>..>>.v..>.v>>>...>..vv>v.>...>...v.vv>.>.v>..>v.vv.......v...vv>.>vvv.>...>>.v.vv...>..vv..v>...v...>>>....>.>v.>.v...v......vv >vvv>.vv..>>.>....v..v>>>>v.>.>v....v.v...>>>..v.>..>v..>.vvv..v>.v>.v......>.v.v>>v.v.>.v...>.v.>vv.v>v..>..>>>.>v>>.vvv>>vv>.>v.>..vv.vvv >>>..>v.v>.vv.v>v>vv...v........v>.>.....v>v..v.>>>.>v..vv..>....vv.v>..v....>>>>vv...>v..v>.v.vv.>..>vv.vv...>>..>>.....vv..v>>..>....vvvv v>......vv>>.vv..v>v.v>>..v...>.v.>...>>..vv.>...vvvv.>v.>...>v.vvvvv..>>.....>v.>....>....>.>.>v..>.v.vvvvv..v..>vv.v>.v.v...>v.>..v>..>.. .v>>>>..vvv>v.vv>.v>vv..vv.v.vv.>>v>.>..>.v>v....>....v>>>.>.v.vvv.>>...v..>v>...v.v>>v>>v.v...v.v...vvv>>v.>.>...>v..>....>>.>..>.vvv>.v>. >>.v...>.v>...v>v..v.vv.v..v.v.>...v>v.>.>>.v.>.v>>>.>>.>..>....v..v>>>.v>>.>..>>.>.vv.>>.vv.>>>v>.>>.>.v....v>....>..vvvv....v....v.v.v>vv >..v>vv>.>v.>.....v.>vvv>..>.>.vv>>>..>.....>..>v>.v...>v..>...v...vv..v>>>v.>>..vv>>..>.>>>v.>..>v...v.v..>.>..>.>>..>.v.v>....>...v...v.. >.>.v...v..vv.>>>vv.vvv..>...vv.vv>...v.v>>>>.>.>>v.>..vv...>v>>v>..>..>vv..vv>>.v>>...>.>v...>..>.>>>.......>.>>.>.>....v.v.............>v ...v>.vv..vv...>v>..>>.v..vv.>.v..v..>..>>.>vvvv.vvv.>>vv>v>.>>v>..>...v>...v...v>>.>..>.>.>v>.v..>>......>v...>v>v.>>.....v>..>.>>>>v.v.>> .v..vv>....>>...v>.v.v.>.>>....>..v>>.v>v..>......>v...v.>.v......v..>v..>....v.vvv.v..>vv..v.>..v..>>>....>>>>v.>.....v>>.>..v..v>v.v..>.. v>......v..v..v>.....>v>>.>v>v>.>>v>v>v>>...>.....v>.v>...v...v.....>>...v...>.vv..vv..>.>>...>v.>.vv>..v.v>..vv..vvvv.>v..>....v>.>..vv.>> >.>..v>v..>.vv>>.v>>>>>v>....v.v.>vv..>>...v>v>v.vv>.>>>..>.>v.>>v......>>.>v..v>.vv...vv.v.vv>.>....>.>v...>.v..>.>..vv>..>.vvv.>>>v.v.... >.>.vvv.v>.>vvv...v.>..>.v.>.......>.>....v..>..>...>v..>v....v..>v.v>v.v.>..v.vvvv>>v>.>>.>>>...>..>v>..>v.>v.v..v>>vv.>..v.v>vv...vv>..v. .v>v.v..>...v>v>.>vvv.>.v.....v.>.>>..v>v>.v.>.>....>.v..v.>v.v>.>.v.vv..v>>v>vv....>>....>vv>v>v>>.v..>.vv..>>>......>>>>..v>v>v>.>>..v..v ..>v.vv..>>v>v.v.......vvvv>vv.v>.v...v>v>>.v>.>.v>..vv...>v.>...v.>v>..v>.vv>....>>..v.>.>vv.vvv.>....v...v>.>..vvv>.>>vvvv>>v....>..>>.>. .v.v.>vv>.>...v...vv.....v...v>>.>v.>vv>.>>....>>...v.vvv..>>..v.>vvvvv>..v.>....>v.>.......v.>.v.v.>..>>v>vv>>vv.>v.>v>>..>.v>.vv..v..vv.> ...vv.v...vv....>..>..v.>>v>v.>.v...>...v>...v>>v...>v.>>.v...v>>v...>..>v..v>..v..>.v>.>.>..v...vv>v.>.vv>>>..>>>vv.>..vvv..v.>.>..vvv>.v. .>>.v.>.>..v>..>v>..v>.v.v>>.vvv..vv.>v.>>.>.v.vv.v.vv>.>.vv>.>..v>>.>.v.>v..>>v...v..v>>.>.v>.>.>v..v.v.>>>vv.v.>...v..>v.....>vv..v>.>>>> .>.....>v>>>>....v..>>>vv...v.>>>v..v>vv>>.>.v.>.>v>.v>v..>..v.v...v..v.>.>>...v.>>v.v>vv.v..>.v>.>>vv...v.v...>>....v.>..vv..vv....v>..... ..v>.>v..v>...v>.>..>...vv>v>vv.>...vv>>..v>.v.>....>....v..>v>.>...v>>vvv....v.v..v>.vv.v.vv.v..>v>>..>...>v>>....v.>>..v.>v.>v.>>v.v.v.v. .>.v>>>v>.v.vvv...v>....vvvvv>>v.vv>>>>>....>.....>>...vv.>vvv..>.v..vvv.vv>vv>..vv>>vvv...>.>.>.>...vv>.>v.v.v..v>v..v.>.v>>.>vv.>...v.v.> .>....>>vv.>>>>.>v.>.v..>.>>.vvv>..v..v>..>>.v>.>>>.v.v>>vvv>v...vv.vv..>....>.v..v.>.v>..v....v..vv>v>.>..>..>>>.>>>.v.vvv.v..v......vv.vv .v.v>>>v.>v.>....>..>.>v.......v>>........vv.v>>>...vvv.>>.>.v.>v.v.>...>v.v.....v.v.>vv>.>>v>>..v>>>..v.v..v......>.v>.>.>>v.v.v.vvv>vv.>. .>..>....>>.....>.>...v.v....>v>>>v.>.v>.>vv..>v>v>v.>>>>>>v.>>>>>.>.>>.v>......v.v.v.v...>.v..v...>..>>>>>.>.>..>.vv..v>.>..v>.v.v....v.>. ..v>>>>.>>>>....v>v..>>vv.>>..>..v>..vvv>.>..v.>...v>>..>.>>>..vvv.v..>.>.vv>...>vvvv>vv>>>vv..>...>v.>vv....>v.v>..>vv....>v>..v>.v.>v>>v> .>>.>>>v.>.v>.>.v>.v.>......v...>.v.>..>.vv.>v..v>.v>.v..v...>.vv.v>>.>v.v..>v.>...>>...v.>>v.>>..>v...v.>...v>.>.v..v.>.>....v.>>>>v.>v.>. >vvv..v.v>>..>..v.>vv.vv>..>vv.v.>...>v..v>>....>>...>>.>>....>...>v>..>>>..>...v.>v.v>.....>..v...>vvv.vv.>>.>v>v.v>v..v>...v..>>.>..v...> >>.>>...>.>>>..v>>..>v..vv>>>>.v.>>v..vv..>.>..vv.....v.v.v.>..>>>....v.v.>v>>vv....>.....v>v..v>..vv...>..>>v..vv...v.....>vv..v>.>..>.>.. ..vv>.v>.....v..>.vv>>...>v...>.v.v>>>........>vvvvv>>.>...>.v.v..v....>.>v>>.v.vv.v..v.vv.>.>v>.>v.>..vv...>>..>.....v...>>>v..v..>.v>>v>. .vvvv>.>...>>.v..>...vvv>vvv..vv>.>v>.....vv.v..v...v.....>>>v.v>v>>.>v..>>>..>.>v..vv...>vv>.v.>.v..v.>>.....>v.>v>>.vv..v..>..>.>.v....v. >v>>v...>..>.>>..v..vvv>...>>....>.>>....vv>...>......>..>>v...vv..>>>>>.>v.>.>.vv>>.>>vv....>.v>>..v>>...>v..>...vv..>.>..vvv...>.....>.v. >..v>.>..vv...v.>>>.v>>.>....v.vv.>..>...>..v..>v.>vv.>..v..>.v.>...vv...v>>..>>vvv...>.>v.>.vv.>v..vv.>>vv.>>..>vv>.v.....>>...v..v.vvv.>> v.v..vvv>...>v......v....>..>>>.....v>v>>>..v.v..vv.>.>>>>.>.v.>....v.>.>v>vv>vv>v..>.>.v.v>.....>..v>>v...v.....v...v.v.vv>>........v.>.v> .v>>...>>v>.>...v.>>>....>v>>v.>.v.>>v.v>.>>...>.v.v...vv>v....v>v..>>.>v>.>..>vv.v>>.>..v>>v...>v>>>..v..>v>vv.vv>............>v..>vv.v.vv >.....>vv.>...v>vvvv>vvv..vvv>.v.>...>v..vv>vv.>>>.v..v>v.>..vv.v.>>v....v...v.....>.v.>.>..>.v>..>v..>>>>>>>v..vv>.v.v>v.v>..>....>>>v>.vv v.>.v>v.v>...>>>..v>..>>.>..v.v....>.>....v.>..>>>.>v.>.>.>vv..>.>...v.>.....>vv>.>..vv.vvv.>>.vv.>.....vvvv>..v.>.>>v..v..>.>>.>...v>>v..> v..v>v>..vvv>...v..>.>>...v.v..v..>v..>>.>>.v..>>v...v.vv..v..>...v...v....>v.v.v.v.>.v>vvv.v.v>...>v>.>..>v.v>v>v..v..>>>>...>v.....v.>..v v>v..v..>..v>.....>>>.v..>v>v..>..>v>...v..>....v...v>>vv.....v.vv...v>....v>..v>>.v.>.>>..>v>..>>>vv.>>>...>...v>vv>v>...>..v.v..>.....>>. vv..>>v..>>>.>...v..v.>v>..v.>>>>>v..v>v>..>v>>>v.....v..>.>.>>vv.v....v.....>v......>.>vv..vv>.vv..vv...vv.v...>.v..>.>.v>v...v>..vv...>vv .>...vv>>>.v.....v....>.v......vvvv>.>..>vv>v..vv..>v>>.>v.v>.v>v.vvvvv.v>v......v.>v>vv..>v..>vv.v.v.vvv..>.>.>>v.v.......>vv..v.vv>.>.v.. ....v...v.>.v>>>v.>.....>>v>..v>.v.>.v.>..>v.>vv>>vv.>........v..>v>.v>>v>>v.>....>.>...>.>.v.......v....v>vvv..v>..>..v>....v...>.v.>.v... ..vvv.v>.>...>>.vvv>...v...>..>..>...v>v>..>>.vv....>.v.v.>.v>vv.>>v..v>.v.v..v.>.>>.v.....>.v...v>.....v....v.v.v.>>....v.v>>>.......>vv.v ...v>v>..v.v.v...>v>.vvv.vv..>..v.>v.>vv.>.>>..v....>.v.....>.v>..>..v>>vv..vv.>....v>>.v>...>.>vv....v>>.>>v>....>.v.v>v>>>>...>....>.>..v .>>..v.>v..>>>v.v.v>>...>>v...v>....>.v>>...v.>.v.>...v>>vv.vvv>v....v>.v.>v......v.v.>>.>v...v...>vv.v.....>...>.>..vv.v..>..>.v>..>.v>.vv >..>.>.>>.v.v.>.v.vvv....>.v>v.v..v.v...>...vv..>>.>..>>>...v>.>.v..v.>>.......v.....>.v>vv.>.v..vv>>>>>>v...vvv..vvv>>>.v.>.v..v.v>v>v>..> v..>.v.vv>>vvvvv.....v>>v...vv....v>.>>v.v.>.>>v.vv....vv..v.>>.v.v.>v>....>....v.v>>>.>v.v.>v>v.v.v..>.>v>v......v.v>...>v.vvv...v>...vv.. >>vv.....v...v......>v.v..v>..v.v>..>>>.>>..>v>.v>>>.>v..>>>>v.>..vvvv.v>...v..vv.>.>v....>v.>>.....v>v....v..>.>.v>v.>.>.>v.v..>v......... y2021 - Day 25: Sea Cucumber loige Sometimes you have to handle grids of variable sizes. Actual input (139x137) 73
  56. struct Grid<const W: usize, const H: usize> { cells: [[Option<Cell>;

    W]; H], } 1 2 3 y2021 - Day 25: Sea Cucumber loige You can use const generics to define a matrix with configurable dimensions 74
  57. struct Grid<const W: usize, const H: usize> { cells: [[Option<Cell>;

    W]; H], } pub fn test_readme(input: &str) -> usize { let mut grid1: Grid<10, 9> = input.parse().unwrap(); // ... } pub fn part1(input: &str) -> usize { let mut grid1: Grid<139, 137> = input.parse().unwrap(); // ... } 1 2 3 4 5 6 7 8 9 10 11 12 13 pub fn test_readme(input: &str) -> usize { let mut grid1: Grid<10, 9> = input.parse().unwrap(); // ... struct Grid<const W: usize, const H: usize> { 1 cells: [[Option<Cell>; W]; H], 2 } 3 4 5 6 7 } 8 9 pub fn part1(input: &str) -> usize { 10 let mut grid1: Grid<139, 137> = input.parse().unwrap(); 11 // ... 12 } 13 pub fn part1(input: &str) -> usize { let mut grid1: Grid<139, 137> = input.parse().unwrap(); // ... } struct Grid<const W: usize, const H: usize> { 1 cells: [[Option<Cell>; W]; H], 2 } 3 4 pub fn test_readme(input: &str) -> usize { 5 let mut grid1: Grid<10, 9> = input.parse().unwrap(); 6 // ... 7 } 8 9 10 11 12 13 struct Grid<const W: usize, const H: usize> { cells: [[Option<Cell>; W]; H], } pub fn test_readme(input: &str) -> usize { let mut grid1: Grid<10, 9> = input.parse().unwrap(); // ... } pub fn part1(input: &str) -> usize { let mut grid1: Grid<139, 137> = input.parse().unwrap(); // ... } 1 2 3 4 5 6 7 8 9 10 11 12 13 y2021 - Day 25: Sea Cucumber loige 75
  58. mask = 000000000000000000000000000000X1001X mem[42] = 100 mask = 00000000000000000000000000000000X0XX mem[26]

    = 1 ... y2020 - Day 14: Docking Data loige enum Instr { Mask(String), Mem(u64, u64), } 77
  59. use std::str::FromStr; impl FromStr for Instr { type Err =

    String; fn from_str(s: &str) -> Result<Self, Self::Err> { if s.starts_with("mask") { Ok(Instr::Mask(s[7..].to_string())) } else if s.starts_with("mem") { let addr_value = &mut s[4..].split("] = "); let addr: u64 = addr_value.next().unwrap().parse().unwrap(); let value: u64 = addr_value.next().unwrap().parse().unwrap(); Ok(Instr::Mem(addr, value)) } else { Err(format!("Invalid line found: {s}")) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 use std::str::FromStr; impl FromStr for Instr { } 1 2 3 type Err = String; 4 5 fn from_str(s: &str) -> Result<Self, Self::Err> { 6 if s.starts_with("mask") { 7 Ok(Instr::Mask(s[7..].to_string())) 8 } else if s.starts_with("mem") { 9 let addr_value = &mut s[4..].split("] = "); 10 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 11 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 12 Ok(Instr::Mem(addr, value)) 13 } else { 14 Err(format!("Invalid line found: {s}")) 15 } 16 } 17 18 use std::str::FromStr; impl FromStr for Instr { type Err = String; fn from_str(s: &str) -> Result<Self, Self::Err> { } } 1 2 3 4 5 6 if s.starts_with("mask") { 7 Ok(Instr::Mask(s[7..].to_string())) 8 } else if s.starts_with("mem") { 9 let addr_value = &mut s[4..].split("] = "); 10 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 11 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 12 Ok(Instr::Mem(addr, value)) 13 } else { 14 Err(format!("Invalid line found: {s}")) 15 } 16 17 18 if s.starts_with("mask") { Ok(Instr::Mask(s[7..].to_string())) use std::str::FromStr; 1 2 impl FromStr for Instr { 3 type Err = String; 4 5 fn from_str(s: &str) -> Result<Self, Self::Err> { 6 7 8 } else if s.starts_with("mem") { 9 let addr_value = &mut s[4..].split("] = "); 10 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 11 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 12 Ok(Instr::Mem(addr, value)) 13 } else { 14 Err(format!("Invalid line found: {s}")) 15 } 16 } 17 } 18 } else if s.starts_with("mem") { Ok(Instr::Mem(addr, value)) use std::str::FromStr; 1 2 impl FromStr for Instr { 3 type Err = String; 4 5 fn from_str(s: &str) -> Result<Self, Self::Err> { 6 if s.starts_with("mask") { 7 Ok(Instr::Mask(s[7..].to_string())) 8 9 let addr_value = &mut s[4..].split("] = "); 10 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 11 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 12 13 } else { 14 Err(format!("Invalid line found: {s}")) 15 } 16 } 17 } 18 } else { Err(format!("Invalid line found: {s}")) } use std::str::FromStr; 1 2 impl FromStr for Instr { 3 type Err = String; 4 5 fn from_str(s: &str) -> Result<Self, Self::Err> { 6 if s.starts_with("mask") { 7 Ok(Instr::Mask(s[7..].to_string())) 8 } else if s.starts_with("mem") { 9 let addr_value = &mut s[4..].split("] = "); 10 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 11 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 12 Ok(Instr::Mem(addr, value)) 13 14 15 16 } 17 } 18 use std::str::FromStr; impl FromStr for Instr { type Err = String; fn from_str(s: &str) -> Result<Self, Self::Err> { if s.starts_with("mask") { Ok(Instr::Mask(s[7..].to_string())) } else if s.starts_with("mem") { let addr_value = &mut s[4..].split("] = "); let addr: u64 = addr_value.next().unwrap().parse().unwrap(); let value: u64 = addr_value.next().unwrap().parse().unwrap(); Ok(Instr::Mem(addr, value)) } else { Err(format!("Invalid line found: {s}")) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 loige 78
  60. let mask: Instr = "mask = 00000000000000X1001X".parse().unwrap(); assert_eq!(mask, Instr::Mask("00000000000000X1001X".to_string())); let

    mem: Instr = "mem[42] = 100".parse().unwrap(); assert_eq!(mem, Instr::Mem(42, 100)); 1 2 3 4 5 let mask: Instr = "mask = 00000000000000X1001X".parse().unwrap(); assert_eq!(mask, Instr::Mask("00000000000000X1001X".to_string())); 1 2 3 let mem: Instr = "mem[42] = 100".parse().unwrap(); 4 assert_eq!(mem, Instr::Mem(42, 100)); 5 let mem: Instr = "mem[42] = 100".parse().unwrap(); assert_eq!(mem, Instr::Mem(42, 100)); let mask: Instr = "mask = 00000000000000X1001X".parse().unwrap(); 1 assert_eq!(mask, Instr::Mask("00000000000000X1001X".to_string())); 2 3 4 5 let mask: Instr = "mask = 00000000000000X1001X".parse().unwrap(); assert_eq!(mask, Instr::Mask("00000000000000X1001X".to_string())); let mem: Instr = "mem[42] = 100".parse().unwrap(); assert_eq!(mem, Instr::Mem(42, 100)); 1 2 3 4 5 loige 79
  61. let mask: Instr = "mask = 00000000000000X1001X".parse().unwrap(); let mem: Instr

    = "mem[42] = 100".parse().unwrap(); 1 assert_eq!(mask, Instr::Mask("00000000000000X1001X".to_string())); 2 3 4 assert_eq!(mem, Instr::Mem(42, 100)); 5 loige Implementing the FromStr trait, will make the parse() method available! 80
  62. oops, I did it again: unnecessary allocations! 🤷 loige Why

    don't you just take a slice from the input rather than allocating a String? 81
  63. enum Instr<'a> { Mask(&'a str), Mem(u64, u64), } impl<'a> FromStr

    for Instr<'a> { type Err = String; fn from_str(s: &'a str) -> Result<Self, Self::Err> { if s.starts_with("mask") { Ok(Instr::Mask(&s[7..])) } else if s.starts_with("mem") { let addr_value = &mut s[4..].split("] = "); let addr: u64 = addr_value.next().unwrap().parse().unwrap(); let value: u64 = addr_value.next().unwrap().parse().unwrap(); Ok(Instr::Mem(addr, value)) } else { Err(format!("Invalid line found: {s}")) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 enum Instr<'a> { Mask(&'a str), } 1 2 Mem(u64, u64), 3 4 5 6 impl<'a> FromStr for Instr<'a> { 7 type Err = String; 8 9 fn from_str(s: &'a str) -> Result<Self, Self::Err> { 10 if s.starts_with("mask") { 11 Ok(Instr::Mask(&s[7..])) 12 } else if s.starts_with("mem") { 13 let addr_value = &mut s[4..].split("] = "); 14 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 15 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 16 Ok(Instr::Mem(addr, value)) 17 } else { 18 Err(format!("Invalid line found: {s}")) 19 } 20 } 21 } 22 impl<'a> FromStr for Instr<'a> { enum Instr<'a> { 1 Mask(&'a str), 2 Mem(u64, u64), 3 } 4 5 6 7 type Err = String; 8 9 fn from_str(s: &'a str) -> Result<Self, Self::Err> { 10 if s.starts_with("mask") { 11 Ok(Instr::Mask(&s[7..])) 12 } else if s.starts_with("mem") { 13 let addr_value = &mut s[4..].split("] = "); 14 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 15 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 16 Ok(Instr::Mem(addr, value)) 17 } else { 18 Err(format!("Invalid line found: {s}")) 19 } 20 } 21 } 22 fn from_str(s: &'a str) -> Result<Self, Self::Err> { enum Instr<'a> { 1 Mask(&'a str), 2 Mem(u64, u64), 3 } 4 5 6 impl<'a> FromStr for Instr<'a> { 7 type Err = String; 8 9 10 if s.starts_with("mask") { 11 Ok(Instr::Mask(&s[7..])) 12 } else if s.starts_with("mem") { 13 let addr_value = &mut s[4..].split("] = "); 14 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 15 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 16 Ok(Instr::Mem(addr, value)) 17 } else { 18 Err(format!("Invalid line found: {s}")) 19 } 20 } 21 } 22 loige 82
  64. fn from_str(s: &'a str) -> Result<Self, Self::Err> { enum Instr<'a>

    { 1 Mask(&'a str), 2 Mem(u64, u64), 3 } 4 5 6 impl<'a> FromStr for Instr<'a> { 7 type Err = String; 8 9 10 if s.starts_with("mask") { 11 Ok(Instr::Mask(&s[7..])) 12 } else if s.starts_with("mem") { 13 let addr_value = &mut s[4..].split("] = "); 14 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 15 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 16 Ok(Instr::Mem(addr, value)) 17 } else { 18 Err(format!("Invalid line found: {s}")) 19 } 20 } 21 } 22 loige users.rust-lang.org/t/fromstr-and-lifetimes/12198 83
  65. enum Instr<'a> { Mask(&'a str), Mem(u64, u64), } impl<'a> From<&'a

    str> for Instr<'a> { fn from(s: &'a str) -> Self { if s.starts_with("mask") { Instr::Mask(&s[7..]) } else if s.starts_with("mem") { let addr_value = &mut s[4..].split("] = "); let addr: u64 = addr_value.next().unwrap().parse().unwrap(); let value: u64 = addr_value.next().unwrap().parse().unwrap(); Instr::Mem(addr, value) } else { panic!("Invalid line found: {s}") } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 impl<'a> From<&'a str> for Instr<'a> { } enum Instr<'a> { 1 Mask(&'a str), 2 Mem(u64, u64), 3 } 4 5 6 7 fn from(s: &'a str) -> Self { 8 if s.starts_with("mask") { 9 Instr::Mask(&s[7..]) 10 } else if s.starts_with("mem") { 11 let addr_value = &mut s[4..].split("] = "); 12 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 13 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 14 Instr::Mem(addr, value) 15 } else { 16 panic!("Invalid line found: {s}") 17 } 18 } 19 20 fn from(s: &'a str) -> Self { } enum Instr<'a> { 1 Mask(&'a str), 2 Mem(u64, u64), 3 } 4 5 6 impl<'a> From<&'a str> for Instr<'a> { 7 8 if s.starts_with("mask") { 9 Instr::Mask(&s[7..]) 10 } else if s.starts_with("mem") { 11 let addr_value = &mut s[4..].split("] = "); 12 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 13 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 14 Instr::Mem(addr, value) 15 } else { 16 panic!("Invalid line found: {s}") 17 } 18 19 } 20 panic!("Invalid line found: {s}") enum Instr<'a> { 1 Mask(&'a str), 2 Mem(u64, u64), 3 } 4 5 6 impl<'a> From<&'a str> for Instr<'a> { 7 fn from(s: &'a str) -> Self { 8 if s.starts_with("mask") { 9 Instr::Mask(&s[7..]) 10 } else if s.starts_with("mem") { 11 let addr_value = &mut s[4..].split("] = "); 12 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 13 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 14 Instr::Mem(addr, value) 15 } else { 16 17 } 18 } 19 } 20 loige 84
  66. panic!("Invalid line found: {s}") enum Instr<'a> { 1 Mask(&'a str),

    2 Mem(u64, u64), 3 } 4 5 6 impl<'a> From<&'a str> for Instr<'a> { 7 fn from(s: &'a str) -> Self { 8 if s.starts_with("mask") { 9 Instr::Mask(&s[7..]) 10 } else if s.starts_with("mem") { 11 let addr_value = &mut s[4..].split("] = "); 12 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 13 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 14 Instr::Mem(addr, value) 15 } else { 16 17 } 18 } 19 } 20 loige This panic gives me anxiety 😰 85
  67. use std::convert::{TryFrom, TryInto}; enum Instr<'a> { Mask(&'a str), Mem(u64, u64),

    } impl<'a> TryFrom<&'a str> for Instr<'a> { type Error = String; fn try_from(s: &'a str) -> Result<Self, Self::Error> { if s.starts_with("mask") { Ok(Instr::Mask(&s[7..])) } else if s.starts_with("mem") { let addr_value = &mut s[4..].split("] = "); let addr: u64 = addr_value.next().unwrap().parse().unwrap(); let value: u64 = addr_value.next().unwrap().parse().unwrap(); Ok(Instr::Mem(addr, value)) } else { Err(format!("Invalid line found: {s}")) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 use std::convert::{TryFrom, TryInto}; 1 2 enum Instr<'a> { 3 Mask(&'a str), 4 Mem(u64, u64), 5 } 6 7 impl<'a> TryFrom<&'a str> for Instr<'a> { 8 type Error = String; 9 10 fn try_from(s: &'a str) -> Result<Self, Self::Error> { 11 if s.starts_with("mask") { 12 Ok(Instr::Mask(&s[7..])) 13 } else if s.starts_with("mem") { 14 let addr_value = &mut s[4..].split("] = "); 15 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 16 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 17 Ok(Instr::Mem(addr, value)) 18 } else { 19 Err(format!("Invalid line found: {s}")) 20 } 21 } 22 } 23 impl<'a> TryFrom<&'a str> for Instr<'a> { } use std::convert::{TryFrom, TryInto}; 1 2 enum Instr<'a> { 3 Mask(&'a str), 4 Mem(u64, u64), 5 } 6 7 8 type Error = String; 9 10 fn try_from(s: &'a str) -> Result<Self, Self::Error> { 11 if s.starts_with("mask") { 12 Ok(Instr::Mask(&s[7..])) 13 } else if s.starts_with("mem") { 14 let addr_value = &mut s[4..].split("] = "); 15 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 16 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 17 Ok(Instr::Mem(addr, value)) 18 } else { 19 Err(format!("Invalid line found: {s}")) 20 } 21 } 22 23 type Error = String; use std::convert::{TryFrom, TryInto}; 1 2 enum Instr<'a> { 3 Mask(&'a str), 4 Mem(u64, u64), 5 } 6 7 impl<'a> TryFrom<&'a str> for Instr<'a> { 8 9 10 fn try_from(s: &'a str) -> Result<Self, Self::Error> { 11 if s.starts_with("mask") { 12 Ok(Instr::Mask(&s[7..])) 13 } else if s.starts_with("mem") { 14 let addr_value = &mut s[4..].split("] = "); 15 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 16 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 17 Ok(Instr::Mem(addr, value)) 18 } else { 19 Err(format!("Invalid line found: {s}")) 20 } 21 } 22 } 23 fn try_from(s: &'a str) -> Result<Self, Self::Error> { } use std::convert::{TryFrom, TryInto}; 1 2 enum Instr<'a> { 3 Mask(&'a str), 4 Mem(u64, u64), 5 } 6 7 impl<'a> TryFrom<&'a str> for Instr<'a> { 8 type Error = String; 9 10 11 if s.starts_with("mask") { 12 Ok(Instr::Mask(&s[7..])) 13 } else if s.starts_with("mem") { 14 let addr_value = &mut s[4..].split("] = "); 15 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 16 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 17 Ok(Instr::Mem(addr, value)) 18 } else { 19 Err(format!("Invalid line found: {s}")) 20 } 21 22 } 23 Ok(Instr::Mask(&s[7..])) Ok(Instr::Mem(addr, value)) Err(format!("Invalid line found: {s}")) use std::convert::{TryFrom, TryInto}; 1 2 enum Instr<'a> { 3 Mask(&'a str), 4 Mem(u64, u64), 5 } 6 7 impl<'a> TryFrom<&'a str> for Instr<'a> { 8 type Error = String; 9 10 fn try_from(s: &'a str) -> Result<Self, Self::Error> { 11 if s.starts_with("mask") { 12 13 } else if s.starts_with("mem") { 14 let addr_value = &mut s[4..].split("] = "); 15 let addr: u64 = addr_value.next().unwrap().parse().unwrap(); 16 let value: u64 = addr_value.next().unwrap().parse().unwrap(); 17 18 } else { 19 20 } 21 } 22 } 23 use std::convert::{TryFrom, TryInto}; enum Instr<'a> { Mask(&'a str), Mem(u64, u64), } impl<'a> TryFrom<&'a str> for Instr<'a> { type Error = String; fn try_from(s: &'a str) -> Result<Self, Self::Error> { if s.starts_with("mask") { Ok(Instr::Mask(&s[7..])) } else if s.starts_with("mem") { let addr_value = &mut s[4..].split("] = "); let addr: u64 = addr_value.next().unwrap().parse().unwrap(); let value: u64 = addr_value.next().unwrap().parse().unwrap(); Ok(Instr::Mem(addr, value)) } else { Err(format!("Invalid line found: {s}")) } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 loige 86
  68. let mask: Instr = "mask = 00000000000000X1001X".try_into().unwrap(); let mem: Instr

    = "mem[42] = 100".try_into().unwrap(); 1 assert_eq!(mask, Instr::Mask("00000000000000X1001X")); 2 3 4 assert_eq!(mem, Instr::Mem(42, 100)); 5 loige Implementing the TryFrom trait, will make the try_into() method available! 87
  69. Sensor at x=2, y=18: closest beacon is at x=-2, y=15

    Sensor at x=9, y=16: closest beacon is at x=10, y=16 Sensor at x=13, y=2: closest beacon is at x=15, y=3 Sensor at x=12, y=14: closest beacon is at x=10, y=16 ... y2022 - Day 15: Beacon Exclusion Zone loige struct Pos { x: i64, y: i64, } let sensor = Pos { x: 13, y: 2, } let beacon = Pos { x: 15, y: 3, } 88
  70. use regex::Regex; fn parse_line_regex(line: &str) -> (Pos, Pos) { let

    re = Regex::new( r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon ) .unwrap(); let captures = re.captures(line).unwrap(); let sensor = Pos { x: captures["x1"].parse().unwrap(), y: captures["y1"].parse().unwrap(), }; let beacon = Pos { x: captures["x2"].parse().unwrap(), y: captures["y2"].parse().unwrap(), }; (sensor, beacon) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 use regex::Regex; 1 2 fn parse_line_regex(line: &str) -> (Pos, Pos) { 3 let re = Regex::new( 4 r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon 5 ) 6 .unwrap(); 7 8 let captures = re.captures(line).unwrap(); 9 let sensor = Pos { 10 x: captures["x1"].parse().unwrap(), 11 y: captures["y1"].parse().unwrap(), 12 }; 13 let beacon = Pos { 14 x: captures["x2"].parse().unwrap(), 15 y: captures["y2"].parse().unwrap(), 16 }; 17 (sensor, beacon) 18 } 19 fn parse_line_regex(line: &str) -> (Pos, Pos) { } use regex::Regex; 1 2 3 let re = Regex::new( 4 r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon 5 ) 6 .unwrap(); 7 8 let captures = re.captures(line).unwrap(); 9 let sensor = Pos { 10 x: captures["x1"].parse().unwrap(), 11 y: captures["y1"].parse().unwrap(), 12 }; 13 let beacon = Pos { 14 x: captures["x2"].parse().unwrap(), 15 y: captures["y2"].parse().unwrap(), 16 }; 17 (sensor, beacon) 18 19 let re = Regex::new( r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon ) .unwrap(); use regex::Regex; 1 2 fn parse_line_regex(line: &str) -> (Pos, Pos) { 3 4 5 6 7 8 let captures = re.captures(line).unwrap(); 9 let sensor = Pos { 10 x: captures["x1"].parse().unwrap(), 11 y: captures["y1"].parse().unwrap(), 12 }; 13 let beacon = Pos { 14 x: captures["x2"].parse().unwrap(), 15 y: captures["y2"].parse().unwrap(), 16 }; 17 (sensor, beacon) 18 } 19 let captures = re.captures(line).unwrap(); use regex::Regex; 1 2 fn parse_line_regex(line: &str) -> (Pos, Pos) { 3 let re = Regex::new( 4 r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon 5 ) 6 .unwrap(); 7 8 9 let sensor = Pos { 10 x: captures["x1"].parse().unwrap(), 11 y: captures["y1"].parse().unwrap(), 12 }; 13 let beacon = Pos { 14 x: captures["x2"].parse().unwrap(), 15 y: captures["y2"].parse().unwrap(), 16 }; 17 (sensor, beacon) 18 } 19 let sensor = Pos { x: captures["x1"].parse().unwrap(), y: captures["y1"].parse().unwrap(), }; let beacon = Pos { x: captures["x2"].parse().unwrap(), y: captures["y2"].parse().unwrap(), }; use regex::Regex; 1 2 fn parse_line_regex(line: &str) -> (Pos, Pos) { 3 let re = Regex::new( 4 r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon 5 ) 6 .unwrap(); 7 8 let captures = re.captures(line).unwrap(); 9 10 11 12 13 14 15 16 17 (sensor, beacon) 18 } 19 (sensor, beacon) use regex::Regex; 1 2 fn parse_line_regex(line: &str) -> (Pos, Pos) { 3 let re = Regex::new( 4 r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon 5 ) 6 .unwrap(); 7 8 let captures = re.captures(line).unwrap(); 9 let sensor = Pos { 10 x: captures["x1"].parse().unwrap(), 11 y: captures["y1"].parse().unwrap(), 12 }; 13 let beacon = Pos { 14 x: captures["x2"].parse().unwrap(), 15 y: captures["y2"].parse().unwrap(), 16 }; 17 18 } 19 use regex::Regex; fn parse_line_regex(line: &str) -> (Pos, Pos) { let re = Regex::new( r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon ) .unwrap(); let captures = re.captures(line).unwrap(); let sensor = Pos { x: captures["x1"].parse().unwrap(), y: captures["y1"].parse().unwrap(), }; let beacon = Pos { x: captures["x2"].parse().unwrap(), y: captures["y2"].parse().unwrap(), }; (sensor, beacon) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 loige 93
  71. pub fn parse_regex(input: &str) -> impl Iterator<Item = (Pos, Pos)>

    + '_ input.lines().map(parse_line_regex) } use regex::Regex; 1 2 fn parse_line_regex(line: &str) -> (Pos, Pos) { 3 let re = Regex::new( 4 r"Sensor at x=(?P<x1>[-]?\d+), y=(?P<y1>[-]?\d+): closest beacon 5 ) 6 .unwrap(); 7 8 // ... 9 (sensor, beacon) 10 } 11 12 13 14 15 loige Aren't we re-istantiating the Regex over and over? 🤷 94
  72. #[macro_use] extern crate lazy_static; use regex::Regex; lazy_static! { static ref

    LINE_REGEX: Regex = Regex::new(r"Sensor at x=(?P<x1>[-]?\d .unwrap(); } fn parse_line_regex(line: &str) -> (Pos, Pos) { let captures = LINE_REGEX.captures(line).unwrap(); // ... (sensor, beacon) } pub fn parse_regex(input: &str) -> impl Iterator<Item = (Pos, Pos)> + '_ input.lines().map(parse_line_regex) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #[macro_use] extern crate lazy_static; 1 2 use regex::Regex; 3 4 lazy_static! { 5 static ref LINE_REGEX: Regex = Regex::new(r"Sensor at x=(?P<x1>[-]?\d 6 .unwrap(); 7 } 8 9 fn parse_line_regex(line: &str) -> (Pos, Pos) { 10 let captures = LINE_REGEX.captures(line).unwrap(); 11 12 // ... 13 (sensor, beacon) 14 } 15 16 pub fn parse_regex(input: &str) -> impl Iterator<Item = (Pos, Pos)> + '_ 17 input.lines().map(parse_line_regex) 18 } 19 lazy_static! { static ref LINE_REGEX: Regex = Regex::new(r"Sensor at x=(?P<x1>[-]?\d .unwrap(); } #[macro_use] 1 extern crate lazy_static; 2 use regex::Regex; 3 4 5 6 7 8 9 fn parse_line_regex(line: &str) -> (Pos, Pos) { 10 let captures = LINE_REGEX.captures(line).unwrap(); 11 12 // ... 13 (sensor, beacon) 14 } 15 16 pub fn parse_regex(input: &str) -> impl Iterator<Item = (Pos, Pos)> + '_ 17 input.lines().map(parse_line_regex) 18 } 19 let captures = LINE_REGEX.captures(line).unwrap(); #[macro_use] 1 extern crate lazy_static; 2 use regex::Regex; 3 4 lazy_static! { 5 static ref LINE_REGEX: Regex = Regex::new(r"Sensor at x=(?P<x1>[-]?\d 6 .unwrap(); 7 } 8 9 fn parse_line_regex(line: &str) -> (Pos, Pos) { 10 11 12 // ... 13 (sensor, beacon) 14 } 15 16 pub fn parse_regex(input: &str) -> impl Iterator<Item = (Pos, Pos)> + '_ 17 input.lines().map(parse_line_regex) 18 } 19 #[macro_use] extern crate lazy_static; use regex::Regex; lazy_static! { static ref LINE_REGEX: Regex = Regex::new(r"Sensor at x=(?P<x1>[-]?\d .unwrap(); } fn parse_line_regex(line: &str) -> (Pos, Pos) { let captures = LINE_REGEX.captures(line).unwrap(); // ... (sensor, beacon) } pub fn parse_regex(input: &str) -> impl Iterator<Item = (Pos, Pos)> + '_ input.lines().map(parse_line_regex) } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 loige 96
  73. 🤷 BTW, should I tell you that when you solve

    a problem with a Regex... BLAH BLAH BLAH?! loige 97
  74. fn parse_i64(input: &str) -> IResult<&str, i64> { let (input, sign)

    = opt(tag("-"))(input)?; let (input, value) = digit1(input)?; let mut value = value.parse::<i64>().unwrap(); if sign.is_some() { value *= -1; } Ok((input, value)) } 1 2 3 4 5 6 7 8 9 fn parse_i64(input: &str) -> IResult<&str, i64> { } 1 let (input, sign) = opt(tag("-"))(input)?; 2 let (input, value) = digit1(input)?; 3 let mut value = value.parse::<i64>().unwrap(); 4 if sign.is_some() { 5 value *= -1; 6 } 7 Ok((input, value)) 8 9 let (input, sign) = opt(tag("-"))(input)?; fn parse_i64(input: &str) -> IResult<&str, i64> { 1 2 let (input, value) = digit1(input)?; 3 let mut value = value.parse::<i64>().unwrap(); 4 if sign.is_some() { 5 value *= -1; 6 } 7 Ok((input, value)) 8 } 9 let (input, value) = digit1(input)?; fn parse_i64(input: &str) -> IResult<&str, i64> { 1 let (input, sign) = opt(tag("-"))(input)?; 2 3 let mut value = value.parse::<i64>().unwrap(); 4 if sign.is_some() { 5 value *= -1; 6 } 7 Ok((input, value)) 8 } 9 let mut value = value.parse::<i64>().unwrap(); if sign.is_some() { value *= -1; } fn parse_i64(input: &str) -> IResult<&str, i64> { 1 let (input, sign) = opt(tag("-"))(input)?; 2 let (input, value) = digit1(input)?; 3 4 5 6 7 Ok((input, value)) 8 } 9 Ok((input, value)) fn parse_i64(input: &str) -> IResult<&str, i64> { 1 let (input, sign) = opt(tag("-"))(input)?; 2 let (input, value) = digit1(input)?; 3 let mut value = value.parse::<i64>().unwrap(); 4 if sign.is_some() { 5 value *= -1; 6 } 7 8 } 9 fn parse_i64(input: &str) -> IResult<&str, i64> { let (input, sign) = opt(tag("-"))(input)?; let (input, value) = digit1(input)?; let mut value = value.parse::<i64>().unwrap(); if sign.is_some() { value *= -1; } Ok((input, value)) } 1 2 3 4 5 6 7 8 9 loige 99
  75. fn parse_line(input: &str) -> IResult<&str, (Pos, Pos)> { let (input,

    (s_x, s_y, b_x, b_y)) = all_consuming(tuple(( preceded(tag("Sensor at x="), parse_i64), preceded(tag(", y="), parse_i64), preceded(tag(": closest beacon is at x="), parse_i64), preceded(tag(", y="), parse_i64), )))(input)?; let p1 = Pos { x: s_x, y: s_y }; let p2 = Pos { x: b_x, y: b_y }; Ok((input, (p1, p2))) } 1 2 3 4 5 6 7 8 9 10 11 fn parse_line(input: &str) -> IResult<&str, (Pos, Pos)> { } 1 let (input, (s_x, s_y, b_x, b_y)) = all_consuming(tuple(( 2 preceded(tag("Sensor at x="), parse_i64), 3 preceded(tag(", y="), parse_i64), 4 preceded(tag(": closest beacon is at x="), parse_i64), 5 preceded(tag(", y="), parse_i64), 6 )))(input)?; 7 let p1 = Pos { x: s_x, y: s_y }; 8 let p2 = Pos { x: b_x, y: b_y }; 9 Ok((input, (p1, p2))) 10 11 let (input, (s_x, s_y, b_x, b_y)) = all_consuming(tuple(( preceded(tag("Sensor at x="), parse_i64), preceded(tag(", y="), parse_i64), preceded(tag(": closest beacon is at x="), parse_i64), preceded(tag(", y="), parse_i64), )))(input)?; fn parse_line(input: &str) -> IResult<&str, (Pos, Pos)> { 1 2 3 4 5 6 7 let p1 = Pos { x: s_x, y: s_y }; 8 let p2 = Pos { x: b_x, y: b_y }; 9 Ok((input, (p1, p2))) 10 } 11 let p1 = Pos { x: s_x, y: s_y }; let p2 = Pos { x: b_x, y: b_y }; fn parse_line(input: &str) -> IResult<&str, (Pos, Pos)> { 1 let (input, (s_x, s_y, b_x, b_y)) = all_consuming(tuple(( 2 preceded(tag("Sensor at x="), parse_i64), 3 preceded(tag(", y="), parse_i64), 4 preceded(tag(": closest beacon is at x="), parse_i64), 5 preceded(tag(", y="), parse_i64), 6 )))(input)?; 7 8 9 Ok((input, (p1, p2))) 10 } 11 Ok((input, (p1, p2))) fn parse_line(input: &str) -> IResult<&str, (Pos, Pos)> { 1 let (input, (s_x, s_y, b_x, b_y)) = all_consuming(tuple(( 2 preceded(tag("Sensor at x="), parse_i64), 3 preceded(tag(", y="), parse_i64), 4 preceded(tag(": closest beacon is at x="), parse_i64), 5 preceded(tag(", y="), parse_i64), 6 )))(input)?; 7 let p1 = Pos { x: s_x, y: s_y }; 8 let p2 = Pos { x: b_x, y: b_y }; 9 10 } 11 fn parse_line(input: &str) -> IResult<&str, (Pos, Pos)> { let (input, (s_x, s_y, b_x, b_y)) = all_consuming(tuple(( preceded(tag("Sensor at x="), parse_i64), preceded(tag(", y="), parse_i64), preceded(tag(": closest beacon is at x="), parse_i64), preceded(tag(", y="), parse_i64), )))(input)?; let p1 = Pos { x: s_x, y: s_y }; let p2 = Pos { x: b_x, y: b_y }; Ok((input, (p1, p2))) } 1 2 3 4 5 6 7 8 9 10 11 loige 100
  76. Which one do you think is faster? 🧐 loige regex

    regex_lazy nom 1. 2. 3. 3063.9 µs 9.3 µs 1.8 µs ⭐ +170117% +417% 103
  77. The Iterator & the FromIterator traits Destructuring with if let

    Some(x) / while let Some(x)... Powerful pattern-matching syntax and the matches!() macro Newtype pattern + Deref & DerefMut trait The Display & Debug traits unreachable!() & todo!() macros defaultdict a-la-python using HashMap and the entry API Copy On Write (CoW) Helper methods of the Result and the Option types I would have also loved to tell you about... 🤯 104
  78. Started with a very imperative style and ended up with

    a more functional style "if you look back at your code from 2 years ago and you are not ashamed you are not growing" Noticed that rust has been improving a lot in these 3 years Often needed helpers but they were in nightly (Vec::retain) Rust Analyser & Clippy have been suggesting new improvements over time! Rust is fantastic for Advent of Code! 🦀 In conclusion... 105
  79. Huge thanks to , , Cover photo by on @gbinside

    @AlleviTommaso @giufus Redaviqui Davilli Unsplash TNX loige nodejsdp.link Sorry, I have a contractual obligation to put this here 😛 107