허리케인 매튜와 번개 볼트


27

도전

이 도전 과 불쾌한 허리케인 Matthew 에서 영감을 받아 번개를 동적으로 생성 할 것입니다.

n = 15 :

   \
   /\
  /  \
 /   /
/\  /\
 /  \ \
/   / /\
   /\ \
  / /  \
 /\ \  /\
  /  \ \
 /\  /  
   \
    \
    /\

입력

양의 정수 n는 번개의 깊이를 결정합니다.

규칙과 제약

  • /\사용되어야한다
  • 번개 방향을 안내하는 확률은 다음과 같습니다.
    • 25 %가 2 개의 경로로 분할
    • 25 % 경로가 막 다른 곳에 도달
    • 25 % 남음
    • 25 %가 옳다
    • 아래에 겹침 및 막 다른 골목에 대한 몇 가지 예외가 있습니다.
  • 코드는 결정적이어서는 안되며 매번 새로운 번개가 무작위로 생성되어야합니다.
  • 볼트가 겹치지 않아야합니다. 예를 들어, 현재 볼트의 왼쪽에 볼트가 이미있는 경우, 현재 볼트는 끝나거나 오른쪽으로 가야하지만 왼쪽으로 나눠지지 않아야합니다 (이 경우 여전히 50 %가됩니다) / 50 % 오른쪽)
  • 사용 가능한 다른 분할 경로가없는 경우 경로는 끝나지 않아야합니다. 예를 들어 경로가 하나 뿐인 시작 부분에서 경로는 분할 될 때까지 끝나지 않아야합니다. 목표는 바닥에 도달하는 것입니다 (확률이 33 % 분할 / 33 % 왼쪽 / 33 % 오른쪽이 됨)
  • 공백은 왼쪽에 추가 할 수 있습니다 (높이는 1이어야합니다).
  • 그러나 볼트를 생성하려는 경우 위의 모든 규칙이 충족되는 한 아래에서 위로, 왼쪽에서 오른쪽으로 갈 수 있습니다.

또 다른 예

n = 10

 \
 /
 \
 /\
  /\
 / /
/\ \
 / /\
 \   \
 /

허리케인 매튜가 하늘 위로 빨간 볼트를 쏘고 있습니다

안전을 유지하고 즐거운 골프를 즐기십시오! 안전한 지역에있을 때만 책임감있게 골프를 즐기십시오 !!


7
Stay safe and have fun golfing!또한 EAS가 타격을 받으면 모든 것을 버리고 명령을 따를 것을 명기하십시오! 이러한 상황에서는 골프 코드가 우선 순위가 아닙니다.
Outgolfer Erik

17
@EriktheGolfer 당신은 진정한 골퍼가 아닙니다.
Blue

4
나는 "가장 먼 길은 땅에 닿는 길이어야한다"는 말은 나머지 무작위 세대 기술과 일치한다고 생각하지 않습니다. 예를 들어, 원래 볼트를 두 번 분할 한 다음 중간 두 볼트를 종료 할 수 있습니다. 표시된 확률을 유지하면서 어떻게이 가능성을 무시할 수 있습니까?
Greg Martin

또한, 예를 들어 처음 두 단계가 모두 분할되면 어떻게됩니까? 그런 다음 가운데 두 개의 볼트가 서로 닿아 문제가있는 것처럼 보이지만 특별한 경우에는 배제되지 않습니다.
Greg Martin

@GregMartin 중심 부분의 좋은 점은 원래 균형 잡힌 볼트를 생성하기를 원했지만 이제는 중간에 깊이가 있어야하는 50 %의 제약이 없어도 깊이에 대해 생각합니다. 15 명 중 1 명은 1-2 %의 확률로 오른쪽 또는 왼쪽 경로가 도착합니다. 그 규칙을 제거하겠습니다. 그리고 2 단계 분할 부분의 경우, 2 개의 경로가 연결되어서는 안됩니다 \/.
Zukaberg

답변:


6

Perl, 92 90 89 84 바이트

에 +1 포함 -n

STDIN에 키를 줘 :

perl -M5.010 bolt.pl <<< 15

bolt.pl:

#!/usr/bin/perl -n
map{$_=$;until$;=$_,s/.6|3.?/53|16*rand/eg,/3|6/>/36/;say y|3615|\\/ |r}(1x$_.6)x$_

설명

시작점 0의 오프셋 (점은 문자 상자의 모서리에 있음)을 호출하면 다음 행에서 왼쪽 또는 오른쪽으로 이동하거나 오프셋으로 끝날 수 있습니다 -1,1. 다음 행은 -2,0,2가능한 오프셋 등을 제공 합니다. 모두 2만큼 차이가납니다. 점의 왼쪽 하단에 문자를 호출하고 오른쪽 하단에 홀수를 지정하면 각 문자 위치에 짝수 또는 홀수를 할당하도록 확장 할 수 있습니다 짝수 및 홀수 번갈아 (실제로 전체 평면이 바둑판 패턴으로 바둑판 식으로 배열 됨). 짝수 위치가있을 수 /또는 홀수 위치를 가질 수 있고, \또는 .

a 직전의 문자 /는 홀수 위치에 있으므로 \또는 로 가능하지만 \/금지되어 있으므로 가능합니다. 마찬가지로, 후 문자가 \ 있어야합니다(행 경계가 더 문제가 없습니다 있도록 행을 가정하면 왼쪽과 오른쪽에 충분한 공간으로 채워집니다). 따라서 번개는 다음 행에서 항상 a 바로 아래 \또는 바로 아래에서 계속됩니다 /. 두 경우 모두 아래쪽 지점이 중간에 있고 다음 행 /, \또는 /\상위 2 자 바로 아래 중 하나가있을 수 있습니다 . 다음 행을 생성하려면 간단히 \또는/이 네 가지 확장 중 하나에 의해 확률이 동일합니다 ( 또는 첫 번째 문자를 또는 /두 번째 문자를 또는로 독립적으로 바꿀 수도 있음 \). 펄에서는 다음과 같이 할 수 있습니다.

s#\\ | /#("  "," \\","/ ","/\\")[rand 4]#eg

그러나 결과 행에 \/(금지 된 조인)이 포함되거나 전혀 /없거나 \(볼트가 죽고 바닥에 닿지 않는) 결과는 유효하지 않습니다. 이 경우 전체 행을 버리고 다시 시도하십시오. 유효한 연속성이 항상 존재하며 자주 시도하면 충분히 찾을 수 있습니다 (예 : 1 개의 흐름을 제외한 모든 것이 죽습니다). 이것은 제안 된 겹침 방지 알고리즘과 약간 다른 확률 분포이지만 방향성 바이어스가 없으므로 실제로 더 낫습니다. 유효성은 다음을 사용하여 골프 방식으로 테스트 할 수 있습니다.

m#\\|/#>m#\\/#

여기서 문제는 무작위 대체가 너무 looooong이며 이러한 모든 \탈출은 바이트를 먹는다는 것입니다. 그래서 숫자의 문자열을 사용하여 내 행을 구축하여 적절한 자리 교체하기로 결정 , /그리고 \단지 인쇄하기 전에합니다. 기본적인 무작위 대체는

53|16*rand

어느 하나의 제공 53, 55, 61또는 63동등한 확률. 나는 그 해석 51같은 , 3같은 \6같은 /. 행 인쇄에 대해 설명합니다.

say y|3615|\\/ |r

진지한 골프 대회에서 나는 대안 적으로 마술 공식을 체계적으로 탐구하기 시작하지만, 이것은 아주 좋을 것입니다 (3 바이트 이내)

프로그램의 나머지 구성 요소 :

1x$_.6

이것은 $_높이 공간 다음에 a로 초기화됩니다 (다음 맵 참조) /. 이것은 인쇄되는 첫 번째 행 위에 보이지 않는 행이며 필드가 충분히 넓어서 볼트의 왼쪽 공간이 절대로 부족하지 않도록하십시오.

map{ ... ; say ...}(1x$_.6)x$_

매번 새로운 행을 인쇄하는 것과 동일한 초기 문자열 높이 시간을 처리합니다.

$_=$;until$;=$_,...

에 현재 행을 저장하십시오 $;. 대체 복원 무효로 밝혀지면 $_에서$;

s/.6|3.?/53|16*rand/eg

실제 대체를 수행하십시오. 나는 전에 무엇인지 확인할 필요가 없습니다 /이후 \는 이후 있어야 공백합니다. 공백은 1또는 로 표시 될 수 있으므로 편리합니다 5. \여전히 공백 이 없어도 공백을 왼쪽으로 채 웁니다. 따라서 해당 문자를 선택적으로 만드십시오

/3|6/>/36/

새 행이 유효한지 확인


깔끔한 +1! 이 온라인 테스터를 포함시켜야합니다 perl -M5.010 main.pl <<< 25. 좋은 결과를 얻었습니다!
Zukaberg

작동 방식에 대해 조금 설명해 주시겠습니까? 하하를 생성하는 것이 너무 재미있어서 솔직히 좋은 결과를 기대하지 않았습니다.
Zukaberg

불행히도 공백과 대시도 포함되므로에 대해 3 바이트를 추가해야합니다-n . 동일한 규칙이 명령 줄 인수에 적용됩니다. 두 번째 글 머리표 인 "특별 호출"을 참조하십시오. 나는 그것들을 포함하지 않은 가장 짧은 동등한 호출과 문자 수의 차이로 계산합니다.
Outgolfer Erik

1
이 프로그램을 사용하여 명령 줄에서 벌금을 작동하기 때문에 @EriktheGolfer 아니, 하나는 OK입니다 -nE만 1 문자 이상입니다 -E. (당신이 참조 문서를 참조하십시오.이도에 대한 요구를 제거한다 -M5.010) 난 항상 파일로 내 코드를 제시 그것 때문에 더 편리하지만 항상 다음과 같은 옵션을 계산합니다. 명령 줄에서 실행할 수 있으면 공간과 대시를 계산하지 않습니다. 이 경우 해야한다 (이것은 사용하기 때문에 예를 들어 파일에 수 do$0) 내가 공간 및 대시 계산
톤 Hospel

@TonHospel 오, 나는 당신이 사용한 것을 몰랐습니다 -E. 그렇다면 당신은 좋습니다.
Outgolfer Erik

0

자바 스크립트 (ES6), 154 바이트

f=(n,r=[],s=" ".repeat(n)+"/",t=s.replace(/ \/|\\ |\\$/g,_=>"  /  \\/\\".substr(Math.random()*8&6,2)))=>n?/^ +$|\\\//.test(t)?f(n,r,s):f(n-1,[...r,t],t):r
<input type="number" min=1 oninput=o.textContent=f(this.value).join`\n`><pre id=o>

@TonHospel의 답변을 볼 때까지 구현으로 어려움을 겪었습니다.이 시점에서 포트로 퇴화했습니다. 샘플 출력 :

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