Buat simulator Bubble-wrap


23

Bubble-wraps adalah hiburan tingkat maksimum. Semua orang bisa menyetujui itu.

Sekarang, Anda akan membuat komputer lebih menikmati gelembung.

Spesifikasi

Anda akan diberi dua bilangan bulat, w, dan h. (Masing-masing lebar dan tinggi responsif)

Program Anda harus menampilkan semua fase w, menunggu 1 detik antara masing-masing dan berakhir

Setiap bungkus gelembung dimulai dengan semua sel penuh.

Misalnya, bungkus gelembung 4 * 6 dimulai seperti:

O_O_
_O_O
O_O_
_O_O
O_O_
_O_O

Dan setiap fase, sel acak yang tidak muncul muncul. Misalnya,

O_O_
_O_O
O_X_
_O_O
O_O_
_O_O

Program harus berhenti ketika semua sel muncul. alias.

X_X_
_X_X
X_X_
_X_X
X_X_
_X_X

Contohnya

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

Bisakah kita menggunakan 1dan 0bukannya Odan X?
Pavel

1
NEEDZ BUBBLEZ mohon kirimkan bantuan
Christopher

3
Apakah dapat diterima jika a (1,1)tidak memiliki gelembung (mis. "Sel" kiri atas selalu berupa garis bawah)?
Jonathan Allan

1
@ JonathanAllan Ya.
Matius Roh

1
@KevinCruijssen Tidak harus berupa program lengkap.
Matthew Roh

Jawaban:


7

C (Windows), 260 248 byte

#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);}

masukkan deskripsi gambar di sini


Perhatikan bahwa ada fungsi tidur di pustaka utas, yang termasuk dalam C ++ 11.
Matius Roh

@ MatthewRoh Yap, tapi ini lebih pendek, dan system("cls")ini juga khusus Windows, jadi kodenya tidak akan lebih portabel dengan pustaka thread. Dan dengan C ++ saya juga perlu memasukkan iostreamatau cstdio.
Steadybox

tapi Anda tidak perlu mengatur ulang layar. itu akan membuatnya lebih pendek.
Matthew Roh

5

Python 3 , 222 220 byte

Ini adalah pertama kalinya saya menjawab, jadi harap bersikap lembut (dan tunjukkan kesalahan yang telah saya buat).

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)

Cobalah online!

Bagaimana itu bekerja:

  1. Rantai banyak '0 _' bersama
  2. Potong bagian '0_0 _... \ n' dan '_0_0 ... \ n' dan gabungkan
  3. Hasilkan indeks acak hingga arang pada indeks adalah '0'
  4. Buat string baru dengan char di indeks yang dihasilkan diganti dengan 'X' (Sialan Anda python untuk string yang tidak bisa diubah!)
  5. Ulangi r*c+r%2*c%2waktu: Ada r*cgelembung dalam pola, kecuali r dan c keduanya aneh, dalam hal ini ada r*c+1.

1
Selamat datang di PPCG!
AdmBorkBork

1
Ini agak kecil, tetapi lebar dan tinggi Anda terbalik. Jawaban yang bagus! (Ubah saja f(c,r)dan Anda akan baik-baik saja).
rassar

@rassar Woops, terima kasih!
nil

4

MATL , 37 byte

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

Sudut kiri atas selalu berupa garis bawah (diizinkan oleh tantangan).

Layar dihapus di antara fase. Saya bisa menghemat satu byte dengan tidak membersihkan layar, tetapi tampilannya lebih baik seperti ini.

Program keluar dengan kesalahan ( diizinkan secara default ) setelah menampilkan semua fase.

Cobalah di MATL Online! (Jika tidak berfungsi setelah beberapa detik, segarkan halaman dan coba lagi).


4

Mathematica (145 bytes)

Fungsi anonim, mengambil tinggi dan lebar sebagai input (dalam urutan itu - jika itu masalah, ganti {##}dengan {#2,#}di tengah kode untuk tambahan 2 byte).

Kode:

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

Penjelasan:

  • ""<>Riffle[Array["_"["O"][[Mod[#+#2,2]]]&,{##}],"\n"] membuat wrap-wrap awal yang tidak terpancing, dengan membuat array "_" dan "O" lalu StringJoining mereka di antara baris baru.
  • NestList[RandomChoice@StringReplaceList[#,"O"->"X"]&,..., Floor[##/2]] berulang kali memilih salah satu dari "O" untuk menggantikan dengan "X", sebanyak yang ada "O" (yaitu Lantai [lebar * tinggi / 2] - terima kasih kepada @JonathanAllan untuk ide menempatkan "_ "Bukan" O "di sudut kiri atas, kalau tidak, ini akan menjadi Ceiling 2 byte lebih banyak).
  • Monitor[Do[Pause@1,{i,...}],i]make imengambil nilai dalam daftar yang baru saja kita hitung, masing-masing untuk 1 detik, dan dicetak secara dinamis i.

Contoh output:

GIF dari Mathematica muncul bubble-wrap


3

Jelly , 30 29 byte

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

Contoh dijalankan

Memanggil tautan sebagai angka dua dengan argumen program dan kemudian berhenti dengan pesan (kode untuk itu çṛ“\'=ṙMḋḌẓ(ėo» )

Nuansa: "sel" kanan-bawah akan selalu berupa gelembung (daripada bagian kiri atas seperti contoh dalam pertanyaan), ini untuk memastikan bahwa ketika semua gelembung muncul, pilihan acak mengembalikan 0 yang akan menjadi "X"pada akhir daftar - mengganti yang kemudian tidak membuat perubahan pada nilai dan memutus loop.

Catatan: tidak menghapus layar (tidak ditentukan, dan saya tidak yakin bagaimana melakukannya).

Bagaimana?

=”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)

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

2

Scala , 764 byte

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
    }
  }
}

Bagaimana itu bekerja

Algoritme pertama mengisi Urutan 2D dengan nilai-nilai salah. Ini menentukan berapa banyak iterasi (kotak terbuka) yang ada berdasarkan argumen baris perintah yang dimasukkan. Ini menciptakan lipatan dengan nilai ini sebagai batas atas. Nilai integer dari lipatan hanya digunakan secara implisit sebagai cara untuk menghitung berapa banyak iterasi yang harus dijalankan oleh algoritma. Urutan diisi yang kita buat sebelumnya adalah urutan awal untuk lipatan. Ini digunakan dalam menghasilkan urutan 2D baru dari nilai palsu dengan indek cooresponding mereka.

Sebagai contoh,

[[false, true],
 [true, false],
 [true, true]]

Akan diubah menjadi

[[(false, 0)], [(false, 1)]]

Perhatikan bahwa semua daftar yang sepenuhnya benar (memiliki panjang 0) dihilangkan dari daftar hasil. Algoritme kemudian mengambil daftar ini dan memilih daftar acak di daftar terluar. Daftar acak dipilih sebagai baris acak yang kita pilih. Dari baris acak itu, kita kembali menemukan angka acak, indeks kolom. Setelah kami menemukan dua indeks acak ini, kami tidur utasnya selama 1000 milidetik.

Setelah kami selesai tidur, kami membersihkan layar dan membuat papan baru dengan true nilai yang diperbarui dalam indeks acak yang telah kami buat.

Untuk mencetak ini dengan benar, kami menggunakan mapdan zip dengan indeks peta sehingga kami memilikinya dalam konteks kami. Kami menggunakan nilai kebenaran dari urutan, apakah kami harus mencetak Xatau salah satu Oatau_ . Untuk memilih yang terakhir, kami menggunakan nilai indeks sebagai panduan kami.

Hal-hal menarik untuk diperhatikan

Untuk mengetahui apakah harus mencetak Oatau _, kondisi ((r._2 % 2) + c._2) % 2 == 0digunakan. r._2merujuk ke indeks baris saat ini sementara c._2mengacu pada kolom saat ini. Jika seseorang berada di baris aneh, r._2 % 2akan menjadi 1, oleh karena itu mengimbangi c._2dengan satu di kondisi. Ini memastikan bahwa pada baris ganjil, kolom dipindahkan oleh 1 sebagaimana dimaksud.

Mencetak string "\033[H\033[2J\n", menurut beberapa jawaban Stackoverflow yang saya baca, membersihkan layar. Ini menulis byte ke terminal dan melakukan beberapa hal funky yang saya tidak begitu mengerti. Tetapi saya telah menemukan ini sebagai cara termudah untuk melakukannya. Ini tidak bekerja pada emulator konsol Intellij IDEA. Anda harus menjalankannya menggunakan terminal reguler.

Persamaan lain yang mungkin aneh untuk dilihat ketika pertama kali melihat kode ini adalah (l * k) / 2 - (l * k + 1) % 2. Pertama, mari kita demistifikasikan nama-nama variabel. lmengacu pada argumen pertama yang diteruskan ke program sementara kmengacu pada argumen kedua. Untuk menerjemahkannya (first * second) / 2 - (first * second + 1) % 2,. Tujuan dari persamaan ini adalah untuk menghasilkan jumlah iterasi yang dibutuhkan untuk mendapatkan urutan semua X. Pertama kali saya melakukan ini, saya hanya melakukan (first * second) / 2itu masuk akal. Untuk setiap nelemen di setiap sublist, ada n / 2gelembung yang dapat kami pop. Namun, ini rusak ketika berhadapan dengan input seperti(11 13). Kita perlu menghitung produk dari dua angka, membuatnya aneh jika itu genap, dan bahkan jika itu aneh, dan kemudian mengambil mod itu dengan 2. Ini bekerja karena baris dan kolom yang aneh akan membutuhkan satu iterasi lebih sedikit untuk sampai ke hasil akhir.

mapdigunakan sebagai ganti forEachkarena memiliki lebih sedikit karakter.

Hal-hal yang mungkin bisa diperbaiki

Satu hal yang benar-benar mengganggu saya tentang solusi ini adalah seringnya menggunakan zipWithIndex. Itu mengambil begitu banyak karakter. Saya mencoba membuatnya sehingga saya bisa mendefinisikan fungsi satu karakter saya sendiri yang hanya akan tampil zipWithIndexdengan nilai yang diteruskan. Tetapi ternyata Scala tidak mengizinkan fungsi anonim memiliki parameter tipe. Mungkin ada cara lain untuk melakukan apa yang saya lakukan tanpa menggunakan zipWithIndextetapi saya belum terlalu memikirkan cara cerdas untuk melakukannya.

Saat ini, kode berjalan dalam dua lintasan. Yang pertama menghasilkan papan baru sementara yang kedua mencetaknya. Saya pikir jika seseorang menggabungkan dua lintasan ini menjadi satu lintasan, itu akan menghemat beberapa byte.

Ini adalah golf kode pertama yang saya lakukan sehingga saya yakin ada banyak ruang untuk perbaikan. Jika Anda ingin melihat kode sebelum saya mengoptimalkan byte sebanyak mungkin, ini dia.


1

JavaScript (ES6), 246 229 byte

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>


Lebar tidak dalam hal sel - tetapi termasuk spasi kosong (garis bawah).
Matthew Roh

@ MatthewRoh Maaf, saya ingat untuk memperbaikinya tetapi saya lupa untuk memeriksa lebarnya.
Neil

Hmm .. tidak bisakah bagian ini: `${`_O`.repeat(w).slice(w)} ${`O_`.repeat(w).slice(w)}entah bagaimana digabungkan? Mungkin boolean-flag untuk menentukan _Oatau O_, dan kemudian melakukan .repeat(w).slice(w)?
Kevin Cruijssen

1
@KevinCruijssen Saya kehilangan 16 byte karena perbaikan bug cepat yang saya belum sempat main golf saat itu. Sejak itu saya melihat lagi dan menghasilkan penghematan 17 byte,
Neil

1

Python - 290 byte

Saya belum pernah melakukan ini sebelumnya - jadi kritik konstruktif apa pun akan dihargai :)

Trik utama di sini adalah hanya daftar pemahaman bersarang mengganggu. Saya bisa menyimpan beberapa karakter dengan tidak memiliki baris baru di antara pops tetapi itu hanya terlihat jelek.

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)

Hai, selamat datang di PPCG! Tantangannya adalah untuk mengambil wdan hsebagai input (melalui STDIN, sebagai input fungsi, atau yang serupa), alih-alih memiliki hardcoded H=4 W=6. Juga, meskipun saya tidak pernah memprogram dalam Python, saya pikir Anda dapat bermain golf beberapa ruang dalam kode Anda saat ini. Tips untuk Bermain Golf dengan Python mungkin juga menarik untuk dibaca untuk memberi Anda ide tentang cara bermain golf lebih lanjut. Selamat menikmati! :)
Kevin Cruijssen

Juga, mengenai komentar Anda: " Saya bisa menyimpan beberapa karakter dengan tidak memiliki baris baru di antara pops tetapi itu hanya terlihat jelek. " byte sebanyak mungkin. Semakin pendek dan jelek, semakin baik. ;)
Kevin Cruijssen

@KevinCruijssen yang Python3 di atas saya hanya memilikinya sebagai fungsi w, h, apakah itu diizinkan?
Arya


1
Ok - Saya telah membuatnya menjadi fungsi H dan W sekarang.
Arya

1

Arang , 49 46 39 byte (tidak bersaing)

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

Verbose

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 byte

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

⎕← output
m←m , di mana m adalah
'O_'[... ] karakter-karakter ini diindeks oleh ...
2| pembagian-sisa-ketika-dibagi-dua
-/¨ perbedaan antara masing-masing
 semua koordinat (indeks) dalam array
 input numerik bentuk (jumlah baris dan kolom )

(... )[...]←'X'  tetapkan karakter X ke salah satu ... elemen yang
b/ disaring-oleh- b (untuk didefinisikan)
,m dari m, khususnya ...
? elemen acak (jumlah lit) dalam rentang satu ke
+/ jumlah
b←b , di mana b adalah
'O'= Boolean karena di mana huruf sama dengan
,mm terurai

⎕DL 1D e l ay satu detik

→2 Pergi ke baris 2
/⍨ jika (lit. disaring oleh)
'O'∊ apakah surat itu adalah anggota dari
⎕←m nilai yang dikeluarkan, di mana nilai yang dikeluarkan adalah m

Cobalah online!


Dari versi 16.0 akan lebih pendek:

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


1

Python 3, 195 188 byte

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)

Menggunakan bytearray dan decodetampaknya lebih pendek daripada mengiris dan memasang kembali string a la a[: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 byte

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()));}}

Penjelasan:

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

Tes gif (4,6)

masukkan deskripsi gambar di sini


0

Perl, 148 byte

146 byte kode + -plbendera.

$_=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

Untuk menjalankannya:

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 byte

Kode:

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

Rekomendasi selalu diterima! Cobalah online!

Output Program:

masukkan deskripsi gambar di sini

Penjelasan:

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.