replacements for big int in rust - rust

I made a program to calculate the prime numbers of 1 to n in python and rust. Surprisingly python wins with the difference of 0.008 and 0.590. Rust won all other questions with the difference of 0.001 and 0.008.
The only difference here, is that I need to calculate a large number. Python is fine with large numbers, but rust requires a crate knows as num. Without using the num crate, rust wins.
Is there some how that I can avoid using num, without changing my solution?
Here are the rust and python solutions.
from functools import reduce
fact = lambda x: reduce(lambda y, z: y*z, range(1,x+1))
is_prime = lambda x: False if x <= 1 else fact(x-1) % x == x - 1
primes = lambda x, y: tuple(filter(is_prime, range(x,y+1)))
import sys
print(primes(1, int(sys.argv[1])))
macro_rules! number {
(+ $($args:tt),*) => {
num::BigInt::new(num::bigint::Sign::Plus, vec![$($args),*])
};
(- $($args:tt),*) => {
num::BigInt::new(num::bigint::Sign::Minus, vec![$($args),*])
};
}
fn fact(x: u32) -> num::BigInt {
(1..x+1).map(|x| number!(+ x)).reduce(|x, y| x * y).unwrap()
}
fn is_prime(x: u32) -> bool {
x > 1 && fact(x - 1) % x == number!(+ (x - 1))
}
fn main() {
let n = &(std::env::args().collect::<Vec<String>>())[1];
println!("{:#?}", (1..=n.parse::<u32>().unwrap()).filter(|x| is_prime(*x)).collect::<Vec<u32>>());
}

Related

MoveTo in Crossterm is clearing my output

When using the crossterm library with this code:
fn draw_box(stdout: &mut Stdout, x: u16, y: u16) -> Result<()> {
let size = 5;
let outline = (x..x + size)
.map(|i| (i, y))
.chain((y + 1..y + size - 1).map(|i| (x + size - 1, i)))
.chain((y + 1..y + size - 1).map(|i| (x, i)))
.chain((x..x + size).map(|i| (i, y + size - 1)))
.collect::<Vec<_>>();
for (a, b) in outline {
stdout
.queue(cursor::MoveTo(a, b))?
.queue(style::Print("x"))?;
}
stdout.flush()?;
stdout
.queue(cursor::MoveTo(x + 2, y + 2))?
.queue(style::Print("o"))?;
stdout.flush()?;
Ok(())
}
The last draw command clears the rest of the output to give this:
xxxxx
x x
x o%
If I remove that command I get the full box:
xxxxx
x x
x x
x x
xxxxx%
How can I draw the box and then draw the circle inside of the box?

How to return a value inside for loop in rust?

I want to port this python code
#!/usr/bin/python
# -*- coding: utf-8 -*-
def testing(x, y):
for i in range(y):
x = 2.0 * x
if x > 3.5:
return i
return 999
for i in range(20):
print testing(float(i) / 10, 15)
and its output
999
5
4
3
3
2
2
2
etc.
to rust code. This is the rust code I wrote which is identical to the above python code.
fn testing(x: f32, y: i32) -> i32 {
for i in 0..y {
let x = 2.0 * x;
if x > 3.5 {
return i;
}
}
return 999;
}
fn main() {
for i in 0..20 {
let a = i as f32;
println!("{}", testing(a / 10.0, 15));
}
}
But its output is not the same as the python codes output
999
999
999
999
999
999
999
etc.
What is the right way to return a value in for loop using rust? Why is the my rust code outputting a different output comparing to pythons?
The problem is the line
let x = 2.0 * x;
let introduces a new variable, the original x is not modified.
The next loop iteration will then again multiple 2.0 with the parameter x, not with the variable x from the previous loop's iteration.
You need to instead assign the value to the existing x variable (which requires marking it as mutable):
fn testing(mut x: f32, y: i32) -> i32 {
for i in 0..y {
x = 2.0 * x;
if x > 3.5 {
return i;
}
}
return 999;
}
fn main() {
for i in 0..20 {
let a = i as f32;
println!("{}", testing(a / 10.0, 15));
}
}

Is it possible to do destructuring assignment with type annotations?

The overall question is how to do nested destructuring assignment with type annotations. I'm multiplying two f32 values, but I'm unsure what will happen if the multiple overflows. Therefore, I'd like to assign them as f64 values in order to prevent the overflow.
This example is lightly modified from Rust By Example's chapter on structures:
struct Point {
x: f32,
y: f32,
}
struct Rectangle {
p1: Point,
p2: Point,
}
fn area(rect: Rectangle) -> f64 {
// Here's where I'd like have type annotations
// while doing destructuring assignment:
let Rectangle {
p1: Point { x: x1, y: y1 },
p2: Point { x: x2, y: y2 },
} = rect;
((x2 - x1) * (y2 - y1)).abs() as f64
}
Casts cannot be performed during type destructuring. This is because you cannot annotate the type that will be contained in the type you're destructuring, therefore it doesn't depend on you, and instead on the type that is being destructured. For example:
struct Point {
x: f32,
y: f32,
}
let myOtherPoint = Point { x: 0, y: 0 };
let Point {x, y} = myOtherPoint;
The type of x and y are defined by the type Point. This can, on the other hand be changed in the case of tuples and arrays:
fn main() {
let [x, y, z]: [f32; 3] = [1.2, 2.3, 3.4];
let (x, y, z): (usize, f32, String) = (1, 2.3, "3.4".into());
}
This is mostly because of type annotations needed for tuples when writing function signatures:
fn foo((a, b, c): (usize, f32, String)) {}
But this is only because tuples are not named types, per se, so there is a need to name the tuple, by annotating the type. On the other hand, structs and enums are named and therefore destructurable.
The solution to your specific issue described in the body, and not the title:
Use a separate variable with shadowing to preserve usability. Note too, that the floating point types (f32 and f64) cannot be overflowed (They have an infinity), only integers ([u, i][size, 8, 16, 32, 64, 128]).
fn area(x: Rectangle) -> f64 {
// Here's where I'd like have type annotations
// while doing destructuring assignment:
let Rectangle {
p1: Point { x: x1, y: y1 },
p2: Point { x: x2, y: y2 },
} = rect;
let (x1, x2, y1, y2) = (x1 as f64, x2 as f64,
y1 as f64, y2 as f64);
((x2 - x1) * (y2 - y1)).abs()
}

Python: Compute a Huge Fibonacci Number Modulo m

# Uses python3
# Given two integers n and m, output Fn mod m (that is, the remainder of Fn when divided by m
def Huge_Fib(n,m):
if n == 0 : return 0
elif n == 1: return 1
else:
a,b = 0,1
for i in range(1,n):
a, b = b, (a+b) % m
print(b);
n,m = map(int, input().split());
Huge_Fib(n,m);
The code works very well. However, when I run a case as n = 99999999999999999, m = 2, it takes me much time. Do you have any better solutions?
Here is my solution, you don't have to go through 99999999999999999 iterations if you find the pisano period.
I also recommend that you watch this video: https://www.youtube.com/watch?v=Nu-lW-Ifyec
# Uses python3
import sys
def get_fibonacci_huge(n, m):
if n <= 1:
return n
arr = [0, 1]
previousMod = 0
currentMod = 1
for i in range(n - 1):
tempMod = previousMod
previousMod = currentMod % m
currentMod = (tempMod + currentMod) % m
arr.append(currentMod)
if currentMod == 1 and previousMod == 0:
index = (n % (i + 1))
return arr[index]
return currentMod
if __name__ == '__main__':
input = sys.stdin.read();
n, m = map(int, input.split())
print(get_fibonacci_huge(n,m))
# Uses python3
# Given two integers n and m, output Fn mod m (that is, the remainder of Fn when divided by m
def Huge_Fib(n,m):
# Initialize a matrix [[1,1],[1,0]]
v1, v2, v3 = 1, 1, 0
# Perform fast exponentiation of the matrix (quickly raise it to the nth power)
for rec in bin(n)[3:]:
calc = (v2*v2) % m
v1, v2, v3 = (v1*v1+calc) % m, ((v1+v3)*v2) % m, (calc+v3*v3) % m
if rec == '1': v1, v2, v3 = (v1+v2) % m, v1, v2
print(v2);
n,m = map(int, input().split());
Huge_Fib(n,m);
This is a superfast solution refer to https://stackoverflow.com/a/23462371/3700852
I solved it in Python 3. This the fastest algorithm to compute a huge Fibonacci number modulo m.For example for n =2816213588, m = 239, it took Max time used: 0.01/5.00, max memory used: 9424896/536870912.)
def pisanoPeriod(m):
previous, current = 0, 1
for i in range(0, m * m):
previous, current = current, (previous + current) % m
# A Pisano Period starts with 01
if (previous == 0 and current == 1):
return i + 1
def calc_fib(n,m):
p = pisanoPeriod(m)
n = n % p
if (n <= 1):
return n
else:
previous,current = 0,1
for i in range(2,n+1):
previous,current = current,(previous+current)
return current%m
n,m =map(int,input().split(" "))
print(calc_fib(n,m))
In the below code we are using two concepts of Fibonacci series:
Pisano periods follows a Fibonacci sequence and hence each repetition(pattern) begins with 0 and 1 appearing consecutively one after the other.
fib(n) divides fib(m) only when n divides m which means if fib(4)%3==0,then fib(4+4)%3==0,fib(4+4+4)%3==0 and so on.This helps us in finding the Pisano period.
To know about Pisano periods,I recommend that you watch this video: https://www.youtube.com/watch?v=Nu-lW-Ifyec
#python3
def pisano_length(m):
i=2
while(fib(i)%m!=0):
i+=1
if(fib(i+1)%m!=1):
while(fib(i+1)%m!=1):
i+=i
print("The pisano length for mod {} is: {}".format(m,i))
return(i)
def fib(n):
a,b=0,1
if(n==0 or n==1):
return n
else:
for i in range(2,n+1):
b,a=a+b,b
return(b)
#we want to calculate fib(n)%m for big numbers
n,m=map(int,input().split())
remainder=n%pisano_length(m)
print(fib(remainder)%m)
You should look up Pisano periods.
https://en.wikipedia.org/wiki/Pisano_period and
http://webspace.ship.edu/msrenault/fibonacci/fibfactory.htm should give you a good understanding of what they are.
edit: Just googling "fibonacci modulo" gives you those two as the top two results.
For any integer m>=2, the sequence fn modulo m is periodic - Pisano Period.
So no need to store and find fn. Instead, find a repeating pattern for given m.
This is how i have done by calculating the pisano period.(Java)
public static long get_pisano_period(long m) {
long a = 0, b = 1;
long c;
for (int i = 0; i < m * m; i++) {
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
return i + 1;
}
return 0;
}
public static BigInteger get_fibonacci_huge(long n,long m) {
long remainder = n % get_pisano_period(m);
BigInteger first = BigInteger.valueOf(0);
BigInteger second=BigInteger.valueOf(1);
BigInteger m1=BigInteger.valueOf(m);
BigInteger res = BigInteger.valueOf(remainder);
for (long i = 1; i < remainder; i++) {
res = (first.add(second)).mod(m1);
first = second;
second = res;
}
return res.mod(m1);
}

Iterate two vectors with different lengths

I have two Vecs that can be of different lengths, for example:
let xs = vec![1, 2, 3, 4, 5];
let ys = vec![11, 12, 13];
I want to iterate over them in pairs, printing:
x=1, y=11
x=2, y=12
x=3, y=13
x=4; no matching Y
x=5; no matching Y
I can use Iterator::zip to get the pairs with matching elements in both xs and ys:
for (x, y) in xs.iter().zip(ys.iter()) {
println!("x={}, y={}", x, y);
}
but for the "no matching" bits I need complex code that checks the length and takes a slice of the rest.
I wanted a solution that's fully iterator-based, so I tried:
let mut it_xs = xs.iter();
let mut it_ys = ys.iter();
while let (Some(x), Some(y)) = (it_xs.next(), it_ys.next()) {
println!("x={}, y={}", x, y);
}
while let Some(x) = it_xs.next() {
println!("x={}, no matching Y", x);
}
while let Some(y) = it_ys.next() {
println!("y={}, no matching X", y);
}
which does not work correctly, as the first loop skips the first element that doesn't have a match in the other list (x=4).
Is it possible to solve with the help of an iterator without slicing the rest of the larger Vec?
The implementation without external crates:
let mut it_xs = xs.iter();
let mut it_ys = ys.iter();
loop {
match (it_xs.next(), it_ys.next()) {
(Some(x), Some(y)) => println!("x={}, y={}", x, y),
(Some(x), None) => println!("x={}, no matching Y", x),
(None, Some(y)) => println!("y={}, no matching X", y),
(None, None) => break,
}
}
itertools has a method zip_longest that does just that:
use itertools::Itertools;
use itertools::EitherOrBoth::{Both, Left, Right};
for it in xs.iter().zip_longest(ys.iter()) {
match it {
Both(x, y) => println!("x={}, y={}", x, y),
Left(x) => println!("x={}, no matching Y", x),
Right(y) => println!("y={}, no matching X", y),
}
}

Resources