Slide 1

Slide 1 text

2023-02-15 1

Slide 2

Slide 2 text

2023-02-15 2

Slide 3

Slide 3 text

2023-02-15 3 😅

Slide 4

Slide 4 text

👋 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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

loige podcast awsbites.com How do you write Lambda Functions in Rust? 6

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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`, 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 Future for PollFn where F: FnMut(&mut Context<'_>) -> Poll, { 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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Yeah, but it's not really about tech... loige 10

Slide 11

Slide 11 text

It's about people loige 11

Slide 12

Slide 12 text

It's about people loige @gbinside 12

Slide 13

Slide 13 text

It's about people loige 13

Slide 14

Slide 14 text

🔥 Hot take If you are struggling to learn Rust (or anything else, really)... Find a learning buddy! loige 14

Slide 15

Slide 15 text

Advent of Code . com loige github.com/lmammino/rust-advent 15

Slide 16

Slide 16 text

loige 16

Slide 17

Slide 17 text

loige 17

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

Iterator combinators loige 19

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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::().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::().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::().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::().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::().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::().unwrap(); 8 total += value; 9 10 if total > max { 11 max = total; 12 } 13 } 14 max 15 } 16 let value = line.parse::().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::().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::().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::().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

Slide 22

Slide 22 text

fn combinators(input: &str) -> u64 { input .split("\n\n") .map(|batch| { batch .lines() .map(|line| line.parse::().unwrap()) .sum::() }) .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::().unwrap()) 7 .sum::() 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::().unwrap()) 7 .sum::() 8 9 .max() 10 .unwrap() 11 } 12 batch .lines() .map(|line| line.parse::().unwrap()) .sum::() 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::().unwrap()) 7 .sum::() 8 }) 9 10 11 } 12 fn combinators(input: &str) -> u64 { input .split("\n\n") .map(|batch| { batch .lines() .map(|line| line.parse::().unwrap()) .sum::() }) .max() .unwrap() } 1 2 3 4 5 6 7 8 9 10 11 12 Combinators approach loige 22

Slide 23

Slide 23 text

Nice, but the classic noob version must be much faster, right? 🤔 loige 23

Slide 24

Slide 24 text

⚡ NOT REALLY! loige 24

Slide 25

Slide 25 text

Yeah, but I am sure that iterator combinators are not always flexible enough, right? 🤔 loige 25

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

.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::().unwrap()) 7 .sum::() 8 }) 9 10 .take(3) 11 .sum() 12 } 13 loige 🤷 28

Slide 29

Slide 29 text

But iterator combinators can be "extended" 🤫 loige $ cargo add itertools 29

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

.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::().unwrap()) 9 .sum::() 10 }) 11 12 .rev() 13 .take(3) 14 .sum() 15 } 16 loige 🤩 added by itertools 31

Slide 32

Slide 32 text

But... Do we really want to sort? 😕 loige 32

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

trait TopN { fn top_n(self, n: usize) -> Vec; } 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

Slide 47

Slide 47 text

That's a cool trait indeed... but I am sure we cannot implement it for "all" iterators, right?! 🤷 loige 47

Slide 48

Slide 48 text

Of course, we can! 💪 loige It's called a "blanket implementation". 48

Slide 49

Slide 49 text

impl> TopN for U { fn top_n(self, n: usize) -> Vec { } } 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 for all types U (iterators producing T)! 49

Slide 50

Slide 50 text

impl> TopN for U { fn top_n(self, n: usize) -> Vec { 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> TopN for U { 1 fn top_n(self, n: usize) -> Vec { 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> TopN for U { 1 fn top_n(self, n: usize) -> Vec { 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

Slide 51

Slide 51 text

if value > *top_value { impl> TopN for U { 1 fn top_n(self, n: usize) -> Vec { 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

Slide 52

Slide 52 text

impl> TopN for U { 1 fn top_n(self, n: usize) -> Vec { 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

Slide 53

Slide 53 text

fn combinators_no_sort(input: &str) -> u64 { input .split("\n\n") .map(|batch| { batch .lines() .map(|line| line.parse::().unwrap()) .sum::() }) .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::().unwrap()) 7 .sum::() 8 }) 9 10 11 12 } 13 loige 53

Slide 54

Slide 54 text

.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::().unwrap()) 7 .sum::() 8 }) 9 10 .iter() 11 .sum() 12 } 13 loige 😍 OMG, we added this! 54

Slide 55

Slide 55 text

OK, but you used a Vec there... I heard rustaceans don't like unnecessary allocations, right?! 🤷 loige 55

Slide 56

Slide 56 text

trait Top { fn top(self, n: usize) -> Vec; } impl> Top for U { fn top(self, n: usize) -> Vec { 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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

let mut top = [T;N]; trait Top { 1 fn top(self) -> [T; N]; 2 } 3 4 impl> Top for U { 5 fn top(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige 59

Slide 60

Slide 60 text

let mut top = [Default::default(); N]; trait Top { 1 fn top(self) -> [T; N]; 2 } 3 4 impl> Top for U { 5 fn top(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige 60

Slide 61

Slide 61 text

impl> Top for let mut top = [Default::default(); N]; trait Top { 1 fn top(self) -> [T; N]; 2 } 3 4 5 fn top(self) -> [T; N] { 6 7 // ... 8 top 9 } 10 } 11 loige 61

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

impl> Top for U { let mut top = core::array::from_fn(|_| Default::default()); trait Top { 1 fn top(self) -> [T; N]; 2 } 3 4 5 fn top(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

Slide 65

Slide 65 text

fn combinators_no_sort_const(input: &str) -> u64 { input .split("\n\n") .map(|batch| { batch .lines() .map(|line| line.parse::().unwrap()) .sum::() }) .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::().unwrap()) 7 .sum::() 8 }) 9 10 .iter() 11 .sum() 12 } 13 loige 65

Slide 66

Slide 66 text

.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::().unwrap()) 7 .sum::() 8 }) 9 10 .iter() 11 .sum() 12 } 13 loige Slightly different syntax 🐟 Phew... we did it! 😮 💨 66

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

But let's talk more about const generics, what else can you do with them? loige 69

Slide 70

Slide 70 text

struct Point([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([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([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([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([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([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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

.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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

struct Grid { cells: [[Option; 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 { 1 cells: [[Option; 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 { 1 cells: [[Option; 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 { cells: [[Option; 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

Slide 76

Slide 76 text

Parsing (Ergo, extracting data from text) loige 76

Slide 77

Slide 77 text

mask = 000000000000000000000000000000X1001X mem[42] = 100 mask = 00000000000000000000000000000000X0XX mem[26] = 1 ... y2020 - Day 14: Docking Data loige enum Instr { Mask(String), Mem(u64, u64), } 77

Slide 78

Slide 78 text

use std::str::FromStr; impl FromStr for Instr { type Err = String; fn from_str(s: &str) -> Result { 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 { 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 { } } 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 { 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 { 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 { 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 { 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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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 { 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 { 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 { 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 { 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

Slide 83

Slide 83 text

fn from_str(s: &'a str) -> Result { 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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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 { 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 { 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 { 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 { 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 { } 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 { 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 { 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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

loige89

Slide 90

Slide 90 text

loige 😱 90

Slide 91

Slide 91 text

loige 91

Slide 92

Slide 92 text

loige 92

Slide 93

Slide 93 text

use regex::Regex; fn parse_line_regex(line: &str) -> (Pos, Pos) { let re = Regex::new( r"Sensor at x=(?P[-]?\d+), y=(?P[-]?\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[-]?\d+), y=(?P[-]?\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[-]?\d+), y=(?P[-]?\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[-]?\d+), y=(?P[-]?\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[-]?\d+), y=(?P[-]?\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[-]?\d+), y=(?P[-]?\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[-]?\d+), y=(?P[-]?\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[-]?\d+), y=(?P[-]?\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

Slide 94

Slide 94 text

pub fn parse_regex(input: &str) -> impl Iterator + '_ 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[-]?\d+), y=(?P[-]?\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

Slide 95

Slide 95 text

How can we initialize the regex globally? loige $ cargo add lazy_static 95

Slide 96

Slide 96 text

#[macro_use] extern crate lazy_static; use regex::Regex; lazy_static! { static ref LINE_REGEX: Regex = Regex::new(r"Sensor at x=(?P[-]?\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 + '_ 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[-]?\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 + '_ 17 input.lines().map(parse_line_regex) 18 } 19 lazy_static! { static ref LINE_REGEX: Regex = Regex::new(r"Sensor at x=(?P[-]?\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 + '_ 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[-]?\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 + '_ 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[-]?\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 + '_ 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

Slide 97

Slide 97 text

🤷 BTW, should I tell you that when you solve a problem with a Regex... BLAH BLAH BLAH?! loige 97

Slide 98

Slide 98 text

Ok, let's do proper parsing with nom! 💪 loige $ cargo add nom 98

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

Which one do you think is faster? 🧐 loige regex regex_lazy nom 1. 2. 3. 101

Slide 102

Slide 102 text

Which one do you think is faster? 🧐 loige regex regex_lazy nom 1. 2. 3. 102

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

Photo by on Nathan Dumlao Unsplash loige 106

Slide 107

Slide 107 text

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