Metin Fizz Buzz


29

Giriş

Ben yok özellikle bızz vızıltı eğilim nereden geldiğini biliyoruz. Sadece bir meme veya bir şey olabilir, ama biraz popüler.

Meydan okuma

Bugün sizin işiniz Fizz Buzz'ı sırasıyla ikili (0, 1) dosyaya dönüştürmek ve bu ikili dosyayı metne dönüştürmektir. Oldukça standart şeyler.

Bu nasıl çalışıyor?

FizzBuzzBuzzFizzBuzzFizzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz 01101000 01101001’ye çevrilecekti, sonra bu "hi" diline çevirecekti.

Kısıtlamalar

  • Giriş, ikili açıdan Fizz Buzz'dır (aşağıdaki örneklere bakın).
  • Çıktı metin olmalı.
  • FizzBuzz girişinin doğru olduğunu varsayabilirsiniz.
  • Bu , en kısa bayt kazanır.

Giriş

FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz

Çıktı

"Merhaba!"


15
Meme? Bu bir birincil (ilkokul) okul oyunudur
Beta Decay

2
Girdide boşluk bırakamaz mıyız?
HyperNeutrino

2
Yine de bu boşluğu alamaz mıyız? Bu boşluğu girmek zorunda kalmazsam üç byte tasarruf edebilirim.
HyperNeutrino

10
FizzBuzz, Stack Exchange'de çok fazla para birimine sahip çünkü kısmen Joel'in (kuruculardan biri), program başvuruları için giriş problemi için düşük bir engel olarak kullanmaktan bahseden başka bir bloga gönderme yapan bir blog yazısı vardı .
dmckee

8
@dmckee, Joel'in referans aldığı "başka bir blog" yu Stackoverflow'un diğer kurucusu Jeff Atwood'un.
pilsetnieks,

Yanıtlar:


55

C, 59 bayt

i;f(char*s){while(*s&3?*s&9||(i+=i+*s%5):putchar(i),*s++);}

Sihirli sayılar, her yerde sihirli sayılar!

(Ayrıca, C, Python, JS, PHP ve Ruby'den daha kısa? Duyulmamış!)

Bu, dizgeyi girdi olarak alan ve STDOUT işlevine çıkan bir işlevdir.

Bakış

Temel yapı:

i;           // initialize an integer i to 0
f(char*s){
while(...);  // run the stuff inside until it becomes 0
}

Burada, "içerdeki eşyalar", ardından ,*s++virgül işleyicisinin yalnızca ikinci argümanının değerini döndürdüğü bir demet koddur . Bu nedenle, bu dizge boyunca çalışacak ve çıkmadan önce *sson NUL baytı dahil (her postfix ++önceki değeri döndürdüğü için) her karaktere ayarlanacaktır .

Diğerlerine bir bakalım:

*s&3?*s&9||(i+=i+*s%5):putchar(i)

Üçlü ve kısa devre devre dışı bırakarak ||, bu genişletilebilir

if (*s & 3) {
    if (!(*s & 9)) {
        i += i + *s % 5;
    }
} else {
    putchar(i);
}

Bu sihirli sayılar nereden geliyor? İşte dahil olan tüm karakterlerin ikili gösterimleri:

F  70  01000110
B  66  01000010
i  105 01101001
z  122 01111010
u  117 01110101
   32  00100000
\0 0   00000000

Öncelikle, boşluğu ve NUL'yi karakterlerin geri kalanından ayırmamız gerekiyor. Bu algoritmanın çalışma şekli, "geçerli" sayının bir akümülatörünü tutar ve dizginin bir boşluğuna veya sonuna ulaştığında yazdırır '\0'. Bunu fark ederek ' 've '\0'ayarlanan en az iki önemli bitin hiçbirine sahip olmayan tek karakterlerdir 0b11, karakter boşluk veya NUL ise ve sıfır değilse sıfır karakterini sıfıra getirebiliriz .

Daha derine inerek, ilk "if" dalında, şimdi onlardan biri olan bir karaktere sahibiz FBizu. Sadece akümülatörü Fs ve Bs'de güncellemeyi seçtim , bu yüzden s'yi filtrelemek için bir yola ihtiyacım vardı izu. Uygun şekilde Fve Bher ikisi de yalnızca ikinci, üçüncü veya yedinci en az önemli bit ayarlarına sahiptir ve diğer tüm sayılar en az bir başka bit setine sahiptir. Aslında, hepsinde ilk veya dördüncü en az anlamlı bit bulunur. Bu yüzden, bitsel AND ile 0b00001001, 9 olan, 0 için elde olan Fve Bve sıfır olmayan, aksi takdirde.

Biz bir olduğunu belirledikten sonra Fya B, onları eşleme yapabilirsiniz 0ve 1çünkü onların modülüne 5 alarak sırasıyla Folduğunu 70ve Bbir 66. Sonra pasajı

i += i + *s % 5;

sadece demenin bir golf yolu

i = (i * 2) + (*s % 5);

olarak da ifade edilebilir

i = (i << 1) | (*s % 5);

bu yeni biti en az önemli pozisyona yerleştirir ve her şeyi 1'in üzerine kaydırır.

"Fakat bekle!" protesto edebilirsin. “Yazdırdıktan sonra ne izaman tekrar 0'a sıfırlanır?” Eh, putcharonun argümanını unsigned char8 bit büyüklüğünde olan bir argümanına atar . Bu, 8. en az anlamlı bitin (yani önceki yinelemelerin önemsiz) geçmişindeki her şeyin atıldığı ve bunun için endişelenmemize gerek olmadığı anlamına gelir.

Sayesinde @ETHproductions yerine öneren 57ile 9, bir byte tasarruf!


Putchar ile güzel bir numara.
Computronium

Bu reeeeeally harika. C doğru yaptı!
Gustavo Maciel

13
İşleri doğru yapmaktan bahsetmişken, bu, mütevazi olmayan görüşüme göre, bir kod golf yanıtının nasıl yapılması gerektiğidir. İnsanlara, dil hakkında başka, daha pratik durumlarda yararlı olabilecek bir şey öğreten eksiksiz ve iyi yazılmış bir açıklama eşliğinde akıllıca, anlayışlı bir çözüm yayınlıyorsunuz.
Cody Gray

3
@CodyGray Aynen bu. Code Golf’un SE’imin tepesinde olmamasının sebeplerinden biri de sıkça ziyaret ettiğim bir çok cevabın sadece “burada kod” olması. Dilleri çok iyi bilenler için çok havalı olsa da, sadece bana ses geliyor. Buradaki açıklamaları görmeyi seviyorum, çünkü çoğu insanın kodun kendisinden çok daha ilginç bulacağını düşündüğüm yöntemi ortaya koyuyor . Sadece iki kuruş ...
Chris Cirefice

Çok güzel bir bithack, ama bitlerinizi MSB'den (solda) LSB'ye (sağda) sayıyorsunuz? IMO, 8 bitlik bir bayt (veya 128 bitlik bir SIMD vektörü veya her neyse) bitleri saymanın tek akıllıca yolu LSB = bit 0 - MSB = bit 7'dir.
Peter Cordes



9

Python 3 , 169 101 93 91 85 81 bayt

lambda s,j="".join:j(chr(int(j('01'[b<"C"])for b in c[::4]),2))for c in s.split())

Çevrimiçi deneyin!

Açıklama:

lambda s,j="".join:  # Create a lambda function
    j(  # call "".join, adds characters together with nothing in between
        chr(  # character by int
            int(  # string to int
                j(  # "".join again
                    '01'[b<"C"]  # 1 or 0, based on what character we get
                    for b in c[::4]  # For every first of 4 characters
                ),
                2)  # Base 2
        )
        for c in s.split()  # for every group of Fizz and Buzz with any whitespace character after it
    )

Bu kadar hızlı oldu. +1
HyperNeutrino

Bir süre önce buna benzer bir şey yaptım, sadece kopyala yapıştırma meselesiydi ve FizzBuzz'a değiştirdim: P
Martmists

1
Oh bu açıklıyor. : P Ama sen aşırıya kaçtın; _;
HyperNeutrino


1
Boğmaca, tekrar yaptı , bu sefer bir lambdafonksiyonla 85 bayt
Bay Xcoder

8

JavaScript (ES6), 80 79 bayt

let f =

s=>`${s} `.replace(/.{4} ?/g,m=>m[s=s*2|m<'F',4]?String.fromCharCode(s&255):'')

console.log(f("FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz"))


Çok hoş. Kullanarak birden fazla alternatif 80-bayt çözümleri vardır gerçi, denenmiş ve kısa bir şey ile gelip başarısız .replace(/..zz/g,, '0b'+vb
ETHproductions

@ETHproductions'ın kurtulması n79'a ulaşmayı sağlar. Ne yazık ki, bunun için girdiye eklenmesi gereken fazladan bir alan var. Dolayısıyla oldukça maliyetli `${s} ` .
Arnauld

7

Japt , 26 24 19 17 bayt

¸®ë4 ®c u5Ãn2 dÃq

Çevrimiçi deneyin!

@ETHproductions sayesinde @Shaggy ve 2 byte sayesinde 2 bayt kaydedildi

açıklama

input: "FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz"

¸®                // ["FizzBuzzBuzzFizzBuzzFizzFizzFizz","FizzBuzzBuzzFizzBuzzFizzFizzBuzz","FizzFizzBuzzFizzFizzFizzFizzBuzz"]
  ë4              // ["FBBFBFFF","FBBFBFFB","FFBFFFFB"]
     ®c           // [[70,66,66,70,66,70,70,70],[70,66,66,70,66,70,70,66],[70,70,66,70,70,70,70,66]]
        u5Ã       // ["01101000","01101001","00100001"]
           n2     // [104,105,33]
              d   // ["h","i","!"]
               Ãq // "hi!"

1
2 })ile değiştirebilirsiniz Ã. Bundan daha fazla kurtarılacak kesinlikle bir şey var ama telefonumda çalışmasını sağlayamıyorum.
Shaggy

1
Çok hoş, Japt kullandığınız için teşekkürler! Sen değiştirerek bir çift bayt kaydedebilirsiniz ò4...q n2ile ë4...n2( ë4aynı şey olarak değil ò4; garip, belgelenmelidir görünmüyor, sadece ilk öğe dönen hariç)
ETHproductions

1
@ETHproductions Japt yaptığınız için teşekkürler!
powelles

6

Ruby, 65 63 60 bayt

->s{s.split.map{|x|x.gsub(/..../){$&.ord%5}.to_i(2).chr}*''}

Bu, girdi alan ve dizge olarak çıktı veren anonim bir işlemdir.

->s{
s.split            # split on whitespace
.map{|x|           # for each word as x,
  x.gsub(/..../){  # replace each sequence of four characters with
    $&.ord%5       # the ASCII value of the first character, mod 5
                   # F is 70, B is 66, so this yields 0 for Fizz and 1 for Buzz
  }.to_i(2)        # interpret as a binary number
  .chr             # the character with this ASCII value
}*''               # join on empty string
}

6

JavaScript (ES6), 95 88 85 81 bayt

s=>s.replace(/..zz/g,m=>m<"F"|0).replace(/\d+ ?/g,m=>String.fromCharCode("0b"+m))

Dene

f=
s=>s.replace(/..zz/g,m=>m<"F"|0).replace(/\d+ ?/g,m=>String.fromCharCode("0b"+m))
oninput=_=>o.innerText=f(i.value)
o.innerText=f(i.value="FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz")
*{font-family:sans-serif}
<input id=i><p id=o>


Daha +kısa olduğuna inanıyorumparseInt
Kritixi Lithos

2
Ben +(m[0]<"F")kısaltılabilir düşünüyorumm<"F"|0
ETHproductions

5

Perl 5, 33 Bayt

print(pack'B*',<>=~y/FB -z/01/dr)

Girişteki 'F' ve 'B' harflerini sırasıyla 0 ve 1 ile değiştirir ve diğer karakterleri siler. Daha sonra packbu bit dizesini ASCII karakterlerine dönüştürmek için perl işlevini kullanır .


Vay bu benim Perl 5 girişimi yaklaşık yarısı kadar aşağı golf. Kudos.
David Conrad

1
Sana kullanarak bu oldukça kısa düşünürsek -p0komut satırı seçeneği (kurtaracak istiyorsunuz <>=~rgirişi için ve kullanmak için izin $_=ziyade print()). Yeni satırları nasıl işlemek istediğinize bağlı olarak, buna bile ihtiyacınız olmayabilir 0. (Komut satırı seçeneği cezalarından kaçınmak isteseniz bile say, daha kısadır print.)

@Chris Benim değil, faubiguy's. Ama teşekkürler. ;)
David Conrad

@DavidConrad Benim kötü haha.
Chris

1
Kesinlikle 0'a da ihtiyacınız yok. Sadece -p işaretini kullanın ve $_=pack'B*',y/FB -z/01/drprogramınız için puanınızı 26 bayta düşürün.
Chris

5

Python 2 , 90 83 82 81 bayt

Althemuman sayesinde -1 byte Martmists
sayesinde
-1 byte Jonathan Frech sayesinde -1 byte

lambda x:''.join(chr(int(`[+(l<'D')for l in b[::4]]`[1::3],2))for b in x.split())

Çevrimiçi deneyin!



Eğer çevirerek bir bayt kaydedebilirsiniz *1 foriçine*1for
Martmists

Kullanmak yana *1tam sayıya boolean gelen dönüştürmek için, bir kullanarak bir byte kaydedebilirsiniz +: (l<'D')*1forolabilmektedir +(l<'D')for.
Jonathan Frech

3

Boşluk, 123 bayt

Görünür temsil:

SSNNSSNSNSSSNSNSTNTSTTTSSSTSSSSSNTSSTSNSNTSSNSSSTSSTTSNTSSTNTSTNSSSTNTSSSNSSTNSSNSNSSNSTNTSTNTSTNTSTSSSNSNNNSSSNSNTTNSSNSNN

Unffccated program:

    push  0
loop:
    dup
    push  0
    dup
    ichr
    get
    push  32
    sub
    dup
    jz    space
    push  38
    sub
    jz    fizz
    push  1
    add
fizz:
    push  0
    dup
    dup
    ichr
    ichr
    ichr
    add
    jmp   loop
space:
    swap
    pchr
    jmp   loop

Uygulama ile ilgili garip bir şey yok, tek gerçek golf, bazı daha fazla baytı yok etmek için sınırsız yığın büyümesini önemsememenin yanı sıra, bazı tuhaf geçici kullanımları.


3

Octave , 59 57 53 bayt

@(s)['',bi2de(flip(reshape(s(65<s&s<71)<70,8,[]))')']

Bu, iletişim araç kutusu uygulanmadığından TIO'da çalışmaz. Octave-online'a kopyalayıp yapıştırırsanız iyi çalışır . MATLAB'da çalışma koduna yakın bile değil.

Etrafında tersine döndürdükten sonra, matrisi çevirdikten sonra iki bayttan tasarruf etmeyi başardı.

Açıklama:

@(s)             % Anonymous function that takes a string as input
    ['',<code>]  % Implicitly convert the result of <code> to its ASCII-characters

Ortasında başlayalım <code>:

s(65<s&s<71)      % Takes the elements of the input string that are between 66 and 70 (B and F)
                  % This gives a string FBBFFBBFBBBFFFBF...
s(65<s&s<71)<70   % Converts the resulting string into true and false, where F becomes false.
                  % Transformation: FBBFFB -> [0, 1, 1, 0, 0, 1]

Elde edilen boole (ikili) vektörünü arayalım t.

reshape(t,8,[])       % Convert the list of 1 and 0 into a matrix with 8 rows, one for each bit
flip(reshape(t,8,[])) % Flip the matrix vertically, since bi2de reads the bits from the wrong end
flip(reshape(t,8,[]))' % Transpose it, so that we have 8 columns, and one row per character
bi2de(.....)'          % Convert the result decimal values and transpose it so that it's horizontal

3

Bayraklar için 5, 28 bayt + 4 bayt = 32 bayt

Bayraklarla koş -040pE

$_=chr oct"0b".y/FB -z/01/dr

-040 kayıt ayırıcıyı bir boşluk olarak ayarlar, böylece perl her FizzBuzzes grubunu ayrı bir satır olarak görür, sonra bu satırlar üzerinde dolaşır, F'den 0, B'ye 1 değiştirir, her şeyi siler, sonra ikiliye ve oradan asciğe dönüştürür.




2

Brain-Flak , 107 bayt

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

Çevrimiçi deneyin!

İçin +3 bayt -cBayrak .

açıklama

{                                        For each character in input:
 (((((()()()()){}){}){})({}[{}])()())    Push 32-n and 66-n
 ((){[()](<{}>)}{}<>)<>                  If character is B, push 1 on second stack.  Otherwise, push 0
 {                                       If character is not space:
  (<{}{}{}{}>)                           Burn 3 additional characters
  <>({}({}){})<>                         Multiply current byte by 2 and add previously pushed bit
 }                                       (otherwise, the pushed 0 becomes the new current byte)
 {}                                      Remove character from input
}
<>{({}<>)<>}<>                           Reverse stack for output

2

q / kdb +, 41 40 37 33 bayt

Çözüm:

{10h$0b sv'66=vs[" ";x][;4*(!)8]}

Örnek:

q){10h$0b sv'66=vs[" ";x][;4*(!)8]}"FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz"
"hi!"

Açıklama:

Giriş dizesi Bölünmüş " "ayrı listelerini vermek FizzBuzz...ilk karakter (yani olarak bu listelerin her birine endeksi, 0 4 8 ... 28). Her karakterin "B"(ASCII 66) olup olmadığına göre belirlenen boolean listesi . Bu listeleri 10 tabanına dönüştürün ve sonucu dizeye dönüştürün.

{10h$0b sv'66=vs[" ";x][;4*til 8]} / ungolfed solution
{                                } / lambda function with x as implicit input
              vs[" ";x]            / split (vs) input (x) on space (" ")
                           til 8   / til 8, the range 0..7 inclusive
                         4*        / vectorised multiplication, 0 1 2 3 => 0 4 8 12
                       [;       ]  / index the 2nd level at these indices (0, 4, 8 ... 28)
           66=                     / 66 is ASCII B, 66="FBBFBFFF" -> 01101000b
     0b sv'                        / join (sv) each row back with 0b (converts from binary)
 10h$                              / cast to ASCII (0x686921 -> "hi!")

1

Haskell, 72 bayt

(>>= \w->toEnum(foldl1((+).(2*))[mod(fromEnum c)5|c<-w,c<'a']):"").words

Çevrimiçi deneyin!

Nasıl çalışır

            words      -- split input string into words at spaces
(>>=      )            -- map the function to each word and flatten the resulting
                       -- list of strings into a single string
   \w->                -- for each word w
       [  |c<-w,c<'a'] -- take chars c that are less than 'a' (i.e. B and F)
     mod(fromEnum c)5  -- take ascii value of c modulus 5, i.e. convert to bit value
    foldl1((+).(2*))   -- convert list of bit to int
  toEnum(   ):""       -- convert ascii to char.  :"" forces toEnum to be of type String
                       -- now we have a list of single char strings, e.g. ["h","i","!"]        

1

JavaScript ES6 - 98 bayt

çok fazla bayt, ancak en azından okunabilir

İşlev olarak tanımlanır, 98 bayttır

let s=>s.replace(/(F)|(B)|./g,(c,F,B)=>B?1:F?0:'').replace(/.{8}/g,v=>String.fromCharCode('0b'+v))

Ölçek:

"FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz"
.replace(/(F)|(B)|./g,(c,F,B)=>F?0:B?1:'').replace(/.{8}/g,v=>String.fromCharCode('0b'+v))

Açıklama:

/(F)|(B)|./

F ve B harflerini ve diğer her şeyi Gruplar olarak eşleştirir

(c,F,B)=>F?0:B?1:''

grupları yakalayan, F için 0, B için 1 veya '' döndüren bir İşlevdir.

c,
F ile eşleşen karakterdir ve B şimdi Parametrelerdir!
3 .grup parametre olarak dahil değil

F ve B undefined, 3. grupla eşleştiğinde
B, undefinedF grubu ile eşleştiğinde

Elde edilen 0100 .. etc string

8 bayt dilimler halinde kesilir

.replace(/.{8}/g,v=>String.fromCharCode('0b'+v))

ve 0b ikili dizge olarak işlendi


2
PPCG'ye Hoşgeldiniz! Bu zorluğun amacı, keyfi FizzBuzz dizgilerini çeviren bir program veya işlev sağlamaktır. Çok fazla JavaScript bilmiyorum, ancak geçerli bir işlev sunumu olabilir s=>s.replace( .... Ayrıca lütfen cevabınızın Başlığında bir bayt sayısı ekleyin.
Laikoni

Bazı kod biçimlendirmelerinizi sizin için temizledim. Ayrıca, ihtiyacınız yok let, isimsiz fonksiyonlar kabul edilebilir.
Shaggy




0

Google Sayfaları, 94 bayt

=ArrayFormula(JOIN("",CHAR(BIN2DEC(SPLIT(SUBSTITUTE(SUBSTITUTE(A1,"Fizz",0),"Buzz",1)," ")))))

FizzBuzz ikili bilgisine aşina değilim, ancak boşluklarla sınırlandırılmış gibi görünüyor, bu nedenle bu formül buna güveniyor. Mantık oldukça basittir:

  • Değiştir Fizzile 0ve Buzzile1
  • Ayırıcı olarak boşluk kullanarak sonucu bir diziye bölme
  • Her öğeyi ikiliden ondalıkya dönüştür
  • Her elemanı ASCII eşdeğeri ile değiştirin
  • Sınırlayıcı olmadan her bir öğeye katılın

0

Java 8, 117 115 bayt

s->{for(String x:s.split(" "))System.out.print((char)Long.parseLong(x.replace("Fizz","0").replace("Buzz","1"),2));}

Sana Java regexes yakalanan yakalama-gruplarıyla şey yapamaz başta çünkü çoğu diğer cevaplar gibi Java fantezi regex yedek bir çok şey yapabilir şüphe .. (Yani "$1".charAt(...)ya"$1".replace(...) örneğin mümkün değildir.)

Açıklama:

Burada dene.

s->{                          // Method with String parameter and no return-type
  for(String x:s.split(" "))  //  Loop over the input split by spaces:
    System.out.print(         //   Print:
     (char)                   //    Each character
     Long.parseLong(          //    after we've converted each binary-String to a long
      x.replace("Fizz","0").replace("Buzz","1")
                              //    after we've replaced the Fizz/Buzz to 0/1
     ,2));
}                             // End of method

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.