เขาวงกตไม่มีที่สิ้นสุด


35

พื้นหลัง

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

อินพุต

อินพุตของคุณคือตารางสองมิติของช่วงเวลา.และแฮช#แสดงถึงพื้นที่ว่างและกำแพงซึ่งกำหนดเป็นสตริงที่คั่นด้วยบรรทัดใหม่ จะมีอย่างน้อยหนึ่ง.และหนึ่ง#และคุณสามารถตัดสินใจได้ว่ามีการขึ้นบรรทัดใหม่หรือไม่

กริดนี้เป็นพิมพ์เขียวของเขาวงกตที่ไม่มีที่สิ้นสุดซึ่งสร้างขึ้นโดยการจัดตำแหน่งกริดจำนวนมากที่อยู่ติดกัน เขาวงกตแบ่งออกเป็นช่องว่างซึ่งเป็นส่วนประกอบที่เชื่อมต่อกับพื้นที่ว่าง (ช่องว่างที่อยู่ติดกันในแนวทแยงมุมไม่ได้เชื่อมต่อ) ตัวอย่างเช่นตาราง

##.####
...##..
#..#..#
####..#
##...##

ส่งผลให้เขาวงกตต่อไปนี้ (ต่อไปอย่างไม่มีที่สิ้นสุดในทุกทิศทาง):

##.######.######.####
...##.....##.....##..
#..#..##..#..##..#..#
####..#####..#####..#
##...####...####...##
##.######.######.####
...##.....##.....##..
#..#..##..#..##..#..#
####..#####..#####..#
##...####...####...##
##.######.######.####
...##.....##.....##..
#..#..##..#..##..#..#
####..#####..#####..#
##...####...####...##

เขาวงกตนี้โดยเฉพาะมีโพรงของพื้นที่ไม่มีที่สิ้นสุด ในทางตรงกันข้ามพิมพ์เขียวนี้ส่งผลให้เขาวงกตที่มีเพียงช่องว่างที่ จำกัด :

##.####
##..###
####...
..####.
#..####

เอาท์พุต

ผลลัพธ์ของคุณจะเป็นค่าความจริงหากเขาวงกตมีช่องที่ไม่มีที่สิ้นสุดและค่าเท็จถ้าไม่ โปรดทราบว่าเขาวงกตอาจมีทั้งช่อง จำกัด และช่องว่างไม่ จำกัด ในกรณีนั้นผลลัพธ์จะเป็นจริง

กฎระเบียบ

คุณสามารถเขียนโปรแกรมเต็มรูปแบบหรือฟังก์ชั่น จำนวนไบต์ต่ำสุดที่ชนะและช่องโหว่มาตรฐานไม่ได้รับอนุญาต

กรณีทดสอบเพิ่มเติม

ฟันผุอนันต์:

.#

#.#
...
#.#

#.###.#.###.#
#.#...#...#.#
#.#.#####.#.#
..#.#...#.#..
###.#.#.#.###
#...#.#.#...#
#.###.#.###.#

##.###
#..###
..##..
###..#
##..##

..#..#..#..#..#..#
.#..#..#..#..#..#.
#..#..#..#..#..#..

#.####.###.###.####
#...#..#...###..###
###.#..#.######..##
....####.#######...
###..###...########
##########.##....##
..###......##.##...
#.........##..#####
###########..###..#
#...........####..#
#.###########.##..#
#.##....##.....####
#.####.###.###.####

ฟันผุ จำกัด :

###
#.#
###

.#
#.

####
.#..
####

#.#.#
..#..
#####
..#..
#.#.#

#.#.#.#.#.#
..#...#.#..
###.###.###
..#.#......
#.#.#######
#.#.......#
#.#######.#
#.#.....#.#
#.#.#.#.#.#

##....#####
.#..#...##.
.##.#..#...
..###.###..
#..##.#####
#...##....#
#.#.#####.#
###..####.#
....####...
###...#####

###....##.#########
####...##....#...##
..####.#######.###.
....##..........##.
###..#####.#..##...
####..#..#....#..##
..###.####.#.#..##.
..###...#....#.#...
..####..##.###...##
#.####.##..#####.##
####...##.#####..##


###########
........#..
#########.#
..........#
.##########
.#.........
##.########
...#.......

มีอักขระขึ้นบรรทัดใหม่ที่ต่อท้ายหรือไม่
FUZxxl

@FUZxxl ขึ้นอยู่กับคุณ
Zgarb

เขาวงกตที่ไม่มีที่สิ้นสุดสามารถเป็นเส้นตรงที่ไปยังอินฟินิตี้ได้หรือไม่

1
@ ไม่มีฉันไม่แน่ใจว่าคุณหมายถึงอะไร ตัวอย่างที่ไม่มีที่สิ้นสุดแรกและที่สองมีเส้นที่ไม่มีที่สิ้นสุด แต่มีอย่างน้อยหนึ่ง.และหนึ่ง#ในการป้อนข้อมูล
Zgarb

1
ความท้าทายดีมากยากกว่าที่คิด
edc65

คำตอบ:


2

JavaScript (ES6), 235 253

วิธีการเดียวกับที่ใช้โดย @mac สำหรับเซลล์ว่างแต่ละเซลล์ฉันลองเติมซ้ำโดยทำเครื่องหมายเซลล์ที่ใช้ด้วยพิกัดที่ฉันใช้ (ซึ่งอาจอยู่นอกเทมเพลตเดิม) หากในระหว่างการเติมฉันมาถึงเซลล์ที่ระบุว่ามีพิกัดที่แตกต่างกันฉันอยู่ในเส้นทางที่ไม่มีที่สิ้นสุด

วิธีการเล่นโวหารของการจัดการแบบโมดูโลใน JS มันเป็นที่น่ารำคาญมาก

L=g=>(
  g=g.split('\n').map(r=>[...r]),
  w=g[0].length,h=g.length,
  F=(x,y,t=((x%w)+w)%w,u=((y%h)+h)%h,v=g[u][t],k=0+[x,y])=>
    v<'.'?0:v>'.'?v!=k
    :[0,2,-3,5].some(n=>F(x+(n&3)-1,y+(n>>2)),g[u][t]=k),
  g.some((r,y)=>r.some((c,x)=>c=='.'&&F(x,y)))
)

ทดสอบในคอนโซล Firefox / FireBug

อนันต์

['##.###\n#..###\n..##..\n###..#\n##..##'
,'#.#\n...\n#.#'
,'#.###.#.###.#\n#.#...#...#.#\n#.#.#####.#.#\n..#.#...#.#..\n###.#.#.#.###\n#...#.#.#...#\n#.###.#.###.#'
,'##.###\n#..###\n..##..\n###..#\n##..##'
,'#.####.###.###.####\n#...#..#...###..###\n###.#..#.######..##\n....####.#######...\n###..###...########\n##########.##....##\n..###......##.##...\n#.........##..#####\n###########..###..#\n#...........####..#\n#.###########.##..#\n#.##....##.....####\n#.####.###.###.####'
].forEach(g=>console.log(g,L(g)))

เอาท์พุต

"##.###
#..###
..##..
###..#
##..##" true

"#.#
...
#.#" true

"#.###.#.###.#
#.#...#...#.#
#.#.#####.#.#
..#.#...#.#..
###.#.#.#.###
#...#.#.#...#
#.###.#.###.#" true

"##.###
#..###
..##..
###..#
##..##" true

"#.####.###.###.####
#...#..#...###..###
###.#..#.######..##
....####.#######...
###..###...########
##########.##....##
..###......##.##...
#.........##..#####
###########..###..#
#...........####..#
#.###########.##..#
#.##....##.....####
#.####.###.###.####" true

จำกัด

['###\n#.#\n###', '.#\n#.', '####\n.#..\n####'
,'#.#.#\n..#..\n#####\n..#..\n#.#.#'
,'#.#.#.#.#.#\n..#...#.#..\n###.###.###\n..#.#......\n#.#.#######\n#.#.......#\n#.#######.#\n#.#.....#.#\n#.#.#.#.#.#'
,'##....#####\n.#..#...##.\n.##.#..#...\n..###.###..\n#..##.#####\n#...##....#\n#.#.#####.#\n###..####.#\n....####...\n###...#####'
,'###....##.#########\n####...##....#...##\n..####.#######.###.\n....##..........##.\n###..#####.#..##...\n####..#..#....#..##\n..###.####.#.#..##.\n..###...#....#.#...\n..####..##.###...##\n#.####.##..#####.##\n####...##.#####..##'
].forEach(g=>console.log(g,L(g)))

เอาท์พุต

"###
#.#
###" false

".#
#." false

"####
.#..
####" false

"#.#.#
..#..
#####
..#..
#.#.#" false

"#.#.#.#.#.#
..#...#.#..
###.###.###
..#.#......
#.#.#######
#.#.......#
#.#######.#
#.#.....#.#
#.#.#.#.#.#" false

"##....#####
.#..#...##.
.##.#..#...
..###.###..
#..##.#####
#...##....#
#.#.#####.#
###..####.#
....####...
###...#####" false

"###....##.#########
####...##....#...##
..####.#######.###.
....##..........##.
###..#####.#..##...
####..#..#....#..##
..###.####.#.#..##.
..###...#....#.#...
..####..##.###...##
#.####.##..#####.##
####...##.#####..##" false

ใช่ daft modulo เป็นความเจ็บปวดใน C # เช่นกัน แต่ฉันคิดว่าฉันได้พบวิธีที่จะใช้ประโยชน์จากมันในสำเนาการทำงานของฉันด้วยรหัสทิศทาง (ฉันจะโพสต์อีกครั้งถ้าฉันได้ 10% ลดหรือดีกว่า): (j%4-1)%2ให้รูปแบบการทำซ้ำที่ดี
VisualMelon

ฉันเชื่อว่าฟังก์ชั่นที่ไม่ได้ตั้งชื่อนั้นได้รับอนุญาตและดังนั้นถ้าฟังก์ชั่นนั้นมีการเรียกไปยังตัวมันเอง (มันจะไม่ปรากฏขึ้น) มันอนุญาตให้ไม่นับจำนวนL=ไปยังจำนวนไบต์
SuperJedi224

@ SuperJedi224 คุณน่าจะถูก แต่มันสั้นพอที่จะเป็นหลังจากทั้งหมด
edc65

21

C # - 423 375 ไบต์

เสร็จสิ้นโปรแกรม C # ยอมรับการป้อนผ่าน STDIN เอาต์พุต "True" หรือ "False" ถึง STDOUT ตามความเหมาะสม

ฉันไม่สามารถปล่อยให้ Linq อยู่ในนั้น ... ตอนนี้จะติดตามการมองเห็นและการเยี่ยมชมเซลล์ในอาเรย์ ฉันยังเขียนโค้ดทิศทางอีกครั้งโดยไม่จำเป็นต้องใช้แลมบ์ดาและทำให้รหัสเป็นไปไม่ได้ที่จะเข้าใจมากขึ้น

using C=System.Console;struct P{int x,y;static void Main(){int w=0,W,k=0,o,i,j;P t;string D="",L;for(;(L=C.ReadLine())!=null;D+=L)w=L.Length;for(i=W=D.Length;i-->0&k<W;){k=1;P[]F=new P[W];for(F[j=0].x=i%w+W*W,F[0].y=i/w+W*W;D[i]>35&j<k;)for(t=F[j++],o=1;o<5&k<W;t.y+=(o++&2)-1){t.x+=o&2;if(D[--t.x%w+t.y%(W/w)*w]>35&System.Array.IndexOf(F,t)<0)F[k++]=t;}}C.WriteLine(k>=W);}}

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

รหัสที่ยังไม่ได้ตัด:

using C=System.Console;

struct P
{
    int x,y;

    static void Main()
    {
        int w=0, // w is the width
        W, // W is the length of the whole thing
        k=0, // k is visited count
        o, // o is offset, or something (gives -1,0 0,-1 +1,0 0,+1 t offset pattern)
        i, // i is the start cell we are checking currently
        j; // j is the F index of the cell we are looking at

        P t; // t is the cell at offset from the cell we are looking at

        string D="", // D is the map
        L;

        for(;(L=C.ReadLine())!=null; // read a line, while we can
            D+=L) // add the line to the map
            w=L.Length; // record the width

        for(i=W=D.Length;i-->0&k<W;) // for each cell
        {
            k=1;

            P[]F=new P[W]; // F is the list of visited cells,

            for(F[j=0].x=i%w+W*W,F[0].y=i/w+W*W; // there are reasons (broken modulo)
                D[i]>35&j<k;) // for each cell we've visited, until we've run out
                for(t=F[j++], // get the current cell
                    o=1; // o is just a counter which we use to kick t about
                    o<5& // 4 counts
                    k<W; // make sure we havn't filled F
                    t.y+=(o++&2)-1) // kick and nudge y, inc o
                {
                    t.x+=o&2; // kick x
                    if(D[--t.x%w+t.y%(W/w)*w]>35 // nudge x, it's a dot
                       &System.Array.IndexOf(F,t)<0) // and we've not seen it before
                        F[k++]=t; // then add it
                }
        }

        C.WriteLine(k>=W); // result is whether we visited lots of cells
    }
}

1
อาจเป็นครั้งแรกที่ฉันเห็นC#คำตอบว่าเป็นผู้โหวตที่ได้คะแนนสูงสุดที่นี่
Michael McGriff

1
หลัก () ใน struct ตอนนี้มันน่ารัก
PTwr

10

Python 2 - 258 210 244 ไบต์

ตรวจสอบเส้นทางซ้ำถ้า stack overflow คืนค่า 1 (ความจริง) มิฉะนั้นจะคืนค่า None (falsey)

import sys
def k(s):
 a=len(s);m=[[c=='.'for c in b]*999for b in s.split('\n')]*999;sys.setrecursionlimit(a)
 for x in range(a*a):
  try:p(m,x/a,x%a)
  except:return 1
def p(m,x,y):
 if m[x][y]:m[x][y]=0;map(p,[m]*4,[x,x,x+1,x-1],[y+1,y-1,y,y])

1
คุณสามารถบันทึกไบต์บางอย่างโดยใช้;สำหรับสายในขณะที่คุณจะได้รับพวกเขาในบรรทัดเดียวกันกับp if
PurkkaKoodari

11
"ถ้าแตกล้นกลับจริง" - ฉันสภาพเหมือนปลาย recursion ว่า :)
schnaader

3
ฉันไม่มั่นใจว่านี่เป็นวิธีการที่ถูกต้อง การใช้สแต็คโอเวอร์โฟลว์เพื่อตรวจจับภูมิภาค "ไม่มีที่สิ้นสุด" จะก่อให้เกิดผลบวกปลอม ข้อมูลจำเพาะของปัญหาไม่ได้ระบุข้อ จำกัด ใด ๆ ในช่วงอินพุต แต่บางอย่างเช่นเขาวงกตขนาด 300x300 ดูเหมือนจะไม่มีเหตุผลและสามารถล้อมเส้นทางที่มีความยาวมาก
JohnE

4
เขาวงกต จำกัดเกือบทั้งหมดจะทำให้เกิดการล้นสแต็ก นี่ไม่ใช่โปรแกรมที่ถูกต้อง
PyRulez

@johne ได้รับการอัปเดตดังนั้นขีด จำกัด การเรียกซ้ำตามลำดับของขนาดของเขาวงกต เพิ่ม 34 ไบต์อย่างน่าเสียดาย แต่ควรจะถูกต้องในตอนนี้ (อย่างน้อยก็ถูกต้องเหมือนแฮ็คแบบนี้)
Kyle Gullion มี. ค.

5

Python 2 - 297 286 275 ไบต์

เลือกเซลล์ "เปิด" ตามอำเภอใจเพื่อเริ่มเติมน้ำท่วม เขาวงกตไม่มีที่สิ้นสุดถ้าในระหว่างการเติมเราไปเยี่ยมเซลล์ที่เราเคยไปแล้ว แต่มันมีพิกัดที่แตกต่างจากการเยี่ยมชมครั้งก่อน หากน้ำท่วมเติมเต็มทั้งภูมิภาคโดยไม่ต้องค้นหาเซลล์ลองภูมิภาคอื่น หากไม่พบพื้นที่ดังกล่าวเขาวงกตก็มีขอบเขต จำกัด

นำไฟล์ไปประมวลผลบนบรรทัดคำสั่งส่งคืนรหัสออก1สำหรับอนันต์และ0สำหรับ จำกัด

ส่งคืนผลลัพธ์ที่ถูกต้องสำหรับกรณีทดสอบทั้งหมด

import sys
e=enumerate
C=dict([((i,j),1)for i,l in e(open(sys.argv[1]))for j,k in e(l)if'.'==k])
while C:
 d={}
 def f(r,c):
  n=(r%(i+1),c%j)
  if n in d:return(r,c)!=d[n]
  if C.pop(n,0):d[n]=(r,c);return any(map(f,[r-1,r,r+1,r],[c,c+1,c,c-1]))
 if f(*C.keys()[0]):exit(1)

1
คุณไม่สามารถสันนิษฐานได้ว่าเซลล์ใด ๆ จะเป็นสมาชิกของถ้ำที่ไม่มีที่สิ้นสุดคุณสามารถมีได้ทั้งถ้ำที่ไม่มีที่สิ้นสุดและ จำกัด
VisualMelon

2
@VisualMelon: ขออภัยคำอธิบายไม่ถูกต้องทั้งหมด รหัสจะตรวจสอบทุกภูมิภาคที่เป็นไปได้ของเซลล์ที่เชื่อมต่อถึงกันไม่ใช่แค่หนึ่งเซลล์ นั่นคือสิ่งที่สุดท้ายในขณะที่วนรอบ - เลือกภูมิภาคเพื่อตรวจสอบในขณะที่ยังมีเซลล์ที่ไม่ถูกตรวจสอบเหลืออยู่
Mac
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.