별표 바이러스


9

양의 정수 N ( "virality")이 주어지면 프로그램은 왼쪽 상단에서 아래쪽으로 및 / 또는 오른쪽으로 연장되는 길이 N 의 두 가지 분기가있는 트리의 ASCII 그림을 작성해야합니다 .

첫 번째 별표 이후 각 지점에서 취한 방향 은 오른쪽 또는 아래쪽 일 수 있으며이 선택은 다음 단계마다 무작위로 1 로 설정 해야합니다 .

예를 들어, 입력이 5이면 출력은 다음과 같습니다.

***
* ***
**
 **

두 개의 브랜치는 접촉 할 수 있지만 (인접한 셀에 있음) 겹치지 않아야합니다 (동일한 셀에 있음). 따라서 다음은 허용되지 않습니다.

***
* *
*****
  *
  *

input 1의 경우 가능한 출력은 다음과 같습니다.

**
*

(두 분기가 동일한 경로를 사용하면 겹쳐 질 수 있으므로 모든 유효한 출력에 나타납니다.)

입력에 가능한 출력은 3다음 과 같습니다.

***
* *
**
**
***
*
*

입력의 경우 7:

****
*  **
*   **
*
***
  *

입력의 경우 10:

****
*  *      
*********
  *
  *****

이것은 따라서 가장 짧은 유효한 답변 (바이트)이 이깁니다.

1. 이것은 일정하게 무작위로 (즉, 각 방향의 50/50 확률), 또는 일반 하드웨어에서 얻을 수있는만큼 무작위로 근접해야합니다.


긴 게시물을 소비하는 데 문제가 있다면 의견을 말하십시오. 어쩌면 무언가를 줄일 수 있습니다 (나중에 시도 할 것입니다).
nicael

3
그것을 기대하는 법을 배우십시오. 때로는 너무 바빠서 바쁘다. 다른 때는 지금처럼 조용합니다. 잊지 마세요, 그것은 부활절이기도합니다.
Zacharý

내 게시물에 어떤 문제가 있는지 잘 모르겠습니다. 공감 한 사람이 설명하기에 너무 친절할까요?
nicael

1
IMO N 은 시간으로 더 잘 설명됩니다 : P
ASCII 전용 12

1
공백과 별표 대신 0s와 1s의 행렬을 반환 할 수 있습니까 ?
dylnan

답변:


5

CJam , 58 51 바이트

[TT]{_2_m*\f.+{:-},mR}ri*]ee{~\)S*\{'*t}/}%::a:.+N*

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

기본 아이디어는 시작 [0 0]하여 각 요소에 반복적으로 0 또는 1을 추가하고 (중복을 피하기 위해 시작하지 않는 한 절대로 같지 않도록) 모든 중간 결과를 수집하는 것입니다.

[[0 0] [0 1] [0 2] [0 2] [1 3]]

그런 다음 각 하위 배열 *에 원래 배열의 해당 쌍이 제공하는 인덱스에 다른 배열을 포함하는 큰 배열 배열을 만듭니다 .

["*"
 "**"
 "* *"
 "* * "
 " * * "]

그러면 출력 행렬의 대각선 조각이 생성됩니다 (왼쪽에서 오른쪽으로 이동하면 실제 행렬에서 오른쪽 위에서 왼쪽 아래로 이동하는 것에 해당).

그런 다음 ::a:.+"비대화 (de-diagonalize)"하고 결과 라인을 얻는 데 사용할 수 있습니다 .

[ "**** "
  "*  *"
  "** "
  " *"
  ""     ]

3

, 31 24 바이트

F²«J⁰¦⁰F⊕θ«¿ι*↓*≔‽²ι¿KK↗

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 원래 나는 첫 단계를 무작위로 만드는 것이 더 쉬울 것이라고 생각했지만 첫 번째 지점을 예측 가능하게 만드는 것은 골퍼였습니다. 설명:

F²«

index variable을 사용하여 두 번 반복하십시오 i. (실제로 암시 적 목록을 반복하므로 i루프 내에서 변경하는 것이 안전합니다 .)

J⁰¦⁰

캔버스의 원점으로 이동합니다.

F⊕θ«

루프 N+1타임.

¿ι*↓*

를 인쇄 *하되, 값에 따라 커서를 오른쪽 또는 아래쪽에 둡니다 i.

‽²ι

i내부 루프의 다음 반복 에 대한 값을 랜덤 화하십시오 .

¿KK↗

현재 캐릭터가 인 경우 *, 이것은 우리가 두 번째 분기이고 오른쪽 대신 아래로 내려 갔음을 의미합니다. 첫 번째 분기는 항상 아래쪽으로 시작하므로 두 번째 분기는 항상 그 위에 있으므로 세로 충돌 만 확인하면됩니다.


그것은 거의 정확하지만 N크기 가 아닌 가지를 인쇄 하지만 N-1크기는 :)
nicael

@nicael 죄송합니다.
Neil

이미 이것을 여러 번 본 적이 있지만 23 바이트
ASCII 전용

3

자바 10, 273 272 268 239 바이트

n->{var c=new char[++n][n];for(var d:c)java.util.Arrays.fill(d,' ');for(int i=0,j=0,k=0,l=0,r=0,s=0,t=0,u=0;n-->0;){c[i+=r][j+=s]=c[k+=t][l+=u]=42;do{r=t=2;r*=Math.random();t*=Math.random();s=r^1;u=t^1;}while(i+r==k+t&j+s==l+u);}return c;}

여기에서 온라인으로 사용해보십시오 .

29 바이트 골프 를 한 Kevin Cruijssen 에게 감사 합니다.

언 골프 버전 :

n -> { // lambda taking an int as argument
    var c = new char[++n][n]; // the output; increment the virality since the root does not count
    for(var d : c) // for every line
        java.util.Arrays.fill(d,' '); // initialize it with spaces
    for(int i = 0, j = 0, // coordinates of the first branch
            k = 0, l = 0, // coordinates of the second branch
            r = 0, s = 0, // offsets for the first branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
            t = 0, u = 0; // offsets for the second branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
        n-- > 0; ) { // decrement virality and repeat as many times
        c[i+=r][j+=s] = c[k+=t][l+=u] = 42; // move according to offsets and place an '*' for each branch, 42 is ASCII code
        do { // randomly pick offsets for both branches
            r = t = 2; // Math.random() provides results in [0,1)
            r *= Math.random(); // flip a coin for the first branch
            t *= Math.random(); // flip another coin for the second
            s = r^1; // set s to 0 if r=1, to 1 if r=0
            u = t^1; // set u to 0 if t=1, to 1 if t=0
        } while(i+r==k+t&j+s==l+u); // repeat if the branches overlap
    }
    return c; // return the output
}

239 바이트 (내가 do{}조금만 변경하고 for 루프의 첫 부분에 정수를 넣었습니다.) PS : 초기 답변에서 0.5골프 .5도 가능했습니다.
Kevin Cruijssen

@KevinCruijssen은 수학에 필요한 것 같습니다. 고마워 :-)
OOBalance

3

펄 5 , 208 124 122 118 바이트

줄 바꿈, 들여 쓰기 및 주석없이 118 바이트. 소요 N은 표준 입력에서 :

@b=1..2;                            #number of branches is 2
for(1..<>){                         #add length <> (the input) to each branch
  ($x,$y)=@$_                       #get where current branch has its tip now
 ,.5>rand?$x++:$y++                 #increase either x or y
 ,$o[$y][$x]++&&redo                #try again if that place is already occupied
 ,$_=[$x,$y]                        #register new tip of current branch
   for@b                            #...and do all that for each branch 
}
say map$_||!$i++?'*':$",@$_ for@o;  #output the branches

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


멋지지만 분기보다 별표 1을 짧게 인쇄합니다. :)
nicael

내 질문의 예를 다시 참조하십시오 :)
nicael

아, 나는 변경했습니다 2..$N1..shift지금 또한 몇 바이트를 면도.
Kjetil S.

1
좋은 대답입니다! parens를 피하기 위해 호출하는 reorderinf뿐만 아니라 인수와 인수 <>대신에 및 입력을 사용하여 몇 바이트를 저장할 수 있습니다 . 과제를 포장 할 필요는 없습니다 . 나는 작동하는 것처럼 보였지만 너무 많이 실험하지 않았기 때문에 가장자리가 그리 웠습니다. 그들이 조금 도움이되기를 바랍니다! shiftrand@o@b=([],[]);
돔 헤이스팅스

1
펄 페이지에서 골프에 대한 팁 좋은 조언을 가지고, 그것을 확인하시기 바랍니다! 행운을 빌고 재미있게 보내!
Dom Hastings



1

PHP, 118 바이트

for($r="*",$w=$argn+2;$argn--;$r[$q+=rand(0,$r[$q+1]<"*")?:$w]=$r)$r[$p+=rand(!$i++,1)?:$w]=$r;echo wordwrap($r,$w-1);

Elvis 연산자에는 PHP 5.4 이상이 필요합니다. 교체 ?:?1:오래된 PHP를 위해.

파이프로 실행 -nR하거나 온라인으로 사용해보십시오 .


1
다른 입력을 어떻게 확인합니까?
nicael

@nicael : 당신은 라인의 인수를 변경할 수 있습니다$argBak=$argn=
Galen Ivanov

확인! 이것이 좋은 방법인지 아닌지 확실하지 않은 방법으로 입력을 "수락"할 수는 있지만, 커뮤니티가 투표를 통해 결정하도록하십시오
nicael

@nicael TiO에서 간단히 값을 바꿉니다 $argn. 실제 환경 $argn에서 STDIN을 파이프로 실행하면 STDIN 에서 제공됩니다 -R. 그런 다음 각 입력 줄에 대해 코드를 실행합니다 (그러나 PHP는 그 사이에 변수를 설정 해제하지 않으므로 분명한 연속 실행은 나쁜 놀라움을 피할 가능성이 높습니다.)
Titus

0

빨강 , 195 190 바이트

func[n][g: func[s][i: 0 d: s while[i < n][b/(d): #"*"until[r: 1 if 1 = random 2[r: n + 1]b/(d + r) =#" "]d: d + r
i: i + 1]]b:""loop n[loop n[append b" "]append b"^/"]b/1: #"*"g n + 2 g 2 b]

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

읽을 수있는 :

f: func[n][
    g: func[s][
        i: 0
        d: s
        while[i < n][
            b/(d): #"*"
            until[
                r: 1 if 1 = random 2[r: n + 1]
                b/(d + r) = #" "
            ]
            d: d + r
            i: i + 1
        ]
    ]
    b: ""
    loop n[loop n[append b " "]append b "^/"]
    b/1: #"*"
    g n + 2
    g 2
    b
]

0

젤리 , 50 43 41 바이트

2ḶẊ⁸С+\‘Ṗ
⁸ÇU;Ǥ⁻Q$¿
‘,þ`⁼€þÇS+»þ`Ị$ị⁾* 

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

이것은 정말로 재미있는 글이었습니다. 훨씬 더 최적의 방법이있을 수 있습니다. 이 방법에는 골프가 있을지도 모릅니다.

내가 이것을 게시 한 직후에 ,þ`대신 사용할 수 있음을 깨달았습니다 aþ,""oþ`Ɗ.


0

R , 148142 바이트

n=scan();`~`=sample;o=r=k=1;l=c(1,n);for(i in 1:n){r=r+l~1;t=l~1;k=k+"if"(k+t-r,t,l[l!=t]);o=c(o,r,k)};write(c(" ","*")[1:n^2%in%o+1],1,n,,"")

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

또한 출력 사양에 맞지 않지만 두 가지를 구분할 수 있습니다. 온라인으로 사용해보십시오!

설명:

인덱스에서 시작 1, 우리는 무작위 지점의 오른쪽 또는 왼쪽으로 이동을 선택 r추가 n또는 1각각. 그런 다음 branch k에 대해 다른 오른쪽 또는 왼쪽 이동을 r선택하고 진행 방향 과 교차하는 경우 다른 방향을 선택합니다. 그럼 우리가 사용 r하고 k의 인덱스 등 m으로 그 값을 설정 "*". 반복 n-1시간, 결과를 인쇄합니다.



0

파이썬 (2) , 191 (187) 176 바이트

from random import*
n=input()
p,q=c=1,1j;s={p,q,0}
exec'z=choice(c);q,p=p+[z,1+1j-z][p+z in s],q;s|={q};'*2*~-n
R=range(n+1)
for y in R:print''.join(' *'[y+x*1jin s]for x in R)

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

파이썬은 복잡한 형태의 폼을 기본적으로 지원합니다 a+bj. 이것은 2D 문제를 좀 더 다루기 쉽게 만듭니다 ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.