Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,4 +1,6 @@
The '''[[wp:Ackermann function|Ackermann function]]''' is a classic recursive example in computer science. It is a function that grows very quickly (in its value and in the size of its call tree). It is defined as follows:
The '''[[wp:Ackermann function|Ackermann function]]''' is a classic recursive example in computer science.
It is a function that grows very quickly (in its value and in the size of its call tree).
It is defined as follows:
:<math> A(m, n) =
\begin{cases}
@ -10,3 +12,8 @@ The '''[[wp:Ackermann function|Ackermann function]]''' is a classic recursive ex
<!-- <table><tr><td width=12><td><td><math>n+1</math><td>if <math>m=0</math> <tr><td> <td><math>A(m, n) =</math> <td><math>A(m-1, 1)</math> <td>if <math>m>0</math> and <math>n=0</math> <tr><td><td><td><math>A(m-1, A(m, n-1))</math>&nbsp;&nbsp;<td> if <math>m>0</math> and <math>n>0</math></table> -->
Its arguments are never negative and it always terminates. Write a function which returns the value of <math>A(m, n)</math>. Arbitrary precision is preferred (since the function grows so quickly), but not required.
Interestingly enough, the Ackermann function is one of the very few known examples of function that can ''only'' be implemented recursively. It is impossible to implement it with just for loops and other control flow commands. See this [http://youtube.com/watch?v=i7sm9dzFtEI computerphile episode] for more information.
;See also:
* [[wp:Conway_chained_arrow_notation#Ackermann_function|Conway chained arrow notation]] for the Ackermann function.

View file

@ -30,24 +30,3 @@ ack!:
if }
zero?!: { 0 = }
Output:
A(0 0 ) = 1
A(0 1 ) = 2
A(0 2 ) = 3
A(0 3 ) = 4
A(0 4 ) = 5
A(1 0 ) = 2
A(1 1 ) = 3
A(1 2 ) = 4
A(1 3 ) = 5
A(1 4 ) = 6
A(2 0 ) = 3
A(2 1 ) = 5
A(2 2 ) = 7
A(2 3 ) = 9
A(3 0 ) = 5
A(3 1 ) = 13
A(3 2 ) = 29
A(4 0 ) = 13

View file

@ -0,0 +1,19 @@
#include <iostream>
unsigned int ackermann(unsigned int m, unsigned int n) {
if (m == 0) {
return n + 1;
}
if (n == 0) {
return ackermann(m - 1, 1);
}
return ackermann(m - 1, ackermann(m, n - 1));
}
int main() {
for (unsigned int m = 0; m < 4; ++m) {
for (unsigned int n = 0; n < 10; ++n) {
std::cout << "A(" << m << ", " << n << ") = " << ackermann(m, n) << "\n";
}
}
}

View file

@ -0,0 +1,54 @@
#include <iostream>
#include <sstream>
#include <string>
#include <boost/multiprecision/cpp_int.hpp>
using big_int = boost::multiprecision::cpp_int;
big_int ipow(big_int base, big_int exp) {
big_int result(1);
while (exp) {
if (exp & 1) {
result *= base;
}
exp >>= 1;
base *= base;
}
return result;
}
big_int ackermann(unsigned m, unsigned n) {
static big_int (*ack)(unsigned, big_int) =
[](unsigned m, big_int n)->big_int {
switch (m) {
case 0:
return n + 1;
case 1:
return n + 2;
case 2:
return 3 + 2 * n;
case 3:
return 5 + 8 * (ipow(big_int(2), n) - 1);
default:
return n == 0 ? ack(m - 1, big_int(1)) : ack(m - 1, ack(m, n - 1));
}
};
return ack(m, big_int(n));
}
int main() {
for (unsigned m = 0; m < 4; ++m) {
for (unsigned n = 0; n < 10; ++n) {
std::cout << "A(" << m << ", " << n << ") = " << ackermann(m, n) << "\n";
}
}
std::cout << "A(4, 1) = " << ackermann(4, 1) << "\n";
std::stringstream ss;
ss << ackermann(4, 2);
auto text = ss.str();
std::cout << "A(4, 2) = (" << text.length() << " digits)\n"
<< text.substr(0, 80) << "\n...\n"
<< text.substr(text.length() - 80) << "\n";
}

View file

@ -1,18 +0,0 @@
#include <iostream>
using namespace std;
long ackermann(long x, long y)
{
if (x == 0) return y+1;
else if (y == 0) return ackermann(x-1, 1);
else return ackermann(x-1, ackermann(x, y-1));
}
int main()
{
long x,y;
cout << "x ve y..:";
cin>>x;
cin>>y;
cout<<ackermann(x,y);
return 0;
}

View file

@ -1,4 +1,4 @@
ulong ackermann(in ulong m, in ulong n) pure nothrow {
ulong ackermann(in ulong m, in ulong n) pure nothrow @nogc {
if (m == 0)
return n + 1;
if (n == 0)

View file

@ -1,6 +1,6 @@
import std.stdio, std.bigint, std.conv;
BigInt ipow(BigInt base, BigInt exp) pure /*nothrow*/ {
BigInt ipow(BigInt base, BigInt exp) pure nothrow {
auto result = 1.BigInt;
while (exp) {
if (exp & 1)
@ -12,23 +12,20 @@ BigInt ipow(BigInt base, BigInt exp) pure /*nothrow*/ {
return result;
}
BigInt ackermann(in int m, in int n) pure /*nothrow*/
in {
assert(m >= 0 && n >= 0);
} out(result) {
BigInt ackermann(in uint m, in uint n) pure nothrow
out(result) {
assert(result >= 0);
} body {
static BigInt ack(in int m, in BigInt n) pure /*nothrow*/ {
static BigInt ack(in uint m, in BigInt n) pure nothrow {
switch (m) {
case 0: return n + 1;
case 1: return n + 2;
case 2: return 3 + 2 * n;
//case 3: return 5 + 8 * (2 ^^ n - 1);
case 3: return 5 + 8 * (ipow(2.BigInt, n) - 1);
default: if (n == 0)
return ack(m - 1, 1.BigInt);
else
return ack(m - 1, ack(m, n - 1));
default: return (n == 0) ?
ack(m - 1, 1.BigInt) :
ack(m - 1, ack(m, n - 1));
}
}

View file

@ -1,4 +1,5 @@
#define system.
#define extensions.
// --- Ackermann function ---
@ -14,13 +15,11 @@
#symbol program =
[
control from:0 &to:3 &do: i
control forrange &int:0 &int:3 &do: (&int:i)
[
control from:0 &to:5 &do: j
control forrange &int:0 &int:5 &do: (&int:j)
[
console << "A(" << i << "," << j << ")=" << (ackermann:i:j).
console writeLine.
consoleEx writeLine:"A(":i:",":j:")=":(ackermann:i:j).
].
].

View file

@ -0,0 +1,5 @@
defmodule Ackermann do
def ack(0, n), do: n + 1
def ack(m, 0), do: ack(m - 1, 1)
def ack(m, n), do: ack(m - 1, ack(m, n - 1))
end

View file

@ -1,8 +1,16 @@
m=argument0
n=argument1
///ackermann(m,n)
var m, n;
m = argument0;
n = argument1;
if(m=0)
{
return (n+1)
else if(n=0)
}
else if(n == 0)
{
return (ackermann(m-1,1,1))
}
else
{
return (ackermann(m-1,ackermann(m,n-1,2),1))
}

View file

@ -1,4 +1,3 @@
function ack(m, n)
{
function ack(m, n) {
return m === 0 ? n + 1 : ack(m - 1, n === 0 ? 1 : ack(m, n - 1));
}

View file

@ -0,0 +1,5 @@
using Memoize
@memoize ack3(m, n) =
m == 0 ? n + 1 :
n == 0 ? ack3(m-1, 1) :
ack3(m-1, ack3(m, n-1))

View file

@ -0,0 +1,17 @@
ack: func (m: Int, n: Int) -> Int {
if (m == 0) {
n + 1
} else if (n == 0) {
ack(m - 1, 1)
} else {
ack(m - 1, ack(m, n - 1))
}
}
main: func {
for (m in 0..4) {
for (n in 0..10) {
"ack(#{m}, #{n}) = #{ack(m, n)}" println()
}
}
}

View file

@ -0,0 +1,15 @@
use Memoize; memoize('ack2');
use bigint try=>"GMP";
sub ack2 {
my ($m, $n) = @_;
$m == 0 ? $n + 1 :
$m == 1 ? $n + 2 :
$m == 2 ? 2*$n + 3 :
$m == 3 ? 8 * (2**$n - 1) + 5 :
$n == 0 ? ack2($m-1, 1)
: ack2($m-1, ack2($m, $n-1));
}
print "ack2(3,4) is ", ack2(3,4), "\n";
print "ack2(4,1) is ", ack2(4,1), "\n";
print "ack2(4,2) has ", length(ack2(4,2)), " digits\n";

View file

@ -2,6 +2,6 @@ def ack2(M, N):
if M == 0:
return N + 1
elif N == 0:
return ack1(M - 1, 1)
return ack2(M - 1, 1)
else:
return ack1(M - 1, ack1(M, N - 1))
return ack2(M - 1, ack2(M, N - 1))

View file

@ -0,0 +1,7 @@
fn ack(m: u64, n: u64) -> u64 {
match (m, n) {
(0, n) => n + 1,
(m, 0) => ack(m - 1, 1),
(m, n) => ack(m - 1, ack(m, n - 1)),
}
}

View file

@ -0,0 +1,23 @@
clear
function acker=ackermann(m,n)
global calls
calls=calls+1
if m==0 then acker=n+1
else
if n==0 then acker=ackermann(m-1,1)
else acker=ackermann(m-1,ackermann(m,n-1))
end
end
endfunction
function printacker(m,n)
global calls
calls=0
printf('ackermann(%d,%d)=',m,n)
printf('%d calls=%d\n',ackermann(m,n),calls)
endfunction
maxi=3; maxj=6
for i=0:maxi
for j=0:maxj
printacker(i,j)
end
end

View file

@ -0,0 +1,29 @@
Option Explicit
Dim calls As Long
Sub main()
Const maxi = 4
Const maxj = 9
Dim i As Long, j As Long
For i = 0 To maxi
For j = 0 To maxj
Call print_acker(i, j)
Next j
Next i
End Sub 'main
Sub print_acker(m As Long, n As Long)
calls = 0
Debug.Print "ackermann("; m; ","; n; ")=";
Debug.Print ackermann(m, n), "calls="; calls
End Sub 'print_acker
Function ackermann(m As Long, n As Long) As Long
calls = calls + 1
If m = 0 Then
ackermann = n + 1
Else
If n = 0 Then
ackermann = ackermann(m - 1, 1)
Else
ackermann = ackermann(m - 1, ackermann(m, n - 1))
End If
End If
End Function 'ackermann

View file

@ -1,14 +1,29 @@
(ackermann) integer1 integer2
comment: takes two integers -> returns the result
(zero?) integer1
(add1) integer2
(A) m n
comment:
(=) m 0
(add1) n
(ackermann) integer1 integer2
comment: takes two integers -> returns the result
(and) (positive?) integer1 (zero?) integer2
(ackermann) (sub1) integer1 1
(A) m n
comment:
(=) n 0
(A) (sub1) m 1
(ackermann) integer1 integer2
comment: takes two integers -> returns the result
(and) (positive?) integer1 (positive?) integer2
(ackermann) (sub1) integer1 (ackermann) integer1 (sub1) integer2
(A) m n
comment:
#true
(A) (sub1) m (A) m (sub1) n
(add1) n
comment:
#true
(003) "+" n 1
(sub1) n
comment:
#true
(003) "-" n 1
(=) n1 n2
comment:
#true
(003) "=" n1 n2