-
#!/usr/bin/env lua
-
-
-- used for store four points
-
array={}
-
-
-- reverse the whole array from first to last
-
function array.reverse(this,first,last)
-
first = first or 1
-
last = last or table.maxn(this)
-
while first < last do
-
this[first],this[last]=this[last],this[first]
-
first=first+1
-
last=last-1
-
end
-
end
-
-
-- this algorithm is modified from the C++ STL
-
-- change array to next permutation and returns true
-
-- return false if the current is the last permutation
-
function array.next_permutation(this,first,last)
-
local len=table.maxn(this)
-
if len==0 or len==1 then
-
return false
-
end
-
-
first = first or 1
-
last = last or len
-
-
local i=last
-
while true do
-
local ii=i
-
i=i-1
-
if this[i] < this[ii] then
-
local j=last
-
while this[i] >= this[j] do
-
j=j-1
-
end
-
this[i],this[j]=this[j],this[i]
-
this:reverse(ii,last)
-
return true
-
end
-
-
if i==first then
-
return false
-
end
-
end
-
end
-
-
-- show the array with space seperated
-
function array.show(this)
-
for _,i in ipairs(this) do
-
io.write(i,' ')
-
end
-
io.write('\n')
-
end
-
-
optable={"+","-","*","/"}
-
opfuncs={}
-
opfuncs["+"]=function(a,b)
-
return a+b
-
end
-
-
opfuncs["-"]=function(a,b)
-
return a-b
-
end
-
-
opfuncs["*"]=function(a,b)
-
return a*b
-
end
-
-
opfuncs["/"]=function(a,b)
-
if b==0 then
-
return nil
-
else
-
return a/b
-
end
-
end
-
-
-
-- stack class for calculation
-
function Stack()
-
local stack={}
-
stack.push=table.insert
-
stack.pop=table.remove
-
stack.size=table.maxn
-
stack.bottom=function(this)
-
return this[1]
-
end
-
return stack
-
end
-
-
-- calculate from polish notation
-
function array.eval(toeval)
-
local stack=Stack()
-
for _,v in ipairs(toeval) do
-
local op=opfuncs[v]
-
if op then
-
if stack:size() <2 then
-
return nil
-
end
-
local b=stack:pop()
-
local a=stack:pop()
-
local result=op(a,b)
-
if result then
-
stack:push(result)
-
else
-
return nil
-
end
-
else
-
stack:push(tonumber(v))
-
end
-
end
-
-
return stack:bottom()
-
end
-
-
-- precedence table, "n" is number
-
precedence={
-
["+"] = 1;
-
["-"] = 1;
-
["*"] = 2;
-
["/"] = 2;
-
["n"] = 3;
-
}
-
-
-- convert from polish expression to normal expression
-
function array.show_expr(this)
-
local strStack=Stack()
-
local typeStack=Stack()
-
-
for _,v in ipairs(this) do
-
if opfuncs[v] then
-
local b=strStack:pop()
-
local a=strStack:pop()
-
-
local bp=precedence[typeStack:pop()]
-
local ap=precedence[typeStack:pop()]
-
local vp=precedence[v]
-
-
if ap<=vp then
-
a="("..a..")"
-
end
-
-
if bp<=vp then
-
b="("..b..")"
-
end
-
-
strStack:push(a..v..b)
-
typeStack:push(v)
-
else
-
strStack:push(v)
-
typeStack:push("n")
-
end
-
end
-
print(strStack:bottom())
-
end
-
-
-
-- get table copy(contains its methods)
-
function array.copy(this)
-
local copy={}
-
for index,value in pairs(this) do
-
copy[index]=value
-
end
-
return copy
-
end
-
-
-- the main method to calculate 24 points
-
function array.calc(this)
-
local order=1
-
for i=1,4 do
-
for j=i,4 do
-
for k=j,4 do
-
local toeval=this:copy()
-
table.insert(toeval,optable[i])
-
table.insert(toeval,optable[j])
-
table.insert(toeval,optable[k])
-
table.sort(toeval)
-
while true do
-
if tostring(toeval:eval())=="24" then
-
io.write(order,": ")
-
toeval:show_expr()
-
order=order+1
-
end
-
-
if not toeval:next_permutation() then
-
break
-
end
-
end
-
end
-
end
-
end
-
end
-
-
for i=1,4 do
-
if not arg[i] then
-
io.stderr:write("Please input at least four arguments!\n")
-
return 1
-
end
-
-
local num=tonumber(arg[i])
-
if not num then
-
io.stderr:write("Arguments must be numbers\n")
-
return 2
-
end
-
-
if num<1 or num > 13 then
-
io.stderr:write("Number must in [1,13]\n")
-
return 3
-
end
-
-
if math.floor(num)~=num then
-
io.stderr:write("Number must be an integer!\n")
-
return 4
-
end
-
-
table.insert(array,arg[i])
-
end
-
-
array:calc()