Skip to content

Commit

Permalink
Solve p0034, make math functions more generic
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Jul 23, 2024
1 parent 3b3579d commit e0368a5
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ LivInTheLookingGlass’s Project Euler solutions
| | Pypy 3.6+ |br| | | |
| | GraalPy 23.1+ | | |
+------------+-------------------------+--------+-------------------+
| Rust | 1.69+ | 14 | |Rust| |
| Rust | 1.69+ | 15 | |Rust| |
+------------+-------------------------+--------+-------------------+
| Documentation (in progress) | |Pages| |
+-----------------------------------------------+-------------------+
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ This project is divided into several Makefiles, connected by a root Makefile whi
+-----------+------------+------------+------------+------------+------------+------------+
|:prob:`33` | | | | |:py-d:`0033`| |
+-----------+------------+------------+------------+------------+------------+------------+
|:prob:`34` |:c-d:`0034` |:cp-d:`0034`| | |:py-d:`0034`| |
|:prob:`34` |:c-d:`0034` |:cp-d:`0034`| | |:py-d:`0034`|:rs-d:`0034`|
+-----------+------------+------------+------------+------------+------------+------------+
|:prob:`35` | | | | |:py-d:`0035`| |
+-----------+------------+------------+------------+------------+------------+------------+
Expand Down
7 changes: 6 additions & 1 deletion docs/rust/math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ math.rs

View source code `here on GitHub! <https://github.com/LivInTheLookingGlass/Euler/blob/master/rust/src/math.rs>`_

.. rust:fn:: math::n_choose_r(n: usize, r: usize) -> i128
.. rust:fn:: math::factorial<I: NumAssign + From<u8>>(n: u8) -> I
Returns the factorial of a given number. Note that it only accepts a ``u8`` because
any number that requires a larger type is *guaranteed* to overflow.

.. rust:fn:: math::n_choose_r<I: NumAssign + From<i8> + From<usize>>(n: usize, r: usize) -> I
Returns the number of ways to choose r items from a set of n.

Expand Down
2 changes: 1 addition & 1 deletion docs/rust/p0015.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ View source code `here on GitHub! <https://github.com/LivInTheLookingGlass/Euler
Includes
--------

- `primes <./math.html>`_
- `math <./math.html>`_

Problem Solution
----------------
Expand Down
18 changes: 18 additions & 0 deletions docs/rust/p0034.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Rust Implementation of Problem 34
=================================

View source code `here on GitHub! <https://github.com/LivInTheLookingGlass/Euler/blob/master/rust/src/p0034.rs>`_

Includes
--------

- `math <./math.html>`_

Problem Solution
----------------

.. rust:fn:: p0034::p0034() -> i128
.. literalinclude:: ../../rust/src/p0034.rs
:language: rust
:linenos:
1 change: 1 addition & 0 deletions rust/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@ Problems Solved
- ☒ `11 <./src/p0011.rs>`__
- ☒ `12 <./src/p0012.rs>`__
- ☒ `15 <./src/p0015.rs>`__
- ☒ `15 <./src/p0034.rs>`__
- ☒ `76 <./src/p0076.rs>`__

1 change: 1 addition & 0 deletions rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const ANSWERS: [ProblemRef; 14] = [
("p0011", p0011::p0011, 70600674),
("p0012", p0012::p0012, 76576500),
("p0015", p0015::p0015, 137846528820),
("p0034", p0034::p0034, 40730),

Check failure

Code scanning / clippy

failed to resolve: use of undeclared crate or module p0034 Error

failed to resolve: use of undeclared crate or module p0034
("p0076", p0076::p0076, 190569291),
];

Check failure

Code scanning / clippy

mismatched types Error

mismatched types

Expand Down
27 changes: 19 additions & 8 deletions rust/src/math.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
pub fn n_choose_r(n: usize, r: usize) -> i128 {
use num_traits::NumAssign;
use num_traits::one;

pub fn factorial<I: NumAssign + From<u8>>(n: u8) -> I {
let mut answer: I = one();
for i in 2..=n {
answer *= i.into();
}
return answer
}

pub fn n_choose_r<I: NumAssign + From<i8> + From<usize>>(n: usize, r: usize) -> I {
// slow path for larger numbers
let mut answer: i128 = 1;
let mut tmp: i128;
let mut answer: I = one();
let mut tmp: I;
let mut factors: Vec<i8> = vec![0; n + 1];
// collect factors of final number
for i in 2..=n {
Expand Down Expand Up @@ -30,25 +41,25 @@ pub fn n_choose_r(n: usize, r: usize) -> i128 {
while i <= n {
while factors[i] > 0 {
tmp = answer;
answer *= i as i128;
answer *= i.into();
while answer < tmp && j <= n {

Check failure

Code scanning / clippy

binary operation < cannot be applied to type I Error

binary operation < cannot be applied to type I

Check failure

Code scanning / clippy

binary operation < cannot be applied to type I Error

binary operation < cannot be applied to type I

Check failure

Code scanning / clippy

binary operation < cannot be applied to type I Error

binary operation < cannot be applied to type I
while factors[j] < 0 {
tmp /= j as i128;
tmp /= j.into();
factors[j] += 1;
}
j += 1;
answer = tmp * i as i128;
answer = tmp * i.into();
}
if answer < tmp {

Check failure

Code scanning / clippy

binary operation < cannot be applied to type I Error

binary operation < cannot be applied to type I

Check failure

Code scanning / clippy

binary operation < cannot be applied to type I Error

binary operation < cannot be applied to type I

Check failure

Code scanning / clippy

binary operation < cannot be applied to type I Error

binary operation < cannot be applied to type I
return -1; // this indicates an overflow
return (-1).into(); // this indicates an overflow
}
factors[i] -= 1;
}
i += 1;
}
while j <= n {
while factors[j] < 0 {
answer /= j as i128;
answer /= j.into();
factors[j] += 1;
}
j += 1;
Expand Down
32 changes: 32 additions & 0 deletions rust/src/p0034.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Project Euler Problem 34
This ended up being a filtering problem. The problem with my solution is that I
am not satisfied with my filter at all. I feel like there is a more efficient
way to go about it.
Problem:
145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145.
Find the sum of all numbers which are equal to the sum of the factorial of
their digits.
Note: as 1! = 1 and 2! = 2 are not sums they are not included.
*/
use crate::math::factorial;

pub fn p0034() -> i128 {
let mut answer: u32 = 0;
for x in 10..100000 {
let string: String = x.to_string();
let sum =
string.bytes()
.into_iter()
.fold(0, |a, b| a + factorial::<u32>(b - '0' as u8));
if sum == x {
answer += x;
}
}
return answer.into();
}

0 comments on commit e0368a5

Please sign in to comment.