원형 테이프가 흥미 롭습니까?


32

Brainfuck 파생 상품

간단한 Brainfuck 같은 프로그래밍 언어를 정의 해 봅시다 . 셀에는 양방향 테이프가 있으며 각 셀에는 1 비트가 있습니다. 모든 비트는 처음에는 0입니다. 테이프에는 처음에 위치 0에 움직이는 헤드가 있습니다. 프로그램은 문자 <>01!에서 다음과 같은 의미로 왼쪽에서 오른쪽으로 실행되는 문자열입니다 .

  • < 머리를 왼쪽으로 한 단계 이동합니다.
  • > 머리를 오른쪽으로 한 단계 이동합니다.
  • 0 현재 셀에 0을 넣습니다.
  • 1 현재 셀에 1을 넣습니다.
  • ! 현재 셀을 뒤집습니다.

루프가 없으므로 n 문자 의 프로그램은 정확히 n 단계 후에 종료됩니다 . 실행이 끝날 때 모든 셀에 0이 포함되어 있으면 프로그램이 지루하고 1 이상이 있으면 흥미 롭습니다 . 테이프의 크기가 지정되지 않았으므로 구현에 따라 양방향 무한대이거나 회보.

예제 프로그램

프로그램을 고려하십시오 1>>>!<<<<0>!>>>!. 무한 테이프에서는 다음과 같이 실행됩니다.

     v
00000000000000  Put 1
     v
00000100000000  Move by >>>
        v
00000100000000  Flip
        v
00000100100000  Move by <<<<
    v
00000100100000  Put 0
    v
00000100100000  Move by >
     v
00000100100000  Flip
     v
00000000100000  Move by >>>
        v
00000000100000  Flip
        v
00000000000000

결국 모든 셀은 0 이므로이 프로그램은 지루합니다. 이제 길이가 4 인 원형 테이프에서 동일한 프로그램을 실행 해 봅시다.

v
0000  Put 1
v
1000  Move by >>>
   v
1000  Flip
   v
1001  Move by <<<< (wrapping around at the edge)
   v
1001  Put 0
   v
1000  Move by > (wrapping back)
v
1000  Flip
v
0000  Move by >>>
   v
0000  Flip
   v
0001

이번에는 값 1의 셀이 있으므로 프로그램이 흥미 롭습니다! 우리는 프로그램이 지루하거나 흥미로운 지 여부는 테이프의 크기에 달려 있음을 알 수 있습니다.

작업

귀하의 입력은 <>01!위의 프로그래밍 언어의 프로그램을 나타내는 비어 있지 않은 문자열 입니다. 문자 배열도 허용되는 입력 형식입니다. 무한 테이프에서 실행될 때 프로그램은 지루합니다. 출력물은 프로그램이 흥미 진진한 테이프 길이 목록이됩니다. 프로그램 길이보다 짧은 테이프에서만 프로그램을 테스트하면됩니다.

각 언어에서 가장 적은 바이트 수를 가진 솔루션이 승자입니다. 표준 규칙이 적용됩니다.

테스트 사례

> : []
110 : []
1>0<! : [1]
0>>1>0<<>! : [1]
1>>>!<<<<0>!>>>! : [2, 4]
!<!<><<0>!>!<><1!>>0 : [2]
>>!>><>001>0<1!<<!>< : [1, 2, 3]
1!><<!<<<!!100><>>>! : [1, 3]
!!1>!>11!1>>0<1!0<!<1><!0<!<0> : [3, 4]
<><<>>!<!!<<<!0!!!><<>0>>>>!>> : [1, 2, 4]
0>>><!<1><<<0>!>>!<<!!00>!<>!0 : [3]
0000!!!!><1<><>>0<1><<><<>>!<< : []
!>!>!>!>!>1>!>0<!<!<!<0<!<0<!<!<!<1>!>0<<! : [1, 2, 5, 7]
<!!>!!><<1<>>>!0>>>0!<!>1!<1!!><<>><0<<!>><<!<<!>< : [1, 2, 4, 5]
!>1<<11<1>!>!1!>>>0!!>!><!!00<><<<0<<>0<<!<<<>>!!> : [1, 2, 3, 5, 6]

1
대신에 명확하고 일관된 문자를 선택할 수 있습니까 <>01!?
Mr. Xcoder

1
명령 배열이 허용 가능한 입력입니까?
Arnauld

@ Mr.Xcoder 아니요, 정확한 문자를 사용해야합니다.
Zgarb

@Arnauld 문자 배열은 문자열에 충분히 가깝습니다. 허용하겠습니다.
Zgarb

답변:


6

하스켈, 119 바이트

t#'<'=last t:init t
(h:t)#c|c<'#'=1-h:t|c>'='=t++[h]|1<2=read[c]:t
f p=[n|n<-[1..length p],sum(foldl(#)(0<$[1..n])p)>0]

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

함수 #는 단일 명령의 해석기입니다 c. 전체 프로그램 p에 의해 실행됩니다 fold보내고 #로 시작하는 테이프 p. 모든 테이프에 대해 f실행 p되며 셀 합계가 1 이상인 테이프를 유지합니다.


n<-[1..length p] ... 0<$[1..n]꽤 긴 것 같습니다, 더 짧은 방법이 있어야합니다.
nimi

더 짧은 길을 볼 수 없습니다. 내가 보는 문제는 실제로 n결과 의 가치가 필요하다는 것입니다 . 따라서 0<$[1..n]다른 방법으로 (예를 들어와 같이 scanr(:)) 구성하면 그 가치를 사용해야 length합니다. (나는 또한 사용하여 시도 1(대체 할 lengthsum) 또는 False(사용하는 or) 대신 시험을 위해 0,하지만 짧은 나오지 않았다.)
Ørjan 요한센

@ ØrjanJohansen : 예, n<-init$scanr(:)[]$0<$p ... n2 바이트 더 짧은 것을 시도했지만 길이 대신 시작 테이프 목록을 반환합니다 ( 예 :) [[0],[0,0,0]]. 약간의 규칙 굽힘으로 테이프를 단항으로 볼 수 있으므로 괜찮을 것입니다.
nimi

init$[0]초기 목록 으로 넣어서 대체 할 수는 있지만 여전히 부족하지는 않습니다. 나는 단항식이 더 자연스러운 숫자 표현이없는 언어에 대해서만 허용 된다고 생각한다 .
Ørjan Johansen

4

Stax , 56 54 43 38 35 바이트 CP437

è¥%►BΣ░ÜY⌂y(â&.═ªê►V½▲y▌)▀♫♂╣ª?√»!#

압축을 풀 때 42 바이트

%fz(y{{|(}{|)}{B!s+}{0_]e&}4ls"><! "I@!F|a

온라인으로 실행하고 디버그하십시오!

@recursive의 댓글 당 -2 바이트

설명

설명을 위해 접두사 i(예 :)가있는 버전을 사용하고 제거 할 수있는 i%fz(y{{|(}{|)}{B!s+}{0_]e&}4ls"><! "I@!F|a이유를 설명하겠습니다.i

i               Suppress implicit eval
                    This prevents the test case "110" from being interpreted as a number
                    However, this can be removed because a program containing only numbers cannot be exciting and the output will be empty anyway.
                    This is based on the fact that the program is boring on non-circular tapes
 %f             Filter range [1..n] with the rest of this program
                    Where n is the length of the input
                    Implicit output the array after filtering, one element per line
   z(           Initialize the tape
     y{  F      Run the program
          |a    Any cell is non-zero

프로그램을 실행하기위한 코드 :

{|(}                                 Block to rotate left by one element
    {|)}                             Block to rotate right by one element
        {B!s+}                       Block to perform logical not on the element at index 0
              {0_]e&}                Block to obtain current instruction,
                                         Convert it to a number
                                         And assign to element at index 0

                     4l              Pack the 4 blocks in an array
                       s"<>! "I      Find the index of current instruction in string, if not found, the index will be -1
                                         And when indexed with -1, it wraps around to the 4th element.

                               @!    And execute the corresponding block.

1
i수표의 유효성을 검사하기 위해 모든 숫자의 테스트 사례를 추가했습니다 .
Zgarb

0]*로 교체 할 수 있습니다 z(. 또한, 다음! "<>"로 문자열을 변경하는 경우 01그 방법은 차단 목록은 단지 4 개 블록을 필요로하므로 이후 작동합니다 5.이 대신, 인덱스 -1 줄 것이다 01핸들러가 동일 어쨌든입니다.
재귀

@recursive 좋은 지적.
Weijun Zhou




2

빨강 , 243 바이트

func[p][repeat n length? p[b: copy[]insert/dup b 0 n i: 1
parse p[any["<"(i: i - 1 if i < 1[i: n])|">"(i: i + 1 if i > n[i: 1])|"0"(b/(i): 0)|"1"(b/(i): 1)|"!"(b/(i): either b/(i) = 0[1][0])|
skip]]s: 0 foreach c b[s: s + c]if s > 0[print n]]]

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

예쁘고 간결한 구현. Red의 1- 인덱싱을 사용하면 원형 테이프를 반복하기 위해 모듈 식 산술을 사용하여 바이트 수를 줄일 수 없습니다.

언 골프

f: func[p][ 
    repeat n length? p[
        b: [] 
        insert/dup b 0 n
        i: 1
        parse p[
            some [
                 "<" (i: i - 1 if i < 1[i: n])
               | ">" (i: i + 1 if i > n[i: 1])
               | "0" (b/(i): 0)
               | "1" (b/(i): 1)
               | "!" (b/(i): either b/(i) = 0 [1][0])
               | skip 
            ]
        ]
        s: 0
        foreach c b[s: s + c]
        if s > 0 [print n]
    ]
]


2

레티 나 121 바이트

.+
$.&*0¶$&
\G0
0$`¶
{ms`^.(?=.*¶¶(0|1))
$1
"¶¶!"&mT`d`10`^.
"¶¶>"&`(.)(.*)¶
$2$1¶
"¶¶<"&`(.*)(.)¶
$2$1¶
)`¶¶.
¶¶
G`1
%`.

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

.+
$.&*0¶$&
\G0
0$`¶

입력 프로그램 길이까지 각 길이의 테이프 배열을 작성하십시오.

{

프로그램이 사용될 때까지 반복하십시오.

ms`^.(?=.*¶¶(0|1))
$1

프로그램의 다음 문자가 0 또는 1이면 각 행의 첫 번째 문자를 해당 문자로 변경하십시오.

"¶¶!"&mT`d`10`^.

이 경우 !각 줄의 첫 번째 문자를 토글하십시오.

"¶¶>"&`(.)(.*)¶
$2$1¶
"¶¶<"&`(.*)(.)¶
$2$1¶

이 경우 >또는 <선을 회전하십시오. (머리를 움직이는 것보다 쉽습니다.)

)`¶¶.
¶¶

명령을 삭제하고 루프를 종료하십시오.

G`1

신나는 라인 만 유지하십시오.

%`.

각 줄의 길이를 세십시오.


2

자바 스크립트 (ES6) 126 118 바이트

@ user71546 덕분에 3 바이트 절약

입력을 1 자 문자열 배열로 취합니다.

f=(s,l=0,p=0,t=[])=>s[l++]?s.map(c=>1/c?t[p%l]=+c:c>'='?p++:c>';'?p+=l-1:t[p%l]^=1)&&+t.join``?[l,...f(s,l)]:f(s,l):[]

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


교체 t.some(x=>x)?+t.join``?대신하는 숫자로 배열 확인 (0은 모든 제로 테이프를 나타냄) 그러나 3 바이트 이하이다.
Shieru Asakoto

2

APL (Dyalog Unicode) , 79 64 54 바이트 ( Adám의 SBCS )

⍸⊂{∨/⍎⍕(↓',',⍨5 3'0@11@1~@1 1⌽¯1⌽')['01!<'⍳⌽⍺]⍵}¨0=,\

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

Adám 에게 -15 감사합니다 (monadic 잊어 버렸습니다 ). ngn
덕분에 -10 .



@ Adám Hm은 최적이 아닌 것 같습니다 (예 : 필요 없음 ). 살펴보고 업데이트하겠습니다. :)
Outgolfer Erik

당신은 제거하지만 당신이 필요합니다 ;아니?
Adám

@ Adám no , 왜 하시겠습니까?
아웃 골퍼 Erik


1

MATL , 46 39 바이트

f"@:~G"@59>?@61-YS}@33=?t1)~}@U]1(]]a?@

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

작동 원리

f             % Push indices of nonzero chars of (implicit) input string: gives
              % [1 2 ... n] where n is input length
"             % For each k in [1 2 ... n]. These are the possible tape lengths
  @:~         %   Push array of k zeros. This is the tape, in its initial state
  G           %   Push input string
  "           %   For each char in the input string
    @59>?     %     If code point of current char exceeds 59 (so it is '<' or '>')
      @61-    %       Push code point minus 61: gives -1 for '<', or 1 for '>'
      YS      %       Circularly shift the tape by that amount. Instead of moving
              %       the head, we shift the tape and keep the head at entry 1
    }         %     Else
      @33=?   %       If code point of current char is 33 (so it is '!')
        t1)   %         Duplicate the array representing the tape, and get its
              %         first entry
        ~     %         Logical negate
      }       %       Else
        @U    %         Push current char (it is '0' or '1') converted to number
      ]       %       End
      1(      %       Write (either 0, 1 or old value negated) at entry 1
    ]         %     End
  ]           %   End
  a?          %   If the tape contains at least a nonzero value
    @         %     Push tape length, k
              %   End (implicit)
              % End (implicit)
              % Display (implicit)

1

APL (Dyalog Unicode) , 192 78 바이트

⊂{t/⍵⊣⍵{t[m]←('01!'⍳⍵)⊃0 1,e,⍨~et[m←⍺|ii+←¯1 1 0⊃⍨'<>'⍳⍵]}¨⍺⊣i←⊃t←⍬⍳⍺}¨1+⍳∘≢

온라인으로 사용해보십시오! (평평하지 않은 결과)

온라인으로 사용해보십시오! (단조롭게 하는)

벽에 머리를 대고 시간을 보낸 후, 나는 Dfn 대신 Tradfn을 만들기로 결정했습니다. 이것이 결과입니다. 나보다 똑똑한 사람들은 이것으로부터 도둑질을 할 수 있습니다.

스마트 놀람, 놀람, 누군가 나보다 골프이 밖으로 지옥. Adám에 114 바이트 감사합니다.

그는 말했다 :

내부 : Ifs 및 collapsing : For-loops를 {_} ¨ 대신 사용하고 전역 인수를 대체 할 왼쪽 인수를 제공하는 것을 제외하고는 정확한 프로그램입니다.

이 함수는를 가정합니다 ⎕IO←0.


방법?

(이 설명은 "ungolfed"버전을 사용하여 읽기를 용이하게합니다)

⊂{                                   Enclose
      i←⊃t←⍬⍳⍺                       Assign a vector of 0s to t (the tape), then assign the first 0 to i.
      t/⍵⊣⍵{                         Use  as left argument for the nested function, then compress the result into t. If there is a 1 anywhere in t, the result will be a vector of the result. If not, the result is an empty vector.
          i+←¯1 1 0⊃⍨'<>'⍳⍵          Map the string '<>' to the argument (which is the BF program). That yields 0 for <, 1 for >, and 2 for anything else.
                                     The resulting vector will then be used as the argument for  to add -1 (index 0), 1 (index 1) or 0 (index 2) to the variable i.
          et[m←⍺|i]                 Assign i mod  (left arg) to m, and use it to index t. Then, assign the value to e.
          t[m]←('01!'⍳⍵)⊃0 1,e,⍨~e   Map the string '01!' to ⍵. As before, this yields 0 for 0, 1 for 1, 2 for ! and 3 for anything else.
                                     Then, concatenate (not e) with e, then concatenate that with the vector 0 1. This is used as argument to be picked from, and it is assigned to t[m].
      }¨⍺                            Do that for each argument
  1+⍳∘≢                            And do that for each possible tape length from 1 to the length of the input.

1
t←l⍴0be 를 만들고 t←l⍴i←0그 위의 줄을 제거하여 1 바이트를 저장하십시오 . 로 변경 t[i|⍨≢t]←1-t[i|⍨≢t]하여 다른 파일을 저장할 수도 있습니다 t[i|⍨≢t]←~t[i|⍨≢t].
Zacharý

2
@ Zacharý, 추가로 112 바이트를 추가저장하십시오 . 정확히 같은 코드, 약간의 골프.
Adám

그래, 그냥 "약간"갔다. s 가 필요하지 않습니까?
Zacharý

@ Zacharý 뭐죠 ? 암묵적인 기능입니다.
Adám

@ Zacharý 나는 이것을 꽤 Adám'd라고 생각할 것입니까?
J. Sallé


0

C (클랑) , 171 바이트

l,i;f(S){for(char*p,t[l=strlen(S)];l;memchr(t,1,l)&&printf("%d ",l),l--)for(memset(t,i=0,l),p=S;*p;p++)*p==60?i=i?i-1:l-1:*p==62?i=i^l-1?i+1:0:*p^33?t[i]=*p-48:(t[i]^=1);}

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

char*p,t[l=strlen(S)]어떤 이유로 든 초기화 표현식으로 사용 하면 GCC strlen를 호출하지 않고 선언하고 싶다고 생각하기 때문에 clang을 사용해야 했습니다.

매우 간단합니다 : 줄어드는 길이의 원형 테이프에서 프로그램을 실행하여 테이프 어딘가에 1을 초래하는 모든 길이를 출력합니다.

삼항 연산자의 엉킴을 줄이려고 노력했지만 건강보다 더 많은 괄호가 필요했습니다.


제안 i=0,bzero(t,l)대신 memset(t,i=0,l)하고 *p-62?t[i]=*p^33?*p-48:t[i]^1:(i=~i+l?i+1:0)대신*p==62?i=i^l-1?i+1:0:*p^33?t[i]=*p-48:(t[i]^=1)
ceilingcat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.