Fizz Buzz con personajes únicos en columnas

21

Inspirado por Dígitos en sus carriles y 1, 2, Fizz, 4, Buzz

Introducción

Su tarea es generar exactamente el siguiente resultado:

1
2
Fizz
4
  Buzz
    Fizz
7
8
      Fizz
        Buzz
 11
          Fizz
   13
    14
            FizzBuzz
     16
      17
              Fizz
       19
                  Buzz
                    Fizz
 22
    23
                      Fizz
                        Buzz
   26
                          Fizz
     28
      29
                            FizzBuzz
       31
      32
                              Fizz
34
                                  Buzz
                                    Fizz
 37
  38
                                      Fizz
                                        Buzz
        41
                                          Fizz
  43
   44
                                            FizzBuzz
      46
       47
                                              Fizz
         49
                                                  Buzz

Reto

Este desafío se basa en el desafío Fizz Buzz, y aquí hay un resumen: genera los números del 1 al 100 inclusive, cada número en su propia línea, pero si el número es un múltiplo de 3, debes generar "Fizz" en lugar de el número original, si el número es un múltiplo de 5, debe generar "Buzz" en lugar del número original. Si el número es un múltiplo de 15, debe generar "FizzBuzz" en lugar del número original.

Sin embargo, además del requisito anterior, también debe sangrar cada línea usando espacios para que cada columna contenga caracteres únicos (excluyendo espacios y líneas nuevas) solamente. Los espacios antepuestos a cada línea son los mínimos requeridos para que todas las líneas aparezcan antes de que (inclusive) tenga caracteres únicos en cada columna.

Por ejemplo, 1,2,Fizz,4no necesita ninguna sangría porque ya tienen caracteres únicos en cada columna (columna 1:, 12F4columna2:, icolumna3:, zcolumna4:) z, pero al agregar Buzznecesitamos sangrar por dos espacios porque de lo contrario tendríamos dos z's tanto en la tercera como en la cuarta columna. Dado que dos espacios son suficientes para lograr el objetivo, no debe sangrarlo por tres espacios. 7y 8no necesita ninguna sangría, pero cuando 11salimos necesitamos sangrar por un espacio porque la primera columna ya tiene un 1. 13luego necesita sangrar por tres espacios porque ahora la 1ra, 2da y 3ra columna tienen a 1. La sangría para las líneas restantes sigue la misma regla.

Para simplificar el desafío, el límite superior se ha cambiado a 50.

Especificaciones

  • Puedes escribir un programa o una función. Ninguno de ellos debería tomar ninguna entrada no vacía. Tomar una entrada vacía está bien.

  • Dado que este es un desafío de KC, debe producir el resultado tal como se especifica en la sección Introducción. Una nueva línea final está bien. Sin encabezado de nuevas líneas o espacios de encabezado adicionales. No hay espacios finales adicionales para cada línea.

  • Su programa puede salir con error o tener una salida STDERR no vacía siempre que STDOUT se ajuste a la especificación.

  • Este es el dentro del idioma , el programa con el menor número de bytes gana en su idioma.

  • Se aplican las lagunas predeterminadas .

Weijun Zhou
fuente
2
La salida dada no coincide exactamente con la especificación, por ejemplo, las líneas 12, 20, 35 y 50.
Bubbler
1
Pero el segundo carácter en las dos primeras líneas es el retorno de carro.
Acumulación
He excluido espacios, ahora también debería excluir nuevas líneas.
Weijun Zhou

Respuestas:

9

Python 2 , 127 bytes

i=0;exec"print ord('<<<<>@<<BD=F?@HABJCNP=@RT?VABXCBZ<^`=>bdDf>?hBCjEn'[i])%60*' '+(i%3/2*'Fizz'+i%5/4*'Buzz'or`-~i`);i+=1;"*50

Pruébalo en línea!

Una tabla de búsqueda de cincuenta bytes parece dañar el tamaño del código menos que la lógica necesaria para rastrear qué caracteres han ocurrido en cada columna.

Lynn
fuente
1
La lógica hubiera sido mejor si tuviéramos que imprimir hasta 100 en su lugar ...
Bubbler
5

Python 2 , 167 166 163 161 157 bytes

a=eval(`[{0}]*99`);i=0
exec"f=i%3/2*'Fizz'+i%5/4*'Buzz'or`i+1`;i+=1;g=0\nwhile any(b>{c}for b,c in zip(a[g:],f)):g+=1\nmap(set.add,a[g:],f);print' '*g+f;"*50

Pruébalo en línea!

Ediciones:

  • whilees más corto que for..range()en 1 byte.
  • Gracias a @ovs por reducir 3 bytes. Siempre me olvido exec...
  • i%3/2Truco adaptado de la respuesta de Lynn (-2 bytes).
  • @Lynn sugirió a=map(set,[[]]*99), pero encontré otra forma de usar evaly reprcon los mismos bytes (-4 bytes).

Use una lista de conjuntos para rastrear los caracteres utilizados para cada columna y establezca la desigualdad para la membresía. El resto sigue la especificación exacta dada.

Bubbler
fuente
4

C (gcc) , 145 144 bytes (143 para hex)

i;main(){for(;i++<50;printf("%*s%s%.d\n","000402800:81>34@56B7BH14JH3N56P76R0RX12ZX8^23`67b9b"[i]-48,i%3?"":"Fizz",i%5?"":"Buzz",i%3*i%5?i:0));}

Pruébalo en línea!

0000h: 69 3B 6D 61 69 6E 28 29 7B 66 6F 72 28 3B 69 2B ; i;main(){for(;i+
0010h: 2B 3C 35 30 3B 70 72 69 6E 74 66 28 22 25 2A 73 ; +<50;printf("%*s
0020h: 25 73 25 2E 64 5C 6E 22 2C 22 FE FE FE 02 FE 00 ; %s%.d\n","......
0030h: 06 FE FE 08 06 FF 0C 01 02 0E 03 04 10 05 10 16 ; ................
0040h: FF 02 18 16 01 1C 03 04 1E 05 04 20 FE 20 26 FF ; ........... . &.
0050h: 63 28 26 06 2C 00 01 2E 04 05 30 07 30 22 5B 69 ; c(&.,.....0.0"[i
0060h: 5D 2B 32 2C 69 25 33 3F 22 22 3A 22 46 69 7A 7A ; ]+2,i%3?"":"Fizz
0070h: 22 2C 69 25 35 3F 22 22 3A 22 42 75 7A 7A 22 2C ; ",i%5?"":"Buzz",
0080h: 69 25 33 2A 69 25 35 3F 69 3A 30 29 29 3B 7D    ; i%3*i%5?i:0));}
l4m2
fuente
3

Rubí , 129 bytes

puts (1..50).map{|n|" "*(".<<<<>@<<BD=F?@HABJCNP=@RT?VABXCBZ<^`=>bdDf>?hBCjEn"[n].ord%60)+("FizzBuzz
"[i=n**4%-15,i+13]||n.to_s)}

Pruébalo en línea!

El doble crédito va para Lynn aquí, por el enfoque de la tabla de búsqueda y el algoritmo fizzbuzz .

El algoritmo FizzBuzz es muy interesante, y depende de la notable coincidencia de que todos los números positivos, no compuestos, menores de 15 (que no sean 3 y 5), cuando se elevan a la cuarta potencia, son 1 más que un múltiplo de 15. En hecho:

 n     n**4  n**4%15  n**4%-15
 1        1     1       -14
 2       16     1       -14
 3       81     6        -9
 4      256     1       -14
 5      625    10        -5
 6     1296     6        -9
 7     2401     1       -14
 8     4096     1       -14
 9     6561     6        -9
10    10000    10        -5
11    14641     1       -14
12    20736     6        -9
13    28561     1       -14
14    38416     1       -14
15    50625     0         0

Los valores 3**4%15y 5**4%15son exactamente 4 separados: la longitud de la cadena "Fizz". Podemos explotar esto usándolos para indexar desde el final de una cadena, de al menos 9 caracteres de longitud. Los múltiplos de 3 se indexarán desde el principio de la cadena, y los múltiplos de 5 indexarán desde 5 caracteres desde el final. Cualquier otro número intentará indexar desde antes del comienzo de la cadena, y fallará, regresando nil. Luego 15, por supuesto, índices del carácter 0. El hecho de que "FizzBuzz" tenga solo 8 caracteres es un pequeño obstáculo; usamos un carácter de nueva línea para rellenarlo, que luego será ignorado por puts.

Es posible que la tabla de búsqueda pueda ser superada por un enfoque más procesal, pero mi intento fue de alrededor de 190 bytes.

benj2240
fuente
2
Interesante. Cabe señalar que el hecho de que todos los números coprimen a 15 cuando se eleva a 4ta potencia igual a 1 módulo 15 puede derivarse del pequeño teorema de Fermat.
Weijun Zhou
2

[JavaScript (Node.js) REPL], 144 bytes

(f=(i,s=[['Fizz'][i%3]]+[['Buzz'][i%5]]||i+[],b=i>1?f(i-1):[])=>[...s].some((p,j)=>b.some(w=>w[j]==p&0!=p))?f(i,' '+s):b.push(s)&&b)(50).join`

``

Pruébalo en línea!

El programa de advertencia en sí ejecuta un tiempo inaceptable

JavaScript (Node.js) , 132 bytes por Arnauld

f=(a=n=[],s=`${b=++n%5?'':'Buzz',n%3?b||n:'Fizz'+b}
`)=>n>50?'':a.some(x=>[...x].some((c,i)=>c!=0&c==s[i]))?f(a,' '+s):s+f([s,...a])

Pruébalo en línea!

l4m2
fuente
Su respuesta no parece ser la misma que el enlace TIO
Jo King,
@JoKing TIO genera una matriz, y no sé si está permitido
l4m2
1

Haskell , 190 187 186 178 176 bytes

unlines$foldl(\a x->a++[[z|z<-iterate(' ':)x,all(\m->null[p|(p,q)<-m`zip`z,p==q&&p>' '])a]!!0])[]$h<$>[1..50]
a%b=a`mod`b<1
h n|n%15="FizzBuzz"|n%3="Fizz"|n%5="Buzz"|1<2=show n

Pruébalo en línea!

La versión ligeramente más legible (y anotada):

-- check if a is evenly divisible by b
a%b=a`mod`b<1
-- produce correct FizzBuzz output for a number
h n|n%15="FizzBuzz"|n%3="Fizz"|n%5="Buzz"|1<2=show n
-- test if all chars distinct between two strings
x#y=null[a|(a,b)<-x`zip`y,a==b&&a>' ']
-- given a new string and all previous strings
-- shift the new string to the right until all
-- chars are distinct
x!y=[z|z<-iterate(' ':)y,all(z#)x]!!0
g=h<$>[1..50]
f'=foldl step[]g
  where step acc x = acc++[acc!x]

Editar: terminé alineando algunas funciones en la versión de golf para guardar más bytes.

Cristian Lupascu
fuente
@Laikoni a la derecha. Fijo.
Cristian Lupascu
1

Jstx , 122 bytes

◄50-☺6*ø($♥:ø↕♂Fizz♀☺(◙$♣:ø↕♂Buzz♀6☺(◙"ø↕$6◙♂<<<<>@<<BD=F?@HABJCNP=@RT?VABXCBZ<^`=>bdDf>?hBCjEn'[i])%60*♀&P◄59▼ö,► 7.☻a0.2

Pruébalo en línea!

Quantum64
fuente