Chuỗi hạt ngọc trai


18

Tổng quat

Pearls (hay Masyu) là một trò chơi logic được chơi trên lưới. Có những viên ngọc trai đen và trắng được đặt trên lưới. Đối tượng là tạo thành một vòng đơn, khép kín đi qua mỗi viên ngọc chỉ sử dụng các đoạn thẳng và góc vuông.

Có một số quy tắc chi phối cách vòng lặp tương tác với ngọc trai:

  • Ngọc trai trắng phải được đi thẳng qua, nhưng vòng lặp phải quay trong ô trước và / hoặc ô tiếp theo trên đường đi của nó.
  • Ngọc trai đen phải được bật , nhưng vòng lặp phải đi thẳng qua các tế bào tiếp theo trước đó trên đường đi của nó.
  • Vòng lặp không được vượt qua hoặc giao nhau. Tất cả các ô có chính xác không hoặc hai lần nhập / thoát vòng lặp.

Một câu đố ví dụ từ Wikipedia (và giải pháp của nó):

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Mục tiêu của bạn là để giải quyết một câu đố nhất định. Nếu có nhiều giải pháp khả thi, bạn đưa ra giải pháp nào không quan trọng.

Đầu vào

Đầu vào sẽ là một lưới vuông chưa giải quyết . Ví dụ hiển thị ở trên sẽ trông như thế này:

..w.w.....
....w...b.
..b.b.w...
...w..w...
b....w...w
..w....w..
..b...w...
w...b....w
......ww..
..b......b

wlà một viên ngọc trắng, blà một viên ngọc đen và .là một ô trống.

Giả sử đầu vào là hợp lệ. Điều này có nghĩa là nó được hình thành tốt, và ít nhất một giải pháp là có thể. Tất cả các câu đố hợp lệ ít nhất là 3x3 và chứa ít nhất một viên ngọc.

Đầu ra

Đầu ra là một chuỗi tọa độ đại diện cho đường dẫn. Góc trên bên trái của lưới là 0 0, phía trên bên phải là n-1 0, trong đó n là chiều rộng của lưới.

Một đường dẫn chỉ đơn giản là một chuỗi các tọa độ được sắp xếp:

x1 y1 x2 y2 x3 y3 ...

Đường dẫn được coi là đã đóng, vì vậy bạn không cần lặp lại tọa độ đầu tiên ở cuối, nhưng không có hình phạt nào cho việc đó.

Đầu ra phải bao gồm ít nhất tất cả các góc trong đường dẫn. Bạn không phải xuất mọi ô trên đường dẫn nếu không có ngã rẽ. Chẳng hạn, đầu ra cho ví dụ có thể bắt đầu bằng:

1 0 5 0 5 1 ...

hoặc là

1 0 2 0 3 0 4 0 5 0 5 1 ...

Đầu ra không được chứa bất kỳ ô nào không có trong đường dẫn. Bạn có thể bắt đầu tại bất kỳ ô nào trong đường dẫn.


Đoạn trích

Đây là một đoạn bạn có thể sử dụng để trực quan hóa giải pháp của mình. Chỉ cần dán vào lưới bạn đang làm việc và đường dẫn bạn xuất ra. Tôi biết rằng thật đau đớn khi xem mã của tôi, vì vậy tôi chỉ đề nghị bạn không nên;)


Các trường hợp thử nghiệm

Các trường hợp thử nghiệm này hiển thị một đầu ra có thể cho mỗi đầu vào (ngoại trừ đầu ra cuối cùng, được hiển thị chưa được giải quyết). Có thể có các đường dẫn hợp lệ khác, bạn có thể đi CW hoặc CCW hoặc bắt đầu ở một điểm khác, v.v. Các giải pháp sẽ có thể giải quyết các trường hợp thử nghiệm trong vài giây / phút / giờ, không phải ngày / tuần / giờ.

ngọc trai-3

...
w..
..b

0 0 1 0 2 0 2 1 2 2 1 2 0 2 0 1

ngọc trai-6

.wb..b
......
..b...
w.ww..
......
b....b

0 0 2 0 2 2 4 2 4 1 3 1 3 0 5 0 5 5 3 5 3 4 4 4 4 3 1 3 1 4 2 4 2 5 0 5 0 2 1 2 1 1 0 1

ngọc trai-12

.....w.b.w..
ww..b...b...
.w.....b....
...wbww..b.b
....b.......
w.w.........
..w......b.b
.....bb.....
.....b.....w
w.ww..b.....
...w......w.
b..w.....b..

Bạn đã không đặt giải pháp cho trường hợp thử nghiệm cuối cùng ...
mbomb007

2
@ mbomb007 Đúng.
Geobits

Vì vậy, không có giải pháp?
mbomb007

2
Có một giải pháp. Tôi để nó mở để câu trả lời sẽ có cái gì đó cho thấy nỗ lực của họ. Ngoài ra, nó có thể giúp giải một hoặc hai câu đố bằng tay để cảm nhận các quy tắc và điều đó khó thực hiện nếu tất cả các ví dụ được giải trước.
Geobits

Là lưới 2x2 hoặc lưới lớn hơn không có Ngọc trai được coi là hợp lệ (câu thứ hai cho thấy không, và điểm về đầu vào chưa được giải quyết (nếu không có ngọc trai chưa được xử lý, thì phải giải quyết)? Nếu vậy, bạn sẽ mong đợi một vòng lặp, chỉ không có ngọc trai trong đó, hoặc chính xác là gì? Có lẽ không có yêu cầu cho bất kỳ màu sắc cụ thể có mặt?
VisualMelon

Câu trả lời:


7

C, 590 640 760 880 963 1018

Lực lượng vũ phu là khá nhanh cho việc này. Thử nghiệm 12x12 chạy dưới 10ms. Biết rằng có thể lựa chọn một số ngôn ngữ phù hợp hơn để chơi gôn.

Tôi không cho rằng bảng là hình vuông vì các câu đố lớn hơn có xu hướng không vuông.

Định Wnghĩa đặt giới hạn cho kích thước bảng. Giới hạn thực tế nhỏ hơn W - 2khi tôi sử dụng các hàng bổ sung cho các đường viền để tránh kiểm tra ranh giới.

#define W 40
int Y,X,T,P,Q[W*W],D[]={-W,-1,1,W};char B[W*W],K[W*W],I[W];
t(x,d,s){for(P=0;B[x];x*=x!=*Q)s-=K[Q[P++]=x]-1,
d=(54202126527627840ll>>2*(d*7+B[x+=D[d]]%8))&3;return x?0:s;}
m(x){int c=K[x],u=B[x-W],U=u&7,l=B[x-1],L=l&7,r=0,
i=U!=3&U!=4&L!=2&L!=4,o=(39>>U)&1?57:70;o&=(52>>L)&1?42:85;
if(x/W>Y+1){for(;P--;)printf("%d %d ",Q[P]%W-1,Q[P]/W-1);exit(0);}
if(u>7)o&=U>4?~64:~6;if(l>7)o&=L>4?~32:~10;
for(o&=c?c>1?c>2?(r=8*i,96):(r=8,i*30):~0:1;o;r++,o/=2)
if(o&1)if(B[x]=r,r%8!=1||!t(x,0,T))m(x+1);B[x]=0;}
main(){for(;gets(I);Y++)for(X=0;I[X];X++)
T+=(K[X+1+Y*W+W]=I[X]/36)-1;m(W);}

Kiểm tra tôi .

Đây là một trường hợp thử nghiệm khó khăn hơn:

.b.....b.b.......b..
.....w.....b.w....w.
....w.........w.....
..bb.....w.w.b....b.
.w.....b..b......w..
.....b..............
.b..........b.b..bw.
....w....w....b...w.
.......bb...b...w...
..b.......w.........
....b.w.....w.b...b.
w...b...w..b.w.w....
b.w....w............
...b.w......b..b...b
w......w.b.ww.......
.b....b..........b..
....b....w.bb.w...w.
w..b......w...b.....
b.....w.........w...
...b....w..w..b...w.
...................b
.b..w..bb.b..b..w...
........w......b....
b....w......b..b.b..
...b..bb.w.w........
...b.......w......w.
w...w.b.w.....b....b
............w..ww...
..b.b..b....b.......
....b.........w...b.
.ww.......b.w.w.....
b.....w..w.w...b....
....ww..b.b.w....w.w
.............bb..w..
.b....w.b.b........w
....bw..........b...

Tôi đã may mắn mã của tôi tìm thấy giải pháp khá sớm trong quá trình chạy (<5 phút), nhưng việc tìm kiếm đầy đủ mất nhiều thời gian hơn (67 phút).

20x36


s / Lực lượng vũ trang khá nhanh / C khá nhanh /
kirbyfan64sos

9

Con trăn - 1669

Vẫn còn khá dài, nhưng đủ nhanh để chạy ví dụ cuối cùng trong một giây trên máy tính của tôi. Có thể rút ngắn hơn với chi phí tốc độ, nhưng hiện tại nó tương đương với mã không được mã hóa.

Ví dụ đầu ra cho trường hợp thử nghiệm cuối cùng:

0 11 1 11 2 11 3 11 4 11 4 10 3 10 2 10 1 10 1 9 2 9 3 9 4 9 4 8 3 8 3 7 4 7 5 7 5 6 5 5 6 5 6 6 6 7 7 7 8 7 8 8 7 8 6 8 5 8 5 9 5 10 5 11 6 11 6 10 6 9 7 9 8 9 8 10 7 10 7 11 8 11 9 11 9 10 9 9 10 9 10 10 10 11 11 11 11 10 11 9 11 8 11 7 10 7 10 8 9 8 9 7 9 6 10 6 11 6 11 5 11 4 11 3 10 3 9 3 9 4 9 5 8 5 8 4 8 3 8 2 8 1 9 1 10 1 10 0 9 0 8 0 7 0 7 1 7 2 6 2 5 2 5 1 6 1 6 0 5 0 4 0 3 0 2 0 2 1 3 1 4 1 4 2 4 3 5 3 6 3 7 3 7 4 6 4 5 4 4 4 4 5 4 6 3 6 3 5 3 4 3 3 3 2 2 2 2 3 1 3 1 2 1 1 1 0 0 0 0 1 0 2 0 3 0 4 0 5 0 6 1 6 1 5 1 4 2 4 2 5 2 6 2 7 1 7 1 8 0 8 0 9 0 10

nhập mô tả hình ảnh ở đây

Mã số:

I=raw_input().split('\n');X=len(I[0]);Y=len(I);R=range
def S(g=0,c=0,x=0,y=0):
    if y>=Y:return 0
    if g==0:g=[[-1]*X for i in R(Y)];c=[[-1]*X for i in R(Y)]
    o={'.':set(R(7)),'w':{1,2},'b':{3,4,5,6}}[I[y][x]].copy()
    o&={0,1,3,4}if y<1 or g[y-1][x]in[0,1,5,6]else{2,5,6}
    o&={0,2,4,5}if x<1 or g[y][x-1]in[0,2,3,6]else{1,3,6}
    if y>Y-2:o&={0,1,5,6}
    if x>X-2:o&={0,2,3,6}
    if y>0 and g[y-1][x]in[2,3,4]:
        if'b'==I[y][x]and g[y-1][x]!=2:return 0
        if'b'==I[y-1][x]:o&={2}
        elif'w'==I[y-1][x]and g[y-2][x]==2:o&={5,6}
    if x>0 and g[y][x-1]in[1,4,5]:
        if'b'==I[y][x]and g[y][x-1]!=1:return 0
        if'b'==I[y][x-1]:o&={1}
        elif'w'==I[y][x-1]and g[y][x-2]==1:o&={3,6}
    h=[r[:]for r in c]
    if y>0 and g[y-1][x]in[2,3,4]:
        if x>0 and g[y][x-1]in[1,4,5]:
            if c[y-1][x]==c[y][x-1]:
                if(6 not in o)+any(any(i!=c[y-1][x]and i!=-1 for i in r)for r in c)+any(I[v][u]!='.'and(v>y)+(u>x)for v in R(y,Y)for u in R(X)):return 0
                g[y][x]=6
                for v in R(y,Y):
                    for u in R(X):
                        if v!=y or u>x:g[v][u]=0
                for y in R(Y):
                    for x in R(X):
                        if g[y][x]>0:break
                f=[];d=-1;u,v=p,q=x,y
                while(u,v)!=(p,q)or-1==d:f+=[u,v];d=([0,{0,2},{1,3},{2,3},{0,3},{0,1},{1,2}][g[v][u]]-{(d+2)%4}).pop();i,j={0:(u+1,v),1:(u,v-1),2:(u-1,v),3:(u,v+1)}[d];u,v=i,j
                return f
            else:
                for v in R(y+1):
                    for u in R(X):
                        if h[v][u]==c[y][x-1]:h[v][u]=c[y-1][x]
                h[y][x]=c[y-1][x]
        else:h[y][x]=c[y-1][x]
    elif x>0 and g[y][x-1]in[1,4,5]:h[y][x]=c[y][x-1]
    else:h[y][x]=max(max(r)for r in c)+1
    for n in sorted(list(o))[::-1]:
        if n==0:h[y][x]=-1
        if x>X-2:i,j=0,y+1
        else:i,j=x+1,y
        g[y][x]=n;r=S(g,h,i,j)
        if r!=0:return r
    return 0
for i in S():print i,

Ung dung:

class Grid:
    def __init__(self,input):
        self.input = input.split('\n')
        self.x = len(self.input[0])
        self.y = len(self.input)
        self.options = {'.':{0,1,2,3,4,5,6},'w':{1,2},'b':{3,4,5,6}}

    def convert(self,grid):
        directions = [None,{0,2},{1,3},{2,3},{0,3},{0,1},{1,2}]

        for y in range(self.y):
            for x in range(self.x):
                if grid[y][x] != 0:
                    break

        chain = []
        start_pos = (x,y)
        dir = -1
        pos = start_pos
        while dir == -1 or pos != start_pos:
            chain.extend(pos)
            x,y = pos
            next_dir = (directions[grid[y][x]]-{(dir+2)%4}).pop()
            if next_dir == 0: nx,ny = x+1,y
            elif next_dir == 1: nx,ny = x,y-1
            elif next_dir == 2: nx,ny = x-1,y
            elif next_dir == 3: nx,ny = x,y+1
            dir = next_dir
            pos = (nx,ny)

        return chain

    def solve(self,grid=None,chain_ids=None,pos=(0,0)):
        x,y = pos
        if y >= self.y:
            return None

        if grid is None:
            grid = [[-1]*self.x for i in range(self.y)]
        if chain_ids is None:
            chain_ids = [[-1]*self.x for i in range(self.y)]

        options = self.options[self.input[y][x]].copy()
        if y == 0 or grid[y-1][x] in [0,1,5,6]:
            options &= {0,1,3,4}
        else:
            options &= {2,5,6}
        if y == self.y-1:
            options &= {0,1,5,6}

        if x == 0 or grid[y][x-1] in [0,2,3,6]:
            options &= {0,2,4,5}
        else:
            options &= {1,3,6}
        if x == self.x-1:
            options &= {0,2,3,6}

        if y != 0 and grid[y-1][x] in [2,3,4]:
            if self.input[y][x] == 'b' and grid[y-1][x] != 2:
                return None
            if self.input[y-1][x] == 'b':
                options &= {2}
            elif self.input[y-1][x] == 'w':
                if grid[y-2][x] == 2:
                    options &= {5,6}
        if x != 0 and grid[y][x-1] in [1,4,5]:
            if self.input[y][x] == 'b' and grid[y][x-1] != 1:
                return None
            if self.input[y][x-1] == 'b':
                options &= {1}
            elif self.input[y][x-1] == 'w':
                if grid[y][x-2] == 1:
                    options &= {3,6}


        new_chain_ids = [[i for i in row] for row in chain_ids]
        if y != 0 and grid[y-1][x] in [2,3,4]:
            if x != 0 and grid[y][x-1] in [1,4,5]:

                if chain_ids[y-1][x] == chain_ids[y][x-1]:
                    if 6 not in options:
                        return None

                    if any(any(i != chain_ids[y-1][x] and i != -1 for i in row) for row in chain_ids) or \
                    any(self.input[v][u] != '.' and (v!=y or u>x) for v in range(y,self.y) for u in range(self.x)):
                        return None

                    grid[y][x] = 6
                    for v in range(y,self.y):
                        for u in range(self.x):
                            if v != y or u > x: 
                                grid[v][u] = 0

                    return self.convert(grid)

                else:
                    for v in range(y+1):
                        for u in range(self.x):
                            if new_chain_ids[v][u] == chain_ids[y][x-1]:
                                new_chain_ids[v][u] = chain_ids[y-1][x]
                    new_chain_ids[y][x] = chain_ids[y-1][x]

            else:
                new_chain_ids[y][x] = chain_ids[y-1][x]
        elif x != 0 and grid[y][x-1] in [1,4,5]:
            new_chain_ids[y][x] = chain_ids[y][x-1]
        else:
            new_chain_ids[y][x] = max(max(row) for row in chain_ids)+1

        for n in sorted(list(options),key=lambda n: -n):
            grid[y][x] = n
            if n == 0:
                new_chain_ids[y][x] = -1

            if x == self.x-1:
                nx,ny = 0,y+1
            else:
                nx,ny = x+1,y

            result = self.solve(grid,new_chain_ids,(nx,ny))
            if result is not None:
                return result

input = """

.....w.b.w..
ww..b...b...
.w.....b....
...wbww..b.b
....b.......
w.w.........
..w......b.b
.....bb.....
.....b.....w
w.ww..b.....
...w......w.
b..w.....b..

""".strip()

def print_grid(grid):
    for y,row in enumerate(grid):
        s = ""
        for i in row:
            s += {-1:'xxx',0:'   ',1:'   ',2:' | ',3:'   ',4:'   ',5:' | ',6:' | '}[i]
        s += '\n'
        for x,i in enumerate(row):
            s += {-1:'x%sx',0:' %s ',1:'-%s-',2:' %s ',3:'-%s ',4:' %s-',5:' %s-',6:'-%s '}[i] % input.split('\n')[y][x]
        s += '\n'
        for i in row:
            s += {-1:'xxx',0:'   ',1:'   ',2:' | ',3:' | ',4:' | ',5:'   ',6:'   '}[i]
        s += '\n'
        print s

result = Grid(input).solve()
print result

@Geobits Ồ, có vẻ như tôi đã không đọc các quy tắc một cách cẩn thận. Câu trả lời được cập nhật với những gì tôi tin là chính xác ngay bây giờ
KSab

Con đường mới có vẻ tốt với tôi! +1
Geobits

1

Lua, 830 810 765 752 739 729 710

Chạy board1 và board2 chỉ tốt, nhưng mất một lúc trên board3.

Nó có thể tiết kiệm 9 byte bằng cách xuất ra mọi đường dẫn thay vì chỉ ...

b={}s={0,0,0}R=table.insert Z=unpack for l in io.lines()do w=#l for i=1,w do
c=({b=1,w=2,['.']=3})[l:sub(i,i)]R(b,c)s[c]=s[c]+1 end end h=#b/w for e=0,w*h-1
do function g(p,d,X,t)local function G(I,r)T={Z(t)}a=b[I+1]T[a]=T[a]+1
P={Z(p)}D={Z(d)}R(P,I%w)R(P,I/w-I/w%1)R(D,r)l=#D for U=2,#p,2 do if
I==p[U-1]+w*p[U]then return end end if I==e then if T[1]==s[1]and T[2]==s[2]then
for k=1,l do K=D[k]M=D[(k-2)%l+1]N=D[k%l+1]O=D[(k+1)%l+1]if({K==N or K~=M or
N~=O,K~=N or(K==M and N==O)})[b[1+P[2*k-1]+w*P[2*k]]]then return end end
os.exit(print(table.concat(P,' ')))end else g(P,D,I,T)end end _=X%w<w-1 and
G(X+1,1)_=X/w-X/w%1<h-1 and G(X+w,2)_=X%w>0 and G(X-1,3)_=X/w-X/w%1>0 and
G(X-w,4)end g({},{},e,{0,0,0})end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.