Fibonacci word

From Rosetta Code
Task
Fibonacci word
You are encouraged to solve this task according to the task description, using any language you may know.

The Fibonacci Word may be created in a manner analogous to the Fibonacci Sequence as described here:

Define F_Word1 as 1;
Define F_Word2 as 0;
Form F_Word3 as F_Word2 concatenated with F_Word1 i.e "01"
Form F_Wordn as F_Wordn-1 concatenated with F_wordn-2

For this task we shall do this for n = 37. You may display the first few but not the larger values of n, doing so will get me into trouble with them what be (again!).

Instead create a table for F_Words 1 to 37 which shows:

The number of characters in the word
The word's Entropy.

Icon and Unicon

The following solution works in both Icon and Unicon. The first eight Fibonacci words are shown, while the Fibonacci word length and Entropy are shown for all 37.

<lang unicon>procedure main(A)

   n := integer(A[1]) | 37
   write(right("N",4)," ",right("length",15)," ",left("Entrophy",15)," ",
         " Fibword")
   every w := fword(i := 1 to n) do {
       writes(right(i,4)," ",right(*w,15)," ",left(H(w),15))
       if i <= 8 then write(": ",w) else write()
       }

end

procedure fword(n)

   static fcache
   initial fcache := table()
   /fcache[n] := case n of {
                    1: "1"
                    2: "0"
                    default: fword(n-1)||fword(n-2)
                    }
   return fcache[n]

end

procedure H(s)

   P := table(0.0)
   every P[!s] +:= 1.0/*s
   every (h := 0.0) -:= P[c := key(P)] * log(P[c],2)
   return h

end</lang>

Sample run:

->fw
   N          length Entrophy         Fibword
   1               1 0.0            : 1
   2               1 0.0            : 0
   3               2 1.0            : 01
   4               3 0.9182958340544: 010
   5               5 0.9709505944546: 01001
   6               8 0.9544340029249: 01001010
   7              13 0.9612366047228: 0100101001001
   8              21 0.9587118829771: 010010100100101001010
   9              34 0.9596868937742
  10              55 0.9593160320543
  11              89 0.9594579158386
  12             144 0.9594037542210
  13             233 0.9594244469559
  14             377 0.9594165437404
  15             610 0.9594195626031
  16             987 0.9594184095152
  17            1597 0.9594188499578
  18            2584 0.9594186817240
  19            4181 0.9594187459836
  20            6765 0.9594187214387
  21           10946 0.9594187308140
  22           17711 0.9594187272330
  23           28657 0.9594187286009
  24           46368 0.9594187280783
  25           75025 0.9594187282781
  26          121393 0.9594187282015
  27          196418 0.9594187282313
  28          317811 0.9594187282195
  29          514229 0.9594187282251
  30          832040 0.9594187282196
  31         1346269 0.9594187282169
  32         2178309 0.9594187282191
  33         3524578 0.9594187282130
  34         5702887 0.9594187282322
  35         9227465 0.9594187281818
  36        14930352 0.9594187282743
  37        24157817 0.9594187282928
->

PARI/GP

<lang parigp>ent(a,b)=[a,b]=[a,b]/(a+b);(a*log(if(a,a,1))+b*log(if(b,b,1)))/log(1/2) allocatemem(75<<20) \\ Allocate 75 MB stack space F=vector(37);F[1]="1";F[2]="0";for(n=3,37,F[n]=Str(F[n-1],F[n-2])) for(n=1,37,print(n" "fibonacci(n)" "ent(fibonacci(n-1),fibonacci(n-2))))</lang>

For those output fascists:

1 1 0.E-9
2 1 0.E-9
3 2 1.00000000
4 3 0.918295834
5 5 0.970950594
6 8 0.954434003
7 13 0.961236604
8 21 0.958711883
9 34 0.959686894
10 55 0.959316032
11 89 0.959457916
12 144 0.959403754
13 233 0.959424447
14 377 0.959416544
15 610 0.959419563
16 987 0.959418409
17 1597 0.959418850
18 2584 0.959418682
19 4181 0.959418746
20 6765 0.959418721
21 10946 0.959418731
22 17711 0.959418727
23 28657 0.959418728
24 46368 0.959418728
25 75025 0.959418728
26 121393 0.959418728
27 196418 0.959418728
28 317811 0.959418728
29 514229 0.959418728
30 832040 0.959418728
31 1346269 0.959418728
32 2178309 0.959418728
33 3524578 0.959418728
34 5702887 0.959418728
35 9227465 0.959418728
36 14930352 0.959418728
37 24157817 0.959418728

Perl 6

Does not work yet with rakudo for rakudo does not recognize * R~ * as priming. It's possible to write -> $a, $b { $b ~ $a } instead but it's kind of verbose.

<lang Perl 6>my @fib-word := 1, 0, * R~ * ... *;

sub entropy {

   -log(2) R/
   [+] map -> \p { p * log p },
   $^string.comb.bag.values »/» $string.chars

} for 1 .. 37 -> $n {

   printf "%5d\t%10d\t%.8e\t%s\n", $n, .chars, .&entropy, $n > 10 ??  !! $_
   given @fib-word[$n];

}</lang>