Task: Metallic ratios


C++: #include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>

const char* names[] = { "Platinum", "Golden", "Silver", "Bronze", "Copper", "Nickel", "Aluminium", "Iron", "Tin", "Lead" };

template<const uint N>
void lucas(ulong b) {
    std::cout << "Lucas sequence for " << names[b] << " ratio, where b = " << b << ":\nFirst " << N << " elements: ";
    auto x0 = 1L, x1 = 1L;
    std::cout << x0 << ", " << x1;
    for (auto i = 1u; i <= N - 1 - 1; i++) {
        auto x2 = b * x1 + x0;
        std::cout << ", " << x2;
        x0 = x1;
        x1 = x2;
    }
    std::cout << std::endl;
}

template<const ushort P>
void metallic(ulong b) {
    using namespace boost::multiprecision;
    using bfloat = number<cpp_dec_float<P+1>>;
    bfloat x0(1), x1(1);
    auto prev = bfloat(1).str(P+1);
    for (auto i = 0u;;) {
        i++;
        bfloat x2(b * x1 + x0);
        auto thiz = bfloat(x2 / x1).str(P+1);
        if (prev == thiz) {
            std::cout << "Value after " << i << " iteration" << (i == 1 ? ": " : "s: ") << thiz << std::endl << std::endl;
            break;
        }
        prev = thiz;
        x0 = x1;
        x1 = x2;
    }
}

int main() {
    for (auto b = 0L; b < 10L; b++) {
        lucas<15>(b);
        metallic<32>(b);
    }
    std::cout << "Golden ratio, where b = 1:" << std::endl;
    metallic<256>(1);

    return 0;
}




Java: import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.List;

public class MetallicRatios {

    private static String[] ratioDescription = new String[] {"Platinum", "Golden", "Silver", "Bronze", "Copper", "Nickel", "Aluminum", "Iron", "Tin", "Lead"};
    
    public static void main(String[] args) {
        int elements = 15;
        for ( int b = 0 ; b < 10 ; b++ ) {
            System.out.printf("Lucas sequence for %s ratio, where b = %d:%n", ratioDescription[b], b);
            System.out.printf("First %d elements: %s%n", elements, lucasSequence(1, 1, b, elements));
            int decimalPlaces = 32;
            BigDecimal[] ratio = lucasSequenceRatio(1, 1, b, decimalPlaces+1);
            System.out.printf("Value to %d decimal places after %s iterations : %s%n", decimalPlaces, ratio[1], ratio[0]);
            System.out.printf("%n");
        }
        int b = 1;
        int decimalPlaces = 256;
        System.out.printf("%s ratio, where b = %d:%n", ratioDescription[b], b);
        BigDecimal[] ratio = lucasSequenceRatio(1, 1, b, decimalPlaces+1);
        System.out.printf("Value to %d decimal places after %s iterations : %s%n", decimalPlaces, ratio[1], ratio[0]);
    }
    
    private static BigDecimal[] lucasSequenceRatio(int x0, int x1, int b, int digits) {
        BigDecimal x0Bi = BigDecimal.valueOf(x0);
        BigDecimal x1Bi = BigDecimal.valueOf(x1);
        BigDecimal bBi = BigDecimal.valueOf(b);
        MathContext mc = new MathContext(digits);
        BigDecimal fractionPrior = x1Bi.divide(x0Bi, mc);
        int iterations = 0;
        while ( true ) {
            iterations++;
            BigDecimal x = bBi.multiply(x1Bi).add(x0Bi);
            BigDecimal fractionCurrent = x.divide(x1Bi, mc);
            if ( fractionCurrent.compareTo(fractionPrior) == 0 ) {
                break;
            }
            x0Bi = x1Bi;
            x1Bi = x;
            fractionPrior = fractionCurrent;
        }
        return new BigDecimal[] {fractionPrior, BigDecimal.valueOf(iterations)};
    }

    private static List<BigInteger> lucasSequence(int x0, int x1, int b, int n) {
        List<BigInteger> list = new ArrayList<>();
        BigInteger x0Bi = BigInteger.valueOf(x0);
        BigInteger x1Bi = BigInteger.valueOf(x1);
        BigInteger bBi = BigInteger.valueOf(b);
        if ( n > 0 ) {
            list.add(x0Bi);
        }
        if ( n > 1 ) {
            list.add(x1Bi);
        }
        while ( n > 2 ) {
            BigInteger x = bBi.multiply(x1Bi).add(x0Bi);
            list.add(x);
            n--;
            x0Bi = x1Bi;
            x1Bi = x;
        }
        return list;
    }
    
}