68 lines
1.9 KiB
Plaintext
68 lines
1.9 KiB
Plaintext
fn fib(n: int, f: fn (num: i64) -> bool) -> (i64, int) {
|
|
if n < 0 {
|
|
// Let these variables be mutated, otherwise too slow
|
|
let mut n1:i64 = 0, n2:i64 = -1, i:int = 0, tmp:i64;
|
|
while i > n {
|
|
f(n1);
|
|
tmp = n1-n2;
|
|
if (tmp > 0 && n2 > 0) { //Detect overflow
|
|
io::println("\nReached the limit of i64, halting");
|
|
return (n1, i);
|
|
}
|
|
n1 = n2;
|
|
n2 = tmp;
|
|
i -= 1;
|
|
}
|
|
(n1+n2, n)
|
|
} else if n > 0 {
|
|
// And these variables
|
|
let mut n1:i64 = 0, n2:i64 = 1, i:int = 0, tmp:i64;
|
|
while i < n {
|
|
f(n1);
|
|
tmp = n1+n2;
|
|
if (tmp < 0) { //Detect overflow
|
|
io::println("\nReached the limit of i64, halting");
|
|
return (n1, i);
|
|
}
|
|
n1 = n2;
|
|
n2 = tmp;
|
|
i += 1;
|
|
}
|
|
(n2-n1, n)
|
|
} else {
|
|
f(0);
|
|
(0,1)
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let args = os::args();
|
|
let n = if args.len() == 1 {
|
|
10
|
|
} else if args.len() > 1 {
|
|
// Convert from a string
|
|
match (int::from_str(args[1])) {
|
|
Some(num) => num,
|
|
None => 10 //Fall back to default
|
|
}
|
|
} else {
|
|
/* Required to use the if as an expression.
|
|
* We know that args.len() is always >= 1, the compiler
|
|
* does not. fail lets it know that we can't get past here.
|
|
*/
|
|
fail ~"No arguments given, somehow...";
|
|
};
|
|
|
|
/* Use the loop protocol to be able to do things
|
|
* with the sequence given, in this case, print them out.
|
|
* The loop itself returns a tuple with where it got to and
|
|
* what the number is.
|
|
*/
|
|
let (result, n) = for fib(n) |num| {
|
|
//print out the sequence
|
|
io::print(fmt!("%? ", num));
|
|
};
|
|
|
|
io::println(fmt!("\nThe %dth fibonacci number is: %?", n, result));
|
|
}
|