Tatamibari çözücü


10

Arka fon

Tatamibari , Nikoli tarafından tasarlanan bir mantık bulmacasıdır.

Bir Tatamibari bulmacası, içinde üç farklı sembol bulunan dikdörtgen bir ızgarada oynanır: +, -. ve |. Çözücü, ızgarayı aşağıdaki kurallara göre dikdörtgen veya kare bölgelere ayırmalıdır:

  • Her bölüm tam olarak bir sembol içermelidir.
  • Bir +kare içinde bir sembol bulunmalıdır.
  • Bir |sembol genişliğinden daha büyük bir yüksekliğe sahip bir dikdörtgen bulunması gerekir.
  • Bir -sembol, yüksekliğinden daha geniş bir dikdörtgenin içinde bulunmalıdır.
  • Dört parça asla aynı köşeyi paylaşamaz. (Japon tatami çinileri genellikle bu şekilde yerleştirilir.)

Aşağıdaki bir çözüm ile örnek bir bulmaca:

Yapboz Tatamibari örneği Örnek Tatamibari bulmaca çözümü

Görev

Verilen Tatamibari bulmacasını çözün.

Giriş çıkış

Giriş, verilen Tatamibari bulmacasını temsil eden bir 2B ızgaradır. Her hücre dört karakterlerinden biri içerir: +, -, |, ve sizin seçtiğiniz bir karakteri olmayan bir ipucu hücreyi temsil etmek. Test durumlarda, bir yıldız işareti *kullanılır.

Bir Tatamibari bulmacasına geçerli herhangi bir çözümü kesin olarak temsil edebilecek herhangi bir uygun çıktı biçimini seçebilirsiniz. Bu aşağıdakileri içerir, ancak bunlarla sınırlı değildir: (şüpheniz varsa, yorumlarda sorun.)

  • 4 grubun bir listesi; burada her grubun üst dizin, sol dizin, bir dikdörtgenin genişliği veya yüksekliği (veya herhangi bir eşdeğer gösterim)
  • Her sayının bir dikdörtgeni temsil ettiği girişle aynı şekle sahip sayısal bir ızgara
  • Her kümenin bir dikdörtgendeki hücrelerin tüm koordinatlarını içerdiği koordinat kümelerinin listesi

Bir bulmacanın birden fazla çözümü varsa, geçerli çözümlerinden istediğiniz sayıda (bir veya daha fazla) çıktı alabilirsiniz. Girişin en az bir çözümü olduğu garanti edilmektedir.

Test senaryoları

Puzzle:
|-*
*+|
*-*
Solution:
122
134
554
=====
Puzzle:
+***
**|*
*+**
***-
Solution:
1122
1122
3322
3344
======
Puzzle:
|*+*+
*****
****-
***+|
+****
Solution:
12233
12233
44444
55667
55667
=======
Puzzle:
****-**
**-**|*
*|*****
****-**
*******
**+*|**
*****+*
One possible solution:
1122222
1133344
1155544
1155544
6667744
6667788
6667788
===========
Puzzle:
*-****|+**
+*-******|
****+*****
*-******||
**++|*****
+****-|***
-****-**+*
********-*
|*+*+|****
*-*--**+*+
Solution:
1111122334
5666622334
7777822994
7777A2299B
CCDEA2299B
CCFFFFGGHH
IIIIJJGGHH
KLLMMNGGOO
KLLMMNGGPP
QQRRSSSTPP

kurallar

Standart kuralları geçerlidir. Bayt cinsinden en kısa kod kazanır.

Yanıtlar:


5

Python 2 , 417 374 366 bayt

Girdi, ~ipucu için satır listesidir . Stderr biçiminde tek bir çözüm çıktılar (x_start, width, y_start, height).

R=range
k=input()
X,Y=len(k[0]),len(k)
W,H=R(X),R(Y)
Q=[[]]
for q in Q:C=[(x,y)for(a,b,c,d)in q for x in(a,a+b)for y in(c,c+d)];max(map(C.count,C+W))<4>0<all(sum(w>x-s>-1<y-t<h<[c for r in k[t:t+h]for c in r[s:s+w]if'~'>c]==['+|-'[cmp(h,w)]]for(s,w,t,h)in q)==1for x in W for y in H)>exit(q);Q+=[q+[(s,w+1,t,h+1)]for s in W for w in R(X-s)for t in H for h in R(Y-t)]

Çevrimiçi deneyin! Bu, önerilen test vakaları için çok verimsizdir.


Ungolfed

grid = input()
total_width = len(grid[0])
total_height = len(grid)

partitions = [[]]

for partition in partitions:
    # list the corners of all rectangles in the current partition
    corners = [(x, y)
               for (start_x, width, start_y, height) in partition
               for x in (start_x, start_x + width)
               for y in (start_y, start_y + height)]
    # if no corners appears more than three times ...
    if corners != [] and max(map(corners.count, corners)) < 4:
        # .. and all fields are covered by a single rectangle ...
        if all(
                sum(width > x - start_x > -1 < y - start_y < height
                    for (start_x, width, start_y, height) in partition) == 1
                for x in range(total_width)
                for y in range(total_height)):
            # ... and all rectangles contain a single non-~
            # symbol that matches their shape:
            if all(
                [char for row in grid[start_y: start_y + height]
                    for char in row[start_x:start_x + width] if '~' > char]
                == ['+|-'[cmp(height, width)]]
                    for (start_x, width, start_y, height) in partition):
                # output the current partition and stop the program
                exit(partition)

    # append each possible rectangle in the grid to the current partition,
    # and add each new partition to the list of partitions.
    partitions += [partition + [(start_x, width + 1, start_y, height + 1)]
                   for start_x in range(total_width)
                   for width in range(total_width - start_x)
                   for start_y in range(total_height)
                   for height in range(total_height - start_y)]

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.