ターミナルで雨が降っています!


24

チャレンジの説明

ターミナルで雨のシミュレーションを表示する必要があります。

以下の例では、100個の雨滴をランダムに追加し(言語が提供するデフォルトのランダム関数を使用)座標を調整し、0.2秒待ってから、指定された時間が経過するまで再描画します。雨滴を表すために任意の文字を使用できます。

パラメーター

  • 再描画間の待機時間(秒単位)。
  • 雨が見える時間。これは、反復回数を表す単なる整数です。[したがって、雨が見える正味時間は、この整数に待機時間を掛けたものです]
  • 雨が終わったときに表示されるメッセージ。(これは中央に配置する必要があります)
  • 画面に表示される雨滴の数。

ルール

  • 雨滴を表すために1バイトを使用する必要があり、猫や犬でも何でも構いません。
  • 端末サイズに対応する必要はありません。つまり、さまざまな端末サイズのバグを処理する必要はありません。端末の幅と高さは独自に指定できます。
  • ゴルフの標準ルールが適用されます。

コードのサンプルと出力

これは、ncursesを使用してpython 2.7で記述された非ゴルフバージョンです。

import curses
import random
import time

myscreen = curses.initscr()
curses.curs_set(0) # no cursor please 
HEIGHT, WIDTH = myscreen.getmaxyx() 
RAIN = '/' # this is what my rain drop looks like 
TIME = 10 

def make_it_rain(window, tot_time, msg, wait_time, num_drops):
    """
    window    :: curses window 
    time      :: Total time for which it rains
    msg       :: Message displayed when it stops raining
    wait_time :: Time between redrawing scene 
    num_drops :: Number of rain drops in the scene 
    """
    for _ in range(tot_time):
        for i in range(num_drops):
            x,y=random.randint(1, HEIGHT-2),random.randint(1,WIDTH-2)       
            window.addstr(x,y,RAIN)
        window.refresh()
        time.sleep(wait_time)
        window.erase()

    window.refresh()
    window.addstr(HEIGHT/2, int(WIDTH/2.7), msg)


if __name__ == '__main__':
    make_it_rain(myscreen, TIME, 'IT HAS STOPPED RAINING!', 0.2, 100)
    myscreen.getch()
    curses.endwin()

出力-

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


3
今後、再度投稿する代わりに、オリジナルを編集してください。仕様が明確であると人々が考える場合、彼らは再開のためにそれを指名します。
小麦ウィザード

6
テキストは中央に配置する必要がありますか?ランダムに雨が降っていますか?液滴の初期位置は重要ですか?時間をどのように測定していますか?ミリ秒、秒、分で?「追加ポイント」とは何ですか?
魔法のタコUr

1
もしそうなら、A。単位を指定します。B.端末サイズを指定するか、入力として使用します。そして、C.は、余分なポイントに関する部分を削除します。この課題はより明確に定義されるでしょう。
魔法のタコUr

「ランダム」と言うとき、それは「一様にランダム」を意味すると仮定できますか?
デジタル外傷

3
多くの場合、サンドボックスでの1日では十分ではありません。人々はレクリエーションや多様なタイムゾーンからここにいることを忘れないでください-即時のフィードバックは期待すべきではありません。
デジタル外傷

回答:


12

MATL、52バイト

xxx:"1GY.Xx2e3Z@25eHG>~47*cD]Xx12:~c!3G80yn-H/kZ"why

入力は、更新間の一時停止、ドロップの数、メッセージ、繰り返しの数の順です。モニターのサイズは80×25文字(ハードコード化)です。

GIFまたはそれは起こりませんでした!(入力を備えた実施例0.2100'THE END'30

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

または、MATL Onlineで試してください。

説明

xxx      % Take first three inputs implicitly and delete them (but they get
         % copied into clipboard G)
:"       % Take fourth input implicitly. Repeat that many times
  1G     %   Push first input (pause time)
  Y.     %   Pause that many seconds
  Xx     %   Clear screen
  2e3    %   Push 2000 (number of chars in the monitor, 80*25)
  Z@     %   Push random permutation of the integers from 1 to 2000
  25e    %   Reshape as a 25×80 matrix, which contains the numbers from 1 to 2000
         %   in random positions
  HG     %   Push second input (number of drops)
  >~     %   Set numbers that are <= second input to 1, and the rest to 0
  47*c   %   Multiply by 47 (ASCII for '/') and convert to char. Char 0 will
         %   be displayed as a space
  D      %   Display
]        % End
Xx       % Clear screen
12:~     % Push row vector of twelve zeros
c!       % Convert to char and transpose. This will produce 12 lines containing
         % a space, to vertically center the message in the 25-row monitor
3G       % Push third input (message string)
80       % Push 80
yn       % Duplicate message string and push its length
-        % Subtract
H/k      % Divide by 2 and round down
Z"       % Push string of that many spaces, to horizontally center the message 
         % in the 80-column monitor
w        % Swap
h        % Concatenate horizontally
y        % Duplicate the column vector of 12 spaces to fill the monitor
         % Implicitly display

1
それはどのように終わるようなI why:)
tkellehe

1
@tkellehe私はあなたのプロフィールの説明が好きです:-)
ルイスメンドー

1
ありがとうございました。あなたの言語は読むのがとても楽しいです。(はい、私はあなたのストーカーされているMATLの笑回答)
tkellehe

10

JavaScriptの(ES6)、268の 261バイト

t=
(o,f,d,r,m,g=(r,_,x=Math.random()*78|0,y=Math.random()*9|0)=>r?g(r-(d[y][x]<`/`),d[y][x]=`/`):d.map(a=>a.join``).join`
`)=>i=setInterval(_=>o.data=f--?g(r,d=[...Array(9)].map(_=>[...` `.repeat(78)])):`



`+` `.repeat(40-m.length/2,clearInterval(i))+m,d*1e3)
<input id=f size=10 placeholder="# of frames"><input id=d placeholder="Interval between frames"><input id=r size=10 placeholder="# of raindrops"><input id=m placeholder="End message"><input type=button value=Go onclick=t(o.firstChild,+f.value,+d.value,+r.value,m.value)><pre id=o>&nbsp;

少なくとも私のブラウザでは、出力は「フルページ」に移動することなくスタックスニペット領域に収まるように設計されているため、702を超える雨滴を要求するとクラッシュします。

編集:テキストノードを出力領域として使用して、7バイトを保存しました。


関数を文字列としてに渡すことで、数バイトを節約できますsetInterval。また、textContent代わりに使用するのはなぜinnerHTMLですか?
ルーク

@L.Serné内部関数を使用すると、外部関数の変数を参照できます。
ニール

おっと、私は悪いことに気づかなかった。
ルーク

8

R、196192185バイト

説明に基づいて作成したモックバージョンです。うまくいけば、OPが探していたものになります。

@plannapusのおかげで数バイト節約できました。

f=function(w,t,m,n){for(i in 1:t){x=matrix(" ",100,23);x[sample(2300,n)]="/";cat("\f",rbind(x,"\n"),sep="");Sys.sleep(w)};cat("\f",g<-rep("\n",11),rep(" ",(100-nchar(m))/2),m,g,sep="")}

引数:

  • w:フレーム間の待機時間
  • t:フレームの総数
  • m:カスタムメッセージ
  • n:雨滴の数

上に雨が降っているように見えるのはなぜですか?

編集:これは私のカスタマイズされた23x100キャラクターR-studioコンソールであることを言及する必要があります。寸法は関数にハードコーディングされていますが、原則getOption("width")としてコンソールサイズに合わせて柔軟に使用できます。

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

非ゴルフと説明

f=function(w,t,m,n){
    for(i in 1:t){
        x=matrix(" ",100,23);             # Initialize matrix of console size
        x[sample(2300,n)]="/";            # Insert t randomly sampled "/"
        cat("\f",rbind(x,"\n"),sep="");   # Add newlines and print one frame
        Sys.sleep(w)                      # Sleep 
    };
    cat("\f",g<-rep("\n",11),rep(" ",(100-nchar(m))/2),m,g,sep="")  # Print centered msg
}

これは完璧に見えます!+1と私はそれだけであなたの知覚lol上向きに行くとは思わないlol
hashcode55

@plannapus。rep()自動的にtimes引数がフロアリングされるため、その必要もありません。さらに7バイト節約しました!
ビリーウォブ

とてもいい解決策。コンソールサイズを関数引数にプッシュすることで1バイトを節約できます(許可されている場合)。マトリックスにランダムに入力するのrunifではなく、sampleを使用して別のバイトを保存できます。そのように:f=function(w,t,m,n,x,y){for(i in 1:t){r=matrix(" ",x,y);r[runif(n)*x*y]="/";cat("\f",rbind(r,"\n"),sep="");Sys.sleep(w)};cat("\f",g<-rep("\n",y/2),rep(" ",(x-nchar(m))/2),m,g,sep="")}
rturnbull

5

C 160バイト

f(v,d,w,char *s){i,j;char c='/';for(i=0;i<v;i++){for(j=0;j<d;j++)printf("%*c",(rand()%100),c);fflush(stdout);sleep(w);}system("clear");printf("%*s\n",1000,s);}

v-Time the raindrops are visible in seconds.
d-Number of drops per iteration
w-Wait time in seconds, before the next iteration
s-String to be passed on once its done

ゴルフされていないバージョン:

void f(int v, int d, int w,char *s)
{ 

   char c='/';
   for(int i=0;i<v;i++)
   { 
      for(int j=0;j<d;j++)
         printf("%*c",(rand()%100),c);

      fflush(stdout);
      sleep(w); 
   }   
   system("clear");
   printf("%*s\n", 1000,s);
}

私の端末のテストケース

v - 5 seconds
d - 100 drops
w - 1 second wait time
s - "Raining Blood" :)

4

R、163文字

f=function(w,t,n,m){for(i in 1:t){cat("\f",sample(rep(c("/"," "),c(n,1920-n))),sep="");Sys.sleep(w)};cat("\f",g<-rep("\n",12),rep(" ",(80-nchar(m))/2),m,g,sep="")}

インデントと改行あり:

f=function(w,t,n,m){
    for(i in 1:t){
        cat("\f",sample(rep(c("/"," "),c(n,1920-n))),sep="")
        Sys.sleep(w)
    }
    cat("\f",g<-rep("\n",12),rep(" ",(80-nchar(m))/2),m,g,sep="")
}

24行80列の端末サイズに適合します。w待ち時間t、フレームn数、雨滴の数m、最終メッセージです。

それは異なり@ billywobの答えの異なる使用中のsample出力サイズが省略されている場合、:sampleここで入力ベクトル(雨滴の必要な数とスペースの対応する番号を含むベクトルの順列を与える、という事実は、引数に感謝timesの関数repはベクトル化されます)。ベクトルのサイズは画面のサイズに正確に対応するため、改行を追加したり、行列に強制的に整形したりする必要はありません。

出力のGIF


3

NodeJS:691 158 148バイト

編集

要求に応じて、追加の機能が削除され、ゴルフが行われました。

s=[];setInterval(()=>{s=s.slice(L='',9);for(;!L[30];)L+=' |'[Math.random()*10&1];s.unshift(L);console.log("\u001b[2J\u001b[0;0H"+s.join('\n'))},99)

ルールではサイズを無視するように指定されていますが、このバージョンでは最初の数フレームにグリッチが含まれています。それは129バイト。

s='';setInterval(()=>{for(s='\n'+s.slice(0,290);!s[300];)s=' |'[Math.random()*10&1]+s;console.log("\u001b[2J\u001b[0;0H"+s)},99)

前の答え

おそらく最高のゴルフではありませんが、少し夢中になりました。オプションの風向と雨の要因があります。

node rain.js 0 0.3

var H=process.stdout.rows-2, W=process.stdout.columns,wnd=(arg=process.argv)[2]||0, rf=arg[3]||0.3, s=[];
let clr=()=>{ console.log("\u001b[2J\u001b[0;0H") }
let nc=()=>{ return ~~(Math.random()*1+rf) }
let nl=()=>{ L=[];for(i=0;i<W;i++)L.push(nc()); return L}
let itrl=(l)=>{ for(w=0;w<wnd;w++){l.pop();l.unshift(nc())}for(w=0;w>wnd;w--){l.shift();l.push(nc())};return l }
let itrs=()=>{ if(s.length>H)s.pop();s.unshift(nl());s.map(v=>itrl(v)) }
let d=(c,i)=>{if(!c)return ' ';if(i==H)return '*';if(wnd<0)return '/';if(wnd>0)return '\\';return '|'}
let drw=(s)=>{ console.log(s.map((v,i)=>{ return v.map(  c=>d(c,i)  ).join('') }).join('\r\n')) }
setInterval(()=>{itrs();clr();drw(s)},100)

ここで動作するwebmを参照してください


2

Noodel、非競合44 バイト

言語を作成してから、すべきことのリストにテキストを集中させました...しかし、私は怠け者であり、この挑戦​​の後まで追加しませんでした。だから、ここで私は競争していませんが、挑戦を楽しんでいました:)

ØGQÆ×Øæ3/×Æ3I_ȥ⁻¤×⁺Æ1Ḷḋŀ÷25¶İÇæḍ€Æ1uụC¶×12⁺ß

コンソールのサイズは25x50にハードコーディングされており、オンラインエディターでは見栄えがよくありませんが、スニペットでは見栄えがします。

それを試してみてください:)


使い方

Ø                                            # Pushes all of the inputs from the stack directly back into the stdin since it is the first token.

 GQÆ×Ø                                       # Turns the seconds into milliseconds since can only delay by milliseconds.
 GQ                                          # Pushes on the string "GQ" onto the top of the stack.
   Æ                                         # Consumes from stdin the value in the front and pushes it onto the stack which is the number of seconds to delay.
    ×                                        # Multiplies the two items on top of the stack.
                                             # Since the top of the stack is a number, the second parameter will be converted into a number. But, this will fail for the string "GQ" therein treated as a base 98 number producing 1000.
     Ø                                       # Pops off the new value, and pushes it into the front of stdin.

      æ3/×Æ3I_ȥ⁻¤×⁺                          # Creates the correct amount of rain drops and spaces to be displayed in a 50x25 console.
      æ3                                     # Copies the forth parameter (the number of rain drops).
        /                                    # Pushes the character "/" as the rain drop character.
         ×                                   # Repeats the rain drop character the specified number of times provided.
          Æ3                                 # Consumes the number of rain drops from stdin.
            I_                               # Pushes the string "I_" onto the stack.
              ȥ                              # Converts the string into a number as if it were a base 98 number producing 25 * 50 = 1250.
               ⁻                             # Subtract 1250 - [number rain drops] to get the number of spaces.
                ¤                            # Pushes on the string "¤" which for Noodel is a space.
                 ×                           # Replicate the "¤" that number of times.
                  ⁺                          # Concatenate the spaces with the rain drops.

                   Æ1Ḷḋŀ÷25¬İÇæḍ€            # Handles the animation of the rain drops.
                   Æ1                        # Consumes and pushes on the number of times to loop the animation.
                     Ḷ                       # Pops off the number of times to loop and loops the following code that many times.
                      ḋ                      # Duplicate the string with the rain drops and spaces.
                       ŀ                     # Shuffle the string using Fisher-Yates algorithm.
                        ÷25                  # Divide it into 25 equal parts and push on an array containing those parts.
                           ¶                 # Pushes on the string "¶" which is a new line.
                            İ                # Join the array by the given character.
                             Ç               # Clear the screen and display the rain.
                              æ              # Copy what is on the front of stdin onto the stack which is the number of milliseconds to delay.
                               ḍ             # Delay for the specified number of milliseconds.
                                €            # End of the loop.

                                 Æ1uụC¶×12⁺ß # Creates the centered text that is displayed at the end.
                                 Æ1          # Pushes on the final output string.
                                   u         # Pushes on the string "u" onto the top.
                                    ụC       # Convert the string on the top of the stack to an integer (which will fail and default to base 98 which is 50) then center the input string based off of that width.
                                      ¶      # Push on a the string "¶" which is a new line.
                                       ×12   # Repeat it 12 times.
                                          ⁺  # Append the input string that has been centered to the new lines.
                                           ß # Clear the screen.
                                             # Implicitly push on what is on the top of the stack which is the final output.

<div id="noodel" code="ØGQÆ×Øæ3/×Æ3I_ȥ⁻¤×⁺Æ1Ḷḋŀ÷25¶İÇæḍ€Æ1uụC¶×12⁺ß" input='0.2, 50, "Game Over", 30' cols="50" rows="25"></div>

<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


1
ああ、ツールボックスにあるのはかっこいい言語です(笑)。とにかく、チャレンジが気に入ってくれてうれしいです:) +1
hashcode55

2

Ruby + GNU Core Utils、169バイト

関数のパラメーターは、待ち時間、反復回数、メッセージ、および雨滴の数です。読みやすさのための改行。

コアUtilsのは、のために必要であったtputclear

->w,t,m,n{x=`tput cols`.to_i;z=x*h=`tput lines`.to_i
t.times{s=' '*z;[*0...z].sample(n).map{|i|s[i]=?/};puts`clear`+s;sleep w}
puts`clear`+$/*(h/2),' '*(x/2-m.size/2)+m}

1

パイソン2.7、254の 251バイト

これは、ncursesを使用しない私自身の試みです。

from time import*;from random import*;u=range;y=randint
def m(t,m,w,n):
    for _ in u(t):
        r=[[' 'for _ in u(40)]for _ in u(40)]
        for i in u(n):r[y(0,39)][y(0,39)]='/'
        print'\n'.join(map(lambda k:' '.join(k),r));sleep(w);print '<esc>[2J'
    print' '*33+m

バイトを修正して保存してくれた@ErikTheOutgolferに感謝します。


forループを1行に入れることはできません(のように40)];for i in u()。ESC charも必要'[2J'だと思います。また、に余分なスペースがありましたu(n): r[y。しかし、249をカウントした方法がわかりません。私が見つけたすべての問題はここで修正されました
エリックアウトゴルファー

私が投稿したコードは私のために働いています。ええ、私は実際にそれを間違って数えました、私は白いインデントされたスペースを数えませんでした、私はそれについて知りませんでした。リンクをありがとう!編集します。
hashcode55

@EriktheOutgolferええ、そのESC文字に関しては、エスケープシーケンスは必要ありません。これは、 'ESC [2J'を効果的に出力するだけです。これは、画面をクリアするためのANSIエスケープシーケンスです。ただし、カーソル位置はリセットされません。
hashcode55

さらにゴルフできます:)しかし、コードの下に<esc>、リテラル0x1B ESCバイトを示すメモを追加する必要があります。バイト数は242、いない246
Outgolferエリック

@EriktheOutgolferああありがとう!
hashcode55

1

SmileBASIC、114バイト

INPUT W,T,M$,N
FOR I=1TO T
VSYNC W*60CLS
FOR J=1TO N
LOCATE RND(50),RND(30)?7;
NEXT
NEXT
LOCATE 25-LEN(M$)/2,15?M$

コンソールのサイズは常に50 * 30です。


1

Perl 5、156バイト

154バイトのコード+の2 -pl

$M=$_;$W=<>;$I=<>;$R=<>;$_=$"x8e3;{eval'$-=rand 8e3;s!.{$-}\K !/!;'x$R;print;select$a,$a,$a,$W;y!/! !;--$I&&redo}$-=3920-($l=length$M)/2;s;.{$-}\K.{$l};$M

160x50の固定サイズを使用します。

オンラインでご覧ください!


Perl 5、203バイト

201バイトコードの+ 2 -pl

$M=$_;$W=<>;$I=<>;$R=<>;$_=$"x($z=($x=`tput cols`)*($y=`tput lines`));{eval'$-=rand$z;s!.{$-}\K !/!;'x$R;print;select$a,$a,$a,$W;y!/! !;--$I&&redo}$-=$x*($y+!($y%2))/2-($l=length$M)/2;s;.{$-}\K.{$l};$M

tput端末のサイズを決定するために使用します。

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