From 4d142157b954156c91aaa4e5c4c77749388760c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Tue, 20 Sep 2022 23:53:37 -0500 Subject: [PATCH 01/11] nested-parens, benchmarking, and rayon --- assignments/nested-parens.adoc | 228 ++++++++++++++++++ .../solutions/nested-parens/Cargo.lock | 143 +++++++++++ .../solutions/nested-parens/Cargo.toml | 9 + .../solutions/nested-parens/src/main.rs | 97 ++++++++ presentations/index.adoc | 2 + 5 files changed, 479 insertions(+) create mode 100644 assignments/nested-parens.adoc create mode 100644 assignments/solutions/nested-parens/Cargo.lock create mode 100644 assignments/solutions/nested-parens/Cargo.toml create mode 100644 assignments/solutions/nested-parens/src/main.rs diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc new file mode 100644 index 00000000..2c302b87 --- /dev/null +++ b/assignments/nested-parens.adoc @@ -0,0 +1,228 @@ += Exercise: Nested Parens +:source-language: rust + +In this exercise, you will learn + +* how to translate a `for loop` into an `iterator` solution by using `map`, `scan`, and `fold` +* how to setup a benchmarking harness to compare speeds +* how to use `Rayon` to parallelize your iterators! +* how to compress data to get even more speedups + +We will take a famous coding problem and iterate solutions, and measure their performance. +Problem statement: Given a well-formed set of `String` parentheses (one entry per line, all lines in a single text file), + +[source, text, linenums] +---- +()(()) +(())() +(()()) +()()() +((())) + +---- + +find the line where there is the maximum number of nested parentheses. +In the above example, it would be one line `5`, as the maximum nesting level is `3`. + + +In this assignment, you will be given: +* Code to write to a local file the parenthesis inputs (which you can assume are only nested correctly) +* A working solution via a `for loop`, and it will be your task to translate it to an iterator style, and then to benchmark the difference. + + +=== Step 1 +1. Make a new cargo crate with + +[source, bash] +---- +cargo new nested +---- + +and copy the following code in your `src/main.rs`: +2. Complete some of the missing blanks of the code, and make sure `cargo test` passes. + +[source,rust, linenums] +==== +---- +use std::env; +use std::fs::File; +use std::io::prelude::*; + +// Adapted from https://haggainuchi.com/nestedparens.html +fn nested(n: i32) -> Vec { + if n == 0 { + // πŸ‘€ How did I make an empty `String` again? + vec![XXX] + } else { + let mut parens = Vec::new(); + for i in 0..n { + for a in nested(i) { + for b in nested(n - 1 - i) { + parens.push("(".to_owned() + &a + ")" + &b); + } + } + } + parens + } +} + +// You don't need to modify this function - skip it. +fn main() -> std::io::Result<()> { + // Collect an i32 input from CLI + let args: Vec = env::args().collect(); + let input = if args.len() != 1 { + panic!("Please only supply a single i32 as CLI arg. e.g., `cargo run 10`"); + } else { + let num = args[0].parse::().unwrap(); + if num < 1 || 15 < num { + panic!("Please only supply an i32 between 2 and 13 as an arg") + } + num + }; + + // Create a file name + let parens_vec = nested(input); + let name = format!("bench_{}_length_{}.txt", input, parens_vec.len()); + + // Skip if File already exists, + // Otherwise write the Vec into the file, one element per line + let mut file = File::create(name).expect("File already existed!"); + for f in &parens_vec { + writeln!(file, "{}", f)?; + } + Ok(()) +} + + +// `for loop` solution +// On LeetCode, this code obtains: +// Runtime: 1 ms, faster than 53.49% of Rust online submissions for Maximum Nesting Depth of the Parentheses. +// Memory Usage: 2.2 MB, less than 23.26% of Rust online submissions for Maximum Nesting Depth of the Parentheses. + +// Complete the following code! +fn max_depth1(s: String) -> i32 { + let mut max_count = 0; + let mut count = 0; + // πŸ‘€ How did I iterate over each char in a `String` again? πŸ‘€ + for c in s.πŸ‘ΎπŸ‘ΎπŸ‘Ύ { + // πŸ‘€ If I'm careful about how I map each `char` to a value... πŸ‘€ + if c == πŸ‘ΎπŸ‘ΎπŸ‘Ύ { + count += 1; + if count > max_count { + // πŸ‘€ I can propagate that information along the `Vec`! πŸ‘€ + max_count = πŸ‘ΎπŸ‘ΎπŸ‘Ύ; + } + // πŸ‘€ Oh right, gotta catch the other case in the `map` here πŸ‘€ + } else if c == πŸ‘ΎπŸ‘ΎπŸ‘Ύ { + count -= 1; + } + } + max_count +} + +// Make sure this test passes! +#[test] +fn max_depth1_works() { + assert_eq!(nested(10).into_iter().map(max_depth1).max().unwrap(), 10); +} +---- +==== + + +=== Step 2 + +1. Implement `max_depth2`, but now with iterators. Try to do the *smallest* possible change! You can do it with 2 lines of code being changed, but you might have to figure out what the right thing to do by looking at the documentation of `Rust Iterators`, like https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map[`map`] or https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.for_each[`for_each`] + +Click to see a hint! + +[%collapsible] +==== +Replace the top level loop with a `for_each` +[source, rust] +---- +s.chars() + .for_each(|c| { + ... }) +---- +You might have to add a few `})` at the end to compensate for introducing the `|c| {...}` closure. +==== + +2. Implement a test to verify your implementations match. + +Optional! +Compare your `max_depth1` and `max_depth2` implementations to those of the https://leetcode.com/problems/maximum-nesting-depth-of-the-parentheses/[`LeetCode Maximum Nested Parenthesis`] in Rust implementations. + +[%collapsible] +==== + +==== `for loop` solution +On LeetCode, this code obtains: +Runtime: 1 ms, faster than 53.49% of Rust online submissions for Maximum Nesting Depth of the Parentheses. +Memory Usage: 2.2 MB, less than 23.26% of Rust online submissions for Maximum Nesting Depth of the Parentheses. + +==== `iterator` solution, First Pass Attempt! +On LeetCode, this code obtains: +Runtime: 0 ms, faster than 100.00% of Rust online submissions for Maximum Nesting Depth of the Parentheses. +Memory Usage: 1.9 MB, less than 97.67% of Rust online submissions for Maximum Nesting Depth of the Parentheses. +==== + + +=== Step 3 +Use `criterion` to benchmark your implementations! + +1. Before we measure, it's good to step back and hypothesize what might happen: Which version do you think will be fastest? Why? +2. Copy this into your `src/lib.rs`: +[source, rust] +==== +---- +TODO +---- +==== + +And run the benchmark with +[source, bash] +==== +---- +TODO +---- +==== + +3. Write a benchmark harness for `max_depth2`. + +=== Step 4 + +1. Write a `max_depth3` that uses a https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.scan[`scan`] instead of the `count += 1` and `count -= 1` idioms. +2. Write a test and benchmark for `max_depth3`. + + +=== Step 5 +1. Write a `max_depth4` that uses a https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.reduce[`reduce`] instead of the `if maxcount < count {...` +2. Write a test and benchmark for `max_depth4`. + +=== Step6 + +Time to slap on the rocket skates 😎 + +1. Install `rayon` by running +[source, bash] +==== +---- +cargo add rayon +---- +==== + +2. Make a slew of functions that are `max_depth*_par` by replacing the `iter().chars()` with `par_iter().chars()`. +3. Test them for correctness. +4. Benchmark, compare and analyze. + +=== Step 7 + +Optional! + +Investigate any and all of the following questions: +0. Did you remember to set the `--release` flag? Most iterator optimizations will *never* fire if you don't make a release build. +1. Which is your fastest `serial` (non-parallel) version? +2. You may need to restructure your input generation mechanism, but can you find at what input sizes the serial is *faster* than the parallel version? +3. Plot the times to completion vs input sizes in terms of Kilobytes handled. Where do you see `super linear` scaling? Can you estimate your cache sizes based on performance using these chars? Verify your findings with `hwloc` or `lstopo`. +4. Profile the memory usage with `bytehound` or `dhall` for each `max_depth*` method +5. Use `cargo-asm`, `Godbolt` compiler or `llvm-mca` to analyze possible. diff --git a/assignments/solutions/nested-parens/Cargo.lock b/assignments/solutions/nested-parens/Cargo.lock new file mode 100644 index 00000000..c9c7941b --- /dev/null +++ b/assignments/solutions/nested-parens/Cargo.lock @@ -0,0 +1,143 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "once_cell", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "nested-parens" +version = "0.1.0" +dependencies = [ + "rayon", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "once_cell" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" + +[[package]] +name = "rayon" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" diff --git a/assignments/solutions/nested-parens/Cargo.toml b/assignments/solutions/nested-parens/Cargo.toml new file mode 100644 index 00000000..70aba5f8 --- /dev/null +++ b/assignments/solutions/nested-parens/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "nested-parens" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rayon = "1.5.3" diff --git a/assignments/solutions/nested-parens/src/main.rs b/assignments/solutions/nested-parens/src/main.rs new file mode 100644 index 00000000..d455815e --- /dev/null +++ b/assignments/solutions/nested-parens/src/main.rs @@ -0,0 +1,97 @@ +use std::env; +use std::fs::File; +use std::io::prelude::*; + +// Adapted from https://haggainuchi.com/nestedparens.html +fn nested(n: i32) -> Vec { + if n == 0 { + vec![String::new()] + } else { + let mut parens = Vec::new(); + for i in 0..n { + for a in nested(i) { + for b in nested(n - 1 - i) { + parens.push("(".to_owned() + &a + ")" + &b); + } + } + } + parens + } +} + +fn main() -> std::io::Result<()> { + // Collect an i32 input from CLI + let args: Vec = env::args().collect(); + let input = if args.len() != 1 { + panic!("Please only supply a single i32 as CLI arg. e.g., `cargo run 10`"); + } else { + let num = args[0].parse::().unwrap(); + if num < 1 || 15 < num { + panic!("Please only supply an i32 between 2 and 13 as an arg") + } + num + }; + + // Create a file name + let parens_vec = nested(input); + let name = format!("bench_{}_length_{}.txt", &input, &parens_vec.len()); + + // Skip if File already exists, + // Otherwise write the Vec into the file, one element per line + let mut file = File::create(&name).expect("File already existed!"); + for f in &parens_vec { + writeln!(file, "{}", f)?; + } + println!("File {} with length {} written.", &name, &parens_vec.len()); + Ok(()) +} + +// `for loop` solution +// On LeetCode, this code obtains: +// Runtime: 1 ms, faster than 53.49% of Rust online submissions for Maximum Nesting Depth of the Parentheses. +// Memory Usage: 2.2 MB, less than 23.26% of Rust online submissions for Maximum Nesting Depth of the Parentheses. +fn max_depth1(s: String) -> i32 { + let mut max_count = 0; + let mut count = 0; + for c in s.chars() { + if c == '(' { + count += 1; + if count > max_count { + max_count = count; + } + } else if c == ')' { + count -= 1; + } + } + max_count +} + +// `iterator` solution, First Pass Attempt! +// On LeetCode, this code obtains: +// Runtime: 0 ms, faster than 100.00% of Rust online submissions for Maximum Nesting Depth of the Parentheses. +// Memory Usage: 1.9 MB, less than 97.67% of Rust online submissions for Maximum Nesting Depth of the Parentheses. +pub fn max_depth2(s: String) -> i32 { + let mut max_count = 0; + let mut count = 0; + s.chars().for_each(|c| { + if c == '(' { + count += 1; + if count > max_count { + max_count = count; + } + } else if c == ')' { + count -= 1; + }; + }); + max_count +} +#[test] +fn max_depth1_works() { + assert_eq!(nested(10).into_iter().map(max_depth1).max().unwrap(), 10); +} + +#[test] +fn max_depth2_works() { + assert_eq!(nested(10).into_iter().map(max_depth2).max().unwrap(), 10); +} + diff --git a/presentations/index.adoc b/presentations/index.adoc index 56843ce9..993a4d3c 100644 --- a/presentations/index.adoc +++ b/presentations/index.adoc @@ -94,6 +94,8 @@ * link:./assignments/async-channels.html[Async Channels] * link:./assignments/actix.html[Actix Chat using Websockets] +* link:./assignments/nested-parens.html[Nested Parens] + .SemVer trail * link:./assignments/semver_from_file.html[SemVer from file] From 0b78362cd37dfb0a6391cb77014ef33e8378ba86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:47:21 -0500 Subject: [PATCH 02/11] fixup functions, add logic to write file --- .../solutions/nested-parens/bench_3_length_5.txt | 5 +++++ assignments/solutions/nested-parens/src/main.rs | 13 ++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 assignments/solutions/nested-parens/bench_3_length_5.txt diff --git a/assignments/solutions/nested-parens/bench_3_length_5.txt b/assignments/solutions/nested-parens/bench_3_length_5.txt new file mode 100644 index 00000000..f4bc9486 --- /dev/null +++ b/assignments/solutions/nested-parens/bench_3_length_5.txt @@ -0,0 +1,5 @@ +()()() +()(()) +(())() +(()()) +((())) diff --git a/assignments/solutions/nested-parens/src/main.rs b/assignments/solutions/nested-parens/src/main.rs index d455815e..c4f81a92 100644 --- a/assignments/solutions/nested-parens/src/main.rs +++ b/assignments/solutions/nested-parens/src/main.rs @@ -3,6 +3,7 @@ use std::fs::File; use std::io::prelude::*; // Adapted from https://haggainuchi.com/nestedparens.html +// Skip this function, nothing to do. fn nested(n: i32) -> Vec { if n == 0 { vec![String::new()] @@ -22,10 +23,10 @@ fn nested(n: i32) -> Vec { fn main() -> std::io::Result<()> { // Collect an i32 input from CLI let args: Vec = env::args().collect(); - let input = if args.len() != 1 { + let input = if args.len() != 2 { panic!("Please only supply a single i32 as CLI arg. e.g., `cargo run 10`"); } else { - let num = args[0].parse::().unwrap(); + let num = args[1].parse::().unwrap(); if num < 1 || 15 < num { panic!("Please only supply an i32 between 2 and 13 as an arg") } @@ -38,6 +39,9 @@ fn main() -> std::io::Result<()> { // Skip if File already exists, // Otherwise write the Vec into the file, one element per line + if std::path::Path::new(&name).exists() { + panic!("File already exists. Exiting."); + } let mut file = File::create(&name).expect("File already existed!"); for f in &parens_vec { writeln!(file, "{}", f)?; @@ -87,11 +91,14 @@ pub fn max_depth2(s: String) -> i32 { } #[test] fn max_depth1_works() { + assert_eq!(max_depth1(String::from("()()()")), 1); + assert_eq!(max_depth1(String::from("((()))")), 3); assert_eq!(nested(10).into_iter().map(max_depth1).max().unwrap(), 10); } #[test] fn max_depth2_works() { + assert_eq!(max_depth2(String::from("()()()")), 1); + assert_eq!(max_depth2(String::from("((()))")), 3); assert_eq!(nested(10).into_iter().map(max_depth2).max().unwrap(), 10); } - From 9ada1efe7a04d97c9f7e323ae9e5de579023a685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:47:41 -0500 Subject: [PATCH 03/11] Update assignments/nested-parens.adoc Co-authored-by: Jonathan Pallant --- assignments/nested-parens.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index 2c302b87..bb70bc26 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -22,7 +22,7 @@ Problem statement: Given a well-formed set of `String` parentheses (one entry pe ---- find the line where there is the maximum number of nested parentheses. -In the above example, it would be one line `5`, as the maximum nesting level is `3`. +In the above example, it would be on line `5`, as the maximum nesting level is `3`. In this assignment, you will be given: From f7fec51f73084a97a09dc5c466cc1605797769fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:47:58 -0500 Subject: [PATCH 04/11] Update assignments/nested-parens.adoc Co-authored-by: Jonathan Pallant --- assignments/nested-parens.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index bb70bc26..74ad8b27 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -26,7 +26,7 @@ In the above example, it would be on line `5`, as the maximum nesting level is ` In this assignment, you will be given: -* Code to write to a local file the parenthesis inputs (which you can assume are only nested correctly) +* Code to write the input parentheses (which you can assume are always nested correctly) to a local file * A working solution via a `for loop`, and it will be your task to translate it to an iterator style, and then to benchmark the difference. From a44997340b42fc5f74e2b771168c48277400d9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:50:56 -0500 Subject: [PATCH 05/11] Update assignments/nested-parens.adoc Co-authored-by: Christian Poveda <31802960+pvdrz@users.noreply.github.com> --- assignments/nested-parens.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index 74ad8b27..ac62ea39 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -3,7 +3,7 @@ In this exercise, you will learn -* how to translate a `for loop` into an `iterator` solution by using `map`, `scan`, and `fold` +* how to translate code using `for` loops into an code using iterators and the functions `map`, `scan`, and `fold`. * how to setup a benchmarking harness to compare speeds * how to use `Rayon` to parallelize your iterators! * how to compress data to get even more speedups From 5b84c7a05c59ec9715064db5f15c45b85fda2a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:53:14 -0500 Subject: [PATCH 06/11] Update assignments/nested-parens.adoc Co-authored-by: Christian Poveda <31802960+pvdrz@users.noreply.github.com> --- assignments/nested-parens.adoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index ac62ea39..57ebdd8d 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -27,7 +27,10 @@ In the above example, it would be on line `5`, as the maximum nesting level is ` In this assignment, you will be given: * Code to write the input parentheses (which you can assume are always nested correctly) to a local file -* A working solution via a `for loop`, and it will be your task to translate it to an iterator style, and then to benchmark the difference. + +* A working solution using a `for` loop, + +It will be your task to modify this solution to use iterators and benchmark the two solutions === Step 1 From 12a660ed0e1ee83a4245a5c6bcc698f5847c664e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:53:50 -0500 Subject: [PATCH 07/11] Update assignments/nested-parens.adoc Co-authored-by: Christian Poveda <31802960+pvdrz@users.noreply.github.com> --- assignments/nested-parens.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index 57ebdd8d..c1378c7e 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -54,8 +54,7 @@ use std::io::prelude::*; // Adapted from https://haggainuchi.com/nestedparens.html fn nested(n: i32) -> Vec { if n == 0 { - // πŸ‘€ How did I make an empty `String` again? - vec![XXX] + vec![todo!("πŸ‘€ How do I make an empty `String` again?")] } else { let mut parens = Vec::new(); for i in 0..n { From ba6cb96d187d906c501fc8ba16480ef5ec44295a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:54:45 -0500 Subject: [PATCH 08/11] Update assignments/nested-parens.adoc Co-authored-by: Christian Poveda <31802960+pvdrz@users.noreply.github.com> --- assignments/nested-parens.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index c1378c7e..f378a288 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -21,7 +21,7 @@ Problem statement: Given a well-formed set of `String` parentheses (one entry pe ---- -find the line where there is the maximum number of nested parentheses. +find the entry with the maximum nesting level. In the above example, it would be on line `5`, as the maximum nesting level is `3`. From d2732cb6d241e2971b88cc42bbbf09897a6bf82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:54:59 -0500 Subject: [PATCH 09/11] Update assignments/nested-parens.adoc Co-authored-by: Christian Poveda <31802960+pvdrz@users.noreply.github.com> --- assignments/nested-parens.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index f378a288..723ac959 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -38,7 +38,7 @@ It will be your task to modify this solution to use iterators and benchmark the [source, bash] ---- -cargo new nested +cargo new --bin nested ---- and copy the following code in your `src/main.rs`: From 3f1546a50b2311f95d56c79086a419c360d53bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:55:12 -0500 Subject: [PATCH 10/11] Update assignments/nested-parens.adoc Co-authored-by: Christian Poveda <31802960+pvdrz@users.noreply.github.com> --- assignments/nested-parens.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index 723ac959..6f188f2b 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -101,7 +101,7 @@ fn main() -> std::io::Result<()> { // Runtime: 1 ms, faster than 53.49% of Rust online submissions for Maximum Nesting Depth of the Parentheses. // Memory Usage: 2.2 MB, less than 23.26% of Rust online submissions for Maximum Nesting Depth of the Parentheses. -// Complete the following code! +// TODO: Complete the following code! fn max_depth1(s: String) -> i32 { let mut max_count = 0; let mut count = 0; From a99a660f4d618b23157b0d85f499c4055046b9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Raz=20Guzm=C3=A1n=20Macedo?= Date: Wed, 21 Sep 2022 10:55:37 -0500 Subject: [PATCH 11/11] Update assignments/nested-parens.adoc Co-authored-by: Christian Poveda <31802960+pvdrz@users.noreply.github.com> --- assignments/nested-parens.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignments/nested-parens.adoc b/assignments/nested-parens.adoc index 6f188f2b..1f686662 100644 --- a/assignments/nested-parens.adoc +++ b/assignments/nested-parens.adoc @@ -41,7 +41,7 @@ It will be your task to modify this solution to use iterators and benchmark the cargo new --bin nested ---- -and copy the following code in your `src/main.rs`: +and copy the following code to the `src/main.rs` file: 2. Complete some of the missing blanks of the code, and make sure `cargo test` passes. [source,rust, linenums]