เชื่อมต่อ 4: ค้นหาของปลอม!


35

ธนาคารถูกบุกรุกและบรรดานักเลงมาเฟียในท้องถิ่นมีข้อแก้ตัวที่ผิดปกติ: พวกเขาเล่นที่บ้าน Connect 4! เพื่อช่วยในการสืบสวนคุณจะถูกขอให้เขียนโปรแกรมเพื่อตรวจสอบบอร์ด Connect 4 ทั้งหมดที่ถูกยึดเพื่อตรวจสอบว่าตำแหน่งนั้นอยู่ในตำแหน่งที่แน่นอนจากเกม Connect 4 ที่ถูกต้องและยังไม่ได้รวมเข้าด้วยกัน ทันทีที่ตำรวจเคาะประตู

กฎสำหรับการเชื่อมต่อ 4: ผู้เล่นRและYหันมาวางไพ่ที่มีสีลงในคอลัมน์ของตารางขนาด 7x6 เมื่อผู้เล่นวางไทล์ลงในคอลัมน์มันจะหล่นลงมาเพื่อครองตำแหน่งที่ไม่สำเร็จที่ต่ำที่สุดในคอลัมน์นั้น หากผู้เล่นจัดการเพื่อให้ได้สีในแนวนอนแนวตั้งหรือแนวทแยงของไพ่สี่สีบนกระดานจากนั้นพวกเขาชนะและเกมจะจบลงทันที

ตัวอย่างเช่น (เมื่อRเริ่มต้น) ต่อไปนี้เป็นตำแหน่งเชื่อมต่อ 4 ที่เป็นไปไม่ได้

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | |
| | |Y| | | | |
|R| |Y| | | | |

โปรแกรมหรือฟังก์ชั่นของคุณจะต้องใช้บอร์ด Connect 4 และส่งคืน

  • ค่าเท็จแสดงว่าตำแหน่งนั้นเป็นไปไม่ได้หรือ
  • สตริงของตัวเลข 1-7 แสดงให้เห็นลำดับที่เป็นไปได้อย่างใดอย่างหนึ่งของการเคลื่อนไหวที่นำไปสู่ตำแหน่งที่ (คอลัมน์ที่มีหมายเลข1ที่จะ7จากซ้ายไปขวาและอื่น ๆ ตามลำดับ112ตัวอย่างเช่นระบุว่ามีการย้ายสีแดงในคอลัมน์1ตามด้วยการย้ายสีเหลือง ในคอลัมน์1ตามด้วยการย้ายสีแดงในคอลัมน์2) คุณสามารถเลือกหมายเลขคอลัมน์อื่นที่ไม่ใช่ 1234567 หากคุณต้องการตราบใดที่คุณระบุในโซลูชันของคุณ หากคุณต้องการส่งคืนรายการในรูปแบบอื่น ตัวอย่างเช่นอาเรย์[2, 4, 3, 1, 1, 3]แล้วก็ใช้ได้เช่นกันตราบใดที่ง่ายต่อการดูว่าการเคลื่อนไหวนั้นเป็นอย่างไร

คุณสามารถเลือกที่จะอ่านกระดานในรูปแบบที่เหมาะสมรวมถึงการใช้ตัวอักษรที่นอกเหนือจากRและYสำหรับผู้เล่น แต่คุณต้องระบุผู้เล่นคนแรก คุณสามารถสันนิษฐานได้ว่าบอร์ดจะมีขนาด 6x7 โดยมีผู้เล่นสองคน

คุณอาจสันนิษฐานได้ว่าตำแหน่งที่คุณได้รับนั้นเป็นไปได้อย่างน้อยที่สุดที่จะสร้างบนกระดาน Connect 4 มาตรฐาน กล่าวคือจะไม่มีชิ้นส่วน 'ลอย' คุณสามารถสันนิษฐานได้ว่าบอร์ดจะไม่ว่างเปล่า

นี่คือรหัสกอล์ฟดังนั้นคำตอบที่สั้นที่สุดจึงชนะ ช่องโหว่มาตรฐานใช้

ตัวอย่าง

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | --> 1234567 (one possible answer)
| | | | | | | |
|R|Y|R|Y|R|Y|R|

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | | --> false
| | |Y| | | | |
|R| |Y| | | | |

| | | | | | | |
| | |Y| | | | |
| | |R| | | | |
| | |Y| | | | | --> 323333 (only possible answer)
| | |R| | | | |
| |Y|R| | | | |

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> false (this is the position arising after
| |Y|Y|Y|Y| | |     the moves 11223344, but using those moves
| |R|R|R|R| | |     the game would have ended once R made a 4)

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> 2134231211 (among other possibilities)
|R|R|Y| | | | |
|Y|R|R|Y| | | |

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> false (for example, 21342312117 does not
|R|R|Y| | | | |     work, because Y has already made a diagonal 4)
|Y|R|R|Y| | |R|

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> 112244553 or similar
|Y|Y| |Y|Y| | |
|R|R|R|R|R| | |

จอห์นคุณรู้หรือไม่ว่ามีอัลกอริธึมที่ไม่ดุร้ายหรือไม่
โยนาห์

คำตอบ:


9

เยลลี่ , 57 ไบต์

ŒṪŒ!µ0ịŒṬ¬a³ZU,Ɗ;ŒD$€Ẏṡ€4Ḅo1%15;Ḋ€ṢṚ$Ƒƙ$Ȧȧœị³$2R¤ṁ$ƑµƇṪṪ€

ใช้เมทริกซ์ที่0ไม่ได้บรรจุ1เล่นครั้งแรกและ2เล่นวินาที ให้ผลลัพธ์รายการของคอลัมน์ที่มีการจัดทำดัชนี 1 ซึ่งจะว่างเปล่าหากมีการระบุของปลอม

ลองออนไลน์! (ไม่มีประสิทธิภาพเกินกว่า 7 ชิ้นในเวลาไม่ถึงนาที)

บันทึก:

  1. สมมติว่าไม่มีชิ้นส่วน "ที่ลอยอยู่" (แก้ไขได้ด้วยการเพิ่มที่ZṠṢ€Ƒȧ+6 ไบต์)
  2. สมมติว่าบอร์ดว่างเปล่าเป็นของปลอม

11

JavaScript (ES6),  202 194 187  183 ไบต์

รับอินพุตเป็นเมทริกซ์ด้วยสำหรับสีแดง,สำหรับสีเหลืองและสำหรับค่าว่าง ส่งคืนสตริงของการเลื่อนดัชนี 0 ครั้ง (หรือสตริงว่างถ้าไม่มีวิธีแก้ไข) สีแดงเริ่มเกม240

m=>(p=[...'5555555'],g=(c,s=o='')=>/2|4/.test(m)?['',0,2,4].some(n=>m.join``.match(`(1|3)(.{1${n}}\\1){3}`))?o:p.map((y,x)=>m[m[y][x]--^c||p[g(c^6,s+x,p[x]--),x]++,y][x]++)&&o:o=s)(2)

ลองออนไลน์!

อย่างไร?

ฟังก์ชันเรียกซ้ำพยายามแทนที่ทั้งและในเมทริกซ์อินพุตด้วยและตามลำดับg2413

ในขณะที่ทำเช่นนั้นตรวจสอบให้แน่ใจว่าเราไม่มีการเรียกใช้ค่าคี่สี่ติดต่อกันจนกว่าค่าทั้งหมดแม้จะหายไป (เช่นถ้าฝ่ายชนะมันจะต้องย้ายครั้งสุดท้าย)

แถวของช่องที่มีอยู่ต่อไปสำหรับแต่ละคอลัมน์ถูกเก็บไว้ใน[x]yxp[x]

แสดงความคิดเห็น

m => (                            // m[] = input matrix
  p = [...'5555555'],             // p[] = next row for each column
  g = (c,                         // g = recursive function taking c = color,
          s = o = '') =>          //     s = current solution, o = final output
    /2|4/.test(m) ?               // if the matrix still contains at least a 2 or a 4:
      ['', 0, 2, 4]               //   see if we have four consecutive 1's or 3's
      .some(n =>                  //   by testing the four possible directions
        m.join``                  //   on the joined matrix, using
        .match(                   //   a regular expression where the number of characters
          `(1|3)(.{1${n}}\\1){3}` //   between each occurrence is either 1, 10, 12 or 14
        )                         //   (horizontal, diagonal, vertical, anti-diagonal)
      ) ?                         //   if we have a match:
        o                         //     abort and just return the current value of o
      :                           //   else:
        p.map((y, x) =>           //     for each cell at (x, y = p[x]):
          m[                      // 
            m[y][x]--             //       decrement the value of the cell
            ^ c ||                //       compare the original value with c
            p[                    //       if they're equal:
              g(                  //         do a recursive call with:
                c ^ 6,            //           the other color
                s + x,            //           the updated solution
                p[x]--            //           the updated row for this column
              ),                  //         end of recursive call
              x                   //         then:
            ]++,                  //         restore p[x]
            y                     //         and restore m[y][x]
          ][x]++                  //         to their initial values
        ) && o                    //     end of map(); yield o
    :                             // else:
      o = s                       //   we've found a solution: copy s to o
)(2)                              // initial call to g() with c = 2

หมายเหตุฉันได้ถามว่า "เราจะสมมติได้หรือไม่ว่าบอร์ดว่างเปล่าจะไม่ได้รับการป้อนข้อมูล" - หากเราต้องจัดการกับสิ่งนี้รหัสของคุณจะต้องมีการปรับแต่ง
Jonathan Allan

ฉันไม่รู้ว่าทำไมf([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [0,2,2,0,2,2,0], [1,1,1,1,1,1,1] ])ยกเลิกโดย0 และf([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [2,2,2,0,2,2,1], [1,1,1,1,1,1,1] ])ควรจะเป็นจริง
Nahuel Fouilleul

@NahuelFouilleul ขอบคุณที่รายงานสิ่งนี้ ฉันได้แก้ไขรหัสเพิ่มแล้วเพิ่มกรณีทดสอบเหล่านี้
Arnauld

2

Python 2 , 295 285 ไบต์

def f(a):
 if 1-any(a):return[]
 p=sum(map(len,a))%2
 for i in R(7):
	if a[i][-1:]==`p`:
	 b=a[:];b[i]=b[i][:-1];L=f(b)
	 if L>1>(`1-p`*4in','.join([J((u[j]+' '*14)[n-j]for j in R(7))for n in R(12)for u in[b,b[::-1]]]+b+map(J,zip(*[r+' '*7for r in b])))):return L+[i]
R=range;J=''.join

ลองออนไลน์!

-10 ขอบคุณไปยังโจกษัตริย์

อินพุตคือรายการของสตริงที่แทนคอลัมน์ ด้วย '1' สำหรับสีแดงและ '0' สำหรับสีเหลือง สตริงไม่ใช่ '' -padded ดังนั้นกรณี (falsey):

| | | | | | | |
| | | | | | | |
|Y| | | | | | |
|R|Y| | | | | |
|R|R|Y| | | | |
|Y|R|R|Y| | |R|

เป็นอินพุตเป็น:

[
  '0110',
  '110',
  '10',
  '0',
  '',
  '',
  '1'
]

เอาท์พุทเป็นรายการของดัชนีคอลัมน์ 0 ดัชนีที่สามารถทำให้คณะกรรมการ; หรือNoneถ้ามันไม่ถูกต้อง

ยอมรับบอร์ดว่างเปล่าว่าใช้ได้ (ส่งคืนรายการเปล่า[]แทนNone)

วิธีการนี้ซ้ำจากการย้ายครั้งสุดท้ายไปยังการย้ายครั้งแรก: ขึ้นอยู่กับความเท่าเทียมกันของจำนวนการเคลื่อนไหวทั้งหมดที่ดำเนินการเราจะลบการย้ายสีแดงครั้งสุดท้ายหรือการย้ายสีเหลืองครั้งล่าสุด (หรือล้มเหลวหากไม่สามารถทำได้) ตรวจสอบกระดานผลลัพธ์เพื่อดูว่าฝ่ายตรงข้ามมี 4-in-a-row (ในกรณีนี้ล้มเหลวเพราะเกมควรหยุดเล่นไปแล้ว); มิฉะนั้นให้เรียกคืนจนกว่าบอร์ดจะว่างเปล่า (ซึ่งใช้ได้)

รหัส 4-in-a-row เป็นส่วนที่บวมที่สุด สตริงเส้นทแยงมุมทั้งหมดสำหรับเมทริกซ์bถูกสร้างโดย:

[
    ''.join(
        (u[j]+' '*14)[n-j] for j in range(7)
    )
    for u in[b,b[::-1]]for n in range(12) 
]

สิ่งแรกที่แสดงรายการเส้นทแยงมุม 'down-sloping' และ 'up-sloping'

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