Rock, Paper, Scissors... and Traits | Advent of Code 2022 Day 2

  Рет қаралды 10,647

chris biscardi

chris biscardi

Күн бұрын

Пікірлер: 59
@bustamove361
@bustamove361 2 жыл бұрын
I'm so happy you are doing AoC. I decided to try it in Rust this year (previous years I used Python) and it's great for me to see your videos after I've done my solution so I can refactor my code to be more Rust-idiomatic. Thanks for taking the time. I'll be learning a lot from following along.
@tobiasgraf5246
@tobiasgraf5246 2 жыл бұрын
As already said on the first video. Same for me, keep on with the series. It helps so much when I'm finished coding, and your video pops up short after. I can reflect on my own implementation while watching your videos 👍🤗
@WanderWeird
@WanderWeird 2 жыл бұрын
The docs. for PartialOrd state that an implementation must satisfy a transitivity rule: a < b and b < c implies that a < c. As such, it is not really correct to use PartialOrd for Rock, Paper, Scissors.
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
mm yeah, I think you're right. This would be a trait implementation that was surprising if it were shipped in a production application. Perhaps I should've used an iter.cycle in the video instead, or just left it to match 🤔
@BlackSharkfr
@BlackSharkfr 2 жыл бұрын
​@@chrisbiscardi This and using the enum coercion is just adding complexity where it's not needed. But you did it just for showing off cool stuff.
@ltsSmitty
@ltsSmitty 2 жыл бұрын
I'm doing these in TS each morning and am really enjoying watching these in rust. I know nothing of rust (yet) but I hope you keep going all through advent!
@perc-ai
@perc-ai 2 жыл бұрын
Hey man a lot of us are moving away from TS and getting into Rust. I can only say amazing things about Rust
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
@@perc-ai Rust and TS also work very well together via tools like napi-rs or wasm!
@tenthlegionstudios1343
@tenthlegionstudios1343 Жыл бұрын
I appreciate you actually implementing the partial order trait. This is actually a great series for learning Rust. I have finished the Rust book and am going a few other books/projects. But going through advent of code is one of the best ways to learn. Thanks!
@MasterHigure
@MasterHigure 2 жыл бұрын
Technically, you are required to ensure that the ordering of PartialOrd is transitive. The compiler doesn't check it for you, though, which is nice for hacky solutions on a type that will never be used in another project.
@valhalla_dev
@valhalla_dev 2 жыл бұрын
lol this is so much more graceful (even if complex) than my "death by if-statements" solution. I'm using AoC to learn Rust better, and you've been a big part of that journey as well. Good luck!
@gareth2021
@gareth2021 2 жыл бұрын
for me rusts powerful match syntax worked great, easy copy pasting xd
@valhalla_dev
@valhalla_dev 2 жыл бұрын
@@gareth2021 See the problem is that I'm still so new at Rust that I'm writing it like Python. I didn't use any of the great features Rust has, like the match syntax that Chris shows later in the video, just the if(a == b) type syntax. AoC is teaching me some super powerful lessons on a nightly basis. Today's lessons were: - Read the prompt carefully (got X = loss, Z = win mixed up) - Write Rust code, not Python code in Rust - Use templated code (reading from a text file and splitting on lines, messed up the syntax on that several times costing me precious minutes)
@markday3145
@markday3145 2 жыл бұрын
@@gareth2021 Yes, this was definitely a good use case for match. I did a split(' ') on the lines, and then matched on a 2-tuple of &str. If I were to do it over again, I think I'd probably just match on the entire line since there are only 9 possibilities (I ended up listing all 9 possibilities for part 2 to figure out why my shape had to be).
@cristobaljavier
@cristobaljavier 2 жыл бұрын
It's so interesting to see different ways to solve the challenge as I'm not focusing so much on speed but more on learning in my solutions, and I'm learning a lot here, thanks for sharing.
@peter9477
@peter9477 2 жыл бұрын
I meant to do AoC (first year) but it turns out my daily life poses enough significant programming challenges that I haven't had a chance even to start. Fortunately I bookmarked this vid on day 1 and I guess I'll learn some more Rust vicariously. Thanks Chris!
@ArgoIo
@ArgoIo 2 жыл бұрын
I really enjoy this series of videos. Though I'm late to the party, I really enjoy working through these problems. I solved this one by calculating a table for the scores, storing it in a HashMap and use it to map over the input.
@adamglass2599
@adamglass2599 2 жыл бұрын
it's actually a great demo of the AoC conundrum -- you're rarely sure which tradeoffs to make relative to developer efficiency, complexity, performance, learning value, etc. do you use enums, will the input be interpreted the same way in part 2, is part 2 going to involve shooting for a specific score, etc. You choose a set of tradeoffs and part2 sometimes goes your way and sometimes not. Sometimes i go back and rewrite the solutions for simplicity or clarity with full hindsight.
@aranasaurus
@aranasaurus 2 жыл бұрын
Thanks again for these videos, they are such a huge help! As I was doing it last night I _wanted_ to use some kind of Comparison based approach but wasn't sure how to do it. So I ended up just doing matches inline. It's great to see how this way works. Looking forward to seeing how our solutions differ as the problems get more difficult as they always do.
@kentbowling7513
@kentbowling7513 2 жыл бұрын
Another possibly way to maybe "complete the loop" on the ordering is possibly adding 1 to the second value (other) when you coerce it into a u8, then mod 4 it. This will cause a "Rock" to have a value of 0 when it's the 2nd (other). It's probably harder to read, but less control flow blocks etc.
@echobucket
@echobucket 2 жыл бұрын
I tried making enums for this several different ways, and couldn't figure out how to make it work. Seeing your FromStr trait was an eye opener for me.
@samuelhurel6402
@samuelhurel6402 2 жыл бұрын
Using an Outcome enum made things a lot simpler to me when I did it. Great vid tho, I'll keep watching your videos after completion, always interesting to see how other people are tackling the problem
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
yeah! An outcome enum is a great idea. I avoided it because I felt like I spent my complexity budget for the video in part 1 😅
@AceofSpades5757
@AceofSpades5757 2 жыл бұрын
When rushing to finish this one, I too made the rock beats scissors, etc. more complex than it should have been but I didn't know how to do it any better.
@BlackSharkfr
@BlackSharkfr 2 жыл бұрын
I find matching on moves easier. And you can also use the powerful match syntax to simplify the work : match (their_move, your_move) { (Move::Paper, Move::Scissors) | (Move::Rock, Move::Paper) | (Move::Scissors, Move::Rock) => 6, // Win ! _ if their_move == your_move => 3, // Draw ! _ => 0, // Loose ! }
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
yeah, taking advantage of the multiple match syntax is a great way to group similar cases and cut down the 9 lines!
@felixst-gelais6722
@felixst-gelais6722 2 жыл бұрын
i love comparing my answers with u! we did pretty much the same thing which i thought was clunky but i dont feel so bad anymore :,)
@dj-maxus
@dj-maxus Жыл бұрын
Thank you for your awesome videos! Your channel really helps on my path of learning Rust. I was wondering how do you organize your windows this way? Is this some tool which helps you conveniently adjust multiple windows at once?
@chrisbiscardi
@chrisbiscardi Жыл бұрын
Glad you're enjoying the videos! I use yabai on macos for window management
@artemivasyuk1699
@artemivasyuk1699 2 жыл бұрын
Enums with numbers was a cool thing
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
The numbers are actually there by default too! But it starts at 0, which is why I set them up manually.
@amiganer681130
@amiganer681130 2 жыл бұрын
I did it completly different (in Rust). Here we can see more auf the "Rust Way".
@ReedoTV
@ReedoTV 2 жыл бұрын
I started almost exactly the same as you with a Move enum and a from impl. Then I got lazy and just did a match on the 9 possible line strings, returning the score lol.
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
That's totally in the spirit of aoc! They're puzzles to have fun with so be sure to have fun!
@gimmypharel
@gimmypharel 2 жыл бұрын
Whats the window tiling manager he uses?
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
It's yabai on macos. I go over my setup here: kzbin.info/www/bejne/l6GoiaCAhZqrrtk
@gimmypharel
@gimmypharel 2 жыл бұрын
@@chrisbiscardi thanks!
@awnion
@awnion 2 жыл бұрын
AoC Enterprise edition TM on Rust 😅 GJ!
@amoghrijal
@amoghrijal 2 жыл бұрын
awesome!!!!!! thankyou!!
@dealloc
@dealloc 2 жыл бұрын
It's validating that my implementation (which is very similar to yours, again, using traits) wasn't totally out there, although I still feel I was overly complicating the solution, compared to the simplicity of the challenge.
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
Yeah definitely. Although Advent of code for me is more about experimentation and pushing the corners of the language I use less often. I match all the time, and I implement partialord manually basically never. The questions can always be done in a competitive style, (less code/structure, more tricks, pattern matching solutions) but that's not how I find it fun.
@dealloc
@dealloc 2 жыл бұрын
​@@chrisbiscardi Absolutely, I dont want to code golf it. My goal with these exercises is to become more familiar with Rust's language features and higher level abstractions.
@valeth6472
@valeth6472 2 жыл бұрын
My solution is quite similar, I did use a dedicated RoundResult enum though instead of reusing Ordering. Also didn't know that you can do "as " on enum variants, I think I remember trying that in the past and it didn't work, could be wrong though.
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
yeah the as cast is a neat trick but in hindsight I probably should've used an impl like this instead, which feels less "tricky". Hard to think of everything when I'm recording live though 😅 ``` impl Move { fn score(&self) -> u32 { match self { Rock => 1, Paper => 2, Scissors => 3 } } } ```
@jamese.spivak4170
@jamese.spivak4170 2 жыл бұрын
meh, so many possible ways to implement this, but I like how you did it, even if it was technically a tiny bit more convoluted because I feel like in a real/larger program you would want to separate the logic into the trait like you did
@Neph0
@Neph0 2 жыл бұрын
I think `matches` were a better tool for today's exercise, great video nonetheless.
@yaksher
@yaksher Жыл бұрын
It's funny because while the implementation demonstrating traits and stuff is neat, in this case, you would probably have been better off just writing a single match statement on strings with 9 arms lmao
@glorkspangle
@glorkspangle 2 жыл бұрын
Abuse of PartialOrd: Rock/Paper/Scissors do not form a partial order (the relation is not transitive). Interesting to see the Rust though.
@avinashthakur80
@avinashthakur80 2 жыл бұрын
I also tried it in Rust, but you're writing too much of code. Which is good for big projects, but I didn't since it's small project
@verified_tinker1818
@verified_tinker1818 2 жыл бұрын
Thanks for the video! One thing I'd change is add Itertools and use `collect_tuple()` instead of indexing moves, like so: ``` let (opponents, yours) = line .split(' ') .map(|s| s.parse().unwrap()) .collect_tuple() .unwrap(); ``` Functionally, it changes nothing, and perhaps it's even a tad slower, _and_ the extra `unwrap()` call is unwieldy, but indexing feels so inelegant to me. In Part 2, I created an `Outcome` enum and matched it with the opponent's hand to decide my own: ``` let (opponents, outcome) = line.split(' ').collect_tuple().unwrap(); let outcome: Outcome = outcome.parse().unwrap(); let opponents: Hand = opponents.parse().unwrap(); let yours = match (outcome, opponents) { (Outcome::Defeat, Hand::Scissors) | (Outcome::Draw, Hand::Paper) | (Outcome::Victory, Hand::Rock) => Hand::Paper, (Outcome::Defeat, Hand::Rock) | (Outcome::Draw, Hand::Scissors) | (Outcome::Victory, Hand::Paper) => Hand::Scissors, (Outcome::Defeat, Hand::Paper) | (Outcome::Draw, Hand::Rock) | (Outcome::Victory, Hand::Scissors) => Hand::Rock, }; ``` IMO, it's a bit simpler this way, though the flood of unwraps is painful.
@chrisbiscardi
@chrisbiscardi 2 жыл бұрын
true, but I haven't pulled in Itertools yet, so I don't have access to collect_tuple here.
@CuriousSpy
@CuriousSpy 2 жыл бұрын
about your PartialCmp. Try to do match (self, other) { (Move::A, Move::B) => {} }. A lot cleaner
@SighAme
@SighAme 2 жыл бұрын
Great 18:42, I made something similar: pub fn part1(data: &str) -> u32 { data.split(' ') .map(|round| -> u32 { let mut round = round.chars(); let opponent = Move::new(round.next()); let you = Move::new(round.nth(1)); match (opponent, you) { (Rock, Rock) => Rock + Draw, (Rock, Paper) => Paper + Win, (Rock, Scissors) => Scissors + Lose, (Paper, Rock) => Rock + Lose, (Paper, Paper) => Paper + Draw, (Paper, Scissors) => Scissors + Win, (Scissors, Rock) => Rock + Win, (Scissors, Paper) => Paper + Lose, (Scissors, Scissors) => Scissors + Draw, } }) .sum() }
@a.l.i.c.e6227
@a.l.i.c.e6227 2 жыл бұрын
I like your code, it's kinda similar to my code too XD
@perc-ai
@perc-ai 2 жыл бұрын
Who this is beautiful code. I did nearly the same but with if statements.
@perc-ai
@perc-ai 2 жыл бұрын
@@a.l.i.c.e6227 four gold stars so far 😊
@tommymalm
@tommymalm 2 жыл бұрын
With some math, tho unreadable for most pub fn main() { println!( "{}", include_bytes!("../input.txt") .split(|b| *b == b' ') .map(|l| ((l[0] - b'A') as i16, (l[2] - b'X') as i16,)) .map(|(a, b)| 1 + b + 3 * (1 + b - a).rem_euclid(3)) .sum::(), ); }
@narigoncs
@narigoncs 2 жыл бұрын
Just wanted to mention that you can also easily calculate the winning like this: fn get_winning(m: Move) -> Move { ((m as u32 % 3) + 1).into() } and then you implement From for Move!
@narigoncs
@narigoncs 2 жыл бұрын
Nevermind. I just now understood, that's pretty much what the partial_cmp does
Enabling Nightly features in Rust | Advent of Code 2022 Day 03
32:55
Summing numbers with Iterators in Rust | Advent of Code 2022 Day 1
16:46
Air Sigma Girl #sigma
0:32
Jin and Hattie
Рет қаралды 45 МЛН
Vampire SUCKS Human Energy 🧛🏻‍♂️🪫 (ft. @StevenHe )
0:34
Alan Chikin Chow
Рет қаралды 138 МЛН
Sigma girl VS Sigma Error girl 2  #shorts #sigma
0:27
Jin and Hattie
Рет қаралды 124 МЛН
Generic Traits, Impls, and Slices in Rustlang
18:05
chris biscardi
Рет қаралды 11 М.
Parsing strings with nom | Advent of Code 2022 Day 04
30:48
chris biscardi
Рет қаралды 11 М.
Advent of Code 2022 - Day 2
7:21
Jonathan Paulson
Рет қаралды 9 М.
The Dome Paradox: A Loophole in Newton's Laws
22:59
Up and Atom
Рет қаралды 272 М.
How C++ took a turn for the worse
5:03
Code Persist
Рет қаралды 331 М.
How to read complicated Rust types
20:17
chris biscardi
Рет қаралды 55 М.
Learning Rust the wrong way - Ólafur Waage - NDC TechTown 2022
51:54
NDC Conferences
Рет қаралды 110 М.
Why JavaScript Devs are Switching to Rust in 2024
10:35
warpdotdev
Рет қаралды 263 М.