Variadic fixed-point combinator: Difference between revisions
Content added Content deleted
(New post.) |
(Have removed my own post as I misunderstood the task.) Tag: Manual revert |
||
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#}}== |