Problem #
pidigits need lgmp large number library
lgmp is not available for Lua 5.4.x
lgmp is only available in luarocks for up to Lua 5.3.6
pidigits.lua from CLBG site just use some kind of ‘bn’ library, but the library is not given.
in original code, ‘bn’ library is loaded with the following code:
local Lbn=require"bn"
which gives error:
lua: pidigits.lua:7: module 'bn' not found:
no field package.preload['bn']
no file '/usr/local/share/lua/5.4/bn.lua'
no file '/usr/local/share/lua/5.4/bn/init.lua'
no file '/usr/local/lib/lua/5.4/bn.lua'
no file '/usr/local/lib/lua/5.4/bn/init.lua'
no file './bn.lua'
no file './bn/init.lua'
no file '/usr/local/lib/lua/5.4/bn.so'
no file '/usr/local/lib/lua/5.4/loadall.so'
no file './bn.so'
stack traceback:
[C]: in function 'require'
pidigits.lua:7: in main chunk
[C]: in ?
Reading from the CLBG site does not offer clue how to install this ‘bn’ library.
Install lua-openssh #
After searching for ‘big number library for Lua’, or ‘bn.lua’, I found a solution.
Alternative is to use big number libraray (bn) from lua-openssh
How to install with luarocks:
luarocks install openssl
Other installation method: https://zhaozg.github.io/lua-openssl/topics/README.md.html#quick-start
Modify pidigits.Lua #
Modification: change the line to:
local Lbn=require('openssl').bn
According to https://zhaozg.github.io/lua-openssl/modules/bn.html
Final Code #
-- The Computer Language Benchmarks Game
-- https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
-- Translated from Mr Ledrug's C program by Jeremy Zerfas.
-- Transliterated from GMP to bn by Isaac Gouy
local Lbn=require('openssl').bn
local add, sub, mul, div = Lbn.add, Lbn.sub, Lbn.mul, Lbn.div
local set, get = Lbn.number, Lbn.tonumber
local tmp1, tmp2, acc, den, num
local function extractDigit(nth)
tmp1 = mul(num, nth)
tmp2 = add(tmp1, acc)
tmp1 = div(tmp2, den)
return tmp1
end
local function eliminateDigit(d)
acc = sub(acc, mul(den, d))
acc = mul(acc, 10)
num = mul(num, 10)
end
local function nextTerm(k)
k2 = k * 2 + 1
acc = add(acc, mul(num, 2))
acc = mul(acc, k2)
den = mul(den, k2)
num = mul(num, k)
end
local function main(n)
local write = io.write
tmp1 = set(0)
tmp2 = set(0)
acc = set(0)
den = set(1)
num = set(1)
i = 0
k = 0
while i < n do
k = k + 1
nextTerm(k)
if num > acc then goto continue end
d = extractDigit(3)
if d ~= extractDigit(4) then goto continue end
write(get(d))
i = i + 1; if i % 10 == 0 then write("\t:", i, "\n") end
eliminateDigit(d)
::continue::
end
if i % 10 ~= 0 then write(string.rep(" ", 10 - n % 10), "\t:", n, "\n") end
end
main(tonumber(arg and arg[1]) or 27)
(base) root@z170:/home/waskita/plee/bench-clbg/benchmarksgame-sourcecode-2025-03-07/pidigits# more p.lua
-- The Computer Language Benchmarks Game
-- https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
-- Translated from Mr Ledrug's C program by Jeremy Zerfas.
-- Transliterated from GMP to bn by Isaac Gouy
local Lbn=require('openssl').bn
local add, sub, mul, div = Lbn.add, Lbn.sub, Lbn.mul, Lbn.div
local set, get = Lbn.number, Lbn.tonumber
local tmp1, tmp2, acc, den, num
local function extractDigit(nth)
tmp1 = mul(num, nth)
tmp2 = add(tmp1, acc)
tmp1 = div(tmp2, den)
return tmp1
end
local function eliminateDigit(d)
acc = sub(acc, mul(den, d))
acc = mul(acc, 10)
num = mul(num, 10)
end
local function nextTerm(k)
k2 = k * 2 + 1
acc = add(acc, mul(num, 2))
acc = mul(acc, k2)
den = mul(den, k2)
num = mul(num, k)
end
local function main(n)
local write = io.write
tmp1 = set(0)
tmp2 = set(0)
acc = set(0)
den = set(1)
num = set(1)
i = 0
k = 0
while i < n do
k = k + 1
nextTerm(k)
if num > acc then goto continue end
d = extractDigit(3)
if d ~= extractDigit(4) then goto continue end
write(get(d))
i = i + 1; if i % 10 == 0 then write("\t:", i, "\n") end
eliminateDigit(d)
::continue::
end
if i % 10 ~= 0 then write(string.rep(" ", 10 - n % 10), "\t:", n, "\n") end
end
main(tonumber(arg and arg[1]) or 27)
And it finally works.