diff --git a/notes/anagram.md b/notes/anagram.md index 1d36a11..51af440 100644 --- a/notes/anagram.md +++ b/notes/anagram.md @@ -10,26 +10,31 @@ I benchmarked a few solutions. The results for this solution were slower than expected. This solution: + ```rust test test_multiple_anagrams ... bench: 10,408 ns/iter (+/- 1,640) ``` A solution using sort and HashSet: + ```rust test test_multiple_anagrams ... bench: 3,025 ns/iter (+/- 283) ``` A solution using sort without HashMap: + ```rust test test_multiple_anagrams ... bench: 3,296 ns/iter (+/- 216) ``` A solution using unicase and lexical-sort with a HashSet: + ```rust test test_multiple_anagrams ... bench: 7,256 ns/iter (+/- 547) ``` A solution using no sort with a HashMap in a fold: + ```rust test test_multiple_anagrams ... bench: 5,680 ns/iter (+/- 290) ``` diff --git a/notes/armstrong-numbers.md b/notes/armstrong-numbers.md index ba30774..2ef39a3 100644 --- a/notes/armstrong-numbers.md +++ b/notes/armstrong-numbers.md @@ -1,6 +1,6 @@ Congratulations on passing all the tests! -- I like this solution uses `div_euclid`. + * I like this solution uses `div_euclid`. I don't benchmark this exercise, but this solution seems to be performant. diff --git a/notes/atbash-cypher.md b/notes/atbash-cypher.md index e185169..59a11ec 100644 --- a/notes/atbash-cypher.md +++ b/notes/atbash-cypher.md @@ -1,19 +1,15 @@ Congratulations on passing all the tests! -- I like this solution uses iterators. - -- I like this solution uses a macro and includes a test for it. - -- I like this approach uses iterators and match expressions. - -- I like this approach uses an `reverse` function instead of doing comparisons - with collections such as a HashMap, Vector of tuples, or arrays. - -- I like the use of constants. + * I like this solution uses iterators. + * I like this solution uses a macro and includes a test for it. + * I like this approach uses iterators and match expressions. + * I like this approach uses an `reverse` function instead of doing comparisons + with collections such as a HashMap, Vector of tuples, or arrays. + * I like the use of constants. A quibble is that instead of always adding 1 here -``` +```rust (elem as u8 - A_ASCII) as i32 + 1) ``` diff --git a/notes/beer-song.md b/notes/beer-song.md index ba71b64..f71b9d9 100644 --- a/notes/beer-song.md +++ b/notes/beer-song.md @@ -1,15 +1,17 @@ Congratulations on passing all the tests! -- I like this solution is readable. + * I like this solution is readable. + * I like the use of: -- I like the use of -```rust -(end..=start) -``` -instead of -```rust -(end..start + 1) -``` + ```rust + (end..=start) + ``` + + instead of: + + ```rust + (end..start + 1) + ``` If you cared to, for a further challenge you might try to convert the if expressions into a [match diff --git a/notes/benchmark.md b/notes/benchmark.md index 1cb2977..bcaad88 100644 --- a/notes/benchmark.md +++ b/notes/benchmark.md @@ -11,24 +11,24 @@ extern crate test; use test::Bencher; ``` -- For the test you want to benchmark, replace #[test] with #[bench]. -- If the test is marked #[ignore], delete #[ignore] -- Pass in the variable `b: &mut Bencher`. -- Modify the line calling `assert!` to call the function in a closure inside a - call to b.iter(). -- I use rust analyzer in Vim, VSCode or CLion, which gives me a couple links to - run the benchmark or to run the code in Debug. -- Example below is from Sublist: + * For the test you want to benchmark, replace #[test] with #[bench]. + * If the test is marked #[ignore], delete #[ignore] + * Pass in the variable `b: &mut Bencher`. + * Modify the line calling `assert!` to call the function in a closure inside a + call to b.iter(). + * I use rust analyzer in Vim, VSCode or CLion, which gives me a couple links to + run the benchmark or to run the code in Debug. + * Example below is from Sublist: -```rust -#[bench] -fn huge_sublist_not_in_huge_list(b: &mut Bencher) { - let v1: Vec = (10..1_000_001).collect(); - let v2: Vec = (1..1_000_000).collect(); - - b.iter(|| sublist(&v1, &v2)); -} -``` + ```rust + #[bench] + fn huge_sublist_not_in_huge_list(b: &mut Bencher) { + let v1: Vec = (10..1_000_001).collect(); + let v2: Vec = (1..1_000_000).collect(); + + b.iter(|| sublist(&v1, &v2)); + } + ``` Finally compile and run the benchmarks using `cargo +nightly bench`. diff --git a/notes/clock.md b/notes/clock.md index dc85e93..fc1fad5 100644 --- a/notes/clock.md +++ b/notes/clock.md @@ -1,14 +1,11 @@ Congratulations on passing all the tests! -- I like the use of constants. - -- I like that `PartialEq` was derived instead of implementing it manually. - -- I like the use of `{:02}:{:02}` instead of calculating the leading zero manually. - -- I like the use of `rem_euclid`. - -- I like that Clock only stores minutes. + * I like the use of constants. + * I like that `PartialEq` was derived instead of implementing it manually. + * I like the use of `{:02}:{:02}` instead of calculating the leading zero + manually. + * I like the use of `rem_euclid`. + * I like that Clock only stores minutes. Something to consider is how the logic may possibly be simplified by storing only minutes in the Clock struct. diff --git a/notes/forth.md b/notes/forth.md index 62a99c0..3579bc9 100644 --- a/notes/forth.md +++ b/notes/forth.md @@ -1,12 +1,9 @@ Congratulations on passing all the tests! -- I like the Operation enum. - -- I like the use of match statements. - -- I like the use of comments - -- I like the code is broken up into functions instead of being one big blob. + * I like the Operation enum. + * I like the use of match statements. + * I like the use of comments + * I like the code is broken up into functions instead of being one big blob. If you care to, you may try getting it to pass another test of my own which is a bit more complicated. diff --git a/notes/gigasecond.md b/notes/gigasecond.md index 6a16b48..6f22f35 100644 --- a/notes/gigasecond.md +++ b/notes/gigasecond.md @@ -1,11 +1,10 @@ Congratulations on passing all the tests! -- I like the large numeric is formatted with underscores to be more readable. - -- I like this solution directly adds `Duration` to `start` with the `+` operator. - -- I like the expression is directly returned instead of being set to a binding - and returning the binding or using `return` and a semicolon. + * I like the large numeric is formatted with underscores to be more readable. + * I like this solution directly adds `Duration` to `start` with the `+` + operator. + * I like the expression is directly returned instead of being set to a binding + and returning the binding or using `return` and a semicolon. A minor style point is that usually `rustfmt` will usually put `use` elements in alphabetical order. In larger programs with a lot of `use` statements it can diff --git a/notes/grains.md b/notes/grains.md index feaf361..64384e4 100644 --- a/notes/grains.md +++ b/notes/grains.md @@ -2,12 +2,14 @@ Congratulations on passing all the tests! I benchmarked this solution. It was among the fastest. -This solution +This solution: + ```rust test test_returns_the_total_number_of_grains_on_the_board ... bench: 0 ns/iter (+/- 0) ``` -Here is another 0 nanosecond solution which uses less ceremony +Here is another 0 nanosecond solution which uses less ceremony: + ```rust pub fn square(s: u32) -> u64 { if (s < 1) | (s > 64) { @@ -21,7 +23,8 @@ pub fn total() -> u64 { } ``` -Other solution benchmarks +Other solution benchmarks: + ```rust test test_returns_the_total_number_of_grains_on_the_board ... bench: 0 ns/iter (+/- 0) test test_returns_the_total_number_of_grains_on_the_board ... bench: 224 ns/iter (+/- 32) diff --git a/notes/hamming.md b/notes/hamming.md index deeda19..17d1fcb 100644 --- a/notes/hamming.md +++ b/notes/hamming.md @@ -1,6 +1,6 @@ Congratulations on passing all the tests! -- I like the match on a tuple + * I like the match on a tuple. As formattted, it may be a bit less readable than a maintainer would like to come back to in a few months to modify. diff --git a/notes/high-score.md b/notes/high-score.md index 2e49ec7..3830cfe 100644 --- a/notes/high-score.md +++ b/notes/high-score.md @@ -1,20 +1,20 @@ Congratulations on passing all the tests! -- I like the solution is succinct and readable. + * I like the solution is succinct and readable. + * I like that `personal_best` reuses `personal_top_three`. + * I like that you used a `match` expression. -- I like that `personal_best` reuses `personal_top_three`. - -- I like that you used a `match` expression. - -`personal_top_three` could be handled by the [min](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min) function. +`personal_top_three` could be handled by the +[min](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.min) +function. ```rust - pub fn personal_top_three(&self) -> Vec { - let mut tmp = self.scores.to_vec(); - tmp.sort(); - tmp.reverse(); - tmp[0..min(3, tmp.len())].to_vec() - } +pub fn personal_top_three(&self) -> Vec { + let mut tmp = self.scores.to_vec(); + tmp.sort(); + tmp.reverse(); + tmp[0..min(3, tmp.len())].to_vec() +} ``` `latest` could be a match expression on `scores.is_empty()`, returning `None` @@ -30,12 +30,12 @@ so it also could be `self.scores.last().cloned()`. function. ```rust - pub fn personal_best(&self) -> Option { - match self.nums.iter().max() { - None => None, - Some(val) => Some(*(val)), - } +pub fn personal_best(&self) -> Option { + match self.nums.iter().max() { + None => None, + Some(val) => Some(*(val)), } +} ``` `personal_top_three` could be simplified by the @@ -43,12 +43,12 @@ function. function. ```rust - pub fn personal_top_three(&self) -> Vec { - let mut tmp = self.scores.to_vec(); - tmp.sort(); - tmp.reverse(); - tmp[0..min(3, tmp.len())].to_vec() - } +pub fn personal_top_three(&self) -> Vec { + let mut tmp = self.scores.to_vec(); + tmp.sort(); + tmp.reverse(); + tmp[0..min(3, tmp.len())].to_vec() +} ``` Viewing the community solutions may offer other approaches to this exercise diff --git a/notes/isbn-verifier.md b/notes/isbn-verifier.md index cd742fd..28f2e62 100644 --- a/notes/isbn-verifier.md +++ b/notes/isbn-verifier.md @@ -1,9 +1,7 @@ Congratulations on passing all the tests! -- I like the use of match expressions and iterators. - -- I like that the work is broken up into private helper functions. - -- I like the use of Result. + * I like the use of match expressions and iterators. + * I like that the work is broken up into private helper functions. + * I like the use of `Result`. An idiomatic Rust solution. diff --git a/notes/macros.md b/notes/macros.md index f8aa2c8..6bc0b73 100644 --- a/notes/macros.md +++ b/notes/macros.md @@ -1,11 +1,11 @@ Congratulations on passing all the tests! -I like this solution is well-commented. - -I like that the logic cascades down. This is probably more readable than a more -succinct but perhaps less readable solution, such as + * I like this solution is well-commented. + * I like that the logic cascades down. This is probably more readable than a + more succinct but perhaps less readable solution, such as This is more succinct, but perhaps less readable... + ```rust #[macro_export] macro_rules! hashmap { @@ -17,6 +17,6 @@ macro_rules! hashmap { } ``` -The inside pattern is saying to match one or more of key=>val with zero or one -comma after it. The outside pattern is saying there could be zero or more of the -inside pattern, which takes care of `test_empty`. +The inside pattern is saying to match one or more of `key => val` with zero or +one comma after it. The outside pattern is saying there could be zero or more +of the inside pattern, which takes care of `test_empty`. diff --git a/notes/matching-brackets.md b/notes/matching-brackets.md index bd472c4..1fb0883 100644 --- a/notes/matching-brackets.md +++ b/notes/matching-brackets.md @@ -1,17 +1,14 @@ Congratulations on passing all the tests! -- I like this solution is succinct and readable. - -- I like the use of constants. - -- I like the use of `match`. - -- I like that Some and None are used instead of - [unwrap](https://doc.rust-lang.org/stable/rust-by-example/error/option_unwrap.html). - Not that using `unwrap` is not always wrong, but I like that the code shows a - comfort with using Options instead of immediately dereferencing them. In this - solution it goes to graceful handling of the braces and when there is nothing - left to pop. + * I like this solution is succinct and readable. + * I like the use of constants. + * I like the use of `match`. + * I like that Some and None are used instead of + [unwrap](https://doc.rust-lang.org/stable/rust-by-example/error/option_unwrap.html). + Not that using `unwrap` is not always wrong, but I like that the code shows + a comfort with using Options instead of immediately dereferencing them. In + this solution it goes to graceful handling of the braces and when there is + nothing left to pop. Did you consider using a match in `is_correct_closing_brace`? @@ -32,17 +29,16 @@ Also, since it is a helper function, `is_correct_closing_brace` can be private This: ```rust - if open_brace_stack.len() == 0 { - return true; - } - false - +if open_brace_stack.len() == 0 { + return true; +} +false ``` could be just ```rust - open_brace_stack.len() == 0 +open_brace_stack.len() == 0 ``` There are many idiomatic ways to solve this exercise. For diff --git a/notes/nth-prime.md b/notes/nth-prime.md index 5511062..3be8df8 100644 --- a/notes/nth-prime.md +++ b/notes/nth-prime.md @@ -1,6 +1,6 @@ Congratulations on passing all the tests! -- I like that this solution is succinct and readable. + * I like that this solution is succinct and readable. FYI, I benchmarked `test_big_prime` and got a quite respectable result. Most I've seen are usually ~100 milliseconds. Some have been ~7 milliseconds and diff --git a/notes/nucleotide-count.md b/notes/nucleotide-count.md index 7a46143..707b962 100644 --- a/notes/nucleotide-count.md +++ b/notes/nucleotide-count.md @@ -1,29 +1,29 @@ Congratulations on passing all the tests! -- I like that this solution is succinct and mostly readable. + * I like that this solution is succinct and mostly readable. A quibble is with having `Some` return an `Err` and `None` return an `Ok` being a bit counter-intuitive and it could confuse a future maintainer on the first read. ```rust - match dna.chars().find(|&x| !VALID_NUCLEOTIDES.contains(x)) { - Some(e) => Err(e), - None => Ok(dna.chars().filter(|&x| x == nucleotide).count()), - } +match dna.chars().find(|&x| !VALID_NUCLEOTIDES.contains(x)) { + Some(e) => Err(e), + None => Ok(dna.chars().filter(|&x| x == nucleotide).count()), +} ``` To pick up from how `nucleotide` is validated, I might, if I were that future maintainer, prefer ```rust - for c in dna.chars() { - if !VALID_NUCLEOTIDES.contains(c) { - return Err(c); - } +for c in dna.chars() { + if !VALID_NUCLEOTIDES.contains(c) { + return Err(c); } +} - Ok(dna.chars().filter(|&x| x == nucleotide).count()) +Ok(dna.chars().filter(|&x| x == nucleotide).count()) ``` Viewing the community solutions may offer other approaches to this exercise diff --git a/notes/parallel-letter-frequency.md b/notes/parallel-letter-frequency.md index 834da6f..488c951 100644 --- a/notes/parallel-letter-frequency.md +++ b/notes/parallel-letter-frequency.md @@ -1,10 +1,8 @@ Congratulations on passing all the tests! -- I like this solution uses the std library - -- I like the code is succinct and readable. - -- I like that it is well-commented. + * I like this solution uses the std library + * I like the code is succinct and readable. + * I like that it is well-commented. There is a limitation around threads: they were previously scoped, i.e. could infer data was only used inside a certain context, but they now enforce a diff --git a/notes/poker.md b/notes/poker.md index 92436c9..876d851 100644 --- a/notes/poker.md +++ b/notes/poker.md @@ -1,23 +1,16 @@ Congratulations on passing all the tests! -- I like the use of enums. - -- I like the code is broken up into functions instead of being one big blob. - -- I like the use of the `'a` lifetime specifier and that it was not sprinkled everywhere. - -- I like the derivations of `PartialEq` and `PartialOrd` etc. instead of - manually implementing them. - -- I like the use of custom tests. - -- I like the creation and use of a macro. - -- I like the comments. - -- I like this solution demonstrates a familiarity with itertools. - -- I like the familiarity with `unreachable!` + * I like the use of enums. + * I like the code is broken up into functions instead of being one big blob. + * I like the use of the `'a` lifetime specifier and that it was not sprinkled + everywhere. + * I like the derivations of `PartialEq` and `PartialOrd` etc. instead of + manually implementing them. + * I like the use of custom tests. + * I like the creation and use of a macro. + * I like the comments. + * I like this solution demonstrates a familiarity with itertools. + * I like the familiarity with `unreachable!` As a style issue, perhaps some of the `if` expressions could be `match` expressions, but that's just a quibble. diff --git a/notes/prime-factors.md b/notes/prime-factors.md index a320351..3d02edc 100644 --- a/notes/prime-factors.md +++ b/notes/prime-factors.md @@ -1,6 +1,6 @@ Congratulations on passing all the tests! -I like this solution is succinct and readable. + * I like this solution is succinct and readable. I benchmarked this solution and it is toward the low end of what I've seen so far.. This solution: diff --git a/notes/proverb.md b/notes/proverb.md index 428658e..4b63d17 100644 --- a/notes/proverb.md +++ b/notes/proverb.md @@ -1,20 +1,14 @@ Congratulations on passing all the tests! -- I like that this solution is succinct and readable. - -- I like how this solution uses `windows`. - -- I like how this solution uses `format`. - -- I like the `match` on `first` with `Some` and `None` arms. - -- I like how this solution uses `join`. - -- I like this solution directly returns `verse.join` without using `return` and a semicolon. - -- I like this solution displays an understanding of `peekable`. - -- I like the `match` on `peek` with `Some` and `None` arms. + * I like that this solution is succinct and readable. + * I like how this solution uses `windows`. + * I like how this solution uses `format`. + * I like the `match` on `first` with `Some` and `None` arms. + * I like how this solution uses `join`. + * I like this solution directly returns `verse.join` without using `return` + and a semicolon. + * I like this solution displays an understanding of `peekable`. + * I like the `match` on `peek` with `Some` and `None` arms. Some people use any of [zip](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.zip), diff --git a/notes/raindrops.md b/notes/raindrops.md index f9bbacc..086f88a 100644 --- a/notes/raindrops.md +++ b/notes/raindrops.md @@ -13,7 +13,7 @@ are other ways that a `match` on a `tuple` could work, for example... pub fn raindrops(n: u32) -> String { let output = match (n % 3 == 0, n % 5 == 0, n % 7 == 0) { (true, false, false) => "Pling", -//and so on + // and so on ``` Viewing the community solutions may offer other approaches to this exercise @@ -37,9 +37,7 @@ won't make a String out of &String. You can see that `flatten` creates a reference in the first `flatten` example of two vectors being flattened into a reference to one vector. -``` -Basic usage: - +```rust let data = vec![vec![1, 2, 3, 4], vec![5, 6]]; let flattened = data.into_iter().flatten().collect::>(); assert_eq!(flattened, &[1, 2, 3, 4, 5, 6]); @@ -61,7 +59,7 @@ ceremony/verbosity than needed. I think you're very close to a succinct and readable solution with the array of tuples approach. I think it can be simplified to -``` +```rust [(3, "Pling"), (5, "Plang"), (7, "Plong")] ``` diff --git a/notes/reverse-string.md b/notes/reverse-string.md index 0929d0a..2cb5eee 100644 --- a/notes/reverse-string.md +++ b/notes/reverse-string.md @@ -1,10 +1,10 @@ Congratulations on passing all the tests, including the bonus test! -- I like the use of `unicode-segmentation` + * I like the use of `unicode-segmentation` -This can also be... -```rust +This can also be: +```rust use unicode_segmentation::UnicodeSegmentation; pub fn reverse(input: &str) -> String { diff --git a/notes/rna-transcription.md b/notes/rna-transcription.md index 14d6694..7dc441e 100644 --- a/notes/rna-transcription.md +++ b/notes/rna-transcription.md @@ -1,22 +1,21 @@ Congratulations on passing all the tests! -- I like this solution is succinct and readable, with almost-always informative - names for the bindings. -- I like that you derive the `PartialEq` on `DNA` and `RNA` instead if - implementing it manually. + * I like this solution is succinct and readable, with almost-always + informative names for the bindings. + * I like that you derive the `PartialEq` on `DNA` and `RNA` instead if + implementing it manually. One thing I noticed was: -``` +```rust #[derive(Debug, PartialEq)] pub struct DNA(String); ``` which leaves referring to the struct field as if it were a tuple, for example: -``` +```rust RNA(self.0.chars()... - ``` which makes it less informative, as if it were a magic number, when it doesn't @@ -26,7 +25,7 @@ Something to consider is that the logic needed to create correct values in the `new` methods would be bypassed if someone were to create DNA or RNA as a struct literal, for example: -``` +```rust let my_DNA = DNA {0: "ACGT"}; ``` diff --git a/notes/saddle-points.md b/notes/saddle-points.md index 1a8d10d..22f05b8 100644 --- a/notes/saddle-points.md +++ b/notes/saddle-points.md @@ -6,7 +6,6 @@ This solution: ```rust test identify_all_saddle_points ... bench: 1,559 ns/iter (+/- 87) - ``` Elsewhere: diff --git a/notes/simple-linked-list.md b/notes/simple-linked-list.md index a9685ca..afcdb2d 100644 --- a/notes/simple-linked-list.md +++ b/notes/simple-linked-list.md @@ -1,9 +1,8 @@ Congratulations on passing all the tests! -- I like this solution is succinct and readable. - -- I like this solution uses a `length` field that's updated in `push` and - `pop`, so the `len` function doesn't need to calculate. + * I like this solution is succinct and readable. + * I like this solution uses a `length` field that's updated in `push` and + `pop`, so the `len` function doesn't need to calculate. Since `Option>>` occurs in both the `Node` and `SimpleLinkedList` structs, another approach might be to create a type for that which would be diff --git a/notes/space-age.md b/notes/space-age.md index e8afec2..384c762 100644 --- a/notes/space-age.md +++ b/notes/space-age.md @@ -1,6 +1,6 @@ Congratulations on passing all the tests! -- I like the use of a constant. + * I like the use of a constant. Another approach to consider is how the use of a macro could reduce the boilerplate for this exercise. For instance, [a macro can implement a trait for diff --git a/notes/sum-of-multiples.md b/notes/sum-of-multiples.md index 2313d40..c479664 100644 --- a/notes/sum-of-multiples.md +++ b/notes/sum-of-multiples.md @@ -1,7 +1,7 @@ Congratulations on passing all the tests! -- I like the use of `checked_rem` in a match expression, although it is not - strictly necessary. + * I like the use of `checked_rem` in a match expression, although it is not + strictly necessary. I bench-tested using the arguments for `solutions_using_include_exclude_must_extend_to_cardinality_greater_than_3` and