バブルラップシミュレーターを作成する


23

バブルラップは、最高レベルのエンターテイメントです。誰もがそれに同意することができます。

これで、コンピューターでもプチプチを楽しむことができます。

スペック

2つの整数wとhが与えられます(それぞれが幅と高さに反応します)

プログラムは、各フェーズの間に1秒待機するすべてのw * hフェーズを出力し、終了する必要があります。

すべてのバブルラップは、すべてのセルがいっぱいになると始まります。

たとえば、4 * 6のバブルラップは次のように始まります。

O_O_
_O_O
O_O_
_O_O
O_O_
_O_O

また、各フェーズでは、ランダムな非ポップセルがポップされます。たとえば、

O_O_
_O_O
O_X_
_O_O
O_O_
_O_O

すべてのセルがポップされると、プログラムは終了します。別名。

X_X_
_X_X
X_X_
_X_X
X_X_
_X_X

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

1andの0代わりにOand を使用できますXか?
パベル

1
NEEDZ BUBBLEZ plsがヘルプを送信
クリストファー

3
a (1,1)にバブルがないことは許容されますか(たとえば、左上の「セル」は常にアンダースコアです)?
ジョナサンアラン

1
@JonathanAllanはい。
マシュー盧

1
@KevinCruijssen完全なプログラムである必要はありません。
マシュー盧

回答:


7

C(Windows)、260 248バイト

#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


スレッドライブラリにはスリープ関数があり、C ++ 11に含まれていることに注意してください。
マシュー

@MatthewRohうん、しかし、これはより短く、system("cls")またWindows固有であるため、スレッドライブラリでもコードの移植性は高くなりません。また、C ++では、iostreamまたはを含める必要がありますcstdio
Steadybox

ところで、画面をリセットする必要はありません。短くなります。
マシュー盧

5

Pythonの3222の 220バイト

これは私の最初の回答ですので、優しくしてください(そして私が犯した間違いを指摘してください)。

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)

オンラインでお試しください!

使い方:

  1. たくさんの「0_」をつなげる
  2. 「0_0 _... \ n」と「_0_0 ... \ n」の部分に切り分けて連結します
  3. インデックスの文字が「0」になるまでランダムインデックスを生成します
  4. 生成されたインデックスの文字が「X」に置き換えられた新しい文字列を作成する
  5. 繰り返しr*c+r%2*c%2時間:r*crとcの両方が奇数である場合を除き、パターンにはバブルがありますr*c+1

1
PPCGへようこそ!
AdmBorkBork

1
これはかなりマイナーですが、幅と高さが逆になります。しかし、素晴らしい答えです!(変更するだけf(c,r)で大丈夫です)。
ラッサー

@rassar Woops、ありがとう!
ナイル

4

MATL、37バイト

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

左上隅は常に下線です(チャレンジで許可されます)。

画面はフェーズ間でクリアされます。画面をクリアしないことで1バイト節約できますが、この方法のほうが見やすくなります。

すべてのフェーズを表示した後、プログラムはエラー(デフォルトで許可)で終了します

MATL Online試しください(数秒たっても動作しない場合は、ページを更新してもう一度お試しください)。


4

Mathematica(145バイト)

匿名関数、(そのために-それが問題だ場合、交換の入力としての高さと幅を取る{##}{#2,#}、余分な2バイトのコードの真ん中に)。

コード:

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

説明:

  • ""<>Riffle[Array["_"["O"][[Mod[#+#2,2]]]&,{##}],"\n"] 「_」と「O」の配列を作成し、改行間でそれらをStringJoiningすることにより、初期のポップされていないバブルラップを作成します。
  • NestList[RandomChoice@StringReplaceList[#,"O"->"X"]&,..., Floor[##/2]]「O」の数だけ何度も「O」の1つを選択して「X」に置き換えます(Floor [width * height / 2] — @_onathanAllanに「_左上隅の「O」の代わりに「」、そうでなければ、これはCeiling代わりに、したがって2バイト多くなります。
  • Monitor[Do[Pause@1,{i,...}],i]make iは、計算したばかりのリストの値をそれぞれ1秒ずつ取得し、動的に出力しiます。

出力例:

GIF of Mathematica popping bubble-wrap


3

ゼリー30 29 バイト

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

Example run

プログラム引数を使用してリンクをダイアッドとして呼び出し、その後メッセージ(コードはçṛ“\'=ṙMḋḌẓ(ėo»)で終了します

ニュアンス:右下の「セル」は常に(左上問題の例のようにではなく)、これはすべての気泡がランダムな選択戻り0をポップしているときにはなることを確実にするためであるバブルになる"X"でリストの終わり-これを置き換えると、値は変更されず、ループが中断されます。

注:画面はクリアされません(指定されていなかったため、どうすればいいかわかりません)。

どうやって?

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

@ГригорийПерельманが書きました。
ジョナサンアラン

2

Scala、764バイト

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

使い方

アルゴリズムはまず、2Dシーケンスに偽の値を入力します。入力されたコマンドライン引数に基づいて、反復(開いたボックス)の数を決定します。この値を上限として折り畳みを作成します。フォールドの整数値は、アルゴリズムが実行される反復回数をカウントする方法として暗黙的にのみ使用されます。前に作成した塗りつぶしシーケンスは、フォールドの開始シーケンスです。これは、対応する不確実性を持つ偽値の新しい2Dシーケンスを生成する際に使用されます。

例えば、

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

になります

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

完全に真である(長さが0の)リストはすべて、結果リストから省略されることに注意してください。次に、アルゴリズムはこのリストを取得し、最も外側のリストからランダムなリストを選択します。ランダムリストは、選択したランダムな行になるように選択されます。そのランダムな行から、再び乱数、列インデックスを見つけます。これらの2つのランダムなインデックスを見つけたら、現在のスレッドを1000ミリ秒スリープします。

スリープが完了したら、画面をクリアし、作成trueしたランダムインデックスで値が更新された新しいボードを作成します。

これを適切に印刷mapするには、コンテキストの中でそれを使用するために、マップのインデックスを使用して圧縮します。我々は、印刷すべきかどうかについての一連の真理値を使用するXかのいずれかOまたはを_。後者を選択するには、インデックス値をガイドとして使用します。

注意すべき興味深いこと

Oまたはを印刷する必要があるかどうかを判断するため_に、条件((r._2 % 2) + c._2) % 2 == 0が使用されます。r._2は現在の行インデックスをc._2参照し、現在の列を参照します。1つが奇数行にある場合、1になります。r._2 % 2したがってc._2、条件付きで1つオフセットされます。これにより、奇数行では、意図したとおりに列が1ずつ移動します。

"\033[H\033[2J\n"読んだStackoverflowの回答によると、文字列を出力すると画面がクリアされます。ターミナルにバイトを書き込んで、あまり理解できないファンキーなことをしています。しかし、私はそれが最も簡単な方法であることがわかりました。ただし、Intellij IDEAのコンソールエミュレーターでは機能しません。通常のターミナルを使用して実行する必要があります。

このコードを最初に見ると、奇妙なことに気付くかもしれない別の方程式があります(l * k) / 2 - (l * k + 1) % 2。まず、変数名を分かりやすく説明しましょう。lは、プログラムに渡される最初の引数をk参照し、2番目の引数を参照します。それを翻訳するには、(first * second) / 2 - (first * second + 1) % 2。この方程式の目標は、すべてのXのシーケンスを取得するために必要な正確な反復量を算出することです。初めてこれをやったとき、(first * second) / 2それは理にかなっているようにした。n各サブリストのすべての要素には、n / 2ポップできるバブルがあります。ただし、次のような入力を処理する場合、これは壊れます。(11 13)。2つの数値の積を計算し、偶数の場合は奇数にし、奇数の場合でも奇数にし、そのmodを2にする必要があります。これは、奇数の行と列が1回少ない反復を必要とするため最終結果を得るために。

mapforEach文字数が少ないため、aの代わりに使用されます。

おそらく改善できるもの

このソリューションについて本当に私を悩ませていることの1つは、頻繁に使用することですzipWithIndex。それは非常に多くのキャラクターを占めています。zipWithIndex渡された値で実行する独自の1文字関数を定義できるようにしようとしました。しかし、Scalaでは匿名関数に型パラメーターを許可していません。おそらくzipWithIndex私が使用せずにやっていることを行う別の方法がありますが、私はそれを行う賢い方法についてあまり考えていません。

現在、コードは2つのパスで実行されます。1つ目は新しいボードを生成し、2つ目のパスはそれを出力します。これら2つのパスを1つのパスに結合すると、数バイトを節約できると思います。

これは私がやった最初のコードゴルフですので、改善の余地があると確信しています。可能な限りバイトを最適化する前にコードをご覧になりたい場合は、こちらをご覧ください。


1

JavaScript(ES6)、246 229バイト

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>


幅はセル単位ではなく、空白(下線)スペースを含みます。
マシュー盧

@MatthewRoh申し訳ありませんが、高さを修正することを覚えていましたが、幅を確認するのを忘れました。
ニール

うーん..この部分はできません:`${`_O`.repeat(w).slice(w)} ${`O_`.repeat(w).slice(w)}どういうわけか結合されますか?おそらくブールフラグを使用して、最初に_Oまたはを決定しO_、次に.repeat(w).slice(w)
ケビンCruijssen

1
@KevinCruijssen当時はゴルフをする時間がなかったので、バグをすばやく修正したために16バイトを失いました。私は以来、別の外観を撮影したと17バイトの節約を作ってみた
ニール・

1

Python-290バイト

私はこれらのいずれかを以前にやったことがありません-建設的な批判は大歓迎です:)

ここでの主なトリックは、迷惑なようにネストされたリスト内包表記です。ポップの間に改行を入れないことで数文字を節約できましたが、見苦しいだけです。

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)

こんにちは、PPCGへようこそ!課題は、ハードコーディングされたを持たずに、入力を(STDINを介して、関数入力wなどhとして)受け取ることでしたH=4 W=6。また、Pythonでプログラミングしたことはありませんが、現在のコードでいくつかのスペースをゴルフできると思います。Pythonでのゴルフのヒントは、さらにゴルフをする方法についてのアイデアを提供するために読み通すのも面白いかもしれません。滞在を楽しんで!:)
ケビンクルーッセン

また、あなたのコメントに関して:「ポップの間に改行を入れないことでいくつかの文字を節約できましたが、見苦しいだけです。」可能な限り多くのバイト。短くandいほど良い。;)
ケビンクルーイッセン

@KevinCruijssen私の上のPython3はw、hの関数としてそれを持っていますが、それは許可されていますか?
アーヤ


1
わかりました-これでHとWの機能になりました。
アーヤ

1

49 46 39バイト(非競合)

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

冗長

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バイト

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

⎕←
m←mを  出力します 。ここで、m
'O_'[] これらの文字によってインデックス付けされます…
2| 2で除算されたときの除算剰余
-/¨
 形状
 数値入力(行と列の数)の配列内 のすべての座標(インデックス)の それぞれの差の )

(... )[... ]←'X' ...のいずれかに文字Xを割り当てる
b/ 濾過バイB(定義する)
,m Mのraveled要素、具体的...
? の範囲のいずれかで(数リットル)ランダム要素
+/ の和
b←BBがであり、
'O'= ブール文字が等しい場所
,m m raveledに場所

⎕DL 1D E のL AY一秒

→2 文字がのメンバーであるかどうか
/⍨ (点灯、フィルター)の場合、  2行目に移動します
'O'∊
⎕←m  出力値のある出力値がmの

オンラインでお試しください!


バージョン16.0以降は短くなります。

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


1

Python 3、195 188バイト

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)

bytearrayandの使用はdecode、文字列をスライスして再組み立てするよりも短いよう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バイト

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

説明:

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

テストgif(4,6)

ここに画像の説明を入力してください


0

Perl、148バイト

146バイトのコード+ -plフラグ。

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

実行するには:

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バイト

コード:

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

おすすめはいつでも大歓迎です!オンラインでお試しください!

プログラム出力:

ここに画像の説明を入力してください

説明:

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.