Variadic fixed-point combinator: Difference between revisions

Content added Content deleted
m (Minor code improvement.)
(New post.)
Line 60: Line 60:
:test (odd? (+5)) ([[1]])
:test (odd? (+5)) ([[1]])
</syntaxhighlight>
</syntaxhighlight>

=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <cstdint>
#include <iostream>

template <typename T, typename R>
class fixer {
public:
const virtual R fix(const T& x) {
return f(x);
}

virtual ~fixer() = default;

private:
virtual R f(T) = 0;
};

uint64_t factorial(uint32_t x) {

class fact : public fixer<uint32_t, uint64_t> {
virtual uint64_t f(uint32_t x) {
return ( x == 0 ) ? 1 : x * fix(x - 1);
}
};

return fact().fix(x);
}

uint32_t fibonacci(uint32_t x) {

class fib : public fixer<uint32_t, uint32_t> {
virtual uint32_t f(uint32_t x) {
return ( x == 0 ) ? 0 : ( x <= 2 ) ? 1 : fix(x - 1 ) + fix(x - 2);
}
};

return fib().fix(x);
}

template <typename T, typename U, typename R>
class bi_fixer {
public:
const virtual R bi_fix(const T& x, const U& y) {
return g(x, y);
}

virtual ~bi_fixer() = default;

private:
virtual R g(T, U) = 0;
};

uint32_t collatz(uint32_t n, uint32_t c) {

class coll : public bi_fixer<uint32_t, uint32_t, uint32_t> {
virtual uint32_t g(uint32_t n, uint32_t c) {
return ( n == 1 ) ? c : ( n % 2 == 0 ) ? bi_fix(n / 2, c + 1) : bi_fix(3 * n + 1, c + 1);
}
};

return coll().bi_fix(n, c);
}

uint64_t ackermann(uint32_t m, uint32_t n) {

class acker : public bi_fixer<uint32_t, uint32_t, uint64_t> {
virtual uint64_t g(uint32_t m, uint32_t n) {
return ( m == 0 ) ? n + 1 : ( n == 0 ) ? g(m - 1, 1) : g(m - 1, g(m, n - 1));
}
};


return acker().bi_fix(m, n);
}

int main() {
for ( int i = 1; i <= 10; ++i ) {
std::cout << "factorial(" << i << ") = " << factorial(i) << std::endl;
std::cout << "fibonacci(" << i << ") = " << fibonacci(i) << std::endl;
std::cout << "collatz(" << i << ") = " << collatz(i, 0) << std::endl;
std::cout << "ackermann(3, " << i << ") = " << ackermann(3, i) << std::endl;
std::cout << std::endl;
}
}
</syntaxhighlight>
{{ out }}
<pre>
factorial(1) = 1
fibonacci(1) = 1
collatz(1) = 0
ackermann(3, 1) = 13

factorial(2) = 2
fibonacci(2) = 1
collatz(2) = 1
ackermann(3, 2) = 29

factorial(3) = 6
fibonacci(3) = 2
collatz(3) = 7
ackermann(3, 3) = 61

factorial(4) = 24
fibonacci(4) = 3
collatz(4) = 2
ackermann(3, 4) = 125

factorial(5) = 120
fibonacci(5) = 5
collatz(5) = 5
ackermann(3, 5) = 253

factorial(6) = 720
fibonacci(6) = 8
collatz(6) = 8
ackermann(3, 6) = 509

factorial(7) = 5040
fibonacci(7) = 13
collatz(7) = 16
ackermann(3, 7) = 1021

factorial(8) = 40320
fibonacci(8) = 21
collatz(8) = 3
ackermann(3, 8) = 2045

factorial(9) = 362880
fibonacci(9) = 34
collatz(9) = 19
ackermann(3, 9) = 4093

factorial(10) = 3628800
fibonacci(10) = 55
collatz(10) = 6
ackermann(3, 10) = 8189
</pre>


=={{header|F Sharp|F#}}==
=={{header|F Sharp|F#}}==