Счетчик повторяющихся байтов


19

Ваша задача состоит в том, чтобы написать непустую программу / функцию подсчета байт L , который, когда повторные М раз, проверяет , является ли данная целым положительным числом N равен L × M .

Теоретически вы должны поддерживать произвольное количество повторений (произвольное положительное целое число M ), но это нормально, если из-за языковых ограничений он не может работать через определенный порог. Чтение исходного кода вашей программы или доступ к информации о нем строго запрещены .

Для обеспечения вывода вы должны выбрать непротиворечивое значение для одного из состояний (истинное или ложное) и использовать любой другой (не обязательно непротиворечивый) возможный вывод для другого состояния ( Обсуждение ).

Ваши ответы будут оцениваться по длине вашей начальной программы L (в байтах), при этом меньше байтов будет лучше.

пример

Допустим, ваша (начальная) программа ABCDE. Потом:

  • ABCDE(1 повторение) должен проверить, равен ли вход 5 .
  • ABCDEABCDE(2 повторения) должны проверить, равен ли вход 10 .
  • ABCDEABCDEABCDE(3 повторения) должны проверить, равен ли вход 15 . И т.д...

Оценка этого примера кода будет 5 , поскольку исходный источник имеет длину 5 байтов.


Просто чтобы уточнить: исходный код длины, соединенной Lпосле себя, Mдолжен возвращать, Nравен ли его входL*M ?

Ответы:


12

Желе , 1 байт

Выходной сигнал равен 0 для совпадения, ненулевой для несоответствия.

Попробуйте онлайн!

Как это устроено

Это дает преимущество чрезмерно либерального формата вывода. Повторение M раз просто уменьшает ввод M раз, поэтому результат будет нулевым, если и только если вводом является LM , где L = 1 .


О, боже, я не ожидал, что это произойдет ... ( inb4 каждый переносит это на другие esolangs ... )
Mr. Xcoder

Я имел в виду 0-байтовый ответ, но, ну, Quine . : P
Эрик Outgolfer

Первая мысль Избит на 23 минуты :(
Хулдраесет на'Барья,

11

Haskell, 8 байт

(-8+).id

Попробуйте онлайн!

Как и многие другие ответы, он возвращает 0 для истинности и не 0 для ложных, многократно вычитая длину кода из входного числа.


Я был так близок к тому, чтобы возиться с этим ...
человеческое

8

Сетчатка , 21 20 байт

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

_

Попробуйте онлайн! Просто повторите часть в окне кода, чтобы увидеть, как он обрабатывает мультипликаторы.

Дает 0правильные кратные и положительные целые числа для всего остального.

объяснение

Давайте сначала посмотрим на одну программу:

\d+
*

Это преобразует десятичное число в унарное (используя _в качестве унарной цифры).

^$
_

Если строка пуста (что не может произойти в этот момент, потому что входные данные гарантированно будут положительными), мы заменим ее одинарной _.

^_{20}

Теперь мы избавляемся от первых 20 подчеркиваний. Если вход был 20, это приводит к пустой строке.

_

И, наконец, мы подсчитываем количество подчеркиваний в результате, которое равно нулю, если ввод был 20.


Теперь, что происходит, когда мы повторяем исходный код. Так как мы не вставляем перевод строки при присоединении к программам, первая строка будет идти в конце последней строки, мы получаем это, когда программа удваивается:

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

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

_

Теперь вместо подсчета подчеркивания мы получаем следующую стадию:

_\d+
*

Этот этап ничего не делает, потому что в рабочей строке больше нет цифр, поэтому регулярное выражение не может совпадать.

^$
_

Теперь этот этап становится актуальным. Если ввод был кратен 20, строка была очищена предыдущей копией исходного кода. В этом случае мы превращаем его в единственное подчеркивание, которое, как мы знаем, больше никогда не может быть превращено нашей программой в пустую строку. Таким образом , мы гарантируем , что только в М - е множественный принимаются (и не все кратные вплоть до М - го).

^_{20}

Мы удалим первые 20 подчеркиваний еще раз. Таким образом, M повторений исходного кода удалит 20M подчеркивания из строки, если это возможно.

_

И когда мы дойдем до конца программы, мы по-прежнему будем считать подчеркивание, чтобы действительные входные данные давали ноль.


6

32-битный фрагмент машинного кода x86, 1 байт

48                      dec    eax

Вход в EAX, вывод в EAX: 0 для истины, ненулевое значение для ложных. (Также оставляет флаг ZF установленным для true, не установленным для false, чтобы вы могли je was_equal). В качестве «бонуса» вам не нужно беспокоиться об упаковке; 32-битный x86 может адресовать только 4 ГБ памяти, поэтому вы не можете сделать M достаточно большим, чтобы полностью обернуться и найти 1 == 2**32 + 1что-нибудь.

Чтобы создать вызываемую функцию, добавьте 0xC3 retинструкцию после повторения 0x48M раз. (Не учитывается при общем подсчете, потому что многим языкам нужно повторять только тело функции или выражение, чтобы иметь возможность конкурировать).

Вызывается из GNU C с помощью атрибута функции x86 прототипа __attribute__((regparm(1))) int checkeqM(int eax); GNU Cregparm , например -mregparm, использует EAX для передачи первого целочисленного аргумента.

Например, эта полная программа принимает 2 аргумента, и JIT помещает M копий инструкции + a 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

Первый аргумент in r0и возвращаемое значение in 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вместо этого вы получили память , оптимизация не происходит.
Джозеф Сибл-Восстановить Монику

4

V , 16 (или 1) байт

Скучный ответ:

<C-x>

один байт

Менее скучный ответ:

uÓ^$/0
16Ø^a$

Попробуйте онлайн!

HexDump:

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 только когда input = n*24.



2

TI-Basic (серия 83), 4 байта

:Ans-4

Принимает ввод в Ans: например, вы можете набрать, 17:prgmCODEGOLFчтобы запустить это с вводом 17. Печатает (и возвращает Ans) значение, 0если входное значение равно L × M , и ненулевое значение в противном случае.

Обратите внимание, что :это часть кода, поэтому, если вы вводите это в редактор программы, вы должны увидеть

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

JavaScript 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, поэтому отзывы приветствуются. Использует соглашение _fastcall с ecx в качестве первого аргумента.

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

Питер Кордес есть 1-байтовое решение в комментариях.


Комментарий Brainfuck : сложная часть состоит в том, чтобы заставить brainfuck вернуть единственное значение. Иначе что-то вроде этого было бы легко.

- >,[-<->] < .

1
Ваш фрагмент кода x86 будет иметь тот же размер для 32-разрядных целых чисел, нет необходимости ограничивать до 8. Но если вы использовали пользовательское соглашение о вызовах (arg в AL, retval где-то еще), вы могли бы использовать специальный двухбайтовый AL кодировка sub $4, %al/ mov %al, %dl. Или все же вернитесь в AL / EAX, и тогда вы получите решение Денниса с dec %eax(1 байт в 32-битном режиме). И да, пользовательские соглашения о вызовах хороши для asm. Это asm, а не просто "asm, который легко вызвать из C"; реальный код, написанный на asm, использует пользовательские соглашения о вызовах, где это помогает, так что это полностью оправдано.
Питер Кордес

1
Обычное соглашение о вызовах ARM - это первый аргумент arg, в r0котором также указан ответ, поэтому Thumb sub r0, #2имеет размер 2 байта.
Питер Кордес

1
Обратите внимание, что ни одна из этих функций не является функцией : для них требуется retконец блока повтора, прежде чем вы сможете их вызвать. Обычно я включаю retподсчет байтов для моих ответов на x86 asm. Но я думаю, что изменение правил здесь, чтобы только тело функции имело смысл, иначе многие языки не могут конкурировать вообще.
Питер Кордес

1
(НВМ, это не оставляет ретваль в% al). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecxсоставляет 4 байта и следует соглашению _fastcall. Использование AL, короткие кодировки imm8 и xchg-with-eax часто полезны для гольф-кода.
Питер Кордес

1
Я обычно использую, objdump -drwC -Mintelчтобы получить hexdump байтов машинного кода. add r32, imm8также 3 байта: код операции + ModR / M + imm8. Все инструкции, которые могут использовать imm32, имеют альтернативный код операции, который принимает расширенный знак imm8. См. Felixcloutier.com/x86/ADD.html, например; все «классические» инструкции ALU (но не MOV), относящиеся к 8086 году, имеют все эти кодировки, включая специальные AL / AX / EAX без modr / m, просто op + imm8 / 16/32. В этом ответе есть примеры
Питер Кордес

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

PS, вы можете получить тот же результат, +24;if N==ans;-1;end;ansно bytecount такой же


1

Луа, 56 46 байт

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

Выводит 0 (без завершающего символа новой строки), если оно равно, и либо ничего, либо последовательность отрицательных чисел (с предшествующим нулем в некоторых случаях), если они не равны.

В одиночку: попробуйте онлайн!

Повторил кучу раз: попробуйте онлайн!

объяснение

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

На первой итерации (когда она aеще не определена и, следовательно, есть nil) задается aчисло, взятое из ввода, в противном случае - для себя. В обоих случаях 46 затем вычитается из a.

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

Это просто печатает a если оно меньше чем (чтобы позаботиться о случаях, когда ввод был больше, чем общая длина) или равно нулю, и пустая строка в противном случае.

-10 байт для запоминания того, что Lua автоматически выполняет преобразование между числами и строками. Упс.


0

JavaScript (ES6), 47 байт

Это , используя ту же технику, Benoit Esnard в этом ответе (от меня двойной источник, вы удвоить выход! ).

Печать 0, если n = 47 * M , или ненулевое значение в противном случае.

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

Демо для М = 1

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

Демо для М = 2

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


0

Brain-Flak , 24 байта

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

Попробуйте онлайн!

Просто вычитает 24 из входных данных. Выходы0 для истины и что-нибудь еще для ложных.

Brain-Flak , 68 байт

{<>}<>(({}[((((()()()()){}){}()){}){}])<>{})((){[()](<{}<>>)}{}<>{})

Попробуйте онлайн!

Этот более сложный, он выводит 1как true, так и 0false.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.