버블 랩 시뮬레이터 만들기


23

버블 랩은 최대 수준의 엔터테인먼트입니다. 누구나 동의 할 수 있습니다.

이제 컴퓨터에서도 버블 랩을 즐길 수 있습니다.

명세서

두 개의 정수 w와 h가 주어질 것입니다 (각각 반응 적으로 너비와 높이가 있습니다)

프로그램은 각 w * h 단계를 각각 1 초간 대기하고 출력해야합니다.

모든 버블 랩은 모든 셀이 가득 찬 상태로 시작합니다.

예를 들어, 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)

우리가 사용할 수 10대신 O하고 X?
Pavel

1
NEEDZ BUBBLEZ pls 도움말 보내기
Christopher

3
(1,1)기포가없는 것이 허용 됩니까 (예 : 왼쪽 상단의 "셀"은 항상 밑줄입니다)?
Jonathan Allan

1
@JonathanAllan 예.
Matthew Roh

1
@KevinCruijssen 전체 프로그램 일 필요는 없습니다.
Matthew Roh

답변:


7

C (윈도우), (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);}

여기에 이미지 설명을 입력하십시오


스레드 라이브러리에는 C ++ 11에 포함 된 절전 기능이 있습니다.
Matthew Roh

@MatthewRoh Yep, 그러나 이것은 더 짧고 system("cls")Windows에 따라 다르므로 코드는 스레드 라이브러리로 이식성 이 떨어집니다 . 그리고 C와 ++ 나는 또한 포함해야 iostream하거나 cstdio.
Steadybox

btw 화면을 재설정 할 필요가 없습니다. 짧아 질 것입니다.
Matthew Roh

5

파이썬 3 , 222220 바이트

이것은 처음으로 대답하는 것이므로 조심하십시오 (내가 저지른 실수를 지적하십시오).

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. 생성 된 색인에서 char로 새 문자열을 생성하면 'X'로 바뀝니다 (변경 불가능한 문자열의 경우 파이썬입니다!)
  5. 반복 r*c+r%2*c%2시간 : r*cr과 c가 모두 홀수 인 경우를 제외하고 패턴에 기포가 있습니다 r*c+1.

1
PPCG에 오신 것을 환영합니다!
AdmBorkBork

1
이것은 약간 작지만 너비와 높이가 반대로됩니다. 그래도 좋은 대답입니다! (그냥 변경 f(c,r)하면 괜찮을 것입니다).
rassar

@rassar Woops, 감사합니다!
nile

4

MATL , 37 바이트

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

왼쪽 위 모서리는 항상 밑줄입니다 (도전으로 허용됨).

화면이 단계별로 지워집니다. 화면을 지우지 않으면 바이트를 절약 할 수 있지만이 방법이 더 좋습니다.

모든 단계를 표시 한 후 프로그램은 오류 ( 기본적으로 허용됨) 와 함께 종료 됩니다.

MATL Online 에서 사용해보십시오 ! 몇 초 후에도 작동하지 않으면 페이지를 새로 고침 한 후 다시 시도하십시오.


4

매스 매 티카 (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"중 하나를 반복적으로 선택하여 "X"로 대체합니다. "O"(Floor [width * height / 2])는 "_" 왼쪽 상단에있는 "O"대신 "를 사용하면 Ceiling대신 2 바이트가 더 사용됩니다).
  • Monitor[Do[Pause@1,{i,...}],i]i방금 계산 한 목록의 값을 각각 1 초씩 가져 와서 동적으로 인쇄합니다 i.

출력 예 :

GIF의 Mathematica 터지는 버블 랩


3

젤리 , 30 29 바이트

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

예제 실행

프로그램 인수를 사용하여 링크를 dyad로 호출 한 다음 메시지 (코드는 çṛ“\'=ṙ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)

@ ГригорийПерельман가 작성했습니다.
Jonathan Allan

2

스칼라 , 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) 인 모든리스트는 결과리스트에서 생략됩니다. 그런 다음 알고리즘은이 목록을 가져 와서 가장 바깥 쪽 목록에서 임의의 목록을 선택합니다. 무작위 목록은 우리가 선택한 임의의 행으로 선택됩니다. 그 임의의 행에서, 우리는 난수, 즉 열 인덱스를 다시 찾습니다. 이 두 개의 임의의 인덱스를 찾으면 1000 밀리 초 동안 스레드를 잠들게됩니다.

수면이 끝나면 화면을 지우고 true우리가 만든 임의의 지수로 업데이트 된 값 으로 새 보드를 만듭니다 .

이것을 올바르게 출력하기 map위해 맵의 인덱스와 함께 사용 하고 압축하여 문맥에 맞게 만듭니다. 우리는 우리가 인쇄해야하는지에 대한 일련의 진리 값을 사용 X하거나 어느 쪽 O또는 _. 후자를 선택하기 위해 인덱스 값을 가이드로 사용합니다.

흥미로운 것들

그것이 인쇄해야하는 경우 알아 내기 위해 O또는를 _, 조건이 ((r._2 % 2) + c._2) % 2 == 0사용된다. r._2현재 행 인덱스를 c._2참조하고 현재 열 을 나타냅니다. 하나가 홀수 행에 있으면 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나타냅니다. 번역하려면 (first * second) / 2 - (first * second + 1) % 2. 이 방정식의 목표는 모든 X의 시퀀스를 얻는 데 필요한 정확한 반복 횟수를 도출하는 것입니다. 내가 이것을 처음 할 때, 나는 (first * second) / 2그 의미가 이해가되었습니다. n각 하위 목록의 모든 요소에 대해 n / 2버블을 터뜨릴 수 있습니다. 그러나 다음과 같은 입력을 처리 할 때 중단됩니다.(11 13). 두 숫자의 곱을 계산하고 짝수이면 홀수이고 홀수이면 모수를 2로 수정해야합니다. 홀수 인 행과 열에 반복이 한 번 덜 필요하기 때문에 작동합니다. 최종 결과를 얻을 수 있습니다.

mapforEach문자 수가 적기 때문에 대신에 사용됩니다 .

아마 개선 될 수있는 것들

이 솔루션에 대해 정말로 나를 괴롭히는 것은 자주 사용하는 것입니다 zipWithIndex. 너무 많은 캐릭터를 차지하고 있습니다. zipWithIndex전달 된 값으로 수행 할 수 있는 하나의 문자 함수를 정의 할 수 있도록 만들려고했지만 Scala는 익명 함수에 유형 매개 변수를 허용하지 않는 것으로 나타났습니다. 사용하지 않고 내가하고있는 일을하는 또 다른 방법이있을 수 zipWithIndex있지만 그렇게 하는 영리한 방법에 대해서는별로 생각하지 않았습니다.

현재 코드는 두 단계로 실행됩니다. 첫 번째 보드는 새 보드를 생성하고 두 번째 패스는 보드를 인쇄합니다. 이 두 패스를 하나의 패스로 결합하면 몇 바이트를 절약 할 수 있다고 생각합니다.

이것은 내가 한 첫 번째 코드 골프이므로 개선의 여지가 많이 있다고 확신합니다. 가능한 한 바이트를 최적화하기 전에 코드를 보려면 여기에 있습니다.


1

자바 스크립트 (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>


너비는 셀 측면이 아니라 공백 (밑줄)을 포함합니다.
Matthew Roh

@MatthewRoh 죄송합니다. 높이를 수정하는 것을 기억했지만 너비를 확인하는 것을 잊었습니다.
Neil

흠 ..이 부분 `${`_O`.repeat(w).slice(w)} ${`O_`.repeat(w).slice(w)}은 어떻습니까? 어떻게 든 결합 될 수 있습니까? 아마도 처음에 부울 플래그 결정 _O또는 O_다음을 .repeat(w).slice(w)?
케빈 크루이 센

1
@KevinCruijssen 나는 당시 골프를 할 시간이 없었던 빠른 버그 수정으로 16 바이트를 잃었습니다. 그 이후로 또 다른 모습을 보았고 17 바이트 절약을하였습니다.
Neil

1

파이썬-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에 오신 것을 환영합니다! 도전은 취 하였다 w하고 h대신에 하드 코딩 갖는, (a 함수 입력, 또는 비슷한 같이 STDIN 통해)를 입력으로 H=4 W=6. 또한 파이썬으로 프로그래밍 한 적이 없지만 현재 코드에서 일부 공간을 골프로 칠 수 있다고 생각합니다. 파이썬에서 골프를 치기위한 팁은 골프를 밟는 방법에 대한 아이디어를 제공하기 위해 읽는 것이 흥미로울 수 있습니다. 체류를 즐길 수! :)
Kevin Cruijssen

또한, 귀하의 의견과 관련하여 : " 팝 사이에 줄 바꿈이 없어서 몇 개의 문자를 절약 할 수 있지만 그 결과는 추악하게 보입니다. "실제 프로그래밍에서 얼마나 못생긴 지 또는하지 않은지에 관계없이 codegolf는 다음과 같이 저장합니다. 가능한 많은 바이트. 짧고 추악할수록 좋습니다. ;)
Kevin Cruijssen

@ KevinCruijssen 위의 Python3은 w, h의 함수로 사용됩니다. 허용됩니까?
Arya


1
Ok-이제 H와 W의 기능으로 만들었습니다.
Arya

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

⎕← output
m←m , 여기서 m
'O_'[] 이 문자 는 …  숫자 숫자  배열 (행 및 열 수 )의 배열에서 모든 좌표 ( 개수 )  사이의 차이의
2| 두 개로 나눌 때 나누기-나머지로 구분됩니다. )
-/¨

(... )[... ]←'X' ... 중 하나에 문자 X 할당
b/ 필터링 된 부산물 B를 (규정한다)
,m m 구체적 ... 요소 raveled
? 의 범위의 하나에 임의의 요소 (문헌 참조)
+/ 의 합
b←(B) , B는
'O'= 부울 문자가
,mm raveled 와 같은 곳

⎕DL 1D의리터 AY 일초

→2 문자가 다음의 구성원인지 여부에 따라
/⍨ (조회하여 필터링 됨)  2 행으로 이동하십시오.
'O'∊
⎕←m  출력 값 하십시오. 여기서 출력 값은 m입니다.

온라인으로 사용해보십시오!


버전 16.0부터는 더 짧습니다.

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


1

파이썬 3, 195188 바이트

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)

사용 bytearray하고 decode문자열 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

자바 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

펄, 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.