Task: Padovan sequence


C++: #include <iostream>
#include <map>
#include <cmath>



int pRec(int n) {
    static std::map<int,int> memo;
    auto it = memo.find(n);
    if (it != memo.end()) return it->second;

    if (n <= 2) memo[n] = 1;
    else memo[n] = pRec(n-2) + pRec(n-3);
    return memo[n];
}



int pFloor(int n) {
    long const double p = 1.324717957244746025960908854;
    long const double s = 1.0453567932525329623;
    return std::pow(p, n-1)/s + 0.5;
}


std::string& lSystem(int n) {
    static std::map<int,std::string> memo;
    auto it = memo.find(n);
    if (it != memo.end()) return it->second;
    
    if (n == 0) memo[n] = "A";
    else {
        memo[n] = "";
        for (char ch : memo[n-1]) {
            switch(ch) {
                case 'A': memo[n].push_back('B'); break;
                case 'B': memo[n].push_back('C'); break;
                case 'C': memo[n].append("AB"); break;
            }
        }
    }
    return memo[n];
}


using pFn = int(*)(int);
void compare(pFn f1, pFn f2, const char* descr, int stop) {
    std::cout << "The " << descr << " functions ";
    int i;
    for (i=0; i<stop; i++) {
        int n1 = f1(i);
        int n2 = f2(i);
        if (n1 != n2) {
            std::cout << "do not match at " << i
                      << ": " << n1 << " != " << n2 << ".\n";
            break;
        }
    }
    if (i == stop) {
        std::cout << "match from P_0 to P_" << stop << ".\n";
    }
}

int main() {
    
    std::cout << "P_0 .. P_19: ";
    for (int i=0; i<20; i++) std::cout << pRec(i) << " ";
    std::cout << "\n";
    
    
    compare(pFloor, pRec, "floor- and recurrence-based", 64);
    
    
    std::cout << "\nThe first 10 L-system strings are:\n";
    for (int i=0; i<10; i++) std::cout << lSystem(i) << "\n";
    std::cout << "\n";
    
    
    compare(pFloor, [](int n){return (int)lSystem(n).length();}, 
                            "floor- and L-system-based", 32);
    return 0;
}



Go: package main

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

func padovanRecur(n int) []int {
    p := make([]int, n)
    p[0], p[1], p[2] = 1, 1, 1
    for i := 3; i < n; i++ {
        p[i] = p[i-2] + p[i-3]
    }
    return p
}

func padovanFloor(n int) []int {
    var p, s, t, u = new(big.Rat), new(big.Rat), new(big.Rat), new(big.Rat)
    p, _ = p.SetString("1.324717957244746025960908854")
    s, _ = s.SetString("1.0453567932525329623")
    f := make([]int, n)
    pow := new(big.Rat).SetInt64(1)
    u = u.SetFrac64(1, 2)
    t.Quo(pow, p)
    t.Quo(t, s)
    t.Add(t, u)
    v, _ := t.Float64()
    f[0] = int(math.Floor(v))
    for i := 1; i < n; i++ {
        t.Quo(pow, s)
        t.Add(t, u)
        v, _ = t.Float64()
        f[i] = int(math.Floor(v))
        pow.Mul(pow, p)
    }
    return f
}

type LSystem struct {
    rules         map[string]string
    init, current string
}

func step(lsys *LSystem) string {
    var sb strings.Builder
    if lsys.current == "" {
        lsys.current = lsys.init
    } else {
        for _, c := range lsys.current {
            sb.WriteString(lsys.rules[string(c)])
        }
        lsys.current = sb.String()
    }
    return lsys.current
}

func padovanLSys(n int) []string {
    rules := map[string]string{"A": "B", "B": "C", "C": "AB"}
    lsys := &LSystem{rules, "A", ""}
    p := make([]string, n)
    for i := 0; i < n; i++ {
        p[i] = step(lsys)
    }
    return p
}


func areSame(l1, l2 []int) bool {
    for i := 0; i < len(l1); i++ {
        if l1[i] != l2[i] {
            return false
        }
    }
    return true
}

func main() {
    fmt.Println("First 20 members of the Padovan sequence:")
    fmt.Println(padovanRecur(20))
    recur := padovanRecur(64)
    floor := padovanFloor(64)
    same := areSame(recur, floor)
    s := "give"
    if !same {
        s = "do not give"
    }
    fmt.Println("\nThe recurrence and floor based functions", s, "the same results for 64 terms.")

    p := padovanLSys(32)
    lsyst := make([]int, 32)
    for i := 0; i < 32; i++ {
        lsyst[i] = len(p[i])
    }
    fmt.Println("\nFirst 10 members of the Padovan L-System:")
    fmt.Println(p[:10])
    fmt.Println("\nand their lengths:")
    fmt.Println(lsyst[:10])

    same = areSame(recur[:32], lsyst)
    s = "give"
    if !same {
        s = "do not give"
    }
    fmt.Println("\nThe recurrence and L-system based functions", s, "the same results for 32 terms.")