bool first = true
integer fn = open("fasta.txt","r")
if fn=-1 then ?9/0 end if
while true do
    object line = trim(gets(fn))
    if atom(line) then puts(1,"\n") exit end if
    if length(line) then
        if line[1]=='>' then
            if not first then puts(1,"\n") end if
            printf(1,"%s: ",{line[2..$]})
            first = false
        elsif first then
            printf(1,"Error : File does not begin with '>'\n")
            exit
        elsif not find_any(" \t",line) then
            puts(1,line)
        else
            printf(1,"\nError : Sequence contains space(s)\n")
            exit
        end if
    end if
end while
close(fn)


(de fasta (F)
   (in F
      (while (from ">")
         (prin (line T) ": ")
         (until (or (= ">" (peek)) (eof))
            (prin (line T)) )
         (prinl) ) ) )
(fasta "fasta.dat")


$file = @'
>Rosetta_Example_1
THERECANBENOSPACE
>Rosetta_Example_2
THERECANBESEVERAL
LINESBUTTHEYALLMUST
BECONCATENATED
'@

$lines = $file.Replace("`n","~").Split(">").ForEach({$_.TrimEnd("~").Split("`n",2,[StringSplitOptions]::RemoveEmptyEntries)})

$output = New-Object -TypeName PSObject

foreach ($line in $lines)
{
    $name, $value = $line.Split("~",2).ForEach({$_.Replace("~","")})

    $output | Add-Member -MemberType NoteProperty -Name $name -Value $value
}

$output | Format-List


EnableExplicit
Define Hdl_File.i,
       Frm_File.i,
       c.c,
       header.b

Hdl_File=ReadFile(#PB_Any,"c:\code_pb\rosettacode\data\FASTA_TEST.txt")
If Not IsFile(Hdl_File) : End -1 : EndIf
Frm_File=ReadStringFormat(Hdl_File)

If OpenConsole("FASTA format")
  While Not Eof(Hdl_File)
    c=ReadCharacter(Hdl_File,Frm_File)
    Select c
      Case '>'
        header=#True
        PrintN("")
      Case #LF, #CR
        If header
          Print(": ")
          header=#False
        EndIf
      Default
        Print(Chr(c))
    EndSelect
  Wend
  CloseFile(Hdl_File)
  Input()
EndIf


import io

FASTA='''\
>Rosetta_Example_1
THERECANBENOSPACE
>Rosetta_Example_2
THERECANBESEVERAL
LINESBUTTHEYALLMUST
BECONCATENATED'''

infile = io.StringIO(FASTA)

def fasta_parse(infile):
    key = ''
    for line in infile:
        if line.startswith('>'):
            if key:
                yield key, val
            key, val = line[1:].rstrip().split()[0], ''
        elif key:
            val += line.rstrip()
    if key:
        yield key, val

print('\n'.join('%s: %s' % keyval for keyval in fasta_parse(infile)))


#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

int binomial(int n, int k) {
    int num, denom, i;

    if (n < 0 || k < 0 || n < k) return -1;
    if (n == 0 || k == 0) return 1;

    num = 1;
    for (i = k + 1; i <= n; ++i) {
        num = num * i;
    }

    denom = 1;
    for (i = 2; i <= n - k; ++i) {
        denom *= i;
    }

    return num / denom;
}

int gcd(int a, int b) {
    int temp;
    while (b != 0) {
        temp = a % b;
        a = b;
        b = temp;
    }
    return a;
}

typedef struct tFrac {
    int num, denom;
} Frac;

Frac makeFrac(int n, int d) {
    Frac result;
    int g;

    if (d == 0) {
        result.num = 0;
        result.denom = 0;
        return result;
    }

    if (n == 0) {
        d = 1;
    } else if (d < 0) {
        n = -n;
        d = -d;
    }

    g = abs(gcd(n, d));
    if (g > 1) {
        n = n / g;
        d = d / g;
    }

    result.num = n;
    result.denom = d;
    return result;
}

Frac negateFrac(Frac f) {
    return makeFrac(-f.num, f.denom);
}

Frac subFrac(Frac lhs, Frac rhs) {
    return makeFrac(lhs.num * rhs.denom - lhs.denom * rhs.num, rhs.denom * lhs.denom);
}

Frac multFrac(Frac lhs, Frac rhs) {
    return makeFrac(lhs.num * rhs.num, lhs.denom * rhs.denom);
}

bool equalFrac(Frac lhs, Frac rhs) {
    return (lhs.num == rhs.num) && (lhs.denom == rhs.denom);
}

bool lessFrac(Frac lhs, Frac rhs) {
    return (lhs.num * rhs.denom) < (rhs.num * lhs.denom);
}

void printFrac(Frac f) {
    printf("%d", f.num);
    if (f.denom != 1) {
        printf("/%d", f.denom);
    }
}

Frac bernoulli(int n) {
    Frac a[16];
    int j, m;

    if (n < 0) {
        a[0].num = 0;
        a[0].denom = 0;
        return a[0];
    }

    for (m = 0; m <= n; ++m) {
        a[m] = makeFrac(1, m + 1);
        for (j = m; j >= 1; --j) {
            a[j - 1] = multFrac(subFrac(a[j - 1], a[j]), makeFrac(j, 1));
        }
    }

    if (n != 1) {
        return a[0];
    }

    return negateFrac(a[0]);
}

void faulhaber(int p) {
    Frac coeff, q;
    int j, pwr, sign;

    printf("%d : ", p);
    q = makeFrac(1, p + 1);
    sign = -1;
    for (j = 0; j <= p; ++j) {
        sign = -1 * sign;
        coeff = multFrac(multFrac(multFrac(q, makeFrac(sign, 1)), makeFrac(binomial(p + 1, j), 1)), bernoulli(j));
        if (equalFrac(coeff, makeFrac(0, 1))) {
            continue;
        }
        if (j == 0) {
            if (!equalFrac(coeff, makeFrac(1, 1))) {
                if (equalFrac(coeff, makeFrac(-1, 1))) {
                    printf("-");
                } else {
                    printFrac(coeff);
                }
            }
        } else {
            if (equalFrac(coeff, makeFrac(1, 1))) {
                printf(" + ");
            } else if (equalFrac(coeff, makeFrac(-1, 1))) {
                printf(" - ");
            } else if (lessFrac(makeFrac(0, 1), coeff)) {
                printf(" + ");
                printFrac(coeff);
            } else {
                printf(" - ");
                printFrac(negateFrac(coeff));
            }
        }
        pwr = p + 1 - j;
        if (pwr > 1) {
            printf("n^%d", pwr);
        } else {
            printf("n");
        }
    }
    printf("\n");
}

int main() {
    int i;

    for (i = 0; i < 10; ++i) {
        faulhaber(i);
    }

    return 0;
}


library("seqinr")

data <- c(">Rosetta_Example_1","THERECANBENOSPACE",">Rosetta_Example_2","THERECANBESEVERAL","LINESBUTTHEYALLMUST","BECONCATENATED")
fname <- "rosettacode.fasta"
f <- file(fname,"w+")
writeLines(data,f)
close(f)

fasta <- read.fasta(file = fname, as.string = TRUE, seqtype = "AA")
for (aline in fasta) {
  cat(attr(aline, 'Annot'), ":", aline, "\n")
}


#lang racket
(let loop ([m #t])
  (when m
    (when (regexp-try-match #rx"^>" (current-input-port))
      (unless (eq? #t m) (newline))
      (printf "~a: " (read-line)))
    (loop (regexp-match #rx"\n" (current-input-port) 0 #f
                        (current-output-port)))))
(newline)


grammar FASTA {

    rule TOP    { <entry>+ }
    rule entry  { \> <title> <sequence> }
    token title { <.alnum>+ }
    token sequence { ( <.alnum>+ )+ % \n { make $0.join } }

}

FASTA.parse: q:to /§/;
>Rosetta_Example_1
THERECANBENOSPACE
>Rosetta_Example_2
THERECANBESEVERAL
LINESBUTTHEYALLMUST
BECONCATENATED
§

for $/<entry>[] {
    say ~.<title>, " : ", .<sequence>.made;
}


using System;

namespace FaulhabersFormula {
    internal class Frac {
        private long num;
        private long denom;

        public static readonly Frac ZERO = new Frac(0, 1);
        public static readonly Frac ONE = new Frac(1, 1);

        public Frac(long n, long d) {
            if (d == 0) {
                throw new ArgumentException("d must not be zero");
            }
            long nn = n;
            long dd = d;
            if (nn == 0) {
                dd = 1;
            }
            else if (dd < 0) {
                nn = -nn;
                dd = -dd;
            }
            long g = Math.Abs(Gcd(nn, dd));
            if (g > 1) {
                nn /= g;
                dd /= g;
            }
            num = nn;
            denom = dd;
        }

        private static long Gcd(long a, long b) {
            if (b == 0) {
                return a;
            }
            return Gcd(b, a % b);
        }

        public static Frac operator -(Frac self) {
            return new Frac(-self.num, self.denom);
        }

        public static Frac operator +(Frac lhs, Frac rhs) {
            return new Frac(lhs.num * rhs.denom + lhs.denom * rhs.num, rhs.denom * lhs.denom);
        }

        public static Frac operator -(Frac lhs, Frac rhs) {
            return lhs + -rhs;
        }

        public static Frac operator *(Frac lhs, Frac rhs) {
            return new Frac(lhs.num * rhs.num, lhs.denom * rhs.denom);
        }

        public static bool operator <(Frac lhs, Frac rhs) {
            double x = (double)lhs.num / lhs.denom;
            double y = (double)rhs.num / rhs.denom;
            return x < y;
        }

        public static bool operator >(Frac lhs, Frac rhs) {
            double x = (double)lhs.num / lhs.denom;
            double y = (double)rhs.num / rhs.denom;
            return x > y;
        }

        public static bool operator ==(Frac lhs, Frac rhs) {
            return lhs.num == rhs.num && lhs.denom == rhs.denom;
        }

        public static bool operator !=(Frac lhs, Frac rhs) {
            return lhs.num != rhs.num || lhs.denom != rhs.denom;
        }

        public override string ToString() {
            if (denom == 1) {
                return num.ToString();
            }
            return string.Format("{0}/{1}", num, denom);
        }

        public override bool Equals(object obj) {
            var frac = obj as Frac;
            return frac != null &&
                   num == frac.num &&
                   denom == frac.denom;
        }

        public override int GetHashCode() {
            var hashCode = 1317992671;
            hashCode = hashCode * -1521134295 + num.GetHashCode();
            hashCode = hashCode * -1521134295 + denom.GetHashCode();
            return hashCode;
        }
    }

    class Program {
        static Frac Bernoulli(int n) {
            if (n < 0) {
                throw new ArgumentException("n may not be negative or zero");
            }
            Frac[] a = new Frac[n + 1];
            for (int m = 0; m <= n; m++) {
                a[m] = new Frac(1, m + 1);
                for (int j = m; j >= 1; j--) {
                    a[j - 1] = (a[j - 1] - a[j]) * new Frac(j, 1);
                }
            }
            // returns 'first' Bernoulli number
            if (n != 1) return a[0];
            return -a[0];
        }

        static int Binomial(int n, int k) {
            if (n < 0 || k < 0 || n < k) {
                throw new ArgumentException();
            }
            if (n == 0 || k == 0) return 1;
            int num = 1;
            for (int i = k + 1; i <= n; i++) {
                num = num * i;
            }
            int denom = 1;
            for (int i = 2; i <= n - k; i++) {
                denom = denom * i;
            }
            return num / denom;
        }

        static void Faulhaber(int p) {
            Console.Write("{0} : ", p);
            Frac q = new Frac(1, p + 1);
            int sign = -1;
            for (int j = 0; j <= p; j++) {
                sign *= -1;
                Frac coeff = q * new Frac(sign, 1) * new Frac(Binomial(p + 1, j), 1) * Bernoulli(j);
                if (Frac.ZERO == coeff) continue;
                if (j == 0) {
                    if (Frac.ONE != coeff) {
                        if (-Frac.ONE == coeff) {
                            Console.Write("-");
                        }
                        else {
                            Console.Write(coeff);
                        }
                    }
                }
                else {
                    if (Frac.ONE == coeff) {
                        Console.Write(" + ");
                    }
                    else if (-Frac.ONE == coeff) {
                        Console.Write(" - ");
                    }
                    else if (Frac.ZERO < coeff) {
                        Console.Write(" + {0}", coeff);
                    }
                    else {
                        Console.Write(" - {0}", -coeff);
                    }
                }
                int pwr = p + 1 - j;
                if (pwr > 1) {
                    Console.Write("n^{0}", pwr);
                }
                else {
                    Console.Write("n");
                }
            }
            Console.WriteLine();
        }

        static void Main(string[] args) {
            for (int i = 0; i < 10; i++) {
                Faulhaber(i);
            }
        }
    }
}


/*REXX program reads a (bio-informational)  FASTA  file  and  displays the contents.    */
parse arg iFID .                                 /*iFID:  the input file to be read.    */
if iFID==''  then iFID='FASTA.IN'                /*Not specified?  Then use the default.*/
name=                                            /*the name of an output file (so far). */
$=                                               /*the value of the output file's stuff.*/
     do  while  lines(iFID)\==0                  /*process the  FASTA  file contents.   */
     x=strip( linein(iFID), 'T')                 /*read a line (a record) from the file,*/
                                                 /*───────── and strip trailing blanks. */
     if left(x, 1)=='>'  then do
                              if $\==''  then say name':'  $
                              name=substr(x,  2)
                              $=
                              end
                         else $=$ || x
     end   /*j*/                                 /* [↓]  show output of last file used. */
if $\==''  then say name':'  $                   /*stick a fork in it,  we're all done. */


# Project : FAST format

a = ">Rosetta_Example_1
THERECANBENOSPACE
>Rosetta_Example_2
THERECANBESEVERAL
LINESBUTTHEYALLMUST
BECONCATENATED"

i = 1
while i <= len(a)
      if substr(a,i,17) = ">Rosetta_Example_"
         see nl
         see substr(a,i,18) + ": " + nl
         i = i + 17
      else
         if ascii(substr(a,i,1)) > 20
            see a[i]
         ok
      ok
      i = i + 1
end


def fasta_format(strings)
  out, text = [], ""
  strings.split("\n").each do |line|
    if line[0] == '>'
      out << text unless text.empty?
      text = line[1..-1] + ": "
    else
      text << line
    end
  end
  out << text unless text.empty?
end

data = <<'EOS'
>Rosetta_Example_1
THERECANBENOSPACE
>Rosetta_Example_2
THERECANBESEVERAL
LINESBUTTHEYALLMUST
BECONCATENATED
EOS

puts fasta_format(data)


#include <iostream>
#include <numeric>
#include <sstream>
#include <vector>

class Frac {
public:
	Frac(long n, long d) {
		if (d == 0) {
			throw new std::runtime_error("d must not be zero");
		}

		long nn = n;
		long dd = d;
		if (nn == 0) {
			dd = 1;
		} else if (dd < 0) {
			nn = -nn;
			dd = -dd;
		}

		long g = abs(std::gcd(nn, dd));
		if (g > 1) {
			nn /= g;
			dd /= g;
		}

		num = nn;
		denom = dd;
	}

	Frac operator-() const {
		return Frac(-num, denom);
	}

	Frac operator+(const Frac& rhs) const {
		return Frac(num*rhs.denom + denom * rhs.num, rhs.denom*denom);
	}

	Frac operator-(const Frac& rhs) const {
		return Frac(num*rhs.denom - denom * rhs.num, rhs.denom*denom);
	}

	Frac operator*(const Frac& rhs) const {
		return Frac(num*rhs.num, denom*rhs.denom);
	}

	bool operator==(const Frac& rhs) const {
		return num == rhs.num && denom == rhs.denom;
	}

	bool operator!=(const Frac& rhs) const {
		return num != rhs.num || denom != rhs.denom;
	}

	bool operator<(const Frac& rhs) const {
		if (denom == rhs.denom) {
			return num < rhs.num;
		}
		return num * rhs.denom < rhs.num * denom;
	}

	friend std::ostream& operator<<(std::ostream&, const Frac&);

	static Frac ZERO() {
		return Frac(0, 1);
	}

	static Frac ONE() {
		return Frac(1, 1);
	}

private:
	long num;
	long denom;
};

std::ostream & operator<<(std::ostream & os, const Frac &f) {
	if (f.num == 0 || f.denom == 1) {
		return os << f.num;
	}

	std::stringstream ss;
	ss << f.num << "/" << f.denom;
	return os << ss.str();
}

Frac bernoulli(int n) {
	if (n < 0) {
		throw new std::runtime_error("n may not be negative or zero");
	}

	std::vector<Frac> a;
	for (int m = 0; m <= n; m++) {
		a.push_back(Frac(1, m + 1));
		for (int j = m; j >= 1; j--) {
			a[j - 1] = (a[j - 1] - a[j]) * Frac(j, 1);
		}
	}

	// returns 'first' Bernoulli number
	if (n != 1) return a[0];
	return -a[0];
}

int binomial(int n, int k) {
	if (n < 0 || k < 0 || n < k) {
		throw new std::runtime_error("parameters are invalid");
	}
	if (n == 0 || k == 0) return 1;

	int num = 1;
	for (int i = k + 1; i <= n; i++) {
		num *= i;
	}

	int denom = 1;
	for (int i = 2; i <= n - k; i++) {
		denom *= i;
	}

	return num / denom;
}

void faulhaber(int p) {
	using namespace std;
	cout << p << " : ";

	auto q = Frac(1, p + 1);
	int sign = -1;
	for (int j = 0; j < p + 1; j++) {
		sign *= -1;
		auto coeff = q * Frac(sign, 1) * Frac(binomial(p + 1, j), 1) * bernoulli(j);
		if (coeff == Frac::ZERO()) {
			continue;
		}
		if (j == 0) {
			if (coeff == -Frac::ONE()) {
				cout << "-";
			} else if (coeff != Frac::ONE()) {
				cout << coeff;
			}
		} else {
			if (coeff == Frac::ONE()) {
				cout << " + ";
			} else if (coeff == -Frac::ONE()) {
				cout << " - ";
			} else if (coeff < Frac::ZERO()) {
				cout << " - " << -coeff;
			} else {
				cout << " + " << coeff;
			}
		}
		int pwr = p + 1 - j;
		if (pwr > 1) {
			cout << "n^" << pwr;
		} else {
			cout << "n";
		}
	}
	cout << endl;
}

int main() {
	for (int i = 0; i < 10; i++) {
		faulhaber(i);
	}

	return 0;
}


a$ = ">Rosetta_Example_1
THERECANBENOSPACE
>Rosetta_Example_2
THERECANBESEVERAL
LINESBUTTHEYALLMUST
BECONCATENATED"

i = 1
while i <= len(a$)
  if mid$(a$,i,17) = ">Rosetta_Example_" then
    print
    print mid$(a$,i,18);": ";
    i = i + 17
   else
    if asc(mid$(a$,i,1)) > 20 then print mid$(a$,i,1);
  end if
  i = i + 1
wend


use std::env;
use std::io::{BufReader, Lines};
use std::io::prelude::*;
use std::fs::File;

fn main() {
    let args: Vec<String> = env::args().collect();
    let f = File::open(&args[1]).unwrap();
    for line in FastaIter::new(f) {
        println!("{}", line);
    }
}

struct FastaIter<T> {
    buffer_lines: Lines<BufReader<T>>,
    current_name: Option<String>,
    current_sequence: String
}

impl<T: Read> FastaIter<T> {
    fn new(file: T) -> FastaIter<T> {
        FastaIter { buffer_lines: BufReader::new(file).lines(),
                    current_name: None,
                    current_sequence: String::new() }
    }
}

impl<T: Read> Iterator for FastaIter<T> {
    type Item = String;

    fn next(&mut self) -> Option<String> {
        while let Some(l) = self.buffer_lines.next() {
            let line = l.unwrap();
            if line.starts_with(">") {
                if self.current_name.is_some() {
                    let mut res = String::new();
                    res.push_str(self.current_name.as_ref().unwrap());
                    res.push_str(": ");
                    res.push_str(&self.current_sequence);
                    self.current_name = Some(String::from(&line[1..]));
                    self.current_sequence.clear();
                    return Some(res);
                } else {
                    self.current_name = Some(String::from(&line[1..]));
                    self.current_sequence.clear();
                }
                continue;
            }
            self.current_sequence.push_str(line.trim());
        }
        if self.current_name.is_some() {
            let mut res = String::new();
            res.push_str(self.current_name.as_ref().unwrap());
            res.push_str(": ");
            res.push_str(&self.current_sequence);
            self.current_name = None;
            self.current_sequence.clear();
            self.current_sequence.shrink_to_fit();
            return Some(res);
        }
        None
    }
}


import java.io.File
import java.util.Scanner

object ReadFastaFile extends App {
  val sc = new Scanner(new File("test.fasta"))
  var first = true

  while (sc.hasNextLine) {
    val line = sc.nextLine.trim
    if (line.charAt(0) == '>') {
      if (first) first = false
      else println()
      printf("%s: ", line.substring(1))
    }
    else print(line)
  }

  println("~~~+~~~")
}


(import (scheme base)
        (scheme file)
        (scheme write))

(with-input-from-file ; reads text from named file, one line at a time
  "fasta.txt"
  (lambda ()
    (do ((first-line? #t #f)
         (line (read-line) (read-line)))
      ((eof-object? line) (newline))
      (cond ((char=? #\> (string-ref line 0)) ; found a name
             (unless first-line? ; no newline on first name
               (newline))
             (display (string-copy line 1)) (display ": "))
            (else ; display the string directly
              (display line))))))


#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int binomial(int n, int k) {
    int num, denom, i;

    if (n < 0 || k < 0 || n < k) return -1;
    if (n == 0 || k == 0) return 1;

    num = 1;
    for (i = k + 1; i <= n; ++i) {
        num = num * i;
    }

    denom = 1;
    for (i = 2; i <= n - k; ++i) {
        denom *= i;
    }

    return num / denom;
}

int gcd(int a, int b) {
    int temp;
    while (b != 0) {
        temp = a % b;
        a = b;
        b = temp;
    }
    return a;
}

typedef struct tFrac {
    int num, denom;
} Frac;

Frac makeFrac(int n, int d) {
    Frac result;
    int g;

    if (d == 0) {
        result.num = 0;
        result.denom = 0;
        return result;
    }

    if (n == 0) {
        d = 1;
    } else if (d < 0) {
        n = -n;
        d = -d;
    }

    g = abs(gcd(n, d));
    if (g > 1) {
        n = n / g;
        d = d / g;
    }

    result.num = n;
    result.denom = d;
    return result;
}

Frac negateFrac(Frac f) {
    return makeFrac(-f.num, f.denom);
}

Frac subFrac(Frac lhs, Frac rhs) {
    return makeFrac(lhs.num * rhs.denom - lhs.denom * rhs.num, rhs.denom * lhs.denom);
}

Frac multFrac(Frac lhs, Frac rhs) {
    return makeFrac(lhs.num * rhs.num, lhs.denom * rhs.denom);
}

bool equalFrac(Frac lhs, Frac rhs) {
    return (lhs.num == rhs.num) && (lhs.denom == rhs.denom);
}

bool lessFrac(Frac lhs, Frac rhs) {
    return (lhs.num * rhs.denom) < (rhs.num * lhs.denom);
}

void printFrac(Frac f) {
    char buffer[7];
    int len;

    if (f.denom != 1) {
        snprintf(buffer, 7, "%d/%d", f.num, f.denom);
    } else {
        snprintf(buffer, 7, "%d", f.num);
    }

    len = 7 - strlen(buffer);
    while (len-- > 0) {
        putc(' ', stdout);
    }

    printf(buffer);
}

Frac bernoulli(int n) {
    Frac a[16];
    int j, m;

    if (n < 0) {
        a[0].num = 0;
        a[0].denom = 0;
        return a[0];
    }

    for (m = 0; m <= n; ++m) {
        a[m] = makeFrac(1, m + 1);
        for (j = m; j >= 1; --j) {
            a[j - 1] = multFrac(subFrac(a[j - 1], a[j]), makeFrac(j, 1));
        }
    }

    if (n != 1) {
        return a[0];
    }

    return negateFrac(a[0]);
}

void faulhaber(int p) {
    Frac q, *coeffs;
    int j, sign;

    coeffs = malloc(sizeof(Frac)*(p + 1));

    q = makeFrac(1, p + 1);
    sign = -1;
    for (j = 0; j <= p; ++j) {
        sign = -1 * sign;
        coeffs[p - j] = multFrac(multFrac(multFrac(q, makeFrac(sign, 1)), makeFrac(binomial(p + 1, j), 1)), bernoulli(j));
    }

    for (j = 0; j <= p; ++j) {
        printFrac(coeffs[j]);
    }
    printf("\n");

    free(coeffs);
}

int main() {
    int i;

    for (i = 0; i < 10; ++i) {
        faulhaber(i);
    }

    return 0;
}


import std.algorithm : fold;
import std.exception : enforce;
import std.format : formattedWrite;
import std.numeric : cmp, gcd;
import std.range : iota;
import std.stdio;
import std.traits;

auto abs(T)(T val)
if (isNumeric!T) {
    if (val < 0) {
        return -val;
    }
    return val;
}

struct Frac {
    long num;
    long denom;

    enum ZERO = Frac(0, 1);
    enum ONE = Frac(1, 1);

    this(long n, long d) in {
        enforce(d != 0, "Parameter d may not be zero.");
    } body {
        auto nn = n;
        auto dd = d;
        if (nn == 0) {
            dd = 1;
        } else if (dd < 0) {
            nn = -nn;
            dd = -dd;
        }
        auto g = gcd(abs(nn), abs(dd));
        if (g > 1) {
            nn /= g;
            dd /= g;
        }
        num = nn;
        denom = dd;
    }

    auto opBinary(string op)(Frac rhs) const {
        static if (op == "+" || op == "-") {
            return mixin("Frac(num*rhs.denom"~op~"denom*rhs.num, rhs.denom*denom)");
        } else if (op == "*") {
            return Frac(num*rhs.num, denom*rhs.denom);
        }
    }

    auto opUnary(string op : "-")() const {
        return Frac(-num, denom);
    }

    int opCmp(Frac rhs) const {
        return cmp(cast(real) this, cast(real) rhs);
    }

    bool opEquals(Frac rhs) const {
        return num == rhs.num && denom == rhs.denom;
    }

    void toString(scope void delegate(const(char)[]) sink) const {
        if (denom == 1) {
            formattedWrite(sink, "%d", num);
        } else {
            formattedWrite(sink, "%d/%s", num, denom);
        }
    }

    T opCast(T)() const if (isFloatingPoint!T) {
        return cast(T) num / denom;
    }
}

auto abs(Frac f) {
    if (f.num >= 0) {
        return f;
    }
    return -f;
}

auto bernoulli(int n) in {
    enforce(n >= 0, "Parameter n must not be negative.");
} body {
    Frac[] a;
    a.length = n+1;
    a[0] = Frac.ZERO;
    foreach (m; 0..n+1) {
        a[m] = Frac(1, m+1);
        foreach_reverse (j; 1..m+1) {
            a[j-1] = (a[j-1] - a[j]) * Frac(j, 1);
        }
    }
    if (n != 1) {
        return a[0];
    }
    return -a[0];
}

auto binomial(int n, int k) in {
    enforce(n>=0 && k>=0 && n>=k);
} body {
    if (n==0 || k==0) return 1;
    auto num = iota(k+1, n+1).fold!"a*b"(1);
    auto den = iota(2, n-k+1).fold!"a*b"(1);
    return num / den;
}

auto faulhaber(int p) {
    write(p, " : ");
    auto q = Frac(1, p+1);
    auto sign = -1;
    foreach (j; 0..p+1) {
        sign *= -1;
        auto coeff = q * Frac(sign, 1) * Frac(binomial(p+1, j), 1) * bernoulli(j);
        if (coeff == Frac.ZERO) continue;
        if (j == 0) {
            if (coeff == -Frac.ONE) {
                write("-");
            } else if (coeff != Frac.ONE) {
                write(coeff);
            }
        } else {
            if (coeff == Frac.ONE) {
                write(" + ");
            } else if (coeff == -Frac.ONE) {
                write(" - ");
            } else if (coeff > Frac.ZERO) {
                write(" + ", coeff);
            } else {
                write(" - ", -coeff);
            }
        }
        auto pwr = p + 1 - j;
        if (pwr > 1) {
            write("n^", pwr);
        } else {
            write("n");
        }
    }
    writeln;
}

void main() {
    foreach (i; 0..10) {
        faulhaber(i);
    }
}


$ include "seed7_05.s7i";

const proc: main is func
  local
    var file: fastaFile is STD_NULL;
    var string: line is "";
    var boolean: first is TRUE;
  begin
    fastaFile := open("fasta_format.in", "r");
    if fastaFile <> STD_NULL then
      while hasNext(fastaFile) do
        line := getln(fastaFile);
        if startsWith(line, ">") then
          if first then
            first := FALSE;
          else
            writeln;
          end if;
          write(line[2 ..] <& ": ");
        else
          write(line);
        end if;
      end while;
      close(fastaFile);
    end if;
    writeln;
  end func;


func fasta_format(strings) {
    var out = []
    var text = ''
    for line in (strings.lines) {
        if (line.begins_with('>')) {
            text.len && (out << text)
            text = line.substr(1)+': '
        }
        else {
            text += line
        }
    }
    text.len && (out << text)
    return out
}

fasta_format(DATA.slurp).each { .say }

__DATA__
>Rosetta_Example_1
THERECANBENOSPACE
>Rosetta_Example_2
THERECANBESEVERAL
LINESBUTTHEYALLMUST
BECONCATENATED


proc fastaReader {filename} {
    set f [open $filename]
    set sep ""
    while {[gets $f line] >= 0} {
	if {[string match >* $line]} {
	    puts -nonewline "$sep[string range $line 1 end]: "
	    set sep "\n"
	} else {
	    puts -nonewline $line
	}
    }
    puts ""
    close $f
}

fastaReader ./rosettacode.fas


prog:   ignore(spaces)
loop:   parse(line)\loop parse(( = {*} ));
line:   ( name | * = {} | seqns );
name:   <>> ignore(none) smark string(nonl) scopy *
        ( [f>0?] = {} | = {*} ) [f=0]
        = { 1 2 <: > };
seqns:  smark string(nonl) scopy * [f=0];

none:   <<>>;
nonl:   !<<
>>;
spaces:	<< 	>>;

f:      1;


using System;

namespace FaulhabersTriangle {
    internal class Frac {
        private long num;
        private long denom;

        public static readonly Frac ZERO = new Frac(0, 1);
        public static readonly Frac ONE = new Frac(1, 1);

        public Frac(long n, long d) {
            if (d == 0) {
                throw new ArgumentException("d must not be zero");
            }
            long nn = n;
            long dd = d;
            if (nn == 0) {
                dd = 1;
            }
            else if (dd < 0) {
                nn = -nn;
                dd = -dd;
            }
            long g = Math.Abs(Gcd(nn, dd));
            if (g > 1) {
                nn /= g;
                dd /= g;
            }
            num = nn;
            denom = dd;
        }

        private static long Gcd(long a, long b) {
            if (b == 0) {
                return a;
            }
            return Gcd(b, a % b);
        }

        public static Frac operator -(Frac self) {
            return new Frac(-self.num, self.denom);
        }

        public static Frac operator +(Frac lhs, Frac rhs) {
            return new Frac(lhs.num * rhs.denom + lhs.denom * rhs.num, rhs.denom * lhs.denom);
        }

        public static Frac operator -(Frac lhs, Frac rhs) {
            return lhs + -rhs;
        }

        public static Frac operator *(Frac lhs, Frac rhs) {
            return new Frac(lhs.num * rhs.num, lhs.denom * rhs.denom);
        }

        public static bool operator <(Frac lhs, Frac rhs) {
            double x = (double)lhs.num / lhs.denom;
            double y = (double)rhs.num / rhs.denom;
            return x < y;
        }

        public static bool operator >(Frac lhs, Frac rhs) {
            double x = (double)lhs.num / lhs.denom;
            double y = (double)rhs.num / rhs.denom;
            return x > y;
        }

        public static bool operator ==(Frac lhs, Frac rhs) {
            return lhs.num == rhs.num && lhs.denom == rhs.denom;
        }

        public static bool operator !=(Frac lhs, Frac rhs) {
            return lhs.num != rhs.num || lhs.denom != rhs.denom;
        }

        public override string ToString() {
            if (denom == 1) {
                return num.ToString();
            }
            return string.Format("{0}/{1}", num, denom);
        }

        public override bool Equals(object obj) {
            var frac = obj as Frac;
            return frac != null &&
                   num == frac.num &&
                   denom == frac.denom;
        }

        public override int GetHashCode() {
            var hashCode = 1317992671;
            hashCode = hashCode * -1521134295 + num.GetHashCode();
            hashCode = hashCode * -1521134295 + denom.GetHashCode();
            return hashCode;
        }
    }

    class Program {
        static Frac Bernoulli(int n) {
            if (n < 0) {
                throw new ArgumentException("n may not be negative or zero");
            }
            Frac[] a = new Frac[n + 1];
            for (int m = 0; m <= n; m++) {
                a[m] = new Frac(1, m + 1);
                for (int j = m; j >= 1; j--) {
                    a[j - 1] = (a[j - 1] - a[j]) * new Frac(j, 1);
                }
            }
            // returns 'first' Bernoulli number
            if (n != 1) return a[0];
            return -a[0];
        }

        static int Binomial(int n, int k) {
            if (n < 0 || k < 0 || n < k) {
                throw new ArgumentException();
            }
            if (n == 0 || k == 0) return 1;
            int num = 1;
            for (int i = k + 1; i <= n; i++) {
                num = num * i;
            }
            int denom = 1;
            for (int i = 2; i <= n - k; i++) {
                denom = denom * i;
            }
            return num / denom;
        }

        static Frac[] FaulhaberTriangle(int p) {
            Frac[] coeffs = new Frac[p + 1];
            for (int i = 0; i < p + 1; i++) {
                coeffs[i] = Frac.ZERO;
            }
            Frac q = new Frac(1, p + 1);
            int sign = -1;
            for (int j = 0; j <= p; j++) {
                sign *= -1;
                coeffs[p - j] = q * new Frac(sign, 1) * new Frac(Binomial(p + 1, j), 1) * Bernoulli(j);
            }
            return coeffs;
        }

        static void Main(string[] args) {
            for (int i = 0; i < 10; i++) {
                Frac[] coeffs = FaulhaberTriangle(i);
                foreach (Frac coeff in coeffs) {
                    Console.Write("{0,5}  ", coeff);
                }
                Console.WriteLine();
            }
        }
    }
}


(lib 'math) ;; for bernoulli numbers
(string-delimiter "")

;; returns list of polynomial coefficients
(define (Faulhaber p)
	(cons 0
	(for/list ([k (in-range p -1 -1)])
		(* (Cnp (1+ p) k) (bernoulli k)))))

;; prints formal polynomial
(define (task (pmax 10))
    (for ((p pmax))
    (writeln p '→  (/ 1 (1+ p)) '* (poly->string 'n (Faulhaber p)))))

;; extra credit - compute sums
(define (Faulcomp n p)
	(printf "Σ(1..%d) n^%d = %d" n p (/  (poly n (Faulhaber p)) (1+ p) )))


USING: formatting kernel math math.combinatorics math.extras
math.functions regexp sequences ;

: faulhaber ( p -- seq )
    1 + dup recip swap dup <iota>
    [ [ nCk ] [ -1 swap ^ ] [ bernoulli ] tri * * * ] 2with map ;

: (poly>str) ( seq -- str )
    reverse [ 1 + "%un^%d" sprintf ] map-index reverse " + " join ;

: clean-up ( str -- str' )
    R/ n\^1\z/ "n" re-replace            ! Change n^1 to n.
    R/ 1n/ "n" re-replace                ! Change 1n to n.
    R/ \+ -/ "- " re-replace             ! Change + - to - .
    R/ [+-] 0n(\^\d+ )?/ "" re-replace ; ! Remove terms of zero.

: poly>str ( seq -- str ) (poly>str) clean-up ;

10 [ dup faulhaber poly>str "%d: %s\n" printf ] each-integer


If Cmd (0) < 2 Then Print "Usage: fasta <fasta file>" : End
If Set(a, Open (Cmd(2), "r")) < 0 Then Print "Cannot open \q";Cmd(2);"\q" : End

Do While Read (a)                      ' while there are lines to process
  t = Tok (0)                          ' get a lime

  If Peek(t, 0) = Ord(">") Then        ' if it's a marker
    Print Show (Chop(t, 1)); ": "; Show (FUNC(_Payload(a)))
    Continue                           ' get the payload and print it
  EndIf

  Print "Out of sequence" : Break      ' this should never happen
Loop

Close a                                ' close the file
End                                    ' and end the program

_Payload                               ' get the payload
  Param (1)
  Local (4)

  [email protected] = Dup("")                         ' start with an empty string

  Do
    [email protected] = Mark([email protected])                      ' mark its position
  While Read ([email protected])                      ' now read a line
    [email protected] = Tok (0)                       ' get the line
    If Peek ([email protected], 0) = Ord(">") Then [email protected] = Head([email protected], [email protected]) : Break
    [email protected] = Join ([email protected], [email protected])                 ' marker? reset position and exit
  Loop                                 ' if not add the line to current string

Return ([email protected])                            ' return the string


import "io" for File

var checkNoSpaces = Fn.new { |s| !s.contains(" ") && !s.contains("\t") }

var first = true

var process = Fn.new { |line|
    if (line[0] == ">") {
        if (!first) System.print()
        System.write("%(line[1..-1]): ")
        if (first) first = false
    } else if (first) {
        Fiber.abort("File does not begin with '>'.")
    } else if (checkNoSpaces.call(line)) {
        System.write(line)
    } else {
        Fiber.abort("Sequence contains space(s).")
    }
}

var fileName = "input.fasta"
File.open(fileName) { |file|
    var offset = 0
    var line = ""
    while(true) {
        var b = file.readBytes(1, offset)
        offset = offset + 1
        if (b == "\n") {
            process.call(line)
            line = "" // reset line variable
        } else if (b == "\r") { // Windows
            // wait for following "\n"
        } else if (b == "") { // end of stream
            System.print()
            return
        } else {
            line = line + b
        }
    }
}


#include <exception>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <sstream>
#include <vector>

class Frac {
public:

	Frac() : num(0), denom(1) {}

	Frac(int n, int d) {
		if (d == 0) {
			throw std::runtime_error("d must not be zero");
		}

		int sign_of_d = d < 0 ? -1 : 1;
		int g = std::gcd(n, d);

        num = sign_of_d * n / g;
        denom = sign_of_d * d / g;
	}

	Frac operator-() const {
		return Frac(-num, denom);
	}

	Frac operator+(const Frac& rhs) const {
		return Frac(num*rhs.denom + denom * rhs.num, rhs.denom*denom);
	}

	Frac operator-(const Frac& rhs) const {
		return Frac(num*rhs.denom - denom * rhs.num, rhs.denom*denom);
	}

	Frac operator*(const Frac& rhs) const {
		return Frac(num*rhs.num, denom*rhs.denom);
	}

	Frac operator*(int rhs) const {
		return Frac(num * rhs, denom);
	}

	friend std::ostream& operator<<(std::ostream&, const Frac&);

private:
	int num;
	int denom;
};

std::ostream & operator<<(std::ostream & os, const Frac &f) {
	if (f.num == 0 || f.denom == 1) {
		return os << f.num;
	}

	std::stringstream ss;
	ss << f.num << "/" << f.denom;
	return os << ss.str();
}

Frac bernoulli(int n) {
	if (n < 0) {
		throw std::runtime_error("n may not be negative or zero");
	}

	std::vector<Frac> a;
	for (int m = 0; m <= n; m++) {
		a.push_back(Frac(1, m + 1));
		for (int j = m; j >= 1; j--) {
			a[j - 1] = (a[j - 1] - a[j]) * j;
		}
	}

	// returns 'first' Bernoulli number
	if (n != 1) return a[0];
	return -a[0];
}

int binomial(int n, int k) {
	if (n < 0 || k < 0 || n < k) {
		throw std::runtime_error("parameters are invalid");
	}
	if (n == 0 || k == 0) return 1;

	int num = 1;
	for (int i = k + 1; i <= n; i++) {
		num *= i;
	}

	int denom = 1;
	for (int i = 2; i <= n - k; i++) {
		denom *= i;
	}

	return num / denom;
}

std::vector<Frac> faulhaberTraingle(int p) {
	std::vector<Frac> coeffs(p + 1);

	Frac q{ 1, p + 1 };
	int sign = -1;
	for (int j = 0; j <= p; j++) {
		sign *= -1;
		coeffs[p - j] = q * sign * binomial(p + 1, j) * bernoulli(j);
	}

	return coeffs;
}

int main() {

	for (int i = 0; i < 10; i++) {
		std::vector<Frac> coeffs = faulhaberTraingle(i);
		for (auto frac : coeffs) {
			std::cout << std::right << std::setw(5) << frac << "  ";
		}
		std::cout << std::endl;
	}

	return 0;
}


package main

import (
	"fmt"
	"math/big"
)

func bernoulli(z *big.Rat, n int64) *big.Rat {
	if z == nil {
		z = new(big.Rat)
	}
	a := make([]big.Rat, n+1)
	for m := range a {
		a[m].SetFrac64(1, int64(m+1))
		for j := m; j >= 1; j-- {
			d := &a[j-1]
			d.Mul(z.SetInt64(int64(j)), d.Sub(d, &a[j]))
		}
	}
	return z.Set(&a[0])
}

func main() {
	// allocate needed big.Rat's once
	q := new(big.Rat)
	c := new(big.Rat)      // coefficients
	be := new(big.Rat)     // for Bernoulli numbers
	bi := big.NewRat(1, 1) // for binomials

	for p := int64(0); p < 10; p++ {
		fmt.Print(p, " : ")
		q.SetFrac64(1, p+1)
		neg := true
		for j := int64(0); j <= p; j++ {
			neg = !neg
			if neg {
				c.Neg(q)
			} else {
				c.Set(q)
			}
			bi.Num().Binomial(p+1, j)
			bernoulli(be, j)
			c.Mul(c, bi)
			c.Mul(c, be)
			if c.Num().BitLen() == 0 {
				continue
			}
			if j == 0 {
				fmt.Printf(" %4s", c.RatString())
			} else {
				fmt.Printf(" %+2d/%-2d", c.Num(), c.Denom())
			}
			fmt.Print("×n")
			if exp := p + 1 - j; exp > 1 {
				fmt.Printf("^%-2d", exp)
			}
		}
		fmt.Println()
	}
}


proc Echo;      \Echo line of characters from file to screen
int Ch;
def LF=$0A, EOF=$1A;
[loop   [Ch:= ChIn(3);
        case Ch of
          EOF:  exit;
          LF:   quit
        other ChOut(0, Ch);
        ];
];

int Ch;
[FSet(FOpen("fasta.txt", 0), ^i);
loop    [Ch:= ChIn(3);
        if Ch = ^> then
                [CrLf(0);
                Echo;
                Text(0, ": ");
                ]
        else    ChOut(0, Ch);
        Echo;
        ];
]


fcn fasta(data){ // a lazy cruise through a FASTA file
   fcn(w){      // one string at a time, -->False garbage at front of file
      line:=w.next().strip();
      if(line[0]==">") w.pump(line[1,*]+": ",'wrap(l){
         if(l[0]==">") { w.push(l); Void.Stop } else l.strip()
      })
   }.fp(data.walker()) : Utils.Helpers.wap(_);
}


import std.algorithm : fold;
import std.conv : to;
import std.exception : enforce;
import std.format : formattedWrite;
import std.numeric : cmp, gcd;
import std.range : iota;
import std.stdio;
import std.traits;

auto abs(T)(T val)
if (isNumeric!T) {
    if (val < 0) {
        return -val;
    }
    return val;
}

struct Frac {
    long num;
    long denom;

    enum ZERO = Frac(0, 1);
    enum ONE = Frac(1, 1);

    this(long n, long d) in {
        enforce(d != 0, "Parameter d may not be zero.");
    } body {
        auto nn = n;
        auto dd = d;
        if (nn == 0) {
            dd = 1;
        } else if (dd < 0) {
            nn = -nn;
            dd = -dd;
        }
        auto g = gcd(abs(nn), abs(dd));
        if (g > 1) {
            nn /= g;
            dd /= g;
        }
        num = nn;
        denom = dd;
    }

    auto opBinary(string op)(Frac rhs) const {
        static if (op == "+" || op == "-") {
            return mixin("Frac(num*rhs.denom"~op~"denom*rhs.num, rhs.denom*denom)");
        } else if (op == "*") {
            return Frac(num*rhs.num, denom*rhs.denom);
        }
    }

    auto opUnary(string op : "-")() const {
        return Frac(-num, denom);
    }

    int opCmp(Frac rhs) const {
        return cmp(cast(real) this, cast(real) rhs);
    }

    bool opEquals(Frac rhs) const {
        return num == rhs.num && denom == rhs.denom;
    }

    void toString(scope void delegate(const(char)[]) sink) const {
        if (denom == 1) {
            formattedWrite(sink, "%d", num);
        } else {
            formattedWrite(sink, "%d/%s", num, denom);
        }
    }

    T opCast(T)() const if (isFloatingPoint!T) {
        return cast(T) num / denom;
    }
}

auto abs(Frac f) {
    if (f.num >= 0) {
        return f;
    }
    return -f;
}

auto bernoulli(int n) in {
    enforce(n >= 0, "Parameter n must not be negative.");
} body {
    Frac[] a;
    a.length = n+1;
    a[0] = Frac.ZERO;
    foreach (m; 0..n+1) {
        a[m] = Frac(1, m+1);
        foreach_reverse (j; 1..m+1) {
            a[j-1] = (a[j-1] - a[j]) * Frac(j, 1);
        }
    }
    if (n != 1) {
        return a[0];
    }
    return -a[0];
}

auto binomial(int n, int k) in {
    enforce(n>=0 && k>=0 && n>=k);
} body {
    if (n==0 || k==0) return 1;
    auto num = iota(k+1, n+1).fold!"a*b"(1);
    auto den = iota(2, n-k+1).fold!"a*b"(1);
    return num / den;
}

Frac[] faulhaberTriangle(int p) {
    Frac[] coeffs;
    coeffs.length = p+1;
    coeffs[0] = Frac.ZERO;
    auto q = Frac(1, p+1);
    auto sign = -1;
    foreach (j; 0..p+1) {
        sign *= -1;
        coeffs[p - j] = q * Frac(sign, 1) * Frac(binomial(p+1, j), 1) * bernoulli(j);
    }
    return coeffs;
}

void main() {
    foreach (i; 0..10) {
        auto coeffs = faulhaberTriangle(i);
        foreach (coeff; coeffs) {
            writef("%5s  ", coeff.to!string);
        }
        writeln;
    }
    writeln;
}


import java.util.stream.IntStream

class FaulhabersFormula {
    private static long gcd(long a, long b) {
        if (b == 0) {
            return a
        }
        return gcd(b, a % b)
    }

    private static class Frac implements Comparable<Frac> {
        private long num
        private long denom

        public static final Frac ZERO = new Frac(0, 1)
        public static final Frac ONE = new Frac(1, 1)

        Frac(long n, long d) {
            if (d == 0) throw new IllegalArgumentException("d must not be zero")
            long nn = n
            long dd = d
            if (nn == 0) {
                dd = 1
            } else if (dd < 0) {
                nn = -nn
                dd = -dd
            }
            long g = Math.abs(gcd(nn, dd))
            if (g > 1) {
                nn /= g
                dd /= g
            }
            num = nn
            denom = dd
        }

        Frac plus(Frac rhs) {
            return new Frac(num * rhs.denom + denom * rhs.num, rhs.denom * denom)
        }

        Frac negative() {
            return new Frac(-num, denom)
        }

        Frac minus(Frac rhs) {
            return this + -rhs
        }

        Frac multiply(Frac rhs) {
            return new Frac(this.num * rhs.num, this.denom * rhs.denom)
        }

        @Override
        int compareTo(Frac o) {
            double diff = toDouble() - o.toDouble()
            return Double.compare(diff, 0.0)
        }

        @Override
        boolean equals(Object obj) {
            return null != obj && obj instanceof Frac && this == (Frac) obj
        }

        @Override
        String toString() {
            if (denom == 1) {
                return Long.toString(num)
            }
            return String.format("%d/%d", num, denom)
        }

        private double toDouble() {
            return (double) num / denom
        }
    }

    private static Frac bernoulli(int n) {
        if (n < 0) throw new IllegalArgumentException("n may not be negative or zero")
        Frac[] a = new Frac[n + 1]
        Arrays.fill(a, Frac.ZERO)
        for (int m = 0; m <= n; ++m) {
            a[m] = new Frac(1, m + 1)
            for (int j = m; j >= 1; --j) {
                a[j - 1] = (a[j - 1] - a[j]) * new Frac(j, 1)
            }
        }
        // returns 'first' Bernoulli number
        if (n != 1) return a[0]
        return -a[0]
    }

    private static int binomial(int n, int k) {
        if (n < 0 || k < 0 || n < k) throw new IllegalArgumentException()
        if (n == 0 || k == 0) return 1
        int num = IntStream.rangeClosed(k + 1, n).reduce(1, { a, b -> a * b })
        int den = IntStream.rangeClosed(2, n - k).reduce(1, { acc, i -> acc * i })
        return num / den
    }

    private static void faulhaber(int p) {
        print("$p : ")
        Frac q = new Frac(1, p + 1)
        int sign = -1
        for (int j = 0; j <= p; ++j) {
            sign *= -1
            Frac coeff = q * new Frac(sign, 1) * new Frac(binomial(p + 1, j), 1) * bernoulli(j)
            if (Frac.ZERO == coeff) continue
            if (j == 0) {
                if (Frac.ONE != coeff) {
                    if (-Frac.ONE == coeff) {
                        print("-")
                    } else {
                        print(coeff)
                    }
                }
            } else {
                if (Frac.ONE == coeff) {
                    print(" + ")
                } else if (-Frac.ONE == coeff) {
                    print(" - ")
                } else if (coeff > Frac.ZERO) {
                    print(" + $coeff")
                } else {
                    print(" - ${-coeff}")
                }
            }
            int pwr = p + 1 - j
            if (pwr > 1) {
                print("n^$pwr")
            } else {
                print("n")
            }
        }
        println()
    }

    static void main(String[] args) {
        for (int i = 0; i <= 9; ++i) {
            faulhaber(i)
        }
    }
}


// Generate Faulhaber's Triangle. Nigel Galloway: May 8th., 2018
let Faulhaber=let fN n = (1N - List.sum n)::n
              let rec Faul a b=seq{let t = fN (List.mapi(fun n g->b*g/BigRational.FromInt(n+2)) a)
                                   yield t
                                   yield! Faul t (b+1N)}
              Faul [] 0N


USING: kernel math math.combinatorics math.extras math.functions
math.ranges prettyprint sequences ;

: faulhaber ( p -- seq )
    1 + dup recip swap dup 0 (a,b]
    [ [ nCk ] [ -1 swap ^ ] [ bernoulli ] tri * * * ] 2with map ;

10 [ faulhaber . ] each-integer


' version 12-08-2017
' compile with: fbc -s console
' uses GMP

#Include Once "gmp.bi"

#Define i_max 17

Dim As UInteger i, j, x
Dim As String   s
Dim As ZString Ptr gmp_str : gmp_str = Allocate(100)

Dim As Mpq_ptr n, tmp1, tmp2, sum, one, zero
n    = Allocate(Len(__mpq_struct)) : Mpq_init(n)
tmp1 = Allocate(Len(__mpq_struct)) : Mpq_init(tmp1)
tmp2 = Allocate(Len(__mpq_struct)) : Mpq_init(tmp2)
sum  = Allocate(Len(__mpq_struct)) : Mpq_init(sum)
zero = Allocate(Len(__mpq_struct)) : Mpq_init(zero)
one  = Allocate(Len(__mpq_struct)) : Mpq_init(one)
Mpq_set_ui(zero, 0, 0)  ' 0/0 = 0
Mpq_set_ui(one , 1, 1)  ' 1/1 = 1

Dim As Mpq_ptr Faulhaber_triangle(0 To i_max, 1 To i_max +1)
' only initialize the variables we need
For i = 0 To i_max
    For j = 1 To i +1
        Faulhaber_triangle(i, j) = Allocate(Len(__Mpq_struct))
        Mpq_init(Faulhaber_triangle(i, j))
    Next
Next

Mpq_set(Faulhaber_triangle(0, 1), one)

' we calculate the first 18 rows
For i = 1 To i_max
    Mpq_set(sum, zero)
    For j = i +1 To 2 Step -1
        Mpq_set_ui(tmp1, i, j)            ' i / j
        Mpq_set(tmp2, Faulhaber_triangle(i -1, j -1))
        Mpq_mul(Faulhaber_triangle(i, j), tmp2, tmp1)
        Mpq_canonicalize(Faulhaber_triangle(i, j))
        Mpq_add(sum, sum, Faulhaber_triangle(i, j))
    Next
    Mpq_sub(Faulhaber_triangle(i, 1), one, sum)
Next

Print "The first 10 rows"
For i = 0 To 9
    For j = 1 To i +1
        Mpq_get_str(gmp_str, 10, Faulhaber_triangle(i, j))
        s = Space(6) + *gmp_str + Space(6)
        x = InStr(s,"/")
        If x = 0 Then x = 7               ' in case of 0 or 1
        Print Mid(s, x -3, 7);
    Next
    Print
Next
print

' using the 17'the row
Mpq_set(sum, zero)
Mpq_set_ui(n, 1000, 1)                    ' 1000/1 = 1000
Mpq_set(tmp2, n)
For j = 1 To 18
    Mpq_mul(tmp1, n, Faulhaber_triangle(17, j))
    Mpq_add(sum, sum, tmp1)
    Mpq_mul(n, n, tmp2)
Next

Mpq_get_str(gmp_str, 10, sum)
Print *gmp_str

' free memory
DeAllocate(gmp_str)
Mpq_clear(tmp1) : Mpq_clear(tmp2) : Mpq_clear(n)
Mpq_clear(zero) : Mpq_clear(one)  : Mpq_clear(sum)

For i = 0 To i_max
    For j = 1 To i +1
        Mpq_clear(Faulhaber_triangle(i, j))
    Next
Next

' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End


import Data.Ratio ((%), numerator, denominator)
import Data.List (intercalate, transpose)
import Data.Bifunctor (bimap)
import Data.Char (isSpace)
import Data.Monoid ((<>))
import Data.Bool (bool)

------------------------- FAULHABER ------------------------
faulhaber :: [[Rational]]
faulhaber =
  tail $
  scanl
    (\rs n ->
        let xs = zipWith ((*) . (n %)) [2 ..] rs
        in 1 - sum xs : xs)
    []
    [0 ..]

polynomials :: [[(String, String)]]
polynomials = fmap ((ratioPower =<<) . reverse . flip zip [1 ..]) faulhaber

---------------------------- TEST --------------------------
main :: IO ()
main = (putStrLn . unlines . expressionTable . take 10) polynomials

--------------------- EXPRESSION STRINGS -------------------

-- Rows of (Power string, Ratio string) tuples -> Printable lines
expressionTable :: [[(String, String)]] -> [String]
expressionTable ps =
  let cols = transpose (fullTable ps)
  in expressionRow <$>
     zip
       [0 ..]
       (transpose $
        zipWith
          (\(lw, rw) col ->
              fmap (bimap (justifyLeft lw ' ') (justifyLeft rw ' ')) col)
          (colWidths cols)
          cols)

-- Value pair -> String pair (lifted into list for use with >>=)
ratioPower :: (Rational, Integer) -> [(String, String)]
ratioPower (nd, j) =
  let (num, den) = ((,) . numerator <*> denominator) nd
      sn
        | num == 0 = []
        | (j /= 1) = ("n^" <> show j)
        | otherwise = "n"
      sr
        | num == 0 = []
        | den == 1 && num == 1 = []
        | den == 1 = show num <> "n"
        | otherwise = intercalate "/" [show num, show den]
      s = sr <> sn
  in bool [(sn, sr)] [] (null s)

-- Rows of uneven length -> All rows padded to length of longest
fullTable :: [[(String, String)]] -> [[(String, String)]]
fullTable xs =
  let lng = maximum $ length <$> xs
  in (<>) <*> (flip replicate ([], []) . (-) lng . length) <$> xs

justifyLeft :: Int -> Char -> String -> String
justifyLeft n c s = take n (s <> replicate n c)

-- (Row index, Expression pairs) -> String joined by conjunctions
expressionRow :: (Int, [(String, String)]) -> String
expressionRow (i, row) =
  concat
    [ show i
    , " ->  "
    , foldr
        (\s a -> concat [s, bool " + " " " (blank a || head a == '-'), a])
        []
        (polyTerm <$> row)
    ]

-- (Power string, Ratio String) -> Combined string with possible '*'
polyTerm :: (String, String) -> String
polyTerm (l, r)
  | blank l || blank r = l <> r
  | head r == '-' = concat ["- ", l, " * ", tail r]
  | otherwise = intercalate " * " [l, r]

blank :: String -> Bool
blank = all isSpace

-- Maximum widths of power and ratio elements in each column
colWidths :: [[(String, String)]] -> [(Int, Int)]
colWidths =
  fmap
    (foldr
       (\(ls, rs) (lMax, rMax) -> (max (length ls) lMax, max (length rs) rMax))
       (0, 0))

-- Length of string excluding any leading '-'
unsignedLength :: String -> Int
unsignedLength xs =
  let l = length xs
  in bool (bool l (l - 1) ('-' == head xs)) 0 (0 == l)


package main

import (
    "fmt"
    "math/big"
)

func bernoulli(n uint) *big.Rat {
    a := make([]big.Rat, n+1)
    z := new(big.Rat)
    for m := range a {
        a[m].SetFrac64(1, int64(m+1))
        for j := m; j >= 1; j-- {
            d := &a[j-1]
            d.Mul(z.SetInt64(int64(j)), d.Sub(d, &a[j]))
        }
    }
    // return the 'first' Bernoulli number
    if n != 1 {
        return &a[0]
    }
    a[0].Neg(&a[0])
    return &a[0]
}

func binomial(n, k int) int64 {
    if n <= 0 || k <= 0 || n < k {
        return 1
    }
    var num, den int64 = 1, 1
    for i := k + 1; i <= n; i++ {
        num *= int64(i)
    }
    for i := 2; i <= n-k; i++ {
        den *= int64(i)
    }
    return num / den
}

func faulhaberTriangle(p int) []big.Rat {
    coeffs := make([]big.Rat, p+1)
    q := big.NewRat(1, int64(p)+1)
    t := new(big.Rat)
    u := new(big.Rat)
    sign := -1
    for j := range coeffs {
        sign *= -1
        d := &coeffs[p-j]
        t.SetInt64(int64(sign))
        u.SetInt64(binomial(p+1, j))
        d.Mul(q, t)
        d.Mul(d, u)
        d.Mul(d, bernoulli(uint(j)))
    }
    return coeffs
}

func main() {
    for i := 0; i < 10; i++ {
        coeffs := faulhaberTriangle(i)
        for _, coeff := range coeffs {
            fmt.Printf("%5s  ", coeff.RatString())
        }
        fmt.Println()
    }
    fmt.Println()
    // get coeffs for (k + 1)th row
    k := 17
    cc := faulhaberTriangle(k)
    n := int64(1000)
    nn := big.NewRat(n, 1)
    np := big.NewRat(1, 1)
    sum := new(big.Rat)
    tmp := new(big.Rat)
    for _, c := range cc {
        np.Mul(np, nn)
        tmp.Set(np)
        tmp.Mul(tmp, &c)
        sum.Add(sum, tmp)
    }
    fmt.Println(sum.RatString())
}


import java.util.Arrays;
import java.util.stream.IntStream;

public class FaulhabersFormula {
    private static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    private static class Frac implements Comparable<Frac> {
        private long num;
        private long denom;

        public static final Frac ZERO = new Frac(0, 1);
        public static final Frac ONE = new Frac(1, 1);

        public Frac(long n, long d) {
            if (d == 0) throw new IllegalArgumentException("d must not be zero");
            long nn = n;
            long dd = d;
            if (nn == 0) {
                dd = 1;
            } else if (dd < 0) {
                nn = -nn;
                dd = -dd;
            }
            long g = Math.abs(gcd(nn, dd));
            if (g > 1) {
                nn /= g;
                dd /= g;
            }
            num = nn;
            denom = dd;
        }

        public Frac plus(Frac rhs) {
            return new Frac(num * rhs.denom + denom * rhs.num, rhs.denom * denom);
        }

        public Frac unaryMinus() {
            return new Frac(-num, denom);
        }

        public Frac minus(Frac rhs) {
            return this.plus(rhs.unaryMinus());
        }

        public Frac times(Frac rhs) {
            return new Frac(this.num * rhs.num, this.denom * rhs.denom);
        }

        @Override
        public int compareTo(Frac o) {
            double diff = toDouble() - o.toDouble();
            return Double.compare(diff, 0.0);
        }

        @Override
        public boolean equals(Object obj) {
            return null != obj && obj instanceof Frac && this.compareTo((Frac) obj) == 0;
        }

        @Override
        public String toString() {
            if (denom == 1) {
                return Long.toString(num);
            }
            return String.format("%d/%d", num, denom);
        }

        private double toDouble() {
            return (double) num / denom;
        }
    }

    private static Frac bernoulli(int n) {
        if (n < 0) throw new IllegalArgumentException("n may not be negative or zero");
        Frac[] a = new Frac[n + 1];
        Arrays.fill(a, Frac.ZERO);
        for (int m = 0; m <= n; ++m) {
            a[m] = new Frac(1, m + 1);
            for (int j = m; j >= 1; --j) {
                a[j - 1] = a[j - 1].minus(a[j]).times(new Frac(j, 1));
            }
        }
        // returns 'first' Bernoulli number
        if (n != 1) return a[0];
        return a[0].unaryMinus();
    }

    private static int binomial(int n, int k) {
        if (n < 0 || k < 0 || n < k) throw new IllegalArgumentException();
        if (n == 0 || k == 0) return 1;
        int num = IntStream.rangeClosed(k + 1, n).reduce(1, (a, b) -> a * b);
        int den = IntStream.rangeClosed(2, n - k).reduce(1, (acc, i) -> acc * i);
        return num / den;
    }

    private static void faulhaber(int p) {
        System.out.printf("%d : ", p);
        Frac q = new Frac(1, p + 1);
        int sign = -1;
        for (int j = 0; j <= p; ++j) {
            sign *= -1;
            Frac coeff = q.times(new Frac(sign, 1)).times(new Frac(binomial(p + 1, j), 1)).times(bernoulli(j));
            if (Frac.ZERO.equals(coeff)) continue;
            if (j == 0) {
                if (!Frac.ONE.equals(coeff)) {
                    if (Frac.ONE.unaryMinus().equals(coeff)) {
                        System.out.print("-");
                    } else {
                        System.out.print(coeff);
                    }
                }
            } else {
                if (Frac.ONE.equals(coeff)) {
                    System.out.print(" + ");
                } else if (Frac.ONE.unaryMinus().equals(coeff)) {
                    System.out.print(" - ");
                } else if (coeff.compareTo(Frac.ZERO) > 0) {
                    System.out.printf(" + %s", coeff);
                } else {
                    System.out.printf(" - %s", coeff.unaryMinus());
                }
            }
            int pwr = p + 1 - j;
            if (pwr > 1)
                System.out.printf("n^%d", pwr);
            else
                System.out.print("n");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        for (int i = 0; i <= 9; ++i) {
            faulhaber(i);
        }
    }
}


module Faulhaber

function bernoulli(n::Integer)
    n ≥ 0 || throw(DomainError(n, "n must be a positive-or-0 number"))
    a = fill(0 // 1, n + 1)
    for m in 1:n
        a[m] = 1 // (m + 1)
        for j in m:-1:2
            a[j - 1] = (a[j - 1] - a[j]) * j
        end
    end
    return ifelse(n != 1, a[1], -a[1])
end

const _exponents = collect(Char, "⁰¹²³⁴⁵⁶⁷⁸⁹")
toexponent(n) = join(_exponents[reverse(digits(n)) .+ 1])

function formula(p::Integer)
    print(p, ": ")
    q = 1 // (p + 1)
    s = -1
    for j in 0:p
        s *= -1
        coeff = q * s * binomial(p + 1, j) * bernoulli(j)
        iszero(coeff) && continue
        if iszero(j)
            print(coeff == 1 ? "" : coeff == -1 ? "-" : "$coeff")
        else
            print(coeff == 1 ? " + " : coeff == -1 ? " - " : coeff > 0 ? " + $coeff " : " - $(-coeff) ")
        end
        pwr = p + 1 - j
        if pwr > 1
            print("n", toexponent(pwr))
        else
            print("n")
        end
    end
    println()
end

end  # module Faulhaber


// version 1.1.2

fun gcd(a: Long, b: Long): Long = if (b == 0L) a else gcd(b, a % b)

class Frac : Comparable<Frac> {
    val num: Long
    val denom: Long

    companion object {
        val ZERO = Frac(0, 1)
        val ONE  = Frac(1, 1)
    }

    constructor(n: Long, d: Long) {
        require(d != 0L)
        var nn = n
        var dd = d
        if (nn == 0L) {
            dd = 1
        }
        else if (dd < 0) {
            nn = -nn
            dd = -dd
        }
        val g = Math.abs(gcd(nn, dd))
        if (g > 1) {
            nn /= g
            dd /= g
        }
        num = nn
        denom = dd
    }

    constructor(n: Int, d: Int) : this(n.toLong(), d.toLong())

    operator fun plus(other: Frac) =
        Frac(num * other.denom + denom * other.num, other.denom * denom)

    operator fun unaryMinus() = Frac(-num, denom)

    operator fun minus(other: Frac) = this + (-other)

    operator fun times(other: Frac) = Frac(this.num * other.num, this.denom * other.denom)

    fun abs() = if (num >= 0) this else -this

    override fun compareTo(other: Frac): Int {
        val diff = this.toDouble() - other.toDouble()
        return when {
            diff < 0.0  -> -1
            diff > 0.0  -> +1
            else        ->  0
        }
    }

    override fun equals(other: Any?): Boolean {
       if (other == null || other !is Frac) return false
       return this.compareTo(other) == 0
    }

    override fun toString() = if (denom == 1L) "$num" else "$num/$denom"

    fun toDouble() = num.toDouble() / denom
}

fun bernoulli(n: Int): Frac {
    require(n >= 0)
    val a = Array<Frac>(n + 1) { Frac.ZERO }
    for (m in 0..n) {
        a[m] = Frac(1, m + 1)
        for (j in m downTo 1) a[j - 1] = (a[j - 1] - a[j]) * Frac(j, 1)
    }
    return if (n != 1) a[0] else -a[0] // returns 'first' Bernoulli number
}

fun binomial(n: Int, k: Int): Int {
    require(n >= 0 && k >= 0 && n >= k)
    if (n == 0 || k == 0) return 1
    val num = (k + 1..n).fold(1) { acc, i -> acc * i }
    val den = (2..n - k).fold(1) { acc, i -> acc * i }
    return num / den
}

fun faulhaber(p: Int) {
    print("$p : ")
    val q = Frac(1, p + 1)
    var sign = -1
    for (j in 0..p) {
        sign *= -1
        val coeff = q * Frac(sign, 1) * Frac(binomial(p + 1, j), 1) * bernoulli(j)
        if (coeff == Frac.ZERO) continue
        if (j == 0) {
            print(when {
                coeff == Frac.ONE  -> ""
                coeff == -Frac.ONE -> "-"
                else               -> "$coeff"
            })
        }
        else {
            print(when {
                coeff == Frac.ONE  -> " + "
                coeff == -Frac.ONE -> " - "
                coeff >  Frac.ZERO -> " + $coeff"
                else               -> " - ${-coeff}"
            })
        }
        val pwr = p + 1 - j
        if (pwr > 1)
            print("n^${p + 1 - j}")
        else
            print("n")
    }
    println()
}

fun main(args: Array<String>) {
    for (i in 0..9) faulhaber(i)
}


import java.math.MathContext
import java.util.stream.LongStream

class FaulhabersTriangle {
    private static final MathContext MC = new MathContext(256)

    private static long gcd(long a, long b) {
        if (b == 0) {
            return a
        }
        return gcd(b, a % b)
    }

    private static class Frac implements Comparable<Frac> {
        private long num
        private long denom

        public static final Frac ZERO = new Frac(0, 1)

        Frac(long n, long d) {
            if (d == 0) throw new IllegalArgumentException("d must not be zero")
            long nn = n
            long dd = d
            if (nn == 0) {
                dd = 1
            } else if (dd < 0) {
                nn = -nn
                dd = -dd
            }
            long g = Math.abs(gcd(nn, dd))
            if (g > 1) {
                nn /= g
                dd /= g
            }
            num = nn
            denom = dd
        }

        Frac plus(Frac rhs) {
            return new Frac(num * rhs.denom + denom * rhs.num, rhs.denom * denom)
        }

        Frac negative() {
            return new Frac(-num, denom)
        }

        Frac minus(Frac rhs) {
            return this + -rhs
        }

        Frac multiply(Frac rhs) {
            return new Frac(this.num * rhs.num, this.denom * rhs.denom)
        }

        @Override
        int compareTo(Frac o) {
            double diff = toDouble() - o.toDouble()
            return Double.compare(diff, 0.0)
        }

        @Override
        boolean equals(Object obj) {
            return null != obj && obj instanceof Frac && this == (Frac) obj
        }

        @Override
        String toString() {
            if (denom == 1) {
                return Long.toString(num)
            }
            return String.format("%d/%d", num, denom)
        }

        double toDouble() {
            return (double) num / denom
        }

        BigDecimal toBigDecimal() {
            return BigDecimal.valueOf(num).divide(BigDecimal.valueOf(denom), MC)
        }
    }

    private static Frac bernoulli(int n) {
        if (n < 0) throw new IllegalArgumentException("n may not be negative or zero")
        Frac[] a = new Frac[n + 1]
        Arrays.fill(a, Frac.ZERO)
        for (int m = 0; m <= n; ++m) {
            a[m] = new Frac(1, m + 1)
            for (int j = m; j >= 1; --j) {
                a[j - 1] = (a[j - 1] - a[j]) * new Frac(j, 1)
            }
        }
        // returns 'first' Bernoulli number
        if (n != 1) return a[0]
        return -a[0]
    }

    private static long binomial(int n, int k) {
        if (n < 0 || k < 0 || n < k) throw new IllegalArgumentException()
        if (n == 0 || k == 0) return 1
        long num = LongStream.rangeClosed(k + 1, n).reduce(1, { a, b -> a * b })
        long den = LongStream.rangeClosed(2, n - k).reduce(1, { acc, i -> acc * i })
        return num / den
    }

    private static Frac[] faulhaberTriangle(int p) {
        Frac[] coeffs = new Frac[p + 1]
        Arrays.fill(coeffs, Frac.ZERO)
        Frac q = new Frac(1, p + 1)
        int sign = -1
        for (int j = 0; j <= p; ++j) {
            sign *= -1
            coeffs[p - j] = q * new Frac(sign, 1) * new Frac(binomial(p + 1, j), 1) * bernoulli(j)
        }
        return coeffs
    }

    static void main(String[] args) {
        for (int i = 0; i <= 9; ++i) {
            Frac[] coeffs = faulhaberTriangle(i)
            for (Frac coeff : coeffs) {
                printf("%5s  ", coeff)
            }
            println()
        }
        println()
        // get coeffs for (k + 1)th row
        int k = 17
        Frac[] cc = faulhaberTriangle(k)
        int n = 1000
        BigDecimal nn = BigDecimal.valueOf(n)
        BigDecimal np = BigDecimal.ONE
        BigDecimal sum = BigDecimal.ZERO
        for (Frac c : cc) {
            np = np * nn
            sum = sum.add(np * c.toBigDecimal())
        }
        println(sum.toBigInteger())
    }
}


function binomial(n,k)
    if n<0 or k<0 or n<k then return -1 end
    if n==0 or k==0 then return 1 end

    local num = 1
    for i=k+1,n do
        num = num * i
    end

    local denom = 1
    for i=2,n-k do
        denom = denom * i
    end

    return num / denom
end

function gcd(a,b)
    while b ~= 0 do
        local temp = a % b
        a = b
        b = temp
    end
    return a
end

function makeFrac(n,d)
    local result = {}

    if d==0 then
        result.num = 0
        result.denom = 0
        return result
    end

    if n==0 then
        d = 1
    elseif d < 0 then
        n = -n
        d = -d
    end

    local g = math.abs(gcd(n, d))
    if g>1 then
        n = n / g
        d = d / g
    end

    result.num = n
    result.denom = d
    return result
end

function negateFrac(f)
    return makeFrac(-f.num, f.denom)
end

function subFrac(lhs, rhs)
    return makeFrac(lhs.num * rhs.denom - lhs.denom * rhs.num, rhs.denom * lhs.denom)
end

function multFrac(lhs, rhs)
    return makeFrac(lhs.num * rhs.num, lhs.denom * rhs.denom)
end

function equalFrac(lhs, rhs)
    return (lhs.num == rhs.num) and (lhs.denom == rhs.denom)
end

function lessFrac(lhs, rhs)
    return (lhs.num * rhs.denom) < (rhs.num * lhs.denom)
end

function printFrac(f)
    io.write(f.num)
    if f.denom ~= 1 then
        io.write("/"..f.denom)
    end
    return nil
end

function bernoulli(n)
    if n<0 then
        return {num=0, denom=0}
    end

    local a = {}
    for m=0,n do
        a[m] = makeFrac(1, m+1)
        for j=m,1,-1 do
            a[j-1] = multFrac(subFrac(a[j-1], a[j]), makeFrac(j, 1))
        end
    end

    if n~=1 then
        return a[0]
    end
    return negateFrac(a[0])
end

function faulhaber(p)
    io.write(p.." : ")
    local q = makeFrac(1, p+1)
    local sign = -1
    for j=0,p do
        sign = -1 * sign
        local coeff = multFrac(multFrac(multFrac(q, makeFrac(sign, 1)), makeFrac(binomial(p + 1, j), 1)), bernoulli(j))
        if not equalFrac(coeff, makeFrac(0, 1)) then
            if j==0 then
                if not equalFrac(coeff, makeFrac(1, 1)) then
                    if equalFrac(coeff, makeFrac(-1, 1)) then
                        io.write("-")
                    else
                        printFrac(coeff)
                    end
                end
            else
                if equalFrac(coeff, makeFrac(1, 1)) then
                    io.write(" + ")
                elseif equalFrac(coeff, makeFrac(-1, 1)) then
                    io.write(" - ")
                elseif lessFrac(makeFrac(0, 1), coeff) then
                    io.write(" + ")
                    printFrac(coeff)
                else
                    io.write(" - ")
                    printFrac(negateFrac(coeff))
                end
            end

            local pwr = p + 1 - j
            if pwr>1 then
                io.write("n^"..pwr)
            else
                io.write("n")
            end
        end
    end
    print()
    return nil
end

-- main
for i=0,9 do
    faulhaber(i)
end


import Data.Ratio (Ratio, denominator, numerator, (%))

------------------------ FAULHABER -----------------------

faulhaber :: Int -> Rational -> Rational
faulhaber p n =
  sum $
    zipWith ((*) . (n ^)) [1 ..] (faulhaberTriangle !! p)

faulhaberTriangle :: [[Rational]]
faulhaberTriangle =
  tail $
    scanl
      ( \rs n ->
          let xs = zipWith ((*) . (n %)) [2 ..] rs
           in 1 - sum xs : xs
      )
      []
      [0 ..]

--------------------------- TEST -------------------------
main :: IO ()
main = do
  let triangle = take 10 faulhaberTriangle
      widths = maxWidths triangle
  mapM_
    putStrLn
    [ unlines
        ( (justifyRatio widths 8 ' ' =<<)
            <$> triangle
        ),
      (show . numerator) (faulhaber 17 1000)
    ]

------------------------- DISPLAY ------------------------

justifyRatio ::
  (Int, Int) -> Int -> Char -> Rational -> String
justifyRatio (wn, wd) n c nd =
  go $
    [numerator, denominator] <*> [nd]
  where
    -- Minimum column width, or more if specified.
    w = max n (wn + wd + 2)
    go [num, den]
      | 1 == den = center w c (show num)
      | otherwise =
        let (q, r) = quotRem (w - 1) 2
         in concat
              [ justifyRight q c (show num),
                "/",
                justifyLeft (q + r) c (show den)
              ]

justifyLeft :: Int -> a -> [a] -> [a]
justifyLeft n c s = take n (s <> replicate n c)

justifyRight :: Int -> a -> [a] -> [a]
justifyRight n c = (drop . length) <*> (replicate n c <>)

center :: Int -> a -> [a] -> [a]
center n c s =
  let (q, r) = quotRem (n - length s) 2
      pad = replicate q c
   in concat [pad, s, pad, replicate r c]

maxWidths :: [[Rational]] -> (Int, Int)
maxWidths xss =
  let widest f xs = maximum $ fmap (length . show . f) xs
   in ((,) . widest numerator <*> widest denominator) $
        concat xss


ClearAll[Faulhaber]
Faulhaber[n_, 0] := n
Faulhaber[n_, p_] := n^(p + 1)/(p + 1) + 1/2 n^p + Sum[BernoulliB[k]/k! p!/(p - k + 1)! n^(p - k + 1), {k, 2, p}]
Table[{p, Faulhaber[n, p]}, {p, 0, 9}] // Grid


MODULE Faulhaber;
FROM EXCEPTIONS IMPORT AllocateSource,ExceptionSource,GetMessage,RAISE;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;

VAR TextWinExSrc : ExceptionSource;

(* Helper Functions *)
PROCEDURE Abs(n : INTEGER) : INTEGER;
BEGIN
    IF n < 0 THEN
        RETURN -n
    END;
    RETURN n
END Abs;

PROCEDURE Binomial(n,k : INTEGER) : INTEGER;
VAR i,num,denom : INTEGER;
BEGIN
    IF (n < 0) OR (k < 0) OR (n < k) THEN
        RAISE(TextWinExSrc, 0, "Argument Exception.")
    END;
    IF (n = 0) OR (k = 0) THEN
        RETURN 1
    END;
    num := 1;
    FOR i:=k+1 TO n DO
        num := num * i
    END;
    denom := 1;
    FOR i:=2 TO n - k DO
        denom := denom * i
    END;
    RETURN num / denom
END Binomial;

PROCEDURE GCD(a,b : INTEGER) : INTEGER;
BEGIN
    IF b = 0 THEN
        RETURN a
    END;
    RETURN GCD(b, a MOD b)
END GCD;

PROCEDURE WriteInteger(n : INTEGER);
VAR buf : ARRAY[0..15] OF CHAR;
BEGIN
    FormatString("%i", buf, n);
    WriteString(buf)
END WriteInteger;

(* Fraction Handling *)
TYPE Frac = RECORD
    num,denom : INTEGER;
END;

PROCEDURE InitFrac(n,d : INTEGER) : Frac;
VAR nn,dd,g : INTEGER;
BEGIN
    IF d = 0 THEN
        RAISE(TextWinExSrc, 0, "The denominator must not be zero.")
    END;
    IF n = 0 THEN
        d := 1
    ELSIF d < 0 THEN
        n := -n;
        d := -d
    END;
    g := Abs(GCD(n, d));
    IF g > 1 THEN
        n := n / g;
        d := d / g
    END;
    RETURN Frac{n, d}
END InitFrac;

PROCEDURE EqualFrac(a,b : Frac) : BOOLEAN;
BEGIN
    RETURN (a.num = b.num) AND (a.denom = b.denom)
END EqualFrac;

PROCEDURE LessFrac(a,b : Frac) : BOOLEAN;
BEGIN
    RETURN a.num * b.denom < b.num * a.denom
END LessFrac;

PROCEDURE NegateFrac(f : Frac) : Frac;
BEGIN
    RETURN Frac{-f.num, f.denom}
END NegateFrac;

PROCEDURE SubFrac(lhs,rhs : Frac) : Frac;
BEGIN
    RETURN InitFrac(lhs.num * rhs.denom - lhs.denom * rhs.num, rhs.denom * lhs.denom)
END SubFrac;

PROCEDURE MultFrac(lhs,rhs : Frac) : Frac;
BEGIN
    RETURN InitFrac(lhs.num * rhs.num, lhs.denom * rhs.denom)
END MultFrac;

PROCEDURE Bernoulli(n : INTEGER) : Frac;
VAR
    a : ARRAY[0..15] OF Frac;
    i,j,m : INTEGER;
BEGIN
    IF n < 0 THEN
        RAISE(TextWinExSrc, 0, "n may not be negative or zero.")
    END;
    FOR m:=0 TO n DO
        a[m] := Frac{1, m + 1};
        FOR j:=m TO 1 BY -1 DO
            a[j-1] := MultFrac(SubFrac(a[j-1], a[j]), Frac{j, 1})
        END
    END;
    IF n # 1 THEN RETURN a[0] END;
    RETURN NegateFrac(a[0])
END Bernoulli;

PROCEDURE WriteFrac(f : Frac);
BEGIN
    WriteInteger(f.num);
    IF f.denom # 1 THEN
        WriteString("/");
        WriteInteger(f.denom)
    END
END WriteFrac;

(* Target *)
PROCEDURE Faulhaber(p : INTEGER);
VAR
    j,pwr,sign : INTEGER;
    q,coeff : Frac;
BEGIN
    WriteInteger(p);
    WriteString(" : ");
    q := InitFrac(1, p + 1);
    sign := -1;
    FOR j:=0 TO p DO
        sign := -1 * sign;
        coeff := MultFrac(MultFrac(MultFrac(q, Frac{sign, 1}), Frac{Binomial(p + 1, j), 1}), Bernoulli(j));
        IF EqualFrac(coeff, Frac{0, 1}) THEN CONTINUE END;
        IF j = 0 THEN
            IF NOT EqualFrac(coeff, Frac{1, 1}) THEN
                IF EqualFrac(coeff, Frac{-1, 1}) THEN
                    WriteString("-")
                ELSE
                    WriteFrac(coeff)
                END
            END
        ELSE
            IF EqualFrac(coeff, Frac{1, 1}) THEN
                WriteString(" + ")
            ELSIF EqualFrac(coeff, Frac{-1, 1}) THEN
                WriteString(" - ")
            ELSIF LessFrac(Frac{0, 1}, coeff) THEN
                WriteString(" + ");
                WriteFrac(coeff)
            ELSE
                WriteString(" - ");
                WriteFrac(NegateFrac(coeff))
            END
        END;
        pwr := p + 1 - j;
        IF pwr > 1 THEN
            WriteString("n^");
            WriteInteger(pwr)
        ELSE
            WriteString("n")
        END
    END;
    WriteLn
END Faulhaber;

(* Main *)
VAR i : INTEGER;
BEGIN
    FOR i:=0 TO 9 DO
        Faulhaber(i)
    END;
    ReadChar
END Faulhaber.


import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Arrays;
import java.util.stream.LongStream;

public class FaulhabersTriangle {
    private static final MathContext MC = new MathContext(256);

    private static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    private static class Frac implements Comparable<Frac> {
        private long num;
        private long denom;

        public static final Frac ZERO = new Frac(0, 1);

        public Frac(long n, long d) {
            if (d == 0) throw new IllegalArgumentException("d must not be zero");
            long nn = n;
            long dd = d;
            if (nn == 0) {
                dd = 1;
            } else if (dd < 0) {
                nn = -nn;
                dd = -dd;
            }
            long g = Math.abs(gcd(nn, dd));
            if (g > 1) {
                nn /= g;
                dd /= g;
            }
            num = nn;
            denom = dd;
        }

        public Frac plus(Frac rhs) {
            return new Frac(num * rhs.denom + denom * rhs.num, rhs.denom * denom);
        }

        public Frac unaryMinus() {
            return new Frac(-num, denom);
        }

        public Frac minus(Frac rhs) {
            return this.plus(rhs.unaryMinus());
        }

        public Frac times(Frac rhs) {
            return new Frac(this.num * rhs.num, this.denom * rhs.denom);
        }

        @Override
        public int compareTo(Frac o) {
            double diff = toDouble() - o.toDouble();
            return Double.compare(diff, 0.0);
        }

        @Override
        public boolean equals(Object obj) {
            return null != obj && obj instanceof Frac && this.compareTo((Frac) obj) == 0;
        }

        @Override
        public String toString() {
            if (denom == 1) {
                return Long.toString(num);
            }
            return String.format("%d/%d", num, denom);
        }

        public double toDouble() {
            return (double) num / denom;
        }

        public BigDecimal toBigDecimal() {
            return BigDecimal.valueOf(num).divide(BigDecimal.valueOf(denom), MC);
        }
    }

    private static Frac bernoulli(int n) {
        if (n < 0) throw new IllegalArgumentException("n may not be negative or zero");
        Frac[] a = new Frac[n + 1];
        Arrays.fill(a, Frac.ZERO);
        for (int m = 0; m <= n; ++m) {
            a[m] = new Frac(1, m + 1);
            for (int j = m; j >= 1; --j) {
                a[j - 1] = a[j - 1].minus(a[j]).times(new Frac(j, 1));
            }
        }
        // returns 'first' Bernoulli number
        if (n != 1) return a[0];
        return a[0].unaryMinus();
    }

    private static long binomial(int n, int k) {
        if (n < 0 || k < 0 || n < k) throw new IllegalArgumentException();
        if (n == 0 || k == 0) return 1;
        long num = LongStream.rangeClosed(k + 1, n).reduce(1, (a, b) -> a * b);
        long den = LongStream.rangeClosed(2, n - k).reduce(1, (acc, i) -> acc * i);
        return num / den;
    }

    private static Frac[] faulhaberTriangle(int p) {
        Frac[] coeffs = new Frac[p + 1];
        Arrays.fill(coeffs, Frac.ZERO);
        Frac q = new Frac(1, p + 1);
        int sign = -1;
        for (int j = 0; j <= p; ++j) {
            sign *= -1;
            coeffs[p - j] = q.times(new Frac(sign, 1)).times(new Frac(binomial(p + 1, j), 1)).times(bernoulli(j));
        }
        return coeffs;
    }

    public static void main(String[] args) {
        for (int i = 0; i <= 9; ++i) {
            Frac[] coeffs = faulhaberTriangle(i);
            for (Frac coeff : coeffs) {
                System.out.printf("%5s  ", coeff);
            }
            System.out.println();
        }
        System.out.println();
        // get coeffs for (k + 1)th row
        int k = 17;
        Frac[] cc = faulhaberTriangle(k);
        int n = 1000;
        BigDecimal nn = BigDecimal.valueOf(n);
        BigDecimal np = BigDecimal.ONE;
        BigDecimal sum = BigDecimal.ZERO;
        for (Frac c : cc) {
            np = np.multiply(nn);
            sum = sum.add(np.multiply(c.toBigDecimal()));
        }
        System.out.println(sum.toBigInteger());
    }
}


import math, rationals

type
  Fraction = Rational[int]
  FaulhaberSequence = seq[Fraction]

const
  Zero = 0 // 1
  One = 1 // 1
  MinusOne = -1 // 1
  Powers = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"]

#---------------------------------------------------------------------------------------------------

func bernoulli(n: Natural): Fraction =
  ## Return nth Bernoulli coefficient.

  var a = newSeq[Fraction](n + 1)
  for m in 0..n:
    a[m] = 1 // (m + 1)
    for k in countdown(m, 1):
      a[k - 1] = (a[k - 1] - a[k]) * k
  result = if n != 1: a[0] else: -a[0]

#---------------------------------------------------------------------------------------------------

func faulhaber(n: Natural): FaulhaberSequence =
  ## Return nth Faulhaber sequence.

  var a = 1 // (n + 1)
  var sign = -1
  for k in 0..n:
    sign = -sign
    result.add(a * sign * binom(n + 1, k) * bernoulli(k))

#---------------------------------------------------------------------------------------------------

func npower(k: Natural): string =
  ## Return the string representing "n" at power "k".

  if k == 0: return ""
  if k == 1: return "n"
  var k = k
  result = "n"
  while k != 0:
    result.insert(Powers[k mod 10], 1)
    k = k div 10

#---------------------------------------------------------------------------------------------------

func `$`(fs: FaulhaberSequence): string =
  ## Return the string representing a Faulhaber sequence.

  for i, coeff in fs:

    # Process coefficient.
    if coeff.num == 0: continue
    if i == 0:
      if coeff == MinusOne: result.add(" - ")
      elif coeff != One: result.add($coeff)
    else:
      if coeff == One: result.add(" + ")
      elif coeff == MinusOne: result.add(" - ")
      elif coeff > Zero: result.add(" + " & $coeff)
      else: result.add(" - " & $(-coeff))

    # Process power of "n".
    let pwr = fs.len - i
    result.add(npower(pwr))

#———————————————————————————————————————————————————————————————————————————————————————————————————

for n in 0..9:
  echo n, ": ", faulhaber(n)


\\ Using "Faulhaber's" formula based on Bernoulli numbers. aev 2/7/17
\\ In str string replace all occurrences of the search string ssrch with the replacement string srepl. aev  3/8/16
sreplace(str,ssrch,srepl)={
  my(sn=#str,ssn=#ssrch,srn=#srepl,sres="",Vi,Vs,Vz,vin,vin1,vi,L=List(),tok,zi,js=1);
  if(sn==0,return("")); if(ssn==0||ssn>sn,return(str));
  \\ Vi - found ssrch indexes
  Vi=sfindalls(str,ssrch); vin=#Vi;
  if(vin==0,return(str));
  vin1=vin+1; Vi=Vec(Vi,vin1); Vi[vin1]=sn+1;
  for(i=1,vin1, vi=Vi[i];
  for(j=js,sn, \\print("ij:",i,"/",j,": ",sres);
    if(j!=vi, sres=concat(sres,ssubstr(str,j,1)),
              sres=concat(sres,srepl); js=j+ssn; break)
  ); \\fend j
  ); \\fend i
  return(sres);
}
B(n)=(bernfrac(n));
Comb(n,k)={my(r=0); if(k<=n, r=n!/(n-k)!/k!); return(r)};
Faulhaber2(p)={
  my(s="",s1="",s2="",c1=0,c2=0);
  for(j=0,p, c1=(-1)^j*Comb(p+1,j)*B(j); c2=(p+1-j);
    s2="*n";
    if(c1==0, next);
    if(c2==1, s1="", s1=Str("^",c2));
    s=Str(s,c1,s2,s1,"+") );
  s=ssubstr(s,1,#s-1); s=sreplace(s,"1*n","n"); s=sreplace(s,"+-","-");
  if(p==0, s="n", s=Str("(",s,")/",p+1)); print(p,": ",s);
}
{\\ Testing:
for(i=0,9, Faulhaber2(i))}


(() => {

    // Order of Faulhaber's triangle -> rows of Faulhaber's triangle
    // faulHaberTriangle :: Int -> [[Ratio Int]]
    const faulhaberTriangle = n =>
        map(x => tail(
                scanl((a, x) => {
                    const ys = map((nd, i) =>
                        ratioMult(nd, Ratio(x, i + 2)), a);
                    return cons(ratioMinus(Ratio(1, 1), ratioSum(ys)), ys);
                }, [], enumFromTo(0, x))
            ),
            enumFromTo(0, n));

    // p -> n -> Sum of the p-th powers of the first n positive integers
    // faulhaber :: Int -> Ratio Int -> Ratio Int
    const faulhaber = (p, n) =>
        ratioSum(map(
            (nd, i) => ratioMult(nd, Ratio(raise(n, i + 1), 1)),
            last(faulhaberTriangle(p))
        ));

    // RATIOS -----------------------------------------------------------------

    // (Max numr + denr widths) -> Column width -> Filler -> Ratio -> String
    // justifyRatio :: (Int, Int) -> Int -> Char -> Ratio Integer -> String
    const justifyRatio = (ws, n, c, nd) => {
        const
            w = max(n, ws.nMax + ws.dMax + 2),
            [num, den] = [nd.num, nd.den];
        return all(Number.isSafeInteger, [num, den]) ? (
            den === 1 ? center(w, c, show(num)) : (() => {
                const [q, r] = quotRem(w - 1, 2);
                return concat([
                    justifyRight(q, c, show(num)),
                    '/',
                    justifyLeft(q + r, c, (show(den)))
                ]);
            })()
        ) : "JS integer overflow ... ";
    };

    // Ratio :: Int -> Int -> Ratio
    const Ratio = (n, d) => ({
        num: n,
        den: d
    });

    // ratioMinus :: Ratio -> Ratio -> Ratio
    const ratioMinus = (nd, nd1) => {
        const
            d = lcm(nd.den, nd1.den);
        return simpleRatio({
            num: (nd.num * (d / nd.den)) - (nd1.num * (d / nd1.den)),
            den: d
        });
    };

    // ratioMult :: Ratio -> Ratio -> Ratio
    const ratioMult = (nd, nd1) => simpleRatio({
        num: nd.num * nd1.num,
        den: nd.den * nd1.den
    });

    // ratioPlus :: Ratio -> Ratio -> Ratio
    const ratioPlus = (nd, nd1) => {
        const
            d = lcm(nd.den, nd1.den);
        return simpleRatio({
            num: (nd.num * (d / nd.den)) + (nd1.num * (d / nd1.den)),
            den: d
        });
    };

    // ratioSum :: [Ratio] -> Ratio
    const ratioSum = xs =>
        simpleRatio(foldl((a, x) => ratioPlus(a, x), {
            num: 0,
            den: 1
        }, xs));

    // ratioWidths :: [[Ratio]] -> {nMax::Int, dMax::Int}
    const ratioWidths = xss => {
        return foldl((a, x) => {
            const [nw, dw] = ap(
                [compose(length, show)], [x.num, x.den]
            ), [an, ad] = ap(
                [curry(flip(lookup))(a)], ['nMax', 'dMax']
            );
            return {
                nMax: nw > an ? nw : an,
                dMax: dw > ad ? dw : ad
            };
        }, {
            nMax: 0,
            dMax: 0
        }, concat(xss));
    };

    // simpleRatio :: Ratio -> Ratio
    const simpleRatio = nd => {
        const g = gcd(nd.num, nd.den);
        return {
            num: nd.num / g,
            den: nd.den / g
        };
    };

    // GENERIC FUNCTIONS ------------------------------------------------------

    // all :: (a -> Bool) -> [a] -> Bool
    const all = (f, xs) => xs.every(f);

    // A list of functions applied to a list of arguments
    // <*> :: [(a -> b)] -> [a] -> [b]
    const ap = (fs, xs) => //
        [].concat.apply([], fs.map(f => //
            [].concat.apply([], xs.map(x => [f(x)]))));

    // Size of space -> filler Char -> Text -> Centered Text
    // center :: Int -> Char -> Text -> Text
    const center = (n, c, s) => {
        const [q, r] = quotRem(n - s.length, 2);
        return concat(concat([replicate(q, c), s, replicate(q + r, c)]));
    };

    // compose :: (b -> c) -> (a -> b) -> (a -> c)
    const compose = (f, g) => x => f(g(x));

    // concat :: [[a]] -> [a] | [String] -> String
    const concat = xs =>
        xs.length > 0 ? (() => {
            const unit = typeof xs[0] === 'string' ? '' : [];
            return unit.concat.apply(unit, xs);
        })() : [];

    // cons :: a -> [a] -> [a]
    const cons = (x, xs) => [x].concat(xs);

    // 2 or more arguments
    // curry :: Function -> Function
    const curry = (f, ...args) => {
        const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :
            function () {
                return go(xs.concat(Array.from(arguments)));
            };
        return go([].slice.call(args, 1));
    };

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = (m, n) =>
        Array.from({
            length: Math.floor(n - m) + 1
        }, (_, i) => m + i);

    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = f => (a, b) => f.apply(null, [b, a]);

    // foldl :: (b -> a -> b) -> b -> [a] -> b
    const foldl = (f, a, xs) => xs.reduce(f, a);

    // gcd :: Integral a => a -> a -> a
    const gcd = (x, y) => {
        const _gcd = (a, b) => (b === 0 ? a : _gcd(b, a % b)),
            abs = Math.abs;
        return _gcd(abs(x), abs(y));
    };

    // head :: [a] -> a
    const head = xs => xs.length ? xs[0] : undefined;

    // intercalate :: String -> [a] -> String
    const intercalate = (s, xs) => xs.join(s);

    // justifyLeft :: Int -> Char -> Text -> Text
    const justifyLeft = (n, cFiller, strText) =>
        n > strText.length ? (
            (strText + cFiller.repeat(n))
            .substr(0, n)
        ) : strText;

    // justifyRight :: Int -> Char -> Text -> Text
    const justifyRight = (n, cFiller, strText) =>
        n > strText.length ? (
            (cFiller.repeat(n) + strText)
            .slice(-n)
        ) : strText;

    // last :: [a] -> a
    const last = xs => xs.length ? xs.slice(-1)[0] : undefined;

    // length :: [a] -> Int
    const length = xs => xs.length;

    // lcm :: Integral a => a -> a -> a
    const lcm = (x, y) =>
        (x === 0 || y === 0) ? 0 : Math.abs(Math.floor(x / gcd(x, y)) * y);

    // lookup :: Eq a => a -> [(a, b)] -> Maybe b
    const lookup = (k, pairs) => {
        if (Array.isArray(pairs)) {
            let m = pairs.find(x => x[0] === k);
            return m ? m[1] : undefined;
        } else {
            return typeof pairs === 'object' ? (
                pairs[k]
            ) : undefined;
        }
    };

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) => xs.map(f);

    // max :: Ord a => a -> a -> a
    const max = (a, b) => b > a ? b : a;

    // min :: Ord a => a -> a -> a
    const min = (a, b) => b < a ? b : a;

    // quotRem :: Integral a => a -> a -> (a, a)
    const quotRem = (m, n) => [Math.floor(m / n), m % n];

    // raise :: Num -> Int -> Num
    const raise = (n, e) => Math.pow(n, e);

    // replicate :: Int -> a -> [a]
    const replicate = (n, x) =>
        Array.from({
            length: n
        }, () => x);

    // scanl :: (b -> a -> b) -> b -> [a] -> [b]
    const scanl = (f, startValue, xs) =>
        xs.reduce((a, x) => {
            const v = f(a.acc, x);
            return {
                acc: v,
                scan: cons(a.scan, v)
            };
        }, {
            acc: startValue,
            scan: [startValue]
        })
        .scan;

    // show :: a -> String
    const show = (...x) =>
        JSON.stringify.apply(
            null, x.length > 1 ? [x[0], null, x[1]] : x
        );

    // tail :: [a] -> [a]
    const tail = xs => xs.length ? xs.slice(1) : undefined;

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // TEST -------------------------------------------------------------------
    const
        triangle = faulhaberTriangle(9),
        widths = ratioWidths(triangle);

    return unlines(
            map(row =>
                concat(map(cell =>
                    justifyRatio(widths, 8, ' ', cell), row)), triangle)
        ) +
        '\n\n' + unlines(
            [
                'faulhaber(17, 1000)',
                justifyRatio(widths, 0, ' ', faulhaber(17, 1000)),
                '\nfaulhaber(17, 8)',
                justifyRatio(widths, 0, ' ', faulhaber(17, 8)),
                '\nfaulhaber(4, 1000)',
                justifyRatio(widths, 0, ' ', faulhaber(4, 1000)),
            ]
        );
})();


use 5.014;
use Math::Algebra::Symbols;

sub bernoulli_number {
    my ($n) = @_;

    return 0 if $n > 1 && $n % 2;

    my @A;
    for my $m (0 .. $n) {
        $A[$m] = symbols(1) / ($m + 1);

        for (my $j = $m ; $j > 0 ; $j--) {
            $A[$j - 1] = $j * ($A[$j - 1] - $A[$j]);
        }
    }

    return $A[0];
}

sub binomial {
    my ($n, $k) = @_;
    return 1 if $k == 0 || $n == $k;
    binomial($n - 1, $k - 1) + binomial($n - 1, $k);
}

sub faulhaber_s_formula {
    my ($p) = @_;

    my $formula = 0;
    for my $j (0 .. $p) {
        $formula += binomial($p + 1, $j)
                 *  bernoulli_number($j)
                 *  symbols('n')**($p + 1 - $j);
    }

    (symbols(1) / ($p + 1) * $formula)
        =~ s/\$n/n/gr =~ s/\*\*/^/gr =~ s/\*/ /gr;
}

foreach my $i (0 .. 9) {
    say "$i: ", faulhaber_s_formula($i);
}


include "Rational";

# Preliminaries
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

# for gojq
def idivide($j):
  . as $i
  | ($i % $j) as $mod
  | ($i - $mod) / $j ;

# use idivide for precision
def binomial(n; k):
  if k > n / 2 then binomial(n; n-k)
  else reduce range(1; k+1) as $i (1; . * (n - $i + 1) | idivide($i))
  end;

# Here we conform to the modern view that B(1) is 1 // 2
def bernoulli:
  if type != "number" or . < 0 then "bernoulli must be given a non-negative number vs \(.)" | error
  else . as $n
  | reduce range(0; $n+1) as $i ([];
        .[$i] = r(1; $i + 1)
        | reduce range($i; 0; -1) as $j (.;
            .[$j-1] = rmult($j;  rminus(.[$j-1]; .[$j])) ) )
  | .[0]  # the modern view
  end;

# Input: a non-negative integer, $p
# Output: an array of Rationals corresponding to the
# Faulhaber coefficients for row ($p + 1) (counting the first row as row 1).
def faulhabercoeffs:
  def altBernoulli:  # adjust B(1) for this task
    bernoulli as $b
    | if . == 1 then rmult(-1; $b) else $b end;
  . as $p
  | r(1; $p + 1) as $q
  | { coeffs: [], sign: -1 }
  | reduce range(0; $p+1) as $j (.;
      .sign *= -1
      | binomial($p + 1; $j) as $b
      | .coeffs[$p - $j] = ([ .sign, $q, $b, ($j|altBernoulli) ] | rmult))
  | .coeffs
;

# Calculate the sum for ($k|faulhabercoeffs)
def faulhabersum($n; $k):
  ($k|faulhabercoeffs) as $coe
  | reduce range(0;$k+1) as $i ({sum: 0, power: 1};
      .power *= $n
      | .sum = radd(.sum; rmult(.power; $coe[$i]))
      )
  | .sum;

# pretty print a Rational assumed to have the {n,d} form
def rpp:
  if .n == 0 then "0"
  elif .d == 1 then .n | tostring
  else "\(.n)/\(.d)"
  end;

def testfaulhaber:
  (range(0; 10) as $i
  | ($i | faulhabercoeffs | map(rpp | lpad(6)) | join(" "))),
    "\nfaulhabersum(1000; 17):",
    (faulhabersum(1000; 17) | rpp) ;

testfaulhaber


function bernoulli(n)
    A = Vector{Rational{BigInt}}(undef, n + 1)
    for i in 0:n
        A[i + 1] = 1 // (i + 1)
        for j = i:-1:1
            A[j] = j * (A[j] - A[j + 1])
        end
    end
    return n == 1 ? -A[1] : A[1]
end

function faulhabercoeffs(p)
    coeffs = Vector{Rational{BigInt}}(undef, p + 1)
    q = Rational{BigInt}(1, p + 1)
    sign = -1
    for j in 0:p
        sign *= -1
        coeffs[p - j + 1] = bernoulli(j) * (q * sign) * Rational{BigInt}(binomial(p + 1, j), 1)
    end
    coeffs
end

faulhabersum(n, k) = begin coe = faulhabercoeffs(k); mapreduce(i -> BigInt(n)^i * coe[i], +, 1:k+1) end

prettyfrac(x) = (x.num == 0 ? "0" : x.den == 1 ? string(x.num) : replace(string(x), "//" => "/"))

function testfaulhaber()
    for i in 0:9
        for c in faulhabercoeffs(i)
            print(prettyfrac(c), "\t")
        end
        println()
    end
    println("\n", prettyfrac(faulhabersum(1000, 17)))
end

testfaulhaber()