반복 바이트 카운터


19

당신의 임무는 바이트 카운트 L 의 비어 있지 않은 프로그램 / 함수를 작성하는 것입니다.이 횟수 는 M 번 반복되면 주어진 양의 정수 NL × M 과 같은지 확인합니다 .

이론적으로는 임의의 수의 반복 ( M 의 임의의 양의 정수 값 )을 지원해야하지만 언어 제한으로 인해 특정 임계 값을 초과하여 작동하지 않는 것이 좋습니다. 프로그램의 소스 코드를 읽거나 이에 대한 정보에 액세스하는 것은 엄격히 금지되어 있습니다.

출력을 제공하려면 상태 중 하나에 대해 일관된 값을 선택하고 (진실하거나 허위) 다른 상태에 대해 가능한 다른 출력을 사용해야합니다 ( 토론 ).

답은 초기 프로그램의 길이 L (바이트) 에 따라 점수가 매겨지며 적은 바이트가 더 좋습니다.

(초기) 프로그램이라고 가정 해 봅시다 ABCDE. 그때:

  • ABCDE(1 반복) 입력이 5 와 같은지 확인해야합니다 .
  • ABCDEABCDE(2 회 반복) 입력이 10과 같은지 확인해야합니다 .
  • ABCDEABCDEABCDE(3 회 반복) 입력이 15 와 같은지 확인해야합니다 . 기타...

이 샘플 코드의 점수는 것 (5) 초기 소스가 5 바이트 길이로.


명확히하기 위해 : 자체 시간 후에 연결된 길이의 소스 코드 는 입력 이LMNL*M ? 인지 여부를 반환해야 합니다 .

답변:


12

젤리 , 1 바이트

일치 는 출력이 0 이고 일치하지 않으면 0이 아닙니다.

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

작동 원리

이것은 지나치게 자유로운 출력 형식을 이용합니다. M 횟수를 반복 하면 입력 M 횟수가 감소 하므로 입력이 LM 인 경우에만 결과가 0이됩니다 . 여기서 L = 1 입니다.


오 신 이시여 .. ( b4 모두가 다른 esolangs에 그것을 포팅 ... )
Xcoder Mr. 23:18

나는 0 바이트의 대답을 염두에 두었지만 eh, quine . : P
Outgolfer Erik

내 첫 생각. 23 분
치다

11

하스켈, 8 바이트

(-8+).id

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

다른 많은 답변과 마찬가지로 입력 숫자에서 코드의 길이를 반복적으로 빼서 진리의 경우 0을, 거짓의 경우 0이 아닌 값을 반환합니다.


나는이었다 그래서 ... 가까운이에 얻기에 땜질에
totallyhuman

8

망막 , 21 20 바이트

\d+
*
^$
_
^_{20}

_

온라인으로 사용해보십시오! 코드 창 에서 해당 부분을 반복 하여 다중을 처리하는 방법을 확인하십시오.

0다른 모든 것에 대해 올바른 배수 및 양의 정수를 제공합니다 .

설명

단일 프로그램을 먼저 살펴 보자.

\d+
*

십진수를 단항으로 변환합니다 ( _단항 숫자로 사용).

^$
_

문자열이 비어있는 경우 (이 시점에서 입력이 양수임을 보장하기 때문에 발생하지 않음) 단일 문자열로 대체합니다 _.

^_{20}

이제 첫 20 개의 밑줄을 제거합니다. 입력이 20인 경우 빈 문자열이됩니다.

_

마지막으로 결과의 밑줄 수를 세고 입력이 0이면 0 20입니다.


이제 소스 코드를 반복하면 어떻게됩니까? 프로그램에 참여할 때 줄 바꿈을 삽입하지 않기 때문에 첫 번째 줄은 마지막 줄의 끝에서 오른쪽으로 이동합니다.

\d+
*
^$
_
^_{20}

_\d+
*
^$
_
^_{20}

_

이제 밑줄을 세는 대신 다음 단계로 끝납니다.

_\d+
*

이 단계에서는 작업 문자열에 더 이상 숫자가 없으므로 정규식을 일치시킬 수 없으므로이 단계는 아무 것도 수행하지 않습니다.

^$
_

이제이 단계가 관련됩니다. 입력이 20의 작은 배수 인 경우, 소스 코드의 이전 사본에 의해 문자열이 비워졌습니다. 이 경우 단일 밑줄로 바꾸어 프로그램에서 다시 빈 문자열로 바꿀 수 없다는 것을 알고 있습니다. 이 방법은 우리가 보장 에만 M 번째 여러합니다 (최대 및 모든 배수 접수 M의 일을).

^_{20}

처음 20 개의 밑줄을 다시 한 번 제거합니다. 따라서 소스 코드를 M 반복 하면 가능한 경우 문자열에서 20M 밑줄 이 제거 됩니다.

_

그리고 프로그램이 끝날 때에도 유효한 입력 값이 0이되도록 밑줄을 세어 본다.


6

x86 32 비트 머신 코드 조각, 1 바이트

48                      dec    eax

EAX 입력, EAX 출력 : true의 경우 0, false의 경우 0이 아님. (또한 ZF 플래그를 true로 설정하고 false로 설정하지 않은 상태로 두어도됩니다.je was_equal 있습니다. "보너스"로서 랩핑에 대해 걱정할 필요가 없습니다. 32 비트 x86은 4GiB의 메모리 만 처리 할 수 ​​있으므로 M을 감싸서 찾 1 == 2**32 + 1거나 찾을 수있을 정도로 크게 만들 수는 없습니다 .

호출 가능한 함수를 만들려면 0xC3 ret0x48 M 번 반복 한 후 명령을 . (많은 언어가 경쟁 할 수 있도록 함수 본문이나 식만 반복하면되기 때문에 전체 수에 포함되지 않습니다).

프로토 타입 __attribute__((regparm(1))) int checkeqM(int eax); GNU C의 regparmx86 함수 속성으로 GNU C에서 호출 가능 , 같은-mregparm EAX를 사용하여 첫 번째 정수 인수를 전달합니다.

예를 들어,이 완전한 프로그램은 2 개의 args와 명령어 + a의 JIT M 사본을 ret버퍼로 가져간 다음 함수로 호출합니다. (실행 파일 힙 필요,로 컴파일 gcc -O3 -m32 -z execstack)

/******* Test harness: JIT into a buffer and call it ******/
// compile with gcc -O3 -no-pie -fno-pie -m32 -z execstack
// or use mprotect or VirtualProtect instead of -z execstack
// or mmap(PROT_EXEC|PROT_READ|PROT_WRITE) instead of malloc

// declare a function pointer to a regparm=1 function
// The special calling convention applies to this function-pointer only
// So main() can still get its args properly, and call libc functions.
// unlike if you compile with -mregparm=1
typedef int __attribute__((regparm(1))) (*eax_arg_funcptr_t)(unsigned arg);

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc<3) return -1;
    unsigned N=strtoul(argv[1], NULL, 0), M = strtoul(argv[2], NULL, 0);

    char *execbuf = malloc(M+1);   // no error checking
    memset(execbuf, 0x48, M);     // times M  dec eax
    execbuf[M] = 0xC3;            // ret
    // Tell GCC we're about to run this data as code.  x86 has coherent I-cache,
    // but this also stops optimization from removing these as dead stores.
    __builtin___clear_cache (execbuf, execbuf+M+1);
     //   asm("" ::: "memory");  // compiler memory barrier works too.

    eax_arg_funcptr_t execfunc = (eax_arg_funcptr_t) execbuf;
    int res = execfunc(N);
    printf("%u == %u  =>  %d\n", N,M, res );
    return !!res;   // exit status only takes the low 8 bits of return value
}

비 PIE 실행 파일 은 가상 메모리에서 더 낮은 수준으로로드됩니다. 더 큰 연속적인 malloc을 할 수 있습니다.

$ gcc -g -O3 -m32 -no-pie -fno-pie -fno-plt -z execstack coderepeat-i386.c
$ time ./a.out 2747483748 2747483748   # 2^31 + 600000100 is close to as big as we can allocate successfully
2747483748 == 2747483748  =>  0

real    0m1.590s     # on a 3.9GHz Skylake with DDR4-2666
user    0m0.831s
sys     0m0.755s

$ echo $?
0

 # perf stat output:
       670,816      page-faults               #    0.418 M/sec                  
 6,235,285,157      cycles                    #    3.885 GHz                    
 5,370,142,756      instructions              #    0.86  insn per cycle         

참고 GNU C가 지원하지 않는 개체가보다 큰 크기 ptrdiff_t(32 비트 부호)하지만,malloc 그리고 memset이 프로그램이 성공 때문에, 아직도 작동합니다.

ARM Thumb 머신 코드 조각, 2 바이트

 3802            subs    r0, #2

첫 번째 인수 r0및 반환 값 r0은 표준 ARM 호출 규칙입니다. 또한 플래그 ( s접미사)를 설정합니다 . 재미있는 사실; 의 -flag-설정 버전sub 32 비트 폭의 명령어이다.

추가해야 할 반품 지침은 bx lr 입니다.

AArch64 머신 코드 조각, 4 바이트

d1001000        sub     x0, x0, #0x4

64 비트 정수에서 작동합니다. 입출력x0표준 호출 규칙에 따라의 . int64_t foo(uint64_t);

AArch64에는 Thumb 모드 (아직)가 없으므로 1 개의 명령이 최선입니다.


이 문제를 겪고있는 다른 사람을위한 참고 사항 : 호출 __builtin___clear_cache은 필요한 메모리를 실행하고 있기 때문에 필요합니다 malloc. mmap대신 메모리를 가져 오면 최적화가 수행되지 않습니다.
Joseph Sible-Reinstate Monica

4

V , 16 (또는 1) 바이트

지루한 답변 :

<C-x>

1 바이트

덜 지루한 답변 :

uÓ^$/0
16Ø^a$

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

16 진 덤프 :

00000000: 75d3 5e24 2f30 0a31 3601 d85e 1261 240a  u.^$/0.16..^.a$.

나는 도전이 나온 지 약 5 분 후에 이것을 실제로 썼습니다. 언어 라고 부르는이 끔찍한 스파게티 코드를 패치하는 데 30 분이 걸렸습니다 .





2

Brain-Flak , 24 바이트

({}[(((()()()){}){}){}])

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

보고 0같거나 같지 않은 다른 것을 합니다.

작동 방식 :

({} #pop the top of the stack
  [(((()()()){}){}){}] #subtract 24
) #push the result.

이 코드 실행 n시간은 n * 24입력에서 빼고 입력 = 일 때만 0을 제공 n*24합니다.



2

TI 기본 (83 시리즈), 4 바이트

:Ans-4

에 입력 걸린다 Ans예를 들어, 사용자가 입력 할 수 있습니다 : 17:prgmCODEGOLF의 입력에 이것을 실행을 17. 입력이 L × M 과 같으면 Ans값을 인쇄하고 반환하고 그렇지 않으면 0이 아닌 값을 출력합니다.0

(가) 있습니다 :이 프로그램 편집기에이를 입력 그렇다면, 당신은 볼 수, 코드의 일부입니다

PROGRAM:CODEGOLF
::Ans-4

한번 입력하면

PROGRAM:CODEGOLF
::Ans-4:Ans-4:An
s-4

세 번 입력하면



1

Befunge-98 , 15 바이트

]#<@.-&+
>fv
v+

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

두 배로 해보십시오!

같으면 0을 사용하고 같지 않은 것은 사용

설명:

이 코드를 여러 번 반복하면 다음과 같이 보일 것입니다.

]#<@.-&+
>fv
v+]#<@.-&+
>fv
v+]#<@.-&+
>fv
 .
 .
 .
v+]#<@.-&+
>fv
v+
  1. ]우회전. IP를 아래로 보냅니다.

  2. >동쪽으로 이동 IP 권리를 보냅니다.

  3. f 16을 누르십시오.

  4. v남쪽으로 이동 IP를 아래로 보냅니다. 이것이 마지막 인 경우 8 단계로 이동하십시오.

  5. ]우회전. IP를 왼쪽으로 보냅니다.

  6. +더하다. 16을 스택 맨 위에 추가합니다.

  7. v남쪽으로 이동 IP를 아래로 보냅니다. 2 단계로 이동하십시오.

  8. <서쪽으로 이동 IP를 왼쪽으로 보냅니다.

  9. #건너 뛰기. 위로 뛰어 넘고 ]끝까지 감싸십시오.

  10. +더하다. 16을 스택 맨 위에 추가합니다.

  11. &입력. 사용자로부터 숫자를 누릅니다.

  12. -덜다. 우리가 작업 한 합계와 입력의 차이를 얻으십시오.

  13. .인쇄. 결과를 인쇄하십시오.

  14. @ 종료.



1

, 13 바이트

PI⁼Iθ×¹³L⊞Oυω

온라인으로 사용해보십시오! 내가 소스를 두 배로 내 대답에 따라, 당신은 출력을 두 배! 설명:

         ⊞Oυω   Push empty string to predefined empty list
        L       Take the length
     ×¹³        Multiply by 13
  ⁼Iθ           Compare to the input
 I              Cast to string
P               Print without moving the cursor

1진실하고 허위 로 출력 하도록 관리합니다 0. 이후 반복은에 대한 입력을 비교 13, 26, 39, 52등이 있지만 대답이 겹쳐 인쇄 할 때마다 그렇게 만 최종 답변을 볼 수 있습니다.


1

자바 스크립트 ES6, 32 바이트

((f=k=>n=>n>0?n==k:f(k+32))(32))

true이면 다른 값으로 0, false이면 31 바이트

(f=k=>n=>n>0?n-k:_=>f(k+_))(31)

console.log([
    ((f=k=>n=>n>0?n==k:f(k+32))(32)) (31),
    ((f=k=>n=>n>0?n==k:f(k+32))(32)) (32),
    ((f=k=>n=>n>0?n==k:f(k+32))(32)) (33),
    ((f=k=>n=>n>0?n==k:f(k+32))(32)) (64),
    ((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32)) (32),
    ((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32)) (63),
    ((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32)) (64),
    ((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32))((f=k=>n=>n>0?n==k:f(k+32))(32)) (96)
]);


1

MIPS, 4 바이트

$a0인수 및 반환 값으로 사용 합니다.

0x2084fffc    addi $a0, $a0, -4

MIPS, 8 바이트 (MIPS 호출 규칙 사용)

0x2084fff8    addi $a0, $a0, -8
0x00041021    move $v0, $a0

x86, 5 바이트

이것은 내 첫 x86 답변이므로 피드백을 환영합니다. 첫 번째 인수로 ecx와 함께 _fastcall 규칙을 사용합니다.

83 e9 05                sub    $0x5,%ecx
89 c8                   mov    %ecx,%eax

Peter Cordes 는 주석에 1 바이트 솔루션을 가지고 있습니다.


Brainfuck commentary : 어려운 부분은 brainfuck이 단일 값을 반환하도록하는 것입니다. 그렇지 않으면 이와 같은 것이 쉽습니다.

- >,[-<->] < .

1
x86 코드 조각은 32 비트 정수에 대해 같은 크기이며 8로 제한 할 필요가 없습니다. 그러나 사용자 지정 호출 규칙 (AL에서 ar, 다른 곳에서 retval)을 사용한 경우 2 바이트 AL special을 사용할 수 있습니다. 인코딩 sub $4, %al/ mov %al, %dl. 또는 여전히 AL / EAX로 돌아 가면 dec %eax(32 비트 모드에서 1 바이트)로 Dennis의 솔루션을 얻게 됩니다. 그렇습니다. 맞춤식 호출 규칙은 asm에 적합합니다. "C에서 쉽게 호출 할 수있는 asm"이 아니라 asm입니다. asm으로 작성된 실제 코드는 도움이되는 사용자 정의 호출 규칙을 사용하므로 완전히 정당화됩니다.
Peter Cordes

1
ARM의 일반적인 호출 규칙은 첫 번째 인수이며, r0이는 또한 retval이므로 Thumb sub r0, #2은 2 바이트입니다.
Peter Cordes

1
참고이 중 어느 것도 있음 기능 : 그들은을 필요로 ret당신이 그들을 호출 할 수 있기 전에 반복 블록의 끝에서. 일반적으로 retx86 asm 응답의 바이트 수를 포함합니다 . 그러나 함수 본문 으로 규칙을 구부리는 것은 의미가 있다고 생각 합니다. 그렇지 않으면 많은 언어가 전혀 경쟁 할 수 없습니다.
Peter Cordes

1
(nvm, 이것은 retval을 % al로 남겨 두지 않습니다). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecx는 4 바이트이며 _fastcall 규칙을 따릅니다. AL을 사용하면 imm8 및 xchg-with-eax 짧은 인코딩이 코드 골프에 종종 도움이됩니다.
Peter Cordes

1
나는 보통 objdump -drwC -Mintel기계 코드 바이트의 16 진수 덤프를 얻는 데 사용 합니다. add r32, imm8opcode + ModR / M + imm8도 3 바이트입니다. imm32를 사용할 수있는 모든 명령어에는 부호 확장 imm8을 사용하는 대체 opcode가 있습니다. 예를 들어 felixcloutier.com/x86/ADD.html 을 참조하십시오 . 8086 년으로 거슬러 올라간 모든 "클래식"ALU 명령어 (MOV는 아님)는 modr / m이없는 특수 AL / AX / EAX를 포함한 모든 인코딩을 가지고 있으며 op + imm8 / 16 / 32입니다. 이 답변은 예입니다
Peter Cordes

1

옥타브 : 23 바이트

+23;[ans,i]((N==ans)+1)

N = L * M 인 경우 표현식은 반환합니다 0+i(즉, 순수한 허수). 그렇지 않으면 표현식은 실수 성분을 갖는 복소수를 나타냅니다.

추가 바이트 비용으로 약간 더 좋은 결과를 얻으려면 :

+24;[ans,-1]((N==ans)+1)

N = L * M이면 표현식이 반환됩니다. -1 , 그렇지 않으면 양수를 .

데모:

N=48;
+24;[ans,-1]((N==ans)+1)                                                 #>> 24 
+24;[ans,-1]((N==ans)+1)+24;[ans,-1]((N==ans)+1)                         #>> -1
+24;[ans,-1]((N==ans)+1)+24;[ans,-1]((N==ans)+1)+24;[ans,-1]((N==ans)+1) #>> 23

추신 : 당신은 같은 결과를 얻을 수 +24;if N==ans;-1;end;ans있지만 바이트 수는 같습니다


1

루아, 56 46 바이트

a=(a or io.read())-46io.write(a<=0 and a or"")

같으면 0 (후행 줄 바꿈없이)을 출력하고 같지 않은 경우 일련의 음수 (일부 경우 앞에 0)를 출력합니다.

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

여러 번 반복 : 온라인으로 사용해보십시오!

설명

a=(a or io.read())-46

첫 번째 반복 ( a아직 정의되지 않았으므로 nil) a인 경우 입력에서 가져온 숫자로 설정 하고 그렇지 않으면 자체로 설정합니다. 두 경우 모두에서 46을 뺍니다 a.

io.write(a<=0 and a or"")

이 단지 지문 a이보다 작은 경우 (입력이 전체 길이보다 더 큰 어디에 경우 돌봐) 또는 제로로 동일하고, 그렇지 않으면 빈 문자열.

Lua는 숫자와 문자열 간의 변환을 자동으로 수행한다는 것을 기억하기 위해 -10 바이트 입니다. 으악.


0

자바 스크립트 (ES6), 47 바이트

이것은 이 답변 에서 Benoit Esnard 와 동일한 기술을 사용하고 있습니다 ( 소스를 두 배로하면 출력이 두 배가됩니다! ).

n = 47 * M 이면 0을 인쇄하고 , 그렇지 않으면 0이 아닌 값을 인쇄합니다.

n=prompt(setTimeout`alert(n)`)-47/*
n-=47//*///

M = 1에 대한 데모

n=prompt(setTimeout`alert(n)`)-47/*
n-=47//*///

M = 2에 대한 데모

n=prompt(setTimeout`alert(n)`)-47/*
n-=47//*///n=prompt(setTimeout`alert(n)`)-47/*
n-=47//*///


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