Тёмный

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

chris biscardi
Подписаться 30 тыс.
Просмотров 11 тыс.
50% 1

day 02's code: github.com/Chr...
PartialOrd: doc.rust-lang....
FromStr: doc.rust-lang....

Опубликовано:

 

20 окт 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 59   
@bustamove361
@bustamove361 Год назад
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 Год назад
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 Год назад
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 Год назад
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 Год назад
​@@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 Год назад
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 Год назад
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 Год назад
@@perc-ai Rust and TS also work very well together via tools like napi-rs or wasm!
@MasterHigure
@MasterHigure Год назад
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 Год назад
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 Год назад
for me rusts powerful match syntax worked great, easy copy pasting xd
@valhalla_dev
@valhalla_dev Год назад
@@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 Год назад
@@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).
@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!
@adamglass2599
@adamglass2599 Год назад
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 Год назад
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.
@peter9477
@peter9477 Год назад
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 Год назад
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.
@cristobaljavier
@cristobaljavier Год назад
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.
@kentbowling7513
@kentbowling7513 Год назад
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 Год назад
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 Год назад
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 Год назад
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 😅
@felixst-gelais6722
@felixst-gelais6722 Год назад
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 :,)
@BlackSharkfr
@BlackSharkfr Год назад
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 Год назад
yeah, taking advantage of the multiple match syntax is a great way to group similar cases and cut down the 9 lines!
@AceofSpades5757
@AceofSpades5757 Год назад
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.
@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 Год назад
Enums with numbers was a cool thing
@chrisbiscardi
@chrisbiscardi Год назад
The numbers are actually there by default too! But it starts at 0, which is why I set them up manually.
@ReedoTV
@ReedoTV Год назад
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 Год назад
That's totally in the spirit of aoc! They're puzzles to have fun with so be sure to have fun!
@amiganer681130
@amiganer681130 Год назад
I did it completly different (in Rust). Here we can see more auf the "Rust Way".
@valeth6472
@valeth6472 Год назад
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 Год назад
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 Год назад
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
@gimmypharel
@gimmypharel Год назад
Whats the window tiling manager he uses?
@chrisbiscardi
@chrisbiscardi Год назад
It's yabai on macos. I go over my setup here: ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-apEXmJP5xxw.html
@gimmypharel
@gimmypharel Год назад
@@chrisbiscardi thanks!
@amoghrijal
@amoghrijal Год назад
awesome!!!!!! thankyou!!
@dealloc
@dealloc Год назад
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 Год назад
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 Год назад
​@@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.
@awnion
@awnion Год назад
AoC Enterprise edition TM on Rust 😅 GJ!
@Neph0
@Neph0 Год назад
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 Год назад
Abuse of PartialOrd: Rock/Paper/Scissors do not form a partial order (the relation is not transitive). Interesting to see the Rust though.
@verified_tinker1818
@verified_tinker1818 Год назад
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 Год назад
true, but I haven't pulled in Itertools yet, so I don't have access to collect_tuple here.
@avinashthakur80
@avinashthakur80 Год назад
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
@CuriousSpy
@CuriousSpy Год назад
about your PartialCmp. Try to do match (self, other) { (Move::A, Move::B) => {} }. A lot cleaner
@SighAme
@SighAme Год назад
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 Год назад
I like your code, it's kinda similar to my code too XD
@perc-ai
@perc-ai Год назад
Who this is beautiful code. I did nearly the same but with if statements.
@perc-ai
@perc-ai Год назад
@@a.l.i.c.e6227 four gold stars so far 😊
@tommymalm
@tommymalm Год назад
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 Год назад
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 Год назад
Nevermind. I just now understood, that's pretty much what the partial_cmp does
Далее
Parsing strings with nom | Advent of Code 2022 Day 04
30:48
1 Subscriber = 1 Penny
00:17
Просмотров 46 млн
Angry bird PIZZA?
00:20
Просмотров 5 млн
Павел Дедищев - «Как кайф»
42:08
Просмотров 469 тыс.
going fast is about doing less
19:41
Просмотров 173 тыс.
These Problems Made Me A Great Dev
8:12
Просмотров 60 тыс.
Generic Traits, Impls, and Slices in Rustlang
18:05
Просмотров 11 тыс.
My 10 “Clean” Code Principles (Start These Now)
15:12
How C++ took a turn for the worse
5:03
Просмотров 306 тыс.