Variadic fixed-point combinator: Difference between revisions

New post.
m (Minor code improvement.)
(New post.)
Line 60:
:test (odd? (+5)) ([[1]])
</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#}}==
894

edits