Trời đang mưa trong nhà ga của tôi!


24

Mô tả thử thách

Bạn phải hiển thị một mô phỏng của mưa trong thiết bị đầu cuối.

Trong ví dụ được đưa ra dưới đây, việc thêm 100 hạt mưa một cách ngẫu nhiên (sử dụng hàm ngẫu nhiên mặc định mà ngôn ngữ của bạn cung cấp) tọa độ, đợi trong 0,2 giây và sau đó vẽ lại cho đến khi hết thời gian. Bất kỳ ký tự có thể được sử dụng để đại diện cho hạt mưa.

Thông số

  • Thời gian chờ giữa lúc vẽ lại trong vài giây.
  • Thời gian mà mưa sẽ được nhìn thấy. Đây chỉ là một số nguyên biểu thị số lần lặp. [Vì vậy, thời gian thực mà mưa sẽ hiển thị là số nguyên này nhân với thời gian chờ]
  • Thông báo sẽ được hiển thị khi mưa kết thúc. (Điều này phải được tập trung)
  • Số lượng hạt mưa sẽ được hiển thị trên màn hình.

Quy tắc

  • Một byte đơn nên được sử dụng để thể hiện một giọt mưa và nó có thể là bất cứ thứ gì, kể cả mèo và chó.
  • Nó không phải đáp ứng với kích thước thiết bị đầu cuối, điều đó có nghĩa là bạn không phải xử lý lỗi đối với các kích cỡ thiết bị đầu cuối khác nhau. Bạn có thể tự xác định chiều rộng và chiều cao của thiết bị đầu cuối.
  • Tiêu chuẩn quy tắc chơi golf áp dụng.

Mẫu mã và đầu ra

Đây là một phiên bản không được viết bằng python 2.7 bằng cách sử dụng ncurses.

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

Đầu ra -

nhập mô tả hình ảnh ở đây


3
Trong tương lai thay vì đăng lại xin vui lòng chỉnh sửa bản gốc. Nếu mọi người nghĩ rằng thông số kỹ thuật rõ ràng, họ sẽ đề cử nó để mở lại.
Thuật sĩ lúa mì

6
Có phải văn bản phải được tập trung? Có phải trời mưa ngẫu nhiên, vị trí ban đầu của các giọt có quan trọng không? Bạn đang đo thời gian như thế nào? Trong mili giây, giây, phút? "Điểm thêm" là gì?
Bạch tuộc ma thuật Urn

1
Nếu bạn, A. Chỉ định đơn vị. B. Chỉ định kích thước thiết bị đầu cuối hoặc lấy nó làm đầu vào. và C. Loại bỏ phần về các điểm phụ; thách thức này sẽ được xác định tốt hơn.
Bạch tuộc ma thuật Urn

Khi bạn nói "ngẫu nhiên", chúng ta có thể cho rằng điều đó có nghĩa là "ngẫu nhiên thống nhất" không?
Chấn thương kỹ thuật số

3
1 ngày trong hộp cát thường không đủ. Hãy nhớ rằng mọi người đang ở đây giải trí và từ các múi giờ khác nhau - không nên phản hồi ngay lập tức.
Chấn thương kỹ thuật số

Câu trả lời:


12

MATL , 52 byte

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

Các đầu vào, theo thứ tự này: tạm dừng giữa các lần cập nhật, số lần giảm, tin nhắn, số lần lặp lại. Màn hình có kích thước 80 × 25 ký tự (mã hóa cứng).

GIF hoặc nó đã không xảy ra! (Ví dụ với đầu vào 0.2, 100, 'THE END', 30)

nhập mô tả hình ảnh ở đây

Hoặc dùng thử tại MATL Online .

Giải trình

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
Tôi thích cách nó kết thúc vào why:)
tkellehe

1
@tkellehe Tôi thích phần mô tả trong hồ sơ của bạn :-)
Luis Mendo

1
cảm ơn bạn. Ngôn ngữ của bạn rất thú vị để đọc. (Vâng, tôi đã theo dõi câu trả lời MATL của bạn lol)
tkellehe

10

JavaScript (ES6), 268 261 byte

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;

Ít nhất trên trình duyệt của tôi, đầu ra được thiết kế để phù hợp với khu vực Stack Snippet mà không phải đi đến "Toàn trang", vì vậy nếu bạn yêu cầu hơn 702 hạt mưa thì nó sẽ bị sập.

Chỉnh sửa: Đã lưu 7 byte bằng cách sử dụng nút văn bản làm vùng đầu ra của tôi.


Bạn có thể lưu một vài byte bằng cách chuyển hàm dưới dạng chuỗi sang setInterval. Ngoài ra, tại sao bạn sử dụng textContentthay vì innerHTML?
Lu-ca

@ L.Serné Sử dụng hàm bên trong cho phép tôi tham khảo các biến trong hàm ngoài.
Neil

Rất tiếc, xấu của tôi, đã không nhận thấy điều đó.
Lu-ca

8

R, 196 192 185 byte

Chỉ là một phiên bản giả tôi đã viết dựa trên mô tả. Hy vọng rằng đó là phần nào những gì OP đang tìm kiếm.

Đã lưu một số byte nhờ @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="")}

Các đối số:

  • w: Thời gian chờ giữa các khung
  • t: Tổng số khung
  • m: Thông báo tùy chỉnh
  • n: Số giọt mưa

Thí dụ

Tại sao có vẻ như trời đang mưa?

Chỉnh sửa: Tôi nên đề cập rằng đây là bảng điều khiển R-studio 23x100 ký tự tùy chỉnh của tôi. Các kích thước được mã hóa cứng vào chức năng nhưng về nguyên tắc người ta có thể sử dụng getOption("width")để làm cho nó linh hoạt với kích thước bàn điều khiển.

nhập mô tả hình ảnh ở đây

Ung dung và giải thích

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
}

Điều này có vẻ hoàn toàn tốt! +1 và tôi không nghĩ nó sẽ đi lên, đó chỉ là nhận thức của bạn lol
hashcode55

@plannapus. Thực hiện rep()tự động tầng timesđối số để không cần điều đó. Đã lưu thêm 7 byte!
Billywob

Giải pháp rất hay. Bạn có thể lưu một byte bằng cách đẩy kích thước bàn điều khiển vào các đối số chức năng (nếu điều đó được cho phép); bạn có thể lưu một byte khác bằng cách sử dụng runifthay vì sampleđiền ngẫu nhiên vào ma trận. Giống như vậy: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 byte

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

Phiên bản bị đánh cắp:

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

Testcase trên thiết bị đầu cuối của tôi

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

4

R, 163 ký tự

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="")}

Với thụt lề và dòng mới:

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="")
}

Nó thích nghi với kích thước đầu cuối gồm 24 dòng bằng 80 cột. wlà thời gian chờ đợi, tsố lượng khung hình, nsố lượng hạt mưa và mthông điệp cuối cùng.

Nó khác với câu trả lời của @ billywob trong cách sử dụng khác nhau sample: nếu bỏ qua kích thước đầu ra, samplesẽ cho phép hoán vị của vectơ đầu vào (ở đây một vectơ chứa số lượng hạt mưa cần thiết và số lượng khoảng trắng tương ứng, nhờ vào lý lẽ timescủa chức năng repđược vector hóa). Vì kích thước của vectơ tương ứng chính xác với kích thước của màn hình, không cần thêm dòng mới hoặc buộc hình dạng nó thành ma trận.

Gif của đầu ra


3

NodeJS: 691 158 148 byte

Chỉnh sửa

Theo yêu cầu, các tính năng bổ sung đã bị xóa và chơi gôn.

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)

Các quy tắc xác định bỏ qua kích thước, nhưng phiên bản này bao gồm một trục trặc cho một vài khung hình đầu tiên. Nó là 129 byte.

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)

Câu trả lời trước

Có lẽ không phải là chơi golf tốt nhất, nhưng tôi đã mang đi một chút. Nó có hướng gió tùy chọn và yếu tố mưa.

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)

Xem webm của nó làm việc ở đây


2

Noodel , không biên dịch 44 byte

Tôi đã tập trung văn bản vào danh sách những việc cần làm kể từ khi tôi tạo ngôn ngữ ... Nhưng, tôi lười biếng và không thêm vào cho đến sau thử thách này. Vì vậy, ở đây tôi không thi đấu, nhưng đã vui vẻ với thử thách :)

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

Bảng điều khiển có kích thước được mã hóa cứng thành 25x50, trông không đẹp trong trình chỉnh sửa trực tuyến, nhưng đối với đoạn trích.

Thử nó:)


Làm thế nào nó hoạt động

Ø                                            # 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
Ah đó là một ngôn ngữ tuyệt vời để có trong hộp công cụ của tôi haha! Dù sao, rất vui vì bạn thích thử thách :) +1
hashcode55

2

Sử dụng Ruby + GNU Core, 169 byte

Các tham số của hàm là thời gian chờ, số lần lặp, thông báo và số hạt mưa, theo thứ tự đó. Dòng mới cho dễ đọc.

Utils Core là cần thiết cho 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

Python 2.7, 254 251 byte

Đây là thử của riêng tôi mà không sử dụng 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

Cảm ơn @ErikTheOutgolfer đã sửa và lưu tôi byte.


Bạn không thể đặt một forvòng lặp trong một dòng (giống như bạn có 40)];for i in u(). Bạn cũng cần một char ESC trong '[2J'tôi nghĩ. Ngoài ra, có thêm một không gian trong u(n): r[y. Tôi không biết làm thế nào bạn đếm được 249 mặc dù. Tất cả các vấn đề tôi tìm thấy đã được sửa chữa ở đây .
Erik the Outgolfer

Mã tôi đã đăng đang làm việc cho tôi. Và vâng tôi thực sự đã đếm sai, tôi đã không đếm khoảng trắng thụt vào trong, tôi không biết về nó. Cảm ơn các liên kết! Tôi sẽ chỉnh sửa nó.
hashcode55

@EriktheOutgolfer Oh và yeah liên quan đến ESC char đó, không cần trình tự thoát. Nó chỉ in 'ESC [2J' một cách hiệu quả, đó là chuỗi thoát ansi để xóa màn hình. Nó không đặt lại vị trí con trỏ mặc dù.
hashcode55

Bạn có thể chơi golf nhiều hơn nữa :) Nhưng bạn cần thêm một ghi chú bên dưới mã của bạn chỉ định rằng <esc>biểu thị một byte ESC 0x1B bằng chữ. Số lượng byte là 242 , không phải là 246.
Erik the Outgolfer

@EriktheOutgolfer ơi cảm ơn!
hashcode55

1

SmileBASIC, 114 byte

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$

Kích thước bàn điều khiển luôn là 50 * 30.


1

Perl 5, 156 byte

Mã 154 byte + 2 cho -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

Sử dụng kích thước cố định 160x50.

Xem nó trực tuyến!


Perl 5, 203 byte

201 byte mã + 2 cho -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

Sử dụng tputđể xác định kích thước của thiết bị đầu cuối.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.