2013-01-23 13:53:53 -08:00
|
|
|
package DDG::Goodie::Fibonacci;
|
2014-08-20 11:45:33 -07:00
|
|
|
# ABSTRACT: n-th Fibonacci number
|
2013-01-23 13:53:53 -08:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
|
|
|
|
use DDG::Goodie;
|
2013-01-24 01:20:34 -08:00
|
|
|
use Lingua::EN::Numbers::Ordinate qw(ordsuf);
|
2016-06-09 13:01:15 -07:00
|
|
|
use Math::NumSeq::Fibonacci;
|
2016-06-20 22:52:02 -07:00
|
|
|
use Math::BigInt;
|
2013-01-23 13:53:53 -08:00
|
|
|
|
|
|
|
triggers any => 'fib', 'fibonacci';
|
2014-10-14 09:21:34 -07:00
|
|
|
|
2013-01-23 13:53:53 -08:00
|
|
|
zci answer_type => 'fibonacci';
|
2014-10-14 09:21:34 -07:00
|
|
|
zci is_cached => 1;
|
2013-01-23 13:53:53 -08:00
|
|
|
|
2016-06-10 00:00:31 -07:00
|
|
|
sub answer {
|
|
|
|
my ($text_ans, $title, $subtitle) = @_;
|
|
|
|
|
|
|
|
return $text_ans, structured_answer => {
|
2016-05-15 09:54:04 -07:00
|
|
|
data => {
|
2016-06-20 22:52:02 -07:00
|
|
|
title => "$title",
|
|
|
|
subtitle => "$subtitle"
|
2016-05-15 09:54:04 -07:00
|
|
|
},
|
|
|
|
templates => {
|
|
|
|
group => 'text'
|
|
|
|
}
|
|
|
|
};
|
2016-06-10 00:00:31 -07:00
|
|
|
}
|
|
|
|
|
2016-06-13 21:57:47 -07:00
|
|
|
my $ith_limit = 25000; # limit for nth fibonacci numbers
|
2016-06-12 08:22:17 -07:00
|
|
|
my $pred_limit = 10**22; # limit for if n is a fibonacci number
|
|
|
|
my $fib_seq = Math::NumSeq::Fibonacci->new;
|
2016-06-10 00:00:31 -07:00
|
|
|
|
2016-06-12 08:22:17 -07:00
|
|
|
handle remainder_lc => sub {
|
2016-06-10 00:00:31 -07:00
|
|
|
# check "what is the nth fibonacci number"
|
|
|
|
if (/^(?:what(?:'s| is) the )?(?<which>\d+)(?:st|nd|rd|th)?(?: number)?(?: in the (?:series|sequence))?\??$/ && $1 <= $ith_limit)
|
|
|
|
{
|
|
|
|
my $n = $+{'which'};
|
|
|
|
my $val = $fib_seq->ith($n);
|
|
|
|
my $suf = ordsuf($n);
|
2016-06-13 21:57:47 -07:00
|
|
|
my $text_answer ="The $n$suf fibonacci number is $val (assuming f(0) = 0)";
|
2016-06-10 00:00:31 -07:00
|
|
|
|
2016-06-20 22:52:02 -07:00
|
|
|
return answer($text_answer, $val, "$n$suf Fibonacci number");
|
2016-06-10 00:00:31 -07:00
|
|
|
}
|
|
|
|
# check "is n a fibonacci number"
|
|
|
|
elsif (/^is (?<which>\d+) (?:a|in the)? ?(?:number|sequence)?\??$/ && $1 <= $pred_limit)
|
|
|
|
{
|
|
|
|
my $n = $+{'which'};
|
|
|
|
my $val = $fib_seq->pred($n);
|
|
|
|
my $is_fib = $val ? "is" : "is not";
|
2016-06-13 21:57:47 -07:00
|
|
|
my $text_answer ="$n $is_fib a Fibonacci number";
|
2016-06-10 00:00:31 -07:00
|
|
|
|
2016-06-13 21:57:47 -07:00
|
|
|
return answer($text_answer, $val ? "Yes" : "No", $text_answer);
|
|
|
|
}
|
2016-06-10 00:00:31 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return; # didn't match anything
|
|
|
|
}
|
2013-01-23 13:53:53 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
1;
|