Commit 55ace496 authored by  tawada's avatar tawada

Add resolver

parent c592b577
TARGET = resolver
OBJS = $(CPPS:.cpp=.o)
CPPS = $(wildcard *.cpp)
CXX = g++
CXXFLAGS = -Wall -O3
PYTHON = python3
.PHONY:run
run:
$(PYTHON) $(TARGET).py -i dataAsample.txt
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) -o $@ $(OBJS)
clean:
rm *.o
rm $(TARGET)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import heapq
import numpy as np
import random
import parse
import itertools
class MAP:
def __init__(self, afile):
#解答ファイルから読み込み
x_index = 0
y_index = 0
z_index = -1
with open(afile) as f:
for str_line in f:
if str_line[0]=='G':
pass
elif str_line[0]=='S':
size = parse.parse("SIZE {X:d}X{Y:d}X{Z:d}", str_line)
self.X=size["X"]
self.Y=size["Y"]
self.Z=size["Z"]
self.name="%dX%dX%d" % (self.X, self.Y, self.Z)
self.map=np.zeros((self.X+1, self.Y+1, self.Z+1))
self.mapdic=0
elif str_line[0]=='L':
z_index += 1
y_index = 0
elif str_line[0] >= '0' and str_line[0] <= '9':
array = str_line.split(",")
x_index = 0
for num in array:
self.map[x_index][y_index][z_index] = int(num)
x_index += 1
y_index += 1
self.n_line = int(np.amax(self.map))
self.line = np.zeros((self.n_line,2,3))
for x,y,z in itertools.product(\
range(self.X), range(self.Y), range(self.Z)):
neighbours = self.neighbour([x,y,z])
index = int(self.map[x][y][z]-1)
num = self.countV(index+1, neighbours)
if num == 1:
if list(self.line[index][0]) == [0,0,0]:
self.line[index][0][0] = x
self.line[index][0][1] = y
self.line[index][0][2] = z
else:
self.line[index][1][0] = x
self.line[index][1][1] = y
self.line[index][1][2] = z
def countV(self, value, point_list):
"""座標リストpoint_list内の座標(x,y,z)のself.mapの値(ラインのインデックス)がvalueと等しいものの個数を数えます"""
c = 0
for p in point_list:
if self.map[tuple(p)] == value:
c += 1
return c
def delLine(self, index):
"""self.map上のラインindexを消す. 端点は消さない"""
for x,y,z in itertools.product(\
range(self.X), range(self.Y), range(self.Z)):
if self.map[x][y][z] == index+1 \
and [x,y,z] != list(self.line[index][0]) \
and [x,y,z] != list(self.line[index][1]):
self.map[x][y][z] = 0
def sortline(self, start, end, x, y, z):
""" 不明 使えるかもしれないので残しておく"""
length=len(x)
lines=np.append(np.append(x,y),z).reshape((3,length))
lines=lines.T
for i in range(1,length):
if np.equal(start,lines[i]).all():
lines[0],lines[i]=np.copy(lines[i]),np.copy(lines[0])
break
for i in range(0,len(x)-1):
if np.linalg.norm(lines[i]-lines[i+1])==1:continue
for j in range(i+2,len(x)):
if np.linalg.norm(lines[i]-lines[j])==1:
lines[j],lines[i+1]=np.copy(lines[i+1]),np.copy(lines[j])
break
lines=lines.T
x,y,z=lines[0],lines[1],lines[2]
return x,y,z
def print(self):
"""問題・解答をプリント """
self.printQ()
self.printA()
def printQ(self):
"""問題をプリント """
print(self.strQ())
def printA(self):
"""解答をプリント """
print(self.strA())
def strQ(self):
"""問題文字列を作成する"""
str=[]
str.append("SIZE %dX%dX%d\n" % (self.X, self.Y, self.Z))
str.append("LINE_NUM %d\n\n" % (self.n_line))
for i,line in enumerate(self.line):
str.append("LINE#%d (%d,%d,%d)%s(%d,%d,%d)\n" % (i+1, line[0][0], line[0][1], line[0][2]+1, random.choice([' ', '-']), line[1][0], line[1][1], line[1][2]+1))
return "".join(str)
def strA(self):
"""解答文字列を作成する"""
str=[]
str.append("SIZE %dX%dX%d\n" % (self.X, self.Y, self.Z))
for zm in range(self.Z):
z=zm+1
str.append("LAYER %d\n" % (z))
for y in range(self.Y):
for x in range(self.X-1):
str.append("%02d," % self.map[x][y][zm])
str.append("%d\n" % self.map[self.X-1][y][zm])
return "".join(str)
def save(self):
"""問題・解答をファイルとして保存する"""
self.saveQ()
self.saveA()
def saveQ(self):
"""問題をファイルとして保存する"""
filename="Q-"+self.name+".txt"
f=open(filename, 'w')
f.write(self.strQ())
f.close()
def saveA(self):
"""解答をファイルとして保存する"""
filename="A-"+self.name+".txt"
f=open(filename, 'w')
f.write(self.strA())
f.close()
def isregular(self, points):
"""self.mapの範囲内の座標だけを返す"""
a=np.all(points>=0,axis=1)
b=points[:,0]<self.X#0-col vector
c=points[:,1]<self.Y#1-col vector
d=points[:,2]<self.Z#2-col vector
e=a*b*c*d
return points[e]
def isblank(self, points):
"""空白"""
l=np.array([],dtype=bool)
for point in points:
if self.map[tuple(point)]==0:
l=np.append(l, True)
else:
l=np.append(l, False)
return points[l]
def istip(self, points):
l=np.array([],dtype=bool)
for point in points:
nlist=self.neighbour(point)
nlist=self.isregular(nlist)
sum=0
for n in nlist:
if self.map[tuple(n)]==self.n_line:
sum=sum+1
if sum>=2:
l=np.append(l,True)
else:
l=np.append(l,False)
return points[l==False]
def neighbour(self, point):
""" 与えられた座標をX,Y,Z方向に1移動させ, それら座標のリストを返す """
dlist=np.array([[0,0,-1], [0,0,1], [0,-1,0], [0,1,0], [-1,0,0], [1,0,0]])
nlist=point+dlist
return nlist
def addLine(self, maxlength):
MAXLOOP=1000
for i in range(MAXLOOP):
start=np.array([[random.randrange(self.X), random.randrange(self.Y), random.randrange(self.Z)]])
if len(self.isblank(start))!=0:break
else:
return False
self.n_line=self.n_line+1
point = start[0]
self.map[tuple(point)]=self.n_line
for i in range(maxlength):
points = self.neighbour(point)
points = self.isregular(points)
points = self.isblank(points)
points = self.istip(points)
if len(points)==0:
break
point=random.choice(points)
self.map[tuple(point)]=self.n_line
end=point
if np.array_equal(start[0],end):
self.map[tuple(end)]=0
self.n_line=self.n_line-1
return False
self.line=np.append(self.line, [[start[0], end]], axis=0)
return True
def optLine(self, n_line):
MAX=72*72*8
dlist=np.array([[0,0,-1], [0,0,1], [0,-1,0], [0,1,0], [-1,0,0], [1,0,0]])
self.map[self.map==n_line]=0
q=[]
heapq.heappush(q, (0, self.line[i][0], [0,0,0]))
while True:
if q == []:
break
(priority, point, direction) = heapq.heappop(q)
next_points=point+dlist
boollist=isregular(next_points)
for n, d in zip(next_points[boollist],dlist[boollist]):
if self.map[tuple(n)]!=0:continue
if len(isregular(next_point))==0:continue
if np.array_equal(direction, d):
i
def generate(self, linenum, maxlength):
self.name="".join([self.name,"_%d_%d" % (linenum, maxlength)])
for i in range(linenum):
self.addLine(maxlength)
#for i in range(self.n_line):
# self.optLine(i)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='NLGenerator')
parser.add_argument('--input', '-i', default=None, type=str,
help='Input file')
args = parser.parse_args()
m=MAP(args.input)
m.delLine(10-1)
m.print()
#m.save()
#m.saveQ()
#m.saveA()
#m.show()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment