แก้ปริศนาไบนารี


10

บทนำ

กฎของปริศนา:

Binary Puzzle (หรือที่รู้จักกันในชื่อTakuzuหรือ Subiku) นั้นง่ายต่อการเข้าใจและมีกฎเพียงไม่กี่:
เนื่องจากชื่อของเกมนั้นเป็นเลขฐานสองมันค่อนข้างชัดเจน แต่คุณสามารถเติมเลขศูนย์และคนได้เท่านั้น

  1. ไม่เกินสองหลักเดียวกันสามารถติดกันในแนวตั้งหรือแนวนอน
  2. แต่ละแถวและแต่ละคอลัมน์จะต้องมีค่าศูนย์และจำนวนเท่ากัน (โดยปริยายหมายความว่าทุกเกมไบนารีจะมีขนาดเท่ากันเสมอ)
  3. อาจไม่มีแถวที่ซ้ำกันและไม่มีคอลัมน์ที่ซ้ำกัน (โดยมีศูนย์และคอลัมน์เดียวกัน)

คุณสามารถเล่นเกมได้ที่www.binarypuzzle.comหากคุณต้องการ

กลยุทธ์:

เนื่องจากกฎข้อที่ 1 เราสามารถกรอกตัวเลขได้เสมอหาก:
- มีตัวเลขสองหลักเดียวกันในแนวตั้งหรือแนวนอนติดกันซึ่งในกรณีนี้เราสามารถกรอกตัวเลขตรงข้ามทั้งสองด้าน เช่น→.11... - มีตัวเลขสองหลักเดียวกันในแนวตั้งหรือแนวนอนโดยมีเพียงหนึ่งช่องว่างในระหว่างนั้น เช่น→0110..
.1.1...101..

เนื่องจากกฎข้อที่ 1 เมื่อเหลือช่องว่างสามช่องและเราไม่สามารถมีเลขสามหลักที่อยู่ติดกันได้เราสามารถเติมช่องว่างช่องใดช่องหนึ่งได้ Ie .0.1.010.1.0(เรายังต้องเติมสองอันและเราไม่สามารถมีสามอันที่อยู่ติดกันตรงกลางดังนั้นช่องว่างแรกจะต้องเป็น1)

เนื่องจากกฎที่ 2 เราสามารถเติมช่องว่างที่เหลือในแถวหรือคอลัมน์ได้เสมอหากครึ่งหนึ่งของพวกเขาเต็มไปด้วยตัวเลขตรงกันข้าม เช่น.1.011010011

เนื่องจากกฎข้อที่ 3 เราสามารถเติมตัวเลขตรงข้ามได้เสมอหากเหลือเพียงสองตัวเท่านั้นที่จะแก้ปัญหาในบรรทัดที่ได้รับคำสั่งเท่ากัน เช่น101100 & 1..100101100 & 110100

เนื่องจากกฎข้อที่ 3 บางครั้งเราสามารถเติมเต็มช่องว่างเมื่อเหลือช่องว่างสามช่องในบรรทัดที่มีคำสั่งเท่ากัน Ie 010011 & .1.01.010011 & .1.010(ที่นี่เราไม่สามารถเติม1ท้ายได้เพราะนั่นหมายความว่าเราต้องเติมเลขศูนย์ที่อีกสองช่องว่างทำให้ทั้งสองเส้นเท่ากันตามลำดับ)

ตัวอย่าง:

เราเริ่มต้นด้วยตาราง 6x6 ต่อไปนี้โดยเติมบางส่วนและเลขศูนย์ (และจุดนั้นเป็นช่องว่างที่เรายังไม่ต้องกรอก):

.1....
.10.0.
1.11..
.1....
...1.0
......

เนื่องจากกฎที่ 1 & 2 เราสามารถกรอกตัวเลขเหล่านี้:

.1.01.
.1010.
101100
010011
.0.1.0
.010..

เนื่องจากกฎ 1 เราสามารถเติม 1 ในแถว 5 คอลัมน์ 1:

.1.01.
.1010.
101100
010011
10.1.0
.010..

เนื่องจากกฎ 3 เราสามารถเติม 0 ที่แถว 1 คอลัมน์ 6 (เมื่อดูแถว 4):

.1.010
.1010.
101100
010011
10.1.0
.010..

ตอนนี้เราสามารถเติมตัวเลขด้วยช่องว่างได้เนื่องจากกฎ 1 & 2:

.1.010
010101
101100
010011
10.1.0
.010.1

ตอนนี้เราสามารถจบแถวที่ 5 ได้เนื่องจากกฎ 3 (เมื่อดูแถวที่ 3):

.1.010
010101
101100
010011
100110
.010.1

จากนั้นเราก็สามารถไขปริศนาให้เสร็จเนื่องจากกฎ 1 & 2:

011010
010101
101100
010011
100110
101001

ท้าทาย:

ความท้าทายนั้นง่าย: ให้ตารางเริ่มต้นเอาท์พุทปริศนาที่แก้ไขแล้ว

หมายเหตุ: คุณไม่จำเป็นต้องปฏิบัติตามกฎข้างต้น แน่นอนคุณสามารถและควรให้คำแนะนำเกี่ยวกับวิธีการใช้ความท้าทายนี้ แต่การแก้ไขปัญหาด้วยกฎในใจนั้นดีมาก
วิธีที่คุณแก้ปัญหานั้นขึ้นอยู่กับคุณ แต่ความท้าทายคือการไขปริศนาที่มีการแก้ไข

กฏท้าทาย:

  • รูปแบบอินพุตและเอาต์พุตสำหรับกริดมีความยืดหยุ่น แต่โปรดระบุสิ่งที่คุณใช้ (เช่นอาร์เรย์ไบต์ 2 มิติสตริงที่มีการขึ้นบรรทัดใหม่ ฯลฯ )
  • สิ่งนี้ยังใช้กับตัวละครที่ใช้ ในตัวอย่างที่ฉันเคยใช้01.แต่ถ้าคุณต้องการคุณสามารถใช้ABxแทน โปรดระบุรูปแบบอินพุต / เอาต์พุตและอักขระที่คุณใช้
  • คุณสามารถสันนิษฐานได้ว่าจะใช้ขนาดกริดต่อไปนี้: 6x6; 8x8; 10x10; 12x12; 14x14; 16x16.

กฎทั่วไป:

  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ
    อย่าปล่อยให้ภาษารหัสกอล์ฟกีดกันคุณจากการโพสต์คำตอบด้วยภาษาที่ไม่ได้เข้ารหัส พยายามหาคำตอบสั้น ๆ ที่เป็นไปได้สำหรับภาษาโปรแกรม 'ใด ๆ '
  • กฎมาตรฐานจะใช้สำหรับคำตอบของคุณดังนั้นคุณจึงได้รับอนุญาตให้ใช้ STDIN / STDOUT ฟังก์ชัน / เมธอดพร้อมพารามิเตอร์ที่เหมาะสมโปรแกรมเต็มรูปแบบ การโทรของคุณ
  • ช่องโหว่เริ่มต้นเป็นสิ่งต้องห้าม
  • หากเป็นไปได้โปรดเพิ่มลิงค์พร้อมทดสอบรหัสของคุณ
  • นอกจากนี้โปรดเพิ่มคำอธิบายหากจำเป็น

กรณีทดสอบ:

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

Input:
1..0..
..00.1
.00..1
......
00.1..
.1..00

Output:
101010
010011
100101
011010
001101
110100

Input:
.1....
.10.0.
1.11..
.1....
...1.0
......

Output:
011010
010101
101100
010011
100110
101001

Input:
.......1..
.00..0..1.
.0..1..0.0
..1...1...
1.1......1
.......1..
.0..1...0.
....11...0
.0.0..1..0
0...0...1.

Output:
0110010101
1001100110
1001101010
0110011001
1010100101
0101010110
1001101001
0110110100
1010011010
0101001011


คำตอบ:


4

Brachylogขนาด 34 ไบต์

{ℕ<2}ᵐ²&≜{d?ọᵐctᵐ=&{ḅlᵐ⌉<3}ᵐ}&\↰₂&

ลองออนไลน์!

นี่เป็นเรื่องที่ช้ามากดังนั้นกรณีทดสอบของ TIO คือ 4x4 ฉันกำลังใช้กรณีทดสอบ 6x6 บนคอมพิวเตอร์ของฉันเพื่อดูว่าต้องใช้เวลานานเท่าใด

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

คำอธิบาย

เรา จำกัด ค่าที่จะอยู่ใน{0,1}นั้นจากนั้นเราลองอินสแตนซ์ของตัวแปรจนกว่าเราจะเคารพกฎทั้ง 3 ข้อ นี่คือสาเหตุที่มันช้ามาก (เพราะมันจะลองพวกเขาทั้งหมดจนกระทั่งพบหนึ่งอันและเพราะในกรณีนั้น Brachylog นั้นยังไม่ได้ใช้งานได้ดีพอเพื่อให้สามารถกำหนดข้อ จำกัด ก่อนลองเมทริกซ์ที่เป็นไปได้)

                                 &  Output = Input
{   }ᵐ²                             Map two levels on the Input (i.e. each cell):
 ℕ<2                                  The cell is either 0 or 1
       &≜                           Assign values to all cells
         {                  }       Define predicate 2:
          d?                          The Input with no duplicates is still the Input
                                        (i.e. all rows are different)
           ?ọᵐctᵐ=                    All occurences of 1s and 0s for each rows are equal
                  &{      }ᵐ          Map on rows:
                    ḅlᵐ                 Get the lengths of runs of equal values
                       ⌉<3              The largest one is strictly less than 3
                             &\↰₂   Apply predicate 2 on the transpose of the Input
                                      (i.e. do the same checks but on columns)

Brachylog บ่งบอกถึงตัวแปรที่นอกเหนือจากตัวอักษรพิมพ์ใหญ่ได้อย่างไร ดังนั้นสมมติว่าโซลูชันของคุณจะทำงานได้เร็วขึ้นมันจะไม่สามารถเติมเต็มช่องว่างทั้งหมดในตาราง 14x14 ด้วยการAผ่านY(พร้อมZเป็นพารามิเตอร์เอาต์พุต) มันยังคงมีAA, ABetc?
Kevin Cruijssen

2
@KevinCruijssen all-uppercase identifier ใด ๆ เป็นตัวแปรดังนั้นใช่AAเป็นตัวแปรและKEVINCRUIJSSENยังเป็นตัวแปรด้วย
เสียชีวิต

3
อย่างที่ฉันสงสัยความท้าทายสำหรับ Brachylog: D
Jonathan Allan

3

JavaScript (ES6), 274 270 ไบต์

จะเข้าเป็น array 2D 2ที่เซลล์ว่างจะมีเครื่องหมาย พิมพ์โซลูชันที่เป็นไปได้ทั้งหมดไปยังคอนโซล

f=(a,x=0,y=0,w=a.length,p,R=a[y])=>(M=z=>!a.some((r,y)=>/(0|1),\1,\1/.exec(s=r.map((v,x)=>(v=z?v:a[x][y],b-=v&1,c-=!v,m|=v&2,v),b=c=w/2))||b*c<0|o[b*c||s]&(o[s]=1),o={}))(m=0)&M(1)&&(m?R&&[0,1].map(n=>(p=R[x])==n|p>1&&(R[x]=n,f(a,z=(x+1)%w,y+!z),R[x]=p)):console.log(a))

มันทำงานอย่างไร

ส่วนแรกของรหัสใช้M()ฟังก์ชั่นเพื่อตรวจสอบความถูกต้องของบอร์ดปัจจุบันทั้งแนวนอนและแนวตั้ง

M = z =>
  !a.some((r, y) =>
    /(0|1),\1,\1/.exec(
      s = r.map((v, x) =>
        (
          v = z ? v : a[x][y],
          b -= v & 1,
          c -= !v,
          m |= v & 2,
          v
        ),
        b = c = w / 2
      )
    ) ||
    b * c < 0 |
    o[b * c || s] &
    (o[s] = 1),
    o = {}
  )

มันแผนที่แถวหรือคอลัมน์สตริงs "1,2,2,0,2,2"นี้เป็นจริงอาร์เรย์บังคับให้สตริงเพื่อให้ดูเหมือนว่า

มันใช้:

  • นิพจน์ทั่วไป/(0|1),\1,\1/เพื่อตรวจจับตัวเลขที่เหมือนกัน 3 ตัวขึ้นไป
  • เคาน์เตอร์และในการติดตามของจำนวนคนและศูนย์ ตัวนับทั้งสองถูกกำหนดค่าเริ่มต้นเป็นw / 2และลดค่าในแต่ละครั้งที่พบหนึ่งหรือศูนย์ (ตามลำดับ) สิ่งนี้นำไปสู่:
    • b = c = 0 b * c = 0 →บรรทัดนั้นสมบูรณ์และถูกต้อง (มีค่าศูนย์มากเท่าที่มี )
    • b> 0 และ c> 0 b * ค> 0 →เส้นยังไม่สมบูรณ์ แต่ที่ถูกต้องเพื่อให้ห่างไกล (เราไม่ได้มีมากกว่า w / 2 ศูนย์หรือมากกว่า w / 2 คน )
    • b <0 หรือ c <0 b * c <0 →เส้นไม่ถูกต้อง
  • ธงm (สำหรับ 'หายไป') ซึ่งไม่เป็นศูนย์หากมีสองอย่างน้อยหนึ่งอันที่เหลืออยู่บนกระดาน
  • วัตถุoเพื่อติดตามรูปแบบเส้นทั้งหมดที่พบจนถึง

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

[0, 1].map(n =>
  (p = a[y][x]) == n |
  p > 1 && (
    a[y][x] = n,
    f(a, z = (x + 1) % w, y + !z),
    a[y][x] = p
  )
)

การสาธิต


ขอขอบคุณที่เพิ่มคำอธิบาย และฉันชอบวิธีที่คุณพิมพ์เอาต์พุตที่เป็นไปได้ทั้งหมดแทนที่จะเป็นเพียงหนึ่งเดียว!
Kevin Cruijssen

1
@KevinCruijssen นี่อาจจะยังไม่เหมาะสม แต่ก็สนุกดีที่จะเขียน ท้าทายมาก!
Arnauld

1

เจลลี่ , 53 51 ไบต์

ṡ€3ḄFf0,7L
SḤnLṀȯÇ
⁻QȯÇ
Fṣ©2L’0,1ṗż@€®F€s€LÇÐḟZÇ$Ðḟ

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

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

วิธีการบังคับเดรัจฉานบริสุทธิ์ - ดำเนินการกฎและตรวจสอบพวกเขาสำหรับแต่ละตารางที่สามารถเกิดขึ้นได้โดยการแทนที่ใด ๆ ของ2s ด้วย1s หรือ0s

ṡ€3ḄFf0,7L - Link 1, # of runs of 3 1s or 3 0s by row: list of lists
ṡ€3        - all contiguous slices of length 3 for €ach list
   Ḅ       - convert all results from binary
    F      - flatten into one list
     f     - filter keep values in:
      0,7  -   0 paired with 7: [0,7]
         L - length

SḤnLṀȯÇ - Link 2, unequal counts of 1s and 0s by column ...or link 1: list of lists
S       - sum (vectorises, hence "by column", counts 1s since only 1s or 0s appear)
 Ḥ      - double
   L    - length (number of rows - OK since square)
  n     - not equal? (vectorises)
    Ṁ   - maximum (1 if any not equal)
     ȯÇ - ... or last link (1) as a monad

⁻QȯÇ - Link 3, rows are unique ...or link 2: list of lists
 Q   - unique
⁻    - not equal?
  ȯÇ - ... or last link (2) as a monad

Fṣ©2L’0,1ṗż@€®F€s€LÇÐḟZÇ$Ðḟ - Main link: list of lists
F                           - flatten
 ṣ©2                        - split at 2s and copy the result to the register
    L                       - length (# of such slices)
     ’                      - decrement (# of 2s)
      0,1                   - 0 paired with 1
         ṗ                  - Cartesian power (all binary lists of length # of 2s)
             ®              - recall value from register (the flat version split at 2s)
          ż@€               - zip (reversed @rguments) for €ach (1s & 0s where 2s were)
              F€            - flatten €ach
                s€L         - split €ach into chunks of length length(input) (into rows)
                    Ðḟ      - filter discard if:
                   Ç        -   call last link(3) as a monad
                         Ðḟ - filter discard if:
                        $   -   last two links as a monad:
                      Z     -     transpose
                       Ç    -     call last link(3) as a monad
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.