Fizz Buzz to Text


29

pengantar

Saya tidak terlalu tahu dari mana tren desis desis itu berasal. Mungkin hanya meme atau sesuatu, tetapi agak populer.

Tantangan

Tugas Anda hari ini adalah mengubah Fizz Buzz menjadi biner (0, 1), dan mengonversi biner itu menjadi teks. Barang yang cukup standar.

Bagaimana cara kerjanya?

FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz akan diterjemahkan menjadi 01101000 01101001 maka itu akan diterjemahkan menjadi "hai"

Kendala

  • Input adalah Fizz Buzz dalam sudut pandang biner (lihat contoh di bawah.)
  • Keluaran harus berupa teks.
  • Anda dapat menganggap input FizzBuzz benar.
  • Ini adalah , byte terpendek menang.

Memasukkan

FizzBuzzBuzzFizzBuzzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzFizzBuzz

Keluaran

"Hai!"


15
Meme? Ini adalah permainan sekolah dasar (dasar)
Beta Decay

2
Bisakah kita tidak mengambil spasi di input?
HyperNeutrino

2
Bisakah kita tidak mengambil ruang itu? Saya dapat menghemat tiga byte jika saya tidak perlu memasukkan ruang itu.
HyperNeutrino

10
FizzBuzz menikmati banyak mata uang di Stack Exchange sebagian karena Joel (salah satu pendiri) memiliki posting blog referensi blog lain yang berbicara tentang menggunakannya sebagai hambatan rendah untuk masalah entri bagi pelamar pemrograman .
dmckee

8
@dmckee "blog lain" yang dirujuk Joel adalah Jeff Atwood's, pendiri Stackoverflow lainnya.
pilsetnieks

Jawaban:


55

C, 59 byte

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

Angka ajaib, angka ajaib di mana-mana!

(Juga, C lebih pendek dari Python, JS, PHP, dan Ruby? Belum pernah terjadi!)

Ini adalah fungsi yang mengambil string sebagai input dan output ke STDOUT.

Panduan

Struktur dasarnya adalah:

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

Di sini, "barang-barang di dalam" adalah sekelompok kode diikuti oleh ,*s++, di mana koma operater hanya mengembalikan nilai argumen kedua. Oleh karena itu, ini akan dijalankan melalui string dan diatur *ske setiap karakter, termasuk byte NUL yang tertinggal (karena postfix ++mengembalikan nilai sebelumnya), sebelum keluar.

Mari kita lihat sisanya:

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

Mengupas bagian luar dan hubungan arus pendek ||, ini dapat diperluas

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

Dari mana angka-angka ajaib ini berasal? Berikut adalah representasi biner dari semua karakter yang terlibat:

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

Pertama, kita perlu memisahkan ruang dan NUL dari karakter lainnya. Cara algoritme ini bekerja, ia menyimpan akumulator dari angka "saat ini", dan mencetaknya setiap kali mencapai ruang atau akhir string (yaitu '\0'). Dengan memperhatikan itu ' 'dan '\0'merupakan satu-satunya karakter yang tidak memiliki salah satu dari dua bit paling tidak signifikan yang ditetapkan, kita dapat bitwise DAN karakter dengan 0b11untuk mendapatkan nol jika karakter tersebut adalah spasi atau NUL dan bukan nol sebaliknya.

Menggali lebih dalam, di cabang "jika" pertama, kita sekarang memiliki karakter yang salah satunya FBizu. Saya hanya memilih untuk memperbarui akumulator pada Fs dan Bs, jadi saya perlu beberapa cara untuk menyaring izus. Secara mudah, Fdan Bkeduanya hanya memiliki set bit paling signifikan kedua, ketiga, atau ketujuh yang ditetapkan, dan semua angka lainnya memiliki setidaknya satu set bit lainnya. Faktanya, mereka semua memiliki bit pertama atau keempat yang paling tidak signifikan. Oleh karena itu, kita dapat bitwise AND dengan 0b00001001, yaitu 9, yang akan menghasilkan 0 untuk Fdan Bdan bukan nol sebaliknya.

Setelah kita menentukan bahwa kita memiliki Fatau B, kita dapat memetakannya ke 0dan 1masing - masing dengan mengambil modulus 5 mereka, karena Fada 70dan Bsedang 66. Lalu potongannya

i += i + *s % 5;

hanyalah cara pepatah golf

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

yang juga dapat dinyatakan sebagai

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

yang memasukkan bit baru pada posisi paling tidak signifikan dan menggeser yang lainnya lebih dari 1.

"Tapi tunggu!" Anda mungkin protes. "Setelah Anda mencetak i, kapan itu akan kembali ke 0?" Nah, putcharmelemparkan argumennya ke sebuah unsigned char, yang kebetulan berukuran 8 bit. Itu berarti semuanya melewati bit ke-8 yang paling signifikan (yaitu sampah dari iterasi sebelumnya) dibuang, dan kita tidak perlu khawatir tentang hal itu.

Terima kasih kepada @ETHproductions karena menyarankan untuk mengganti 57dengan 9, menghemat satu byte!


Trik yang bagus dengan putchar.
Computronium

Ini benar-benar luar biasa. C melakukannya dengan benar!
Gustavo Maciel

13
Berbicara tentang melakukan hal yang benar, ini, menurut pendapat saya yang tidak terlalu rendah hati, bagaimana jawaban kode golf harus dilakukan. Anda memposting solusi cerdas, wawasan, disertai dengan penjelasan lengkap, ditulis dengan baik yang benar-benar mengajarkan orang sesuatu tentang bahasa yang mungkin berguna dalam keadaan lain yang lebih praktis.
Cody Grey

3
@CodyGray Persis seperti ini. Salah satu alasan Code Golf tidak berada di atas SE saya yang sering saya kunjungi adalah karena banyak jawaban hanya "ini kode". Sementara itu keren untuk orang-orang yang sangat terbiasa dengan bahasa, sepertinya berisik bagi saya. Saya suka melihat penjelasan seperti di sini karena ini mengungkapkan metode , yang saya pikir kebanyakan orang menemukan jauh lebih menarik daripada kode itu sendiri. Hanya dua sen saya ...
Chris Cirefice

Bithack yang sangat bagus, tetapi Anda menghitung bit Anda dari MSB (kiri) ke LSB (kanan)? IMO satu-satunya cara yang waras untuk menghitung bit dalam byte 8-bit (atau vektor 128-bit SIMD, atau apa pun) adalah dari LSB = bit 0 hingga MSB = bit 7.
Peter Cordes



9

Python 3 , 169 101 93 91 85 81 byte

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

Cobalah online!

Penjelasan:

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
    )

Itu cepat. +1
HyperNeutrino

Saya melakukan sesuatu yang mirip dengan ini beberapa waktu yang lalu, itu hanya masalah salin-tempel dan ubah ke FizzBuzz: P
Martmists

1
Oh, itu menjelaskan. : P Tapi kau dikalahkan; _;
HyperNeutrino


1
Aduh, lakukan lagi , 85 byte kali ini dengan lambdafungsi
Tn. Xcoder

8

JavaScript (ES6), 80 79 byte

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"))


Sangat bagus. Aku mencoba dan gagal untuk datang dengan sesuatu yang lebih pendek, meskipun ada beberapa alternatif solusi 80-byte menggunakan .replace(/..zz/g,, '0b'+, dll
ETHproductions

@ ETHproductions Menghilangkan nmemungkinkan untuk mencapai 79. Sayangnya, ini membutuhkan ruang tambahan untuk ditambahkan ke input. Karena itu agak mahal `${s} ` .
Arnauld

7

Japt , 26 24 19 17 bytes

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

Cobalah online!

Disimpan 2 byte berkat @Shaggy & 2 byte berkat @ETHproduksi

Penjelasan

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
Anda dapat mengganti 2 })dengan Ã. Pasti ada lebih banyak yang bisa diselamatkan dari itu, tetapi saya tidak bisa membuatnya berfungsi di ponsel saya.
Shaggy

1
Bagus sekali, terima kasih telah menggunakan Japt! Anda dapat menyimpan beberapa byte dengan menggantinya ò4...q n2dengan ë4...n2( ë4melakukan hal yang sama seperti ò4, kecuali mengembalikan hanya item pertama; anehnya, itu sepertinya tidak didokumentasikan)
ETHproductions

1
@ ETHproduk Terima kasih telah membuat Japt!
powelles

6

Ruby, 65 63 60 byte

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

Ini adalah proc anonim yang mengambil input dan memberikan output sebagai string.

->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 byte

s=>s.replace(/..zz/g,m=>m<"F"|0).replace(/\d+ ?/g,m=>String.fromCharCode("0b"+m))
  • 4 byte disimpan berkat produk ETH .

Cobalah

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>


Saya percaya +lebih pendek dariparseInt
Kritixi Lithos

2
Saya pikir +(m[0]<"F")bisa disingkat menjadim<"F"|0
ETHproduksi

5

Perl 5, 33 Bytes

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

Mengganti 'F' dan 'B' di input dengan masing-masing 0 dan 1, dan menghapus karakter lainnya. Ini kemudian menggunakan packfungsi perl untuk mengubah string bit ini menjadi karakter ASCII.


Wow ini golf turun menjadi sekitar setengah ukuran usaha Perl 5 saya. Pujian.
David Conrad

1
Saya percaya Anda bisa membuat ini jauh lebih pendek menggunakan -p0opsi baris perintah (yang akan menghemat <>=~rinput Anda, dan memungkinkan Anda untuk menggunakan $_=daripada print()). Bergantung pada bagaimana Anda ingin menangani baris baru, Anda bahkan mungkin tidak memerlukannya 0. (Bahkan jika Anda ingin menghindari hukuman opsi baris perintah, saylebih pendek dari print.)

@ Chris Bukan milikku, faubiguy's. Tapi terima kasih. ;)
David Conrad

@ Davidvidon Haha buruk saya.
Chris

1
Anda pasti tidak membutuhkan 0 baik. Cukup gunakan flag -p dan $_=pack'B*',y/FB -z/01/druntuk program Anda menurunkan skor Anda menjadi 26 byte.
Chris

5

Python 2 , 90 83 82 81 byte

-1 byte terima kasih kepada benar-benar manusia
-1 byte terima kasih kepada Martmists
-1 byte terima kasih kepada Jonathan Frech

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

Cobalah online!



Anda dapat menyimpan byte dengan mengubahnya *1 formenjadi*1for
Martmists

Karena Anda menggunakan *1untuk mengkonversi dari boolean ke integer, Anda dapat menyimpan byte dengan menggunakan +: (l<'D')*1forcan +(l<'D')for.
Jonathan Frech

3

Ruang putih, 123 byte

Representasi yang terlihat:

SSNNSSNSNSSSNSNSTNTSTTTSSSTSSSSSNTSSTSNSNTSSNSSSTSSTTSNTSSTNTSTNSSSTNTSSSNSSTNSSNSNSSNSTNTSTNTSTNTSTSSSNSNNNSSSNSNTTNSSNSNN

Program tanpa gangguan:

    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

Tidak ada yang aneh tentang implementasinya, satu-satunya golf sesungguhnya adalah penggunaan kembali temporari yang aneh dan juga tidak peduli dengan pertumbuhan stack yang tidak terbatas untuk membaca beberapa byte lagi.


3

Oktaf , 59 57 53 byte

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

Ini tidak berfungsi pada TIO, karena kotak alat komunikasi tidak diterapkan. Ini berfungsi dengan baik jika Anda menyalin-menempelkannya ke Octave-online . Itu bahkan tidak dekat dengan kode yang berfungsi di MATLAB.

Berhasil menyimpan dua byte dengan mentransposasi matriks setelah membaliknya, bukan sebaliknya.

Penjelasan:

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

Mari kita mulai di tengah <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]

Mari kita sebut vektor boolean (biner) yang dihasilkan untuk 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

Perl 5, 28 byte + 4 byte untuk flags = 32 byte

Jalankan dengan bendera -040pE

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

-040 mengatur pemisah rekaman ke spasi sehingga perl melihat setiap grup FizzBuzzes sebagai baris terpisah, lalu lompati garis-garis itu, mengubah F ke 0, B ke 1, menghapus semua yang lain, kemudian mengonversi ke biner dan dari sana ke ascii.




2

Brain-Flak , 107 byte

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

Cobalah online!

+3 byte untuk -cbendera.

Penjelasan

{                                        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 byte

Larutan:

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

Contoh:

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

Penjelasan:

Pisahkan string input pada " "untuk memberikan daftar FizzBuzz..., indeks yang berbeda ke masing-masing daftar ini pada karakter pertama (yaitu 0 4 8 ... 28). Kembalikan daftar boolean ditentukan oleh apakah masing-masing karakter "B"(ASCII 66). Konversikan daftar ini ke basis 10, dan kemudian hasilkan menjadi string.

{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 byte

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

Cobalah online!

Bagaimana itu bekerja

            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 byte

terlalu banyak byte, tetapi setidaknya dapat dibaca

Didefinisikan sebagai fungsinya adalah 98 byte

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

uji:

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

Penjelasan:

/(F)|(B)|./

Cocok dengan huruf F dan B dan apa pun sebagai Grup

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

adalah Fungsi yang menangkap grup, mengembalikan 0 untuk F dan 1 untuk B, atau ''

c adalah karakter yang cocok dengan
F dan B sekarang menjadi Parameter!
yang ke-3 . grup dinonaktifkan sebagai parameter

F dan B adalah undefinedketika kelompok ke-3 dicocokkan
B adalah undefinedketika kelompok F cocok

0100 yang dihasilkan .. string dll

dipotong dalam irisan 8 byte

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

dan diproses sebagai string biner 0b


2
Selamat datang di PPCG! Tujuan dari tantangan ini adalah untuk menyediakan program atau fungsi menerjemahkan string FizzBuzz yang sewenang-wenang. Saya tidak tahu banyak tentang JavaScript, tetapi pengajuan fungsi yang valid mungkin s=>s.replace( .... Harap sertakan juga jumlah byte dalam Tajuk jawaban Anda.
Laikoni

Saya membersihkan beberapa pemformatan kode Anda untuk Anda. Juga, Anda tidak perlu let, fungsi anonim dapat diterima.
Shaggy

1

shortC , 35 byte

i;AW*@&3?*@&9||(i+=i+*s%5):Pi),*s++

Konversi dalam program ini:

  • A - int main(int argc, char **argv){
  • W - while(
  • @ - argv
  • P - putchar(
  • Dimasukkan secara otomatis );}

Didasarkan dari pada jawaban Doorknob.




0

Google Sheets, 94 byte

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

Saya tidak terbiasa dengan biner FizzBuzz tetapi tampaknya mereka digambarkan oleh spasi sehingga rumus ini bergantung pada itu. Logikanya cukup sederhana:

  • Ganti Fizzdengan 0dan Buzzdengan1
  • Bagi hasil menjadi sebuah array menggunakan spasi sebagai pembatas
  • Konversi setiap elemen dari biner ke desimal
  • Ganti setiap elemen dengan ASCII yang setara
  • Gabung setiap elemen tanpa pembatas

0

Java 8, 117 115 byte

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

Saya ragu Anda dapat melakukan banyak penggantian regex mewah di Jawa seperti kebanyakan jawaban lainnya, terutama karena Anda tidak dapat melakukan apa pun dengan kelompok tangkapan yang ditangkap di Jawa-regex .. (Yaitu "$1".charAt(...)atau "$1".replace(...)tidak mungkin misalnya.)

Penjelasan:

Coba di sini.

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.