# Lua學習筆記

apt-get install lua5.1-0-dev
find / -name lua.h
/home/hanxiaohua/work1/MathTool/lua/lua.h
/usr/include/lua5.1/lua.h
./luatest
./luatest: /usr/lib/x86_64-linux-gnu/liblua5.1.so.0: no version information available (required by ./luatest)
[email protected]:/home/cpptest/lua# ./luatest NumberTheory.lua
5!=120
6!=720
7!=5040
8!=40320
9!=362880
10!=3628800
11!=39916800
12!=479001600
4    -4    -4
4    6
totient(37)=36
totient(57)=36
totient(63)=36
totient(74)=36
totient(76)=36
100
7
PowerMod(5,-2,17)=15
PowerMod(5,-1,17)=7
PowerMod(5,0,17)=1
PowerMod(5,1,17)=5
PowerMod(5,2,17)=8
PowerMod(5,4,17)=13
PowerMod(5,8,17)=16
PowerMod(5,16,17)=1

lprimroot(2)=1,lprimroot(3)=2,lprimroot(4)=3,lprimroot(5)=2,lprimroot(6)=5,lprimroot(7)=3,lprimroot(9)=2,lprimroot(10)=3,lprimroot(11)=2,lprimroot(13)=2,lprimroot(14)=3,lprimroot(17)=3,lprimroot(18)=5,lprimroot(19)=2,lprimroot(22)=7,lprimroot(23)=5,lprimroot(25)=2,lprimroot(26)=7,lprimroot(27)=2,lprimroot(29)=2,有原根

function Factorial(n)
if n==0 or n==1 then
return 1
else
return n * Factorial(n-1)
end
end

--print("Enter a number : ")
for i=5,12,1 do
io.write(i,"!=",Factorial(i),"\n")
end

--求2個整數的最大公約數
function GcdInt(a,b)
if(a*b<0) then
return -GcdInt(math.abs(a),math.abs(b))
end
if(a<b) then
local temp=a
a=b
b=temp
end
if(a%b==0)then
return b
else
return GcdInt(a%b,b)
end
end

local ret=GcdInt(12,32)
local ret1=GcdInt(-12,32)
local ret2=GcdInt(12,-32)
print(ret,ret1,ret2)

function Iscoprime(a,b)
local ret=0
if(GcdInt(a,b)==1)then
ret=1
end
return ret
end

--φ(n)表示不大於n且與n互素的正整數個數、n階循環羣中n階元的個數、本原n次單位根（n次單位原根）的個數、整數模n乘法羣（模n既約剩餘類）(Z/p^nZ)^×中與n互素剩餘類的個數
function Phi(n)
local ret=0
if(n==1)then
return 1
end
for i=1,n-1,1 do
ret=ret+Iscoprime(n,i)
end
return ret
end

--T(n)表示n的正因子的個數、n階循環羣子羣的個數、Z/nZ理想的個數
function Sigma0(n)
local ret=0
for d=1,n,1 do
if(n%d==0)then
ret=ret+1
end
end
return ret
end

--totient(12)=4
--|S(C_12)|=T(12)=|{1,2,3,4,6,12}|=6
print(Phi(12),Sigma0(12))

local v36={37,57,63,74,76}
for i,v in pairs(v36) do
io.write("totient(",v,")=",Phi(v),"\n")
end

function Mod(ret,n)
if(ret<0)then
local ret1=ret+(-ret+1)*n
return ret1%n
end
return ret%n
end

function mod(ret,n)
local raw_mod=ret%n
if (raw_mod==0) then
return 0
elseif (ret>= 0) then
return raw_mod
else
return raw_mod+n
end
end

function inverse_mod_p(u,p)
for i=1,p-1,1 do
if (Mod(u * i, p ) == 1)then
return i
end
end
return nil
--[[
local t1 = 0
local t3 = 0
local q  = 0
local u1 = 1
local u3 = u
local v1 = 0
local v3 = p
local inv_v = 0

while( v3 ~= 0)    do
q = u3 / v3
t1 = u1 - v1 * q
t3 = u3 - v3 * q
u1 = v1
u3 = v3
v1 = t1
v3 = t3
end
inv_v=mod(u1,p)
if (mod(u * inv_v, p ) ~= 1)then
return 0
end
return inv_v
]]--
end

function PowerMod(a,k,p)
if k<0 then
local a1=inverse_mod_p(a,p)
return PowerMod(a1,-k,p)
end
local ans=1
for i=1,k,1 do
ans=ans*a%p
end
return ans
end

function OrderMod(a,p)
local k=1
while(k<=p)    do
if(PowerMod(a,k,p)==1)then
break
end
k=k+1
end
return k
end

function LogMod(b,a,p)
local k=1
while(k<=p)    do
if(PowerMod(a,k,p)==b)then
break
end
k=k+1
end
return k
end

print(LogMod(57, 3, 113))
print(inverse_mod_p(5,17))
local bArr={-2,-1,0,1,2,4,8,16}
for i,v in pairs(bArr) do
io.write("PowerMod(5,",v,",17)=",PowerMod(5,v,17),"\n")
end

function is_primitive_root(a,p)
local k=OrderMod(a,p)
return k==Phi(p)
end

--計算模n的最小原根
function PrimitiveRootMod(n)
for a=1,n-1,1 do
local ret=is_primitive_root(a,n)
if(ret)then
return a
end
end
return nil
end

io.write("在前30個正整數中,")
for n=1,30,1 do
if PrimitiveRootMod(n)==nil then
io.write(n,",")
end
end
io.write("沒有原根\n")
for n=1,30,1 do
local ret=PrimitiveRootMod(n)
if ret~=nil then
io.write("lprimroot(",n,")=",ret,",")
end
end
io.write("有原根\n")

test.lua中依賴於宿主程序calllua的Lua代碼：暫無
[email protected]:/home/cpptest/lua# g++ -o calllua calllua.cpp -I /usr/include/lua5.1/ -llua5.1
Hello, World!
10+30=40
1    靈智系
2    蠻荒系
3    地脈系
4    天羽系
5    蜚廉系
6    瑞獸系
7    神巫系
8    幽冥系
PHYLE_MAX=8
eWorldPhyle.P_TERRAN=0
eWorldPhyle.PHYLE_MAX=8
0    靈智系
1    蠻荒系
2    地脈系
3    天羽系
4    蜚廉系
5    瑞獸系
6    神巫系
7    幽冥系
(1/17)=1,x=1
(2/17)=1,x=6
(3/17)=-1,x=0
(4/17)=1,x=2
(5/17)=-1,x=0
(6/17)=-1,x=0
(7/17)=-1,x=0
(8/17)=1,x=5
(9/17)=1,x=3
(10/17)=-1,x=0
(11/17)=-1,x=0
(12/17)=-1,x=0
(13/17)=1,x=8
(14/17)=-1,x=0
(15/17)=1,x=7
(16/17)=1,x=4
(17/17)=0,x=0
3    8    8    1
1二次剩餘:[1,2,4,8,9,13,15,16,]
-1二次非剩餘:[3,5,6,7,10,11,12,14,]
0整除:[17,]
10+5=15

-- test.lua
print "Hello, World!"

myName = "beauty girl"
helloTable = {name = "mutou", IQ = 125}

return (num1 + num2)
end;

print("10+30="..sum)

gszWorldPhyle= {"靈智系", "蠻荒系", "地脈系", "天羽系", "蜚廉系", "瑞獸系", "神巫系", "幽冥系"}
--i 表示索引, v 表示值
for i,v in ipairs(gszWorldPhyle) do
print(i, v)
end
PHYLE_MAX=#gszWorldPhyle
print("PHYLE_MAX="..PHYLE_MAX)

-- 填index=-1從0開始，填index=0或不填index從1開始,……
function CreateEnumTable(tbl, index)
local enumtbl = {}
local enumindex = index or 0
for i, v in ipairs(tbl) do
enumtbl[v] = enumindex + i
end
return enumtbl
end
--[[
種族= 0人型系,1野獸系,2植物系,3飛行系,4昆蟲系,5龍系,6神系,7不死系
]]--
eWorldPhyle = CreateEnumTable({"P_TERRAN", "P_BEAST", "P_PLANTS", "P_FLY", "P_INSECT", "P_DRAGON", "P_PROTOSS", "P_UNDEAD", "PHYLE_MAX"},-1)
print("eWorldPhyle.P_TERRAN="..eWorldPhyle.P_TERRAN)
print("eWorldPhyle.PHYLE_MAX="..eWorldPhyle.PHYLE_MAX)

function getWorldPhyle(Phyle)
return gszWorldPhyle[Phyle+1]
end

for i=eWorldPhyle.P_TERRAN,eWorldPhyle.PHYLE_MAX-1,1 do
local v=getWorldPhyle(i)
print(i,v)
end

--正確的獲取table的長度應該是遍歷,而且要用pairs，不要用ipairs
local function get_len(tb)
local len = 0
for k,v in pairs(tb) do
len= len+1
end
return len
end

--[[

x=8,(13/17)=1
x=無解,(5/17)=-1
]]--
function Legendre(a,p)
local x=0
if(a%p==0) then
return 0,x--是p的倍數
end
for i=1,p-1,1 do
if((i*i-a)%p==0) then
x=i
return 1,x--a是p的二次剩餘
end
end
return -1,x--a是p的二次非剩餘
end

local Ret17={[1]={}, [-1]={}, [0]={}}
for i=1,17,1 do
local ret,x=Legendre(i,17)
local str = string.format("(%d/17)=%d,x=%d",i,ret,x)
print(str)
--print(i,ret,x)
table.insert(Ret17[ret],i)
end
print(get_len(Ret17),#Ret17[1], #Ret17[-1], #Ret17[0])

function getRetStr(ret)
local strArr={"二次非剩餘","整除","二次剩餘"}
return strArr[ret+2]
end

for k,v in pairs(Ret17) do
io.write(k..getRetStr(k)..":[")
for k1,v1 in pairs(v) do
io.write(v1,",")
end
print("]")
end

lua中元表的應用例子1：lua複數類
[email protected]:/home/cpptest/lua# ./luatest2
./luatest2: /usr/lib/x86_64-linux-gnu/liblua5.1.so.0: no version information available (required by ./luatest2)
4    5
-2    -3
-1    7
0.28    -0.04
c:4    5
The sum is 21
luapythagorean(3,4)=5.000000

-- test2.lua

return x+y
end

function pythagorean(a,b)
local c2 = a^2 + b^2
return math.sqrt(c2)
end

function fun(x)
return math.sqrt(math.sqrt(4*x*x+1)-x*x-1)
end

complex={
op = {}
op.x = op1.x + op2.x
op.y = op1.y + op2.y
setmetatable(op,complex)
return op
end,

__sub=function(op1,op2)
op = {}
op.x = op1.x - op2.x
op.y = op1.y - op2.y
setmetatable(op,complex)
return op
end,

__mul=function(op1,op2)
op = {}
op.x = op1.x * op2.x-op1.y * op2.y
op.y = op1.x* op2.y + op2.x* op1.y
setmetatable(op,complex)
return op
end,

__div=function(op1,op2)
op = {}
op.x = (op1.x * op2.x+op1.y * op2.y)/(op2.x * op2.x+op2.y * op2.y)
op.y = (-op1.x* op2.y + op2.x* op1.y)/(op2.x * op2.x+op2.y * op2.y)
setmetatable(op,complex)
return op
end,

create=function(o)
o = o or {}
setmetatable(o,complex)
return o
end
}

a=complex.create{x=1,y=1}
b=complex.create{x=3,y=4}
c = a + b
print(c.x, c.y)  -- 輸出 4，5
d = a - b
print(d.x, d.y)  -- 輸出 -2，-3
e = a * b
print(e.x, e.y)  -- 輸出 -1，7
f = a / b
print(f.x, f.y)  -- 輸出 0.28，-0.04

meta={
op = {}
op.x = op1.x + op2.x
op.y = op1.y + op2.y
return op
end
}

a={x=1,y=1}
setmetatable(a,meta)
b={x=3,y=4}
c = a + b
print("c:"..c.x, c.y) -- 輸出 4，5

metatable通過其包含的函數來給所掛接的table定義一些特殊的操作，包括:
__mul: 定義乘法操作
__div: 定義除法操作
__sub: 定義減法操作
__unm: 定義負操作, 即: -table的含義
__tostring: 定義當table作爲tostring()函式之參數被呼叫時的行爲(例如: print(table)時將呼叫tostring(table)作爲輸出結果)
__concat: 定義連接操作(".."運算符)
__index: 定義當table中不存在的key值被試圖獲取時的行爲
__newindex: 定義在table中產生新key值時的行爲
Lua中用表類型模擬複數，x表示實部，y表示虛部；然後把複數相加的邏輯（實部+實部，虛部+虛部）寫進元表內 __add 方法中，因此，(1+1i) + (3+4i) = (4+5i)。元表是普通表變量中的一張隱藏的表，用 setmetatable 函數設置它，想要讀出來則用 getmetatable。

Lua基礎知識

a=10
a=2.5
a="諸葛量化"
=是賦值符號，==是等於符號
lua變量必須以字母或者下劃線開頭，區分大小寫
lua的關鍵字不能用作變量名
8種數據類型：

Lua語言優勢：

lua、luac一個是運行環境，一個是編譯器
Lua語言調用C語言帶參數的方法:getString
luaL_checkstring(L,1);//獲取傳進來的參數，檢查第1個參數
lua_pushstring(L,buf);壓入棧中
return 1;//指明返回值有1個
Lua語言和C語言的交互機制
lua語言的索引是從1開始的

Lua語言不依賴於數組語言的數據類型

C語言調用Lua語言的方法
Lua語言沒有入口方法

lua_getglobal(L,"main");//Lua棧的第一個位置放進方法
lua_call(L,0,0);//第二個表示傳進參數的個數，第三個表示返回值的個數

luaL_newstate創建一個lua_State
Lua_openlibs加載庫(print是庫裏面的方法)
dofile(L,"app.lua")

dostring(L,"print(\"Hello eoe\")","MyScript");