สร้างตัวสร้างตัวต่อปริศนา + ตัวแก้ปริศนา


13

ในTwitch Plays Pokémonหนึ่งในอุปสรรคที่น่ารำคาญที่สุดที่สามารถพบเจอได้คือปริศนาน้ำแข็งที่คุณต้องเดินทางจากที่หนึ่งไปยังอีกที่หนึ่งโดยเลื่อนไปตลอดทางในทิศทางเดียวจนกว่าคุณจะชนกำแพงหรือก้อนหิน

งานของคุณคือการสร้างโปรแกรมที่จะสร้างปริศนาน้ำแข็งสุ่มยาก

โปรแกรมของคุณจะยอมรับสามตัวเลขM, NและPเป็น input (มี10 <= M <= 30, 15 <= N <= 40และ0 <= P < 65536):

12 18

และจะส่งออก:

  • MโดยNตารางประกอบด้วย.และOคิดเป็นน้ำแข็งและหินตามลำดับ
  • เครื่องหมายบอกตำแหน่งที่เป็นตัวต่อปริศนา เครื่องหมายตำแหน่งนี้ประกอบด้วยตัวอักษรL, R, TหรือBคิดเป็นซ้ายขวาด้านบนและด้านล่างตามด้วยหมายเลขที่แสดงตำแหน่ง (จากด้านซ้ายหรือด้านบน) ในด้านที่จะป้อนจาก
  • เครื่องหมายตำแหน่งที่คล้ายกันซึ่งแสดงว่าตัวต่อออกจาก
  • วิธีการแก้ปัญหาที่สั้นที่สุดเพื่อปริศนาประกอบด้วยลำดับของL, R, UและDตามลำดับ

ตัวอย่างผลลัพธ์:

..O...O...........
............O.....
..O...............
.......O..........
..................
...........O......
O..O...........O..
..........O.......
..O..........O....
........O.........
O....O.........O..
............O.....
R 4
B 5
LDLDRULD
(Note that this output is actually invalid because it is not actually long enough.)

สำหรับอินพุทMและNทางออกของจิ๊กซอว์จะต้องมีอย่างน้อยmin(M, N)ขั้นตอนและย้าย2 (M + N)พื้นที่อย่างน้อยที่สุด (สำหรับการอ้างอิงปริศนาดังกล่าวข้างต้นจะย้ายทั้งหมด 12 ขั้นตอนการย้ายพื้นที่ 69.) ปริศนากำเนิดไฟฟ้าของคุณจะต้องสร้างที่แตกต่างกันMโดยNปริศนาที่มีเส้นทางการแก้ปัญหาที่แตกต่างกัน (เช่นลำดับที่แตกต่างกันของขั้นตอนในการแก้ปัญหาแต่ละ) Pสำหรับแต่ละเมล็ด

  • โปรดทราบว่าความต้องการของเส้นทางการแก้ปัญหาที่แตกต่างกันคือการแก้ปัญหาการหลีกเลี่ยงการที่พยายามที่จะสร้างระบบเส้นทางหินเช่นการแก้ปัญหา Claudiu ที่นี่ หากมีวิธีการแก้ปัญหาที่เหมือนกันสองหรือสามคู่เนื่องจากการเล่นโวหารในการสุ่มที่จะโอเคตราบใดที่โปรแกรมไม่ได้ตั้งใจที่จะพยายามสร้างปริศนาอย่างเป็นระบบด้วยการเคลื่อนที่แบบเดียวกัน

รหัสที่สั้นที่สุดที่จะทำดังกล่าวข้างต้นชนะ


2
ฉันไม่เข้าใจวัตถุประสงค์: "คุณต้องเดินทางจากที่หนึ่งไปอีกที่หนึ่งโดยเลื่อนไปตลอดทางในทิศทางเดียวจนกว่าคุณจะชนกำแพงหรือก้อนหิน" เป็นการดีที่จะตีกำแพงหรือก้อนหิน? คุณตั้งเป้าหมายที่จะไปตั้งแต่ต้นที่ไหน? หากคุณตีก้อนหินเกมจบลง? จะเกิดอะไรขึ้นเมื่อคุณชนกำแพง มันเป็นเพียงฉันหรือทิศทางที่ไม่ชัดเจน?
DavidC

3
โอ้ความทรงจำเก่า ๆ ของโปเกมอนโกลด์และซิลเวอร์ที่นี่ ค้นหาทางออกรับ HM07 แล้วไปที่เมือง Blackthorn
Victor Stafusa

3
นี้ทำให้ผมนึกถึงระดับน้ำแข็งในความท้าทายของชิป
luser droog

1
ทำไมไม่ใช้>และ<(หรืออักขระใด ๆ ) สำหรับการเข้าและออก? ปริศนาจะอ่านง่ายขึ้น
อัล

1
ที่จริงแล้วผลลัพธ์ตัวอย่างของคุณไม่ถูกต้อง - เส้นทางที่สั้นที่สุดคือLDLDRULDซึ่งมีความยาวเพียง 8 ขั้นตอน
Claudiu

คำตอบ:


5

Python, 672 548 ตัวละคร, ปริศนาที่น่าสนใจมากขึ้น

แม้ว่าจะทำตามกฎอย่างเคร่งครัด แต่โปรแกรม Python อื่น ๆ ของฉันชนะอันนี้ฉันตัดสินใจที่จะเขียนอันที่จะสร้างตัวต่อที่น่าสนใจมากกว่านี้ นี่มันคือ:

R=range;import random as J;X=J.randint
x=(0,1,-1,0);y=x[2:]+x
g=lambda r,c:(0<=r<H)+(0<=c<W)>1and f[r][c]or x[(r,c)in(A,E)]
l=lambda r,c:g(r+y[d],c+x[d])<1and(r,c)or l(r+y[d],c+x[d])
H,W,P=input();J.seed(P)
while 1:
 A=(-1,X(0,W));E=(H,X(0,W));f=[[X(0,7)for _ in R(W)]for _ in R(H)]
 q=[(A,'')];n=z={}
 while q and n!=E:
    n,O=q.pop()
    for d in R(4):
     N=l(*n)
     if g(n[0]+y[d],n[1]+x[d])and N not in z:q[:0]=[(N,O+"URLD"[d])];z[N]=1
 if(n==E)*len(O)>min(H,W):print"\n".join(''.join('O.'[c>0]for c in T)for T in f),"\nT",A[1],"\nB",E[1],"\n",O;break

ระดับการเยื้องคือช่องว่างแท็บแท็บ + ช่องว่าง

ตัวอย่าง :

$ echo [10,15,0] | python ice2.py
.....OO........
...............
...O....O.OO..O
...........O...
..O....O.......
.......O....O..
....O..........
.............O.
..............O
...............
T 1
B 10
DLURDRURULDRD

มันใช้Pเป็นเมล็ดดังนั้นแต่ละอันPจะสร้างตัวต่อที่เหมือนกันและแต่ละอันPมีแนวโน้มที่จะแตกต่างกันอย่างมาก:

$ echo [10,15,1] | python ice2.py
.OOO.O.........
...O......O.O.O
.......O.......
..O..........OO
.....O.........
.............O.
.O.............
.O............O
O....O.........
......O........
T 14
B 8
DLDRDLURULD

มันทำงานได้เร็วพอสมควรจนถึงขนาดของM=25,N=40อดีต แต่เมื่อก่อนมันจะช้ามาก ในทางทฤษฎีมันควรจะทำงานM=30, N=40ถ้าคุณปล่อยให้มันทำงานได้นานพอ ฉันเขียนด้วยตนเองในเส้นทางที่นี่เนื่องจากมันยากที่จะติดตาม - โปรแกรมเพิ่งสร้างตัวต่อ

$ echo [25,40,0] | python ice2.py
                   *
...................dO....urrrO..O..O....
....O.....O........dO....u..dO..........
..........O.....O..d....Ou.Odrrrrrrrrrrr
...........O.......d.O..Ou..O.....OOllld
.O....O.OO.........drrrrrrO....Olllud..O
O......O...O.O.....O............dO.ud...
O........OO..........O.........Od..ud..O
.........O......................d..ud...
....O.....O.O....O.....O........d..ud.O.
.....O..O...................O...d..udO..
.........O.........O..O.........d..ud...
.......O.O...O..O.OO....O...OOlldOOld...
........Olllllllllu....OO.OO..dOO...O...
.O.O....Od........u......O....d..O...O..
..O....O.d........u..O........d..O..O...
....O....d..O.....uO.....O....d.........
.........d........u...........d.........
.........d....O...u.O..O.....Od.O.......
........Od...O....u...........d.........
.O.....OuxrrrrO...u...OOOO..O.d.........
........udO..dO.O.u...........d.........
O..O.O..ud...d..urrO..........d.O...O...
........ud...d..u.O.O........Od..O...O..
..OO....ud..Od..u......OllllludO.....O..
..O....OldO..dOOlllllllld...Old...O..O..
             *
T 19
B 13
DRURDRDLDLULDLDLULDLURULDLURD

คำอธิบาย :

โปรแกรมวนซ้ำสร้างตำแหน่งเริ่มต้นแบบสุ่มที่ด้านบนตำแหน่งสิ้นสุดแบบสุ่มที่ด้านล่างและตารางแบบสุ่มที่มี12.5%โอกาสสำหรับก้อนหินที่จุดใด ๆ จากนั้นจะไขปริศนาด้วยการค้นหาแบบกว้างแรกและหากวิธีแก้ปัญหานั้นมีอยู่และใหญ่กว่าmin(H,W)ก็จะพิมพ์และออก


4

Java - 2632

ในขณะที่ฉันชื่นชมความบริสุทธิ์ทางเทคนิคของคำตอบของ Claudiuฉันตัดสินใจลองทำปริศนาที่ยากขึ้นเล็กน้อย ;)

ขั้นตอนพื้นฐาน (เรียบง่าย):

Randomize entry location
Step forward
For min(m,n)-1 steps:
    Rotate left or right
    Slide until I hit something or go a random distance
    Place a rock in front of stopping location
If I can slide straight to any wall:
    Slide to exit
Else
    Create another step and try again

If at any step I get trapped, start over
If BFS finds shorter path, start over

ฉันยังทำเครื่องหมายแต่ละจุดว่า 'nogo' ในขณะที่ฉันเลื่อน ถ้าฉันจบลงที่จุด nogo (หรืออยู่ด้านหน้าหนึ่งซึ่งหมายความว่าหินกำลังจะไปที่นั่น) มันเป็นขั้นตอนที่ไม่ถูกต้อง

ดังนั้นโดยพื้นฐานแล้วความคิดคือการสุ่มสร้างแผนที่จำนวนมากและเก็บแผนที่แรกที่ถูกต้อง ฉันวางแผนที่จะทำให้ชาญฉลาดขึ้น (การย้อนรอย ฯลฯ ) แต่มันใช้ได้ดีในขณะนี้ นอกจากนี้ยังอาจลดรหัสซ้ำซ้อนบางรายการที่เราจะเห็น

ตามที่เป็นอยู่มันสร้างแผนที่ขนาดเล็ก (15x10) เกือบจะทันทีแผนที่ขนาดกลาง (30x20) ในไม่กี่วินาทีและใหญ่ (40x30) ในระยะเวลาสุ่มระหว่าง 20 วินาทีถึง 20 นาทีขึ้นอยู่กับเมล็ด มันทดสอบระหว่าง 300k-500k maps / วินาทีบนเครื่องของฉันขึ้นอยู่กับขนาด

หมายเหตุด้านข้าง: บางครั้งแผนที่ไม่ยากเกินไปเพียงเพราะมีโขดหินเพียงไม่กี่ก้าวเท่านั้นเว้นแต่ว่าขั้นตอนนำคุณไปสู่กำแพงส่วนใหญ่มีเพียงตัวเลือกเดียวถ้าคุณต้องการตีหินจริง ฉันจะแก้ไขได้ในภายหลังโดยวางหิน "สุ่ม" ในจุดที่ปลอดภัยหลังจากทำตามขั้นตอนทั้งหมดแล้ว เนื่องจากมีจุด nogo ที่ทำเครื่องหมายไว้แล้วนั่นน่าจะง่าย สำหรับตอนนี้เพียงแค่สนุกกับตัวอย่างเหล่านี้:

ผลผลิตแสดงขนาดต่าง ๆ / เมล็ด:

$ java I 30 20 6851              $ java I 15 10 1     $ java I 15 10 65513  

............................O.      .......O.......     ....O..........     
..............................      ...............     ...............     
..............................      .........O.....     .........O.....     
..........O......O............      .............O.     ..............O     
...............O...........O..      ...............     ...............     
..............................      .......O.......     .....O.O.......     
..............................      O..............     ...............     
........................O.....      ...............     ..........O....     
..............................      ...............     O..............     
...O.......................O..      ......O........     ...............     
O...............O.OO..........          
..............O..........O....          
...........O..................      T 14                R 6         
....O.........................      T 7                 T 14            
..............................      DLDLULURU           LULDLDRURU
..............................
..............................
.................O............
.O............................
..............................


B 28
R 9
ULURDLDLDRURDLDRURUR

ขนาดสูงสุด 40x30:

$ java I 40 30 2

........................................
........................................
........................................
........................................
................O.......................
..........O.............................
........................................
.......O................................
.....................O..........O.......
......................O.................
.................................O......
......................................O.
........................................
........................................
..............................O.........
...........O............................
........................................
.......................................O
.........O...................O..........
....................O...................
...............................O........
............O..O......................O.
......O...........O.....................
..................O....O................
..................................O.....
........................................
..............................O.........
.....................................O..
...........O............................
...................O....................

B 19
B 11
URURDLULULDRDRDLULDLDLULURDLD

แข็งแรงเล่นกอล์ฟ:

import java.util.*;import java.awt.*;class I{int m,n,p,g,a[][],b[][];Random r;Point s,e,c;ArrayList<Integer>z;void Q(String q,int l){if(l>0)System.out.println(q);else System.out.print(q);}void G(String[]y){m=Integer.valueOf(y[0]);n=Integer.valueOf(y[1]);p=Integer.valueOf(y[2]);r=new Random(p);Q("",1);int o=0,i,j,u=0;char t,f[]={85,76,68,82};while(o<3){if(++u%20000==0)Q("\r#"+u,0);a=new int[m+2][n+2];b=new int[m+2][n+2];for(i=0;i<m+2;i++)for(j=0;j<n+2;j++)if(i==0||i==m+1||j==0||j==n+1)a[i][j]=2;s=new Point();int e=r.nextInt(m*2+n*2);if(e<m*2){s.x=e%m+1;s.y=e<m?0:n+1;}else{s.y=(e-m*2)%n+1;s.x=(e-m*2)<n?0:m+1;}if(s.x<1)g=3;else if(s.x>m)g=1;else if(s.y<1)g=2;else if(s.y>n)g=0;a[s.x][s.y]=0;c=new Point(s);z=new ArrayList<Integer>();z.add(g);for(i=0;i++<Math.min(m,n)-1;)if(N()<1&&N()<1)break;o=((z.size()>=Math.min(m,n)-1)?1:0)+F()+((V()==z.size())?1:0);}Q("\r",0);for(j=1;j<n+1;j++){for(i=1;i<m+1;i++)Q(String.valueOf(a[i][j]>0?'O':'.'),0);Q("",1);}Q("\n\n",0);if(s.x<1||s.x>m){t=s.x<1?'L':'R';u=s.y;}else{t=s.y<1?'T':'B';u=s.x;}Q(t+" "+u,1);if(e.x<1||e.x>m){t=e.x<1?'L':'R';u=e.y;}else{t=e.y<1?'T':'B';u=e.x;}Q(t+" "+u,1);for(i=0;i<z.size();)Q(String.valueOf(f[z.get(i++)]),0);Q("",1);}public static void main(String[]a){new I().G(a);}int F(){int c=0;while(C()<1&&c++<10)if(N()<1)return 0;return e==null?0:1;}int C(){int d=g<2?-1:1;if(g%2<1){int y=c.y;while(y>0&&y<n+1){y+=d;if(a[c.x][y]==1)return 0;}e=new Point(c.x,y);}else{int x=c.x;while(x>0&&x<m+1){x+=d;if(a[x][c.y]==1)return 0;}e=new Point(x,c.y);}a[e.x][e.y]=0;return 1;}int V(){if((s.x-e.x)+(s.y-e.y)<2)return 0;Queue<Point>q=new ArrayDeque<Point>();Queue<Integer>d=new ArrayDeque<Integer>();a[s.x][s.y]=-2;q.add(s);d.add(0);while(q.size()>0){Point t=q.poll();int h=d.poll(),i=0;if(t.equals(e))return h;for(;i<4;i++){Point n=S(a,t,i<2?0:1,i%2<1?-1:1,99,1);if(a[n.x][n.y]==-2)continue;a[n.x][n.y]=-2;q.add(n);d.add(h+1);}}return 0;}int N(){Point q;int d=g<2?-1:1,x,y;System.arraycopy(a,0,b,0,a.length);q=S(b,c,g,d,r.nextInt((g%2<1?n:m)/2)+2,0);if(q.x<1||q.y<1||q.x>m||q.y>n||q.equals(c)||b[q.x][q.y]!=0)return 0;x=q.x;y=q.y;if(g%2<1)y+=d;else x+=d;if(b[x][y]<0)return 0;b[q.x][q.y]=-1;b[x][y]=1;int f=r.nextInt(2)<1?-1:1;g=g%2<1?(f<0?1:3):(g=f<0?0:2);c=q;System.arraycopy(b,0,a,0,a.length);z.add(g);return 1;}Point S(int[][]u,Point f,int w,int d,int q,int s){int i=1,x=f.x,y=f.y;for(;i<=q;i++){if(w%2<1)y=f.y+i*d;else x=f.x+i*d;if(e!=null&&e.x==x&&e.y==y)return e;if(y<0||y>n+1||x<0||x>m+1)return f;if(s<1&&u[x][y]<1)u[x][y]=-1;if(u[x][y]>0){if(w%2<1)y-=d;else x-=d;return new Point(x,y);}}if(w%2<1)return new Point(f.x,f.y+i*d);else return new Point(f.x+i*d,f.y);}}

ด้วยตัวแบ่งบรรทัด:

import java.util.*;
import java.awt.*;

class I{
    int m,n,p,g,a[][],b[][];
    Random r;
    Point s,e,c;
    ArrayList<Integer>z;

    void Q(String q,int l){if(l>0)System.out.println(q);else System.out.print(q);}

    void G(String[]y){
        m=Integer.valueOf(y[0]);
        n=Integer.valueOf(y[1]);
        p=Integer.valueOf(y[2]);
        r=new Random(p);
        Q("",1);

        int o=0,i,j,u=0;
        char t,f[]={85,76,68,82};
        while(o<3){
            if(++u%20000==0)
                Q("\r#"+u,0);

            a=new int[m+2][n+2];
            b=new int[m+2][n+2];
            for(i=0;i<m+2;i++)
                for(j=0;j<n+2;j++)
                    if(i==0||i==m+1||j==0||j==n+1)
                        a[i][j]=2;

            s=new Point(); 
            int e=r.nextInt(m*2+n*2);
            if(e<m*2){
                s.x=e%m+1;
                s.y=e<m?0:n+1;
            }else{
                s.y=(e-m*2)%n+1;
                s.x=(e-m*2)<n?0:m+1;
            }
            if(s.x<1)g=3;
            else if(s.x>m)g=1;
            else if(s.y<1)g=2;
            else if(s.y>n)g=0;

            a[s.x][s.y]=0;
            c=new Point(s);
            z=new ArrayList<Integer>();
            z.add(g);

            for(i=0;i++<Math.min(m,n)-1;)
                if(N()<1&&N()<1)
                        break;
            o=((z.size()>=Math.min(m,n)-1)?1:0)+F()+((V()==z.size())?1:0);
        }

        Q("\r",0);
        for(j=1;j<n+1;j++){
            for(i=1;i<m+1;i++)
                Q(String.valueOf(a[i][j]>0?'O':'.'),0);
            Q("",1);
        }
        Q("\n\n",0);
        if(s.x<1||s.x>m){
            t=s.x<1?'L':'R';
            u=s.y;
        }else{
            t=s.y<1?'T':'B';
            u=s.x;
        }
        Q(t+" "+u,1);
        if(e.x<1||e.x>m){
            t=e.x<1?'L':'R';
            u=e.y;
        } else {
            t=e.y<1?'T':'B';
            u=e.x;
        }
        Q(t+" "+u,1);
        for(i=0;i<z.size();)
            Q(String.valueOf(f[z.get(i++)]),0);
        Q("",1);
    }

    public static void main(String[]a){
        new I().G(a);
    }

    int F(){
        int c=0;
        while(C()<1&&c++<10)
            if(N()<1)
                return 0;
        return e==null?0:1;
    }

    int C(){
        int d=g<2?-1:1;
        if(g%2<1){
            int y=c.y;
            while(y>0&&y<n+1){
                y+=d;
                if(a[c.x][y]==1)
                    return 0;
            }
            e=new Point(c.x,y);
        }else{
            int x=c.x;
            while(x>0&&x<m+1){
                x+=d;
                if(a[x][c.y]==1)
                    return 0;
            }
            e=new Point(x,c.y);
        }
        a[e.x][e.y]=0;
        return 1;
    }


    int V(){
        if((s.x-e.x)+(s.y-e.y)<2)
            return 0;
        Queue<Point>q=new ArrayDeque<Point>();
        Queue<Integer>d=new ArrayDeque<Integer>();
        a[s.x][s.y]=-2;

        q.add(s);
        d.add(0);
        while(q.size()>0){
            Point t=q.poll();
            int h=d.poll(),i=0;
            if(t.equals(e))
                return h;
            for(;i<4;i++){
                Point n=S(a,t,i<2?0:1,i%2<1?-1:1,99,1);
                if(a[n.x][n.y]==-2)
                    continue;
                a[n.x][n.y]=-2;
                q.add(n);d.add(h+1);
            }
        }
        return 0;
    }


    int N(){
        Point q;
        int d=g<2?-1:1,x,y;
        System.arraycopy(a,0,b,0,a.length);
        q=S(b,c,g,d,r.nextInt((g%2<1?n:m)/2)+2,0);      
        if(q.x<1||q.y<1||q.x>m||q.y>n||q.equals(c)||b[q.x][q.y]!=0)
            return 0;
        x=q.x;
        y=q.y;
        if(g%2<1)
            y+=d;
        else
            x+=d;
        if(b[x][y]<0)
            return 0;
        b[q.x][q.y]=-1;
        b[x][y]=1;
        int f=r.nextInt(2)<1?-1:1;          
        g=g%2<1?(f<0?1:3):(g=f<0?0:2);
        c=q;
        System.arraycopy(b,0,a,0,a.length);
        z.add(g);
        return 1;
    }

    Point S(int[][]u,Point f,int w,int d,int q,int s){
        int i=1,x=f.x,y=f.y;
        for(;i<=q;i++){
            if(w%2<1)
                y=f.y+i*d;
            else
                x=f.x+i*d;
            if(e!=null&&e.x==x&&e.y==y)
                return e;
            if(y<0||y>n+1||x<0||x>m+1)
                return f;
            if(s<1&&u[x][y]<1)
                u[x][y]=-1;
            if(u[x][y]>0){
                if(w%2<1)
                    y-=d;
                else
                    x-=d;
                return new Point(x,y);
            }
        }
        if(w%2<1)
            return new Point(f.x,f.y+i*d);
        else
            return new Point(f.x+i*d,f.y);              
    }
}

ไม่while(o<3){...;o=...;}สามารถfor(;o<3;o=...){...;}บันทึกหนึ่งไบต์ได้ใช่ไหม
Jonathan Frech

if(w%2<1)return new Point(f.x,f.y+i*d);else return new Point(f.x+i*d,f.y);return new Point(f.x+(w%2<1?0:i*d),f.y+(w%2<1?f.y:0));->
Jonathan Frech

3

Python, 235 206 185 176 ตัวอักษร

H,W,P=input()
t=''
for x in range(16):t+=".O"[(P>>x)%2]
for n in[t[1:],t[0],"O","...O"]+["."]*(H-5)+[".O.."]:print(n*W)[:W]
print"B 1\nR",(H,3)[-W%4/2],"\n",("URDR"*W)[:W+W%2]

การใช้งาน :

การป้อนข้อมูลผ่าน stdin [M, N, P]ของแบบฟอร์ม

$ echo [14, 17, 2] | python ice.py
O..............O.
.................
OOOOOOOOOOOOOOOOO
...O...O...O...O.
.................
.................
.................
.................
.................
.................
.................
.................
.................
.O...O...O...O...
B 1
R 3
URDRURDRURDRURDRUR

คุณบอกว่าแผนที่จะต้องแตกต่างกันไปในแต่ละเมล็ดP... และมันคือ:

$ echo [14, 17, 233] | python ice.py
..O.OOO..........
OOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOO
...O...O...O...O.
.................
.................
.................
.................
.................
.................
.................
.................
.................
.O...O...O...O...
B 1
R 3
URDRURDRURDRURDRUR
$ echo [14, 17, 65133] | python ice.py
.OO.OO..OOOOOOO.O
OOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOO
...O...O...O...O.
.................
.................
.................
.................
.................
.................
.................
.................
.................
.O...O...O...O...
B 1
R 3
URDRURDRURDRURDRUR

และตัวอย่างที่มีขนาดแตกต่างกัน:

$ echo [10, 15, 65133] | python ice.py
.OO.OO..OOOOOOO
OOOOOOOOOOOOOOO
OOOOOOOOOOOOOOO
...O...O...O...
...............
...............
...............
...............
...............
.O...O...O...O.
B 1
R 10
URDRURDRURDRURDR

เป็นไปตามเกณฑ์วัตถุประสงค์ที่ให้มาทั้งหมด:

  • แต่ละคนPนำไปสู่ปริศนาที่แตกต่างกัน
  • มีวิธีแก้ปัญหาเพียงวิธีเดียวเท่านั้นจึงเป็นวิธีที่สั้นที่สุด
  • วิธีการแก้ปัญหาใช้N + N%2ขั้นตอนซึ่งเป็นอย่างน้อยN
  • การแก้ปัญหาใช้เวลามากกว่า2 (M + N)พื้นที่ทั้งหมดเสมอ

คำอธิบาย :

แต่ละแถวถูกสร้างขึ้นโดยการทำซ้ำองค์ประกอบสตริงบางWครั้งและจำกัดความยาวไว้ที่W(ฉันใช้HและWแทนMและN)

สองแถวแรกขึ้นอยู่กับPการทำให้ปริศนาแต่ละตัวไม่ซ้ำกัน โดยทั่วไปให้สังเกตว่าPเหมาะกับจำนวนเต็ม 16 บิตที่ไม่ได้ลงชื่อ ฉันแปลงPเป็นไบนารี่โดยใช้.0 และO1:

t=''
for x in range(16):t+=".O"[(P>>x)%2]

องค์ประกอบแถวแรกเป็นช่วง 15 บิตส่วนแถวที่สองคือบิตที่t[1:] 1 t[0]ฉันไม่สามารถวางมันทั้งหมดในหนึ่งแถวเพราะความกว้างต่ำสุดคือ 15 ซึ่งจะไม่พอดีทั้งหมด 16 บิตถ้าP> 32767 Pดังนั้นสองแถวแรกที่ไม่ซ้ำกันเป็นตัวแทนของแต่ละค่าเป็นไปได้ของ

แถวที่สามเป็นกำแพงเต็มเพื่อให้ค่าของPไม่มีผลต่อการแก้ปัญหา

จากนั้นทำตามองค์ประกอบเขาวงกตที่เกิดขึ้นจริง บรรทัดนี้พิมพ์พวกเขาทั้งหมดซ้ำไปจนถึงฝาปิด ผลลัพธ์จะเป็นดังที่คุณเห็นด้านบน:

for n in[t[1:],t[0],"O","O..."]+["."]*(H-5)+["..O."]:print(n*W)[:W]

ที่เหลือก็แค่หาวิธีแก้เขาวงกตที่สร้างขึ้นแบบไดนามิก ขึ้นอยู่กับความกว้างของเขาวงกตเท่านั้น ฉันตั้งข้อสังเกตว่าการแก้ปัญหาสำหรับความกว้างที่กำหนดคือ:

  W  | solution 
-----+---------
  1  | UR
  2  | UR
  3  | UR DR
  4  | UR DR 
  5  | UR DR UR
  6  | UR DR UR
  7  | UR DR UR DR
  8  | UR DR UR DR

เป็นต้นดังนั้นมันจึงถูกURDRทำซ้ำและถูกตัดในตำแหน่งที่ถูกต้องW+W%2.

print"B 1\nR",(H,3,3,H)[W%4],"\n",("URDR"*W)[:W+W%2]

1
วิธีการที่เป็นจำนวนเต็มบิตที่ 33 ทำงานอย่างไร
masterX244

@ masterX244: การเล่นกอล์ฟจำนวนมาก ... โดยทั่วไปจะใช้ประโยชน์จากลักษณะที่ซ้ำ ๆ ของการส่งออกและทำคณิตศาสตร์เพื่อให้แน่ใจว่าทุกอย่างสอดคล้องกันอย่างเหมาะสม
Claudiu

ส่วนใหญ่สงสัยเกี่ยวกับวิธีการทำ "randomness" (PS downvote ไม่ได้มาจากฉัน)
masterX244

@ masterX244: อา gotcha ฉันจะเพิ่มคำอธิบาย
Claudiu

1
ฉันไม่ได้ตั้งใจในทางลบ มันฉลาดแน่นอนฉันแค่หวังว่าเกม devs ที่ต้องการจะไม่ใช้สิ่งนี้กับปริศนาที่เกิดขึ้นจริง: p
Geobits
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.