Tekrarlayan bayt sayacı


19

Göreviniz boş olmayan bir program / bayt sayısı L fonksiyonu yazmaktır , bu da M kez tekrarlandığında belirli bir pozitif tamsayı N'nin L × M'ye eşit olup olmadığını kontrol eder .

Teorik olarak, rasgele sayıda tekrarlamayı ( M'nin rasgele pozitif tamsayı değeri ) desteklemelisiniz, ancak dil sınırlamaları nedeniyle belirli bir eşik üzerinde çalışamazsa iyi olur. Programınızın kaynak kodunu okumak veya programla ilgili bilgilere erişmek kesinlikle yasaktır .

Çıktı sağlamak için, durumlardan biri (doğruluk ya da yanlış) için tutarlı bir değer seçmeli ve diğer durum için başka herhangi bir olası (zorunlu olarak tutarlı değil) olası çıktı kullanmalısınız ( Tartışma ).

Yanıtlarınız ilk programınızın uzunluğu L (bayt cinsinden) ile puanlandırılacak ve daha az bayt daha iyi olacaktır.

Misal

Diyelim ki (başlangıç) programınız ABCDE. Sonra:

  • ABCDE(1 tekrar) girişin 5 olup olmadığını kontrol etmelidir .
  • ABCDEABCDE(2 tekrar) girişin 10 olup olmadığını kontrol etmelidir .
  • ABCDEABCDEABCDE(3 tekrar) girişin 15 olup olmadığını kontrol etmelidir . Vb...

İlk kaynak 5 bayt uzunluğunda olduğundan , bu örnek kodun puanı 5 olacaktır .


Sadece netleştirmek için: uzunluk kaynak kodunu Lkendisi sonra birleştirilmiş Mkatına girdi olmadığını dönmelidir NeşittirL*M ?

Yanıtlar:


12

Jöle , 1 bayt

Çıktı bir eşleşme için 0 , eşleşmeyen için sıfır değil.

Çevrimiçi deneyin!

Nasıl çalışır

Bu, aşırı liberal çıktı biçiminden yararlanır. Tekrarlanan M kez sadece giriş azaltır M sonuç sıfır olacak şekilde, kat halinde ve giriş yalnızca LM , burada L = 1 .


Oh tanrım bunun geldiğini görmedim ... ( inb4 herkes onu diğer esolangs'a bağlar ... )
Bay

Aklımda 0 baytlık bir cevap vardı, ama, kın . : P
Outgolfer Erik

Benim ilk düşümcem. 23 dakikaya kadar
dövüldü

11

Haskell, 8 bayt

(-8+).id

Çevrimiçi deneyin!

Diğer birçok cevap gibi, kodun uzunluğunu tekrar tekrar giriş numarasından çıkararak doğruluk için 0 ve yanlış için 0 olmayan döndürür.


Ben bu yüzden ... yakın Buna almak için müdahalesi için
totallyhuman

8

Retina , 21 20 bayt

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

_

Çevrimiçi deneyin! Katları nasıl işlediğini görmek için Kod penceresinde parçayı tekrarlamanız yeterlidir.

Diğer 0her şey için doğru çoklu ve pozitif tamsayılar verir .

açıklama

Önce tek bir programa bakalım:

\d+
*

Bu, ondalık bir sayıyı tek sayıya dönüştürür ( _tek sayı olarak kullanarak ).

^$
_

Dize boşsa (bu noktada gerçekleşemez, çünkü girişin pozitif olması garanti edilir), bunu tek bir ile değiştiririz _.

^_{20}

Şimdi ilk 20 alt çizgiden kurtuluyoruz. Girdi, 20boş bir dize ile sonuçlanır.

_

Ve son olarak, sonuçtaki alt çizgi sayısını sayıyoruz, bu da girdinin sıfır olması durumunda 20.


Şimdi kaynak kodunu tekrarladığımızda ne olur? Programlara katılırken satır besleme eklemediğimizden, ilk satır son satırın sonuna doğru gidecektir, bunu program iki katına çıkınca alırız:

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

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

_

Şimdi alt çizgileri saymak yerine aşağıdaki aşamaya geçiyoruz:

_\d+
*

Bu aşama hiçbir şey yapmaz, çünkü bu noktada çalışma dizesinde daha fazla basamak yoktur, bu nedenle normal ifade eşleşemez.

^$
_

Şimdi bu aşama alakalı hale geliyor. Giriş 20'den küçük bir katsayıysa, dize kaynak kodun önceki kopyası tarafından boşaltılmıştır. Bu durumda, programımız tarafından bir daha asla boş bir dizgeye dönüştürülemeyeceğini bildiğimiz tek bir alt çizgiye dönüştürüyoruz. Bu şekilde biz sağlamak sadece M inci çoklu (kadar ve tüm katları kabul edilmektedir M th).

^_{20}

İlk 20 alt çizgiyi bir kez daha kaldırıyoruz. Bu nedenle , kaynak kodun M tekrarları , mümkünse dizeden 20M alt çizgiyi kaldıracaktır .

_

Ve programın sonuna geldiğimizde, geçerli girdilerin sıfır vermesi için alt çizgileri hala sayıyoruz.


6

x86 32 bit makine kodu parçası, 1 bayt

48                      dec    eax

EAX girişi, EAX çıkışı: true için 0, false için sıfır olmayan. (Ayrıca, ZF bayrağını true için ayarlanmış, false için ayarlanmamış bırakır, böylece yapabilirsiniz je was_equal). Bir "bonus" olarak, sarma konusunda endişelenmenize gerek yok; 32-bit x86 yalnızca 4GiB belleğe hitap edebilir, bu nedenle M'yi etrafı saran ve bir 1 == 2**32 + 1şey bulabilecek kadar büyük yapamazsınız .

Çağrılabilir bir işlev yapmak için M 0xC3 retkezini tekrarladıktan sonra bir talimat ekleyin 0x48. (Toplam sayıya dahil edilmez, çünkü birçok dilin rekabet edebilmek için sadece işlev gövdesini veya bir ifadeyi tekrarlaması gerekir).

Prototip ile GNU C Calleable __attribute__((regparm(1))) int checkeqM(int eax); GNU C'nin regparmx86 fonksiyonu özniteliği gibi -mregparm, ilk tamsayı arg geçmek EAX kullanır.

Örneğin, bu tam program 2 argüman alır ve JIT komutunun + a kopyasını retbir arabelleğe alır ve bir işlev olarak çağırır. (Yürütülebilir yığın gerektirir; ile derleyin 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 olmayan yürütülebilir dosyalar sanal belleğe daha az yüklenir; daha büyük bitişik bir malloc yapabilir.

$ 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         

O Not GNU C desteklemediği nesneyi daha büyük boyutları ptrdiff_t(32-bit imzalı), ancak mallocve memsetbu program başarılı yüzden, hala ne iş.

ARM Thumb makine kodu parçası, 2 bayt

 3802            subs    r0, #2

İlk arg r0ve dönüş değeri r0standart ARM çağırma kuralıdır. Bu aynı zamanda bayrakları ( ssonek) ayarlar . Eğlenceli gerçek; olmayan bir -flag belirleyici sürümü sub32 bit genişliğinde talimatıdır.

Eklemeniz gereken iade talimatı bx lr.

AArch64 makine kodu parçası, 4 bayt

d1001000        sub     x0, x0, #0x4

64 bit tamsayılar için çalışır. x0Standart çağrı kuralına göre giriş / çıkış girişi . int64_t foo(uint64_t);

AArch64'te henüz bir Başparmak modu yok, bu yüzden 1 komut yapabileceğimiz en iyisidir.


Buna rastlayan herkes için not: çağrı __builtin___clear_cachesadece gerekli olan hafızayı yürüttüğünüz için gereklidir malloc. Belleği mmapbunun yerine aldıysanız , optimizasyon gerçekleşmez.
Joseph Sible-Reinstate Monica

4

V , 16 (veya 1) bayt

Sıkıcı cevap:

<C-x>

bir bayt.

Daha az sıkıcı cevap:

uÓ^$/0
16Ø^a$

Çevrimiçi deneyin!

HexDump:

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

Aslında bunu meydan okumadan yaklaşık 5 dakika sonra yazdım. Bir dil dediğim bu korkunç spagetti kod yığınını düzeltmem 30 dakika sürdü .





2

Brain-Flak , 24 bayt

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

Çevrimiçi deneyin!

0Eşittir ve eşit olmayan bir şey döndürür .

Nasıl çalışır:

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

Bu kod çalışma nsüreleri n * 24girdiden çıkarılır ve yalnızca input = olduğunda 0 verilir n*24.



2

TI-Basic (83 serisi), 4 bayt

:Ans-4

Girdiyi alır Ans: örneğin, bunu 17:prgmCODEGOLFbir girdiyle çalıştırmak için yazabilirsiniz 17. Giriş L × M'ye eşitse Ansdeğeri yazdırır (ve döndürür )0 değeri, aksi halde sıfırdan farklı bir değer .

:Kodun bir parçası olduğunu unutmayın , bu yüzden bunu program düzenleyicisine giriyorsanız,

PROGRAM:CODEGOLF
::Ans-4

bir kez girerseniz ve

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

üç kez girerseniz.



1

Befunge-98 , 15 bayt

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

Çevrimiçi deneyin!

Deneyin iki katına çıktı!

Eşit için 0, eşit olmayan için başka bir şey kullanır.

Açıklama:

Birçok kez tekrarlanan bu kod şöyle görünecektir:

]#<@.-&+
>fv
v+]#<@.-&+
>fv
v+]#<@.-&+
>fv
 .
 .
 .
v+]#<@.-&+
>fv
v+
  1. ]sağa dönüş. IP'yi gönderir.

  2. >doğuya hareket et. IP hakkını gönderir.

  3. f 16'yı itin.

  4. vgüneye taşın. IP'yi gönderir. Bu son kez ise, 8. adıma geçin.

  5. ]sağa dönüş. IP'yi sola gönderir.

  6. +Ekle. 16'yı yığının üstüne ekler.

  7. vgüneye taşın. IP'yi gönderir. 2. adıma geçin.

  8. <batıya doğru hareket et. IP'yi sola gönderin.

  9. #atlayın. üzerinden atlamak ]ve sonuna kadar sarın.

  10. +Ekle. 16'yı yığının üstüne ekler.

  11. &giriş. Kullanıcıdan bir sayı itin.

  12. -çıkarma. üzerinde çalıştığımız toplam ve girdi arasındaki farkı elde edebilir.

  13. .Yazdır. Sonucu yazdırın.

  14. @ son.



1

Kömür , 13 bayt

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

Çevrimiçi deneyin! Kaynağı iki katına çıkardığım cevaba dayanarak , çıktıyı iki katına çıkarıyorsunuz! Açıklama:

         ⊞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

1Doğruluk ve sahtelik için çıktı almayı 0başarır. Daha sonraki tekrarlar karşı girişini karşılaştırmak 13, 26, 39, 52vb ama cevap basılması ve her seferinde bu yüzden sadece son cevabın görülmektedir.


1

JavaScript ES6, 32 Bayt

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

doğruysa 0, diğerleri gibi yanlış, 31 bayt

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

Bağımsız $a0değişken ve dönüş değeri olarak kullanır .

0x2084fffc    addi $a0, $a0, -4

MIPS, 8 bayt (MIPS çağrı kuralını kullanarak)

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

x86, 5 bayt

Bu benim ilk x86 cevap bu yüzden geribildirim hoş geldiniz. Ecx ile _fastcall kuralını ilk argüman olarak kullanır.

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

Peter Cordes'in yorumlarında 1 baytlık bir çözüm var.


Brainfuck yorumu : Zor olan kısım, tek bir değer döndürmek için beyin sikini almaktır. Aksi takdirde böyle bir şey kolay olurdu.

- >,[-<->] < .

1
X86 kod parçanız, 32 bit tamsayılar için aynı boyutta olacaktır, 8 ile sınırlandırmanıza gerek yoktur. Ancak özel bir çağrı kuralı (AL'de arg, başka bir yerde retval) kullandıysanız, 2 baytlık AL özel özelliğini kullanabilirsiniz. kodlayan sub $4, %al/ mov %al, %dl. Ya da yine AL / EAX'a dönün ve sonra Dennis'in çözümünü elde edin dec %eax(32 bit modunda 1 bayt). Ve evet, özel çağrı kuralları asm için iyidir. Bu sadece "C'den kolay çağrı yapan asm" değil; asm'de yazılmış gerçek kod, yardımcı olduğu özel çağrı kurallarını kullanır, bu yüzden bu tamamen haklıdır.
Peter Cordes

1
ARM'nin normal çağrı kuralı, r0aynı zamanda retval olan ilk argümandır, bu yüzden Thumb sub r0, #22 bayttır.
Peter Cordes

1
Bunların hiçbirinin işlev olmadığını unutmayın : retyineleme bloğunun sonunda onları çağırmadan önce a gerekir. Normalde retx86 asm cevaplarım için bayt sayılarını eklerim. Ama bence buradaki kuralları sadece işlev gövdesine bükmek mantıklı, aksi takdirde pek çok dil rekabet edemez.
Peter Cordes

1
(nvm,% al cinsinden retva bırakmaz). xchg %eax, %ecx/ sub $4, %al/ xchg %eax, %ecx4 bayttır ve _fastcall kuralını izler. AL, imm8 ve xchg-with-eax kısa kodlamaları kullanmak, kod golfü için genellikle yararlıdır.
Peter Cordes

1
Genellikle objdump -drwC -Mintelmakine kodu baytlarının onaltılık dökümünü almak için kullanılır . add r32, imm8ayrıca 3 bayttır: opcode + ModR / M + imm8. Bir imm32 alabilen tüm talimatlar, işaret uzatılmış bir imm8 alan alternatif bir opcode'a sahiptir. Örneğin felixcloutier.com/x86/ADD.html adresine bakın ; 8086'ya kadar giden tüm "klasik" ALU talimatları (ancak MOV değil), modr / m içermeyen özel AL / AX / EAX olanlar da dahil olmak üzere tüm kodlamalara sahiptir, sadece op + imm8 / 16/32. Bu cevabın örnekleri var
Peter Cordes

1

Oktav: 23 bayt

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

N = L * M ise, ifade 0+i(yani tamamen hayali bir sayı) döndürür , aksi takdirde ifade, gerçek bir bileşene sahip karmaşık bir sayı ile sonuçlanır.

Ekstra bayt pahasına biraz daha hoş bir sonuç için:

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

N = L * M ise ifade geri döner -1, aksi takdirde pozitif bir sayı olur.

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, aynı sonucu alabilirsiniz +24;if N==ans;-1;end;ansama bytecount aynı


1

Lua, 56 46 bayt

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

Eşitse 0 (izleyen satırsonu olmadan) ve eşit değilse hiçbir şey veya bir dizi negatif sayı (bazı durumlarda önceki sıfır ile) verir.

Yalnız: Çevrimiçi deneyin!

Birkaç kez tekrarlayın: Çevrimiçi deneyin!

açıklama

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

İlk yinelemede ( ahenüz tanımlanmadığı ve dolayısıyla tanımlandığı zaman nil), agirdiden alınan bir sayıya, aksi takdirde kendisine ayarlanır . Her iki durumda da, 46 çıkarılır a.

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

Bu, yalnızca a(girişin toplam uzunluktan büyük olduğu durumlara dikkat etmek için) veya sıfıra eşitse ve boş dize ise yazdırılır .

Lua'nın sayılar ve dizeler arasında otomatik olarak dönüşüm yaptığını hatırlamak için -10 bayt . Whoops.


0

JavaScript (ES6), 47 bayt

Bu aynı teknik kullanılarak olduğu Benoit Esnard içinde bu cevap den ( Kaynağını çift, çıktısını katına! ).

N = 47 * M ise 0 veya aksi halde sıfırdan farklı bir değer yazdırır .

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

M = 1 için demo

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

M = 2 için demo

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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.