Powtarzalny licznik bajtów


19

Twoim zadaniem jest napisanie niepusty program / funkcję count bajtów L , która, gdy powtarzane M czasy, sprawdza, czy dana liczba całkowita dodatnia N jest równa L x M .

Teoretycznie powinieneś popierać dowolną liczbę powtórzeń (arbitralną dodatnią wartość całkowitą M ), ale w porządku, jeśli z powodu ograniczeń językowych nie może działać powyżej pewnego progu. Czytanie kodu źródłowego programu lub uzyskiwanie dostępu do informacji na jego temat jest surowo zabronione .

Aby uzyskać dane wyjściowe, należy wybrać spójną wartość dla jednego ze stanów (prawda lub fałsz) i użyć innego (niekoniecznie spójnego) możliwego wyniku dla drugiego stanu ( Dyskusja ).

Twoje odpowiedzi zostaną ocenione na podstawie długości początkowego programu L (w bajtach), przy czym mniej bajtów będzie lepszych.

Przykład

Powiedzmy, że twój (początkowy) program to ABCDE. Następnie:

  • ABCDE(1 powtórzenie) powinno sprawdzić, czy wartość wejściowa wynosi 5 .
  • ABCDEABCDE(2 powtórzenia) powinny sprawdzić, czy wartość wejściowa wynosi 10 .
  • ABCDEABCDEABCDE(3 powtórzenia) powinny sprawdzić, czy wartość wejściowa wynosi 15 . Itp...

Wynik tego przykładowego kodu wynosiłby 5 , ponieważ początkowe źródło ma 5 bajtów.


Tylko dla wyjaśnienia: kod źródłowy o długości Lskonkatenowanej po sobie Mrazy powinien zwrócić, czy jego dane wejściowe Nsą równeL*M ?

Odpowiedzi:


12

Galaretka , 1 bajt

Dane wyjściowe wynoszą 0 dla dopasowania, a niezerowe dla braku dopasowania.

Wypróbuj online!

Jak to działa

Wykorzystuje to zbyt liberalny format wyjściowy. Powtarzanie M razy po prostu zmniejsza wejściowe M razy, więc wynik wyniesie zero wtedy i tylko wtedy, gdy dane wejściowe to LM , gdzie L = 1 .


O Boże, nie widziałem, żeby to nadchodziło ... ( inb4 wszyscy przenoszą to na inne esolangi ... )
Pan Xcoder

Miałem na myśli odpowiedź 0-bajtową, ale eh, quine . : P
Erik the Outgolfer

Moja pierwsza myśl. Pobity przez 23 minuty :(
Khuldraeseth na'Barya

11

Haskell, 8 bajtów

(-8+).id

Wypróbuj online!

Podobnie jak wiele innych odpowiedzi, zwraca wartość 0 dla prawdy i wartość inną niż 0 dla fałszu poprzez wielokrotne odejmowanie długości kodu od liczby wejściowej.


Byłem tak blisko majsterkowania, żeby się do tego dostać ...
całkowicie ludzki

8

Siatkówka , 21 20 bajtów

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

_

Wypróbuj online! Wystarczy powtórzyć część w oknie Kod, aby zobaczyć, jak obsługuje wielokrotności.

Podaje 0poprawne wielokrotne i dodatnie liczby całkowite dla wszystkiego innego.

Wyjaśnienie

Najpierw spójrzmy na pojedynczy program:

\d+
*

Konwertuje liczbę dziesiętną na unarną (używając _jako cyfry unary).

^$
_

Jeśli ciąg znaków jest pusty (co nie może się zdarzyć w tym momencie, ponieważ wejście jest gwarantowane jako dodatnie), zastępujemy go pojedynczym _.

^_{20}

Teraz pozbywamy się pierwszych 20 znaków podkreślenia. Iff wejściowy był 20, to powoduje, że pusty ciąg.

_

Na koniec zliczamy liczbę znaków podkreślenia w wyniku, która wynosi zero, jeśli dane wejściowe były 20.


Co się stanie, gdy powtórzymy kod źródłowy. Ponieważ nie wstawiamy kanału przy dołączaniu do programów, pierwsza linia pójdzie w prawo na końcu ostatniej linii, otrzymamy to, gdy program podwoi się:

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

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

_

Teraz zamiast liczyć podkreślenia, kończymy na następującym etapie:

_\d+
*

Ten etap nic nie robi, ponieważ w tym momencie nie ma już cyfr w ciągu roboczym, więc wyrażenie regularne nie może się zgadzać.

^$
_

Teraz ten etap staje się istotny. Jeśli dane wejściowe były mniejsze od wielokrotności 20, ciąg został opróżniony przez poprzednią kopię kodu źródłowego. W takim przypadku zamieniamy go w pojedynczy znak podkreślenia, który, jak wiemy, nigdy nie może zostać zmieniony w pusty ciąg znaków przez nasz program. W ten sposób mamy pewność, że tylko w M th wielokrotność jest akceptowana (i nie wszystkie wielokrotności aż do M Th).

^_{20}

Po raz kolejny usuwamy pierwsze 20 znaków podkreślenia. Tak więc M powtórzeń kodu źródłowego usunie 20M podkreślników z łańcucha, jeśli to możliwe.

_

Kiedy dochodzimy do końca programu, nadal liczymy podkreślenia, aby prawidłowe dane wejściowe dawały zero.


6

x86 32-bitowy fragment kodu maszynowego, 1 bajt

48                      dec    eax

Dane wejściowe w EAX, dane wyjściowe w EAX: 0 dla wartości true, niezerowe dla wartości false. (Pozostawia również flagę ZF ustawioną na wartość true, a nie ustawioną na wartość false, abyś mógł je was_equal). Jako „bonus” nie musisz się martwić o opakowanie; 32-bitowy procesor x86 może adresować tylko 4GiB pamięci, więc nie możesz zrobić M wystarczająco dużego, aby owinąć go dookoła i znaleźć 1 == 2**32 + 1lub coś w tym rodzaju.

Aby włączyć funkcję wywoływaną, dołącz 0xC3 retinstrukcję po powtórzeniu 0x48M razy. (Nie liczony w łącznej liczbie, ponieważ wiele języków musi powtarzać tylko treść funkcji lub wyrażenie, aby móc konkurować).

Możliwe do wylogowania z GNU C za pomocą atrybutu funkcji x86 prototypu __attribute__((regparm(1))) int checkeqM(int eax); GNU Cregparm , na przykład -mregparm, używa EAX do przekazania pierwszej liczby całkowitej arg.

Na przykład ten kompletny program pobiera 2 argumenty, a kopie instrukcji JIT M + retbufor do bufora, a następnie wywołuje je jako funkcję. (Wymaga pliku wykonywalnego; kompiluj z 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
}

pliki wykonywalne inne niż PIE są ładowane niżej w pamięci wirtualnej; może zrobić większy ciągły 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         

Zauważ, że GNU C nie obsługuje obiektów o rozmiarach większych niż ptrdiff_t(32-bitową), ale malloci memsetzrobić jeszcze pracy, więc ten program się powiedzie.

Fragment kodu maszynowego ARM Thumb, 2 bajty

 3802            subs    r0, #2

Pierwszy argument arg r0i zwracana wartość r0to standardowa konwencja wywoływania ARM. To także ustawia flagi ( ssufiks). Śmieszny fakt; non FLAG ustalania wersja subjest 32-bitowe instrukcje szerokości.

Instrukcja zwrotu, którą musisz dołączyć, to bx lr.

Fragment kodu maszynowego AArch64, 4 bajty

d1001000        sub     x0, x0, #0x4

Działa dla 64-bitowych liczb całkowitych. Wejście / wyjście w x0, zgodnie ze standardową konwencją wywoływania. int64_t foo(uint64_t);

AArch64 nie ma (jeszcze) trybu kciuka, więc 1 instrukcja jest najlepsza, co możemy zrobić.


Uwaga dla każdego, kto się z tym spotka: połączenie z __builtin___clear_cachejest konieczne tylko dlatego, że wykonujesz pamięć, z której masz malloc. Jeśli mmapzamiast tego dostaniesz pamięć , optymalizacja nie nastąpi.
Joseph Sible-Reinstate Monica

4

V , 16 (lub 1) bajtów

Nudna odpowiedź:

<C-x>

jeden bajt.

Mniej nudna odpowiedź:

uÓ^$/0
16Ø^a$

Wypróbuj online!

Hexdump:

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

Napisałem to około 5 minut po tym, jak wyszło wyzwanie. Zajęło mi 30 minut, aby załatać ten okropny stos kodu spaghetti, który nazywam językiem .





2

Brain-Flak , 24 bajty

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

Wypróbuj online!

Zwraca 0za równe i coś innego za nie równe.

Jak to działa:

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

nCzasy działania tego kodu odejmą się n * 24od danych wejściowych, dając 0 tylko wtedy, gdy dane wejściowe = n*24.



2

TI-Basic (seria 83), 4 bajty

:Ans-4

Bierze dane wejściowe Ans: na przykład możesz wpisać, 17:prgmCODEGOLFaby uruchomić to z danymi wejściowymi 17. Wyświetla (i zwraca Ans) wartość, 0jeśli wartość wejściowa jest równa L × M , a wartość niezerowa w przeciwnym razie.

Zauważ, że :jest to część kodu, więc jeśli wpisujesz to w edytorze programów, powinieneś zobaczyć

PROGRAM:CODEGOLF
::Ans-4

jeśli wpiszesz go raz i

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

jeśli wpiszesz to trzy razy.



1

Befunge-98 , 15 bajtów

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

Wypróbuj online!

Spróbuj dwukrotnie!

Używa 0 dla równości i cokolwiek innego dla nierówności.

Wyjaśnienie:

Ten wielokrotnie powtarzany kod będzie wyglądał mniej więcej tak:

]#<@.-&+
>fv
v+]#<@.-&+
>fv
v+]#<@.-&+
>fv
 .
 .
 .
v+]#<@.-&+
>fv
v+
  1. ]skręt w prawo. Wysyła adres IP w dół.

  2. >przesuń się na wschód. Wysyła adres IP w prawo.

  3. f naciśnij 16.

  4. vidź na południe. Wysyła adres IP w dół. Jeśli jest to ostatni raz, przejdź do kroku 8.

  5. ]skręt w prawo. Wysyła adres IP w lewo.

  6. +Dodaj. Dodaje 16 do góry stosu.

  7. vidź na południe. Wysyła adres IP w dół. Idź do kroku 2.

  8. <idź na zachód. Wyślij adres IP w lewo.

  9. #pominąć. przeskocz nad ]i zawiń do końca.

  10. +Dodaj. Dodaje 16 do góry stosu.

  11. &Wejście. Naciśnij numer od użytkownika.

  12. -odejmować. uzyskać różnicę sumy, nad którą pracowaliśmy i dane wejściowe.

  13. .wydrukować. Wydrukuj wynik.

  14. @ koniec.



1

Węgiel drzewny , 13 bajtów

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

Wypróbuj online! Na podstawie mojej odpowiedzi, że podwoiłem źródło, podwoiłeś moc wyjściową! Wyjaśnienie:

         ⊞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

1Udaje się wyjść na prawdę i 0na fałsz. Kolejne powtórzenia porównać wejście na 13, 26, 39, 52itd., Ale za każdym razem odpowiedź jest nadrukowany tak tylko ostateczna odpowiedź jest postrzegana.


1

JavaScript ES6, 32 bajty

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

jeśli true, równe 0, a false - 31 bajtów

(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 bajty

Wykorzystuje $a0jako argument i zwraca wartość.

0x2084fffc    addi $a0, $a0, -4

MIPS, 8 bajtów (przy użyciu konwencji wywoływania MIPS)

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

x 86, 5 bajtów

To moja pierwsza odpowiedź na x86, więc proszę o opinie. Używa konwencji _fastcall z ecx jako pierwszym argumentem.

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

Peter Cordes ma jednobajtowe rozwiązanie w komentarzach.


Komentarz Brainfuck : Trudność polega na tym, żeby pieprzyć mózg, żeby zwrócił jedną wartość. W przeciwnym razie coś takiego byłoby łatwe.

- >,[-<->] < .

1
Twój fragment kodu x86 byłby tego samego rozmiaru dla liczb całkowitych 32-bitowych, nie musisz ograniczać do 8. Ale jeśli użyłeś niestandardowej konwencji wywoływania (arg w AL, retval gdzie indziej,), możesz użyć 2-bajtowej specjalnej wartości AL kodowanie sub $4, %al/ mov %al, %dl. Lub nadal wróć do AL / EAX, a następnie otrzymasz rozwiązanie Dennisa, z dec %eax(1 bajt w trybie 32-bitowym). I tak, niestandardowe konwencje wywoływania są odpowiednie dla asm. To asm, nie tylko „asm, do którego łatwo jest zadzwonić z C”; prawdziwy kod napisany w asm korzysta z niestandardowych konwencji wywoływania, gdy jest to pomocne, więc jest to całkowicie uzasadnione.
Peter Cordes,

1
Normalną konwencją wywoływania ARM jest pierwszy argument, w r0którym jest również retval, więc Thumb sub r0, #2ma 2 bajty.
Peter Cordes,

1
Zauważ, że żadna z tych funkcji nie jest funkcją : wymagają znaku retna końcu bloku powtarzania, zanim będziesz mógł je wywołać. Zwykle retdo moich odpowiedzi asm x86 dołączam liczbę bajtów. Ale myślę, że naginanie reguł tutaj tylko dla funkcji ciała ma sens, w przeciwnym razie wiele języków nie będzie w stanie konkurować.
Peter Cordes

1
(nvm, to nie pozostawia retval w% al). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecxJest 4 bajty, a następująca konwencję _fastcall. Korzystanie z krótkich kodowań AL, imm8 i xchg-with-eax jest często pomocne dla golfa kodowego.
Peter Cordes,

1
Zwykle używam, objdump -drwC -Mintelaby uzyskać zrzut heksowy bajtów kodu maszynowego. add r32, imm8ma również 3 bajty: opcode + ModR / M + imm8. Wszystkie instrukcje, które mogą przyjąć imm32, mają alternatywny kod operacji, który przyjmuje imm8 z rozszerzonym znakiem. Zobacz na przykład felixcloutier.com/x86/ADD.html ; wszystkie „klasyczne” instrukcje ALU (ale nie MOV) datowane na 8086 mają wszystkie te kodowania, w tym specjalne AL / AX / EAX bez modr / m, tylko op + imm8 / 16/32. Ta odpowiedź zawiera przykłady
Peter Cordes,

1

Oktawa: 23 bajty

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

Jeśli N = L * M, wyrażenie jest zwracane 0+i (tj. Liczbę wyłącznie urojoną), w przeciwnym razie wynikiem jest liczba zespolona z rzeczywistym składnikiem.

Aby uzyskać nieco lepszy wynik kosztem dodatkowego bajtu:

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

Jeśli N = L * M, wyrażenie zwraca -1, w przeciwnym razie liczba dodatnia.

Próbny:

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, możesz uzyskać ten sam wynik z +24;if N==ans;-1;end;ans ale liczba bajtów jest taka sama


1

Lua, 56 46 bajtów

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

Zwraca 0 (bez końcowego nowego wiersza), jeśli jest równe, albo albo nic, albo szereg liczb ujemnych (w niektórych przypadkach poprzedzających zero), jeśli nie jest równy.

Sam: Wypróbuj online!

Powtarzano kilka razy: Wypróbuj online!

Wyjaśnienie

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

Przy pierwszej iteracji (gdy anie została jeszcze zdefiniowana i dlatego jest nil), ustawia asię na liczbę pobraną z danych wejściowych, w przeciwnym razie do siebie. W obu przypadkach odejmuje się następnie 46 a.

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

To po prostu drukuje a jeśli jest mniejsze niż (aby zająć się przypadkami, w których dane wejściowe były większe niż całkowita długość) lub równe zero, a pusty łańcuch w przeciwnym razie.

-10 bajtów do zapamiętania, że ​​Lua automatycznie przekształca liczby i ciągi znaków. Ups


0

JavaScript (ES6), 47 bajtów

Używa tej samej techniki, co Benoit Esnard w tej odpowiedzi (od podwoić źródło, podwoisz wynik! ).

Wyświetla 0, jeśli n = 47 * M lub w przeciwnym razie wartość niezerową.

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

Demo dla M = 1

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

Demo dla M = 2

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


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.