Penghitung byte berulang

19

Tugas Anda adalah untuk menulis sebuah program non-kosong / fungsi count byte L , yang, ketika diulang M kali, cek apakah positif yang diberikan bilangan bulat N adalah sama dengan L × M .

Anda harus, secara teori, mendukung jumlah pengulangan yang sewenang-wenang (nilai bilangan bulat positif sewenang-wenang dari M ), tetapi tidak apa-apa jika, karena keterbatasan bahasa, ia tidak dapat bekerja pada ambang batas tertentu. Membaca kode sumber program Anda atau mengakses informasi tentang hal itu dilarang keras .

Untuk memberikan output, Anda harus memilih nilai yang konsisten untuk salah satu negara (baik jujur ​​atau salah) dan menggunakan yang lain (tidak harus konsisten) kemungkinan hasil untuk negara lain ( Diskusi ).

Jawaban Anda akan dinilai berdasarkan panjang program awal Anda L (dalam byte), dengan lebih sedikit byte yang lebih baik.

Contoh

Katakanlah program (awal) Anda ABCDE. Kemudian:

  • ABCDE(1 pengulangan) harus memeriksa apakah input sama dengan 5 .
  • ABCDEABCDE(2 pengulangan) harus memeriksa apakah input sama dengan 10 .
  • ABCDEABCDEABCDE(3 pengulangan) harus memeriksa apakah input sama dengan 15 . Dll ...

Skor kode sampel ini adalah 5 , karena sumber awal adalah 5 byte.

Tuan Xcoder
sumber
Hanya untuk mengklarifikasi: kode sumber panjang Lsetelah Mwaktu itu sendiri harus kembali apakah inputnya Nsama denganL*M ?

Jawaban:

12

Jelly , 1 byte

Output adalah 0 untuk pertandingan, bukan nol untuk pertandingan.

Cobalah online!

Bagaimana itu bekerja

Ini memanfaatkan format output yang terlalu liberal. Pengulangan M kali hanya mengurangi input M kali, sehingga hasilnya akan nol jika dan hanya jika inputnya adalah LM , di mana L = 1 .

Dennis
sumber
Ya Tuhan, aku tidak melihat kedatangan ini ... ( inb4 semua orang port itu ke esolangs lain ... )
Mr Xcoder
Saya memang memiliki jawaban 0 byte dalam pikiran, tetapi, eh, quine . : P
Erik the Outgolfer
Pikiran pertamaku. Dipukul 23 menit :(
Khuldraeseth na'Barya
11

Haskell, 8 byte

(-8+).id

Cobalah online!

Seperti banyak jawaban lain, ia mengembalikan 0 untuk benar dan non-0 untuk falsy dengan berulang kali mengurangi panjang kode dari nomor input.

nimi
sumber
Aku begitu dekat dengan bermain-main dengan mendapatkan untuk ini ...
totallyhuman
8

Retina , 21 20 byte

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

_

Cobalah online! Cukup ulangi bagian di jendela Kode untuk melihat bagaimana menangani kelipatan.

Memberikan 0bilangan bulat multipel dan positif yang benar untuk yang lainnya.

Penjelasan

Mari kita lihat satu-satunya program:

\d+
*

Ini mengubah angka desimal menjadi unary (menggunakan _sebagai digit unary).

^$
_

Jika string kosong (yang tidak dapat terjadi pada titik ini, karena input dijamin positif), kami menggantinya dengan satu _.

^_{20}

Sekarang kita menyingkirkan 20 garis bawah pertama. Jika inputnya adalah 20, ini menghasilkan string kosong.

_

Dan akhirnya kami menghitung jumlah garis bawah pada hasilnya, yaitu nol jika inputnya 20.


Sekarang apa yang terjadi ketika kita mengulangi kode sumber. Karena kita tidak memasukkan umpan baris ketika bergabung dengan program, baris pertama akan langsung di akhir baris terakhir, kita mendapatkan ini ketika menggandakan program:

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

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

_

Sekarang alih-alih menghitung garis bawah, kita berakhir dengan tahap berikut:

_\d+
*

Tahap ini tidak melakukan apa-apa, karena tidak ada lagi digit dalam string yang bekerja pada titik ini, sehingga regex tidak dapat cocok.

^$
_

Sekarang tahap ini menjadi relevan. Jika inputnya adalah kelipatan 20, string telah dikosongkan oleh salinan kode sumber sebelumnya. Dalam hal ini, kami mengubahnya menjadi garis bawah tunggal, yang kami tahu tidak akan pernah bisa diubah menjadi string kosong lagi oleh program kami. Dengan cara ini kita memastikan bahwa hanya para M beberapa th diterima (dan tidak semua kelipatan hingga M th).

^_{20}

Kami menghapus 20 garis bawah pertama sekali lagi. Jadi, pengulangan M dari kode sumber akan menghapus 20M garis bawah dari string, jika memungkinkan.

_

Dan ketika kita sampai pada akhir program, kita masih menghitung garis bawah sehingga input yang valid memberikan nol.

Martin Ender
sumber
6

x86 fragmen kode mesin 32-bit, 1 byte

48                      dec    eax

Input dalam EAX, output dalam EAX: 0 untuk true, non-nol untuk false. (Juga membiarkan flag ZF disetel ke true, tidak disetel untuk false, jadi Anda bisa je was_equal). Sebagai "bonus", Anda tidak perlu khawatir tentang pembungkus; 32-bit x86 hanya dapat mengatasi memori 4GiB, jadi Anda tidak dapat membuat M cukup besar untuk membungkus semua jalan dan menemukan 1 == 2**32 + 1atau sesuatu.

Untuk membuat fungsi yang dapat dipanggil, tambahkan 0xC3 retinstruksi setelah mengulangi 0x48M kali. (Tidak dihitung dalam jumlah total, karena banyak bahasa hanya perlu mengulangi fungsi tubuh, atau ekspresi, untuk dapat bersaing).

Calleable dari GNU C dengan atribut fungsi atribut x86 __attribute__((regparm(1))) int checkeqM(int eax); GNU Cregparm , seperti -mregparm, menggunakan EAX untuk melewati integer arg pertama.

Sebagai contoh, program lengkap ini mengambil 2 args, dan JITs M menyalin instruksi + a retke dalam buffer, dan kemudian menyebutnya sebagai fungsi. (Membutuhkan tumpukan yang dapat dieksekusi; kompilasi dengan 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
}

executable non-PIE dimuat lebih rendah dalam memori virtual; dapat melakukan malloc berdekatan yang lebih besar.

$ 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         

Perhatikan bahwa GNU C tidak mendukung objek ukuran lebih besar dari ptrdiff_t(ditandatangani 32-bit), tapi mallocdan memsetmelakukan masih bekerja, sehingga program ini berhasil.

ARM jempol kode mesin, 2 byte

 3802            subs    r0, #2

Arg pertama r0dan nilai kembali r0adalah konvensi panggilan ARM standar. Ini juga menetapkan bendera ( sakhiran). Fakta menyenangkan; versi non -flag-setting subadalah instruksi lebar 32-bit.

Instruksi pengembalian yang perlu Anda tambahkan adalah bx lr.

Fragmen kode mesin AArch64, 4 byte

d1001000        sub     x0, x0, #0x4

Bekerja untuk bilangan bulat 64-bit. Input / output dalam x0, sesuai dengan konvensi panggilan standar. int64_t foo(uint64_t);

AArch64 tidak memiliki mode Jempol (belum), jadi 1 instruksi adalah yang terbaik yang bisa kita lakukan.

Peter Cordes
sumber
Catatan untuk siapa pun yang menemukan ini: panggilan ke __builtin___clear_cachehanya diperlukan karena Anda menjalankan memori yang Anda dapatkan malloc. Jika Anda mendapatkan memori dari mmapsebaliknya, optimasi tidak terjadi.
Joseph Sible-Reinstate Monica
4

V , 16 (atau 1) byte

Jawaban membosankan:

<C-x>

satu byte.

Jawaban yang kurang membosankan:

uÓ^$/0
16Ø^a$

Cobalah online!

Hexdump:

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

Saya benar-benar menulis ini sekitar 5 menit setelah tantangan keluar. Butuh waktu 30 menit untuk menambal tumpukan kode spageti yang mengerikan ini yang saya sebut bahasa .

DJMcMayhem
sumber
3

Perl 5 -p , 6 byte

$_-=6;

Cobalah online!

gunakan 0untuk sama

Ton Hospel
sumber
1
Juga -psolusi Perl 6 yang valid .
nwellnhof
3

Python 3 , 27 byte

int=lambda x,i=int:i(x)-27;

Cobalah online!

Kode diulang dua kali:

int=lambda x,i=int:i(x)-27;int=lambda x,i=int:i(x)-27;

Cobalah online!

Luca Citi
sumber
2

Brain-Flak , 24 byte

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

Cobalah online!

Kembali 0 untuk yang sama dan yang lainnya tidak sama.

Bagaimana itu bekerja:

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

Kali ini kode dijalankan nakan mengurangi n * 24dari input, memberikan 0 hanya ketika input = n*24.

MegaTom
sumber
2

TI-Basic (83 series), 4 byte

:Ans-4

Membawa input Ans: misalnya, Anda dapat mengetik 17:prgmCODEGOLFuntuk menjalankan ini dengan input 17. Mencetak (dan mengembalikan Ans) nilai 0jika input sama dengan L × M , dan nilai bukan nol sebaliknya.

Perhatikan bahwa :ini adalah bagian dari kode, jadi jika Anda memasukkan ini ke dalam editor program, Anda akan melihat

PROGRAM:CODEGOLF
::Ans-4

jika Anda memasukkannya sekali dan

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

jika Anda memasukkannya tiga kali.

Misha Lavrov
sumber
1

Haskell , 12 byte

(-)$0
 +12--

Cobalah online!

Keluaran 0 untuk truey dan beberapa integer non-nol untuk falsy.

Solusi alternatif, 12 byte

id
 .(-)12--

Cobalah online!

benar-benar manusiawi
sumber
1

Befunge-98 , 15 byte

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

Cobalah online!

Coba dua kali lipat!

Menggunakan 0 untuk sama dan apa pun untuk tidak setara.

Penjelasan:

Kode ini berulang kali akan terlihat seperti ini:

]#<@.-&+
>fv
v+]#<@.-&+
>fv
v+]#<@.-&+
>fv
 .
 .
 .
v+]#<@.-&+
>fv
v+
  1. ]belok kanan. Mengirim IP ke bawah.

  2. >bergerak ke timur. Mengirimkan IP dengan benar.

  3. f tekan tombol 16.

  4. vpindah ke selatan. Mengirim IP ke bawah. Jika ini yang terakhir, lakukan langkah 8.

  5. ]belok kanan. Kirim IP yang tersisa.

  6. +Menambahkan. Tambahkan 16 ke atas tumpukan.

  7. vpindah ke selatan. Mengirim IP ke bawah. Goto langkah 2.

  8. <bergerak ke barat. Kirim IP kiri.

  9. #melewatkan. melompati ]dan membungkus sampai akhir.

  10. +Menambahkan. Tambahkan 16 ke atas tumpukan.

  11. &memasukkan. Dorong nomor dari pengguna.

  12. -mengurangi. dapatkan perbedaan jumlah yang sedang kita kerjakan dan inputnya.

  13. .mencetak. Cetak hasilnya.

  14. @ akhir.

MegaTom
sumber
1

Arang , 13 byte

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

Cobalah online! Berdasarkan jawaban saya untuk saya gandakan sumbernya, Anda gandakan hasilnya! Penjelasan:

         ⊞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

Mengatur keluaran 1untuk kebenaran dan 0kepalsuan. Pengulangan berikutnya membandingkan masukan terhadap 13, 26, 39, 52dll tapi setiap kali jawabannya adalah overprinted sehingga hanya jawaban akhir terlihat.

Neil
sumber
1

JavaScript ES6, 32 Bytes

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

jika benar 0 dan salah seperti yang lain, 31 byte

(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)
]);

l4m2
sumber
1

MIPS, 4 byte

Digunakan $a0sebagai argumen dan mengembalikan nilai.

0x2084fffc    addi $a0, $a0, -4

MIPS, 8 byte (menggunakan konvensi panggilan MIPS)

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

x86, 5 byte

Ini adalah jawaban x86 pertama saya, jadi kami menerima umpan balik. Gunakan _fastcall convention dengan ecx sebagai argumen pertama.

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

Peter Cordes memiliki solusi 1 byte di komentar.


Komentar Brainfuck : Bagian yang sulit adalah mendapatkan brainfuck untuk mengembalikan nilai tunggal. Kalau tidak, sesuatu seperti ini akan mudah.

- >,[-<->] < .
qwr
sumber
1
Fragmen kode x86 Anda akan memiliki ukuran yang sama untuk bilangan bulat 32-bit, tidak perlu dibatasi hingga 8. Namun jika Anda menggunakan konvensi pemanggilan kustom (arg di AL, retval di tempat lain,), Anda dapat menggunakan AL khusus 2-byte penyandian sub $4, %al/ mov %al, %dl. Atau masih kembali dalam AL / EAX dan kemudian Anda mendapatkan solusi Dennis, dengan dec %eax(1 byte dalam mode 32-bit). Dan ya, konvensi panggilan kustom tidak masalah untuk ASM Asm, bukan hanya "asm yang mudah dipanggil dari C"; kode asli yang ditulis dalam asm memang menggunakan konvensi pemanggilan kustom di mana ia membantu, jadi ini benar-benar dapat dibenarkan.
Peter Cordes
1
Konvensi panggilan normal ARM adalah arg pertama r0yang juga merupakan retval, jadi Thumb sub r0, #2adalah 2 byte.
Peter Cordes
1
Perhatikan bahwa tidak satu pun dari ini adalah fungsi : mereka memerlukan retdi akhir blok ulang sebelum Anda bisa memanggil mereka. Biasanya saya memasukkan jumlah retdalam byte untuk jawaban x86 asm saya. Tapi saya pikir membengkokkan aturan di sini hanya untuk fungsi tubuh masuk akal, kalau tidak banyak bahasa tidak bisa bersaing sama sekali.
Peter Cordes
1
(nvm, ini tidak meninggalkan retval di% al). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecxadalah 4 byte, dan mengikuti konvensi _fastcall. Menggunakan penyandian pendek AL, imm8 dan xchg-dengan-eax sering bermanfaat untuk kode golf.
Peter Cordes
1
Saya biasanya menggunakan objdump -drwC -Minteluntuk mendapatkan hexdump dari byte kode mesin. add r32, imm8juga 3 byte: opcode + ModR / M + imm8. Semua instruksi yang dapat menggunakan imm32 memiliki opcode alternatif yang membutuhkan imm8 yang diperpanjang. Lihat felixcloutier.com/x86/ADD.html misalnya; semua instruksi ALU "klasik" (tetapi bukan MOV) yang berasal dari 8086 memiliki semua penyandian, termasuk yang AL / AX / EAX khusus tanpa modr / m, cukup op + imm8 / 16/32. Jawaban ini memiliki contoh
Peter Cordes
1

Oktaf: 23 byte

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

Jika N = L * M, ekspresi kembali 0+i(yaitu bilangan imajiner murni), jika tidak, ekspresi menghasilkan bilangan kompleks dengan komponen nyata.

Untuk hasil yang sedikit lebih bagus dengan biaya byte tambahan:

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

Jika N = L * M ekspresi kembali -1 , sebaliknya angka positif.

Demo:

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, Anda bisa mendapatkan hasil yang sama dengan +24;if N==ans;-1;end;anstetapi bytecount sama

Tasos Papastylianou
sumber
1

Lua, 56 46 byte

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

Menghasilkan 0 (tanpa baris tambahan) jika sama dan tidak ada atau serangkaian angka negatif (dengan nol sebelumnya dalam beberapa kasus) jika tidak sama.

Sendiri: Cobalah online!

Berulang kali beberapa kali: Cobalah online!

Penjelasan

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

Pada iterasi pertama (ketika abelum didefinisikan dan karena itunil ), setel ake nomor yang diambil dari input, jika tidak dengan sendirinya. Dalam kedua kasus, 46 kemudian dikurangi dari a.

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

Ini hanya mencetak ajika kurang dari (untuk menangani kasus di mana input lebih besar dari total panjang) atau sama dengan nol, dan string kosong sebaliknya.

-10 byte untuk mengingat bahwa Lua melakukan konversi antara angka dan string secara otomatis. Aduh.

ivzem
sumber
0

JavaScript (ES6), 47 byte

Ini menggunakan teknik yang sama dengan Benoit Esnard dalam jawaban ini (dari saya gandakan sumbernya, Anda gandakan hasilnya! ).

Mencetak 0 jika n = 47 * M , atau nilai bukan nol sebaliknya.

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

Demo untuk M = 1

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

Demo untuk M = 2

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

Arnauld
sumber
0

Brain-Flak , 24 byte

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

Cobalah online!

Cukup kurangi 24 dari input. Output 0untuk true dan lainnya untuk false.

Brain-Flak , 68 byte

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

Cobalah online!

Yang ini lebih canggih itu output 1untuk benar dan 0salah.

Wisaya Gandum
sumber