|
32 | 32 |
|
33 | 33 | =end pod
|
34 | 34 |
|
35 |
| -our $limit; |
36 |
| -our $digits; |
37 |
| -# You can optionally pass how many digits you're looking for, defaults |
38 |
| -# to the request in the original challenge. |
39 |
| -sub MAIN(Int :$length = 1000, Bool :$verbose = False) { |
40 |
| - # As of August 12, 2009 we don't have big integers, so we'll have |
41 |
| - # to conjure up something. We'll represent each number with an |
42 |
| - # array of digits, base 10 for ease of length computation. The most |
43 |
| - # significant part is at the end of the array, i.e. the array should |
44 |
| - # be read in reverse. |
45 |
| - $digits = 10; |
46 |
| - $limit = 10 ** $digits; |
47 |
| - my @x = (0); |
48 |
| - my @y = (1); |
49 |
| - |
50 |
| - # This will count the n-th Fibonacci number |
51 |
| - my $c = 1; |
52 |
| - my $current_length = 1; |
53 |
| - while ($current_length < $length) { |
54 |
| - ++$c; |
55 |
| - |
56 |
| - # (x, y) = (y, x + y) |
57 |
| - my @z = @y; |
58 |
| - addto(@y, @x); # modifies @y in-place |
59 |
| - @x = @z; |
60 |
| - |
61 |
| - # The most significant part of the number is in the last element |
62 |
| - # of the array; every other element is $digits bytes long by |
63 |
| - # definition. |
64 |
| - my $msb = printable([@y[*-1]]); |
65 |
| - $current_length = $msb.encode('utf-8').bytes + (@y - 1) * $digits; |
66 |
| - |
67 |
| - # Print a feedback every 20 steps |
68 |
| - if $verbose { |
69 |
| - say "$c -> $current_length" unless $c % 100; |
70 |
| - } |
| 35 | +sub MAIN(Int :$length = 1000, Bool :$boring = False) { |
| 36 | + if $boring { |
| 37 | + my ($x, $y, $c) = (1, 1, 2); |
| 38 | + ($x, $y, $c) = ($y, $x + $y, $c + 1) while $y.chars < $length; |
| 39 | + $c.say; |
| 40 | + return; |
71 | 41 | }
|
72 | 42 |
|
73 |
| - say $c; |
74 |
| -} |
75 |
| - |
76 |
| -# Add a "number" to another, modifies first parameter in place. |
77 |
| -# This assumes that length(@y) <= length(@x), which will be true in |
78 |
| -# our program because @y is lower than @x |
79 |
| -sub addto (@x is rw, @y) { |
80 |
| - my $rest = 0; |
81 |
| - # Assuming length(@y) <= length(@x) means that we have to |
82 |
| - # put "0"s to iterate over the whole $x. This could be |
83 |
| - # improved, but it's unlikely that two consecutive Fibonacci |
84 |
| - # numbers differ by more than one digit |
85 |
| - for (@x Z (@y, 0, *)).flat -> $x is rw, $y { |
86 |
| - $x += $y + $rest; |
87 |
| - $rest = ($x / $limit).Int; |
88 |
| - $x %= $limit; |
89 |
| - } |
90 |
| - push @x, $rest if $rest; |
| 43 | + my @fibs := 0, 1, *+* ... *; |
| 44 | + ((1..*).grep:{@fibs[$_].chars == $length})[0].say; |
91 | 45 | return;
|
92 | 46 | }
|
93 | 47 |
|
94 |
| -sub printable (@x is copy) { |
95 |
| - my $msb = pop @x; |
96 |
| - return $msb ~ @x.reverse.map({sprintf '%0'~$digits~'d', $_ }).join(''); |
97 |
| -} |
98 |
| - |
99 | 48 | # vim: expandtab shiftwidth=4 ft=perl6
|
0 commit comments