From 3c3837c5402b86b9cbfe028f92c70ea489473c63 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Fri, 19 Sep 2025 10:01:45 -0700 Subject: [PATCH 1/3] [Blog] Project Euler in Rust --- resources/blog-styles.css | 9 + resources/default-styles.css | 2 +- sitemap.xml | 3 + src/Blog/posts/20250919-rust-euler.md | 262 ++++++++++++++++++++++++++ tests/data/Home.html | 7 +- tests/data/blog-index.html | 6 +- 6 files changed, 285 insertions(+), 4 deletions(-) create mode 100644 src/Blog/posts/20250919-rust-euler.md diff --git a/resources/blog-styles.css b/resources/blog-styles.css index db5acc1..f6c135c 100644 --- a/resources/blog-styles.css +++ b/resources/blog-styles.css @@ -64,6 +64,15 @@ white-space: nowrap; } +.blog-page--unhighlighted-block pre:not(.pygments-highlighter pre) { + /* Multi-line blocks */ + background-color: #f8f8f8; + + code { + white-space: pre; + } +} + .blog-page--has-toc.content-wrapper { width: 100%; display: grid; diff --git a/resources/default-styles.css b/resources/default-styles.css index 33599db..d66122e 100644 --- a/resources/default-styles.css +++ b/resources/default-styles.css @@ -9,7 +9,7 @@ width: 80%; margin-bottom: calc( var(--footer-elem-height) + 10px ); - p, li, blockquote { + p, li, blockquote, summary { font-size: 18px; } } diff --git a/sitemap.xml b/sitemap.xml index 7fccbfc..ef8ea5a 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -51,4 +51,7 @@ https://scherzer.dev/Blog/20250912-hello-world-rust + + https://scherzer.dev/Blog/20250919-rust-euler + diff --git a/src/Blog/posts/20250919-rust-euler.md b/src/Blog/posts/20250919-rust-euler.md new file mode 100644 index 0000000..ee21df8 --- /dev/null +++ b/src/Blog/posts/20250919-rust-euler.md @@ -0,0 +1,262 @@ +--- +extensions: + footnotes: true + pygments: true +extra-classes: + - blog-page--unhighlighted-block +title: Project Euler in Rust +--- + +# Project Euler in Rust + +Having done the obligatory hello world, I set out to actually code something +useful in Rust. When I learn a new programming language, my go-to source of +coding problems to try and solve in the new language is +[Project Euler][proj-euler], which features hundreds of coding challenges of +various difficulty levels. + +With Rust, I didn't try to solve any new problems, but rather focused on +problems that I had already solved in other languages. That way, I could be +focused on the specifics of working in Rust rather than generally figuring out +how to solve the problem. + +## Starter Problems + +I kicked things off with [Problem #1][proj-euler-prob-1], which asks for the +sum of all natural numbers below 1000 that are multiples of 3 or 5 (or both). +That problem is simple enough that I didn't need to refer back to any previous +code of mine - my program[^1] was as simple as: + +```rust +fn main() { + let mut sum = 0; + for iii in 1..1000 { + if (iii % 3 == 0) || (iii % 5 == 0) { + sum += iii; + } + } + println!("Sum: {}", sum); +} +``` + +Working on this problem brought me to my first three major observations about +how Rust differs from other languages that I have used in the past: + +1. Rust variables are immutable by default. + +In other languages, immutability for local variables needs to be declared +explicitly (C, JavaScript) or is not possible (PHP). This will likely take some +getting used to, but I like it! + +2. The Rust compiler has helpful error messages. + +Without the `mut` keyword, trying to compile the program would lead to: + +
+ +Expand for errors + +``` +error[E0384]: cannot assign twice to immutable variable `sum` + --> problem1.rs:5:4 + | +2 | let sum = 0; + | --- first assignment to `sum` +... +5 | sum += iii; + | ^^^^^^^^^^ cannot assign twice to immutable variable + | +help: consider making this binding mutable + | +2 | let mut sum = 0; + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0384`. +``` +
+ +Not only is there an explanation of what went wrong (assigning twice to an +immutable variable) but there is also + +* identification of exactly where the assignments are made +* a suggestion of how to fix things +* a built-in help tool for information about the error code + +That built-in tool explains that by default, variables in Rust are immutable. +Compared to the compiler errors that I am used to from C and C++, Rust is a +refreshing change of pace. + +3. The Rust compiler warns about style issues too. + +I'm used to the conditions for `if` statements needing to be surrounded with +`()`, i.e. `if ((iii % 3 == 0) || (iii % 5 == 0)) {`, but with Rust, those are +unnecessary. Not only that, but the compiler will warn that they are unused, and +suggest removing them. I appreciate the compiler letting me know these are +unneeded, but I'm not sure how I feel about the compiler having a style +preference for removing unneeded parentheses. + +[Problem #2][proj-euler-prob-2], which asks for the sum of all even terms in +the Fibonacci sequence that are less than four million, was also pretty simple. +However, one of the compiler warnings that I got introduced me to a new Rust +feature: [`loop`][rust-loop], which is used for infinite loops. Other languages +that I have used lack a dedicated mechanism for infinite loops, and so I was +used to something like `while (true)`, but the compiler gave me a helpful +nudge via a warning. + +## Sudoku Solver + +Having gotten a hang of the basics, I figured it wouldn't hurt to just dive in, +and so I jumped to [Problem #96][proj-euler-prob-96]. Briefly, that problem +entails reading in 50 different sudoku grids, solving them, and then for each +grid, consider the first three digits of the top row as a three digit number, +and sum those three digit numbers across the 50 sudoku grids. + +So that I could focus on learning Rust rather than figuring out how to solve +the problem, I started off by basically copying my C++ implementation of the +problem and then working to adapt it to Rust. I'm not going to discuss every +difference between the languages, but there were a few places where Rust was +remarkably different from other languages that I have used in the past that I +think are worth mentioning for anyone considering taking up Rust. + +The first major difference was a big pain point in my conversion of the C++ +code to Rust that required re-engineering my approach: + +4. Rust prohibits having multiple mutable references to the same value. + +Sudoku digits cannot repeat within the same row, column, or box of the grid. +To help with managing the nine rows, nine columns, and nine boxes, in C++ I had +a `DigitCollection` class that would hold pointers to the nine different +`Digit`s of the grid in a row/column/box. The `DigitCollection` could also +modify the values of the grid `Digit`s - if there was only one `Digit` that +could hold the value `1`, for example, then that `Digit` would be updated to be +a `1`. Then, the other two collections that the `Digit` was in would propagate +the change and remove the `1` option from the other `Digit`s. + +In Rust, such an approach was not going to work. I tried various work-arounds +using Rust's standard library, like the [`std::cell::RefCell`][rust-refcell] +struct, but wasn't able to get anything to work. As a result, I instead +refactored the way `DigitCollection` worked: instead of holding a reference to +the various `Digit` instances, they would hold the details of the *locations* +(row and column) of each `Digit` in the collection. Then, any time that the +`DigitCollection` wanted to do anything, it would fetch a reference to the +needed `Digit`. That reference would only remain around while it was in use, +and so there would not be multiple references to the same `Digit` at once as +long as only one `DigitCollection` was doing work at a time. + +At that point, I realized that the setup of the `DigitCollection` struct meant +that it was no longer tied to a specific grid. The `DigitCollection` only held +details of the *locations* of `Digit`s in the grid, not the `Digit`s themselves. +Thus, I should be able to allocate the 27 `DigitCollection` instances once at +the start (nine rows, nine columns, nine boxes) and just reuse those rather than +allocating 27 instances for each of the 50 grids. However, I quickly ran into +another limitation of Rust: + +5. Rust global variables have restrictions on their initialization. + +I was initializing the nine `DigitCollection` instances corresponding to the +rows of the grid with + +```rust +let row_sets: [DigitCollection; 9] = core::array::from_fn( + |row| + DigitCollection { + locations: core::array::from_fn(|col| DigitLoc{ row: row, col: col } ), + } +); +``` + +Each of the nine rows was a `DigitCollection`, where the locations were +initialized with a callback mapping the column index to a new `DigitLoc` +struct, which just holds the row and column information together.[^2] + +Unfortunately, while the snippet above worked fine within a function, doing it +for a global variable (which needs to be declared with either `const` or +`static` rather than `let`) did not work. Using either `static` or `const` +results in error E0015 complaining that the `std::array::from_fn` function is +non-const. + +The final big difference that I encountered was not an issue for the first few +grids, so I did not realize the impact right away: + +6. Rust does not have exceptions that can be thrown and caught. + +At various points in the solving process, the solver might conclude that the +grid is impossible to solve - for example, a `Digit` might not have any possible +values, or a value might not be an option in any `Digit` in a collection. At +that point, the C++ code would throw an exception; when converting to Rust, I +started by replacing those exceptions with Rust's [`panic!` macro][rust-panic]. + +However, sometimes the exceptions needed to be caught. Specifically, after +implementing a few basic solution stategies (e.g. checking if a `Digit` could +only hold a single value, or if a value could only go in one `Digit` in a +`DigitCollection`) my approach was rather inelegant: bifurcation. I would +pick one `Digit` with multiple options, set it to be one of those options, and +then try to solve the new grid. If solving succeeded, then the "guess" was +correct and the solution from the new grid was used. If solving failed, then +the "guess" was incorrect and that option could be removed from the `Digit` in +question. + +To handle the "if solving failed" case, the C++ code would just catch an +exception; in Rust, I needed to convert this to use the [`Result`][rust-result] +type, which holds either a success value, or an error message. Once I replaced +some of the `panic!()` calls with `Result`s, the program was able to compile, +run, and produce the right answer! + +While I've spent a while on ways that Rust's differences were frustrating or +unexpected, there was also one Rust feature that the other languages I use most +often (C, PHP,[^3] and JavaScript) lack: + +7. Rust has pattern matching!!! + +I've used pattern matching in some other languages ([ML][ml-lang] comes to mind) +and it makes things very nice and compact. For example, part of the switch from +exceptions to a `Result` resulted in the code: + +```rust +match self.check_only_options() { + Err(_) => return false, + Ok(v) => made_change = v, +}; +``` + +If the `check_only_options()` method (which checks each `DigitCollection` to see +if there is a value that can only go into one `Digit`) returns an error, +indicating that the solving is impossible (due to bifurcation), the solving +just returns false. + +## Final Thoughts + +Rust is definitely a language I want to keep using. I plan to continuing +playing around with Rust for Project Euler problems, and I might try to +contribute [more patches to mago][blog-mago]. While Rust will take some +adjusting to, especially the limits on mutable references, I look forward to +adding a new language to my repertoire. + +[^1]: Normally, publishing solutions to the Project Euler problems is +discouraged, but for the first 100 problems sharing solutions is allowed. + +[^2]: In Sudoku, the cells are labeled as row one (top) through row nine +(bottom) and column one (left) through column nine (right). However, in Rust and +most other programming languages that I have used, arrays are indexed starting +from `0`. Thus, the "location" of a `Digit`, indicating where it is in the +two-dimensional array of `Digits` in the grid, has a row and a column that are +in the range 0-8 rather than 1-9. + +[^3]: PHP might be getting pattern matching at some point, there is +[an RFC][php-pattern-rfc] currently in draft to add that feature, but the RFC +has been in draft since 2020 so it could still be a while before it gets +discussed, accepted, and implemented, if it ever does. + +[proj-euler]: https://projecteuler.net/ +[proj-euler-prob-1]: https://projecteuler.net/problem=1 +[proj-euler-prob-2]: https://projecteuler.net/problem=2 +[rust-loop]: https://doc.rust-lang.org/rust-by-example/flow_control/loop.html +[proj-euler-prob-96]: https://projecteuler.net/problem=96 +[rust-refcell]: https://doc.rust-lang.org/std/cell/struct.RefCell.html +[rust-panic]: https://doc.rust-lang.org/std/macro.panic.html +[rust-result]: https://doc.rust-lang.org/std/result/ +[php-pattern-rfc]: https://wiki.php.net/rfc/pattern-matching +[ml-lang]: https://en.wikipedia.org/wiki/ML_(programming_language) +[blog-mago]: ./20250906-mago-rust diff --git a/tests/data/Home.html b/tests/data/Home.html index 184c292..fe2d693 100644 --- a/tests/data/Home.html +++ b/tests/data/Home.html @@ -4,5 +4,8 @@ Computer Science and Political Science and graduating magna cum laude in 2024 with a Bachelor of Science degree. As part of my work in Computer Science, I chose to write an honors thesis in my senior year, see here for details. I continued at Tufts for graduate school, graduating in 2025 with a Master of Science in Computer Science degree.

See the links in the navigation bar above for more information about my -experience.

Contact

Blog

I also have a blog. You can see a full index of my posts here. My latest blog post is:

"Hello, World!" in Rust

Friday, 12 September 2025

Yesterday, I started to teach myself how to program in Rust. As always, the first -step was a "Hello, World!" program. Continue reading...

\ No newline at end of file +experience.

Contact

Blog

I also have a blog. You can see a full index of my posts here. My latest blog post is:

Project Euler in Rust

Friday, 19 September 2025

Having done the obligatory hello world, I set out to actually code something +useful in Rust. When I learn a new programming language, my go-to source of +coding problems to try and solve in the new language is +Project Euler, which features hundreds of coding challenges of +various difficulty levels. Continue reading...

\ No newline at end of file diff --git a/tests/data/blog-index.html b/tests/data/blog-index.html index ddd589d..6b4a6b1 100644 --- a/tests/data/blog-index.html +++ b/tests/data/blog-index.html @@ -1,5 +1,9 @@ -Blog index
HomeRésuméOpen SourceWorkBlog

Blog index

"Hello, World!" in Rust

Friday, 12 September 2025

Yesterday, I started to teach myself how to program in Rust. As always, the first +Blog index

Blog index

Project Euler in Rust

Friday, 19 September 2025

Having done the obligatory hello world, I set out to actually code something +useful in Rust. When I learn a new programming language, my go-to source of +coding problems to try and solve in the new language is +Project Euler, which features hundreds of coding challenges of +various difficulty levels. Continue reading...

"Hello, World!" in Rust

Friday, 12 September 2025

Yesterday, I started to teach myself how to program in Rust. As always, the first step was a "Hello, World!" program. Continue reading...

First Rust Patch

Saturday, 06 September 2025

As part of preparing for my Longhorn PHP talk about what is new in PHP 8.5, I have been going through various PHP tools and checking to what extent they support the new features. When the support is lacking, I have sometimes tried to From f879437ddfeb5f3d7b29013f9fa4d0f4d1c68d93 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Fri, 19 Sep 2025 10:31:27 -0700 Subject: [PATCH 2/3] copy edit --- src/Blog/posts/20250919-rust-euler.md | 78 +++++++++++++++------------ tests/data/Home.html | 6 +-- tests/data/blog-index.html | 6 +-- 3 files changed, 49 insertions(+), 41 deletions(-) diff --git a/src/Blog/posts/20250919-rust-euler.md b/src/Blog/posts/20250919-rust-euler.md index ee21df8..0e96cd3 100644 --- a/src/Blog/posts/20250919-rust-euler.md +++ b/src/Blog/posts/20250919-rust-euler.md @@ -9,9 +9,9 @@ title: Project Euler in Rust # Project Euler in Rust -Having done the obligatory hello world, I set out to actually code something -useful in Rust. When I learn a new programming language, my go-to source of -coding problems to try and solve in the new language is +After writing the obligatory "Hello, World!", I wanted to work on something +more substantial in Rust. When I learn a new programming language, my go-to +source of coding problems to try and solve in the new language is [Project Euler][proj-euler], which features hundreds of coding challenges of various difficulty levels. @@ -24,8 +24,8 @@ how to solve the problem. I kicked things off with [Problem #1][proj-euler-prob-1], which asks for the sum of all natural numbers below 1000 that are multiples of 3 or 5 (or both). -That problem is simple enough that I didn't need to refer back to any previous -code of mine - my program[^1] was as simple as: +That problem is simple enough that I didn't refer back to any of my previous +solutions - my program[^1] was as simple as: ```rust fn main() { @@ -77,12 +77,12 @@ For more information about this error, try `rustc --explain E0384`. ``` -Not only is there an explanation of what went wrong (assigning twice to an -immutable variable) but there is also +Not only does the compiler explain what went wrong (assigning twice to an +immutable variable), it also: -* identification of exactly where the assignments are made -* a suggestion of how to fix things -* a built-in help tool for information about the error code +* highlights were the assignments occur, +* suggests how to fix them, +* and offers a built-in tool for exploring the error code further That built-in tool explains that by default, variables in Rust are immutable. Compared to the compiler errors that I am used to from C and C++, Rust is a @@ -93,9 +93,8 @@ refreshing change of pace. I'm used to the conditions for `if` statements needing to be surrounded with `()`, i.e. `if ((iii % 3 == 0) || (iii % 5 == 0)) {`, but with Rust, those are unnecessary. Not only that, but the compiler will warn that they are unused, and -suggest removing them. I appreciate the compiler letting me know these are -unneeded, but I'm not sure how I feel about the compiler having a style -preference for removing unneeded parentheses. +suggest removing them. I appreciate the compiler pointing this out, though I'm +not sure how I feel about the compiler having style preferences. [Problem #2][proj-euler-prob-2], which asks for the sum of all even terms in the Fibonacci sequence that are less than four million, was also pretty simple. @@ -113,12 +112,12 @@ entails reading in 50 different sudoku grids, solving them, and then for each grid, consider the first three digits of the top row as a three digit number, and sum those three digit numbers across the 50 sudoku grids. -So that I could focus on learning Rust rather than figuring out how to solve -the problem, I started off by basically copying my C++ implementation of the -problem and then working to adapt it to Rust. I'm not going to discuss every -difference between the languages, but there were a few places where Rust was -remarkably different from other languages that I have used in the past that I -think are worth mentioning for anyone considering taking up Rust. +To focus on learning Rust rather than re-solving the problem, I started off by +basically copying my C++ implementation of the problem and then working to adapt +it to Rust. I'm not going to discuss every difference between the languages, but +there were a few places where Rust was remarkably different from other +languages that I have used in the past that I think are worth mentioning for +anyone considering taking up Rust. The first major difference was a big pain point in my conversion of the C++ code to Rust that required re-engineering my approach: @@ -141,9 +140,9 @@ refactored the way `DigitCollection` worked: instead of holding a reference to the various `Digit` instances, they would hold the details of the *locations* (row and column) of each `Digit` in the collection. Then, any time that the `DigitCollection` wanted to do anything, it would fetch a reference to the -needed `Digit`. That reference would only remain around while it was in use, -and so there would not be multiple references to the same `Digit` at once as -long as only one `DigitCollection` was doing work at a time. +needed `Digit`. Those references were short-lived and scoped to their usage, so +there would not be multiple references to the same `Digit` at once as long as +only one `DigitCollection` was doing work at a time. At that point, I realized that the setup of the `DigitCollection` struct meant that it was no longer tied to a specific grid. The `DigitCollection` only held @@ -188,21 +187,21 @@ values, or a value might not be an option in any `Digit` in a collection. At that point, the C++ code would throw an exception; when converting to Rust, I started by replacing those exceptions with Rust's [`panic!` macro][rust-panic]. -However, sometimes the exceptions needed to be caught. Specifically, after -implementing a few basic solution stategies (e.g. checking if a `Digit` could -only hold a single value, or if a value could only go in one `Digit` in a -`DigitCollection`) my approach was rather inelegant: bifurcation. I would -pick one `Digit` with multiple options, set it to be one of those options, and -then try to solve the new grid. If solving succeeded, then the "guess" was -correct and the solution from the new grid was used. If solving failed, then -the "guess" was incorrect and that option could be removed from the `Digit` in -question. +However, some exceptions in the C++ version were meant to be caught and handled, +rather than terminating the entire program. Specifically, after implementing a +few basic solution stategies (e.g. checking if a `Digit` could only hold a +single value, or if a value could only go in one `Digit` in a `DigitCollection`) +my approach was rather inelegant: bifurcation. I would pick one `Digit` with +multiple options, set it to be one of those options, and then try to solve the +new grid. If solving succeeded, then the "guess" was correct and the solution +from the new grid was used. If solving failed, then the "guess" was incorrect +and that option could be removed from the `Digit` in question. To handle the "if solving failed" case, the C++ code would just catch an -exception; in Rust, I needed to convert this to use the [`Result`][rust-result] -type, which holds either a success value, or an error message. Once I replaced -some of the `panic!()` calls with `Result`s, the program was able to compile, -run, and produce the right answer! +exception; in Rust, the `panic!` macro aborts the entire program. I needed to +convert some of the `panic!` calls to instead use the [`Result`][rust-result] +type, which holds either a success value, or an error message. After that +migration, the program was able to compile, run, and produce the right answer! While I've spent a while on ways that Rust's differences were frustrating or unexpected, there was also one Rust feature that the other languages I use most @@ -234,6 +233,12 @@ contribute [more patches to mago][blog-mago]. While Rust will take some adjusting to, especially the limits on mutable references, I look forward to adding a new language to my repertoire. +I also need to get familiar with Rust's package system for installing libraries, +[crates][rust-crates]. These seem to be a built-in part of the core language, +unlike [PHP's Composer packages][php-composer] or +[JavaScript's NPM packages][js-npm], where the package management tools are +provided by third parties. + [^1]: Normally, publishing solutions to the Project Euler problems is discouraged, but for the first 100 problems sharing solutions is allowed. @@ -260,3 +265,6 @@ discussed, accepted, and implemented, if it ever does. [php-pattern-rfc]: https://wiki.php.net/rfc/pattern-matching [ml-lang]: https://en.wikipedia.org/wiki/ML_(programming_language) [blog-mago]: ./20250906-mago-rust +[rust-crates]: https://doc.rust-lang.org/book/ch07-01-packages-and-crates.html +[php-composer]: https://getcomposer.org/doc/00-intro.md +[js-npm]: https://docs.npmjs.com/about-npm \ No newline at end of file diff --git a/tests/data/Home.html b/tests/data/Home.html index fe2d693..ad20b18 100644 --- a/tests/data/Home.html +++ b/tests/data/Home.html @@ -4,8 +4,8 @@ Computer Science and Political Science and graduating magna cum laude in 2024 with a Bachelor of Science degree. As part of my work in Computer Science, I chose to write an honors thesis in my senior year, see here for details. I continued at Tufts for graduate school, graduating in 2025 with a Master of Science in Computer Science degree.

See the links in the navigation bar above for more information about my -experience.

Contact

  • LinkedIn
  • Email: daniel.e.scherzer@gmail.com

Blog

I also have a blog. You can see a full index of my posts here. My latest blog post is:

Project Euler in Rust

Friday, 19 September 2025

Having done the obligatory hello world, I set out to actually code something -useful in Rust. When I learn a new programming language, my go-to source of -coding problems to try and solve in the new language is +experience.

Contact

  • LinkedIn
  • Email: daniel.e.scherzer@gmail.com

Blog

I also have a blog. You can see a full index of my posts here. My latest blog post is:

Project Euler in Rust

Friday, 19 September 2025

After writing the obligatory "Hello, World!", I wanted to work on something +more substantial in Rust. When I learn a new programming language, my go-to +source of coding problems to try and solve in the new language is Project Euler, which features hundreds of coding challenges of various difficulty levels. Continue reading...

\ No newline at end of file diff --git a/tests/data/blog-index.html b/tests/data/blog-index.html index 6b4a6b1..3b612ff 100644 --- a/tests/data/blog-index.html +++ b/tests/data/blog-index.html @@ -1,7 +1,7 @@ -Blog index

Blog index

Project Euler in Rust

Friday, 19 September 2025

Having done the obligatory hello world, I set out to actually code something -useful in Rust. When I learn a new programming language, my go-to source of -coding problems to try and solve in the new language is +Blog index

Blog index

Project Euler in Rust

Friday, 19 September 2025

After writing the obligatory "Hello, World!", I wanted to work on something +more substantial in Rust. When I learn a new programming language, my go-to +source of coding problems to try and solve in the new language is Project Euler, which features hundreds of coding challenges of various difficulty levels. Continue reading...

"Hello, World!" in Rust

Friday, 12 September 2025

Yesterday, I started to teach myself how to program in Rust. As always, the first step was a "Hello, World!" program. Continue reading...

First Rust Patch

Saturday, 06 September 2025

As part of preparing for my Longhorn PHP talk about what is new in PHP 8.5, I From 55cc097f97f7f00964b3cd8364b136c6e8bcbd85 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Fri, 19 Sep 2025 10:37:28 -0700 Subject: [PATCH 3/3] tweaks --- src/Blog/posts/20250919-rust-euler.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Blog/posts/20250919-rust-euler.md b/src/Blog/posts/20250919-rust-euler.md index 0e96cd3..8517992 100644 --- a/src/Blog/posts/20250919-rust-euler.md +++ b/src/Blog/posts/20250919-rust-euler.md @@ -133,9 +133,9 @@ could hold the value `1`, for example, then that `Digit` would be updated to be a `1`. Then, the other two collections that the `Digit` was in would propagate the change and remove the `1` option from the other `Digit`s. -In Rust, such an approach was not going to work. I tried various work-arounds +In Rust, such an approach was not going to work. I tried various workarounds using Rust's standard library, like the [`std::cell::RefCell`][rust-refcell] -struct, but wasn't able to get anything to work. As a result, I instead +struct, but I wasn't able to get anything to work. As a result, I instead refactored the way `DigitCollection` worked: instead of holding a reference to the various `Digit` instances, they would hold the details of the *locations* (row and column) of each `Digit` in the collection. Then, any time that the @@ -227,11 +227,11 @@ just returns false. ## Final Thoughts -Rust is definitely a language I want to keep using. I plan to continuing -playing around with Rust for Project Euler problems, and I might try to -contribute [more patches to mago][blog-mago]. While Rust will take some -adjusting to, especially the limits on mutable references, I look forward to -adding a new language to my repertoire. +Rust is definitely a language I want to keep using. I plan to continue playing +around with Rust for Project Euler problems, and I might try to contribute +[more patches to mago][blog-mago]. While Rust will take some adjusting to, +especially the limits on mutable references, I look forward to adding a new +language to my repertoire. I also need to get familiar with Rust's package system for installing libraries, [crates][rust-crates]. These seem to be a built-in part of the core language,