Task: Calkin-Wilf sequence


C++: #include <iostream>
#include <vector>
#include <boost/rational.hpp>

using rational = boost::rational<unsigned long>;

unsigned long floor(const rational& r) {
    return r.numerator()/r.denominator();
}

rational calkin_wilf_next(const rational& term) {
    return 1UL/(2UL * floor(term) + 1UL - term);
}

std::vector<unsigned long> continued_fraction(const rational& r) {
    unsigned long a = r.numerator();
    unsigned long b = r.denominator();
    std::vector<unsigned long> result;
    do {
        result.push_back(a/b);
        unsigned long c = a;
        a = b;
        b = c % b;
    } while (a != 1);
    if (result.size() > 0 && result.size() % 2 == 0) {
        --result.back();
        result.push_back(1);
    }
    return result;
}

unsigned long term_number(const rational& r) {
    unsigned long result = 0;
    unsigned long d = 1;
    unsigned long p = 0;
    for (unsigned long n : continued_fraction(r)) {
        for (unsigned long i = 0; i < n; ++i, ++p)
            result |= (d << p);
        d = !d;
    }
    return result;
}

int main() {
    rational term = 1;
    std::cout << "First 20 terms of the Calkin-Wilf sequence are:\n";
    for (int i = 1; i <= 20; ++i) {
        std::cout << std::setw(2) << i << ": " << term << '\n';
        term = calkin_wilf_next(term);
    }
    rational r(83116, 51639);
    std::cout << r << " is the " << term_number(r) << "th term of the sequence.\n";
}



Go: package main

import (
    "fmt"
    "math"
    "math/big"
    "strconv"
    "strings"
)

func calkinWilf(n int) []*big.Rat {
    cw := make([]*big.Rat, n+1)
    cw[0] = big.NewRat(1, 1)
    one := big.NewRat(1, 1)
    two := big.NewRat(2, 1)
    for i := 1; i < n; i++ {
        t := new(big.Rat).Set(cw[i-1])
        f, _ := t.Float64()
        f = math.Floor(f)
        t.SetFloat64(f)
        t.Mul(t, two)
        t.Sub(t, cw[i-1])
        t.Add(t, one)
        t.Inv(t)
        cw[i] = new(big.Rat).Set(t)
    }
    return cw
}

func toContinued(r *big.Rat) []int {
    a := r.Num().Int64()
    b := r.Denom().Int64()
    var res []int
    for {
        res = append(res, int(a/b))
        t := a % b
        a, b = b, t
        if a == 1 {
            break
        }
    }
    le := len(res)
    if le%2 == 0 { 
        res[le-1]--
        res = append(res, 1)
    }
    return res
}

func getTermNumber(cf []int) int {
    b := ""
    d := "1"
    for _, n := range cf {
        b = strings.Repeat(d, n) + b
        if d == "1" {
            d = "0"
        } else {
            d = "1"
        }
    }
    i, _ := strconv.ParseInt(b, 2, 64)
    return int(i)
}

func commatize(n int) string {
    s := fmt.Sprintf("%d", n)
    if n < 0 {
        s = s[1:]
    }
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    if n >= 0 {
        return s
    }
    return "-" + s
}

func main() {
    cw := calkinWilf(20)
    fmt.Println("The first 20 terms of the Calkin-Wilf sequnence are:")
    for i := 1; i <= 20; i++ {
        fmt.Printf("%2d: %s\n", i, cw[i-1].RatString())
    }
    fmt.Println()
    r := big.NewRat(83116, 51639)
    cf := toContinued(r)
    tn := getTermNumber(cf)
    fmt.Printf("%s is the %sth term of the sequence.\n", r.RatString(), commatize(tn))
}