Fizz Buzz a texto

29

Introducción

No sé en particular de dónde vino la tendencia a la moda. Puede ser solo un meme o algo así, pero es algo popular.

Reto

Su trabajo hoy es convertir Fizz Buzz en binario (0, 1) respectivamente, y convertir ese binario en texto. Cosas bastante estándar.

¿Cómo funciona?

FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz se traduciría en 01101000 01101001 y eso se traduciría en "hola"

Restricciones

  • La entrada es Fizz Buzz en un punto de vista binario (ver ejemplos a continuación).
  • La salida debe ser texto.
  • Puede suponer que la entrada de FizzBuzz es correcta.
  • Este es el , gana el byte más corto.

Entrada

FizzBuzzBuzzFizzBuzzFizzFizzFizz FizzBuzzBuzzFizzBuzzFizzFizzBuzz FizzFizzBuzzFizzFizzFizzFizzBuzz

Salida

"¡Hola!"

KuanHulio
fuente
15
Meme Este es un juego escolar primario (primaria)
Beta Decay
2
¿No podemos tomar espacios en la entrada?
HyperNeutrino
2
Sin embargo, ¿no podemos tomar ese espacio? Puedo guardar tres bytes si no tengo que ingresar ese espacio.
HyperNeutrino
10
FizzBuzz disfruta mucho dinero en Stack Exchange, en parte porque Joel (uno de los fundadores) tenía una publicación en el blog que hacía referencia a otro blog que hablaba de usarlo como un problema de baja barrera de entrada para los solicitantes de programación .
dmckee
8
@dmckee el "otro blog" al que Joel hace referencia es Jeff Atwood's, el otro fundador de Stackoverflow.
pilsetnieks

Respuestas:

55

C, 59 bytes

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

¡Números mágicos, números mágicos en todas partes!

(Además, ¿C más corto que Python, JS, PHP y Ruby? ¡Inaudito!)

Esta es una función que toma una cadena como entrada y salida a STDOUT.

Tutorial

La estructura básica es:

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

Aquí, las "cosas dentro" son un montón de código seguido de ,*s++, donde el operador de coma devuelve solo el valor de su segundo argumento. Por lo tanto, esto se ejecutará a través de la cadena y se establecerá *sen cada carácter, incluido el byte NUL final (ya que postfix ++devuelve el valor anterior), antes de salir.

Echemos un vistazo al resto:

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

Despegando el ternario y cortocircuito ||, esto se puede expandir a

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

¿De dónde vienen estos números mágicos? Aquí están las representaciones binarias de todos los personajes involucrados:

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

Primero, necesitamos separar el espacio y NUL del resto de los personajes. La forma en que funciona este algoritmo mantiene un acumulador del número "actual" e imprime cada vez que llega a un espacio o al final de la cadena (es decir '\0'). Al notar eso ' 'y '\0'son los únicos caracteres que no tienen ninguno de los dos bits menos significativos establecidos, podemos bit a bit Y el carácter 0b11para obtener cero si el carácter es espacio o NUL y no cero de lo contrario.

Profundizando, en la primera rama "si", ahora tenemos un personaje que es uno de ellos FBizu. Elegí solo actualizar el acumulador en Fsy Bs, por lo que necesitaba alguna forma de filtrar el izus. Convenientemente, Fy Bambos tienen solo el segundo, tercer o séptimo conjunto de bits menos significativo, y todos los otros números tienen al menos otro conjunto de bits. De hecho, todos tienen el primer o cuarto bit menos significativo. Por lo tanto, podemos bit a bit AND con 0b00001001, que es 9, que de lo contrario producirá 0 para Fand By no cero.

Una vez que hemos determinado que tenemos un Fo B, podemos asignarlos a 0y 1respectivamente tomando su módulo 5, porque Fes 70y Bes 66. Entonces el fragmento

i += i + *s % 5;

es solo una forma de decir golf

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

que también se puede expresar como

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

que inserta el nuevo bit en la posición menos significativa y cambia todo lo demás en 1.

"¡Pero espera!" Podrías protestar. "Después de imprimir i, ¿cuándo vuelve a restablecerse a 0?" Bueno, putchararroja su argumento a un unsigned char, que resulta ser de 8 bits de tamaño. Eso significa que todo lo que pasa del octavo bit menos significativo (es decir, la basura de las iteraciones anteriores) se descarta, y no debemos preocuparnos por eso.

¡Gracias a @ETHproductions por sugerir reemplazar 57con 9, guardando un byte!

Pomo de la puerta
fuente
Buen truco con el putchar.
Computronium
Esto es realmente increíble. C hizo bien!
Gustavo Maciel
13
Hablando de hacer las cosas bien, esto es, en mi opinión no tan humilde, cómo se debe hacer una respuesta de código de golf. Publica una solución inteligente y perspicaz, acompañada de una explicación completa y bien escrita que realmente enseña a las personas algo sobre el lenguaje que podría ser útil en otras circunstancias más prácticas.
Cody Gray
3
@CodyGray Exactamente esto. Una de las razones por las que Code Golf no está en la parte superior de mi SE que visito con frecuencia es porque muchas respuestas son simplemente "aquí está el código". Si bien eso es genial para las personas que están muy familiarizadas con los idiomas, solo me parece ruido. Me gusta ver las explicaciones como aquí porque revela el método , que creo que la mayoría de la gente encuentra mucho más interesante que el código en sí. Solo mis dos centavos ...
Chris Cirefice
Muy buen bithack, pero ¿cuentas tus bits de MSB (izquierda) a LSB (derecha)? En mi opinión, la única forma sensata de contar bits en un byte de 8 bits (o un vector SIMD de 128 bits, o lo que sea) es de LSB = bit 0 a MSB = bit 7.
Peter Cordes
10

Jalea , 9 bytes

Ḳm€4O%5ḄỌ

Pruébalo en línea!

Erik el Outgolfer
fuente
Oh inteligente, aplastarlo era innecesario. Agradable.
HyperNeutrino
@HyperNeutrino Tenga en cuenta el comentario que he hecho sobre el suyo, he usado un algoritmo ligeramente diferente para evitar duplicaciones (aunque técnicamente está permitido, no me gusta).
Erik the Outgolfer
@downvoter: ¿probaste esto antes de hacer una votación negativa?
Erik the Outgolfer
9

Bash + coreutils, 61 50 bytes

(-11 bytes gracias a Doorknob !)

tr -d izu<<<$1|tr FB 01|dc -e'2i?[aPz0<k]dskx'|rev

Pruébalo en línea!

R. Kap
fuente
2
Puede reemplazar el sedcon tr FB 01|tr -d izupara guardar 11 bytes.
Pomo de la puerta
9

Python 3 , 169 101 93 91 85 81 bytes

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

Pruébalo en línea!

Explicación:

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
    )
Martistas
fuente
Eso fue rápido. +1
HyperNeutrino
Hice algo similar a esto hace un tiempo, fue solo cuestión de copiar y pegar y cambiarlo a FizzBuzz: P
Martmists
1
Oh eso explica. : P Pero te sobrepasaste; _;
HyperNeutrino
1
Vaya, lo hice de nuevo , 85 bytes esta vez con una lambdafunción
Sr. Xcoder
8

JavaScript (ES6), 80 79 bytes

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

Arnauld
fuente
Muy agradable. Me intentó y no pudo llegar a algo más corto, aunque hay varias alternativas soluciones de 80 bytes que utilizan .replace(/..zz/g,, '0b'+etc.
ETHproductions
@ETHproductions Deshacerse npermite alcanzar 79. Lamentablemente, esto requiere un espacio adicional para agregar a la entrada. De ahí lo bastante costoso `${s} ` .
Arnauld
7

Japt , 26 24 19 17 bytes

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

Pruébalo en línea!

Ahorró 2 bytes gracias a @Shaggy y 2 bytes gracias a @ETHproductions

Explicación

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!"
Powelles
fuente
1
Puede reemplazar el 2 })con Ã. Definitivamente hay más para salvar que eso, pero no puedo hacer que funcione en mi teléfono.
Shaggy
1
Muy bien, gracias por usar Japt! Puede guardar un par de bytes reemplazándolos ò4...q n2con ë4...n2( ë4hace lo mismo que ò4, excepto devolver solo el primer elemento; curiosamente, no parece estar documentado)
ETHproductions
1
@ETHproductions ¡Gracias por hacer Japt!
Powelles
6

Ruby, 65 63 60 bytes

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

Este es un proceso anónimo que toma entrada y da salida como una cadena.

->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
}
Pomo de la puerta
fuente
6

JavaScript (ES6), 95 88 85 81 bytes

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

Intentalo

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>

Lanudo
fuente
Creo que +es más corto queparseInt
Kritixi Lithos
2
Creo que +(m[0]<"F")podría acortarse am<"F"|0
ETHproductions
5

Perl 5, 33 bytes

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

Reemplaza 'F' y 'B' en la entrada con 0 y 1 respectivamente, y elimina los otros caracteres. Luego usa la packfunción de perl para convertir esta cadena de bits en caracteres ASCII.

faubi
fuente
Wow, esto se reduce a la mitad del tamaño de mi intento de Perl 5. Prestigio.
David Conrad
1
Creo que podría hacer esto considerablemente más corto usando la -p0opción de línea de comando (que le ahorraría <>=~rpara la entrada y le permitiría usar en $_=lugar de print()). Dependiendo de cómo desee manejar las nuevas líneas, es posible que ni siquiera necesite el 0. (Incluso si desea evitar las penalizaciones de la opción de línea de comando, sayes más corto que print.)
@ Chris No es mío, faubiguy's. Pero gracias. ;)
David Conrad
@DavidConrad Mi mal jaja.
Chris
1
Definitivamente tampoco necesitas el 0. Simplemente use la bandera -p y$_=pack'B*',y/FB -z/01/dr para su programa baja su puntaje a 26 bytes.
Chris
5

Python 2 , 90 83 82 81 bytes

-1 byte gracias a totalmente humano
-1 byte gracias a Martmists
-1 byte gracias a Jonathan Frech

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

Pruébalo en línea!

Barra
fuente
Sin un byte.
Totalmente humano
puede guardar un byte convirtiéndose *1 foren*1for
Martmists
Como utiliza *1para convertir de booleano a entero, puede guardar un byte utilizando +: (l<'D')*1forpuede ser +(l<'D')for.
Jonathan Frech
3

Espacio en blanco, 123 bytes

Representación visible:

SSNNSSNSNSSSNSNSTNTSTTTSSSTSSSSSNTSSTSNSNTSSNSSSTSSTTSNTSSTNTSTNSSSTNTSSSNSSTNSSNSNSSNSTNTSTNTSTNTSTSSSNSNNNSSSNSNTTNSSNSNN

Programa no ofuscado:

    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

No hay nada particularmente extraño en la implementación, el único juego de golf real es una extraña reutilización de los temporales, así como no preocuparse por el crecimiento ilimitado de la pila para escatimar algunos bytes más.

Nombre de usuario censurado
fuente
3

Octava , 59 57 53 bytes

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

Esto no funciona en TIO, ya que la caja de herramientas de comunicación no está implementada. Funciona bien si lo copia y pega Octave-online . Ni siquiera está cerca de ser código de trabajo en MATLAB.

Se las arregló para guardar dos bytes al transponer la matriz después de voltearla, en lugar de al revés.

Explicación:

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

Comencemos en el medio de <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]

Llamemos al vector booleano (binario) resultante para 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
Stewie Griffin
fuente
3

Perl 5, 28 bytes + 4 bytes para banderas = 32 bytes

Corre con las banderas -040pE

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

-040 establece el separador de registros en un espacio para que Perl vea cada grupo de FizzBuzzes como una línea separada, luego recorra esas líneas, cambie F a 0, B a 1, elimine todo lo demás, luego convierta a binario y de allí a ascii.

Chris
fuente
2

Jalea , 9 bytes

Ḳm€4=”BḄỌ

Pruébalo en línea!

Ḳm€4=”BḄỌ  Main Link
Ḳ          Split on spaces
  €        Map
 m 4       Take every fourth letter (F and B)
    =”B    Check if each letter is equal to B (gives the binary representation)
       Ḅ   Binary -> Integer
        Ọ  Unord; gives chr(i)

-3 bytes gracias a Erik the Outgolfer

Hiperneutrino
fuente
Continuemos esta discusión en el chat .
Erik the Outgolfer
2

PHP, 67 bytes

Limitado a 8 letras

<?=hex2bin(dechex(bindec(strtr($argn,[Fizz=>0,Buzz=>1," "=>""]))));

Pruébalo en línea!

PHP, 77 bytes

foreach(explode(" ",strtr($argn,[Fizz=>0,Buzz=>1]))as$v)echo chr(bindec($v));

Pruébalo en línea!

Jörg Hülsermann
fuente
2

Brain-Flak , 107 bytes

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

Pruébalo en línea!

+3 bytes para el -c bandera.

Explicación

{                                        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
Nitrodon
fuente
2

q / kdb +, 41 40 37 33 bytes

Solución:

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

Ejemplo:

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

Explicación:

Divida la cadena de entrada " "para obtener listas distintas de FizzBuzz...índice en cada una de estas listas en el primer carácter (es decir 0 4 8 ... 28). Devuelve una lista booleana determinada por si cada carácter es "B"(ASCII 66). Convierta estas listas a base 10, y luego convierta el resultado a cadena.

{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!")
callejero
fuente
1

Haskell, 72 bytes

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

Pruébalo en línea!

Cómo funciona

            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","!"]        
nimi
fuente
1

JavaScript ES6 - 98 bytes

demasiados bytes, pero al menos legible

Definido como función, es de 98 bytes.

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

prueba:

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

Explicación:

/(F)|(B)|./

Coincide con las letras F y B y cualquier otra cosa como grupos

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

es una función que captura los grupos, devuelve un 0 para F y 1 para B, o ''

c es el personaje que coincide
F y B ahora son parámetros!
el 3er .el grupo se omite como parámetro

F y B son undefinedcuando se empareja el tercer grupo
B esundefined cuando se hace coincidir el grupo F

La cadena resultante 0100 .. etc.

se corta en rodajas de 8 bytes

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

y procesado como cadena binaria 0b

Danny '365CSI' Engelman
fuente
2
Bienvenido a PPCG! El objetivo de este desafío es proporcionar un programa o función que traduzca cadenas arbitrarias de FizzBuzz. No sé mucho JavaScript, pero podría ser una presentación de función válida s=>s.replace( .... También incluya un recuento de bytes en el encabezado de su respuesta.
Laikoni
Limpié algunos de sus formatos de código para usted. Además, no necesita let, las funciones anónimas son aceptables.
Shaggy
1

shortC , 35 bytes

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

Conversiones en este programa:

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

Basada en la respuesta de Doorknob.

MD XF
fuente
1

APL (Dyalog Classic) , 17 bytes

{82DR'B'=⍵∩'BF'}

Explicación

           ⍵∩'BF'    cut, removes all but 'BF' from 
       'B'=          equals 'B' turns it into binary stream   
 82DR              converts into character stream

Pruébalo en línea!

Gil
fuente
0

Hojas de cálculo de Google, 94 bytes

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

No estoy familiarizado con el binario FizzBuzz, pero parece que están delineados por espacios, por lo que esta fórmula se basa en eso. La lógica es bastante simple:

  • Reemplazar Fizzcon 0y Buzzcon1
  • Divida el resultado en una matriz usando un espacio como delimitador
  • Convierta cada elemento de binario a decimal
  • Reemplace cada elemento con su equivalente ASCII
  • Une cada elemento sin un delimitador
Tostadas de ingeniero
fuente
0

Java 8, 117115 bytes

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

Dudo que pueda hacer muchos reemplazos de expresiones regulares sofisticadas en Java como la mayoría de las otras respuestas, principalmente porque no puede hacer nada con los grupos de captura capturados en expresiones regulares Java (es decir, "$1".charAt(...)o "$1".replace(...)no es posible, por ejemplo).

Explicación:

Pruébalo aquí.

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
Kevin Cruijssen
fuente