한 번에 한 비트 씩 소스 출력


18

호출 될 때 단일 값 1 또는 0을 출력 할 때 여러 번 호출 될 때 출력 번호는 프로그램 소스 코드의 이진 표현을 생성합니다 (코드가 컴파일 된 동일한 코드 페이지에서). / 해석).

예를 들어, 소스 코드가 abcASCII 인 경우 출력은 다음과 같습니다.

1st call:  0           // ASCII letter 'a'
2nd call:  1
3rd call:  1
4th call:  0
5th call:  0
6th call:  0
7th call:  0
8th call:  1

9th call:  0           // ASCII letter 'b'
10th call: 1
11th call: 1
12th call: 0
13th call: 0
14th call: 0
15th call: 1
16th call: 0

17th call: 0           // ASCII letter 'c'
18th call: 1
19th call: 1
20th call: 0
21st call: 0
22nd call: 0
23rd call: 1
24th call: 1

After the 24th call, the behaviour is undefined.

소스의 이진 표현은 적어도 하나의 0 비트와 하나의 1 비트를 포함해야합니다.

1과 0 대신 두 개의 고유하고 일관된 값 (예 : truefalse)을 출력 할 수 있습니다 .

원본 코드의 이진 표현을 출력하는 자체 수정 프로그램은 다음에 인쇄 할 내용을 찾기 위해 소스 코드를 읽지 않는 경우 허용됩니다.

이것은 이므로 바이트 단위의 최단 답변이 이깁니다.

답변:


8

펑키 , 47 41 37 바이트

비트를 나타내는 숫자를 반환합니다.

f=_=>1&("%b"%("f="+f)[i//8])>>7-i++%8

이것은 quine 형식을 사용합니다 f=_=>"f="+f. ⌊i / 8⌋ 위치에있는 문자를 취한 다음 현재 문자의 ASCII 값이 n >> 7-i%8어디에 있는지 쌍을 취하여 비트를 가져옵니다 n.

이 함수는 i각 호출마다 증가하는 반복 함수이며 , 소스 코드에서 벗어나면 n영원히 코드를 작성합니다 .

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


이것이 JavaScript를 사용한 폴리 글롯입니까?
Stan Strum

9

배쉬 , 105 바이트

trap -- 'trap|xxd -b -c1|cut -d\  -f2|tr -d \\n|cut -c`x=\`cat f||echo 1\`;echo $((x+1))>f;echo $x`' EXIT

참고 : f테스트 할 디렉토리에 중요한 파일이 없는지 확인하십시오 .


이것을 테스트하려면 다음 명령을 사용할 수 있습니다.

for i in $(seq 848); do bash path/to/script.sh 2> /dev/null; done | tr -d \\n

동일한 출력을 제공해야합니다 xxd -c1 -b path/to/script.sh|cut -d\ -f2|tr -d \\n.

설명

이것은 trap트릭을 사용하고 있습니다 - 액션 trap내부를 호출 trap하면 해당 라인이 인쇄됩니다. 다음으로 출력이 파이프되어 출력 xxd을 바이너리로 변환합니다 (불행히도 xxd -bp작동하지 않습니다-따라서 cut&로 해결 방법 tr).

xxd -c1 -b $0|cut -d\  -f2|tr -d \\n

이것으로부터 N우리는로 선택할 수 있는 1 비트에만 관심이 있습니다 cut -cN.

N우리가 사용 하는 것을 찾으려면 (각 호출 후에 증가 해야하는 부분임을 기억하십시오) x파일의 내용으로 f설정하고 존재하지 않는 경우 1로 설정하십시오.

x=`cat f||echo 1`

할 마지막 일은, 파일을 업데이트하는 것입니다 f- 쓰기 x+1그것에 :

echo $((x+1))>f

7

TI 기본 (TI-83 시리즈), 592 357 309 바이트

"123456789ABCDEF02A3132333435363738394142434445463004AA003FB958833404593FB9588338045A3F3230363FDA582B383F303FCE5A405A6B3232333F5A70BB0FAA002BBB0CAA002B5A2B313FB932BA32F01058713459713511BB0FAA002BBB0CAA002B597031377132722B31→Str1
iPart(X/4→Y
iPart(X/8→Z
206
IS>(X,8
0
If Z and Z<223
Z+inString(Str1,sub(Str1,Z,1
iPart(2fPart(2^(X-4Y-5)inString(Str1,sub(Str1,Y+17-2Ans,1

이 표 는 소스 코드의 계산기 이진 표현에 대한 가능한 참조이지만 궁극적으로 Virtual TI의 디버거를 사용했습니다.

비교 및 / 또는 역사적 관심사 : TI-Basic으로 작성된 첫 번째 퀴네 .

작동 원리

Str1소스 코드를 저장합니다 (이전의 이진 버전보다 많은 공간을 절약하면서 영광스러운 16 진법으로 표시됨) Str1.

우리는 그래서, 프로그램은 그 메모리 단지 삭제 된 계산기에 밖으로 시작한다고 가정하고 X있다 0. 프로그램을 통해 매번 증가 X합니다.

보통, 우리는 비트를 추출하고,에서 읽고 Str116 진수에서 2 진수로 변환하여 인쇄 하려고하는 하프 바이트를 알아냅니다 . 우리는 저장있어 소스 코드의 일부에 경우 Str1(프로그램의 전체 길이의 3 분의 2 인), 저장 문자열의 해당 부분에 우리 첫 번째 이동 31, 32등.


4

자바 (8) 249 241 237 234 148 바이트

int i;v->{String s="int i;v->{String s=%c%s%1$c;return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}";return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}

자세한 설명은 미리 죄송합니다. :)

  • @Nevay 덕분에 89 바이트가 줄었습니다 .

여기에서 시도하십시오.

설명:

int i;                     // Index-integer on class-level
v->{                       // Method with empty unused parameter and integer return-type
  String s="int i;v->{String s=%c%s%1$c;return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}";
                           //  String containing the unformatted source code
  return s.format(s,34,s)  //    Quine to get the source code,
      .charAt(-i/8)        //     and get the character at index `-i/8`
     >>                    //    And bitwise right-shift it with:
       (--i&7)             //     `i-1` bitwise-AND 7
                           //     by first decreasing `i` by 1 with `--i`
      &1;                  //   Then bitwise-AND everything above with 1
}                          // End of method

추가 설명 :

part :

  • String s 형식화되지 않은 소스 코드를 포함합니다
  • %s 이 문자열을 자체에 넣는 데 사용됩니다. s.format(...)
  • %c, %1$c34(이중 따옴표를 포맷하는 데 사용됩니다 ")
  • s.format(s,34,s) 다 합쳐

quine 출력이 자체 소스 코드인지 확인하기 위해 일부 부품을 제거 / 수정하여 여기에서 시도하십시오.

부분 :


이전 233 바이트 답변 :

int i;v->{String s="int i;v->{String s=%c%s%1$c;return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%%8);}";return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%8);}

여기에서 시도하십시오.

설명:

int i;                           // Index-integer on class-level
v->{                             // Method with empty unused parameter and char return-type
  String s="int i;v->{String s=%c%s%1$c;return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%%8);}";
                                 //  String containing the unformatted source code
  return Long.toString(
          (s.format(s,32,s)      //  Quine-formatting
          .charAt(i/8)           //  Take the current character
           &255)+256,2).substring(1)
                                 //  Convert it to an 8-bit binary-String 
         .charAt(i++%8);         //  And return the bit at index `i` modulo-8
                                 //  and increase index `i` by 1 afterwards with `i++`
}                                // End of method

추가 설명 :

part :

다음을 추가하여 위와 동일한 설명 :

  • %%모듈로 부호 ( %) 의 이스케이프 된 형식입니다.

quine 출력이 자체 소스 코드인지 확인하기 위해 일부 부품을 제거 / 수정하여 여기에서 시도하십시오.

부분 :

  • i/8정수 나누기에서 자동으로 잘 리므로 i0-7 일 때 0; 경우 i8-15, 그것은 될 것입니다 1; 기타
  • 그래서 s.charAt(i/8)소스 코드, 서로 후 여덟 번의 현재의 문자를합니다. 수정 된 버전으로 여기에서 사용해보십시오.
  • 2550xFF또는 11111111(부호 바이트 최대 값)
  • 256이다 0x100100000000.
  • &정수에 ASCII 문자를 업 캐스팅합니다. 그 시점에서, 그 사이 어디의 0255(00000000 ~ 11111111) 있습니다.
  • Long.toString(...,2) 9 비트 이진 문자열 표현으로 변환
  • +256.substring(1)선행 0가 보장되며, 8 비트에 9 비트 변환합니다.

전체 바이트를 확인하기 위해 일부 부품을 제거 / 수정 한 상태로 시도하십시오.


1
149 바이트 :int i;v->{String s="int i;v->{String s=%c%s%1$c;return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}";return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}
Nevay

@Nevay 무려 88 바이트가 저장되었습니다. 감사! 그리고 실제로는 원래와는 다른 접근 방식이기 때문에 이전 답변을 유지하고 새로운 것을 추가했습니다. (원하는 경우 다시 삭제하고 직접 게시 할 수 있지만 과거에 본인의 답변을 게시하는 대신 주로 XD 코드 인 다른 사람들의 골프를 선호한다고 말했습니까?
Kevin Cruijssen

2

자바 스크립트 ES6, 73 58 52 바이트

o=_=>`o=${o}`.charCodeAt((o.n=1+o.n|0)/8)>>(7-o.n%8)&1

설명

코드 분석 :

  • o=_=>: 함수를 정의합니다.
  • `o=${o}`: 문자열을 구성; o이 경우 문자열로 변환되는데이 경우 함수의 소스 코드입니다.
  • .charCodeAt(: 문자열의 문자를 ASCII 문자 코드로 가져옵니다.
  • (o.n=1+o.n|0)/8: 캐릭터를 선택하십시오. 카운터가 증가하는 곳이기도합니다.
  • )>>(7-o.n%8): 원하는 비트가 올바른 위치에 있도록 결과 문자 코드를 이동합니다.
  • &1: 다른 모든 비트를 0으로 설정하십시오.

람다로 이것을 단축 할 수 있습니다o=_=>(o+'').charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco

이것은 함수 정의로 계산됩니다.
ATaco

1
시도o=_=>('o='+o).charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco

대신에 'n'in top?++n:n=0사용할 수있는 ++n||(n=0)또는 ++n?n:n=0또는 n=++n||0또는 n=1+n||0있는 모든 활용의 falsiness NaN그 증가에 의해 생성된다undefined
BERGI

1
o=_=>('o='+o).charCodeAt((o.n=1+o.n|0)/8)>>(~o.n&7)&1
tsh

2

q / kdb + , 45 바이트

해결책:

a:-1;f:{((,/)0b vs'4h$"a:-1;f:",($).z.s)a+:1}

예:

q)f[] / call function f with no parameters
0b   
q)f[]
1b   
q)f[]
1b   
q)f[]
0b   
q)f[]
0b   
q)f[]
0b   
q)f[]
0b   
q)f[]
1b   
q)f[]  
q)"c"$0b sv 01100001b / join back to a byte and cast to a character
"a"

설명:

나는 간단한 내용을 이해 했다고 생각 합니다.

먼저 a시작 값이 전역 변수 로 설정 -1됩니다. 함수 는 정크가 앞에 붙은 함수 (을 포함한 모든 것) f문자열 표현의 이진 표현을 작성하고 색인 a (이는 각 호출마다 증가 함)에서이 이진 목록으로 색인합니다.{}a:-1;f:

a:-1;f:{(raze 0b vs'4h$"a:-1;f:",string .z.s)a+:1} / ungolfed solution
a:-1;                                              / stick -1 in variable a
     f:{                                         } / define function f
                                             a+:1  / increment a by 1 (:: is required as a is a global variable), indexes into the left
        (                                   )      / do all this together
                                 string .z.s       / z.s is the function, string converts it to a string
                       "a:-1;f:",                  / prepend "a:-1;f:" to the start
                    4h$                            / cast to bytes
              0b vs'                               / convert each byte to binary
         raze                                      / flatten binary into long list

2

파이썬 2 , 164 바이트

lambda s='lambda s=%r,i=[]:i.append(1)or"{:08b}".format(ord((s%%s)[~-len(i)/8]))[~-len(i)%%8]',i=[]:i.append(1)or"{:08b}".format(ord((s%s)[~-len(i)/8]))[~-len(i)%8]

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

설명

표준 Python 2 quine부터 시작하겠습니다.

s = '...'; print s % s

알았어. 이렇게 출력하면 돼 바이너리가 필요합니다!

s = '...'; print "\n".join("\n".join("{:08b}".format(ord(i))) for i in s % s)

맞습니다. 모든 것을 이진으로 변환합니다. 그러나 제목은 "한 번에 한 비트"라고 말합니다. 우리는 여러 번 달리기를 지속 할 무언가가 필요합니다. 알아, 기능으로하자!

lambda s = '...': "\n".join("\n".join("{:08b}".format(ord(i))) for i in s % s)

잠깐만, 그건 도움이되지 않습니다 ... 흠, 출력에 필요한 비트 인덱스를 어떻게 추적 할 수 있습니까? Ooh, ooh, 추적 할 정수를 보자.

lambda s = '...', i = 0: "{:08b}".format(ord((s % s)[i / 8]))[i % 8]

음 ... 항상 첫 번째 비트를 출력합니다. 오, 추적기를 늘려야 해요! 아쉽게도 파이썬은 정수를 기본 인수로 수정할 수 없습니다. 그리고 할당은 파이썬에서 표현이 아니기 때문에 람다에서는 그렇게 할 수 없습니다. Welp, 이것은 파이썬에서 불가능합니다. 사건이 종결되었습니다.

글쎄요. 파이썬 리스트를 기본 인수로 수정할 수 있습니다. (그리고 그것은 항상 파이썬 프로그래머에게 물린다.) 길이를 사용하자!

lambda s = '...', i = []: "{:08b}".format(ord((s % s)[len(i) / 8]))[len(i) % 8]

그래도 여전히 트래커를 수정하지는 않습니다. 길이를 늘리기 위해 무언가를 추가 할 수 있습니다 ... 그러나 어떻게? 아, 우리는 list.append. lst.append(1)와 같습니다 lst += [1]. 큰!

lambda s = '...', i = []: i.append(1) and "{:08b}".format(ord((s % s)[len(i) / 8]))[len(i) % 8]

비트가 출력되기 전에 트래커의 길이가 1 이기 때문에 첫 비트를 건너 뜁니다 . 사용되는 길이를 줄여야합니다.

lambda s = '...', i = []: i.append(1) and "{:08b}".format(ord((s % s)[(len(i) - 1) / 8]))[(len(i) - 1) % 8]

거기 있습니다, 여러분! 그것을 골프하고 당신은 나의 해결책을 얻었다!


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