39 lines
1.1 KiB
Lua
39 lines
1.1 KiB
Lua
#!/usr/bin/env luajit
|
|
local gmp = require 'gmp' ('libgmp')
|
|
local mpz, z_mul, z_add, z_add_ui, z_set_d =
|
|
gmp.types.z, gmp.z_mul, gmp.z_add, gmp.z_add_ui, gmp.z_set_d
|
|
local z_cmp, z_cmp_ui, z_init_d, z_set=
|
|
gmp.z_cmp, gmp.z_cmp_ui, gmp.z_init_set_d, gmp.z_set
|
|
local printf = gmp.printf
|
|
|
|
local function ack(i,n)
|
|
local nxt=setmetatable({}, {__index=function(t,k) local z=mpz() z_init_d(z, 0) t[k]=z return z end})
|
|
local goal=setmetatable({}, {__index=function(t,k) local o=mpz() z_init_d(o, 1) t[k]=o return o end})
|
|
goal[i]=mpz() z_init_d(goal[i], -1)
|
|
local v=mpz() z_init_d(v, 0)
|
|
local ic
|
|
local END=n+1
|
|
local ntmp,gtmp
|
|
repeat
|
|
ic=0
|
|
ntmp,gtmp=nxt[ic], goal[ic]
|
|
z_add_ui(v, ntmp, 1)
|
|
while z_cmp(ntmp, gtmp) == 0 do
|
|
z_set(gtmp,v)
|
|
z_add_ui(ntmp, ntmp, 1)
|
|
nxt[ic], goal[ic]=ntmp, gtmp
|
|
ic=ic+1
|
|
ntmp,gtmp=nxt[ic], goal[ic]
|
|
end
|
|
z_add_ui(ntmp, ntmp, 1)
|
|
nxt[ic]=ntmp
|
|
until z_cmp_ui(nxt[i], END) == 0
|
|
return v
|
|
end
|
|
|
|
if #arg<1 then
|
|
print("Ackermann: "..arg[0].." <num1> [num2]")
|
|
else
|
|
printf("%Zd\n", ack(tonumber(arg[1]), arg[2] and tonumber(arg[2]) or 0))
|
|
end
|