From 55ace4962c95bb98239090307398fb417d664571 Mon Sep 17 00:00:00 2001 From: Tawada Date: Wed, 8 Aug 2018 16:33:47 +0900 Subject: [PATCH] Add resolver --- resolver/Makefile | 19 ++++ resolver/resolver.py | 261 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+) create mode 100644 resolver/Makefile create mode 100644 resolver/resolver.py diff --git a/resolver/Makefile b/resolver/Makefile new file mode 100644 index 0000000..635597e --- /dev/null +++ b/resolver/Makefile @@ -0,0 +1,19 @@ +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) diff --git a/resolver/resolver.py b/resolver/resolver.py new file mode 100644 index 0000000..4659226 --- /dev/null +++ b/resolver/resolver.py @@ -0,0 +1,261 @@ +#!/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]=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() + -- 2.22.0