볼링 대형 그리기 O O . O

당신의 목표는 일부 핀만 남아 있는 10 핀 볼링 에서 포메이션의 ASCII 예술을 표시하는 것입니다 . 가장 적은 바이트가 이깁니다.

수십 개의 핀은 삼각형 형태입니다.

O O O O
 O O O
  O O
   O

핀은 다음과 같이 1에서 10까지 표시됩니다.

7 8 9 10
 4 5 6
  2 3
   1

핀을 O핀으로 ., 핀을 누락 하면 다음 과 같이 구성 1 3 5 6 9 10됩니다.

. . O O
 . O O
  . O
   O

입력:

공백으로 구분 된 문자열로 1에서 10까지의 숫자가 아닌 하위 집합을 순서대로 나열합니다.

산출:

해당 형식을 인쇄하거나 줄 바꿈이있는 문자열로 출력하십시오.

포메이션은 스크린의 왼쪽과 같은 높이에 있어야합니다. 보이는 이미지가 정확하다면 모든 공백은 괜찮습니다. 앞뒤 빈 줄도 괜찮습니다.

테스트 사례 :

>> 1 2 3 4 5 6 7 8 9 10

O O O O
 O O O
  O O
   O

>> 7 10

O . . O
 . . .
  . .
   .

>> 3 5 7 9 10

O . O O
 . O .
  . O
   .

>> 1

. . . .
 . . .
  . .
   O


답변

브레인 퍽 – 617 616 604 바이트

+>>>>,[>++++[<-------->-]<[>>>>],]<<<<[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>[,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<]>[>>[,<]<<+++++++++<]<<<[-[+>>-<]>[>>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]]<<<[-[+>]+<<<<]>>>>-<<<<<]>>>>>+++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]<[<<<<]>>>++++[<-------->-]>[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>+[<++++[<++++++++>-]<]>>[+++++++++++++>>>>]<<<<----<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]>[.,>>]<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]<[<<]<...<<.

이것은 나에게 이틀의 더 나은 부분을 가져 갔다. 그만한 가치가 있다고 생각합니다. 어떤 셀에 어떤 것이 저장되어 있는지 또는 무엇이든 변경하여 더 많은 골프를 치는 부분이 있을지 모르지만 지금은 기쁘다.

질문이 입력을 정렬하도록 지정하지 않은 경우이 프로그램은 완전히 달라야합니다. 이것이 작동하는 방식은 입력되는 핀 주위에 10 개의 핀 목록을 구성하는 것입니다. 그것은 혼란 스럽지만 아마도 이것이 더 잘 설명 될 것입니다.

If you input these pins:           [2, 3, 6, 8, 9]
First, the program does this:      [2, 3, 6, 8, 9] + [10]
Then this:                         [2, 3, 6] + [7] + [8, 9, 10]
Then this:                         [2, 3] + [4, 5] + [6, 7, 8, 9, 10]
Finally, this:                     [1] + [2, 3, 4, 5, 6, 7, 8, 9, 10]
To build this:                     [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

그렇게하는 동안 사용자가 거기에 넣은 핀과 핀을 기억합니다. 입력이 정렬되지 않은 경우이 전략을 사용하기가 매우 어려울 것입니다.

분류가 더 쉬운 또 다른 것은 숫자 10을 감지하는 것입니다. brainfuck 자체는 “숫자”가 아닌 개별 바이트를 다루기 때문에 엉덩이에 통증이 있었을 수 있지만 정렬 된 입력으로 인해 처리하기가 훨씬 쉬워졌습니다. 와. 그 이유는 프로그램에 데이터를 저장하는 방법과 관련이 있습니다. 한 번에 한 문자를 입력하고 결과에서 32를 뺍니다. 그 후 셀이 0이 아닌 경우 4 셀 앞으로 이동합니다. 반복하기 전에. 즉, 4 셀마다 공백이 아닌 바이트의 입력을 받고 핀을 숫자 + 16으로 효과적으로 저장합니다. 그러나 10은 입력하는 데 2 ​​바이트가 걸리므로 특수한 경우가 필요했습니다. 입력이 정렬되지 않은 경우 핀을 살펴 봐야하지만 정렬되어 있기 때문에 그것이 나타날 경우 항상 마지막 핀이됩니다. (입력의 마지막 바이트 + 1) == (입력의 마지막 두 번째 바이트)인지 확인하고 그렇다면 10이어야합니다. 마지막 바이트를 제거하고 마지막 두 번째 바이트를 시스템이 이해하는 것으로 설정합니다. “10”. 캐릭터'1'그리고 '0'단일 바이트에 맞게, 그러나 수 (26)은 확인하지 않아!

무언가를 작동시키기위한 요령을 생각해내는 것이이 언어를 사용하는 데있어 제가 가장 좋아하는 부분입니다. 🙂

이 프로그램이 어떻게 작동하는지에 관심이 있다면, 프로그램을 작성할 때 사용한 주석과 함께 프로그램을보고 모든 일을 기억했는지 확인할 수 있습니다. 주석 구문이 없기 때문에 brainfuck로 주석을 작성하는 것조차 어렵습니다. 대신에있는 캐릭터를 제외한 모든 캐릭터 <[+.,-]>는 작전이 아닙니다. 귀하의 의견 을 실수로 포함 .시키거나 포함시켜 버그를 쉽게 소개 ,할 수 있습니다! 이것이 문법이 너무 까다 롭고 세미콜론이 도처에있는 이유입니다.

편집 : 이것이 얼마나 쉬운 짓의 예입니다 : 나는 의견 중 하나에 “비 공간”을 사용했습니다! 소스에서 비 bf 문자를 모두 제거했을 때, 내가 사용했던 프로그램은에서 유지되었습니다 -. 운 좋게도 아무것도 깨지 않았지만 이제는 바이트를 절약하기 위해 제거했습니다. 🙂

편집 II : 이 하나를 만진 지 오래되었습니다. 하하. 이 사이트의 또 다른 brainfuck 답변에서 실수로 주석이 달린 버전에서 쉼표를 사용했음을 알았습니다. 입력이 이미 소진되었으므로 현재 셀을 0으로 설정했습니다 (구현에 따라 다르지만 내 경험상 가장 일반적인 동작입니다). 버그를 수정했지만 생각이 듭니다. 셀을 0으로 설정하는 관용적 방법은 [-]대략 while (*p) { *p--; }2 바이트입니다. 모든 입력을 읽을 때마다 ,대신 사용할 수 있습니다 . 이것은 그 대답에서 2 바이트를 절약하고 이것에서 12 바이트를 절약했습니다!

one flag at the very left; will be important later
+>>>>

all nonspace bytes of input separated by 3 empty cells; pin number `n` stored with value `n` plus 16
,[>++++[<-------->-]<[>>>>],]<<<<

test if last pin is 10
[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>

[
    if not: find 10 minus the number it is; put that many placeholder pins (cells with value 1) at the end
    ,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<
]>


[
    if so: get rid of '0' byte; convert '1' byte to 26 (10 plus 16)
    >>[,<]<<+++++++++<
]<<<

pointer now sitting on the cell with the second greatest pin that was inputted (ie not a placeholder)

;;;;;;;

[
    check for flag placed at the very beginning of the program; if present: break
    -[+>>-<]>
    [
        find ((pin to our right) minus 1) minus pin to our left
        move all pins left of us 4*(that value) cells and insert placeholder pins
        >>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]
    ]

    find first non placeholder pin to our left
    there has to be one because we haven't hit the flag yet
    <<<[-[+>]+<<<<]>>>>-<<<<<
]>>>>>+

we have now added placeholder pins at the end and in the middle; all that's left is the beginning

subtract 17 from lowest pin and put that many placeholders to the left
++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]

subtract 32 from an empty cell 2 to the left of the lowest pin; will be useful later
<[<<<<]>>>++++[<-------->-]>

placeholder pins have the value 1; real pins have a value somewhere between 17 and 26
normalize it by stepping through and setting every pin with value != 1 to 3 (0's ascii code is 2 higher than period so this will make it easier to print later)
[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>

start writing 32s across the board; hitting every second cell
that's every pin and the cell 2 to the right of each pin
this is done in such a way that it will only halt if adding 32 to a cell sets it to 0; which is why we subtracted 0 from an empty cell earlier
it will catch us and prevent an infinite loop
+[<++++[<++++++++>-]<]

now write 13 to each pin; this adds up to 46 or 48; which are exactly the ascii values we want
>>[+++++++++++++>>>>]

we happen to have made a 14; turn it into a 10 for a newline
<<<<----

we're so close now; i can taste it
we have a list of 10 pins; each one with the ascii value that needs to be written
we have 32 everywhere because we'll need spaces
we even have a newline

the only problem now is that our list looks like this:
;;;;;;;;;;;;;;;;;;;;;;;;
;;1 2 3 4 5 6 7 8 9 10;;
;;;;;;;;;;;;;;;;;;;;;;;;

and we need to print in this order:
;;;;;;;;;;;;;;;;;;;;;;;;
;;7 8 9 10 4 5 6 2 3 1;;
;;;;;;;;;;;;;;;;;;;;;;;;

it's a pretty simple fix
once we print a pin we obviously don't need to remember it any more
so we simply print the last 4 pins on the list; destroying them on the way
then we print the last 3; which have become the ones we want
then two; then one
<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]

print pins 7 8 9 10
>[.,>>]

print pins 4 5 6
<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]

print pins 3 2
<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]

print the final pin!! :)
<[<<]<...<<.

답변

파이썬 2, 108 바이트

def f(x):
 for i in 4,3,2,1:print" "*(4-i)+" ".join(".O"[i*~-i/2-~z in map(int,x.split())]for z in range(i))

로 전화하십시오 f("3 5 7 9 10").

i는 행 번호이며, 4는 첫 번째 행이고 1은 마지막입니다. z는 해당 행의 n 번째 핀이며 0은 행의 첫 번째 핀이고 행 i-1의 마지막 핀임을 의미합니다.

주요 해킹은 i*~-i/2-~z, 어떤 개종자 (i, z) -> pin number. 예를 들어, (4, 0) -> 7핀 7은 행 4의 첫 번째 핀 (첫 번째 행)입니다. 파생은 다음과 같습니다.

  • 우리는 기능을 가지고 원하는 i행의 첫 번째 핀에 i4 -> 7, 3 -> 4, 2 -> 2, 1 -> 1. 이는로 만족 (i**2-i)/2 + 1되므로 (i**2-i)/2 + 1 + z입력에 올바른 핀 번호를 제공합니다.(i, z)

  • 그런 다음 단순화하십시오.

(i**2-i)/2 + 1 + z
  = (i*(i-1))/2 + 1 + z
  = i*~-i/2 + 1 + z
  = i*~-i/2-~z

Pyth , 33 바이트

V4~Z-4N+*dNjdm@".O"}+d-11Zrz7U-4N

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

이 프로그램은 대략 다음과 같이 번역됩니다.

z = input()
Z = 0

for N in range(4):
  Z += 4-N
  print(" "*N + " ".join(".O"[d+11-Z in map(int, z.split())] for d in range(4-N)))

(팁을위한 isaacg에 감사합니다)


답변

피 이스 , 31

V4+*dNjdm?\O}+7+dZrz7\.rN4~Z-N4

여기서 사용해보십시오 .

V4 N을 [0,1,2,3]에 대한 변수로 사용하여 for 루프를 설정합니다.

*dN공간이므로 초기 공간을 제공합니다 d.

핀 위치를 찾으려면 +7+dZ-7 + d + Z를 사용합니다.

d 입니다 :

0 1 2 3
 1 2 3
  2 3
   3

동시에 Z첫 번째 행에 0, -4 초에서, 제 -7 및 -8 앞뒤로한다. 이것은 Z0으로 시작 하고 4, 3, 2로 ~Z-N4감소하기 때문 Z입니다.

그런 다음을 사용하여 핀 위치가 입력에 있는지 확인합니다 }+7+dZrz7. rz7in-int 형식의 원하는 핀입니다.

그런 다음 O존재 하는 경우, .그렇지 않으면 생성합니다. 이 공간은으로 구분 jd되어 암시 적으로 인쇄됩니다.


답변

펄 5:51 (50 + 1 -p)

최근 perl 5 추가 중 하나 인 r플래그 사용 s///.

#!perl -p
$_="7890
 456
  23
   1
"=~s!\d!'. '^a
x/$&\b/!egr

답변

CJam, 48 41 바이트

와, 엄청나게 길었어

"6789345 12  0"S*7/N*[l~]:(s"O"erA,s"."er

여기에서 테스트하십시오.

설명

먼저 레이아웃을 생성합니다 :

"6789345 12  0"       "Push this string.";
               S*     "Riffle with spaces.";
                 7/   "Split into substrings of length 7.";
                   N* "Join with newlines.";

이 결과

6 7 8 9
 3 4 5
  1 2
   0

이제 입력에 따라 숫자 문자를 바꿉니다.

[l~]                 "Read the input and turn it into an array of integers.";
    :(s              "Decrement each number and turn the array into a string of digits.";
       "O"           "Push this string.";
          er         "Character transliteration, replaces the input digits with O.";
            A,s      "Create the string '0123456789'.";
               "."   "Push this string.";
                  er "Character transliteration, replaces all remaining digits with periods.";

답변

파이썬 2, 97 94

이것은 변환 함수를 사용하여 문자열에서 문자를 문자로 대체 할 수 있습니다. 입력하는 데 훨씬 더 긴 것을 제외하고 perl의 tr과 같습니다. 9에서 99의 거듭 제곱으로 문자열을 만들어 소수 자릿수 목록을 얻습니다.

lambda a:u"7890\n 456\n  23\n   1".translate({ord(n):u'.O'[n+' 'in a+' ']+' 'for n in`9**99`})

답변

자바 스크립트, 155

첫 골프는 아마 짧을 수 있습니다.

function f(i){q='replace',s='7 8 9 0\n 4 5 6\n  2 3\n   1';alert(s[q](RegExp(i[q]('10','0')[q](/ /g,'|'),'g'),function(a){return a?'O':a})[q](/\d+/g,'.'))}

와 전화

f('1 2 3 4 5 6 7 8 9 10')
f('1 5 10')
f('')

편집하다

ES6 버전, 130

f=i=>{q='replace',s='7 8 9 0\n 4 5 6\n  2 3\n   1';alert(s[q](RegExp(i[q]('10','0')[q](/ /g,'|'),'g'),a=>a?'O':a)[q](/\d+/g,'.'))}

편집하다

ES6 버전 79 실패

f=i=>alert('7890\n 456\n  23\n   1'.replace(/\d/g,a=>i.indexOf(a)<0?'. ':'O '))

ES6 버전, 72 77, 경고 없음, 그냥 반환

f=i=>'7890\n 456\n  23\n   1'.replace(/\d/g,a=>i.search(a+'\\b')<0?'. ':'O ')