Bubble-wrap simülatörü yapın


23

Kabarcık tamamladı en üst seviye eğlencedir. Herkes buna katılabilir.

Şimdi, bilgisayarların bile köpüklü bezlerden hoşlanmasını sağlayacaksınız.

gözlük

W ve h olarak iki tam sayı verilecektir (her biri duyarlı bir şekilde genişlik ve yükseklik)

Programınız her biri arasında 1 saniye bekleyen tüm w * h aşamalarını vermeli ve sonlandırmalıdır.

Her baloncuk sarımı, tüm hücreler dolu halde başlar.

Örneğin, bir 4 * 6 balon sarımı şöyle başlar:

O_O_
_O_O
O_O_
_O_O
O_O_
_O_O

Ve her bir aşamada, rastgele patlamış olmayan bir hücre atıldı. Örneğin,

O_O_
_O_O
O_X_
_O_O
O_O_
_O_O

Tüm hücreler yerleştirildiğinde program sonlandırılmalıdır. diğer adıyla.

X_X_
_X_X
X_X_
_X_X
X_X_
_X_X

Örnekler

(4,6)
(5,5)
(6,2)
(10,10)
(7,9)

Kullandığımız Can 1ve 0yerine Ove X?
Pavel

1
NEEDZ BUBBLEZ pls yardım gönder
Christopher

3
Bir (1,1)kabarcığın olmaması kabul edilebilir mi (ör. Sol üst "hücre" her zaman alt çizgidir)?
Jonathan Allan,

1
@JonathanAllan Evet.
Matthew Roh

1
@KevinCruijssen Tam bir program olması gerekmez.
Matthew Roh

Yanıtlar:


7

C (Windows), 260 248 bayt

#import<windows.h>
i,j,l,r;b(w,h){char*s=malloc(l=w*h+h);for(i=h;i--;*s++=10)for(j=w;j--;*s++=i%2^j%2?79:45);*(s-1)=0;s-=l;for(srand(time(0));j>system("cls")+puts(s)-2;j>-1?s[j]=88:0)for(Sleep(1000),r=rand(),j=-2,i=r+l*2;--i-r;j=s[i%l]==79?i%l:j);}

enter image description here


Iş parçacığı kitaplığında C ++ 11'in içerdiği bir uyku işlevi olduğunu unutmayın.
Matthew Roh

@MatthewRoh Yep, ancak bu daha kısa ve system("cls")aynı zamanda Windows'a özgüdür, bu nedenle kod da iplik kütüphanesinde daha taşınabilir olmazdı. Ve C ++ ile de eklemeliyim iostreamya da cstdio.
Steadybox

Ekranı sıfırlamanız gerekmez. Bu daha kısa hale getirecek.
Matthew Roh

5

Python 3 , 222 220 bayt

Bu benim ilk defa cevap verdiğim için lütfen nazik olun (ve yaptığım hataları işaret edin).

import time,random as t
def f(c,r):
 p=print;a='0_'*c;d=((a[:c]+'\n'+a[1:c+1]+'\n')*r)[:-~c*r]
 for i in[1]*((r*c+r%2*c%2)//2):
  p(d);k=1
  while d[k]!='0':k=t.randrange(len(d))
  d=d[:k]+'X'+d[k+1:];time.sleep(1)
 p(d)

Çevrimiçi deneyin!

Nasıl çalışır:

  1. Zinciri çok '0 _' birlikte
  2. '0_0 _... \ n' ve '_0_0 ... \ n' bölümlerine doğrayın ve birleştirin
  3. Dizindeki karakter karakteri '0' olana kadar rasgele göstergeler oluşturun
  4. Oluşturulan dizindeki char ile yeni bir dize oluşturun. 'X' ile değiştirilir.
  5. Tekrarlanan r*c+r%2*c%2zamanlar: r*cr ve c'nin her ikisi de tuhaf olmadığı sürece, desende kabarcıklar vardır, bu durumda vardır r*c+1.

1
PPCG'ye Hoşgeldiniz!
AdmBorkBork

1
Bu oldukça küçük, ancak genişliğiniz ve yüksekliğiniz ters. Yine de harika cevap! (Sadece değiştirin f(c,r)ve iyi olacaksınız).
rassar

@rassar Woops, teşekkür ederim!
nil

4

MATL , 37 bayt

:!i:+o`T&Xxt3:q'_OX'XEcD2y1=ft&v1Zr(T

Sol üst köşe her zaman bir alt çizgidir (mücadelenin izin verdiği şekilde).

Ekran fazlar arasında temizlenir. Ekranı temizleyerek bir bayt kaydedemedim, ancak bu şekilde daha iyi görünüyor.

Tüm aşamaları gösterdikten sonra program bir hatayla ( varsayılan olarak izin verilir ) çıkar .

MATL Online'da deneyin ! (Birkaç saniye sonra çalışmazsa, lütfen sayfayı yenileyin ve tekrar deneyin).


4

Mathematica (145 bayt)

Anonim fonksiyonu, (bu sırayla - bir sorun ise, yerine girdi olarak yükseklik ve genişlik alır {##}olan {#2,#}ilave bir 2 bayt kod ortasında).

Kod:

Monitor[Do[Pause@1,{i,NestList[RandomChoice@StringReplaceList[#,"O"->"X"]&,""<>Riffle["_"["O"][[Mod[#+#2,2]]]&~Array~{##},"
"],Floor[##/2]]}],i]&

Açıklama:

  • ""<>Riffle[Array["_"["O"][[Mod[#+#2,2]]]&,{##}],"\n"] "_" s ve "O" s dizisi yaparak ve sonra bunları yeni satırlar arasında StringJoining yaparak ilk, açılmamış kabarcık sargısını yaratır.
  • NestList[RandomChoice@StringReplaceList[#,"O"->"X"]&,..., Floor[##/2]]"O" lardan birini "X" ile değiştirmek için "O" lardan birini tekrar tekrar seçer (bu, "O" s olduğu kadardır (bu, Floor [genişlik * yükseklik / 2] 'dir); Sol üst köşede "O" yerine ", aksi takdirde bu Ceilingyerine ve böylece 2 bayt daha).
  • Monitor[Do[Pause@1,{i,...}],i]markaları idinamik baskılar 1 saniye her biri için, sadece hesaplanan listede değerleri alır ve i.

Örnek çıktı:

GIF of Mathematica popping bubble-wrap


3

Jöle , 30 29 bayt

=”OTX
+þ⁹++µị⁾_OYµṄœS1”XǦµÐL

Example run

Bağlantıyı, program argümanlarına sahip bir dyad olarak çağırır ve daha sonra bir mesajla sonlandırılır. çṛ“\'=ṙMḋḌẓ(ėo» )

Nüans: Sağ alt "hücre" her zaman bir kabarcık olacaktır (sorudaki örnekte olduğu gibi sol üst kısımdan ziyade), bu, tüm baloncuklar patladığında rastgele seçimin o anda 0 olacağını döndürmesini "X"sağlamaktır. listenin sonu - bunun değiştirilmesi, değerde hiçbir değişiklik yapmaz ve döngüyü keser.

Not: Ekranı temizlemez (belirtilmedi ve nasıl yapılacağından emin değilim).

Nasıl?

=”OTX - Link 1, choose a random O index or 0: string   e.g. "_O_\nX_O"
 ”O   - "O"
=     - equals (vectorises over the string)            e.g. [0,1,0,0,0,0,1]
   T  - truthy indexes                                 e.g. [2,7]
    X - random choice (if empty this returns 0)

+þ⁹++µị⁾_OYµṄœS1”XǦµÐL - Main link: w, h              e.g. 3, 2
                        - left argument (implicit), w  e.g. 3
  ⁹                     - right argument, h            e.g. 2
 þ                      - outer product with
+                       -     addition                 e.g. [[2,3,4],[3,4,5]]
                        - left argument (implicit), w  e.g. 3
   +                    - add                          e.g. [[5,6,7],[6,7,8]]
                        - right argument (implicit), h e.g. 2
    +                   - add                          e.g. [[7,8,9],[8,9,10]]
     µ                  - monadic chain separation
       ⁾_O              - "_O"
      ị                 - index into (1-based & mod)   e.g. [['_','O','_'],['O','_','O']]
                        -     note: the additions above assure the last entry is an 'O'.
          Y             - join with line feeds         e.g. ['_','O','_','\n','O','_','O']
           µ        µ   - monadic chain separations
                     ÐL - loop until the results are no longer unique:
            Ṅ           -     print with a trailing line feed and yield
             œS1        -     sleep for 1 second and yield
                   ¦    -     apply to index
                  Ç     -         given by calling the last link (1) as a monad 
                        -                 (a random O index or 0 if none exists)
                ”X      -         an "X"  (      ... which will be an X already)

@ ГригорийПерельман yazdı.
Jonathan Allan

2

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 mapiçin haritanın indeksi ile birlikte kullanıyoruz ve sıkıştırdık. Bir dizinin doğruluk değerini, Xbir Oveya_ . Sonuncuyu seçmek için, dizin değerini rehberimiz olarak kullanırız.

Dikkat edilmesi gereken ilginç şeyler

Bir Oveya bir yazdırması gerekip gerekmediğini anlamak _için koşullu ((r._2 % 2) + c._2) % 2 == 0kullanılır. geçerli sütuna atıfta r._2bulunurken mevcut satır dizinini c._2ifade eder. Biri tek bir sıradaysa, r._2 % 21 olacaktır, bu nedenle c._2koş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. lprograma 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) / 2mantıklı olanı yaptım . nHer 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)

mapyerine forEachdaha 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 zipWithIndexdeğ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 zipWithIndexvar 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

JavaScript (ES6), 246 229 bayt

document.write(`<pre id=o></pre>`)
setInterval(_=>{(a=o.innerHTML.split(/(O)/))[1]?a[Math.random()*~-a.length|1]=`X`:0;o.innerHTML=a.join``},1e3)
f=(w,h)=>o.innerHTML=[...Array(h)].map((_,i)=>`O_`.repeat(w+h).substr(i,w)).join`
`
<div oninput=f(+w.value,+h.value)><input id=w type=number min=1><input id=h type=number min=1>


Genişlik, hücreler açısından değil, boşluk (altı çizili) boşluklar içeriyordu.
Matthew Roh

@MatthewRoh Üzgünüm, yüksekliği için düzeltmeyi hatırladım, ancak genişliği kontrol etmeyi unuttum.
Neil

Hmm .. bu kısım olamaz: bir `${`_O`.repeat(w).slice(w)} ${`O_`.repeat(w).slice(w)}şekilde kombine edilebilir mi? Muhtemelen bir boolean bayrağı önce belirleyecek, _Oya da O_sonra yapacak .repeat(w).slice(w)?
Kevin Cruijssen

1
@KevinCruijssen O sırada golf oynamaya vaktim olmadığından dolayı hızlı bir hata yüzünden 16 bayt kaybettim. O zamandan beri başka bir bakış açtım ve 17 baytlık bir tasarrufla geldim,
Neil

1

Python - 290 bayt

Bunlardan birini daha önce hiç yapmadım - bu yüzden yapıcı eleştirilerden memnun kalacaksınız :)

Buradaki temel numara sadece can sıkıcı şekilde iç içe geçmiş liste kavramalarıdır. Pops'lar arasında yeni bir satıra sahip olmadan birkaç karakter kaydedebilirim ama bu sadece çirkin görünüyor.

r=range
q=print
import random as n,time
def f(H,W):
    def p(b):
        q("\n".join(["".join(["O"if(i,j)in b else"X"if(i,j)in X else"_"for j in r(H)])for i in r(W)]));time.sleep(1);q()
    b=[(i,h)for h in r(H)for i in r(h%2,W,2)];n.shuffle(b);X=[]
    while len(b)>0:
        p(b);X+=[b.pop()]
    p(b)

Merhaba, PPCG'ye hoş geldiniz! Meydan almaktı wve hyerine kodlanmış olma, (bir işlev girişi veya benzer bir şey olarak, STDIN'den aracılığıyla) girdi olarak H=4 W=6. Ayrıca, Python'da hiç programlanmadığım halde, şu anki kodunuzda bazı alanlarda golf oynayabileceğinizi düşünüyorum. Python'da Golf için İpuçları, daha fazla nasıl golf oynayacağınız konusunda fikir vermek için okumaktan ilginç olabilir. Kaldınız! :)
Kevin Cruijssen

Ayrıca, yorumunuzla ilgili olarak: " Pops'lar arasında yeni bir çizgiye sahip olmadan birkaç karakterden tasarruf edebilirim, ancak bu sadece çirkin görünüyor. " mümkün olduğu kadar çok bayt. Ne kadar kısa ve çirkin, o kadar iyi. ;)
Kevin Cruijssen

@KevinCruijssen benim üstümdeki Python3 bir w işlevi var, h, bu izin veriliyor mu?
Arya


1
Tamam - Şimdi H ve W işlevini yaptım.
Arya

1

Kömür , 49 46 39 bayt (rekabetçi olmayan)

UONNO_¶_OAKAαA№αOβHWψβ«A§α§⌕AαO‽βXA№αOβ

gereksiz sözlerle dolu

Oblong(InputNumber(), InputNumber(), "O_\n_O")
Assign(PeekAll(), a)
Assign(Count(a, "O"), b)
RefreshWhile (k, b) {
    AssignAtIndex(a, AtIndex(FindAll(a, "O"), Random(b)), "X")
    Assign(Count(a, "O"), b)
}

1

APL (Dyalog) , 61 59 bayt

⎕←m'O_'[2|-/¨⍳⎕]
(b/,m)[?+/b'O'=,m]←'X'
DL 1
2/⍨'O'∊⎕←m

⎕← çıkış
m←m , m olan
'O_'[... ] ... tarafından endeksli bu karakterler
2| bölme-kalanı bölünmüş--iki bölgesinin
-/¨ her biri arasındaki fark
 tüm koordinatlar (endeksler) şekli, bir dizi
 sayısal giriş (satır ve sütun sayısı )

(... )[... ]←'X' ... birine karakter X atamak
b/ süzülmüş-by- b (tanımlanacaktır)
,m m, özellikle ... elemanlarını raveled
? aralığında bir rasgele elemanının (lit. numarası)
+/ toplamı
b←b , b bir
'O'= Boole mektup eşittir nereye
,mm raveled

⎕DL 1D E l ay bir saniye

→2 Hat 2 git
/⍨ (lit. ile filtre edilmiş) halinde
'O'∊ harfli bir üyesi olup olmadığını
⎕←m burada, çıktı değeridir, çıktı değeri, m

Çevrimiçi deneyin!


16.0 sürümünden itibaren daha kısa olacak:

{0::→⋄'X'@(⊂(?∘≢⊃⊢)⍸'O'=⍵⊣⎕DL 1)⊢⎕←⍵}⍣≡'O_'[2|-/¨⍳⎕]


1

Python 3, 195 188 bayt

import time,random
def f(w,h):
 a=bytearray(b'0-'*w*h);b=[*range(0,w*h,2)];random.shuffle(b);
 while 1:print(*(a.decode()[w*i:w*i+w]for i in range(h)),sep='\n');a[b.pop()]=88;time.sleep(1)

Kullanmak bytearrayve decodedilimlemekten daha kısa görünmektedir vea[:i]+'X'+a[i+1:] .

import time,random
def f(w,h):
 x=[*range(1,h*w,2)];random.shuffle(x)
 while 1:
  for i in range(w*h):
   print('-X0'[(i%w%2!=i//w%2)+(i in x)],end='\n'[i%w<w-1:])
  print();time.sleep(1);x.pop()

0

Java 7, 317 bayt

void c(int w,int h)throws Exception{String r="";int x=0,j=0,i;for(;j++<h;x^=1,r+="\n")for(i=0;i<w;r+=(i+++x)%2<1?"_":"O");for(System.out.println(r);r.contains("O");System.out.println(r=r.substring(0,x)+'X'+r.substring(x+1))){Thread.sleep(1000);for(x=0;r.charAt(x)!='O';x=new java.util.Random().nextInt(r.length()));}}

Açıklama:

void c(int w, int h) throws Exception{                     // Method with two integer parameters (throws Exception is required for the Thread.sleep)
  String r = "";                                           //  String we build to print
  int x=0, j=0, i;                                         //  Some temp values and indexes we use
  for(; j++<h;                                             //  Loop over the height 
      x^=1,                                                //    After every iteration change the flag `x` every iteration from 0 to 1, or vice-versa
      r += "\n")                                           //    And append the String with a new-line
    for(i=0; i<w;                                          //   Inner loop over the width
        r += (i++ + x)%2 < 1 ? "_" : "O")                  //    Append the String with either '_' or 'O' based on the row and flag-integer
    ;                                                      //   End inner width-loop (implicit / no body)
                                                           //  End height-loop (implicit / single-line body)
  for(                                                     //  Loop
    System.out.println(r);                                 //   Start by printing the starting wrap
    r.contains("O");                                       //   Continue loop as long as the String contains an 'O'
    System.out.println(r=                                  //   Print the changed String after every iteration
        r.substring(0,x)+'X'+r.substring(x+1))){           //    After we've replaced a random 'O' with 'X'
      Thread.sleep(1000);                                  //   Wait 1 second
      for(x=0; r.charAt(x) != 'O';                         //   Loop until we've found a random index containing still containing an 'O'
          x = new java.util.Random().nextInt(r.length()))  //    Select a random index in the String
      ;                                                    //   End loop that determines random index containing 'O' (implicit / no body)
  }                                                        //  End loop
}                                                          // End method

Test gif (4,6)

görüntü tanımını buraya girin


0

Perl, 148 bayt

146 bayt kod + -plbayrakları.

$_=O x($x=$_+1);s/O\K./_/g;for$i(1..($y=<>)){$b.=($i%2?$_:_.s/.$//r).$/}}print$_="\e[H$b";while(/O/){$r=0|rand$y*$x+3;s/.{$r}\KO/X/s||redo;sleep 1

Çalıştırmak için:

perl -ple '$_=O x($x=$_+1);s/O\K./_/g;for$i(1..($y=<>)){$b.=($i%2?$_:_.s/.$//r).$/}}print$_="\e[H$b";while(/O/){$r=0|rand$y*$x+3;s/.{$r}\KO/X/s||redo;sleep 1' <<< "6
4"

0

MATLAB (R2016b), 172 bayt

Kod:

x=input('');m=[eye(x(2),x(1)) ''];m(:)='O';m(1:2:end,2:2:end)='_';m(2:2:end,1:2:end)='_';o=find(m=='O');r=o(randperm(nnz(o)));disp(m);for i=r';pause(1);m(i)='X';disp(m);end

Öneriler her zaman beklerim! Çevrimiçi deneyin!

Program Çıktısı:

görüntü tanımını buraya girin

Açıklama:

x = input( '' );                    % Input
m = [ eye( x( 2 ), x( 1 ) ) '' ];   % Character Matrix
m( : ) = 'O';                       % Fill Matrix with "Bubbles"

m( 1:2:end, 2:2:end ) = '_';        % Alternate Spaces Between Bubbles (Part 1)
m( 2:2:end, 1:2:end ) = '_';        % Alternate Spaces Between Bubbles (Part 2)

o = find( m == 'O' );               % Index Bubble Locations
r = o( randperm( nnz( o ) ) );      % Randomize Bubble Locations

disp( m );                          % Display Initial Bubble Wrap Phase

for i = r'
    pause( 1 );                     % Pause for 1 Second
    m( i ) = 'X';                   % Pop Bubble
    disp( m );                      % Display Subsequent Bubble Wrap Phase
end
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.