用lua編寫的求五邊形數目的程式

lt發表於2016-10-25

原題見這裡 ,把原一維陣列下標a[x*10+y],改為二維陣列a[x][y]修改後,能適應不同大小的圖案.同時修正了變數比較型別不匹配問題。

function a(s1) --返回最小數開頭的序列,如果反方向的第2個數比正方向更小,則返回反方向的序列
  st=1 --start pos
  minx=1000
  minp=1
  xa={}
  for i=1,100 do --find times is unknown
    pos=string.find(s1,',',st)
    if pos ~= nil then
      x=tonumber(string.sub(s1,st,pos-1))
    else
      x=tonumber(string.sub(s1,st))
    end
    xa[#xa+1]=x
    --print (i,x,st,pos)
    if x<minx then
      minx=x
      minp=st
      minidx=#xa
    end
    if pos==nil then 
      break
    end
    st=pos+1
  end
  if minp==1 then
    s2=s1
  else
    s2=string.sub(s1,minp)..','..string.sub(s1,1,minp-2)
  end
  --print(xa[minidx])
  if xa[minidx%#xa+1]<xa[(minidx-2+#xa)%#xa+1] then
    return s2
  else
    s3=tostring(minx)
    for i=1,#xa-1 do
      s3=s3..','..tostring(xa[(minidx-1-i+#xa)%#xa+1])
      --print(xa[(minidx-1-i+#xa)%#xa+1])
    end

    return s3
  end
end

R,C,T,W={},{},{},{} --table define
id=0
-- for small figure

 --[[
for r=1,4 do
  for c=1,3 do
    if r+c <=5 then
      id=id+1
      R[id],C[id],T[id],W[id]=r,c,r+c-1,(1<<id); --assign
      --print(id,R[id],C[id],T[id],W[id])
    end
  end
end
]]
 --for big figure

for r=1,5 do
  for c=1,5 do
    if r+c>=4 and r+c <=8 and r*1000+c~=1003 and r*1000+c~=3005 then --{r,c}~={1,3} and {r,c}~={3,5}then
      id=id+1
      R[id],C[id],T[id],W[id]=r,c,r+c-1,(1<<id); --assign
      print(id,R[id],C[id],T[id],W[id])
    end
  end
end

PW,D={},{}
for i=1,id do
  PW[i],D[i]={},{}
end

for s=1,id do --start
  for e=1,id do --end
    for m=1,id do --mid
      if s~=e and (R[s]==R[e] or C[s]==C[e] or T[s]==T[e]) then

        if R[s]==R[e] then 
          D[s][e]=1
        elseif C[s]==C[e] then 
          D[s][e]=2
        else
          D[s][e]=3
        end
        D[e][s]=D[s][e]

        if (R[s]==R[e] and C[e]-C[s]>1 and R[m]==R[s] and C[m]>C[s] and C[m]<C[e]) or
        (C[s]==C[e] and R[e]-R[s]>1 and C[m]==C[s] and R[m]>R[s] and R[m]<R[e]) or
        (T[s]==T[e] and R[e]-R[s]>1 and T[m]==T[s] and R[m]>R[s] and R[m]<R[e]) then
          if PW[s][e]==nil then
            PW[s][e]=(1<<m)
          else
            PW[s][e]=PW[s][e]+(1<<m);
          end
          PW[e][s]=PW[s][e]
        end
      end
    end
  end
end

Path,SW,P,D1,D2={},{},{},{},{}

print('***1***')
v=1
Path[1],SW[1],P[1],D1[1],D2[1]={},{},{},{},{}
for i=1,id do --1st point
  Path[1][i]=''..i
  SW[1][i]=W[i]
  P[1][i]=i
  D1[1][i]=0
  D2[1][i]=0
  print(Path[v][i],SW[v][i],P[v][i],D1[v][i],D2[v][i])

end


cnt5=0
for v=2,5 do --2nd to 5th points
  print('***'..v..'***')

  cnt=0
  Path[v],SW[v],P[v],D1[v],D2[v]={},{},{},{},{}
  for k=1,#P[v-1] do -- prior level's point
    for i=1,id do --new/this point
      pt=P[v-1][k] --prior point
      if pt~=i and(R[pt]==R[i] or C[pt]==C[i] or T[pt]==T[i]) then --2 points must be a pair
        wt=W[i]
        if PW[pt][i]~=nil then
          wt=wt+PW[pt][i]
        end

        if (SW[v-1][k] & wt)==0 and 
        D[pt][i]~=D1[v-1][k] then --2 points must be a pair,so D ~= nil
          cnt=cnt+1

          Path[v][cnt]=Path[v-1][k]..','..i
          SW[v][cnt]=SW[v-1][k]+wt
          P[v][cnt]=i
          D1[v][cnt]=D[pt][i]
          D2[v][cnt]=D2[v-1][k]*10+D1[v][cnt]

          if v==5 then
            st=tonumber(string.sub(Path[v][cnt],1,string.find(Path[v][cnt],',')-1)) --st start point 
            if D[i][st]~=nil and D[i][st]~=tonumber(string.sub(D2[v][cnt],1,1)) and D[i][st]~=D1[v][cnt]
            and(PW[i][st]== nil or (SW[v][cnt]&PW[i][st])==0 )
            and a(Path[v][cnt])==Path[v][cnt] then
              print(Path[v][cnt],SW[v][cnt],P[v][cnt],D1[v][cnt],D2[v][cnt])
              cnt5=cnt5+1
            end
          end
        end
      end
    end
  end
end
print(cnt5,"個不同的五邊形")

相關文章