Faulhaber's triangle: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Perl 6}}: Add a Perl6 example)
m (→‎{{header|Perl 6}}: Whitespace cleanup)
Line 42: Line 42:
<lang perl6># Helper subs
<lang perl6># Helper subs


sub infix:<reduce>(\prev, \this) { this.key => this.key * (this.value - prev.value) }
sub infix:<reduce> (\prev, \this) { this.key => this.key * (this.value - prev.value) }


sub next-bernoulli ( (:key($pm), :value(@pa)) ) {
sub next-bernoulli ( (:key($pm), :value(@pa)) ) {
Line 52: Line 52:
sub binomial (Int $n, Int $p) { combinations($n, $p).elems };
sub binomial (Int $n, Int $p) { combinations($n, $p).elems };


sub asRat(FatRat $r) { $r ?? $r.denominator == 1 ?? $r.numerator !! $r.nude.join('/') !! 0 };
sub asRat (FatRat $r) { $r ?? $r.denominator == 1 ?? $r.numerator !! $r.nude.join('/') !! 0 };




Line 59: Line 59:


# First 10 rows of Faulhaber's triangle:
# First 10 rows of Faulhaber's triangle:
say faulhaber_triangle($_)».&asRat.fmt('%6s') for ^10;
say faulhaber_triangle($_)».&asRat.fmt('%5s') for ^10;
say '';
say '';


Line 67: Line 67:
say sum faulhaber_triangle($p).kv.map: { $^value * $n**($^key + 1) };</lang>
say sum faulhaber_triangle($p).kv.map: { $^value * $n**($^key + 1) };</lang>
{{out}}
{{out}}
<pre> 1
<pre> 1
1/2 1/2
1/2 1/2
1/6 1/2 1/3
1/6 1/2 1/3
0 1/4 1/2 1/4
0 1/4 1/2 1/4
-1/30 0 1/3 1/2 1/5
-1/30 0 1/3 1/2 1/5
0 -1/12 0 5/12 1/2 1/6
0 -1/12 0 5/12 1/2 1/6
1/42 0 -1/6 0 1/2 1/2 1/7
1/42 0 -1/6 0 1/2 1/2 1/7
0 1/12 0 -7/24 0 7/12 1/2 1/8
0 1/12 0 -7/24 0 7/12 1/2 1/8
-1/30 0 2/9 0 -7/15 0 2/3 1/2 1/9
-1/30 0 2/9 0 -7/15 0 2/3 1/2 1/9
0 -3/20 0 1/2 0 -7/10 0 3/4 1/2 1/10
0 -3/20 0 1/2 0 -7/10 0 3/4 1/2 1/10


56056972216555580111030077961944183400198333273050000</pre>
56056972216555580111030077961944183400198333273050000</pre>

Revision as of 22:34, 6 June 2017

Faulhaber's triangle is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Named after Johann Faulhaber, the rows of Faulhaber's triangle are the coefficients of polynomials that represent sums of integer powers, which are extracted from Faulhaber's formula:



where is the nth-Bernoulli number.


The first 5 rows of Faulhaber's triangle, are:

    1
  1/2  1/2
  1/6  1/2  1/3
    0  1/4  1/2  1/4
-1/30    0  1/3  1/2  1/5


Using the third row of the triangle, we have:


Task
  • show the first 10 rows of Faulhaber's triangle.
  • using the 17th row of Faulhaber's triangle, compute the sum: (extra credit).
See also

Perl 6

Works with: Rakudo version 2017.05
Translation of: Sidef

<lang perl6># Helper subs

sub infix:<reduce> (\prev, \this) { this.key => this.key * (this.value - prev.value) }

sub next-bernoulli ( (:key($pm), :value(@pa)) ) {

   $pm + 1 => [ map *.value, [\reduce] ($pm + 2 ... 1) Z=> FatRat.new(1, $pm + 2), |@pa ]

}

constant bernoulli = (0 => [1.FatRat], &next-bernoulli ... *).map: { .value[*-1] };

sub binomial (Int $n, Int $p) { combinations($n, $p).elems };

sub asRat (FatRat $r) { $r ?? $r.denominator == 1 ?? $r.numerator !! $r.nude.join('/') !! 0 };


  1. The task

sub faulhaber_triangle ($p) { map { binomial($p+1, $_) * bernoulli[$_] / ($p+1) }, ($p ... 0) }

  1. First 10 rows of Faulhaber's triangle:

say faulhaber_triangle($_)».&asRat.fmt('%5s') for ^10; say ;

  1. Extra credit:

my $p = 17; my $n = 1000; say sum faulhaber_triangle($p).kv.map: { $^value * $n**($^key + 1) };</lang>

Output:
    1
  1/2   1/2
  1/6   1/2   1/3
    0   1/4   1/2   1/4
-1/30     0   1/3   1/2   1/5
    0 -1/12     0  5/12   1/2   1/6
 1/42     0  -1/6     0   1/2   1/2   1/7
    0  1/12     0 -7/24     0  7/12   1/2   1/8
-1/30     0   2/9     0 -7/15     0   2/3   1/2   1/9
    0 -3/20     0   1/2     0 -7/10     0   3/4   1/2  1/10

56056972216555580111030077961944183400198333273050000

Sidef

<lang ruby>func faulhaber_triangle(p) {

   gather {
       for j in (p+1 ^.. 0) {
           take(binomial(p+1, j) * bernoulli(j) / (p+1))
       }
   }

}

    1. First 10 rows of Faulhaber's triangle:

for p in (0 .. 9) {

   say faulhaber_triangle(p).map{ '%6s' % .as_rat }.join

}

    1. Extra credit:

const p = 17 const n = 1000

say say faulhaber_triangle(p).map_kv{|k,v| v * n**(k+1) }.sum</lang>

Output:
     1
   1/2   1/2
   1/6   1/2   1/3
     0   1/4   1/2   1/4
 -1/30     0   1/3   1/2   1/5
     0 -1/12     0  5/12   1/2   1/6
  1/42     0  -1/6     0   1/2   1/2   1/7
     0  1/12     0 -7/24     0  7/12   1/2   1/8
 -1/30     0   2/9     0 -7/15     0   2/3   1/2   1/9
     0 -3/20     0   1/2     0 -7/10     0   3/4   1/2  1/10

56056972216555580111030077961944183400198333273050000