Ackermann function: Difference between revisions

Content added Content deleted
(added Ol)
m (syntax highlighting fixup automation)
Line 34: Line 34:
{{trans|Python}}
{{trans|Python}}


<lang 11l>F ack2(m, n) -> Int
<syntaxhighlight lang=11l>F ack2(m, n) -> Int
R I m == 0 {(n + 1)
R I m == 0 {(n + 1)
} E I m == 1 {(n + 2)
} E I m == 1 {(n + 2)
Line 44: Line 44:
print(ack2(0, 0))
print(ack2(0, 0))
print(ack2(3, 4))
print(ack2(3, 4))
print(ack2(4, 1))</lang>
print(ack2(4, 1))</syntaxhighlight>


{{out}}
{{out}}
Line 57: Line 57:
The OS/360 linkage is a bit tricky with the S/360 basic instruction set.
The OS/360 linkage is a bit tricky with the S/360 basic instruction set.
To simplify, the program is recursive not reentrant.
To simplify, the program is recursive not reentrant.
<lang 360asm>* Ackermann function 07/09/2015
<syntaxhighlight lang=360asm>* Ackermann function 07/09/2015
&LAB XDECO &REG,&TARGET
&LAB XDECO &REG,&TARGET
.*-----------------------------------------------------------------*
.*-----------------------------------------------------------------*
Line 155: Line 155:
STACKLEN EQU *-STACK
STACKLEN EQU *-STACK
YREGS
YREGS
END ACKERMAN</lang>
END ACKERMAN</syntaxhighlight>
{{out}}
{{out}}
<pre style="height:20ex">
<pre style="height:20ex">
Line 199: Line 199:
This implementation is based on the code shown in the computerphile episode in the youtube link at the top of this page (time index 5:00).
This implementation is based on the code shown in the computerphile episode in the youtube link at the top of this page (time index 5:00).


<lang 68000devpac>;
<syntaxhighlight lang=68000devpac>;
; Ackermann function for Motorola 68000 under AmigaOs 2+ by Thorham
; Ackermann function for Motorola 68000 under AmigaOs 2+ by Thorham
;
;
Line 310: Line 310:


outString
outString
dc.b "ackermann (%ld,%ld) is: %ld",10,0</lang>
dc.b "ackermann (%ld,%ld) is: %ld",10,0</syntaxhighlight>


=={{header|8080 Assembly}}==
=={{header|8080 Assembly}}==
Line 317: Line 317:
and <code>n ∊ [0,9)</code>, on a real 8080 this takes a little over two minutes.
and <code>n ∊ [0,9)</code>, on a real 8080 this takes a little over two minutes.


<lang 8080asm> org 100h
<syntaxhighlight lang=8080asm> org 100h
jmp demo
jmp demo
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 397: Line 397:
db '*****' ; Placeholder for number
db '*****' ; Placeholder for number
pnum: db 9,'$'
pnum: db 9,'$'
nl: db 13,10,'$'</lang>
nl: db 13,10,'$'</syntaxhighlight>


{{out}}
{{out}}
Line 410: Line 410:
This code does 16-bit math just like the 8080 version.
This code does 16-bit math just like the 8080 version.


<lang asm> cpu 8086
<syntaxhighlight lang=asm> cpu 8086
bits 16
bits 16
org 100h
org 100h
Line 469: Line 469:
db '*****' ; Placeholder for ASCII number
db '*****' ; Placeholder for ASCII number
pnum: db 9,'$'
pnum: db 9,'$'
nl: db 13,10,'$'</lang>
nl: db 13,10,'$'</syntaxhighlight>


{{out}}
{{out}}
Line 479: Line 479:


=={{header|8th}}==
=={{header|8th}}==
<lang Forth>
<syntaxhighlight lang=Forth>
\ Ackermann function, illustrating use of "memoization".
\ Ackermann function, illustrating use of "memoization".


Line 554: Line 554:
4 1 ackOf
4 1 ackOf


bye</lang>
bye</syntaxhighlight>


{{out|The output}}
{{out|The output}}
Line 571: Line 571:
=={{header|AArch64 Assembly}}==
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
<lang AArch64 Assembly>
<syntaxhighlight lang=AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B or android 64 bits */
/* ARM assembly AARCH64 Raspberry PI 3B or android 64 bits */
/* program ackermann64.s */
/* program ackermann64.s */
Line 693: Line 693:
/* for this file see task include a file in language AArch64 assembly */
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
{{Output}}
{{Output}}
<pre>
<pre>
Line 739: Line 739:
=={{header|ABAP}}==
=={{header|ABAP}}==


<lang ABAP>
<syntaxhighlight lang=ABAP>
REPORT zhuberv_ackermann.
REPORT zhuberv_ackermann.


Line 785: Line 785:
lv_result = zcl_ackermann=>ackermann( m = pa_m n = pa_n ).
lv_result = zcl_ackermann=>ackermann( m = pa_m n = pa_n ).
WRITE: / lv_result.
WRITE: / lv_result.
</syntaxhighlight>
</lang>


=={{header|Action!}}==
=={{header|Action!}}==
Action! language does not support recursion. Therefore an iterative approach with a stack has been proposed.
Action! language does not support recursion. Therefore an iterative approach with a stack has been proposed.
<lang Action!>DEFINE MAXSIZE="1000"
<syntaxhighlight lang=Action!>DEFINE MAXSIZE="1000"
CARD ARRAY stack(MAXSIZE)
CARD ARRAY stack(MAXSIZE)
CARD stacksize=[0]
CARD stacksize=[0]
Line 845: Line 845:
OD
OD
OD
OD
RETURN</lang>
RETURN</syntaxhighlight>
{{out}}
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Ackermann_function.png Screenshot from Atari 8-bit computer]
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Ackermann_function.png Screenshot from Atari 8-bit computer]
Line 872: Line 872:


=={{header|ActionScript}}==
=={{header|ActionScript}}==
<lang actionscript>public function ackermann(m:uint, n:uint):uint
<syntaxhighlight lang=actionscript>public function ackermann(m:uint, n:uint):uint
{
{
if (m == 0)
if (m == 0)
Line 884: Line 884:


return ackermann(m - 1, ackermann(m, n - 1));
return ackermann(m - 1, ackermann(m, n - 1));
}</lang>
}</syntaxhighlight>


=={{header|Ada}}==
=={{header|Ada}}==
<lang ada>with Ada.Text_IO; use Ada.Text_IO;
<syntaxhighlight lang=ada>with Ada.Text_IO; use Ada.Text_IO;


procedure Test_Ackermann is
procedure Test_Ackermann is
Line 907: Line 907:
New_Line;
New_Line;
end loop;
end loop;
end Test_Ackermann;</lang>
end Test_Ackermann;</syntaxhighlight>
The implementation does not care about arbitrary precision numbers because the Ackermann function does not only grow, but also slow quickly, when computed recursively.
The implementation does not care about arbitrary precision numbers because the Ackermann function does not only grow, but also slow quickly, when computed recursively.
{{out}} the first 4x7 Ackermann's numbers:
{{out}} the first 4x7 Ackermann's numbers:
Line 918: Line 918:
{{works with|Agda|2.5.2}}
{{works with|Agda|2.5.2}}
{{libheader|agda-stdlib v0.13}}
{{libheader|agda-stdlib v0.13}}
<lang agda>
<syntaxhighlight lang=agda>
open import Data.Nat
open import Data.Nat
open import Data.Nat.Show
open import Data.Nat.Show
Line 931: Line 931:
main = run (putStrLn (show (ack 3 9)))
main = run (putStrLn (show (ack 3 9)))
</syntaxhighlight>
</lang>


Note the unicode ℕ characters, they can be input in emacs agda mode using "\bN". Running in bash:
Note the unicode ℕ characters, they can be input in emacs agda mode using "\bN". Running in bash:


<lang bash>
<syntaxhighlight lang=bash>
agda --compile Ackermann.agda
agda --compile Ackermann.agda
./Ackermann
./Ackermann
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 947: Line 947:
=={{header|ALGOL 60}}==
=={{header|ALGOL 60}}==
{{works with|A60}}
{{works with|A60}}
<lang algol60>begin
<syntaxhighlight lang=algol60>begin
integer procedure ackermann(m,n);value m,n;integer m,n;
integer procedure ackermann(m,n);value m,n;integer m,n;
ackermann:=if m=0 then n+1
ackermann:=if m=0 then n+1
Line 958: Line 958:
outstring(1,"\n")
outstring(1,"\n")
end
end
end </lang>
end </syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 972: Line 972:
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}}
<lang algol68>PROC test ackermann = VOID:
<syntaxhighlight lang=algol68>PROC test ackermann = VOID:
BEGIN
BEGIN
PROC ackermann = (INT m, n)INT:
PROC ackermann = (INT m, n)INT:
Line 992: Line 992:
OD
OD
END # test ackermann #;
END # test ackermann #;
test ackermann</lang>
test ackermann</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,003: Line 1,003:
=={{header|ALGOL W}}==
=={{header|ALGOL W}}==
{{Trans|ALGOL 60}}
{{Trans|ALGOL 60}}
<lang algolw>begin
<syntaxhighlight lang=algolw>begin
integer procedure ackermann( integer value m,n ) ;
integer procedure ackermann( integer value m,n ) ;
if m=0 then n+1
if m=0 then n+1
Line 1,012: Line 1,012:
for n := 1 until 6 do writeon( ackermann( m, n ) );
for n := 1 until 6 do writeon( ackermann( m, n ) );
end for_m
end for_m
end.</lang>
end.</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,023: Line 1,023:
=={{header|APL}}==
=={{header|APL}}==
{{works with|Dyalog APL}}
{{works with|Dyalog APL}}
<lang APL>ackermann←{
<syntaxhighlight lang=APL>ackermann←{
0=1⊃⍵:1+2⊃⍵
0=1⊃⍵:1+2⊃⍵
0=2⊃⍵:∇(¯1+1⊃⍵)1
0=2⊃⍵:∇(¯1+1⊃⍵)1
∇(¯1+1⊃⍵),∇(1⊃⍵),¯1+2⊃⍵
∇(¯1+1⊃⍵),∇(1⊃⍵),¯1+2⊃⍵
}</lang>
}</syntaxhighlight>


=={{header|AppleScript}}==
=={{header|AppleScript}}==


<lang AppleScript>on ackermann(m, n)
<syntaxhighlight lang=AppleScript>on ackermann(m, n)
if m is equal to 0 then return n + 1
if m is equal to 0 then return n + 1
if n is equal to 0 then return ackermann(m - 1, 1)
if n is equal to 0 then return ackermann(m - 1, 1)
return ackermann(m - 1, ackermann(m, n - 1))
return ackermann(m - 1, ackermann(m, n - 1))
end ackermann</lang>
end ackermann</syntaxhighlight>


=={{header|Argile}}==
=={{header|Argile}}==
{{works with|Argile|1.0.0}}
{{works with|Argile|1.0.0}}
<lang Argile>use std
<syntaxhighlight lang=Argile>use std


for each (val nat n) from 0 to 6
for each (val nat n) from 0 to 6
Line 1,048: Line 1,048:
return (n+1) if m == 0
return (n+1) if m == 0
return (A (m - 1) 1) if n == 0
return (A (m - 1) 1) if n == 0
A (m - 1) (A m (n - 1))</lang>
A (m - 1) (A m (n - 1))</syntaxhighlight>
=={{header|ARM Assembly}}==
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
<lang ARM Assembly>
<syntaxhighlight lang=ARM Assembly>
/* ARM assembly Raspberry PI or android 32 bits */
/* ARM assembly Raspberry PI or android 32 bits */
/* program ackermann.s */
/* program ackermann.s */
Line 1,171: Line 1,171:
/***************************************************/
/***************************************************/
.include "../affichage.inc"
.include "../affichage.inc"
</syntaxhighlight>
</lang>
{{Output}}
{{Output}}
<pre>
<pre>
Line 1,218: Line 1,218:
=={{header|Arturo}}==
=={{header|Arturo}}==


<lang rebol>ackermann: function [m,n][
<syntaxhighlight lang=rebol>ackermann: function [m,n][
(m=0)? -> n+1 [
(m=0)? -> n+1 [
(n=0)? -> ackermann m-1 1
(n=0)? -> ackermann m-1 1
Line 1,229: Line 1,229:
print ["ackermann" a b "=>" ackermann a b]
print ["ackermann" a b "=>" ackermann a b]
]
]
]</lang>
]</syntaxhighlight>


{{out}}
{{out}}
Line 1,255: Line 1,255:


=={{header|ATS}}==
=={{header|ATS}}==
<lang ATS>fun ackermann
<syntaxhighlight lang=ATS>fun ackermann
{m,n:nat} .<m,n>.
{m,n:nat} .<m,n>.
(m: int m, n: int n): Nat =
(m: int m, n: int n): Nat =
Line 1,262: Line 1,262:
| (_, 0) =>> ackermann (m-1, 1)
| (_, 0) =>> ackermann (m-1, 1)
| (_, _) =>> ackermann (m-1, ackermann (m, n-1))
| (_, _) =>> ackermann (m-1, ackermann (m, n-1))
// end of [ackermann]</lang>
// end of [ackermann]</syntaxhighlight>


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
<lang AutoHotkey>A(m, n) {
<syntaxhighlight lang=AutoHotkey>A(m, n) {
If (m > 0) && (n = 0)
If (m > 0) && (n = 0)
Return A(m-1,1)
Return A(m-1,1)
Line 1,275: Line 1,275:


; Example:
; Example:
MsgBox, % "A(1,2) = " A(1,2)</lang>
MsgBox, % "A(1,2) = " A(1,2)</syntaxhighlight>


=={{header|AutoIt}}==
=={{header|AutoIt}}==
=== Classical version ===
=== Classical version ===
<lang autoit>Func Ackermann($m, $n)
<syntaxhighlight lang=autoit>Func Ackermann($m, $n)
If ($m = 0) Then
If ($m = 0) Then
Return $n+1
Return $n+1
Line 1,289: Line 1,289:
EndIf
EndIf
EndIf
EndIf
EndFunc</lang>
EndFunc</syntaxhighlight>


=== Classical + cache implementation ===
=== Classical + cache implementation ===
Line 1,295: Line 1,295:
This version works way faster than the classical one: Ackermann(3, 5) runs in 12,7 ms, while the classical version takes 402,2 ms.
This version works way faster than the classical one: Ackermann(3, 5) runs in 12,7 ms, while the classical version takes 402,2 ms.


<lang autoit>Global $ackermann[2047][2047] ; Set the size to whatever you want
<syntaxhighlight lang=autoit>Global $ackermann[2047][2047] ; Set the size to whatever you want
Func Ackermann($m, $n)
Func Ackermann($m, $n)
If ($ackermann[$m][$n] <> 0) Then
If ($ackermann[$m][$n] <> 0) Then
Line 1,312: Line 1,312:
Return $return
Return $return
EndIf
EndIf
EndFunc ;==>Ackermann</lang>
EndFunc ;==>Ackermann</syntaxhighlight>


=={{header|AWK}}==
=={{header|AWK}}==
<lang awk>function ackermann(m, n)
<syntaxhighlight lang=awk>function ackermann(m, n)
{
{
if ( m == 0 ) {
if ( m == 0 ) {
Line 1,332: Line 1,332:
}
}
}
}
}</lang>
}</syntaxhighlight>


=={{header|Babel}}==
=={{header|Babel}}==
<lang babel>main:
<syntaxhighlight lang=babel>main:
{((0 0) (0 1) (0 2)
{((0 0) (0 1) (0 2)
(0 3) (0 4) (1 0)
(0 3) (0 4) (1 0)
Line 1,367: Line 1,367:


zero?!: { 0 = }
zero?!: { 0 = }
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,391: Line 1,391:
=={{header|BASIC}}==
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
==={{header|Applesoft BASIC}}===
<lang basic>100 DIM R%(2900),M(2900),N(2900)
<syntaxhighlight lang=basic>100 DIM R%(2900),M(2900),N(2900)
110 FOR M = 0 TO 3
110 FOR M = 0 TO 3
120 FOR N = 0 TO 4
120 FOR N = 0 TO 4
Line 1,414: Line 1,414:
250 M = M(SP) : N = N(SP) : IF SP = 0 THEN RETURN
250 M = M(SP) : N = N(SP) : IF SP = 0 THEN RETURN
260 FOR SP = SP - 1 TO 0 STEP -1 : IF R%(SP) THEN M = M(SP) : N = N(SP) : NEXT SP : SP = 0 : RETURN
260 FOR SP = SP - 1 TO 0 STEP -1 : IF R%(SP) THEN M = M(SP) : N = N(SP) : NEXT SP : SP = 0 : RETURN
270 M = M - 1 : N = ACK : R%(SP) = 1 : SP = SP + 1 : GOTO 200</lang>
270 M = M - 1 : N = ACK : R%(SP) = 1 : SP = SP + 1 : GOTO 200</syntaxhighlight>


==={{header|BASIC256}}===
==={{header|BASIC256}}===
<lang basic256>dim stack(5000, 3) # BASIC-256 lacks functions (as of ver. 0.9.6.66)
<syntaxhighlight lang=basic256>dim stack(5000, 3) # BASIC-256 lacks functions (as of ver. 0.9.6.66)
stack[0,0] = 3 # M
stack[0,0] = 3 # M
stack[0,1] = 7 # N
stack[0,1] = 7 # N
Line 1,449: Line 1,449:
stack[lev-1,2] = stack[lev,2]
stack[lev-1,2] = stack[lev,2]
lev = lev-1
lev = lev-1
return</lang>
return</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,455: Line 1,455:
</pre>
</pre>


<lang basic256># BASIC256 since 0.9.9.1 supports functions
<syntaxhighlight lang=basic256># BASIC256 since 0.9.9.1 supports functions
for m = 0 to 3
for m = 0 to 3
for n = 0 to 4
for n = 0 to 4
Line 1,473: Line 1,473:
endif
endif
end if
end if
end function</lang>
end function</syntaxhighlight>


{{out}}
{{out}}
Line 1,499: Line 1,499:


==={{header|BBC BASIC}}===
==={{header|BBC BASIC}}===
<lang bbcbasic> PRINT FNackermann(3, 7)
<syntaxhighlight lang=bbcbasic> PRINT FNackermann(3, 7)
END
END
Line 1,505: Line 1,505:
IF M% = 0 THEN = N% + 1
IF M% = 0 THEN = N% + 1
IF N% = 0 THEN = FNackermann(M% - 1, 1)
IF N% = 0 THEN = FNackermann(M% - 1, 1)
= FNackermann(M% - 1, FNackermann(M%, N%-1))</lang>
= FNackermann(M% - 1, FNackermann(M%, N%-1))</syntaxhighlight>


==={{header|QuickBasic}}===
==={{header|QuickBasic}}===
Line 1,511: Line 1,511:
BASIC runs out of stack space very quickly.
BASIC runs out of stack space very quickly.
The call <tt>ack(3, 4)</tt> gives a stack error.
The call <tt>ack(3, 4)</tt> gives a stack error.
<lang qbasic>DECLARE FUNCTION ack! (m!, n!)
<syntaxhighlight lang=qbasic>DECLARE FUNCTION ack! (m!, n!)


FUNCTION ack (m!, n!)
FUNCTION ack (m!, n!)
Line 1,522: Line 1,522:
ack = ack(m - 1, ack(m, n - 1))
ack = ack(m - 1, ack(m, n - 1))
END IF
END IF
END FUNCTION</lang>
END FUNCTION</syntaxhighlight>


=={{header|Batch File}}==
=={{header|Batch File}}==
Had trouble with this, so called in the gurus at [http://stackoverflow.com/questions/2680668/what-is-wrong-with-this-recursive-windows-cmd-script-it-wont-do-ackermann-prope StackOverflow]. Thanks to Patrick Cuff for pointing out where I was going wrong.
Had trouble with this, so called in the gurus at [http://stackoverflow.com/questions/2680668/what-is-wrong-with-this-recursive-windows-cmd-script-it-wont-do-ackermann-prope StackOverflow]. Thanks to Patrick Cuff for pointing out where I was going wrong.
<lang dos>::Ackermann.cmd
<syntaxhighlight lang=dos>::Ackermann.cmd
@echo off
@echo off
set depth=0
set depth=0
Line 1,556: Line 1,556:
set t=%errorlevel%
set t=%errorlevel%
set /a depth-=1
set /a depth-=1
if %depth%==0 ( exit %t% ) else ( exit /b %t% )</lang>
if %depth%==0 ( exit %t% ) else ( exit /b %t% )</syntaxhighlight>
Because of the <code>exit</code> statements, running this bare closes one's shell, so this test routine handles the calling of Ackermann.cmd
Because of the <code>exit</code> statements, running this bare closes one's shell, so this test routine handles the calling of Ackermann.cmd
<lang dos>::Ack.cmd
<syntaxhighlight lang=dos>::Ack.cmd
@echo off
@echo off
cmd/c ackermann.cmd %1 %2
cmd/c ackermann.cmd %1 %2
echo Ackermann(%1, %2)=%errorlevel%</lang>
echo Ackermann(%1, %2)=%errorlevel%</syntaxhighlight>
A few test runs:
A few test runs:
<pre>D:\Documents and Settings\Bruce>ack 0 4
<pre>D:\Documents and Settings\Bruce>ack 0 4
Line 1,579: Line 1,579:
{{works with|OpenBSD bc}}
{{works with|OpenBSD bc}}
{{Works with|GNU bc}}
{{Works with|GNU bc}}
<lang bc>define ack(m, n) {
<syntaxhighlight lang=bc>define ack(m, n) {
if ( m == 0 ) return (n+1);
if ( m == 0 ) return (n+1);
if ( n == 0 ) return (ack(m-1, 1));
if ( n == 0 ) return (ack(m-1, 1));
Line 1,590: Line 1,590:
}
}
}
}
quit</lang>
quit</syntaxhighlight>


=={{header|BCPL}}==
=={{header|BCPL}}==
<lang BCPL>GET "libhdr"
<syntaxhighlight lang=BCPL>GET "libhdr"


LET ack(m, n) = m=0 -> n+1,
LET ack(m, n) = m=0 -> n+1,
Line 1,603: Line 1,603:
writef("ack(%n, %n) = %n*n", m, n, ack(m,n))
writef("ack(%n, %n) = %n*n", m, n, ack(m,n))
RESULTIS 0
RESULTIS 0
}</lang>
}</syntaxhighlight>


=={{header|beeswax}}==
=={{header|beeswax}}==
Line 1,609: Line 1,609:
Iterative slow version:
Iterative slow version:


<lang beeswax>
<syntaxhighlight lang=beeswax>
>M?f@h@gMf@h3yzp if m>0 and n>0 => replace m,n with m-1,m,n-1
>M?f@h@gMf@h3yzp if m>0 and n>0 => replace m,n with m-1,m,n-1
>@h@g'b?1f@h@gM?f@hzp if m>0 and n=0 => replace m,n with m-1,1
>@h@g'b?1f@h@gM?f@hzp if m>0 and n=0 => replace m,n with m-1,1
Line 1,615: Line 1,615:
>I;
>I;
b < <
b < <
</syntaxhighlight>
</lang>


A functional and recursive realization of the version above. Functions are realized by direct calls of functions via jumps (instruction <code>J</code>) to the entry points of two distinct functions:
A functional and recursive realization of the version above. Functions are realized by direct calls of functions via jumps (instruction <code>J</code>) to the entry points of two distinct functions:
Line 1,625: Line 1,625:
Each block of <code>1FJ</code> or <code>1fFJ</code> in the code is a call of the Ackermann function itself.
Each block of <code>1FJ</code> or <code>1fFJ</code> in the code is a call of the Ackermann function itself.


<lang beeswax>Ag~1?Lp1~2@g'p?g?Pf1FJ Ackermann function. if m=0 => run Ackermann function (m, n+1)
<syntaxhighlight lang=beeswax>Ag~1?Lp1~2@g'p?g?Pf1FJ Ackermann function. if m=0 => run Ackermann function (m, n+1)
xI; x@g'p??@Mf1fFJ if m>0 and n=0 => run Ackermann (m-1,1)
xI; x@g'p??@Mf1fFJ if m>0 and n=0 => run Ackermann (m-1,1)
xM@~gM??f~f@f1FJ if m>0 and n>0 => run Ackermann(m,Ackermann(m-1,n-1))
xM@~gM??f~f@f1FJ if m>0 and n>0 => run Ackermann(m,Ackermann(m-1,n-1))
_ii1FJ input function. Input m,n, then execute Ackermann(m,n)</lang>
_ii1FJ input function. Input m,n, then execute Ackermann(m,n)</syntaxhighlight>


Highly optimized and fast version, returns A(4,1)/A(5,0) almost instantaneously:
Highly optimized and fast version, returns A(4,1)/A(5,0) almost instantaneously:
<lang beeswax>
<syntaxhighlight lang=beeswax>
>Mf@Ph?@g@2h@Mf@Php if m>4 and n>0 => replace m,n with m-1,m,n-1
>Mf@Ph?@g@2h@Mf@Php if m>4 and n>0 => replace m,n with m-1,m,n-1
>~4~L#1~2hg'd?1f@hgM?f2h p if m>4 and n=0 => replace m,n with m-1,1
>~4~L#1~2hg'd?1f@hgM?f2h p if m>4 and n=0 => replace m,n with m-1,1
Line 1,642: Line 1,642:
z b < < <
z b < < <
d <
d <
</syntaxhighlight>
</lang>


Higher values than A(4,1)/(5,0) lead to UInt64 wraparound, support for numbers bigger than 2^64-1 is not implemented in these solutions.
Higher values than A(4,1)/(5,0) lead to UInt64 wraparound, support for numbers bigger than 2^64-1 is not implemented in these solutions.
Line 1,651: Line 1,651:
{{trans|ERRE}}
{{trans|ERRE}}
Since Befunge-93 doesn't have recursive capabilities we need to use an iterative algorithm.
Since Befunge-93 doesn't have recursive capabilities we need to use an iterative algorithm.
<lang befunge>&>&>vvg0>#0\#-:#1_1v
<syntaxhighlight lang=befunge>&>&>vvg0>#0\#-:#1_1v
@v:\<vp0 0:-1<\+<
@v:\<vp0 0:-1<\+<
^>00p>:#^_$1+\:#^_$.
^>00p>:#^_$1+\:#^_$.
</syntaxhighlight>
</lang>


===Befunge-98===
===Befunge-98===
{{works with|CCBI|2.1}}
{{works with|CCBI|2.1}}
<lang befunge>r[1&&{0
<syntaxhighlight lang=befunge>r[1&&{0
>v
>v
j
j
Line 1,665: Line 1,665:
^ v:\_$1+
^ v:\_$1+
\^v_$1\1-
\^v_$1\1-
u^>1-0fp:1-\0fg101-</lang>
u^>1-0fp:1-\0fg101-</syntaxhighlight>
The program reads two integers (first m, then n) from command line, idles around funge space, then outputs the result of the Ackerman function.
The program reads two integers (first m, then n) from command line, idles around funge space, then outputs the result of the Ackerman function.
Since the latter is calculated truly recursively, the execution time becomes unwieldy for most m>3.
Since the latter is calculated truly recursively, the execution time becomes unwieldy for most m>3.


=={{header|BQN}}==
=={{header|BQN}}==
<lang BQN>A ← {
<syntaxhighlight lang=BQN>A ← {
A 0‿n: n+1;
A 0‿n: n+1;
A m‿0: A (m-1)‿1;
A m‿0: A (m-1)‿1;
A m‿n: A (m-1)‿(A m‿(n-1))
A m‿n: A (m-1)‿(A m‿(n-1))
}</lang>
}</syntaxhighlight>
Example usage:
Example usage:
<lang> A 0‿3
<lang> A 0‿3
Line 1,683: Line 1,683:
11
11
A 3‿4
A 3‿4
125</lang>
125</syntaxhighlight>


=={{header|Bracmat}}==
=={{header|Bracmat}}==
Line 1,690: Line 1,690:
The value of A(4,1) cannot be computed due to stack overflow.
The value of A(4,1) cannot be computed due to stack overflow.
It can compute A(3,9) (4093), but probably not A(3,10)
It can compute A(3,9) (4093), but probably not A(3,10)
<lang bracmat>( Ack
<syntaxhighlight lang=bracmat>( Ack
= m n
= m n
. !arg:(?m,?n)
. !arg:(?m,?n)
Line 1,697: Line 1,697:
| Ack$(!m+-1,Ack$(!m,!n+-1))
| Ack$(!m+-1,Ack$(!m,!n+-1))
)
)
);</lang>
);</syntaxhighlight>
The second version is a purely non-recursive solution that easily can compute A(4,1).
The second version is a purely non-recursive solution that easily can compute A(4,1).
The program uses a stack for Ackermann function calls that are to be evaluated, but that cannot be computed given the currently known function values - the "known unknowns".
The program uses a stack for Ackermann function calls that are to be evaluated, but that cannot be computed given the currently known function values - the "known unknowns".
Line 1,705: Line 1,705:


Although all known values are stored in the hash table, the converse is not true: an element in the hash table is either a "known known" or an "unknown unknown" associated with an "known unknown".
Although all known values are stored in the hash table, the converse is not true: an element in the hash table is either a "known known" or an "unknown unknown" associated with an "known unknown".
<lang bracmat> ( A
<syntaxhighlight lang=bracmat> ( A
= m n value key eq chain
= m n value key eq chain
, find insert future stack va val
, find insert future stack va val
Line 1,765: Line 1,765:
& !value
& !value
)
)
& new$hash:?cache</lang>
& new$hash:?cache</syntaxhighlight>
{{out|Some results}}
{{out|Some results}}
<pre>
<pre>
Line 1,774: Line 1,774:
</pre>
</pre>
The last solution is a recursive solution that employs some extra formulas, inspired by the Common Lisp solution further down.
The last solution is a recursive solution that employs some extra formulas, inspired by the Common Lisp solution further down.
<lang bracmat>( AckFormula
<syntaxhighlight lang=bracmat>( AckFormula
= m n
= m n
. !arg:(?m,?n)
. !arg:(?m,?n)
Line 1,784: Line 1,784:
| AckFormula$(!m+-1,AckFormula$(!m,!n+-1))
| AckFormula$(!m+-1,AckFormula$(!m,!n+-1))
)
)
)</lang>
)</syntaxhighlight>
{{Out|Some results}}
{{Out|Some results}}
<pre>AckFormula$(4,1):65533
<pre>AckFormula$(4,1):65533
Line 1,792: Line 1,792:


=={{header|Brat}}==
=={{header|Brat}}==
<lang brat>ackermann = { m, n |
<syntaxhighlight lang=brat>ackermann = { m, n |
when { m == 0 } { n + 1 }
when { m == 0 } { n + 1 }
{ m > 0 && n == 0 } { ackermann(m - 1, 1) }
{ m > 0 && n == 0 } { ackermann(m - 1, 1) }
Line 1,798: Line 1,798:
}
}


p ackermann 3, 4 #Prints 125</lang>
p ackermann 3, 4 #Prints 125</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
Straightforward implementation per Ackermann definition:
Straightforward implementation per Ackermann definition:
<lang C>#include <stdio.h>
<syntaxhighlight lang=C>#include <stdio.h>


int ackermann(int m, int n)
int ackermann(int m, int n)
Line 1,819: Line 1,819:


return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>A(0, 0) = 1
<pre>A(0, 0) = 1
Line 1,842: Line 1,842:
A(4, 1) = 65533</pre>
A(4, 1) = 65533</pre>
Ackermann function makes <i>a lot</i> of recursive calls, so the above program is a bit naive. We need to be slightly less naive, by doing some simple caching:
Ackermann function makes <i>a lot</i> of recursive calls, so the above program is a bit naive. We need to be slightly less naive, by doing some simple caching:
<lang C>#include <stdio.h>
<syntaxhighlight lang=C>#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
Line 1,882: Line 1,882:


return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>A(0, 0) = 1
<pre>A(0, 0) = 1
Line 1,908: Line 1,908:


A couple of alternative approaches...
A couple of alternative approaches...
<lang C>/* Thejaka Maldeniya */
<syntaxhighlight lang=C>/* Thejaka Maldeniya */


#include <conio.h>
#include <conio.h>
Line 2,007: Line 2,007:
//getch();
//getch();
return 0;
return 0;
}</lang>
}</syntaxhighlight>


A couple of more iterative techniques...
A couple of more iterative techniques...
<lang C>/* Thejaka Maldeniya */
<syntaxhighlight lang=C>/* Thejaka Maldeniya */


#include <conio.h>
#include <conio.h>
Line 2,156: Line 2,156:
//getch();
//getch();
return 0;
return 0;
}</lang>
}</syntaxhighlight>


A few further tweaks/optimizations may be possible.
A few further tweaks/optimizations may be possible.
Line 2,163: Line 2,163:


===Basic Version===
===Basic Version===
<lang csharp>using System;
<syntaxhighlight lang=csharp>using System;
class Program
class Program
{
{
Line 2,194: Line 2,194:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,220: Line 2,220:


===Efficient Version===
===Efficient Version===
<lang csharp>
<syntaxhighlight lang=csharp>
using System;
using System;
using System.Numerics;
using System.Numerics;
Line 2,348: Line 2,348:
}
}
}
}
</syntaxhighlight>
</lang>
Possibly the most efficient implementation of Ackermann in C#. It successfully runs Ack(4,2) when executed in Visual Studio. Don't forget to add a reference to System.Numerics.
Possibly the most efficient implementation of Ackermann in C#. It successfully runs Ack(4,2) when executed in Visual Studio. Don't forget to add a reference to System.Numerics.


Line 2,354: Line 2,354:


===Basic version===
===Basic version===
<lang cpp>#include <iostream>
<syntaxhighlight lang=cpp>#include <iostream>


unsigned int ackermann(unsigned int m, unsigned int n) {
unsigned int ackermann(unsigned int m, unsigned int n) {
Line 2,373: Line 2,373:
}
}
}
}
</syntaxhighlight>
</lang>


===Efficient version===
===Efficient version===
Line 2,379: Line 2,379:
C++11 with boost's big integer type. Compile with:
C++11 with boost's big integer type. Compile with:
g++ -std=c++11 -I /path/to/boost ackermann.cpp.
g++ -std=c++11 -I /path/to/boost ackermann.cpp.
<lang cpp>#include <iostream>
<syntaxhighlight lang=cpp>#include <iostream>
#include <sstream>
#include <sstream>
#include <string>
#include <string>
Line 2,432: Line 2,432:
<< text.substr(0, 80) << "\n...\n"
<< text.substr(0, 80) << "\n...\n"
<< text.substr(text.length() - 80) << "\n";
<< text.substr(text.length() - 80) << "\n";
}</lang>
}</syntaxhighlight>
<pre>
<pre>
<pre>
<pre>
Line 2,483: Line 2,483:


=={{header|Chapel}}==
=={{header|Chapel}}==
<lang chapel>proc A(m:int, n:int):int {
<syntaxhighlight lang=chapel>proc A(m:int, n:int):int {
if m == 0 then
if m == 0 then
return n + 1;
return n + 1;
Line 2,490: Line 2,490:
else
else
return A(m - 1, A(m, n - 1));
return A(m - 1, A(m, n - 1));
}</lang>
}</syntaxhighlight>


=={{header|Clay}}==
=={{header|Clay}}==
<lang Clay>ackermann(m, n) {
<syntaxhighlight lang=Clay>ackermann(m, n) {
if(m == 0)
if(m == 0)
return n + 1;
return n + 1;
Line 2,500: Line 2,500:


return ackermann(m - 1, ackermann(m, n - 1));
return ackermann(m - 1, ackermann(m, n - 1));
}</lang>
}</syntaxhighlight>


=={{header|CLIPS}}==
=={{header|CLIPS}}==
'''Functional solution'''
'''Functional solution'''
<lang clips>(deffunction ackerman
<syntaxhighlight lang=clips>(deffunction ackerman
(?m ?n)
(?m ?n)
(if (= 0 ?m)
(if (= 0 ?m)
Line 2,513: Line 2,513:
)
)
)
)
)</lang>
)</syntaxhighlight>
{{out|Example usage}}
{{out|Example usage}}
<pre>CLIPS> (ackerman 0 4)
<pre>CLIPS> (ackerman 0 4)
Line 2,525: Line 2,525:
</pre>
</pre>
'''Fact-based solution'''
'''Fact-based solution'''
<lang clips>(deffacts solve-items
<syntaxhighlight lang=clips>(deffacts solve-items
(solve 0 4)
(solve 0 4)
(solve 1 4)
(solve 1 4)
Line 2,592: Line 2,592:
(retract ?solve)
(retract ?solve)
(printout t "A(" ?m "," ?n ") = " ?result crlf)
(printout t "A(" ?m "," ?n ") = " ?result crlf)
)</lang>
)</syntaxhighlight>
When invoked, each required A(m,n) needed to solve the requested (solve ?m ?n) facts gets generated as its own fact. Below shows the invocation of the above, as well as an excerpt of the final facts list. Regardless of how many input (solve ?m ?n) requests are made, each possible A(m,n) is only solved once.
When invoked, each required A(m,n) needed to solve the requested (solve ?m ?n) facts gets generated as its own fact. Below shows the invocation of the above, as well as an excerpt of the final facts list. Regardless of how many input (solve ?m ?n) requests are made, each possible A(m,n) is only solved once.
<pre>CLIPS> (reset)
<pre>CLIPS> (reset)
Line 2,620: Line 2,620:


=={{header|Clojure}}==
=={{header|Clojure}}==
<lang clojure>(defn ackermann [m n]
<syntaxhighlight lang=clojure>(defn ackermann [m n]
(cond (zero? m) (inc n)
(cond (zero? m) (inc n)
(zero? n) (ackermann (dec m) 1)
(zero? n) (ackermann (dec m) 1)
:else (ackermann (dec m) (ackermann m (dec n)))))</lang>
:else (ackermann (dec m) (ackermann m (dec n)))))</syntaxhighlight>


=={{header|CLU}}==
=={{header|CLU}}==
<lang clu>% Ackermann function
<syntaxhighlight lang=clu>% Ackermann function
ack = proc (m, n: int) returns (int)
ack = proc (m, n: int) returns (int)
if m=0 then return(n+1)
if m=0 then return(n+1)
Line 2,644: Line 2,644:
stream$putl(po, "")
stream$putl(po, "")
end
end
end start_up </lang>
end start_up </syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7 8 9
<pre> 1 2 3 4 5 6 7 8 9
Line 2,652: Line 2,652:


=={{header|COBOL}}==
=={{header|COBOL}}==
<lang cobol> IDENTIFICATION DIVISION.
<syntaxhighlight lang=cobol> IDENTIFICATION DIVISION.
PROGRAM-ID. Ackermann.
PROGRAM-ID. Ackermann.


Line 2,683: Line 2,683:


GOBACK
GOBACK
.</lang>
.</syntaxhighlight>


=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
<lang coffeescript>ackermann = (m, n) ->
<syntaxhighlight lang=coffeescript>ackermann = (m, n) ->
if m is 0 then n + 1
if m is 0 then n + 1
else if m > 0 and n is 0 then ackermann m - 1, 1
else if m > 0 and n is 0 then ackermann m - 1, 1
else ackermann m - 1, ackermann m, n - 1</lang>
else ackermann m - 1, ackermann m, n - 1</syntaxhighlight>


=={{header|Comal}}==
=={{header|Comal}}==
<lang comal>0010 //
<syntaxhighlight lang=comal>0010 //
0020 // Ackermann function
0020 // Ackermann function
0030 //
0030 //
Line 2,708: Line 2,708:
0150 PRINT
0150 PRINT
0160 ENDFOR m#
0160 ENDFOR m#
0170 END</lang>
0170 END</syntaxhighlight>
{{out}}
{{out}}
<pre>1 2 3 4 5
<pre>1 2 3 4 5
Line 2,716: Line 2,716:


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>(defun ackermann (m n)
<syntaxhighlight lang=lisp>(defun ackermann (m n)
(cond ((zerop m) (1+ n))
(cond ((zerop m) (1+ n))
((zerop n) (ackermann (1- m) 1))
((zerop n) (ackermann (1- m) 1))
(t (ackermann (1- m) (ackermann m (1- n))))))</lang>
(t (ackermann (1- m) (ackermann m (1- n))))))</syntaxhighlight>
More elaborately:
More elaborately:
<lang lisp>(defun ackermann (m n)
<syntaxhighlight lang=lisp>(defun ackermann (m n)
(case m ((0) (1+ n))
(case m ((0) (1+ n))
((1) (+ 2 n))
((1) (+ 2 n))
Line 2,730: Line 2,730:
(loop for m from 0 to 4 do
(loop for m from 0 to 4 do
(loop for n from (- 5 m) to (- 6 m) do
(loop for n from (- 5 m) to (- 6 m) do
(format t "A(~d, ~d) = ~d~%" m n (ackermann m n))))</lang>
(format t "A(~d, ~d) = ~d~%" m n (ackermann m n))))</syntaxhighlight>
{{out}}<pre>A(0, 5) = 6
{{out}}<pre>A(0, 5) = 6
A(0, 6) = 7
A(0, 6) = 7
Line 2,744: Line 2,744:
=={{header|Component Pascal}}==
=={{header|Component Pascal}}==
BlackBox Component Builder
BlackBox Component Builder
<lang oberon2>
<syntaxhighlight lang=oberon2>
MODULE NpctAckerman;
MODULE NpctAckerman;
Line 2,774: Line 2,774:


END NpctAckerman.
END NpctAckerman.
</syntaxhighlight>
</lang>
Execute: ^Q NpctAckerman.Do<br/>
Execute: ^Q NpctAckerman.Do<br/>
<pre>
<pre>
Line 2,785: Line 2,785:


=={{header|Coq}}==
=={{header|Coq}}==
<lang coq>Require Import Arith.
<syntaxhighlight lang=coq>Require Import Arith.
Fixpoint A m := fix A_m n :=
Fixpoint A m := fix A_m n :=
match m with
match m with
Line 2,794: Line 2,794:
| S pn => A pm (A_m pn)
| S pn => A pm (A_m pn)
end
end
end.</lang>
end.</syntaxhighlight>


<lang coq>Require Import Utf8.
<syntaxhighlight lang=coq>Require Import Utf8.


Section FOLD.
Section FOLD.
Line 2,809: Line 2,809:
Definition ackermann : nat → nat → nat :=
Definition ackermann : nat → nat → nat :=
fold (λ g, fold g (g (S O))) S.
fold (λ g, fold g (g (S O))) S.
</syntaxhighlight>
</lang>


=={{header|Crystal}}==
=={{header|Crystal}}==
{{trans|Ruby}}
{{trans|Ruby}}
<lang ruby>def ack(m, n)
<syntaxhighlight lang=ruby>def ack(m, n)
if m == 0
if m == 0
n + 1
n + 1
Line 2,827: Line 2,827:
puts (0..6).map { |n| ack(m, n) }.join(' ')
puts (0..6).map { |n| ack(m, n) }.join(' ')
end
end
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 2,839: Line 2,839:
=={{header|D}}==
=={{header|D}}==
===Basic version===
===Basic version===
<lang d>ulong ackermann(in ulong m, in ulong n) pure nothrow @nogc {
<syntaxhighlight lang=d>ulong ackermann(in ulong m, in ulong n) pure nothrow @nogc {
if (m == 0)
if (m == 0)
return n + 1;
return n + 1;
Line 2,849: Line 2,849:
void main() {
void main() {
assert(ackermann(2, 4) == 11);
assert(ackermann(2, 4) == 11);
}</lang>
}</syntaxhighlight>


===More Efficient Version===
===More Efficient Version===
{{trans|Mathematica}}
{{trans|Mathematica}}
<lang d>import std.stdio, std.bigint, std.conv;
<syntaxhighlight lang=d>import std.stdio, std.bigint, std.conv;


BigInt ipow(BigInt base, BigInt exp) pure nothrow {
BigInt ipow(BigInt base, BigInt exp) pure nothrow {
Line 2,896: Line 2,896:
writefln("ackermann(4, 2)) (%d digits):\n%s...\n%s",
writefln("ackermann(4, 2)) (%d digits):\n%s...\n%s",
a.length, a[0 .. 94], a[$ - 96 .. $]);
a.length, a[0 .. 94], a[$ - 96 .. $]);
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 2,930: Line 2,930:
=={{header|Dart}}==
=={{header|Dart}}==
no caching, the implementation takes ages even for A(4,1)
no caching, the implementation takes ages even for A(4,1)
<lang dart>int A(int m, int n) => m==0 ? n+1 : n==0 ? A(m-1,1) : A(m-1,A(m,n-1));
<syntaxhighlight lang=dart>int A(int m, int n) => m==0 ? n+1 : n==0 ? A(m-1,1) : A(m-1,A(m,n-1));


main() {
main() {
Line 2,942: Line 2,942:
print(A(3,5));
print(A(3,5));
print(A(4,0));
print(A(4,0));
}</lang>
}</syntaxhighlight>


=={{header|Dc}}==
=={{header|Dc}}==
This needs a modern Dc with <code>r</code> (swap) and <code>#</code> (comment). It easily can be adapted to an older Dc, but it will impact readability a lot.
This needs a modern Dc with <code>r</code> (swap) and <code>#</code> (comment). It easily can be adapted to an older Dc, but it will impact readability a lot.
<lang dc>[ # todo: n 0 -- n+1 and break 2 levels
<syntaxhighlight lang=dc>[ # todo: n 0 -- n+1 and break 2 levels
+ 1 + # n+1
+ 1 + # n+1
q
q
Line 2,968: Line 2,968:
] sA
] sA


3 9 lA x f</lang>
3 9 lA x f</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,975: Line 2,975:


=={{header|Delphi}}==
=={{header|Delphi}}==
<lang delphi>function Ackermann(m,n:Int64):Int64;
<syntaxhighlight lang=delphi>function Ackermann(m,n:Int64):Int64;
begin
begin
if m = 0 then
if m = 0 then
Line 2,983: Line 2,983:
else
else
Result := Ackermann(m-1, Ackermann(m, n - 1));
Result := Ackermann(m-1, Ackermann(m, n - 1));
end;</lang>
end;</syntaxhighlight>


=={{header|Draco}}==
=={{header|Draco}}==
<lang draco>/* Ackermann function */
<syntaxhighlight lang=draco>/* Ackermann function */
proc ack(word m, n) word:
proc ack(word m, n) word:
if m=0 then n+1
if m=0 then n+1
Line 3,003: Line 3,003:
writeln()
writeln()
od
od
corp</lang>
corp</syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7 8 9
<pre> 1 2 3 4 5 6 7 8 9
Line 3,011: Line 3,011:


=={{header|DWScript}}==
=={{header|DWScript}}==
<lang delphi>function Ackermann(m, n : Integer) : Integer;
<syntaxhighlight lang=delphi>function Ackermann(m, n : Integer) : Integer;
begin
begin
if m = 0 then
if m = 0 then
Line 3,018: Line 3,018:
Result := Ackermann(m-1, 1)
Result := Ackermann(m-1, 1)
else Result := Ackermann(m-1, Ackermann(m, n-1));
else Result := Ackermann(m-1, Ackermann(m, n-1));
end;</lang>
end;</syntaxhighlight>


=={{header|Dylan}}==
=={{header|Dylan}}==
<lang dylan>define method ack(m == 0, n :: <integer>)
<syntaxhighlight lang=dylan>define method ack(m == 0, n :: <integer>)
n + 1
n + 1
end;
end;
define method ack(m :: <integer>, n :: <integer>)
define method ack(m :: <integer>, n :: <integer>)
ack(m - 1, if (n == 0) 1 else ack(m, n - 1) end)
ack(m - 1, if (n == 0) 1 else ack(m, n - 1) end)
end;</lang>
end;</syntaxhighlight>


=={{header|E}}==
=={{header|E}}==
<lang e>def A(m, n) {
<syntaxhighlight lang=e>def A(m, n) {
return if (m <=> 0) { n+1 } \
return if (m <=> 0) { n+1 } \
else if (m > 0 && n <=> 0) { A(m-1, 1) } \
else if (m > 0 && n <=> 0) { A(m-1, 1) } \
else { A(m-1, A(m,n-1)) }
else { A(m-1, A(m,n-1)) }
}</lang>
}</syntaxhighlight>


=={{header|EasyLang}}==
=={{header|EasyLang}}==
Line 3,047: Line 3,047:
.
.
call ackerm 3 6 r
call ackerm 3 6 r
print r</lang>
print r</syntaxhighlight>


=={{header|Egel}}==
=={{header|Egel}}==
<lang Egel>
<syntaxhighlight lang=Egel>
def ackermann =
def ackermann =
[ 0 N -> N + 1
[ 0 N -> N + 1
| M 0 -> ackermann (M - 1) 1
| M 0 -> ackermann (M - 1) 1
| M N -> ackermann (M - 1) (ackermann M (N - 1)) ]
| M N -> ackermann (M - 1) (ackermann M (N - 1)) ]
</syntaxhighlight>
</lang>


=={{header|Eiffel}}==
=={{header|Eiffel}}==
Line 3,062: Line 3,062:
[https://github.com/ljr1981/rosettacode_answers/blob/main/testing/rc_ackerman/rc_ackerman_test_set.e Test of Example code]
[https://github.com/ljr1981/rosettacode_answers/blob/main/testing/rc_ackerman/rc_ackerman_test_set.e Test of Example code]


<lang Eiffel>
<syntaxhighlight lang=Eiffel>
class
class
ACKERMAN_EXAMPLE
ACKERMAN_EXAMPLE
Line 3,086: Line 3,086:


end
end
</syntaxhighlight>
</lang>


=={{header|Ela}}==
=={{header|Ela}}==
<lang ela>ack 0 n = n+1
<syntaxhighlight lang=ela>ack 0 n = n+1
ack m 0 = ack (m - 1) 1
ack m 0 = ack (m - 1) 1
ack m n = ack (m - 1) <| ack m <| n - 1</lang>
ack m n = ack (m - 1) <| ack m <| n - 1</syntaxhighlight>


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 4.x :
ELENA 4.x :
<lang elena>import extensions;
<syntaxhighlight lang=elena>import extensions;


ackermann(m,n)
ackermann(m,n)
Line 3,124: Line 3,124:


console.readChar()
console.readChar()
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,154: Line 3,154:


=={{header|Elixir}}==
=={{header|Elixir}}==
<lang elixir>defmodule Ackermann do
<syntaxhighlight lang=elixir>defmodule Ackermann do
def ack(0, n), do: n + 1
def ack(0, n), do: n + 1
def ack(m, 0), do: ack(m - 1, 1)
def ack(m, 0), do: ack(m - 1, 1)
Line 3,162: Line 3,162:
Enum.each(0..3, fn m ->
Enum.each(0..3, fn m ->
IO.puts Enum.map_join(0..6, " ", fn n -> Ackermann.ack(m, n) end)
IO.puts Enum.map_join(0..6, " ", fn n -> Ackermann.ack(m, n) end)
end)</lang>
end)</syntaxhighlight>


{{out}}
{{out}}
Line 3,173: Line 3,173:


=={{header|Emacs Lisp}}==
=={{header|Emacs Lisp}}==
<lang lisp>(defun ackermann (m n)
<syntaxhighlight lang=lisp>(defun ackermann (m n)
(cond ((zerop m) (1+ n))
(cond ((zerop m) (1+ n))
((zerop n) (ackermann (1- m) 1))
((zerop n) (ackermann (1- m) 1))
(t (ackermann (1- m)
(t (ackermann (1- m)
(ackermann m (1- n))))))</lang>
(ackermann m (1- n))))))</syntaxhighlight>


=={{header|Erlang}}==
=={{header|Erlang}}==


<lang erlang>
<syntaxhighlight lang=erlang>
-module(ackermann).
-module(ackermann).
-export([ackermann/2]).
-export([ackermann/2]).
Line 3,191: Line 3,191:
ackermann(M, N) when M > 0 andalso N > 0 ->
ackermann(M, N) when M > 0 andalso N > 0 ->
ackermann(M-1, ackermann(M, N-1)).
ackermann(M-1, ackermann(M, N-1)).
</syntaxhighlight>
</lang>


=={{header|ERRE}}==
=={{header|ERRE}}==
Line 3,197: Line 3,197:
substituted with the new ERRE control statements.
substituted with the new ERRE control statements.


<lang erre>
<syntaxhighlight lang=erre>
PROGRAM ACKERMAN
PROGRAM ACKERMAN


Line 3,252: Line 3,252:
END FOR
END FOR
END PROGRAM
END PROGRAM
</syntaxhighlight>
</lang>


Prints a list of Ackermann function values: from A(0,0) to A(3,9). Uses a stack to avoid
Prints a list of Ackermann function values: from A(0,0) to A(3,9). Uses a stack to avoid
Line 3,270: Line 3,270:
=={{header|Euler Math Toolbox}}==
=={{header|Euler Math Toolbox}}==


<lang Euler Math Toolbox>
<syntaxhighlight lang=Euler Math Toolbox>
>M=zeros(1000,1000);
>M=zeros(1000,1000);
>function map A(m,n) ...
>function map A(m,n) ...
Line 3,287: Line 3,287:
3 5 7 9 11 13
3 5 7 9 11 13
5 13 29 61 125 253
5 13 29 61 125 253
</syntaxhighlight>
</lang>


=={{header|Euphoria}}==
=={{header|Euphoria}}==
This is based on the [[VBScript]] example.
This is based on the [[VBScript]] example.
<lang Euphoria>function ack(atom m, atom n)
<syntaxhighlight lang=Euphoria>function ack(atom m, atom n)
if m = 0 then
if m = 0 then
return n + 1
return n + 1
Line 3,306: Line 3,306:
end for
end for
puts( 1, "\n" )
puts( 1, "\n" )
end for</lang>
end for</syntaxhighlight>


=={{header|Ezhil}}==
=={{header|Ezhil}}==
<lang Ezhil>
<syntaxhighlight lang=Ezhil>
நிரல்பாகம் அகெர்மன்(முதலெண், இரண்டாமெண்)
நிரல்பாகம் அகெர்மன்(முதலெண், இரண்டாமெண்)


Line 3,348: Line 3,348:


முடி
முடி
</syntaxhighlight>
</lang>


=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
The following program implements the Ackermann function in F# but is not tail-recursive and so runs out of stack space quite fast.
The following program implements the Ackermann function in F# but is not tail-recursive and so runs out of stack space quite fast.
<lang fsharp>let rec ackermann m n =
<syntaxhighlight lang=fsharp>let rec ackermann m n =
match m, n with
match m, n with
| 0, n -> n + 1
| 0, n -> n + 1
Line 3,359: Line 3,359:


do
do
printfn "%A" (ackermann (int fsi.CommandLineArgs.[1]) (int fsi.CommandLineArgs.[2]))</lang>
printfn "%A" (ackermann (int fsi.CommandLineArgs.[1]) (int fsi.CommandLineArgs.[2]))</syntaxhighlight>
Transforming this into continuation passing style avoids limited stack space by permitting tail-recursion.
Transforming this into continuation passing style avoids limited stack space by permitting tail-recursion.
<lang fsharp>let ackermann M N =
<syntaxhighlight lang=fsharp>let ackermann M N =
let rec acker (m, n, k) =
let rec acker (m, n, k) =
match m,n with
match m,n with
Line 3,367: Line 3,367:
| m, 0 -> acker ((m - 1), 1, k)
| m, 0 -> acker ((m - 1), 1, k)
| m, n -> acker (m, (n - 1), (fun x -> acker ((m - 1), x, k)))
| m, n -> acker (m, (n - 1), (fun x -> acker ((m - 1), x, k)))
acker (M, N, (fun x -> x))</lang>
acker (M, N, (fun x -> x))</syntaxhighlight>


=={{header|Factor}}==
=={{header|Factor}}==
<lang factor>USING: kernel math locals combinators ;
<syntaxhighlight lang=factor>USING: kernel math locals combinators ;
IN: ackermann
IN: ackermann


Line 3,378: Line 3,378:
{ [ n 0 = ] [ m 1 - 1 ackermann ] }
{ [ n 0 = ] [ m 1 - 1 ackermann ] }
[ m 1 - m n 1 - ackermann ackermann ]
[ m 1 - m n 1 - ackermann ackermann ]
} cond ;</lang>
} cond ;</syntaxhighlight>


=={{header|Falcon}}==
=={{header|Falcon}}==
<lang falcon>function ackermann( m, n )
<syntaxhighlight lang=falcon>function ackermann( m, n )
if m == 0: return( n + 1 )
if m == 0: return( n + 1 )
if n == 0: return( ackermann( m - 1, 1 ) )
if n == 0: return( ackermann( m - 1, 1 ) )
Line 3,392: Line 3,392:
end
end
>
>
end</lang>
end</syntaxhighlight>
The above will output the below.
The above will output the below.
Formating options to make this pretty are available,
Formating options to make this pretty are available,
Line 3,404: Line 3,404:


=={{header|FALSE}}==
=={{header|FALSE}}==
<lang false>[$$[%
<syntaxhighlight lang=false>[$$[%
\$$[%
\$$[%
1-\$@@a;! { i j -> A(i-1, A(i, j-1)) }
1-\$@@a;! { i j -> A(i-1, A(i, j-1)) }
Line 3,415: Line 3,415:
]?]a: { j i }
]?]a: { j i }


3 3 a;! . { 61 }</lang>
3 3 a;! . { 61 }</syntaxhighlight>


=={{header|Fantom}}==
=={{header|Fantom}}==
<lang fantom>class Main
<syntaxhighlight lang=fantom>class Main
{
{
// assuming m,n are positive
// assuming m,n are positive
Line 3,441: Line 3,441:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,476: Line 3,476:
=={{header|FBSL}}==
=={{header|FBSL}}==
Mixed-language solution using pure FBSL, Dynamic Assembler, and Dynamic C layers of FBSL v3.5 concurrently. '''The following is a single script'''; the breaks are caused by switching between RC's different syntax highlighting schemes:
Mixed-language solution using pure FBSL, Dynamic Assembler, and Dynamic C layers of FBSL v3.5 concurrently. '''The following is a single script'''; the breaks are caused by switching between RC's different syntax highlighting schemes:
<lang qbasic>#APPTYPE CONSOLE
<syntaxhighlight lang=qbasic>#APPTYPE CONSOLE


TestAckermann()
TestAckermann()
Line 3,497: Line 3,497:
END FUNCTION
END FUNCTION


DYNC AckermannC(m AS INTEGER, n AS INTEGER) AS INTEGER</lang><lang C>
DYNC AckermannC(m AS INTEGER, n AS INTEGER) AS INTEGER</syntaxhighlight><syntaxhighlight lang=C>
int Ackermann(int m, int n)
int Ackermann(int m, int n)
{
{
Line 3,508: Line 3,508:
{
{
return Ackermann(m, n);
return Ackermann(m, n);
}</lang><lang qbasic>
}</syntaxhighlight><syntaxhighlight lang=qbasic>
END DYNC
END DYNC


DYNASM AckermannA(m AS INTEGER, n AS INTEGER) AS INTEGER</lang><lang asm>
DYNASM AckermannA(m AS INTEGER, n AS INTEGER) AS INTEGER</syntaxhighlight><syntaxhighlight lang=asm>
ENTER 0, 0
ENTER 0, 0
INVOKE Ackermann, m, n
INVOKE Ackermann, m, n
Line 3,547: Line 3,547:
LEAVE
LEAVE
RET 8
RET 8
</lang><lang qbasic>END DYNASM</lang>
</syntaxhighlight><syntaxhighlight lang=qbasic>END DYNASM</syntaxhighlight>


{{out}}
{{out}}
Line 3,560: Line 3,560:


=={{header|Fermat}}==
=={{header|Fermat}}==
<lang fermat>Func A(m,n) = if m = 0 then n+1 else if n = 0 then A(m-1,1) else A(m-1,A(m,n-1)) fi fi.;
<syntaxhighlight lang=fermat>Func A(m,n) = if m = 0 then n+1 else if n = 0 then A(m-1,1) else A(m-1,A(m,n-1)) fi fi.;
A(3,8)</lang>
A(3,8)</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,568: Line 3,568:


=={{header|Forth}}==
=={{header|Forth}}==
<lang forth>: acker ( m n -- u )
<syntaxhighlight lang=forth>: acker ( m n -- u )
over 0= IF nip 1+ EXIT THEN
over 0= IF nip 1+ EXIT THEN
swap 1- swap ( m-1 n -- )
swap 1- swap ( m-1 n -- )
dup 0= IF 1+ recurse EXIT THEN
dup 0= IF 1+ recurse EXIT THEN
1- over 1+ swap recurse recurse ;</lang>
1- over 1+ swap recurse recurse ;</syntaxhighlight>
{{out|Example of use}}
{{out|Example of use}}
<pre>FORTH> 0 0 acker . 1 ok
<pre>FORTH> 0 0 acker . 1 ok
FORTH> 3 4 acker . 125 ok</pre>
FORTH> 3 4 acker . 125 ok</pre>
An optimized version:
An optimized version:
<lang forth>: ackermann ( m n -- u )
<syntaxhighlight lang=forth>: ackermann ( m n -- u )
over ( case statement)
over ( case statement)
0 over = if drop nip 1+ else
0 over = if drop nip 1+ else
Line 3,590: Line 3,590:
then
then
then then then then
then then then then
;</lang>
;</syntaxhighlight>


=={{header|Fortran}}==
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
{{works with|Fortran|90 and later}}
<lang fortran>PROGRAM EXAMPLE
<syntaxhighlight lang=fortran>PROGRAM EXAMPLE
IMPLICIT NONE
IMPLICIT NONE
Line 3,620: Line 3,620:
END FUNCTION Ackermann
END FUNCTION Ackermann


END PROGRAM EXAMPLE</lang>
END PROGRAM EXAMPLE</syntaxhighlight>


=={{header|Free Pascal}}==
=={{header|Free Pascal}}==
Line 3,626: Line 3,626:


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>' version 28-10-2016
<syntaxhighlight lang=freebasic>' version 28-10-2016
' compile with: fbc -s console
' compile with: fbc -s console
' to do A(4, 2) the stack size needs to be increased
' to do A(4, 2) the stack size needs to be increased
Line 3,666: Line 3,666:
Print : Print "hit any key to end program"
Print : Print "hit any key to end program"
Sleep
Sleep
End</lang>
End</syntaxhighlight>
{{out}}
{{out}}
<pre> 0 1 2 3 4 5 6 7 8 9 10 11
<pre> 0 1 2 3 4 5 6 7 8 9 10 11
Line 3,675: Line 3,675:


=={{header|FunL}}==
=={{header|FunL}}==
<lang funl>def
<syntaxhighlight lang=funl>def
ackermann( 0, n ) = n + 1
ackermann( 0, n ) = n + 1
ackermann( m, 0 ) = ackermann( m - 1, 1 )
ackermann( m, 0 ) = ackermann( m - 1, 1 )
Line 3,681: Line 3,681:


for m <- 0..3, n <- 0..4
for m <- 0..3, n <- 0..4
printf( 'Ackermann( %d, %d ) = %d\n', m, n, ackermann(m, n) )</lang>
printf( 'Ackermann( %d, %d ) = %d\n', m, n, ackermann(m, n) )</syntaxhighlight>


{{out}}
{{out}}
Line 3,710: Line 3,710:
=={{header|Futhark}}==
=={{header|Futhark}}==


<lang Futhark>
<syntaxhighlight lang=Futhark>
fun ackermann(m: int, n: int): int =
fun ackermann(m: int, n: int): int =
if m == 0 then n + 1
if m == 0 then n + 1
else if n == 0 then ackermann(m-1, 1)
else if n == 0 then ackermann(m-1, 1)
else ackermann(m - 1, ackermann(m, n-1))
else ackermann(m - 1, ackermann(m, n-1))
</syntaxhighlight>
</lang>


=={{header|FutureBasic}}==
=={{header|FutureBasic}}==
<lang futurebasic>
<syntaxhighlight lang=futurebasic>
include "NSLog.incl"
include "NSLog.incl"


Line 3,745: Line 3,745:


HandleEvents
HandleEvents
</syntaxhighlight>
</lang>


Output:
Output:
Line 3,800: Line 3,800:


=={{header|Gambas}}==
=={{header|Gambas}}==
<lang gambas>Public Function Ackermann(m As Float, n As Float) As Float
<syntaxhighlight lang=gambas>Public Function Ackermann(m As Float, n As Float) As Float
If m = 0 Then
If m = 0 Then
Return n + 1
Return n + 1
Line 3,817: Line 3,817:
Next
Next
Next
Next
End</lang>
End</syntaxhighlight>


=={{header|GAP}}==
=={{header|GAP}}==
<lang gap>ack := function(m, n)
<syntaxhighlight lang=gap>ack := function(m, n)
if m = 0 then
if m = 0 then
return n + 1;
return n + 1;
Line 3,830: Line 3,830:
return fail;
return fail;
fi;
fi;
end;</lang>
end;</syntaxhighlight>


=={{header|Genyris}}==
=={{header|Genyris}}==
<lang genyris>def A (m n)
<syntaxhighlight lang=genyris>def A (m n)
cond
cond
(equal? m 0)
(equal? m 0)
Line 3,841: Line 3,841:
else
else
A (- m 1)
A (- m 1)
A m (- n 1)</lang>
A m (- n 1)</syntaxhighlight>


=={{header|GML}}==
=={{header|GML}}==
Define a script resource named ackermann and paste this code inside:
Define a script resource named ackermann and paste this code inside:
<lang GML>///ackermann(m,n)
<syntaxhighlight lang=GML>///ackermann(m,n)
var m, n;
var m, n;
m = argument0;
m = argument0;
Line 3,860: Line 3,860:
{
{
return (ackermann(m-1,ackermann(m,n-1,2),1))
return (ackermann(m-1,ackermann(m,n-1,2),1))
}</lang>
}</syntaxhighlight>


=={{header|gnuplot}}==
=={{header|gnuplot}}==
<lang gnuplot>A (m, n) = m == 0 ? n + 1 : n == 0 ? A (m - 1, 1) : A (m - 1, A (m, n - 1))
<syntaxhighlight lang=gnuplot>A (m, n) = m == 0 ? n + 1 : n == 0 ? A (m - 1, 1) : A (m - 1, A (m, n - 1))
print A (0, 4)
print A (0, 4)
print A (1, 4)
print A (1, 4)
print A (2, 4)
print A (2, 4)
print A (3, 4)</lang>
print A (3, 4)</syntaxhighlight>
{{out}}
{{out}}
5
5
Line 3,876: Line 3,876:
=={{header|Go}}==
=={{header|Go}}==
===Classic version===
===Classic version===
<lang go>func Ackermann(m, n uint) uint {
<syntaxhighlight lang=go>func Ackermann(m, n uint) uint {
switch 0 {
switch 0 {
case m:
case m:
Line 3,884: Line 3,884:
}
}
return Ackermann(m - 1, Ackermann(m, n - 1))
return Ackermann(m - 1, Ackermann(m, n - 1))
}</lang>
}</syntaxhighlight>
===Expanded version===
===Expanded version===
<lang go>func Ackermann2(m, n uint) uint {
<syntaxhighlight lang=go>func Ackermann2(m, n uint) uint {
switch {
switch {
case m == 0:
case m == 0:
Line 3,900: Line 3,900:
}
}
return Ackermann2(m - 1, Ackermann2(m, n - 1))
return Ackermann2(m - 1, Ackermann2(m, n - 1))
}</lang>
}</syntaxhighlight>
===Expanded version with arbitrary precision===
===Expanded version with arbitrary precision===
<lang go>package main
<syntaxhighlight lang=go>package main


import (
import (
Line 3,991: Line 3,991:
)
)
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 4,005: Line 4,005:


=={{header|Golfscript}}==
=={{header|Golfscript}}==
<lang golfscript>{
<syntaxhighlight lang=golfscript>{
:_n; :_m;
:_n; :_m;
_m 0= {_n 1+}
_m 0= {_n 1+}
Line 4,012: Line 4,012:
if}
if}
if
if
}:ack;</lang>
}:ack;</syntaxhighlight>


=={{header|Groovy}}==
=={{header|Groovy}}==
<lang groovy>def ack ( m, n ) {
<syntaxhighlight lang=groovy>def ack ( m, n ) {
assert m >= 0 && n >= 0 : 'both arguments must be non-negative'
assert m >= 0 && n >= 0 : 'both arguments must be non-negative'
m == 0 ? n + 1 : n == 0 ? ack(m-1, 1) : ack(m-1, ack(m, n-1))
m == 0 ? n + 1 : n == 0 ? ack(m-1, 1) : ack(m-1, ack(m, n-1))
}</lang>
}</syntaxhighlight>
Test program:
Test program:
<lang groovy>def ackMatrix = (0..3).collect { m -> (0..8).collect { n -> ack(m, n) } }
<syntaxhighlight lang=groovy>def ackMatrix = (0..3).collect { m -> (0..8).collect { n -> ack(m, n) } }
ackMatrix.each { it.each { elt -> printf "%7d", elt }; println() }</lang>
ackMatrix.each { it.each { elt -> printf "%7d", elt }; println() }</syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7 8 9
<pre> 1 2 3 4 5 6 7 8 9
Line 4,030: Line 4,030:


=={{header|Hare}}==
=={{header|Hare}}==
<lang hare>use fmt;
<syntaxhighlight lang=hare>use fmt;


fn ackermann(m: u64, n: u64) u64 = {
fn ackermann(m: u64, n: u64) u64 = {
Line 4,049: Line 4,049:
fmt::println()!;
fmt::println()!;
};
};
};</lang>
};</syntaxhighlight>


=={{header|Haskell}}==
=={{header|Haskell}}==
<lang haskell>ack :: Int -> Int -> Int
<syntaxhighlight lang=haskell>ack :: Int -> Int -> Int
ack 0 n = succ n
ack 0 n = succ n
ack m 0 = ack (pred m) 1
ack m 0 = ack (pred m) 1
Line 4,058: Line 4,058:


main :: IO ()
main :: IO ()
main = mapM_ print $ uncurry ack <$> [(0, 0), (3, 4)]</lang>
main = mapM_ print $ uncurry ack <$> [(0, 0), (3, 4)]</syntaxhighlight>
{{out}}
{{out}}
<pre>1
<pre>1
Line 4,064: Line 4,064:


Generating a list instead:
Generating a list instead:
<lang haskell>import Data.List (mapAccumL)
<syntaxhighlight lang=haskell>import Data.List (mapAccumL)


-- everything here are [Int] or [[Int]], which would overflow
-- everything here are [Int] or [[Int]], which would overflow
Line 4,073: Line 4,073:
f a b = (aa, head aa) where aa = drop b a
f a b = (aa, head aa) where aa = drop b a


main = mapM_ print $ map (\n -> take (6 - n) $ ackermann !! n) [0..5]</lang>
main = mapM_ print $ map (\n -> take (6 - n) $ ackermann !! n) [0..5]</syntaxhighlight>


=={{header|Haxe}}==
=={{header|Haxe}}==
<lang haxe>class RosettaDemo
<syntaxhighlight lang=haxe>class RosettaDemo
{
{
static public function main()
static public function main()
Line 4,095: Line 4,095:
return ackermann(m-1, ackermann(m, n-1));
return ackermann(m-1, ackermann(m, n-1));
}
}
}</lang>
}</syntaxhighlight>


=={{header|Hoon}}==
=={{header|Hoon}}==
<lang Hoon>
<syntaxhighlight lang=Hoon>
|= [m=@ud n=@ud]
|= [m=@ud n=@ud]
?: =(m 0)
?: =(m 0)
Line 4,105: Line 4,105:
$(n 1, m (dec m))
$(n 1, m (dec m))
$(m (dec m), n $(n (dec n)))
$(m (dec m), n $(n (dec n)))
</syntaxhighlight>
</lang>


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==
Line 4,111: Line 4,111:
Taken from the public domain Icon Programming Library's [http://www.cs.arizona.edu/icon/library/procs/memrfncs.htm acker in memrfncs],
Taken from the public domain Icon Programming Library's [http://www.cs.arizona.edu/icon/library/procs/memrfncs.htm acker in memrfncs],
written by Ralph E. Griswold.
written by Ralph E. Griswold.
<lang Icon>procedure acker(i, j)
<syntaxhighlight lang=Icon>procedure acker(i, j)
static memory
static memory


Line 4,135: Line 4,135:
write()
write()
}
}
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 4,144: Line 4,144:


=={{header|Idris}}==
=={{header|Idris}}==
<lang idris>A : Nat -> Nat -> Nat
<syntaxhighlight lang=idris>A : Nat -> Nat -> Nat
A Z n = S n
A Z n = S n
A (S m) Z = A m (S Z)
A (S m) Z = A m (S Z)
A (S m) (S n) = A m (A (S m) n)</lang>
A (S m) (S n) = A m (A (S m) n)</syntaxhighlight>


=={{header|Ioke}}==
=={{header|Ioke}}==
{{trans|Clojure}}
{{trans|Clojure}}
<lang ioke>ackermann = method(m,n,
<syntaxhighlight lang=ioke>ackermann = method(m,n,
cond(
cond(
m zero?, n succ,
m zero?, n succ,
n zero?, ackermann(m pred, 1),
n zero?, ackermann(m pred, 1),
ackermann(m pred, ackermann(m, n pred)))
ackermann(m pred, ackermann(m, n pred)))
)</lang>
)</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
As posted at the [[j:Essays/Ackermann%27s%20Function|J wiki]]
As posted at the [[j:Essays/Ackermann%27s%20Function|J wiki]]
<lang j>ack=: c1`c1`c2`c3 @. (#.@,&*) M.
<syntaxhighlight lang=j>ack=: c1`c1`c2`c3 @. (#.@,&*) M.
c1=: >:@] NB. if 0=x, 1+y
c1=: >:@] NB. if 0=x, 1+y
c2=: <:@[ ack 1: NB. if 0=y, (x-1) ack 1
c2=: <:@[ ack 1: NB. if 0=y, (x-1) ack 1
c3=: <:@[ ack [ ack <:@] NB. else, (x-1) ack x ack y-1</lang>
c3=: <:@[ ack [ ack <:@] NB. else, (x-1) ack x ack y-1</syntaxhighlight>
{{out|Example use}}
{{out|Example use}}
<lang j> 0 ack 3
<syntaxhighlight lang=j> 0 ack 3
4
4
1 ack 3
1 ack 3
Line 4,172: Line 4,172:
9
9
3 ack 3
3 ack 3
61</lang>
61</syntaxhighlight>
J's stack was too small for me to compute <tt>4 ack 1</tt>.
J's stack was too small for me to compute <tt>4 ack 1</tt>.
===Alternative Primitive Recursive Version===
===Alternative Primitive Recursive Version===
Line 4,178: Line 4,178:


The Ackermann function derived in this fashion is primitive recursive. This is possible because in J (as in some other languages) functions, or representations of them, are first-class values.
The Ackermann function derived in this fashion is primitive recursive. This is possible because in J (as in some other languages) functions, or representations of them, are first-class values.
<lang j> Ack=. 3 -~ [ ({&(2 4$'>: 2x&+') ::(,&'&1'&'2x&*'@:(-&2))"0@:[ 128!:2 ]) 3 + ]</lang>
<syntaxhighlight lang=j> Ack=. 3 -~ [ ({&(2 4$'>: 2x&+') ::(,&'&1'&'2x&*'@:(-&2))"0@:[ 128!:2 ]) 3 + ]</syntaxhighlight>
{{out|Example use}}
{{out|Example use}}
<lang j> 0 1 2 3 Ack 0 1 2 3 4 5 6 7
<syntaxhighlight lang=j> 0 1 2 3 Ack 0 1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
Line 4,195: Line 4,195:
5 Ack 0
5 Ack 0
65533
65533
</syntaxhighlight>
</lang>


A structured derivation of Ack follows:
A structured derivation of Ack follows:


<lang j> o=. @: NB. Composition of verbs (functions)
<syntaxhighlight lang=j> o=. @: NB. Composition of verbs (functions)
x=. o[ NB. Composing the left noun (argument)
x=. o[ NB. Composing the left noun (argument)
Line 4,225: Line 4,225:
(Ack=. (3 -~ [ Buck 3 + ])f.) NB. Ackermann function-level code
(Ack=. (3 -~ [ Buck 3 + ])f.) NB. Ackermann function-level code
3 -~ [ ({&(2 4$'>: 2x&+') ::(,&'&1'&'2x&*'@:(-&2))"0@:[ 128!:2 ]) 3 + ]</lang>
3 -~ [ ({&(2 4$'>: 2x&+') ::(,&'&1'&'2x&*'@:(-&2))"0@:[ 128!:2 ]) 3 + ]</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
[[Category:Arbitrary precision]]
[[Category:Arbitrary precision]]
<lang java>import java.math.BigInteger;
<syntaxhighlight lang=java>import java.math.BigInteger;


public static BigInteger ack(BigInteger m, BigInteger n) {
public static BigInteger ack(BigInteger m, BigInteger n) {
Line 4,236: Line 4,236:
: ack(m.subtract(BigInteger.ONE),
: ack(m.subtract(BigInteger.ONE),
n.equals(BigInteger.ZERO) ? BigInteger.ONE : ack(m, n.subtract(BigInteger.ONE)));
n.equals(BigInteger.ZERO) ? BigInteger.ONE : ack(m, n.subtract(BigInteger.ONE)));
}</lang>
}</syntaxhighlight>


{{works with|Java|8+}}
{{works with|Java|8+}}
<lang java5>@FunctionalInterface
<syntaxhighlight lang=java5>@FunctionalInterface
public interface FunctionalField<FIELD extends Enum<?>> {
public interface FunctionalField<FIELD extends Enum<?>> {
public Object untypedField(FIELD field);
public Object untypedField(FIELD field);
Line 4,247: Line 4,247:
return (VALUE) untypedField(field);
return (VALUE) untypedField(field);
}
}
}</lang>
}</syntaxhighlight>
<lang java5>import java.util.function.BiFunction;
<syntaxhighlight lang=java5>import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Predicate;
Line 4,293: Line 4,293:
}
}
}
}
}</lang>
}</syntaxhighlight>
<lang java5>import java.math.BigInteger;
<syntaxhighlight lang=java5>import java.math.BigInteger;
import java.util.Stack;
import java.util.Stack;
import java.util.function.BinaryOperator;
import java.util.function.BinaryOperator;
Line 4,438: Line 4,438:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{Iterative version}}
{{Iterative version}}
<lang java5>/*
<syntaxhighlight lang=java5>/*
* Source https://stackoverflow.com/a/51092690/5520417
* Source https://stackoverflow.com/a/51092690/5520417
*/
*/
Line 4,830: Line 4,830:
}
}


</syntaxhighlight>
</lang>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
===ES5===
===ES5===
<lang javascript>function ack(m, n) {
<syntaxhighlight lang=javascript>function ack(m, n) {
return m === 0 ? n + 1 : ack(m - 1, n === 0 ? 1 : ack(m, n - 1));
return m === 0 ? n + 1 : ack(m - 1, n === 0 ? 1 : ack(m, n - 1));
}</lang>
}</syntaxhighlight>
===Eliminating Tail Calls===
===Eliminating Tail Calls===
<lang javascript>function ack(M,N) {
<syntaxhighlight lang=javascript>function ack(M,N) {
for (; M > 0; M--) {
for (; M > 0; M--) {
N = N === 0 ? 1 : ack(M,N-1);
N = N === 0 ? 1 : ack(M,N-1);
}
}
return N+1;
return N+1;
}</lang>
}</syntaxhighlight>
===Iterative, With Explicit Stack===
===Iterative, With Explicit Stack===
<lang javascript>function stackermann(M, N) {
<syntaxhighlight lang=javascript>function stackermann(M, N) {
const stack = [];
const stack = [];
for (;;) {
for (;;) {
Line 4,864: Line 4,864:
}
}
}
}
}</lang>
}</syntaxhighlight>
===Stackless Iterative===
===Stackless Iterative===
<lang javascript>#!/usr/bin/env nodejs
<syntaxhighlight lang=javascript>#!/usr/bin/env nodejs
function ack(M, N){
function ack(M, N){
const next = new Float64Array(M + 1);
const next = new Float64Array(M + 1);
Line 4,891: Line 4,891:
}
}
var args = process.argv;
var args = process.argv;
console.log(ack(parseInt(args[2]), parseInt(args[3])));</lang>
console.log(ack(parseInt(args[2]), parseInt(args[3])));</syntaxhighlight>


{{out}}
{{out}}
Line 4,901: Line 4,901:


===ES6===
===ES6===
<lang javascript>(() => {
<syntaxhighlight lang=javascript>(() => {
'use strict';
'use strict';


Line 4,938: Line 4,938:
// MAIN ---
// MAIN ---
return main();
return main();
})();</lang>
})();</syntaxhighlight>
{{Out}}
{{Out}}
<pre>[4,5,9,61]</pre>
<pre>[4,5,9,61]</pre>
Line 4,944: Line 4,944:
=={{header|Joy}}==
=={{header|Joy}}==
From [http://www.latrobe.edu.au/phimvt/joy/jp-nestrec.html here]
From [http://www.latrobe.edu.au/phimvt/joy/jp-nestrec.html here]
<lang joy>DEFINE ack == [ [ [pop null] popd succ ]
<syntaxhighlight lang=joy>DEFINE ack == [ [ [pop null] popd succ ]
[ [null] pop pred 1 ack ]
[ [null] pop pred 1 ack ]
[ [dup pred swap] dip pred ack ack ] ]
[ [dup pred swap] dip pred ack ack ] ]
cond.</lang>
cond.</syntaxhighlight>
another using a combinator
another using a combinator
<lang joy>DEFINE ack == [ [ [pop null] [popd succ] ]
<syntaxhighlight lang=joy>DEFINE ack == [ [ [pop null] [popd succ] ]
[ [null] [pop pred 1] [] ]
[ [null] [pop pred 1] [] ]
[ [[dup pred swap] dip pred] [] [] ] ]
[ [[dup pred swap] dip pred] [] [] ] ]
condnestrec.</lang>
condnestrec.</syntaxhighlight>
Whenever there are two definitions with the same name, the last one is the one that is used, when invoked.
Whenever there are two definitions with the same name, the last one is the one that is used, when invoked.


Line 4,958: Line 4,958:
{{ works with|jq|1.4}}
{{ works with|jq|1.4}}
===Without Memoization===
===Without Memoization===
<lang jq># input: [m,n]
<syntaxhighlight lang=jq># input: [m,n]
def ack:
def ack:
.[0] as $m | .[1] as $n
.[0] as $m | .[1] as $n
Line 4,964: Line 4,964:
elif $n == 0 then [$m-1, 1] | ack
elif $n == 0 then [$m-1, 1] | ack
else [$m-1, ([$m, $n-1 ] | ack)] | ack
else [$m-1, ([$m, $n-1 ] | ack)] | ack
end ;</lang>
end ;</syntaxhighlight>
'''Example:'''
'''Example:'''
<lang jq>range(0;5) as $i
<syntaxhighlight lang=jq>range(0;5) as $i
| range(0; if $i > 3 then 1 else 6 end) as $j
| range(0; if $i > 3 then 1 else 6 end) as $j
| "A(\($i),\($j)) = \( [$i,$j] | ack )"</lang>
| "A(\($i),\($j)) = \( [$i,$j] | ack )"</syntaxhighlight>
{{out}}
{{out}}
<lang sh># jq -n -r -f ackermann.jq
<syntaxhighlight lang=sh># jq -n -r -f ackermann.jq
A(0,0) = 1
A(0,0) = 1
A(0,1) = 2
A(0,1) = 2
Line 4,995: Line 4,995:
A(3,4) = 125
A(3,4) = 125
A(3,5) = 253
A(3,5) = 253
A(4,0) = 13</lang>
A(4,0) = 13</syntaxhighlight>
===With Memoization and Optimization===
===With Memoization and Optimization===
<lang jq># input: [m,n, cache]
<syntaxhighlight lang=jq># input: [m,n, cache]
# output [value, updatedCache]
# output [value, updatedCache]
def ack:
def ack:
Line 5,026: Line 5,026:


def A(m;n): [m,n,{}] | ack | .[0];
def A(m;n): [m,n,{}] | ack | .[0];
</syntaxhighlight>
</lang>
'''Example:'''<lang jq>A(4,1)</lang>
'''Example:'''<syntaxhighlight lang=jq>A(4,1)</syntaxhighlight>
{{out}}
{{out}}
<lang sh>65533</lang>
<syntaxhighlight lang=sh>65533</syntaxhighlight>


=={{header|Jsish}}==
=={{header|Jsish}}==
From javascript entry.
From javascript entry.
<lang javascript>/* Ackermann function, in Jsish */
<syntaxhighlight lang=javascript>/* Ackermann function, in Jsish */


function ack(m, n) {
function ack(m, n) {
Line 5,058: Line 5,058:
ack(3,5) ==> 253
ack(3,5) ==> 253
=!EXPECTEND!=
=!EXPECTEND!=
*/</lang>
*/</syntaxhighlight>


{{out}}
{{out}}
Line 5,070: Line 5,070:


=={{header|Julia}}==
=={{header|Julia}}==
<lang julia>function ack(m,n)
<syntaxhighlight lang=julia>function ack(m,n)
if m == 0
if m == 0
return n + 1
return n + 1
Line 5,078: Line 5,078:
return ack(m-1,ack(m,n-1))
return ack(m-1,ack(m,n-1))
end
end
end</lang>
end</syntaxhighlight>


'''One-liner:'''
'''One-liner:'''
<lang julia>ack2(m::Integer, n::Integer) = m == 0 ? n + 1 : n == 0 ? ack2(m - 1, 1) : ack2(m - 1, ack2(m, n - 1))</lang>
<syntaxhighlight lang=julia>ack2(m::Integer, n::Integer) = m == 0 ? n + 1 : n == 0 ? ack2(m - 1, 1) : ack2(m - 1, ack2(m, n - 1))</syntaxhighlight>


'''Using memoization''', [https://github.com/simonster/Memoize.jl source]:
'''Using memoization''', [https://github.com/simonster/Memoize.jl source]:
<lang julia>using Memoize
<syntaxhighlight lang=julia>using Memoize
@memoize ack3(m::Integer, n::Integer) = m == 0 ? n + 1 : n == 0 ? ack3(m - 1, 1) : ack3(m - 1, ack3(m, n - 1))</lang>
@memoize ack3(m::Integer, n::Integer) = m == 0 ? n + 1 : n == 0 ? ack3(m - 1, 1) : ack3(m - 1, ack3(m, n - 1))</syntaxhighlight>


'''Benchmarking''':
'''Benchmarking''':
Line 5,098: Line 5,098:
=={{header|K}}==
=={{header|K}}==
See [https://github.com/kevinlawler/kona/wiki the K wiki]
See [https://github.com/kevinlawler/kona/wiki the K wiki]
<lang k>ack:{:[0=x;y+1;0=y;_f[x-1;1];_f[x-1;_f[x;y-1]]]}
<syntaxhighlight lang=k>ack:{:[0=x;y+1;0=y;_f[x-1;1];_f[x-1;_f[x;y-1]]]}
ack[2;2]</lang>
ack[2;2]</syntaxhighlight>


=={{header|Kdf9 Usercode}}==
=={{header|Kdf9 Usercode}}==
<lang kdf9 usercode>V6; W0;
<syntaxhighlight lang=kdf9 usercode>V6; W0;
YS26000;
YS26000;
RESTART; J999; J999;
RESTART; J999; J999;
Line 5,151: Line 5,151:
J99; (tail recursion for A[m-1, A[m, n-1]]);
J99; (tail recursion for A[m-1, A[m, n-1]]);


FINISH;</lang>
FINISH;</syntaxhighlight>


=={{header|Klingphix}}==
=={{header|Klingphix}}==
Line 5,170: Line 5,170:
msec print
msec print


" " input</lang>
" " input</syntaxhighlight>


=={{header|Klong}}==
=={{header|Klong}}==
<syntaxhighlight lang=k>
<lang k>
ack::{:[0=x;y+1:|0=y;.f(x-1;1);.f(x-1;.f(x;y-1))]}
ack::{:[0=x;y+1:|0=y;.f(x-1;1);.f(x-1;.f(x;y-1))]}
ack(2;2)</lang>
ack(2;2)</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
<lang scala>
<syntaxhighlight lang=scala>
tailrec fun A(m: Long, n: Long): Long {
tailrec fun A(m: Long, n: Long): Long {
require(m >= 0L) { "m must not be negative" }
require(m >= 0L) { "m must not be negative" }
Line 5,204: Line 5,204:
.forEach(::println)
.forEach(::println)
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 5,215: Line 5,215:


=={{header|Lambdatalk}}==
=={{header|Lambdatalk}}==
<lang Scheme>
<syntaxhighlight lang=Scheme>
{def ack
{def ack
{lambda {:m :n}
{lambda {:m :n}
Line 5,238: Line 5,238:
{ack 4 1} // too much
{ack 4 1} // too much
-> ???
-> ???
</syntaxhighlight>
</lang>


=={{header|Lasso}}==
=={{header|Lasso}}==
<lang lasso>#!/usr/bin/lasso9
<syntaxhighlight lang=lasso>#!/usr/bin/lasso9
define ackermann(m::integer, n::integer) => {
define ackermann(m::integer, n::integer) => {
Line 5,256: Line 5,256:
y in generateSeries(0,8,2)
y in generateSeries(0,8,2)
do stdoutnl(#x+', '#y+': ' + ackermann(#x, #y))
do stdoutnl(#x+', '#y+': ' + ackermann(#x, #y))
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>1, 0: 2
<pre>1, 0: 2
Line 5,275: Line 5,275:


=={{header|LFE}}==
=={{header|LFE}}==
<lang lisp>(defun ackermann
<syntaxhighlight lang=lisp>(defun ackermann
((0 n) (+ n 1))
((0 n) (+ n 1))
((m 0) (ackermann (- m 1) 1))
((m 0) (ackermann (- m 1) 1))
((m n) (ackermann (- m 1) (ackermann m (- n 1)))))</lang>
((m n) (ackermann (- m 1) (ackermann m (- n 1)))))</syntaxhighlight>


=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
<lang lb>Print Ackermann(1, 2)
<syntaxhighlight lang=lb>Print Ackermann(1, 2)


Function Ackermann(m, n)
Function Ackermann(m, n)
Line 5,294: Line 5,294:
Ackermann = Ackermann((m - 1), Ackermann(m, (n - 1)))
Ackermann = Ackermann((m - 1), Ackermann(m, (n - 1)))
End Select
End Select
End Function</lang>
End Function</syntaxhighlight>


=={{header|LiveCode}}==
=={{header|LiveCode}}==
<lang LiveCode>function ackermann m,n
<syntaxhighlight lang=LiveCode>function ackermann m,n
switch
switch
Case m = 0
Case m = 0
Line 5,306: Line 5,306:
return ackermann((m - 1), ackermann(m, (n - 1)))
return ackermann((m - 1), ackermann(m, (n - 1)))
end switch
end switch
end ackermann</lang>
end ackermann</syntaxhighlight>


=={{header|Logo}}==
=={{header|Logo}}==
<lang logo>to ack :i :j
<syntaxhighlight lang=logo>to ack :i :j
if :i = 0 [output :j+1]
if :i = 0 [output :j+1]
if :j = 0 [output ack :i-1 1]
if :j = 0 [output ack :i-1 1]
output ack :i-1 ack :i :j-1
output ack :i-1 ack :i :j-1
end</lang>
end</syntaxhighlight>


=={{header|Logtalk}}==
=={{header|Logtalk}}==
<lang logtalk>ack(0, N, V) :-
<syntaxhighlight lang=logtalk>ack(0, N, V) :-
!,
!,
V is N + 1.
V is N + 1.
Line 5,327: Line 5,327:
N2 is N - 1,
N2 is N - 1,
ack(M, N2, V2),
ack(M, N2, V2),
ack(M2, V2, V).</lang>
ack(M2, V2, V).</syntaxhighlight>


=={{header|LOLCODE}}==
=={{header|LOLCODE}}==
{{trans|C}}
{{trans|C}}
<lang LOLCODE>HAI 1.3
<syntaxhighlight lang=LOLCODE>HAI 1.3


HOW IZ I ackermann YR m AN YR n
HOW IZ I ackermann YR m AN YR n
Line 5,352: Line 5,352:
IM OUTTA YR outer
IM OUTTA YR outer


KTHXBYE</lang>
KTHXBYE</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>function ack(M,N)
<syntaxhighlight lang=lua>function ack(M,N)
if M == 0 then return N + 1 end
if M == 0 then return N + 1 end
if N == 0 then return ack(M-1,1) end
if N == 0 then return ack(M-1,1) end
return ack(M-1,ack(M, N-1))
return ack(M-1,ack(M, N-1))
end</lang>
end</syntaxhighlight>


=== Stackless iterative solution with multiple precision, fast ===
=== Stackless iterative solution with multiple precision, fast ===
<lang lua>
<syntaxhighlight lang=lua>
#!/usr/bin/env luajit
#!/usr/bin/env luajit
local gmp = require 'gmp' ('libgmp')
local gmp = require 'gmp' ('libgmp')
Line 5,401: Line 5,401:
printf("%Zd\n", ack(tonumber(arg[1]), arg[2] and tonumber(arg[2]) or 0))
printf("%Zd\n", ack(tonumber(arg[1]), arg[2] and tonumber(arg[2]) or 0))
end
end
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 5,417: Line 5,417:


=={{header|Lucid}}==
=={{header|Lucid}}==
<lang lucid>ack(m,n)
<syntaxhighlight lang=lucid>ack(m,n)
where
where
ack(m,n) = if m eq 0 then n+1
ack(m,n) = if m eq 0 then n+1
Line 5,423: Line 5,423:
else ack(m-1, ack(m, n-1)) fi
else ack(m-1, ack(m, n-1)) fi
fi;
fi;
end</lang>
end</syntaxhighlight>


=={{header|Luck}}==
=={{header|Luck}}==
<lang luck>function ackermann(m: int, n: int): int = (
<syntaxhighlight lang=luck>function ackermann(m: int, n: int): int = (
if m==0 then n+1
if m==0 then n+1
else if n==0 then ackermann(m-1,1)
else if n==0 then ackermann(m-1,1)
else ackermann(m-1,ackermann(m,n-1))
else ackermann(m-1,ackermann(m,n-1))
)</lang>
)</syntaxhighlight>


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
<lang M2000 Interpreter>
<syntaxhighlight lang=M2000 Interpreter>
Module Checkit {
Module Checkit {
Def ackermann(m,n) =If(m=0-> n+1, If(n=0-> ackermann(m-1,1), ackermann(m-1,ackermann(m,n-1))))
Def ackermann(m,n) =If(m=0-> n+1, If(n=0-> ackermann(m-1,1), ackermann(m-1,ackermann(m,n-1))))
Line 5,448: Line 5,448:
}
}
Checkit
Checkit
</syntaxhighlight>
</lang>


=={{header|M4}}==
=={{header|M4}}==
<lang M4>define(`ack',`ifelse($1,0,`incr($2)',`ifelse($2,0,`ack(decr($1),1)',`ack(decr($1),ack($1,decr($2)))')')')dnl
<syntaxhighlight lang=M4>define(`ack',`ifelse($1,0,`incr($2)',`ifelse($2,0,`ack(decr($1),1)',`ack(decr($1),ack($1,decr($2)))')')')dnl
ack(3,3)</lang>
ack(3,3)</syntaxhighlight>
{{out}}
{{out}}
<pre>61 </pre>
<pre>61 </pre>
Line 5,469: Line 5,469:
the arguments to the recursive function via the stack or the global variables. The following program demonstrates this.
the arguments to the recursive function via the stack or the global variables. The following program demonstrates this.


<lang MAD> NORMAL MODE IS INTEGER
<syntaxhighlight lang=MAD> NORMAL MODE IS INTEGER
DIMENSION LIST(3000)
DIMENSION LIST(3000)
SET LIST TO LIST
SET LIST TO LIST
Line 5,507: Line 5,507:
VECTOR VALUES ACKF = $4HACK(,I1,1H,,I1,4H) = ,I4*$
VECTOR VALUES ACKF = $4HACK(,I1,1H,,I1,4H) = ,I4*$
END OF PROGRAM
END OF PROGRAM
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 5,553: Line 5,553:
=={{header|Maple}}==
=={{header|Maple}}==
Strictly by the definition given above, we can code this as follows.
Strictly by the definition given above, we can code this as follows.
<lang Maple>
<syntaxhighlight lang=Maple>
Ackermann := proc( m :: nonnegint, n :: nonnegint )
Ackermann := proc( m :: nonnegint, n :: nonnegint )
option remember; # optional automatic memoization
option remember; # optional automatic memoization
Line 5,564: Line 5,564:
end if
end if
end proc:
end proc:
</syntaxhighlight>
</lang>
In Maple, the keyword <lang Maple>thisproc</lang> refers to the currently executing procedure (closure) and is used when writing recursive procedures. (You could also use the name of the procedure, Ackermann in this case, but then a concurrently executing task or thread could re-assign that name while the recursive procedure is executing, resulting in an incorrect result.)
In Maple, the keyword <syntaxhighlight lang=Maple>thisproc</syntaxhighlight> refers to the currently executing procedure (closure) and is used when writing recursive procedures. (You could also use the name of the procedure, Ackermann in this case, but then a concurrently executing task or thread could re-assign that name while the recursive procedure is executing, resulting in an incorrect result.)


To make this faster, you can use known expansions for small values of <math>m</math>. (See [[wp:Ackermann_function|Wikipedia:Ackermann function]])
To make this faster, you can use known expansions for small values of <math>m</math>. (See [[wp:Ackermann_function|Wikipedia:Ackermann function]])
<lang Maple>
<syntaxhighlight lang=Maple>
Ackermann := proc( m :: nonnegint, n :: nonnegint )
Ackermann := proc( m :: nonnegint, n :: nonnegint )
option remember; # optional automatic memoization
option remember; # optional automatic memoization
Line 5,585: Line 5,585:
end if
end if
end proc:
end proc:
</syntaxhighlight>
</lang>
This makes it possible to compute <code>Ackermann( 4, 1 )</code> and <code>Ackermann( 4, 2 )</code> essentially instantly, though <code>Ackermann( 4, 3 )</code> is still out of reach.
This makes it possible to compute <code>Ackermann( 4, 1 )</code> and <code>Ackermann( 4, 2 )</code> essentially instantly, though <code>Ackermann( 4, 3 )</code> is still out of reach.


To compute Ackermann( 1, i ) for i from 1 to 10 use
To compute Ackermann( 1, i ) for i from 1 to 10 use
<lang Maple>
<syntaxhighlight lang=Maple>
> map2( Ackermann, 1, [seq]( 1 .. 10 ) );
> map2( Ackermann, 1, [seq]( 1 .. 10 ) );
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
</syntaxhighlight>
</lang>
To get the first 10 values for m = 2 use
To get the first 10 values for m = 2 use
<lang Maple>
<syntaxhighlight lang=Maple>
> map2( Ackermann, 2, [seq]( 1 .. 10 ) );
> map2( Ackermann, 2, [seq]( 1 .. 10 ) );
[5, 7, 9, 11, 13, 15, 17, 19, 21, 23]
[5, 7, 9, 11, 13, 15, 17, 19, 21, 23]
</syntaxhighlight>
</lang>
For Ackermann( 4, 2 ) we get a very long number with
For Ackermann( 4, 2 ) we get a very long number with
<lang Maple>
<syntaxhighlight lang=Maple>
> length( Ackermann( 4, 2 ) );
> length( Ackermann( 4, 2 ) );
19729
19729
</syntaxhighlight>
</lang>
digits.
digits.


Line 5,610: Line 5,610:
This particular version of Ackermann's function was created in Mathcad Prime Express 7.0, a free version of Mathcad Prime 7.0 with restrictions (such as no programming or symbolics). All Prime Express numbers are complex. There is a recursion depth limit of about 4,500.
This particular version of Ackermann's function was created in Mathcad Prime Express 7.0, a free version of Mathcad Prime 7.0 with restrictions (such as no programming or symbolics). All Prime Express numbers are complex. There is a recursion depth limit of about 4,500.


<lang Mathcad>A(m,n):=if(m=0,n+1,if(n=0,A(m-1,1),A(m-1,A(m,n-1))))</lang>
<syntaxhighlight lang=Mathcad>A(m,n):=if(m=0,n+1,if(n=0,A(m-1,1),A(m-1,A(m,n-1))))</syntaxhighlight>


The worksheet also contains an explictly-calculated version of Ackermann's function that calls the tetration function n<sub>a</sub>.
The worksheet also contains an explictly-calculated version of Ackermann's function that calls the tetration function n<sub>a</sub>.
Line 5,625: Line 5,625:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Two possible implementations would be:
Two possible implementations would be:
<lang Mathematica>$RecursionLimit=Infinity
<syntaxhighlight lang=Mathematica>$RecursionLimit=Infinity
Ackermann1[m_,n_]:=
Ackermann1[m_,n_]:=
If[m==0,n+1,
If[m==0,n+1,
Line 5,635: Line 5,635:
Ackermann2[0,n_]:=n+1;
Ackermann2[0,n_]:=n+1;
Ackermann2[m_,0]:=Ackermann1[m-1,1];
Ackermann2[m_,0]:=Ackermann1[m-1,1];
Ackermann2[m_,n_]:=Ackermann1[m-1,Ackermann1[m,n-1]]</lang>
Ackermann2[m_,n_]:=Ackermann1[m-1,Ackermann1[m,n-1]]</syntaxhighlight>
Note that the second implementation is quite a bit faster, as doing 'if' comparisons is slower than the built-in pattern matching algorithms.
Note that the second implementation is quite a bit faster, as doing 'if' comparisons is slower than the built-in pattern matching algorithms.
Examples:
Examples:
<lang Mathematica>Flatten[#,1]&@Table[{"Ackermann2["<>ToString[i]<>","<>ToString[j]<>"] =",Ackermann2[i,j]},{i,3},{j,8}]//Grid</lang>
<syntaxhighlight lang=Mathematica>Flatten[#,1]&@Table[{"Ackermann2["<>ToString[i]<>","<>ToString[j]<>"] =",Ackermann2[i,j]},{i,3},{j,8}]//Grid</syntaxhighlight>
gives back:
gives back:
<lang Mathematica>Ackermann2[1,1] = 3
<syntaxhighlight lang=Mathematica>Ackermann2[1,1] = 3
Ackermann2[1,2] = 4
Ackermann2[1,2] = 4
Ackermann2[1,3] = 5
Ackermann2[1,3] = 5
Line 5,663: Line 5,663:
Ackermann2[3,6] = 509
Ackermann2[3,6] = 509
Ackermann2[3,7] = 1021
Ackermann2[3,7] = 1021
Ackermann2[3,8] = 2045</lang>
Ackermann2[3,8] = 2045</syntaxhighlight>
If we would like to calculate Ackermann[4,1] or Ackermann[4,2] we have to optimize a little bit:
If we would like to calculate Ackermann[4,1] or Ackermann[4,2] we have to optimize a little bit:
<lang Mathematica>Clear[Ackermann3]
<syntaxhighlight lang=Mathematica>Clear[Ackermann3]
$RecursionLimit=Infinity;
$RecursionLimit=Infinity;
Ackermann3[0,n_]:=n+1;
Ackermann3[0,n_]:=n+1;
Line 5,672: Line 5,672:
Ackermann3[3,n_]:=5+8 (2^n-1);
Ackermann3[3,n_]:=5+8 (2^n-1);
Ackermann3[m_,0]:=Ackermann3[m-1,1];
Ackermann3[m_,0]:=Ackermann3[m-1,1];
Ackermann3[m_,n_]:=Ackermann3[m-1,Ackermann3[m,n-1]]</lang>
Ackermann3[m_,n_]:=Ackermann3[m-1,Ackermann3[m,n-1]]</syntaxhighlight>
Now computing Ackermann[4,1] and Ackermann[4,2] can be done quickly (<0.01 sec):
Now computing Ackermann[4,1] and Ackermann[4,2] can be done quickly (<0.01 sec):
Examples 2:
Examples 2:
<lang Mathematica>Ackermann3[4, 1]
<syntaxhighlight lang=Mathematica>Ackermann3[4, 1]
Ackermann3[4, 2]</lang>
Ackermann3[4, 2]</syntaxhighlight>
gives back:
gives back:
<div style="width:full;overflow:scroll"><lang Mathematica>65533
<div style="width:full;overflow:scroll"><syntaxhighlight lang=Mathematica>65533
2003529930406846464979072351560255750447825475569751419265016973710894059556311453089506130880........699146577530041384717124577965048175856395072895337539755822087777506072339445587895905719156733</lang></div>
2003529930406846464979072351560255750447825475569751419265016973710894059556311453089506130880........699146577530041384717124577965048175856395072895337539755822087777506072339445587895905719156733</syntaxhighlight></div>
Ackermann[4,2] has 19729 digits, several thousands of digits omitted in the result above for obvious reasons. Ackermann[5,0] can be computed also quite fast, and is equal to 65533.
Ackermann[4,2] has 19729 digits, several thousands of digits omitted in the result above for obvious reasons. Ackermann[5,0] can be computed also quite fast, and is equal to 65533.
Summarizing Ackermann[0,n_], Ackermann[1,n_], Ackermann[2,n_], and Ackermann[3,n_] can all be calculated for n>>1000. Ackermann[4,0], Ackermann[4,1], Ackermann[4,2] and Ackermann[5,0] are only possible now. Maybe in the future we can calculate higher Ackermann numbers efficiently and fast. Although showing the results will always be a problem.
Summarizing Ackermann[0,n_], Ackermann[1,n_], Ackermann[2,n_], and Ackermann[3,n_] can all be calculated for n>>1000. Ackermann[4,0], Ackermann[4,1], Ackermann[4,2] and Ackermann[5,0] are only possible now. Maybe in the future we can calculate higher Ackermann numbers efficiently and fast. Although showing the results will always be a problem.


=={{header|MATLAB}}==
=={{header|MATLAB}}==
<lang MATLAB>function A = ackermannFunction(m,n)
<syntaxhighlight lang=MATLAB>function A = ackermannFunction(m,n)
if m == 0
if m == 0
A = n+1;
A = n+1;
Line 5,692: Line 5,692:
A = ackermannFunction( m-1,ackermannFunction(m,n-1) );
A = ackermannFunction( m-1,ackermannFunction(m,n-1) );
end
end
end</lang>
end</syntaxhighlight>


=={{header|Maxima}}==
=={{header|Maxima}}==
<lang maxima>ackermann(m, n) := if integerp(m) and integerp(n) then ackermann[m, n] else 'ackermann(m, n)$
<syntaxhighlight lang=maxima>ackermann(m, n) := if integerp(m) and integerp(n) then ackermann[m, n] else 'ackermann(m, n)$


ackermann[m, n] := if m = 0 then n + 1
ackermann[m, n] := if m = 0 then n + 1
Line 5,709: Line 5,709:
ackermann(4, n) - (tetration(2, n + 3) - 3);
ackermann(4, n) - (tetration(2, n + 3) - 3);
subst(n = 2, %);
subst(n = 2, %);
ev(%, nouns);</lang>
ev(%, nouns);</syntaxhighlight>


=={{header|MAXScript}}==
=={{header|MAXScript}}==
Use with caution. Will cause a stack overflow for m > 3.
Use with caution. Will cause a stack overflow for m > 3.
<lang maxscript>fn ackermann m n =
<syntaxhighlight lang=maxscript>fn ackermann m n =
(
(
if m == 0 then
if m == 0 then
Line 5,727: Line 5,727:
ackermann (m-1) (ackermann m (n-1))
ackermann (m-1) (ackermann m (n-1))
)
)
)</lang>
)</syntaxhighlight>


=={{header|Mercury}}==
=={{header|Mercury}}==
This is the Ackermann function with some (obvious) elements elided. The <code>ack/3</code> predicate is implemented in terms of the <code>ack/2</code> function. The <code>ack/2</code> function is implemented in terms of the <code>ack/3</code> predicate. This makes the code both more concise and easier to follow than would otherwise be the case. The <code>integer</code> type is used instead of <code>int</code> because the problem statement stipulates the use of bignum integers if possible.
This is the Ackermann function with some (obvious) elements elided. The <code>ack/3</code> predicate is implemented in terms of the <code>ack/2</code> function. The <code>ack/2</code> function is implemented in terms of the <code>ack/3</code> predicate. This makes the code both more concise and easier to follow than would otherwise be the case. The <code>integer</code> type is used instead of <code>int</code> because the problem statement stipulates the use of bignum integers if possible.
<lang mercury>:- func ack(integer, integer) = integer.
<syntaxhighlight lang=mercury>:- func ack(integer, integer) = integer.
ack(M, N) = R :- ack(M, N, R).
ack(M, N) = R :- ack(M, N, R).


Line 5,740: Line 5,740:
; M = integer(0) -> R = N + integer(1)
; M = integer(0) -> R = N + integer(1)
; N = integer(0) -> ack(M - integer(1), integer(1), R)
; N = integer(0) -> ack(M - integer(1), integer(1), R)
; ack(M - integer(1), ack(M, N - integer(1)), R) ).</lang>
; ack(M - integer(1), ack(M, N - integer(1)), R) ).</syntaxhighlight>


=={{header|min}}==
=={{header|min}}==
{{works with|min|0.19.3}}
{{works with|min|0.19.3}}
<lang min>(
<syntaxhighlight lang=min>(
:n :m
:n :m
(
(
Line 5,751: Line 5,751:
((true) (m 1 - m n 1 - ackermann ackermann))
((true) (m 1 - m n 1 - ackermann ackermann))
) case
) case
) :ackermann</lang>
) :ackermann</syntaxhighlight>


=={{header|MiniScript}}==
=={{header|MiniScript}}==


<lang MiniScript>ackermann = function(m, n)
<syntaxhighlight lang=MiniScript>ackermann = function(m, n)
if m == 0 then return n+1
if m == 0 then return n+1
if n == 0 then return ackermann(m - 1, 1)
if n == 0 then return ackermann(m - 1, 1)
Line 5,765: Line 5,765:
print "(" + m + ", " + n + "): " + ackermann(m, n)
print "(" + m + ", " + n + "): " + ackermann(m, n)
end for
end for
end for</lang>
end for</syntaxhighlight>


=={{header|МК-61/52}}==
=={{header|МК-61/52}}==
Line 5,771: Line 5,771:
1 + В/О ИП1 x=0 24 ИП0 1 П1 -
1 + В/О ИП1 x=0 24 ИП0 1 П1 -
П0 ПП 06 В/О ИП0 П2 ИП1 1 - П1
П0 ПП 06 В/О ИП0 П2 ИП1 1 - П1
ПП 06 П1 ИП2 1 - П0 ПП 06 В/О</lang>
ПП 06 П1 ИП2 1 - П0 ПП 06 В/О</syntaxhighlight>


=={{header|ML/I}}==
=={{header|ML/I}}==
ML/I loves recursion, but runs out of its default amount of storage with larger numbers than those tested here!
ML/I loves recursion, but runs out of its default amount of storage with larger numbers than those tested here!
===Program===
===Program===
<lang ML/I>MCSKIP "WITH" NL
<syntaxhighlight lang=ML/I>MCSKIP "WITH" NL
"" Ackermann function
"" Ackermann function
"" Will overflow when it reaches implementation-defined signed integer limit
"" Will overflow when it reaches implementation-defined signed integer limit
Line 5,808: Line 5,808:
a(3,1) => ACK(3,1)
a(3,1) => ACK(3,1)
a(3,2) => ACK(3,2)
a(3,2) => ACK(3,2)
a(4,0) => ACK(4,0)</lang>
a(4,0) => ACK(4,0)</syntaxhighlight>
{{out}}
{{out}}
<lang ML/I>a(0,0) => 1
<syntaxhighlight lang=ML/I>a(0,0) => 1
a(0,1) => 2
a(0,1) => 2
a(0,2) => 3
a(0,2) => 3
Line 5,828: Line 5,828:
a(3,1) => 13
a(3,1) => 13
a(3,2) => 29
a(3,2) => 29
a(4,0) => 13</lang>
a(4,0) => 13</syntaxhighlight>


=={{header|mLite}}==
=={{header|mLite}}==
<lang haskell>fun ackermann( 0, n ) = n + 1
<syntaxhighlight lang=haskell>fun ackermann( 0, n ) = n + 1
| ( m, 0 ) = ackermann( m - 1, 1 )
| ( m, 0 ) = ackermann( m - 1, 1 )
| ( m, n ) = ackermann( m - 1, ackermann(m, n - 1) )</lang>
| ( m, n ) = ackermann( m - 1, ackermann(m, n - 1) )</syntaxhighlight>
Test code providing tuples from (0,0) to (3,8)
Test code providing tuples from (0,0) to (3,8)
<lang haskell>fun jota x = map (fn x = x-1) ` iota x
<syntaxhighlight lang=haskell>fun jota x = map (fn x = x-1) ` iota x


fun test_tuples (x, y) = append_map (fn a = map (fn b = (b, a)) ` jota x) ` jota y
fun test_tuples (x, y) = append_map (fn a = map (fn b = (b, a)) ` jota x) ` jota y


map ackermann (test_tuples(4,9))</lang>
map ackermann (test_tuples(4,9))</syntaxhighlight>
Result
Result
<pre>[1, 2, 3, 5, 2, 3, 5, 13, 3, 4, 7, 29, 4, 5, 9, 61, 5, 6, 11, 125, 6, 7, 13, 253, 7, 8, 15, 509, 8, 9, 17, 1021, 9, 10, 19, 2045]</pre>
<pre>[1, 2, 3, 5, 2, 3, 5, 13, 3, 4, 7, 29, 4, 5, 9, 61, 5, 6, 11, 125, 6, 7, 13, 253, 7, 8, 15, 509, 8, 9, 17, 1021, 9, 10, 19, 2045]</pre>


=={{header|Modula-2}}==
=={{header|Modula-2}}==
<lang modula2>MODULE ackerman;
<syntaxhighlight lang=modula2>MODULE ackerman;


IMPORT ASCII, NumConv, InOut;
IMPORT ASCII, NumConv, InOut;
Line 5,876: Line 5,876:
END;
END;
InOut.WriteLn
InOut.WriteLn
END ackerman.</lang>
END ackerman.</syntaxhighlight>
{{out}}<pre>jan@Beryllium:~/modula/rosetta$ ackerman
{{out}}<pre>jan@Beryllium:~/modula/rosetta$ ackerman
1 2 3 4 5 6 7
1 2 3 4 5 6 7
Line 5,885: Line 5,885:
=={{header|Modula-3}}==
=={{header|Modula-3}}==
The type CARDINAL is defined in Modula-3 as [0..LAST(INTEGER)], in other words, it can hold all positive integers.
The type CARDINAL is defined in Modula-3 as [0..LAST(INTEGER)], in other words, it can hold all positive integers.
<lang modula3>MODULE Ack EXPORTS Main;
<syntaxhighlight lang=modula3>MODULE Ack EXPORTS Main;


FROM IO IMPORT Put;
FROM IO IMPORT Put;
Line 5,908: Line 5,908:
Put("\n");
Put("\n");
END;
END;
END Ack.</lang>
END Ack.</syntaxhighlight>
{{out}}
{{out}}
<pre>1 2 3 4 5 6 7
<pre>1 2 3 4 5 6 7
Line 5,916: Line 5,916:


=={{header|MUMPS}}==
=={{header|MUMPS}}==
<lang MUMPS>Ackermann(m,n) ;
<syntaxhighlight lang=MUMPS>Ackermann(m,n) ;
If m=0 Quit n+1
If m=0 Quit n+1
If m>0,n=0 Quit $$Ackermann(m-1,1)
If m>0,n=0 Quit $$Ackermann(m-1,1)
Line 5,924: Line 5,924:
Write $$Ackermann(1,8) ; 10
Write $$Ackermann(1,8) ; 10
Write $$Ackermann(2,8) ; 19
Write $$Ackermann(2,8) ; 19
Write $$Ackermann(3,5) ; 253</lang>
Write $$Ackermann(3,5) ; 253</syntaxhighlight>


=={{header|Neko}}==
=={{header|Neko}}==
<lang ActionScript>/**
<syntaxhighlight lang=ActionScript>/**
Ackermann recursion, in Neko
Ackermann recursion, in Neko
Tectonics:
Tectonics:
Line 5,949: Line 5,949:
$print("Ackermann(", arg1, ",", arg2, "): ", ack(arg1,arg2), "\n")
$print("Ackermann(", arg1, ",", arg2, "): ", ack(arg1,arg2), "\n")
catch problem
catch problem
$print("Ackermann(", arg1, ",", arg2, "): ", problem, "\n")</lang>
$print("Ackermann(", arg1, ",", arg2, "): ", problem, "\n")</syntaxhighlight>


{{out}}
{{out}}
Line 5,972: Line 5,972:
=={{header|Nemerle}}==
=={{header|Nemerle}}==
In Nemerle, we can state the Ackermann function as a lambda. By using pattern-matching, our definition strongly resembles the mathematical notation.
In Nemerle, we can state the Ackermann function as a lambda. By using pattern-matching, our definition strongly resembles the mathematical notation.
<lang Nemerle>
<syntaxhighlight lang=Nemerle>
using System;
using System;
using Nemerle.IO;
using Nemerle.IO;
Line 5,993: Line 5,993:
}
}
}
}
</syntaxhighlight>
</lang>
A terser version using implicit <code>match</code> (which doesn't use the alias <code>A</code> internally):
A terser version using implicit <code>match</code> (which doesn't use the alias <code>A</code> internally):
<lang Nemerle>
<syntaxhighlight lang=Nemerle>
def ackermann(m, n) {
def ackermann(m, n) {
| (0, n) => n + 1
| (0, n) => n + 1
Line 6,002: Line 6,002:
| _ => throw Exception("invalid inputs");
| _ => throw Exception("invalid inputs");
}
}
</syntaxhighlight>
</lang>
Or, if we were set on using the <code>A</code> notation, we could do this:
Or, if we were set on using the <code>A</code> notation, we could do this:
<lang Nemerle>
<syntaxhighlight lang=Nemerle>
def ackermann = {
def ackermann = {
def A(m, n) {
def A(m, n) {
Line 6,014: Line 6,014:
A
A
}
}
</syntaxhighlight>
</lang>


=={{header|NetRexx}}==
=={{header|NetRexx}}==
<lang NetRexx>/* NetRexx */
<syntaxhighlight lang=NetRexx>/* NetRexx */
options replace format comments java crossref symbols binary
options replace format comments java crossref symbols binary


Line 6,041: Line 6,041:
end
end
return rval
return rval
</syntaxhighlight>
</lang>


=={{header|NewLISP}}==
=={{header|NewLISP}}==
<lang newlisp>
<syntaxhighlight lang=newlisp>
#! /usr/local/bin/newlisp
#! /usr/local/bin/newlisp


Line 6,051: Line 6,051:
((zero? n) (ackermann (dec m) 1))
((zero? n) (ackermann (dec m) 1))
(true (ackermann (- m 1) (ackermann m (dec n))))))
(true (ackermann (- m 1) (ackermann m (dec n))))))
</syntaxhighlight>
</lang>


<pre>
<pre>
Line 6,060: Line 6,060:


=={{header|Nim}}==
=={{header|Nim}}==
<lang nim>from strutils import parseInt
<syntaxhighlight lang=nim>from strutils import parseInt


proc ackermann(m, n: int64): int64 =
proc ackermann(m, n: int64): int64 =
Line 6,085: Line 6,085:
let second = getNumber()
let second = getNumber()
echo "Result: ", $ackermann(first, second)
echo "Result: ", $ackermann(first, second)
</syntaxhighlight>
</lang>


=={{header|Nit}}==
=={{header|Nit}}==
Line 6,091: Line 6,091:
Source: [https://github.com/nitlang/nit/blob/master/examples/rosettacode/ackermann_function.nit the official Nit’s repository].
Source: [https://github.com/nitlang/nit/blob/master/examples/rosettacode/ackermann_function.nit the official Nit’s repository].


<lang nit># Task: Ackermann function
<syntaxhighlight lang=nit># Task: Ackermann function
#
#
# A simple straightforward recursive implementation.
# A simple straightforward recursive implementation.
Line 6,108: Line 6,108:
end
end
print ""
print ""
end</lang>
end</syntaxhighlight>


Output:
Output:
Line 6,147: Line 6,147:


=={{header|Oberon-2}}==
=={{header|Oberon-2}}==
<lang oberon2>MODULE ackerman;
<syntaxhighlight lang=oberon2>MODULE ackerman;


IMPORT Out;
IMPORT Out;
Line 6,172: Line 6,172:
END;
END;
Out.Ln
Out.Ln
END ackerman.</lang>
END ackerman.</syntaxhighlight>


=={{header|Objeck}}==
=={{header|Objeck}}==
{{trans|C#|C sharp}}
{{trans|C#|C sharp}}
<lang objeck>class Ackermann {
<syntaxhighlight lang=objeck>class Ackermann {
function : Main(args : String[]) ~ Nil {
function : Main(args : String[]) ~ Nil {
for(m := 0; m <= 3; ++m;) {
for(m := 0; m <= 3; ++m;) {
Line 6,205: Line 6,205:
return -1;
return -1;
}
}
}</lang>
}</syntaxhighlight>
<pre>
<pre>
Ackermann(0, 0) = 1
Ackermann(0, 0) = 1
Line 6,230: Line 6,230:


=={{header|OCaml}}==
=={{header|OCaml}}==
<lang ocaml>let rec a m n =
<syntaxhighlight lang=ocaml>let rec a m n =
if m=0 then (n+1) else
if m=0 then (n+1) else
if n=0 then (a (m-1) 1) else
if n=0 then (a (m-1) 1) else
(a (m-1) (a m (n-1)))</lang>
(a (m-1) (a m (n-1)))</syntaxhighlight>
or:
or:
<lang ocaml>let rec a = function
<syntaxhighlight lang=ocaml>let rec a = function
| 0, n -> (n+1)
| 0, n -> (n+1)
| m, 0 -> a(m-1, 1)
| m, 0 -> a(m-1, 1)
| m, n -> a(m-1, a(m, n-1))</lang>
| m, n -> a(m-1, a(m, n-1))</syntaxhighlight>
with memoization using an hash-table:
with memoization using an hash-table:
<lang ocaml>let h = Hashtbl.create 4001
<syntaxhighlight lang=ocaml>let h = Hashtbl.create 4001


let a m n =
let a m n =
Line 6,247: Line 6,247:
let res = a (m, n) in
let res = a (m, n) in
Hashtbl.add h (m, n) res;
Hashtbl.add h (m, n) res;
(res)</lang>
(res)</syntaxhighlight>
taking advantage of the memoization we start calling small values of '''m''' and '''n''' in order to reduce the recursion call stack:
taking advantage of the memoization we start calling small values of '''m''' and '''n''' in order to reduce the recursion call stack:
<lang ocaml>let a m n =
<syntaxhighlight lang=ocaml>let a m n =
for _m = 0 to m do
for _m = 0 to m do
for _n = 0 to n do
for _n = 0 to n do
Line 6,255: Line 6,255:
done;
done;
done;
done;
(a m n)</lang>
(a m n)</syntaxhighlight>
=== Arbitrary precision ===
=== Arbitrary precision ===
With arbitrary-precision integers ([http://caml.inria.fr/pub/docs/manual-ocaml/libref/Big_int.html Big_int module]):
With arbitrary-precision integers ([http://caml.inria.fr/pub/docs/manual-ocaml/libref/Big_int.html Big_int module]):
<lang ocaml>open Big_int
<syntaxhighlight lang=ocaml>open Big_int
let one = unit_big_int
let one = unit_big_int
let zero = zero_big_int
let zero = zero_big_int
Line 6,268: Line 6,268:
if eq m zero then (succ n) else
if eq m zero then (succ n) else
if eq n zero then (a (pred m) one) else
if eq n zero then (a (pred m) one) else
(a (pred m) (a m (pred n)))</lang>
(a (pred m) (a m (pred n)))</syntaxhighlight>
compile with:
compile with:
ocamlopt -o acker nums.cmxa acker.ml
ocamlopt -o acker nums.cmxa acker.ml
=== Tail-Recursive ===
=== Tail-Recursive ===
Here is a [[:Category:Recursion|tail-recursive]] version:
Here is a [[:Category:Recursion|tail-recursive]] version:
<lang ocaml>let rec find_option h v =
<syntaxhighlight lang=ocaml>let rec find_option h v =
try Some(Hashtbl.find h v)
try Some(Hashtbl.find h v)
with Not_found -> None
with Not_found -> None
Line 6,302: Line 6,302:
a bounds caller todo m (n-1)
a bounds caller todo m (n-1)


let a = a (Hashtbl.create 42 (* arbitrary *) ) [] [] ;;</lang>
let a = a (Hashtbl.create 42 (* arbitrary *) ) [] [] ;;</syntaxhighlight>
This one uses the arbitrary precision, the tail-recursion, and the optimisation explain on the Wikipedia page about <tt>(m,n) = (3,_)</tt>.
This one uses the arbitrary precision, the tail-recursion, and the optimisation explain on the Wikipedia page about <tt>(m,n) = (3,_)</tt>.
<lang ocaml>open Big_int
<syntaxhighlight lang=ocaml>open Big_int
let one = unit_big_int
let one = unit_big_int
let zero = zero_big_int
let zero = zero_big_int
Line 6,382: Line 6,382:
(string_of_big_int n)
(string_of_big_int n)
(string_of_big_int r);
(string_of_big_int r);
;;</lang>
;;</syntaxhighlight>


=={{header|Octave}}==
=={{header|Octave}}==
<lang octave>function r = ackerman(m, n)
<syntaxhighlight lang=octave>function r = ackerman(m, n)
if ( m == 0 )
if ( m == 0 )
r = n + 1;
r = n + 1;
Line 6,397: Line 6,397:
for i = 0:3
for i = 0:3
disp(ackerman(i, 4));
disp(ackerman(i, 4));
endfor</lang>
endfor</syntaxhighlight>


=={{header|Oforth}}==
=={{header|Oforth}}==
<lang Oforth>: A( m n -- p )
<syntaxhighlight lang=Oforth>: A( m n -- p )
m ifZero: [ n 1+ return ]
m ifZero: [ n 1+ return ]
m 1- n ifZero: [ 1 ] else: [ A( m, n 1- ) ] A
m 1- n ifZero: [ 1 ] else: [ A( m, n 1- ) ] A
;</lang>
;</syntaxhighlight>


=={{header|Ol}}==
=={{header|Ol}}==
<lang scheme>
<syntaxhighlight lang=scheme>
; simple version
; simple version
(define (A m n)
(define (A m n)
Line 6,444: Line 6,444:


(print "extended version (A 3 6): " (A+ 3 6))
(print "extended version (A 3 6): " (A+ 3 6))
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 6,452: Line 6,452:


=={{header|OOC}}==
=={{header|OOC}}==
<lang ooc>
<syntaxhighlight lang=ooc>
ack: func (m: Int, n: Int) -> Int {
ack: func (m: Int, n: Int) -> Int {
if (m == 0) {
if (m == 0) {
Line 6,470: Line 6,470:
}
}
}
}
</syntaxhighlight>
</lang>


=={{header|ooRexx}}==
=={{header|ooRexx}}==
<lang ooRexx>
<syntaxhighlight lang=ooRexx>
loop m = 0 to 3
loop m = 0 to 3
loop n = 0 to 6
loop n = 0 to 6
Line 6,487: Line 6,487:
else if n = 0 then return ackermann(m - 1, 1)
else if n = 0 then return ackermann(m - 1, 1)
else return ackermann(m - 1, ackermann(m, n - 1))
else return ackermann(m - 1, ackermann(m, n - 1))
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 6,521: Line 6,521:


=={{header|Order}}==
=={{header|Order}}==
<lang c>#include <order/interpreter.h>
<syntaxhighlight lang=c>#include <order/interpreter.h>


#define ORDER_PP_DEF_8ack ORDER_PP_FN( \
#define ORDER_PP_DEF_8ack ORDER_PP_FN( \
Line 6,529: Line 6,529:
(8else, 8ack(8dec(8X), 8ack(8X, 8dec(8Y)))))))
(8else, 8ack(8dec(8X), 8ack(8X, 8dec(8Y)))))))


ORDER_PP(8to_lit(8ack(3, 4))) // 125</lang>
ORDER_PP(8to_lit(8ack(3, 4))) // 125</syntaxhighlight>


=={{header|Oz}}==
=={{header|Oz}}==
Oz has arbitrary precision integers.
Oz has arbitrary precision integers.
<lang oz>declare
<syntaxhighlight lang=oz>declare


fun {Ack M N}
fun {Ack M N}
Line 6,544: Line 6,544:
in
in


{Show {Ack 3 7}}</lang>
{Show {Ack 3 7}}</syntaxhighlight>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
Naive implementation.
Naive implementation.
<lang parigp>A(m,n)={
<syntaxhighlight lang=parigp>A(m,n)={
if(m,
if(m,
if(n,
if(n,
Line 6,558: Line 6,558:
n+1
n+1
)
)
};</lang>
};</syntaxhighlight>


=={{header|Pascal}}==
=={{header|Pascal}}==
<lang pascal>Program Ackerman;
<syntaxhighlight lang=pascal>Program Ackerman;


function ackermann(m, n: Integer) : Integer;
function ackermann(m, n: Integer) : Integer;
Line 6,580: Line 6,580:
for m := 0 to 3 do
for m := 0 to 3 do
WriteLn('A(', m, ',', n, ') = ', ackermann(m,n));
WriteLn('A(', m, ',', n, ') = ', ackermann(m,n));
end.</lang>
end.</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
We memoize calls to ''A'' to make ''A''(2, ''n'') and ''A''(3, ''n'') feasible for larger values of ''n''.
We memoize calls to ''A'' to make ''A''(2, ''n'') and ''A''(3, ''n'') feasible for larger values of ''n''.
<lang perl>{
<syntaxhighlight lang=perl>{
my @memo;
my @memo;
sub A {
sub A {
Line 6,596: Line 6,596:
);
);
}
}
}</lang>
}</syntaxhighlight>


An implementation using the conditional statements 'if', 'elsif' and 'else':
An implementation using the conditional statements 'if', 'elsif' and 'else':
<lang perl>sub A {
<syntaxhighlight lang=perl>sub A {
my ($m, $n) = @_;
my ($m, $n) = @_;
if ($m == 0) { $n + 1 }
if ($m == 0) { $n + 1 }
elsif ($n == 0) { A($m - 1, 1) }
elsif ($n == 0) { A($m - 1, 1) }
else { A($m - 1, A($m, $n - 1)) }
else { A($m - 1, A($m, $n - 1)) }
}</lang>
}</syntaxhighlight>


An implementation using ternary chaining:
An implementation using ternary chaining:
<lang perl>sub A {
<syntaxhighlight lang=perl>sub A {
my ($m, $n) = @_;
my ($m, $n) = @_;
$m == 0 ? $n + 1 :
$m == 0 ? $n + 1 :
$n == 0 ? A($m - 1, 1) :
$n == 0 ? A($m - 1, 1) :
A($m - 1, A($m, $n - 1))
A($m - 1, A($m, $n - 1))
}</lang>
}</syntaxhighlight>


Adding memoization and extra terms:
Adding memoization and extra terms:
<lang perl>use Memoize; memoize('ack2');
<syntaxhighlight lang=perl>use Memoize; memoize('ack2');
use bigint try=>"GMP";
use bigint try=>"GMP";


Line 6,629: Line 6,629:
print "ack2(3,4) is ", ack2(3,4), "\n";
print "ack2(3,4) is ", ack2(3,4), "\n";
print "ack2(4,1) is ", ack2(4,1), "\n";
print "ack2(4,1) is ", ack2(4,1), "\n";
print "ack2(4,2) has ", length(ack2(4,2)), " digits\n";</lang>
print "ack2(4,2) has ", length(ack2(4,2)), " digits\n";</syntaxhighlight>
{{output}}
{{output}}
<pre>ack2(3,4) is 125
<pre>ack2(3,4) is 125
Line 6,637: Line 6,637:
An optimized version, which uses <code>@_</code> as a stack,
An optimized version, which uses <code>@_</code> as a stack,
instead of recursion. Very fast.
instead of recursion. Very fast.
<lang Perl>use strict;
<syntaxhighlight lang=Perl>use strict;
use warnings;
use warnings;
use Math::BigInt;
use Math::BigInt;
Line 6,672: Line 6,672:
print "ack(4,2) has ", length(ack(4,2)), " digits\n";
print "ack(4,2) has ", length(ack(4,2)), " digits\n";


</syntaxhighlight>
</lang>


=={{header|Phix}}==
=={{header|Phix}}==
=== native version ===
=== native version ===
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">ack</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">ack</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
Line 6,711: Line 6,711:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 6,727: Line 6,727:
{{trans|Go}}
{{trans|Go}}
{{libheader|Phix/mpfr}}
{{libheader|Phix/mpfr}}
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Ackermann.exw</span>
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Ackermann.exw</span>
<span style="color: #008080;">include</span> <span style="color: #7060A8;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">include</span> <span style="color: #7060A8;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 6,810: Line 6,810:
<span style="color: #000000;">ackermann_tests</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">ackermann_tests</span><span style="color: #0000FF;">()</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 6,830: Line 6,830:


=={{header|Phixmonti}}==
=={{header|Phixmonti}}==
<lang Phixmonti>def ack
<syntaxhighlight lang=Phixmonti>def ack
var n var m
var n var m
Line 6,844: Line 6,844:
enddef
enddef


3 6 ack print nl</lang>
3 6 ack print nl</syntaxhighlight>


=={{header|PHP}}==
=={{header|PHP}}==
<lang php>function ackermann( $m , $n )
<syntaxhighlight lang=php>function ackermann( $m , $n )
{
{
if ( $m==0 )
if ( $m==0 )
Line 6,861: Line 6,861:


echo ackermann( 3, 4 );
echo ackermann( 3, 4 );
// prints 125</lang>
// prints 125</syntaxhighlight>


=={{header|Picat}}==
=={{header|Picat}}==
<lang Picat>go =>
<syntaxhighlight lang=Picat>go =>
foreach(M in 0..3)
foreach(M in 0..3)
println([m=M,[a(M,N) : N in 0..16]])
println([m=M,[a(M,N) : N in 0..16]])
Line 6,902: Line 6,902:
a2(3,N) = 8*(2**N - 1) + 5.
a2(3,N) = 8*(2**N - 1) + 5.
a2(M,N) = cond(N == 0,a2(M-1, 1), a2(M-1, a2(M, N-1))).
a2(M,N) = cond(N == 0,a2(M-1, 1), a2(M-1, a2(M, N-1))).
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 6,923: Line 6,923:


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(de ack (X Y)
<syntaxhighlight lang=PicoLisp>(de ack (X Y)
(cond
(cond
((=0 X) (inc Y))
((=0 X) (inc Y))
((=0 Y) (ack (dec X) 1))
((=0 Y) (ack (dec X) 1))
(T (ack (dec X) (ack X (dec Y)))) ) )</lang>
(T (ack (dec X) (ack X (dec Y)))) ) )</syntaxhighlight>


=={{header|Piet}}==
=={{header|Piet}}==
Line 7,296: Line 7,296:


=={{header|Pike}}==
=={{header|Pike}}==
<lang pike>int main(){
<syntaxhighlight lang=pike>int main(){
write(ackermann(3,4) + "\n");
write(ackermann(3,4) + "\n");
}
}
Line 7,308: Line 7,308:
return ackermann(m-1, ackermann(m, n-1));
return ackermann(m-1, ackermann(m, n-1));
}
}
}</lang>
}</syntaxhighlight>


=={{header|PL/I}}==
=={{header|PL/I}}==
<lang PL/I>Ackerman: procedure (m, n) returns (fixed (30)) recursive;
<syntaxhighlight lang=PL/I>Ackerman: procedure (m, n) returns (fixed (30)) recursive;
declare (m, n) fixed (30);
declare (m, n) fixed (30);
if m = 0 then return (n+1);
if m = 0 then return (n+1);
Line 7,317: Line 7,317:
else if m > 0 & n > 0 then return (Ackerman(m-1, Ackerman(m, n-1)));
else if m > 0 & n > 0 then return (Ackerman(m-1, Ackerman(m, n-1)));
return (0);
return (0);
end Ackerman;</lang>
end Ackerman;</syntaxhighlight>


=={{header|PL/SQL}}==
=={{header|PL/SQL}}==
<lang PLSQL>DECLARE
<syntaxhighlight lang=PLSQL>DECLARE


FUNCTION ackermann(pi_m IN NUMBER,
FUNCTION ackermann(pi_m IN NUMBER,
Line 7,341: Line 7,341:
END LOOP;
END LOOP;
END;
END;
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 7,375: Line 7,375:


=={{header|PostScript}}==
=={{header|PostScript}}==
<lang postscript>/ackermann{
<syntaxhighlight lang=postscript>/ackermann{
/n exch def
/n exch def
/m exch def %PostScript takes arguments in the reverse order as specified in the function definition
/m exch def %PostScript takes arguments in the reverse order as specified in the function definition
Line 7,388: Line 7,388:
m 1 sub m n 1 sub ackermann ackermann
m 1 sub m n 1 sub ackermann ackermann
}if
}if
}def</lang>
}def</syntaxhighlight>
{{libheader|initlib}}
{{libheader|initlib}}
<lang postscript>/A {
<syntaxhighlight lang=postscript>/A {
[/.m /.n] let
[/.m /.n] let
{
{
Line 7,397: Line 7,397:
{.m 0 gt .n 0 gt and} {.m pred .m .n pred A A} is?
{.m 0 gt .n 0 gt and} {.m pred .m .n pred A A} is?
} cond
} cond
end}.</lang>
end}.</syntaxhighlight>


=={{header|Potion}}==
=={{header|Potion}}==
<lang Potion>ack = (m, n):
<syntaxhighlight lang=Potion>ack = (m, n):
if (m == 0): n + 1
if (m == 0): n + 1
. elsif (n == 0): ack(m - 1, 1)
. elsif (n == 0): ack(m - 1, 1)
Line 7,410: Line 7,410:
ack(m, n) print
ack(m, n) print
" " print.
" " print.
"\n" print.</lang>
"\n" print.</syntaxhighlight>


=={{header|PowerBASIC}}==
=={{header|PowerBASIC}}==
<lang powerbasic>FUNCTION PBMAIN () AS LONG
<syntaxhighlight lang=powerbasic>FUNCTION PBMAIN () AS LONG
DIM m AS QUAD, n AS QUAD
DIM m AS QUAD, n AS QUAD


Line 7,430: Line 7,430:
FUNCTION = Ackermann(m - 1, Ackermann(m, n - 1))
FUNCTION = Ackermann(m - 1, Ackermann(m, n - 1))
END IF
END IF
END FUNCTION</lang>
END FUNCTION</syntaxhighlight>


=={{header|PowerShell}}==
=={{header|PowerShell}}==
{{trans|PHP}}
{{trans|PHP}}
<lang powershell>function ackermann ([long] $m, [long] $n) {
<syntaxhighlight lang=powershell>function ackermann ([long] $m, [long] $n) {
if ($m -eq 0) {
if ($m -eq 0) {
return $n + 1
return $n + 1
Line 7,444: Line 7,444:
return (ackermann ($m - 1) (ackermann $m ($n - 1)))
return (ackermann ($m - 1) (ackermann $m ($n - 1)))
}</lang>
}</syntaxhighlight>
Building an example table (takes a while to compute, though, especially for the last three numbers; also it fails with the last line in Powershell v1 since the maximum recursion depth is only 100 there):
Building an example table (takes a while to compute, though, especially for the last three numbers; also it fails with the last line in Powershell v1 since the maximum recursion depth is only 100 there):
<lang powershell>foreach ($m in 0..3) {
<syntaxhighlight lang=powershell>foreach ($m in 0..3) {
foreach ($n in 0..6) {
foreach ($n in 0..6) {
Write-Host -NoNewline ("{0,5}" -f (ackermann $m $n))
Write-Host -NoNewline ("{0,5}" -f (ackermann $m $n))
}
}
Write-Host
Write-Host
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7
<pre> 1 2 3 4 5 6 7
Line 7,459: Line 7,459:


===A More "PowerShelly" Way===
===A More "PowerShelly" Way===
<lang PowerShell>
<syntaxhighlight lang=PowerShell>
function Get-Ackermann ([int64]$m, [int64]$n)
function Get-Ackermann ([int64]$m, [int64]$n)
{
{
Line 7,474: Line 7,474:
return (Get-Ackermann ($m - 1) (Get-Ackermann $m ($n - 1)))
return (Get-Ackermann ($m - 1) (Get-Ackermann $m ($n - 1)))
}
}
</syntaxhighlight>
</lang>
Save the result to an array (for possible future use?), then display it using the <code>Format-Wide</code> cmdlet:
Save the result to an array (for possible future use?), then display it using the <code>Format-Wide</code> cmdlet:
<lang PowerShell>
<syntaxhighlight lang=PowerShell>
$ackermann = 0..3 | ForEach-Object {$m = $_; 0..6 | ForEach-Object {Get-Ackermann $m $_}}
$ackermann = 0..3 | ForEach-Object {$m = $_; 0..6 | ForEach-Object {Get-Ackermann $m $_}}


$ackermann | Format-Wide {"{0,3}" -f $_} -Column 7 -Force
$ackermann | Format-Wide {"{0,3}" -f $_} -Column 7 -Force
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 7,490: Line 7,490:


=={{header|Processing}}==
=={{header|Processing}}==
<lang java>int ackermann(int m, int n) {
<syntaxhighlight lang=java>int ackermann(int m, int n) {
if (m == 0)
if (m == 0)
return n + 1;
return n + 1;
Line 7,508: Line 7,508:
println();
println();
}
}
}</lang>
}</syntaxhighlight>


{{Out}}
{{Out}}
Line 7,522: Line 7,522:
m = 5 it throws 'maximum recursion depth exceeded'
m = 5 it throws 'maximum recursion depth exceeded'


<lang python>from __future__ import print_function
<syntaxhighlight lang=python>from __future__ import print_function


def setup():
def setup():
Line 7,537: Line 7,537:
return ackermann(m - 1, 1)
return ackermann(m - 1, 1)
else:
else:
return ackermann(m - 1, ackermann(m, n - 1))</lang>
return ackermann(m - 1, ackermann(m, n - 1))</syntaxhighlight>


==={{header|Processing.R}}===
==={{header|Processing.R}}===
Line 7,543: Line 7,543:
Processing.R may exceed its stack depth at ~n==6 and returns null.
Processing.R may exceed its stack depth at ~n==6 and returns null.


<lang r>setup <- function() {
<syntaxhighlight lang=r>setup <- function() {
for (m in 0:3) {
for (m in 0:3) {
for (n in 0:4) {
for (n in 0:4) {
Line 7,560: Line 7,560:
ackermann(m-1, ackermann(m, n-1))
ackermann(m-1, ackermann(m, n-1))
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 7,570: Line 7,570:
=={{header|Prolog}}==
=={{header|Prolog}}==
{{works with|SWI Prolog}}
{{works with|SWI Prolog}}
<lang prolog>:- table ack/3. % memoization reduces the execution time of ack(4,1,X) from several
<syntaxhighlight lang=prolog>:- table ack/3. % memoization reduces the execution time of ack(4,1,X) from several
% minutes to about one second on a typical desktop computer.
% minutes to about one second on a typical desktop computer.
ack(0, N, Ans) :- Ans is N+1.
ack(0, N, Ans) :- Ans is N+1.
ack(M, 0, Ans) :- M>0, X is M-1, ack(X, 1, Ans).
ack(M, 0, Ans) :- M>0, X is M-1, ack(X, 1, Ans).
ack(M, N, Ans) :- M>0, N>0, X is M-1, Y is N-1, ack(M, Y, Ans2), ack(X, Ans2, Ans).</lang>
ack(M, N, Ans) :- M>0, N>0, X is M-1, Y is N-1, ack(M, Y, Ans2), ack(X, Ans2, Ans).</syntaxhighlight>


=={{header|Pure}}==
=={{header|Pure}}==
<lang pure>A 0 n = n+1;
<syntaxhighlight lang=pure>A 0 n = n+1;
A m 0 = A (m-1) 1 if m > 0;
A m 0 = A (m-1) 1 if m > 0;
A m n = A (m-1) (A m (n-1)) if m > 0 && n > 0;</lang>
A m n = A (m-1) (A m (n-1)) if m > 0 && n > 0;</syntaxhighlight>


=={{header|Pure Data}}==
=={{header|Pure Data}}==
<lang Pure Data>
<syntaxhighlight lang=Pure Data>
#N canvas 741 265 450 436 10;
#N canvas 741 265 450 436 10;
#X obj 83 111 t b l;
#X obj 83 111 t b l;
Line 7,627: Line 7,627:
#X connect 15 0 10 0;
#X connect 15 0 10 0;
#X connect 16 0 10 0;
#X connect 16 0 10 0;
#X connect 17 0 0 0;</lang>
#X connect 17 0 0 0;</syntaxhighlight>


=={{header|PureBasic}}==
=={{header|PureBasic}}==
<lang PureBasic>Procedure.q Ackermann(m, n)
<syntaxhighlight lang=PureBasic>Procedure.q Ackermann(m, n)
If m = 0
If m = 0
ProcedureReturn n + 1
ProcedureReturn n + 1
Line 7,640: Line 7,640:
EndProcedure
EndProcedure


Debug Ackermann(3,4)</lang>
Debug Ackermann(3,4)</syntaxhighlight>


=={{header|Purity}}==
=={{header|Purity}}==
<lang Purity>data Iter = f => FoldNat <const $f One, $f>
<syntaxhighlight lang=Purity>data Iter = f => FoldNat <const $f One, $f>
data Ackermann = FoldNat <const Succ, Iter></lang>
data Ackermann = FoldNat <const Succ, Iter></syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
===Python: Explicitly recursive===
===Python: Explicitly recursive===
{{works with|Python|2.5}}
{{works with|Python|2.5}}
<lang python>def ack1(M, N):
<syntaxhighlight lang=python>def ack1(M, N):
return (N + 1) if M == 0 else (
return (N + 1) if M == 0 else (
ack1(M-1, 1) if N == 0 else ack1(M-1, ack1(M, N-1)))</lang>
ack1(M-1, 1) if N == 0 else ack1(M-1, ack1(M, N-1)))</syntaxhighlight>
Another version:
Another version:
<lang python>from functools import lru_cache
<syntaxhighlight lang=python>from functools import lru_cache


@lru_cache(None)
@lru_cache(None)
Line 7,662: Line 7,662:
return ack2(M - 1, 1)
return ack2(M - 1, 1)
else:
else:
return ack2(M - 1, ack2(M, N - 1))</lang>
return ack2(M - 1, ack2(M, N - 1))</syntaxhighlight>
{{out|Example of use}}
{{out|Example of use}}
<lang python>>>> import sys
<syntaxhighlight lang=python>>>> import sys
>>> sys.setrecursionlimit(3000)
>>> sys.setrecursionlimit(3000)
>>> ack1(0,0)
>>> ack1(0,0)
Line 7,673: Line 7,673:
1
1
>>> ack2(3,4)
>>> ack2(3,4)
125</lang>
125</syntaxhighlight>
From the Mathematica ack3 example:
From the Mathematica ack3 example:
<lang python>def ack2(M, N):
<syntaxhighlight lang=python>def ack2(M, N):
return (N + 1) if M == 0 else (
return (N + 1) if M == 0 else (
(N + 2) if M == 1 else (
(N + 2) if M == 1 else (
(2*N + 3) if M == 2 else (
(2*N + 3) if M == 2 else (
(8*(2**N - 1) + 5) if M == 3 else (
(8*(2**N - 1) + 5) if M == 3 else (
ack2(M-1, 1) if N == 0 else ack2(M-1, ack2(M, N-1))))))</lang>
ack2(M-1, 1) if N == 0 else ack2(M-1, ack2(M, N-1))))))</syntaxhighlight>
Results confirm those of Mathematica for ack(4,1) and ack(4,2)
Results confirm those of Mathematica for ack(4,1) and ack(4,2)


Line 7,686: Line 7,686:
The heading is more correct than saying the following is iterative as an explicit stack is used to replace explicit recursive function calls. I don't think this is what Comp. Sci. professors mean by iterative.
The heading is more correct than saying the following is iterative as an explicit stack is used to replace explicit recursive function calls. I don't think this is what Comp. Sci. professors mean by iterative.


<lang python>from collections import deque
<syntaxhighlight lang=python>from collections import deque


def ack_ix(m, n):
def ack_ix(m, n):
Line 7,710: Line 7,710:
stack.extend([m-1, m, n-1])
stack.extend([m-1, m, n-1])


return stack[0]</lang>
return stack[0]</syntaxhighlight>


{{out}}
{{out}}
Line 7,735: Line 7,735:


=={{header|Quackery}}==
=={{header|Quackery}}==
<lang Quackery> forward is ackermann ( m n --> r )
<syntaxhighlight lang=Quackery> forward is ackermann ( m n --> r )
[ over 0 = iff
[ over 0 = iff
[ nip 1 + ] done
[ nip 1 + ] done
Line 7,744: Line 7,744:
ackermann ackermann ] resolves ackermann ( m n --> r )
ackermann ackermann ] resolves ackermann ( m n --> r )


3 10 ackermann echo</lang>
3 10 ackermann echo</syntaxhighlight>
'''Output:'''
'''Output:'''
<pre>8189</pre>
<pre>8189</pre>


=={{header|R}}==
=={{header|R}}==
<lang R>ackermann <- function(m, n) {
<syntaxhighlight lang=R>ackermann <- function(m, n) {
if ( m == 0 ) {
if ( m == 0 ) {
n+1
n+1
Line 7,757: Line 7,757:
ackermann(m-1, ackermann(m, n-1))
ackermann(m-1, ackermann(m, n-1))
}
}
}</lang>
}</syntaxhighlight>
<lang R>for ( i in 0:3 ) {
<syntaxhighlight lang=R>for ( i in 0:3 ) {
print(ackermann(i, 4))
print(ackermann(i, 4))
}</lang>
}</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==
<lang racket>
<syntaxhighlight lang=racket>
#lang racket
#lang racket
(define (ackermann m n)
(define (ackermann m n)
Line 7,769: Line 7,769:
[(zero? n) (ackermann (sub1 m) 1)]
[(zero? n) (ackermann (sub1 m) 1)]
[else (ackermann (sub1 m) (ackermann m (sub1 n)))]))
[else (ackermann (sub1 m) (ackermann m (sub1 n)))]))
</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
Line 7,775: Line 7,775:
{{works with|Rakudo|2018.03}}
{{works with|Rakudo|2018.03}}


<lang perl6>sub A(Int $m, Int $n) {
<syntaxhighlight lang=perl6>sub A(Int $m, Int $n) {
if $m == 0 { $n + 1 }
if $m == 0 { $n + 1 }
elsif $n == 0 { A($m - 1, 1) }
elsif $n == 0 { A($m - 1, 1) }
else { A($m - 1, A($m, $n - 1)) }
else { A($m - 1, A($m, $n - 1)) }
}</lang>
}</syntaxhighlight>
An implementation using multiple dispatch:
An implementation using multiple dispatch:
<lang perl6>multi sub A(0, Int $n) { $n + 1 }
<syntaxhighlight lang=perl6>multi sub A(0, Int $n) { $n + 1 }
multi sub A(Int $m, 0 ) { A($m - 1, 1) }
multi sub A(Int $m, 0 ) { A($m - 1, 1) }
multi sub A(Int $m, Int $n) { A($m - 1, A($m, $n - 1)) }</lang>
multi sub A(Int $m, Int $n) { A($m - 1, A($m, $n - 1)) }</syntaxhighlight>
Note that in either case, Int is defined to be arbitrary precision in Raku.
Note that in either case, Int is defined to be arbitrary precision in Raku.


Here's a caching version of that, written in the sigilless style, with liberal use of Unicode, and the extra optimizing terms to make A(4,2) possible:
Here's a caching version of that, written in the sigilless style, with liberal use of Unicode, and the extra optimizing terms to make A(4,2) possible:
<lang perl6>proto A(Int \𝑚, Int \𝑛) { (state @)[𝑚][𝑛] //= {*} }
<syntaxhighlight lang=perl6>proto A(Int \𝑚, Int \𝑛) { (state @)[𝑚][𝑛] //= {*} }


multi A(0, Int \𝑛) { 𝑛 + 1 }
multi A(0, Int \𝑛) { 𝑛 + 1 }
Line 7,799: Line 7,799:
# Testing:
# Testing:
say A(4,1);
say A(4,1);
say .chars, " digits starting with ", .substr(0,50), "..." given A(4,2);</lang>
say .chars, " digits starting with ", .substr(0,50), "..." given A(4,2);</syntaxhighlight>
{{out}}
{{out}}
<pre>65533
<pre>65533
Line 7,814: Line 7,814:


=={{header|ReScript}}==
=={{header|ReScript}}==
<lang ReScript>let _m = Sys.argv[2]
<syntaxhighlight lang=ReScript>let _m = Sys.argv[2]
let _n = Sys.argv[3]
let _n = Sys.argv[3]


Line 7,828: Line 7,828:


Js.log("ackermann(" ++ _m ++ ", " ++ _n ++ ") = "
Js.log("ackermann(" ++ _m ++ ", " ++ _n ++ ") = "
++ string_of_int(a(m, n)))</lang>
++ string_of_int(a(m, n)))</syntaxhighlight>


{{out}}
{{out}}
Line 7,841: Line 7,841:
=={{header|REXX}}==
=={{header|REXX}}==
===no optimization===
===no optimization===
<lang rexx>/*REXX program calculates and displays some values for the Ackermann function. */
<syntaxhighlight lang=rexx>/*REXX program calculates and displays some values for the Ackermann function. */
/*╔════════════════════════════════════════════════════════════════════════╗
/*╔════════════════════════════════════════════════════════════════════════╗
║ Note: the Ackermann function (as implemented here) utilizes deep ║
║ Note: the Ackermann function (as implemented here) utilizes deep ║
Line 7,865: Line 7,865:
if m==0 then return n+1
if m==0 then return n+1
if n==0 then return ackermann(m-1, 1)
if n==0 then return ackermann(m-1, 1)
return ackermann(m-1, ackermann(m, n-1) )</lang>
return ackermann(m-1, ackermann(m, n-1) )</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default input:}}
{{out|output|text=&nbsp; when using the internal default input:}}
<pre style="height:60ex">
<pre style="height:60ex">
Line 7,946: Line 7,946:


===optimized for m ≤ 2===
===optimized for m ≤ 2===
<lang rexx>/*REXX program calculates and displays some values for the Ackermann function. */
<syntaxhighlight lang=rexx>/*REXX program calculates and displays some values for the Ackermann function. */
high=24
high=24
do j=0 to 3; say
do j=0 to 3; say
Line 7,966: Line 7,966:
if n==0 then return ackermann(m-1, 1)
if n==0 then return ackermann(m-1, 1)
if m==2 then return n + 3 + n
if m==2 then return n + 3 + n
return ackermann(m-1, ackermann(m, n-1) )</lang>
return ackermann(m-1, ackermann(m, n-1) )</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default input:}}
{{out|output|text=&nbsp; when using the internal default input:}}
<pre style="height:60ex">
<pre style="height:60ex">
Line 8,050: Line 8,050:
<br><br>If the &nbsp; '''numeric digits 100''' &nbsp; were to be increased to &nbsp; '''20000''', &nbsp; then the value of &nbsp; '''Ackermann(4,2)''' &nbsp;
<br><br>If the &nbsp; '''numeric digits 100''' &nbsp; were to be increased to &nbsp; '''20000''', &nbsp; then the value of &nbsp; '''Ackermann(4,2)''' &nbsp;
<br>(the last line of output) &nbsp; would be presented with the full &nbsp; '''19,729''' &nbsp; decimal digits.
<br>(the last line of output) &nbsp; would be presented with the full &nbsp; '''19,729''' &nbsp; decimal digits.
<lang rexx>/*REXX program calculates and displays some values for the Ackermann function. */
<syntaxhighlight lang=rexx>/*REXX program calculates and displays some values for the Ackermann function. */
numeric digits 100 /*use up to 100 decimal digit integers.*/
numeric digits 100 /*use up to 100 decimal digit integers.*/
/*╔═════════════════════════════════════════════════════════════╗
/*╔═════════════════════════════════════════════════════════════╗
Line 8,085: Line 8,085:
end
end
if n==0 then return ackermann(m-1, 1)
if n==0 then return ackermann(m-1, 1)
return ackermann(m-1, ackermann(m, n-1) )</lang>
return ackermann(m-1, ackermann(m, n-1) )</syntaxhighlight>
Output note: &nbsp; <u>none</u> of the numbers shown below use recursion to compute.
Output note: &nbsp; <u>none</u> of the numbers shown below use recursion to compute.


Line 8,173: Line 8,173:
=={{header|Ring}}==
=={{header|Ring}}==
{{trans|C#}}
{{trans|C#}}
<lang ring>for m = 0 to 3
<syntaxhighlight lang=ring>for m = 0 to 3
for n = 0 to 4
for n = 0 to 4
see "Ackermann(" + m + ", " + n + ") = " + Ackermann(m, n) + nl
see "Ackermann(" + m + ", " + n + ") = " + Ackermann(m, n) + nl
Line 8,191: Line 8,191:
ok
ok
ok
ok
Raise("Incorrect Numerical input !!!") </lang>
Raise("Incorrect Numerical input !!!") </syntaxhighlight>
{{out}}
{{out}}
<pre>Ackermann(0, 0) = 1
<pre>Ackermann(0, 0) = 1
Line 8,216: Line 8,216:
=={{header|Risc-V}}==
=={{header|Risc-V}}==
the basic recursive function, because memorization and other improvements would blow the clarity.
the basic recursive function, because memorization and other improvements would blow the clarity.
<lang Risc-V>ackermann: #x: a1, y: a2, return: a0
<syntaxhighlight lang=Risc-V>ackermann: #x: a1, y: a2, return: a0
beqz a1, npe #case m = 0
beqz a1, npe #case m = 0
beqz a2, mme #case m > 0 & n = 0
beqz a2, mme #case m > 0 & n = 0
Line 8,243: Line 8,243:
addi sp, sp, 4
addi sp, sp, 4
jr t0, 0
jr t0, 0
</syntaxhighlight>
</lang>


=={{header|Ruby}}==
=={{header|Ruby}}==
{{trans|Ada}}
{{trans|Ada}}
<lang ruby>def ack(m, n)
<syntaxhighlight lang=ruby>def ack(m, n)
if m == 0
if m == 0
n + 1
n + 1
Line 8,255: Line 8,255:
ack(m-1, ack(m, n-1))
ack(m-1, ack(m, n-1))
end
end
end</lang>
end</syntaxhighlight>
Example:
Example:
<lang ruby>(0..3).each do |m|
<syntaxhighlight lang=ruby>(0..3).each do |m|
puts (0..6).map { |n| ack(m, n) }.join(' ')
puts (0..6).map { |n| ack(m, n) }.join(' ')
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7
<pre> 1 2 3 4 5 6 7
Line 8,267: Line 8,267:


=={{header|Run BASIC}}==
=={{header|Run BASIC}}==
<lang runbasic>print ackermann(1, 2)
<syntaxhighlight lang=runbasic>print ackermann(1, 2)
function ackermann(m, n)
function ackermann(m, n)
Line 8,273: Line 8,273:
if (m > 0) and (n = 0) then ackermann = ackermann((m - 1), 1)
if (m > 0) and (n = 0) then ackermann = ackermann((m - 1), 1)
if (m > 0) and (n > 0) then ackermann = ackermann((m - 1), ackermann(m, (n - 1)))
if (m > 0) and (n > 0) then ackermann = ackermann((m - 1), ackermann(m, (n - 1)))
end function</lang>
end function</syntaxhighlight>


=={{header|Rust}}==
=={{header|Rust}}==
<lang rust>fn ack(m: isize, n: isize) -> isize {
<syntaxhighlight lang=rust>fn ack(m: isize, n: isize) -> isize {
if m == 0 {
if m == 0 {
n + 1
n + 1
Line 8,290: Line 8,290:
println!("{}", a); // 125
println!("{}", a); // 125
}
}
</syntaxhighlight>
</lang>


Or:
Or:


<lang rust>
<syntaxhighlight lang=rust>
fn ack(m: u64, n: u64) -> u64 {
fn ack(m: u64, n: u64) -> u64 {
match (m, n) {
match (m, n) {
Line 8,302: Line 8,302:
}
}
}
}
</syntaxhighlight>
</lang>


=={{header|Sather}}==
=={{header|Sather}}==
<lang sather>class MAIN is
<syntaxhighlight lang=sather>class MAIN is


ackermann(m, n:INT):INT
ackermann(m, n:INT):INT
Line 8,323: Line 8,323:
end;
end;
end;
end;
end;</lang>
end;</syntaxhighlight>
Instead of <code>INT</code>, the class <code>INTI</code> could be used, even though we need to use a workaround since in the GNU Sather v1.2.3 compiler the INTI literals are not implemented yet.
Instead of <code>INT</code>, the class <code>INTI</code> could be used, even though we need to use a workaround since in the GNU Sather v1.2.3 compiler the INTI literals are not implemented yet.
<lang sather>class MAIN is
<syntaxhighlight lang=sather>class MAIN is


ackermann(m, n:INTI):INTI is
ackermann(m, n:INTI):INTI is
Line 8,343: Line 8,343:
end;
end;
end;
end;
end;</lang>
end;</syntaxhighlight>


=={{header|Scala}}==
=={{header|Scala}}==


<lang scala>def ack(m: BigInt, n: BigInt): BigInt = {
<syntaxhighlight lang=scala>def ack(m: BigInt, n: BigInt): BigInt = {
if (m==0) n+1
if (m==0) n+1
else if (n==0) ack(m-1, 1)
else if (n==0) ack(m-1, 1)
else ack(m-1, ack(m, n-1))
else ack(m-1, ack(m, n-1))
}</lang>
}</syntaxhighlight>
{{out|Example}}
{{out|Example}}
<pre>
<pre>
Line 8,358: Line 8,358:
</pre>
</pre>
Memoized version using a mutable hash map:
Memoized version using a mutable hash map:
<lang scala>val ackMap = new mutable.HashMap[(BigInt,BigInt),BigInt]
<syntaxhighlight lang=scala>val ackMap = new mutable.HashMap[(BigInt,BigInt),BigInt]
def ackMemo(m: BigInt, n: BigInt): BigInt = {
def ackMemo(m: BigInt, n: BigInt): BigInt = {
ackMap.getOrElseUpdate((m,n), ack(m,n))
ackMap.getOrElseUpdate((m,n), ack(m,n))
}</lang>
}</syntaxhighlight>


=={{header|Scheme}}==
=={{header|Scheme}}==
<lang scheme>(define (A m n)
<syntaxhighlight lang=scheme>(define (A m n)
(cond
(cond
((= m 0) (+ n 1))
((= m 0) (+ n 1))
((= n 0) (A (- m 1) 1))
((= n 0) (A (- m 1) 1))
(else (A (- m 1) (A m (- n 1))))))</lang>
(else (A (- m 1) (A m (- n 1))))))</syntaxhighlight>


An improved solution that uses a lazy data structure, streams, and defines [[Knuth up-arrow]]s to calculate iterative exponentiation:
An improved solution that uses a lazy data structure, streams, and defines [[Knuth up-arrow]]s to calculate iterative exponentiation:


<lang scheme>(define (A m n)
<syntaxhighlight lang=scheme>(define (A m n)
(letrec ((A-stream
(letrec ((A-stream
(cons-stream
(cons-stream
Line 8,400: Line 8,400:
(cond ((= b 0) 1)
(cond ((= b 0) 1)
((= n 1) (expt a b))
((= n 1) (expt a b))
(else (loop (-1+ n) (loop n (-1+ b)))))))</lang>
(else (loop (-1+ n) (loop n (-1+ b)))))))</syntaxhighlight>


=={{header|Scilab}}==
=={{header|Scilab}}==
Line 8,425: Line 8,425:
printacker(i,j)
printacker(i,j)
end
end
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre style="height:20ex">ackermann(0,0)=1 calls=1
<pre style="height:20ex">ackermann(0,0)=1 calls=1
Line 8,457: Line 8,457:


=={{header|Seed7}}==
=={{header|Seed7}}==
<lang seed7>const func integer: ackermann (in integer: m, in integer: n) is func
<syntaxhighlight lang=seed7>const func integer: ackermann (in integer: m, in integer: n) is func
result
result
var integer: result is 0;
var integer: result is 0;
Line 8,468: Line 8,468:
result := ackermann(pred(m), ackermann(m, pred(n)));
result := ackermann(pred(m), ackermann(m, pred(n)));
end if;
end if;
end func;</lang>
end func;</syntaxhighlight>
Original source: [http://seed7.sourceforge.net/algorith/math.htm#ackermann]
Original source: [http://seed7.sourceforge.net/algorith/math.htm#ackermann]


=={{header|SETL}}==
=={{header|SETL}}==
<lang SETL>program ackermann;
<syntaxhighlight lang=SETL>program ackermann;


(for m in [0..3])
(for m in [0..3])
Line 8,482: Line 8,482:
end proc;
end proc;


end program;</lang>
end program;</syntaxhighlight>


=={{header|Shen}}==
=={{header|Shen}}==
<lang shen>(define ack
<syntaxhighlight lang=shen>(define ack
0 N -> (+ N 1)
0 N -> (+ N 1)
M 0 -> (ack (- M 1) 1)
M 0 -> (ack (- M 1) 1)
M N -> (ack (- M 1)
M N -> (ack (- M 1)
(ack M (- N 1))))</lang>
(ack M (- N 1))))</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
<lang ruby>func A(m, n) {
<syntaxhighlight lang=ruby>func A(m, n) {
m == 0 ? (n + 1)
m == 0 ? (n + 1)
: (n == 0 ? (A(m - 1, 1))
: (n == 0 ? (A(m - 1, 1))
: (A(m - 1, A(m, n - 1))));
: (A(m - 1, A(m, n - 1))));
}</lang>
}</syntaxhighlight>


Alternatively, using multiple dispatch:
Alternatively, using multiple dispatch:
<lang ruby>func A((0), n) { n + 1 }
<syntaxhighlight lang=ruby>func A((0), n) { n + 1 }
func A(m, (0)) { A(m - 1, 1) }
func A(m, (0)) { A(m - 1, 1) }
func A(m, n) { A(m-1, A(m, n-1)) }</lang>
func A(m, n) { A(m-1, A(m, n-1)) }</syntaxhighlight>


Calling the function:
Calling the function:
<lang ruby>say A(3, 2); # prints: 29</lang>
<syntaxhighlight lang=ruby>say A(3, 2); # prints: 29</syntaxhighlight>


=={{header|Simula}}==
=={{header|Simula}}==
as modified by R. Péter and R. Robinson:
as modified by R. Péter and R. Robinson:
<lang Simula> BEGIN
<syntaxhighlight lang=Simula> BEGIN
INTEGER procedure
INTEGER procedure
Ackermann(g, p); SHORT INTEGER g, p;
Ackermann(g, p); SHORT INTEGER g, p;
Line 8,522: Line 8,522:
outint(Ackermann(g, p), 0); outimage
outint(Ackermann(g, p), 0); outimage
END
END
END</lang>
END</syntaxhighlight>
{{Output}}
{{Output}}
<pre>Ackermann(4, 0) = 13
<pre>Ackermann(4, 0) = 13
Line 8,532: Line 8,532:


=={{header|Slate}}==
=={{header|Slate}}==
<lang slate>m@(Integer traits) ackermann: n@(Integer traits)
<syntaxhighlight lang=slate>m@(Integer traits) ackermann: n@(Integer traits)
[
[
m isZero
m isZero
Line 8,540: Line 8,540:
ifTrue: [m - 1 ackermann: n]
ifTrue: [m - 1 ackermann: n]
ifFalse: [m - 1 ackermann: (m ackermann: n - 1)]]
ifFalse: [m - 1 ackermann: (m ackermann: n - 1)]]
].</lang>
].</syntaxhighlight>


=={{header|Smalltalk}}==
=={{header|Smalltalk}}==
<lang smalltalk>|ackermann|
<syntaxhighlight lang=smalltalk>|ackermann|
ackermann := [ :n :m |
ackermann := [ :n :m |
(n = 0) ifTrue: [ (m + 1) ]
(n = 0) ifTrue: [ (m + 1) ]
Line 8,557: Line 8,557:


(ackermann value: 0 value: 0) displayNl.
(ackermann value: 0 value: 0) displayNl.
(ackermann value: 3 value: 4) displayNl.</lang>
(ackermann value: 3 value: 4) displayNl.</syntaxhighlight>


=={{header|SmileBASIC}}==
=={{header|SmileBASIC}}==
<lang smilebasic>DEF ACK(M,N)
<syntaxhighlight lang=smilebasic>DEF ACK(M,N)
IF M==0 THEN
IF M==0 THEN
RETURN N+1
RETURN N+1
Line 8,568: Line 8,568:
RETURN ACK(M-1,ACK(M,N-1))
RETURN ACK(M-1,ACK(M,N-1))
ENDIF
ENDIF
END</lang>
END</syntaxhighlight>


=={{header|SNOBOL4}}==
=={{header|SNOBOL4}}==
{{works with|Macro Spitbol}}
{{works with|Macro Spitbol}}
Both Snobol4+ and CSnobol stack overflow, at ack(3,3) and ack(3,4), respectively.
Both Snobol4+ and CSnobol stack overflow, at ack(3,3) and ack(3,4), respectively.
<lang SNOBOL4>define('ack(m,n)') :(ack_end)
<syntaxhighlight lang=SNOBOL4>define('ack(m,n)') :(ack_end)
ack ack = eq(m,0) n + 1 :s(return)
ack ack = eq(m,0) n + 1 :s(return)
ack = eq(n,0) ack(m - 1,1) :s(return)
ack = eq(n,0) ack(m - 1,1) :s(return)
Line 8,584: Line 8,584:
output = str; str = ''
output = str; str = ''
n = 0; m = lt(m,3) m + 1 :s(L1)
n = 0; m = lt(m,3) m + 1 :s(L1)
end</lang>
end</syntaxhighlight>
{{out}}
{{out}}
<pre>1 2 3 4 5 6 7
<pre>1 2 3 4 5 6 7
Line 8,592: Line 8,592:


=={{header|SNUSP}}==
=={{header|SNUSP}}==
<lang snusp> /==!/==atoi=@@@-@-----#
<syntaxhighlight lang=snusp> /==!/==atoi=@@@-@-----#
| | Ackermann function
| | Ackermann function
| | /=========\!==\!====\ recursion:
| | /=========\!==\!====\ recursion:
Line 8,603: Line 8,603:
? ? | \<<<+>+>>-/
? ? | \<<<+>+>>-/
\>>+<<-/!==========/
\>>+<<-/!==========/
# #</lang>
# #</syntaxhighlight>
One could employ [[:Category:Recursion|tail recursion]] elimination by replacing "@/#" with "/" in two places above.
One could employ [[:Category:Recursion|tail recursion]] elimination by replacing "@/#" with "/" in two places above.


=={{header|SPAD}}==
=={{header|SPAD}}==
{{works with|FriCAS, OpenAxiom, Axiom}}
{{works with|FriCAS, OpenAxiom, Axiom}}
<lang SPAD>
<syntaxhighlight lang=SPAD>
NNI ==> NonNegativeInteger
NNI ==> NonNegativeInteger


Line 8,620: Line 8,620:
-- Example
-- Example
matrix [[A(i,j) for i in 0..3] for j in 0..3]
matrix [[A(i,j) for i in 0..3] for j in 0..3]
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 8,638: Line 8,638:
{{works with|Db2 LUW}} version 9.7 or higher.
{{works with|Db2 LUW}} version 9.7 or higher.
With SQL PL:
With SQL PL:
<lang sql pl>
<syntaxhighlight lang=sql pl>
--#SET TERMINATOR @
--#SET TERMINATOR @


Line 8,678: Line 8,678:
END WHILE;
END WHILE;
END @
END @
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 8,721: Line 8,721:


=={{header|Standard ML}}==
=={{header|Standard ML}}==
<lang sml>fun a (0, n) = n+1
<syntaxhighlight lang=sml>fun a (0, n) = n+1
| a (m, 0) = a (m-1, 1)
| a (m, 0) = a (m-1, 1)
| a (m, n) = a (m-1, a (m, n-1))</lang>
| a (m, n) = a (m-1, a (m, n-1))</syntaxhighlight>


=={{header|Stata}}==
=={{header|Stata}}==
<lang stata>mata
<syntaxhighlight lang=stata>mata
function ackermann(m,n) {
function ackermann(m,n) {
if (m==0) {
if (m==0) {
Line 8,742: Line 8,742:
11
11
125
125
end</lang>
end</syntaxhighlight>


=={{header|Swift}}==
=={{header|Swift}}==
<lang swift>func ackerman(m:Int, n:Int) -> Int {
<syntaxhighlight lang=swift>func ackerman(m:Int, n:Int) -> Int {
if m == 0 {
if m == 0 {
return n+1
return n+1
Line 8,753: Line 8,753:
return ackerman(m-1, ackerman(m, n-1))
return ackerman(m-1, ackerman(m, n-1))
}
}
}</lang>
}</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
===Simple===
===Simple===
{{trans|Ruby}}
{{trans|Ruby}}
<lang tcl>proc ack {m n} {
<syntaxhighlight lang=tcl>proc ack {m n} {
if {$m == 0} {
if {$m == 0} {
expr {$n + 1}
expr {$n + 1}
Line 8,766: Line 8,766:
ack [expr {$m - 1}] [ack $m [expr {$n - 1}]]
ack [expr {$m - 1}] [ack $m [expr {$n - 1}]]
}
}
}</lang>
}</syntaxhighlight>
===With Tail Recursion===
===With Tail Recursion===
With Tcl 8.6, this version is preferred (though the language supports tailcall optimization, it does not apply it automatically in order to preserve stack frame semantics):
With Tcl 8.6, this version is preferred (though the language supports tailcall optimization, it does not apply it automatically in order to preserve stack frame semantics):
<lang tcl>proc ack {m n} {
<syntaxhighlight lang=tcl>proc ack {m n} {
if {$m == 0} {
if {$m == 0} {
expr {$n + 1}
expr {$n + 1}
Line 8,777: Line 8,777:
tailcall ack [expr {$m - 1}] [ack $m [expr {$n - 1}]]
tailcall ack [expr {$m - 1}] [ack $m [expr {$n - 1}]]
}
}
}</lang>
}</syntaxhighlight>
===To Infinity… and Beyond!===
===To Infinity… and Beyond!===
If we want to explore the higher reaches of the world of Ackermann's function, we need techniques to really cut the amount of computation being done.
If we want to explore the higher reaches of the world of Ackermann's function, we need techniques to really cut the amount of computation being done.
{{works with|Tcl|8.6}}
{{works with|Tcl|8.6}}
<lang tcl>package require Tcl 8.6
<syntaxhighlight lang=tcl>package require Tcl 8.6


# A memoization engine, from http://wiki.tcl.tk/18152
# A memoization engine, from http://wiki.tcl.tk/18152
Line 8,835: Line 8,835:
# Some small tweaks...
# Some small tweaks...
interp recursionlimit {} 100000
interp recursionlimit {} 100000
interp alias {} ack {} cacheable ack</lang>
interp alias {} ack {} cacheable ack</syntaxhighlight>
But even with all this, you still run into problems calculating <math>\mathit{ack}(4,3)</math> as that's kind-of large…
But even with all this, you still run into problems calculating <math>\mathit{ack}(4,3)</math> as that's kind-of large…


Line 8,842: Line 8,842:
This program assumes the variables N and M are the arguments of the function, and that the list L1 is empty. It stores the result in the system variable ANS. (Program names can be no longer than 8 characters, so I had to truncate the function's name.)
This program assumes the variables N and M are the arguments of the function, and that the list L1 is empty. It stores the result in the system variable ANS. (Program names can be no longer than 8 characters, so I had to truncate the function's name.)


<lang ti83b>PROGRAM:ACKERMAN
<syntaxhighlight lang=ti83b>PROGRAM:ACKERMAN
:If not(M
:If not(M
:Then
:Then
Line 8,862: Line 8,862:
:prgmACKERMAN
:prgmACKERMAN
:End
:End
:End</lang>
:End</syntaxhighlight>


Here is a handler function that makes the previous function easier to use. (You can name it whatever you want.)
Here is a handler function that makes the previous function easier to use. (You can name it whatever you want.)


<lang ti83b>PROGRAM:AHANDLER
<syntaxhighlight lang=ti83b>PROGRAM:AHANDLER
:0→dim(L1
:0→dim(L1
:Prompt M
:Prompt M
:Prompt N
:Prompt N
:prgmACKERMAN
:prgmACKERMAN
:Disp Ans</lang>
:Disp Ans</syntaxhighlight>


=={{header|TI-89 BASIC}}==
=={{header|TI-89 BASIC}}==
<lang ti89b>Define A(m,n) = when(m=0, n+1, when(n=0, A(m-1,1), A(m-1, A(m, n-1))))</lang>
<syntaxhighlight lang=ti89b>Define A(m,n) = when(m=0, n+1, when(n=0, A(m-1,1), A(m-1, A(m, n-1))))</syntaxhighlight>


=={{header|TorqueScript}}==
=={{header|TorqueScript}}==
<lang TorqueScript>function ackermann(%m,%n)
<syntaxhighlight lang=TorqueScript>function ackermann(%m,%n)
{
{
if(%m==0)
if(%m==0)
Line 8,885: Line 8,885:
if(%m>0&&%n>0)
if(%m>0&&%n>0)
return ackermann(%m-1,ackermann(%m,%n-1));
return ackermann(%m-1,ackermann(%m,%n-1));
}</lang>
}</syntaxhighlight>


=={{header|TSE SAL}}==
=={{header|TSE SAL}}==
<lang TSESAL>// library: math: get: ackermann: recursive <description></description> <version>1.0.0.0.5</version> <version control></version control> (filenamemacro=getmaare.s) [kn, ri, tu, 27-12-2011 14:46:59]
<syntaxhighlight lang=TSESAL>// library: math: get: ackermann: recursive <description></description> <version>1.0.0.0.5</version> <version control></version control> (filenamemacro=getmaare.s) [kn, ri, tu, 27-12-2011 14:46:59]
INTEGER PROC FNMathGetAckermannRecursiveI( INTEGER mI, INTEGER nI )
INTEGER PROC FNMathGetAckermannRecursiveI( INTEGER mI, INTEGER nI )
IF ( mI == 0 )
IF ( mI == 0 )
Line 8,905: Line 8,905:
IF ( NOT ( Ask( "math: get: ackermann: recursive: n = ", s2, _EDIT_HISTORY_ ) ) AND ( Length( s2 ) > 0 ) ) RETURN() ENDIF
IF ( NOT ( Ask( "math: get: ackermann: recursive: n = ", s2, _EDIT_HISTORY_ ) ) AND ( Length( s2 ) > 0 ) ) RETURN() ENDIF
Message( FNMathGetAckermannRecursiveI( Val( s1 ), Val( s2 ) ) ) // gives e.g. 9
Message( FNMathGetAckermannRecursiveI( Val( s1 ), Val( s2 ) ) ) // gives e.g. 9
END</lang>
END</syntaxhighlight>


=={{header|TXR}}==
=={{header|TXR}}==
Line 8,912: Line 8,912:
with memoization.
with memoization.


<lang txrlisp>(defmacro defmemofun (name (. args) . body)
<syntaxhighlight lang=txrlisp>(defmacro defmemofun (name (. args) . body)
(let ((hash (gensym "hash-"))
(let ((hash (gensym "hash-"))
(argl (gensym "args-"))
(argl (gensym "args-"))
Line 8,933: Line 8,933:
(each ((i (range 0 3)))
(each ((i (range 0 3)))
(each ((j (range 0 4)))
(each ((j (range 0 4)))
(format t "ack(~a, ~a) = ~a\n" i j (ack i j))))</lang>
(format t "ack(~a, ~a) = ~a\n" i j (ack i j))))</syntaxhighlight>


{{out}}
{{out}}
Line 8,960: Line 8,960:
=={{header|UNIX Shell}}==
=={{header|UNIX Shell}}==
{{works with|Bash}}
{{works with|Bash}}
<lang bash>ack() {
<syntaxhighlight lang=bash>ack() {
local m=$1
local m=$1
local n=$2
local n=$2
Line 8,970: Line 8,970:
ack $((m-1)) $(ack $m $((n-1)))
ack $((m-1)) $(ack $m $((n-1)))
fi
fi
}</lang>
}</syntaxhighlight>
Example:
Example:
<lang bash>for ((m=0;m<=3;m++)); do
<syntaxhighlight lang=bash>for ((m=0;m<=3;m++)); do
for ((n=0;n<=6;n++)); do
for ((n=0;n<=6;n++)); do
ack $m $n
ack $m $n
Line 8,978: Line 8,978:
done
done
echo
echo
done</lang>
done</syntaxhighlight>
{{out}}
{{out}}
<pre>1 2 3 4 5 6 7
<pre>1 2 3 4 5 6 7
Line 8,987: Line 8,987:
=={{header|Ursala}}==
=={{header|Ursala}}==
Anonymous recursion is the usual way of doing things like this.
Anonymous recursion is the usual way of doing things like this.
<lang Ursala>#import std
<syntaxhighlight lang=Ursala>#import std
#import nat
#import nat


Line 8,994: Line 8,994:
~&al^?\successor@ar ~&ar?(
~&al^?\successor@ar ~&ar?(
^R/~&f ^/predecessor@al ^|R/~& ^|/~& predecessor,
^R/~&f ^/predecessor@al ^|R/~& ^|/~& predecessor,
^|R/~& ~&\1+ predecessor@l)</lang>
^|R/~& ~&\1+ predecessor@l)</syntaxhighlight>
test program for the first 4 by 7 numbers:
test program for the first 4 by 7 numbers:
<lang Ursala>#cast %nLL
<syntaxhighlight lang=Ursala>#cast %nLL


test = block7 ackermann*K0 iota~~/4 7</lang>
test = block7 ackermann*K0 iota~~/4 7</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 9,009: Line 9,009:
=={{header|V}}==
=={{header|V}}==
{{trans|Joy}}
{{trans|Joy}}
<lang v>[ack
<syntaxhighlight lang=v>[ack
[ [pop zero?] [popd succ]
[ [pop zero?] [popd succ]
[zero?] [pop pred 1 ack]
[zero?] [pop pred 1 ack]
[true] [[dup pred swap] dip pred ack ack ]
[true] [[dup pred swap] dip pred ack ack ]
] when].</lang>
] when].</syntaxhighlight>
using destructuring view
using destructuring view
<lang v>[ack
<syntaxhighlight lang=v>[ack
[ [pop zero?] [ [m n : [n succ]] view i]
[ [pop zero?] [ [m n : [n succ]] view i]
[zero?] [ [m n : [m pred 1 ack]] view i]
[zero?] [ [m n : [m pred 1 ack]] view i]
[true] [ [m n : [m pred m n pred ack ack]] view i]
[true] [ [m n : [m pred m n pred ack ack]] view i]
] when].</lang>
] when].</syntaxhighlight>


=={{header|Vala}}==
=={{header|Vala}}==
<lang vala>uint64 ackermann(uint64 m, uint64 n) {
<syntaxhighlight lang=vala>uint64 ackermann(uint64 m, uint64 n) {
if (m == 0) return n + 1;
if (m == 0) return n + 1;
if (n == 0) return ackermann(m - 1, 1);
if (n == 0) return ackermann(m - 1, 1);
Line 9,034: Line 9,034:
}
}
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 9,081: Line 9,081:


=={{header|VBA}}==
=={{header|VBA}}==
<lang vb>Private Function Ackermann_function(m As Variant, n As Variant) As Variant
<syntaxhighlight lang=vb>Private Function Ackermann_function(m As Variant, n As Variant) As Variant
Dim result As Variant
Dim result As Variant
Debug.Assert m >= 0
Debug.Assert m >= 0
Line 9,109: Line 9,109:
Debug.Print
Debug.Print
Next i
Next i
End Sub</lang>{{out}}
End Sub</syntaxhighlight>{{out}}
<pre> n= 0 1 2 3 4 5 6 7
<pre> n= 0 1 2 3 4 5 6 7
m=0 1 2 3 4 5 6 7 8
m=0 1 2 3 4 5 6 7 8
Line 9,119: Line 9,119:
Based on BASIC version. Uncomment all the lines referring to <code>depth</code> and see just how deep the recursion goes.
Based on BASIC version. Uncomment all the lines referring to <code>depth</code> and see just how deep the recursion goes.
;Implementation
;Implementation
<lang vb>option explicit
<syntaxhighlight lang=vb>option explicit
'~ dim depth
'~ dim depth
function ack(m, n)
function ack(m, n)
Line 9,138: Line 9,138:
end if
end if
end function</lang>
end function</syntaxhighlight>
;Invocation
;Invocation
<lang vb>wscript.echo ack( 1, 10 )
<syntaxhighlight lang=vb>wscript.echo ack( 1, 10 )
'~ depth = 0
'~ depth = 0
wscript.echo ack( 2, 1 )
wscript.echo ack( 2, 1 )
'~ depth = 0
'~ depth = 0
wscript.echo ack( 4, 4 )</lang>
wscript.echo ack( 4, 4 )</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 9,155: Line 9,155:
{{trans|Rexx}}
{{trans|Rexx}}
{{works with|Visual Basic|VB6 Standard}}
{{works with|Visual Basic|VB6 Standard}}
<syntaxhighlight lang=vb>
<lang vb>
Option Explicit
Option Explicit
Dim calls As Long
Dim calls As Long
Line 9,184: Line 9,184:
End If
End If
End If
End If
End Function 'ackermann</lang>
End Function 'ackermann</syntaxhighlight>
{{Out}}
{{Out}}
<pre style="height:20ex">ackermann( 0 , 0 )= 1 calls= 1
<pre style="height:20ex">ackermann( 0 , 0 )= 1 calls= 1
Line 9,230: Line 9,230:


=={{header|Vlang}}==
=={{header|Vlang}}==
<lang go>fn ackermann(m int, n int ) int {
<syntaxhighlight lang=go>fn ackermann(m int, n int ) int {
if m == 0 {
if m == 0 {
return n + 1
return n + 1
Line 9,247: Line 9,247:
}
}
}
}
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 9,273: Line 9,273:


=={{header|Wart}}==
=={{header|Wart}}==
<lang wart>def (ackermann m n)
<syntaxhighlight lang=wart>def (ackermann m n)
(if m=0
(if m=0
n+1
n+1
Line 9,279: Line 9,279:
(ackermann m-1 1)
(ackermann m-1 1)
:else
:else
(ackermann m-1 (ackermann m n-1)))</lang>
(ackermann m-1 (ackermann m n-1)))</syntaxhighlight>


=={{header|WDTE}}==
=={{header|WDTE}}==
<lang WDTE>let memo a m n => true {
<syntaxhighlight lang=WDTE>let memo a m n => true {
== m 0 => + n 1;
== m 0 => + n 1;
== n 0 => a (- m 1) 1;
== n 0 => a (- m 1) 1;
true => a (- m 1) (a m (- n 1));
true => a (- m 1) (a m (- n 1));
};</lang>
};</syntaxhighlight>


=={{header|Wren}}==
=={{header|Wren}}==
<lang ecmascript>// To use recursion definition and declaration must be on separate lines
<syntaxhighlight lang=ecmascript>// To use recursion definition and declaration must be on separate lines
var Ackermann
var Ackermann
Ackermann = Fn.new {|m, n|
Ackermann = Fn.new {|m, n|
Line 9,302: Line 9,302:
var p2 = pair[1]
var p2 = pair[1]
System.print("A[%(p1), %(p2)] = %(Ackermann.call(p1, p2))")
System.print("A[%(p1), %(p2)] = %(Ackermann.call(p1, p2))")
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 9,317: Line 9,317:
{{works with|nasm}}
{{works with|nasm}}
{{works with|windows}}
{{works with|windows}}
<lang asm>
<syntaxhighlight lang=asm>
section .text
section .text


Line 9,347: Line 9,347:
call ack1 ;return ack(M-1,1)
call ack1 ;return ack(M-1,1)
ret
ret
</syntaxhighlight>
</lang>


=={{header|XLISP}}==
=={{header|XLISP}}==
<lang lisp>(defun ackermann (m n)
<syntaxhighlight lang=lisp>(defun ackermann (m n)
(cond
(cond
((= m 0) (+ n 1))
((= m 0) (+ n 1))
((= n 0) (ackermann (- m 1) 1))
((= n 0) (ackermann (- m 1) 1))
(t (ackermann (- m 1) (ackermann m (- n 1))))))</lang>
(t (ackermann (- m 1) (ackermann m (- n 1))))))</syntaxhighlight>
Test it:
Test it:
<lang lisp>(print (ackermann 3 9))</lang>
<syntaxhighlight lang=lisp>(print (ackermann 3 9))</syntaxhighlight>
Output (after a very perceptible pause):
Output (after a very perceptible pause):
<pre>4093</pre>
<pre>4093</pre>
That worked well. Test it again:
That worked well. Test it again:
<lang lisp>(print (ackermann 4 1))</lang>
<syntaxhighlight lang=lisp>(print (ackermann 4 1))</syntaxhighlight>
Output (after another pause):
Output (after another pause):
<pre>Abort: control stack overflow
<pre>Abort: control stack overflow
Line 9,366: Line 9,366:


=={{header|XPL0}}==
=={{header|XPL0}}==
<lang XPL0>include c:\cxpl\codes;
<syntaxhighlight lang=XPL0>include c:\cxpl\codes;


func Ackermann(M, N);
func Ackermann(M, N);
Line 9,381: Line 9,381:
CrLf(0);
CrLf(0);
];
];
]</lang>
]</syntaxhighlight>
Recursion overflows the stack if either M or N is extended by a single count.
Recursion overflows the stack if either M or N is extended by a single count.
{{out}}
{{out}}
Line 9,394: Line 9,394:


The following named template calculates the Ackermann function:
The following named template calculates the Ackermann function:
<lang xml>
<syntaxhighlight lang=xml>
<xsl:template name="ackermann">
<xsl:template name="ackermann">
<xsl:param name="m"/>
<xsl:param name="m"/>
Line 9,424: Line 9,424:
</xsl:choose>
</xsl:choose>
</xsl:template>
</xsl:template>
</syntaxhighlight>
</lang>


Here it is as part of a template
Here it is as part of a template
<lang xml>
<syntaxhighlight lang=xml>
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
Line 9,473: Line 9,473:
</xsl:template>
</xsl:template>
</xsl:stylesheet>
</xsl:stylesheet>
</syntaxhighlight>
</lang>


Which will transform this input
Which will transform this input
<lang xml>
<syntaxhighlight lang=xml>
<?xml version="1.0" ?>
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="ackermann.xslt"?>
<?xml-stylesheet type="text/xsl" href="ackermann.xslt"?>
Line 9,625: Line 9,625:
</args>
</args>
</arguments>
</arguments>
</syntaxhighlight>
</lang>


into this output
into this output
Line 9,668: Line 9,668:


=={{header|Yabasic}}==
=={{header|Yabasic}}==
<lang Yabasic>sub ack(M,N)
<syntaxhighlight lang=Yabasic>sub ack(M,N)
if M = 0 return N + 1
if M = 0 return N + 1
if N = 0 return ack(M-1,1)
if N = 0 return ack(M-1,1)
Line 9,675: Line 9,675:


print ack(3, 4)
print ack(3, 4)
</syntaxhighlight>
</lang>


What smart code can get. Fast as lightning!
What smart code can get. Fast as lightning!
{{trans|Phix}}
{{trans|Phix}}
<lang Yabasic>sub ack(m, n)
<syntaxhighlight lang=Yabasic>sub ack(m, n)
if m=0 then
if m=0 then
return n+1
return n+1
Line 9,706: Line 9,706:
end sub
end sub
Ackermann()</lang>
Ackermann()</syntaxhighlight>


=={{header|Yorick}}==
=={{header|Yorick}}==
<lang yorick>func ack(m, n) {
<syntaxhighlight lang=yorick>func ack(m, n) {
if(m == 0)
if(m == 0)
return n + 1;
return n + 1;
Line 9,716: Line 9,716:
else
else
return ack(m - 1, ack(m, n - 1));
return ack(m - 1, ack(m, n - 1));
}</lang>
}</syntaxhighlight>
Example invocation:
Example invocation:
<lang yorick>for(m = 0; m <= 3; m++) {
<syntaxhighlight lang=yorick>for(m = 0; m <= 3; m++) {
for(n = 0; n <= 6; n++)
for(n = 0; n <= 6; n++)
write, format="%d ", ack(m, n);
write, format="%d ", ack(m, n);
write, "";
write, "";
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>1 2 3 4 5 6 7
<pre>1 2 3 4 5 6 7
Line 9,735: Line 9,735:
=={{header|Z80 Assembly}}==
=={{header|Z80 Assembly}}==
This function does 16-bit math. Sjasmplus syntax, CP/M executable.
This function does 16-bit math. Sjasmplus syntax, CP/M executable.
<lang z80> OPT --syntax=abf : OUTPUT "ackerman.com"
<syntaxhighlight lang=z80> OPT --syntax=abf : OUTPUT "ackerman.com"
ORG $100
ORG $100
jr demo_start
jr demo_start
Line 9,842: Line 9,842:


txt_m_is: db "m=$"
txt_m_is: db "m=$"
crlf: db 10,13,'$'</lang>
crlf: db 10,13,'$'</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 9,854: Line 9,854:
Source -> http://ideone.com/53FzPA
Source -> http://ideone.com/53FzPA
Compiled -> http://ideone.com/OlS7zL
Compiled -> http://ideone.com/OlS7zL
<lang zed>(A) m n
<syntaxhighlight lang=zed>(A) m n
comment:
comment:
(=) m 0
(=) m 0
Line 9,882: Line 9,882:
comment:
comment:
#true
#true
(003) "=" n1 n2</lang>
(003) "=" n1 n2</syntaxhighlight>


=={{header|Zig}}==
=={{header|Zig}}==
<lang zig>pub fn ack(m: u64, n: u64) u64 {
<syntaxhighlight lang=zig>pub fn ack(m: u64, n: u64) u64 {
if (m == 0) return n + 1;
if (m == 0) return n + 1;
if (n == 0) return ack(m - 1, 1);
if (n == 0) return ack(m - 1, 1);
Line 9,901: Line 9,901:
try stdout.print("\n", .{});
try stdout.print("\n", .{});
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre> 1 2 3 4 5 6 7 8 9
<pre> 1 2 3 4 5 6 7 8 9
Line 9,910: Line 9,910:
=={{header|ZX Spectrum Basic}}==
=={{header|ZX Spectrum Basic}}==
{{trans|BASIC256}}
{{trans|BASIC256}}
<lang zxbasic>10 DIM s(2000,3)
<syntaxhighlight lang=zxbasic>10 DIM s(2000,3)
20 LET s(1,1)=3: REM M
20 LET s(1,1)=3: REM M
30 LET s(1,2)=7: REM N
30 LET s(1,2)=7: REM N
Line 9,928: Line 9,928:
190 LET s(lev-1,3)=s(lev,3)
190 LET s(lev-1,3)=s(lev,3)
200 LET lev=lev-1
200 LET lev=lev-1
210 RETURN </lang>
210 RETURN </syntaxhighlight>
{{out}}
{{out}}
<pre>A(3,7) = 1021</pre>
<pre>A(3,7) = 1021</pre>