당신의 목표는 일부 핀만 남아 있는 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
행의 첫 번째 핀에i
예4 -> 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 앞뒤로한다. 이것은 Z
0으로 시작 하고 4, 3, 2로 ~Z-N4
감소하기 때문 Z
입니다.
그런 다음을 사용하여 핀 위치가 입력에 있는지 확인합니다 }+7+dZrz7
. rz7
in-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 ')