Total Pageviews

Saturday, January 9, 2021

Project Euler - Rust Problem 8

Problem 8

The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.


73167176531330624919225119674426574742355349194934

96983520312774506326239578318016984801869478851843

85861560789112949495459501737958331952853208805511

12540698747158523863050715693290963295227443043557

66896648950445244523161731856403098711121722383113

62229893423380308135336276614282806444486645238749

30358907296290491560440772390713810515859307960866

70172427121883998797908792274921901699720888093776

65727333001053367881220235421809751254540594752243

52584907711670556013604839586446706324415722155397

53697817977846174064955149290862569321978468622482

83972241375657056057490261407972968652414535100474

82166370484403199890008895243450658541227588666881

16427171479924442928230863465674813919123162824586

17866458359124566529476545682848912883142607690042

24219022671055626321111109370544217506941658960408

07198403850962455444362981230987879927244284909188

84580156166097919133875499200524063689912560717606

05886116467109405077541002256983155200055935729725

71636269561882670428252483600823257530420752963450


Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?

Well then.  Yeah, that's a thing.

Logically speaking... you would loop through the numbers starting with 0-3 and then ending -4:-1.  So... With Rust, it doesn't index the same way as python.  We should still be able to loop through it just fine.  The bigger issue, for me, is how do you get the input into the program.

You can hard code it.  Just put in the string of numbers manually into the code.  Sure why not? I would pull it in from a text file but... I'm still trying to figure that out. meh.

So I loaded the number string into a vector as integers. 

My code

fn main(){

        let mut my_vec = vec![7,3,(all the numbers from above),5,0];

let mut largest_multi = 0;

let mut first: u64 = my_vec.pop().unwrap();

let mut second: u64 = my_vec.pop().unwrap();

let mut third: u64 = my_vec.pop().unwrap();

let mut fourth: u64 = my_vec.pop().unwrap();

let mut fifth: u64 = my_vec.pop().unwrap();

let mut sixth: u64 = my_vec.pop().unwrap();

let mut seventh: u64 = my_vec.pop().unwrap();

let mut eighth: u64 = my_vec.pop().unwrap();

let mut ninth: u64 = my_vec.pop().unwrap();

let mut tenth: u64 = my_vec.pop().unwrap();

let mut eleventh: u64 = my_vec.pop().unwrap();

let mut twelvth: u64 = my_vec.pop().unwrap();

let mut thirteenth: u64 = my_vec.pop().unwrap();



while my_vec.len() > 0{

let mut x = first * second * third * fourth * fifth * sixth * seventh * eighth * ninth * tenth * eleventh * twelvth * thirteenth;


if x > largest_multi{

largest_multi = x;

}

println!("{}", my_vec.len());

first = second;

second = third;

third = fourth;

fourth = fifth;

fifth = sixth;

sixth = seventh;

seventh = eighth;

eighth = ninth;

ninth = tenth;

tenth = eleventh;

eleventh = twelvth;

twelvth = thirteenth;

thirteenth = my_vec.pop().unwrap();

}

println!("{:?}", largest_multi);

}


So after I hard coded the number string, I defined 13 variables.  Then I filled those with the first 13 popped values from the vector.  Then I created the loop based on the length of the vec.  If the vec is greater than 0 then there's still values in them.  So every loop, all 13 variables are multiplied together.

if the multiple is greater than the largest recorded value, it records the new value.  After all the values have been popped, the largest multiple is printed.

There's obviously ways to improve this.  filter out any iteration if 0 is in the variables. you know skip those.  Change how the slices of the vec are accessed.

I doubt this is the most effective method.

Other Guys Code

Minacode wrote:

The main idea is to not calculate the whole window at every step. Thus, we have to divide through the leftmost number we are "leaving" while moving the window to the next position, and then multiply with the new number on the right. Because there are zeros, we have to be careful. At the start and after every zero, we have to incrementally multiply enough numbers to make up a whole window of 13 numbers. This is why we keep track of a scope count which measures the current size of the window. Until we did not reach 13 elements, we do not update the max value. fn main() { let series = [ 7,3,(all the numbers in the list),5,0 ]; let length = series.len(); let scope = 13; let mut product: u64 = series[0]; let mut max = product; let mut i = 0; let mut scope_count = 1; while i < length-scope { let new = series[i + scope_count]; if new == 0 { i += scope_count; scope_count = 1; while i < length && series[i] == 0 { i += 1; } if i == length { break; } product = series[i]; } else { if scope_count == scope { let last = series[i]; product /= last; product *= new; if product > max { max = product; } i += 1; } else { scope_count += 1; product *= new; } } } println!("{}", max); }


So basically this code improves in all the ways that I had mentioned. It cycles through the list 13 at a time and multiplies them together. If it == 0 then it moves the cycle. He also uses an array instead of a vec. I will be looking into the benefits of using one over the other.

No comments: