일상적인 콩 기계가 아님


42

빈 머신 이나 plinko / pachinko 게임 과 유사한 메커니즘의이 ASCII 버전을 고려하십시오 .

    O

    ^
   \ ^
  ^ ^ \
 \ ^ / ^
U U U U U
1 2 3 4 5

O아래로 떨어지는 볼 수 있습니다.

  • 이에 ^맞으면 50 ~ 50의 확률로 왼쪽이나 오른쪽으로 갈 것입니다.
  • 가에 도달 /하면 항상 왼쪽으로 이동합니다.
  • 가 맞으면 \항상 올바르게 진행됩니다.

공은 결국 U바닥에있는 트로프 중 하나에 속합니다 . 문제는 각 구유에서 발생 될 확률은 얼마입니까?

이 특별한 경우에 대해, 확률은 0.0, 0.1875, 0.5625, 0.125, 및 0.125은 각각 5 내지 1 골.

여기에 3 개 골짜기 대신 5. 확률은 또 다른 예입니다 0.5, 0.5그리고는 0.0:

  O

  /
 ^ ^
U U U
1 2 3

이 과제에서 우리는이 문제를 어떤 방식 으로든 많은 수의 레이어가 설정된 메커니즘으로 일반화 할 것입니다.

도전

메커니즘의 피라미드 구조를 ASCII로 나타내는 프로그램이나 함수를 작성하십시오. (stdin / command line / function arg.를 통한 입력)

적절한 모양으로 배치 할 수있는 공간이 있다고 가정 할 수 있습니다. 예 :

   ^
  \ ^
 ^ ^ \
\ ^ / ^

또는 공백이 전혀 없다고 가정 할 수 있습니다.

^
\^
^^\
\^/^

원하는 경우 후행 줄 바꿈 및 / 또는 일부 일관된 후행 공백 패턴이 있다고 가정 할 수 있습니다.

입력 피라미드 구조는 0을 포함하여 여러 레벨 (일명 선)을 가질 수 있습니다. 각 레벨에는 하나 이상의 ^, /또는 \마지막 레벨이 levels + 1있으며 맨 아래에는 입력의 일부가 아닌 트로프 가 있습니다 .

프로그램 / 기능은 볼이 각 트로프에있는 확률 목록을 인쇄 / 반환해야합니다 (가장 왼쪽 트로프부터 가장 오른쪽 트로프 순서로). 이 인쇄 될 때, 상기 적어도 3 소수점가 부동 소수점 값을한다 (또는 소수 불필요한 제로 포인트가 요구되지 않으며 1괜찮지 1.000, .5괜찮지 0.500등). 함수를 작성한 경우 값을 인쇄하거나 float의 목록 / 배열을 반환 할 수 있습니다.

합리적인 인쇄 목록 형식은 괜찮습니다. 예를 들면 0.5 0.5 0.0, [0.5 0.5 0.0], [0.5, 0.5, 0.0], {0.5, 0.5, 0.0}, 또는 0.5\n0.5\n0.0모든 괜찮을 것입니다.

0 레벨 : (사소한 일로 다운 U)

입력 : [no input/empty string given]
출력 :1.0

1 레벨 :

입력 : ^
출력 :0.5 0.5

입력 : /
출력 :1.0 0.0

입력 : \
출력 :0.0 1.0

2 단계 : (위의 두 번째 예)

입력:

 /
^ ^

산출: 0.5 0.5 0.0

3 단계 :

입력:

  ^
 ^ ^
^ ^ ^

산출: 0.125 0.375 0.375 0.125

입력:

  \
 / \
/ / \

산출: 0.0 0.0 0.0 1.0

4 단계 : (위의 첫 번째 예)

입력:

   ^
  \ ^
 ^ ^ \
\ ^ / ^

산출: 0.0 0.1875 0.5625 0.125 0.125

7 단계 :

입력:

      ^
     / ^
    ^ ^ /
   / \ / \
  ^ ^ / ^ \
 ^ \ ^ \ / ^
\ ^ ^ ^ \ ^ /

산출: 0.0 0.09375 0.28125 0.4375 0.1875 0.0 0.0 0.0

채점

바이트 단위의 최단 답변이 이깁니다. Tiebreaker는 이전 게시물입니다.


16
Quincunx 는 이것에 더 잘 대답했습니다.
Calvin 's Hobbies

"일부 일관된 후행 공백 패턴"-N 번째 줄의 후행 공백이 공이 N 번째 버킷에 도달 할 확률을 인코딩한다고 가정 할 수 있습니까?
Random832

4
@ Random832 No. ( 정말로 날 것 같아요?)
Calvin 's Hobbies

답변 대신 의견으로 게시 한 이유가 있습니다. 나는 단지이 퍼즐이 입력에 대해 얼마나 관대하다는 것이 흥미 로웠다고 생각했다.
Random832

@ Random832 : 입력 및 출력이 매우 명확합니다. 입력에 대한 답변을 인코딩하는 것과 같은 표준 허점은 모든 도전에서 다룰 필요는 없습니다.
Alex A.

답변:


10

CJam, 50 48 45 44 42 40 바이트

1]q{iD%"(+0 0+( (\Y/::+ (d2/_a+"S/=~+}/p

이것은 입력에 공백이없고 줄 바꿈 문자가있을 것으로 예상합니다. 예를 들면 다음과 같습니다.

^
\^
^^\
\^/^

[0 0.1875 0.5625 0.125 0.125]

연산

기본 아이디어는 각 문자를 계속 구문 분석하고 (4 개의 문자 만 있음) 확률 분포 (처음에는 값 1의 1 요소를 포함하는 배열)에 대해 다른 작업을 수행하는 것입니다. 입력 문자의 각 행 (첫 번째 행의 첫 번째 문자로 시작)에 대해 동일한 크기의 확률 배열을 유지합니다. 각 문자는 목록에서 첫 번째 확률에 따라 작용하고 결과 쌍을 목록의 끝으로 푸시합니다. 각 줄마다 목록에서 쌍을 요약하여 다음 줄의 항목으로 정확한 개수의 항목을 얻습니다.

다음은 4 개의 문자와 각각에 해당하는 필수 조치입니다.

  • ^:이 문자가 발생하면 현재 확률을 두 부분으로 나눕니다. 우리는이 첫 번째 줄에있는 경우 예를 들어, 우리는 변환이 [1][0.5 0.5]
  • /:이 문자가 발생 <current probability> 0하면 배열에서 현재 확률을 대신 해야합니다 .
  • \:이 문자가 발생 0 <current probability>하면 배열에서 현재 확률을 대신 해야합니다 .
  • \n:이 캐릭터가 발생하면 새로운 줄이 생깁니다. 따라서 우리는 위의 3 자 이상의 모든 쌍을 그룹화하고 다음 줄에 대한 각 항목의 확률을 얻기 위해 합산합니다. 예를 들어. [0 0.5 0.25 0.25]로 변환됩니다 [0 0.75 0.25]. 첫 번째 항목과 마지막 항목은 그 전후에 암시 적 쌍 (값 0)을 갖습니다.

이제 우리는 올바른 캐릭터를 식별하고 올바른 행동 만 수행하면됩니다. 여기에 일반적인 수학을 사용할 수 있습니다. 대한 ASCII 코드 ^, \, /하고 \n있다 94, 92, 47,와 10. 몇 번의 시행 후,이 간단한 방정식을 통해이 숫자를 0, 1, 2 및 3으로 변환합니다.

"^\/
":ied13f%ed4f%ed

제공합니다 :

Stack: [[94 92 47 10]]
Stack: [[3 1 8 10]]
Stack: [[3 1 0 2]]
3102

길이가 4 인 배열에서 마지막 4f%은 암시 적입니다. 따라서 우리는 단순히 %13문자의 ASCII 코드를 수행하고 일련의 작업에서 올바른 작업을 선택합니다.

코드 설명 :

1]                                 e# Initial probability array with 1 probability
  q{                          }/   e# Read the whole input and iterate char by char
    iD%                            e# mod the ASCII code of the character with 13
"(+0 0+( (\Y/::+ (d2/_a+"S/        e# This is our actions array in order of [\ / \n ^]
                           =~      e# We pick the correct action and eval it
                             +     e# Evaling each action will leave one number out of the
                                   e# pairs out of the array. So we put it back in
                                p  e# Print the final probability array

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


1
0 행으로 어떻게 테스트합니까?
trichoplax

1
@trichoplax가 이제 작동합니다.
Optimizer

그것은 : 빈 입력이 지금 작동
trichoplax

15

루비 140

->s{r=[1.0]
s.lines.map{|l|n=[i=0.0]*(r.size+1)
l.scan(/\S/).map{|e|a,b=e>?/?e>?]?[0.5]*2:[0,1]:[1,0]
z=r[i]
n[i]+=z*a
n[i+=1]+=z*b}
r=n}
r}

문자열을 입력으로 사용하고 (피라미드로 멋지게 형식화 할 수있는) 부동 소수점 배열을 반환하는 함수입니다.

온라인 테스트 : http://ideone.com/kmsZMe

매우 간단한 구현입니다. 여기에 골퍼가 없습니다 :

F = -> input {
  probabilities = [1.0]

  input.lines.each { |line|

    new_probabilities = [0.0] * (probabilities.size+1)
    elements = line.scan /\S/
    elements.map.with_index{|el, i|
      deltas = el > '/' ? (el > ']' ? [0.5,0.5] : [0,1]) : [1,0]

      d1, d2 = deltas

      new_probabilities[i] += probabilities[i] * d1
      new_probabilities[i + 1] += probabilities[i] * d2
    }
    probabilities = new_probabilities
  }
  return probabilities
}

13

루비, 140158 바이트

더 나은 루비 버전 이있을 때 이것을 계속 찬성하지 마십시오 . 더 많은 트릭이 있습니다.

하나의 인수로 이름이없는 함수입니다. 공백이 없어야합니다. 후행 줄 바꿈을 포함하거나 포함하지 않을 수 있습니다.

->s{Z=(s.split'
')<<[]
K=[]
F=->i,j,f{k=Z[i][j]
K[i]||=0
k==?^?2.times{|m|F[i+1,j+m,f/2]}:!k ?K[j]+=f :F[i+1,j+(k==?/?0:1),f]}
F[0,0,1.0]
K}

처리해야 할 경우 9 바이트를 낭비합니다 0 levels(빈 문자열). 모든 테스트 케이스가 올바르게 작동합니다 ( ideone 참조) .


4
"더 나은"루비 답변이 있다고해서 귀하 (또는 그 문제에 대한 다른 루비 답변)가 투표 할 가치가 없다는 것을 의미하지는 않습니다. :)
Alex A.

좋은 트릭이 포함되어 있기 때문에 나는 이것을 스스로 찬성했습니다. split예를 들어 여러 줄이 마음에 듭니다 .
Cristian Lupascu

12

Pyth, 43 42 41 바이트

umsdc+0sm@c[ZJhkJZKcJ2K)2x"\/"ekC,GH2.z]1

이것은 공백이없는 입력을 기대합니다. 온라인 사용해보기 : Pyth Compiler / Executor

Pyth, 40 바이트 (문의 가능)

umsdc+0sm,K@[ZJhkcJ2)x"\/"ek-JKC,GH2.z]1

1 바이트를 절약 한 @isaacg에게 감사합니다. 이 버전은 질문을 받았을 때 실제로 Pyth 버전에서 작동하지 않았습니다. 컴파일러에 작은 버그가있었습니다. 이 코드는 Pyth의 새로운 기능을 사용하지 않지만 (Pyth 문서에 오랫동안 있었고 작동해야했던 것만 해당) 올바른 답변이 아닐 수도 있습니다. 스스로 결정하십시오.

온라인 사용해보기 : Pyth Compiler / Executor

설명:

umsdc+0sm,K@[ZJhkcJ2)x"\/"ek-JKC,GH2.z]1   
u                                   .z]1  reduce G, starting with G = [1], for H in all_input():
                               C,GH         zip(G,H)
        m                                   map each pair k to:
            [ZJhkcJ2)                         create a list [0, k[0], k[0]/2]
                     x"\/"ek                  index of k[1] in "\/" (-1 for "^")
          K@                                  take the correspondent element of the list and store in K
         ,                  -JK               create a pair (K, k[0]-K)                                                      
     +0s                                    sum and insert 0 at the begin
    c                              2        chop into pairs
 msd                                        sum up each pair
                                            G gets updated with this new list

예를 들어 현재 입력 확률 G = [0.5, 0.5, 0.0]과 행이 H = "^/^"있는 경우 다음이 발생합니다.

  • 지퍼 ... [(0.5,"^"), (0.5,"/"), (0.0,"^")]
  • 출력 확률 생성 ... [[0.25,0.25], [0.5,0.0], [0.0, 0.0]]
  • 0 + sum ... [0, 0.25, 0.25, 0.5, 0.0, 0.0, 0.0]
  • 잘라 ... [0,0.25], [0.25,0.5], [0.0,0.0], [0.0]]
  • 합계 ... [0.25, 0.75, 0.0, 0.0]

3
나는 이것을 골프로 만들려고했는데 컴파일러에서 버그가 발생했습니다. 골프가 작동합니다. 이제 버그를 수정했습니다. 골프는 2 값 목록의 목록을 하나의 목록으로 바꾼 다음에서 첫 번째 값을 빼서 다른 값을 생성합니다 hk. ,K@[ZJhkcJ2)x"\/"ek-JK
isaacg

1
버그를 수정하는 것이 최신 버전의 언어로 계산되지 않으므로 수정 전에 질문에 유효합니다.
Optimizer

1
@Optimizer 당신의 권리. 상황을 설명하는 몇 가지 메모를 답변에 추가했습니다.
Jakube

2
@Optimizer이 경우, 경험상 가장 좋은 규칙은 실제로 최신 버전의 언어 인지 아니면 버그를 수정하는 최신 버전의 언어 구현 인지 여부에 따라 구현이 사양에 더 가깝게 적용됩니다.
Desty

@Desty 그렇기 때문에 나는 그것이 훌륭한 라인이라고 언급 한 이유입니다.)
Optimizer

8

C #, 274247 바이트

STDIN에서 (공백 유무에 관계없이 줄을 읽고, 분리하여) STDOUT에 공백으로 구분 된 결과를 인쇄하는 환상적이고 완전한 프로그램은 없습니다.

using Q=System.Console;class P{static void Main(){decimal[]k={1},t;string L;for(int l=0,i;(L=Q.ReadLine())!=null;k=t)for(L=L.Replace(" ",""),t=new decimal[++l+1],i=0;i<l;)t[i]+=k[i]-(t[i+1]=(8-L[i]%8)/2*k[i++]/2);Q.WriteLine(string.Join(" ",k));}}

주석이 포함 된 간단한 코드 :

using Q=System.Console;

class P
{
    // / 47
    // \ 92
    // ^ 94

    static void Main()
    {
        decimal[]k={1},t; // k is old array, t is new array

        string L; // L is the current line, R is the current result (1 if no rows)
        for(int l=0,i; // l is length of old array, i is index in old array
            (L=Q.ReadLine())!=null; // for each line of input
            k=t) // swap array over
            for(L=L.Replace(" ",""), // remove spaces
                t=new decimal[++l+1], // create a new array
                i=0;

                i<l;) // for each position

                t[i]+=k[i]-( // add to left position (for last time)
                        t[i+1]=(8-L[i]%8)/2*k[i++]/2 // assign right position (k is decimal)
                    );

        Q.WriteLine(string.Join(" ",k)); // print result
    }
}

7

파이썬 3, 113

P=[1]
for C in input().split():
 l,*Q=0,
 for p,c in zip(P,C):r=p*"\^/".find(c)/2;Q+=l+r,;l=p-r
 P=Q+[l]
print(P)

P각 선에 따라 확률 벡터 를 반복해서 업데이트합니다 . 이 새로운 확률 벡터 Q는 한 번에 하나의 항목으로 만들어집니다. 새 슬롯을 반복하고 페그에서 오른쪽으로 r기여도를 계산하고, 다음 슬롯에 대한 나머지 기여도를 계산합니다 p-r.

라인이 백 슬래시로 끝나는 문제를 피하기 위해 각 라인이 최소한 하나의 공간에서 끝나기를 기대합니다.


입력에는 여러 줄이 있으므로 단일 항목으로 input()처리 할 수 없다고 생각 합니다.
randomra

입력의 각 줄에 후행 줄 바꿈이 필요하지 않습니다.
Brian Minton

@randomra 나는 이것을 유휴 상태로 작성했으며 쉘 프롬프트에 여러 줄 입력을 넣는 것이 효과적이었습니다.
xnor

6

파이썬 3, 138 바이트

def f(s):
 r=[1];p=t=0
 for e in s:
  if'!'<e:b=p==t*-~t/2;r+=[0]*b;t+=b;v=ord(e)%7+1;a=r[p]/2;r[-1]+=v//3*a;r+=v%3*a,;p+=1
 return r[~t:]

공백으로 모두 필터링되므로 공백으로 작동합니다 (기준 :) if'!'<e.

방법:

  • 우리는 r장애물과 그 아래에있는 암묵에 도달 할 확률 목록 을 계속 확장 하고 있습니다. 우리는 목록에서 시작합니다 [1].
  • 우리가 연속으로 첫 번째 장애물에 있다면 0선두 여물통에 대한 추가 목록을 추가 해야합니다. 인덱스 p를 다음 삼각 숫자와 비교하여 첫 번째 장애물인지 확인합니다 t*-~t/2.
  • 모든 장애물에 대해 목록 값을 부분적으로 마지막 요소에 추가하고 부분적으로 새로운 후행 요소에 추가합니다. 장애물 문자 ( ^:0.5 0.5; /:1 0; \:0 1)를 기준으로 목록 값을 나눕니다 . 우리는 다음 방법을 사용합니다.
    • 가지고 v = ord(char) mod 7 + 1항복^:4 /:6 \:2
    • v div 3 / 2첫 번째 분수를 산출합니다 ( ^:0.5 /:1 \:0)
    • v mod 3 / 2두 번째 분수를 산출합니다 ( ^:0.5 /:0 \:1)
  • 결과는 t + 1최종 목록 의 마지막 요소입니다 r.

@ Sp3000의 채팅 조언 덕분에 2 바이트.


4

펄, 78

#!perl -p0a
@r=($/=1);$^=.5;@r=map$r-$l+($l=$$_*($r=shift@r)),/./g,$r=$l=0for@F;$_="@r"

공백없이 입력을받습니다.

저를 보십시오 .


1

TI-BASIC, 73 76

TI-BASIC에서는 문자열의 줄 바꿈이나 빈 문자열이 적법하지 않기 때문에 한 번에 한 줄씩 입력하고 공백을 입력하면 끝납니다.

{1→X
Input Str1
While Str1≠"  //one space
.5seq(inString("^/",sub(Str1,I,1)),I,1,dim(Ans
augment(Ans∟X,{0})+augment({0},∟X-∟XAns→X
Input Str1
End
∟X

크기가 적당하다고 확신합니다. (TI-BASIC은 토큰 화되어 있으므로 각 명령에는 1 또는 2 바이트가 필요합니다. seq ()는 1, inString ()은 2, dim ()은 1 등을 사용합니다. 크기를 수동으로 계산했습니다.)

백 슬래시 문자는 문자열에서 유효하지만 계산기를 수정하지 않으면 프로그램 내부에서 백 슬래시 문자를 입력 할 수 없습니다.


0

자바 스크립트-117

재귀를 사용하려고 시도했지만 너무 길었습니다 ...

12 개 이상의 캐릭터를 제거하는 빼기 아이디어 를 위해 xnor의 모자 팁 .

w=s=>{a=[1];s.split('\n').map(m=>{for(b=[i=0];z=a[i],f=m[i];b[i++]+=z-b[i])b[i+1]=f>']'?z/2:f<':'?0:z;a=b})
return a}

언 골프 드 :

// s must not have spaces
w=s=>{
  // a is the current probability array
  a=[1];
  s.split('\n').map(
    // for each row of input...
    m=>{
      b=[0];  // b is the next row's probability array
      for(i=0; i<m.length;){
        z=a[i]; // z = probability
        f=m[i]; // f = letter
                                  // let's assume i == 0
        b[i+1] = (f>']') ? z/2 :  // if f == '^', b[1] = z/2
          (f<':' ? 0 :            // else if f == '/', b[1] = 0 
            z);                   // else b[1] = z
        b[i++]+=z-b[i];           // then add (z-b[1]) to b[0]
      }
      a=z-b    // increment current probability array
    }
  )
  return a;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.