Scala , 764 bayt
object B{
def main(a: Array[String]):Unit={
val v=false
val (m,l,k,r,n)=(()=>print("\033[H\033[2J\n"),a(0)toInt,a(1)toInt,scala.util.Random,print _)
val e=Seq.fill(k, l)(v)
m()
(0 to (l*k)/2-(l*k+1)%2).foldLeft(e){(q,_)=>
val a=q.zipWithIndex.map(r => r._1.zipWithIndex.filter(c=>
if(((r._2 % 2) + c._2)%2==0)!c._1 else v)).zipWithIndex.filter(_._1.length > 0)
val f=r.nextInt(a.length)
val s=r.nextInt(a(f)._1.length)
val i=(a(f)._2,a(f)._1(s)._2)
Thread.sleep(1000)
m()
val b=q.updated(i._1, q(i._1).updated(i._2, !v))
b.zipWithIndex.map{r=>
r._1.zipWithIndex.map(c=>if(c._1)n("X")else if(((r._2 % 2)+c._2)%2==0)n("O")else n("_"))
n("\n")
}
b
}
}
}
Nasıl çalışır
Algoritma ilk önce 2B Diziyi yanlış değerlerle doldurur. Girilen komut satırı argümanlarına dayanarak kaç tane yineleme (açık kutu) bulunduğunu belirler. Bu değerle üst sınır olarak bir kat oluşturur. Katlamanın tamsayı değeri yalnızca algoritmanın kaç yinelemeyi çalıştırması gerektiğini saymanın bir yolu olarak kullanılır. Daha önce yarattığımız doldurulmuş dizi, katlamanın başlangıç dizisidir. Bu, uyumlu indeksleri ile birlikte yeni bir 2B yanlış değer dizisi oluşturulmasında kullanılır.
Örneğin,
[[false, true],
[true, false],
[true, true]]
Dönüşecek
[[(false, 0)], [(false, 1)]]
Tamamen doğru olan (0 uzunluğa sahip) tüm listelerin sonuç listesinden çıkarıldığını unutmayın. Daha sonra algoritma bu listeyi alır ve en dıştaki listeye rastgele bir liste seçer. Rastgele liste, seçtiğimiz rastgele satır olarak seçilir. Bu rastgele satırdan tekrar rasgele bir sayı bulduk, bir sütun dizini. Bu iki rastgele indeksi bulduktan sonra, 1000 milisaniye boyunca açık olduğumuz ipliği uyuyalım.
Uyuduktan sonra, ekranı temizledik ve yeni bir pano oluşturduk. true
rasgele endekslerde güncellenen değeri oluştururuz.
Bunu doğru bir şekilde yazdırmak map
için haritanın indeksi ile birlikte kullanıyoruz ve sıkıştırdık. Bir dizinin doğruluk değerini, X
bir O
veya_
. Sonuncuyu seçmek için, dizin değerini rehberimiz olarak kullanırız.
Dikkat edilmesi gereken ilginç şeyler
Bir O
veya bir yazdırması gerekip gerekmediğini anlamak _
için koşullu ((r._2 % 2) + c._2) % 2 == 0
kullanılır. geçerli sütuna atıfta r._2
bulunurken mevcut satır dizinini c._2
ifade eder. Biri tek bir sıradaysa, r._2 % 2
1 olacaktır, bu nedenle c._2
koşullu olarak bir ofset . Bu, tek satırlarda sütunların istenildiği gibi 1 oranında hareket ettirilmesini sağlar.
Dizenin basılması "\033[H\033[2J\n"
basmak, okuduğum bazı Stackoverflow cevaplarına göre ekranı temizliyor. Terminale bayt yazıyor ve gerçekten anlamadığım bazı korkak şeyler yapıyor. Ama bunu yapmanın en kolay yolu buldum. Yine de, Intellij IDEA'nın konsol emülatörü üzerinde çalışmıyor. Düzenli bir terminal kullanarak çalıştırmanız gerekecek.
Başka bir denklem, bu koda ilk ne zaman bakıldığında görmek garip bulabilir (l * k) / 2 - (l * k + 1) % 2
. İlk olarak, değişken isimlerinin ismini açıklayalım. l
programa iletilen ilk argümanları k
, ikincisini ifade eder. Tercüme etmek (first * second) / 2 - (first * second + 1) % 2
,. Bu denklemin amacı, tüm X'lerin bir sırasını elde etmek için gereken tam tekrarlamaları bulmaktır. Bunu ilk yaptığımda, (first * second) / 2
mantıklı olanı yaptım . n
Her alt listedeki her eleman için var . İki sayının çarpımını hesaplamalıyız, eşitse bile tuhaf hale getirmeliyiz, hatta tuhaf olsa bile, ve sonra da 2 modunu almalıyız. nihai sonuca varmak için.n / 2
kabarcıklar . Ancak, bu gibi girdilerle uğraşırken kırılır.(11 13)
map
yerine forEach
daha az karakter içerdiğinden kullanılır .
Muhtemelen geliştirilebilir şeyler
Bu çözüm hakkında beni gerçekten rahatsız eden şeylerden biri de sıkça kullanılması zipWithIndex
. Çok fazla karakter alıyor. Yapmaya çalıştım, böylece sadece girilen zipWithIndex
değerle gerçekleştirilecek kendi karakter işlevimi tanımlayabildim . Fakat Scala'nın adsız bir işlevin tür parametrelerine sahip olmasına izin vermediği ortaya çıktı. Muhtemelen kullanmadan yaptığımı yapmanın başka bir yolu zipWithIndex
var ama yapmanın akıllıca bir yolu hakkında çok fazla düşünmedim.
Şu anda, kod iki geçişte çalışır. Birincisi yeni bir tahta oluşturur, ikincisi ise onu basar. Biri, bu iki geçişi bir geçişte birleştirecek olsaydı, bu bir kaç bayt kurtaracaktı.
Bu yaptığım ilk kod golf, bu yüzden iyileştirme için çok yer olduğuna eminim. Mümkün olduğunca bayt için optimize etmeden önce kodu görmek istersen, işte burada.
1
ve0
yerineO
veX
?