Tetris Tangramları


13

Giriş

Tangrams , blokları çeşitli şekillere yerleştirmeyi / yerleştirmeyi içeren klasik bir bilmecedir. Çin 七巧板 - kelimenin tam anlamıyla "yedi beceri kurulu" anlamına gelir. Bu fikri ele alalım ve bir ızgarayı doldurmak için yedi Tetrominos parçasını kullanalım .

Meydan okuma

Bir dizi ızgara koordinat dizisini girdi olarak alan ve belirtilen koordinatlar dışında Tetris parçalarıyla dolu tamamlanmış 10-20 ızgara çıktısı veren bir işlev veya program yazın.

Parçaların dağılımını eşit tutmaya çalışarak puanınızı optimize edin.

Kriterler

Görevinizi gerçekleştirmek için bu koordinat hamurunu kullanın . Beş takım koordinat vardır. Koordinatların yazıldığı biçimi değiştirmekten çekinmeyin, ancak değerleri değiştirmeyin.

Veri kümesi # 2 çözülemez - bu durumda, ızgarayı giriş hücreleri doldurulmuş olarak (yani, Xdeliklerin bulunduğu yerler) çıktılayın.

Giriş

Izgara koordinatları, ızgaradaki 'delikleri' temsil eder. Bunlar bir Tetromino'nun herhangi bir bölümünü içeremeyen hücrelerdir.

Izgara koordinatları:

(0,0), (1,0), (2,0), ... (9,0)
(0,1), (1,1), (2,1), ... (9,1)
.
.
.
(0,19), (1,19), (2,19), ... (9,19)

Çıktı

20 hücre boyunda 10 hücre genişliğinde standart bir Tetris ızgara boyutu kullanarak , ancak ızgara Tetromino parçaları kullanılarak tamamen ve mükemmel bir şekilde doldurulabiliyorsa bir çözüm ızgarası yazdırın.

Harfleriyle inşa adet I, O, L, J, T, Z, Saşağıdaki gibi:

I          
I          L      J
I    OO    L      J     T     ZZ      SS
I    OO    LL    JJ    TTT     ZZ    SS

Misal

Giriş koordinatı olmayan çıktı çözümü örneği:

ZZIIIILLLI
JZZTTTLLLI
JJJSTLOOLI
SZZSSLOOLI
SSZZSLLJJI
TSOOSLLJII
TTOOSSLJII
TZOOSSLZII
ZZOOSSZZII
ZJJJJSZLLI
TTTJJOOILI
ITZJJOOILI
IZZTTTLIII
IZOOTZLIII
IJOOZZLLII
LJJJZSSTII
LLLTSSTTTI
LLLTTSSZJI
OOLTSSZZJI
OOIIIIZJJI

Dağıtım ile aşağıdaki gibi:

I          
I          L      J
I    OO    L      J     T     ZZ      SS
I    OO    LL    JJ    TTT     ZZ    SS

11   6     8     6      6     7      6

notlar

Koordinatlar bir tek Xve Yızgaradaki konumu temsil eder . Izgara 0 tabanlıdır, yani koordinat (0,0)ya sol üst ya da sol alt hücre olmalıdır, yazarın tercihi.

Tuğla şunları yapabilir:

  • yazarın takdirine bağlı olarak seçilmelidir.
  • yazarın uygun gördüğü şekilde döndürülmelidir.
  • ızgaraya yazarın inisiyatifinde herhangi bir yere yerleştirilebilir (aka: Tetris yerçekimi yok)

Tuğlalar şunları yapamaz:

  • ızgara sınırlarının dışına yerleştirilmelidir.
  • ızgaradaki mevcut bir tuğla veya deliğin üstüne biner.
  • standart olmayan bir Tetris tetromino parçası olabilir.

puanlama

Puanınız şu biçimde:

(1000 - [koddaki bayt]) * (M / 10 + 1)

M, çözüm setlerinizde kullanılan parçaların dağılımı için bir çarpandır.

Mart ayının en yüksek puanı kazanır.

M'yi hesaplamak için, her set için en düşük bireysel tetromino dağılım değerini ekleyin ve ardından M'yi hesaplamak için yuvarlanmış ortalamayı alın.

Örneğin:

Set 1: 5
Set 2: 4
Set 3: 5
Set 4: 6
Set 5: 3

6 + 4 + 5 + 4 + 4 = 21/5 = 4.6

Böylece M değeriniz 4olarak kullanabilirsiniz .

Not: Bir kümenin çözümü yoksa, tetromino dağılımı olmayacağı için M'nin hesaplanmasına dahil edilen faktörleri dikkate almayın.


4
Soruları gönderildikten sonra iyileştirmek genellikle zordur, çünkü değişiklikler önemliyse, sorun üzerinde zaten çalışmaya başlamış (veya daha da kötüsü, sonucu bile yayınlamış) insanların çalışmalarını geçersiz kılacaktır. Kum havuzunda meydan okuma fikirleri göndermenizi tavsiye ederim . Geri bildirim istemek ve ana gitmeden önce spec cilalamak için yer budur . Bununla birlikte, hızlı bir gözden geçirdikten sonra, meydan okumanızla ilgili göze çarpan sorunlar görmedim.
Martin Ender

@ MartinBüttner Usulüne uygun olarak geri bildirim için teşekkür ederiz.
CzarMatt

2
Ides Mart = 15 Mart. Buna bakmam gerekiyordu.
Level River St

Görev açıklamasını önden yüklemek için bazı küçük değişiklikler yaptım, aksi takdirde ilk okumada ne yapmamızı istediğimizi anlamak imkansız. Girdi vakalarından hangilerinin çözülemeyeceğini belirttiyseniz, bir puanlama veri kümesine ek olarak test senaryoları olarak işlev görmeleri gerektiğini düşünüyorum.
Peter Taylor

@PeterTaylor Fair, hangi çözüm setinin çözülemeyeceğini ekledim. Geri dönüşünüz için teşekkür ederiz.
CzarMatt

Yanıtlar:


2

Python 3 , 819 bayt, M = 0, Puan = 181

Bu kaba kuvvet DFS programıdır. Bir numpy dizisi oluşturur ve girilen tüm delikleri ekler. Daha sonra, en soldaki dolgusuz döşemeyi bir tane olan en yüksek sıraya alır ve bir tetromino yerleştirir. Yinelemeli olarak, şimdi tekrar yapıyoruz - ya bir çözüm bulamadığımızda ya da geri dönüp ilk fırsatta başka bir parça deniyoruz.

Bu sahiptir M o, belli bir düzen içinde parçalarını kullanmaya çalışır ve hemen hemen her zaman listedeki sonuncusu olmadan bir çözüm bulur, çünkü 0. Ben daha eşit dağılımını yapmak için rastgele sıralı listesine her döngüsü kullanarak çalıştı, ama ben sadece bir got M ithalat için gerekli bayt değmez 2, random.shuffle .

Aşağıdaki kod yorum yapamam, çünkü benim golf uzun ne yaptığını unuttum. Genel fikir:

  • 1 harfli adlarla numpy ve itertools ürününü içe aktarma
  • Bazı yerleşikleri 1 harfli işlevler olarak yeniden adlandırın ve baytları kaydetmek için bir lambda tanımlayın
  • Mümkün olan diziler gibi olası tetromino dizisini oluşturun, tüm dönüşler dahil
  • Özyinelemeli işlevde:
    • Doldurulmamış döşemenin pozisyonunu istediğiniz şekilde alın ve parça listesinde gezinin
    • Her parça için çevirileri arasında geçiş yapın (yukarı ve aşağı hareket ettirerek)
    • Bir şey işe yaramazsa (parça tahtadan çıkar, başka bir parçaya vurur, bir delik açar, vb.), Bir sonraki çeviriyi veya bir sonraki parçanın tamamını deneyin
    • Çalışırsa harika. Deneyin, ardından işlevi tekrar tekrar çağırın.
    • Bu yol işe yaramazsa, 'a' döndürür, bu yüzden sadece tekrar deneriz. Eğer işe yaradıysa, tahtaya geri döner ve çizgiyi geçiyoruz.
  • Son olarak, program. 10x20 kartını 1'li bir numpy dizisi olarak inşa ediyoruz.
  • Giriş (x1, y1) biçimindedir ; (x2, y2); ... İçindeki her delik için bir 9 koyarız, ardından işlevi üzerinde çalıştırmanın sonucunu alırız.
  • Daha sonra print deyimi, başarılı sonucu veya boş, orijinal kartı satır satır görüntüler ve sayılar için uygun harfleri veya simgeleri değiştirir.
import numpy as n
from itertools import product as e
m,s=range,len
p=[n.rot90(a,k)for a,r in[([[2,2]]*2,1),([[3]*3,[1,3,1]],4),([[0]*4],2),([[1,1,6],[6]*3],4),([[7,1,1],[7]*3],4),([[4,4,1],[1,4,4]],2),([[1,5,5],[5,5,1]],2)]for k in m(r)]
o=lambda a:e(m(s(a)),m(s(a[0])))
def t(l,d=0):
	g=list(zip(*n.where(l==1)))[0]
	for a in p:
		for u,v in o(a):
			w,x=l.copy(),0
			for r,c in o(a):
				if a[r,c]!=1:
					i,j=g[0]+r-u,g[1]+c-v
					if any([i<0,i>19,j<0,j>9])or l[i,j]!=1:
						x=1
						break
					w[i,j]=a[r,c]
			if x==0:
				if len(w[w==1]):
					f=t(w,d+1)
					if type(f)==str:continue
					return f
				return w
	return'a'
b=n.ones((20,10))
b[list(zip(*[eval(k)[::-1]for k in input().split(';')]))]=9
a=t(b)
for r in(a,b)[type(a)==str]:
	print(''.join(map(dict(zip([0,2,3,4,5,6,7,9,1],'IOTZSLJX-')).get,r)))

Çevrimiçi deneyin!

Örnek test:

In: (1,1);(8,1);(4,4);(5,8);(4,11);(5,15);(1,18);(8,18)
Out: 
IIIIOOOOLL
TXOOOOOOXL
TTOOOOOOTL
TOOIOOOOTT
TOOIXOOTTI
TTTITOOTTI
TTTITTTTII
OOTTTTTTII
OOTTTXOOII
TTTTOOOOII
TTTTOOOOII
TTTTXTOOII
ITTTTTTTII
ITTTTTTTII
IITTTLLTTI
IITOOXLTTI
IITOOTLTTI
IITTLTTTTI
IXTLLTJTXI
ILLLLLJJJI

1
Ah benim - bu inanılmaz. Harika yazma ve güzel çalışma için teşekkürler!
CzarMatt
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.