Fizz Buzz avec des caractères uniques dans les colonnes

21

Inspiré par les chiffres dans leurs voies et 1, 2, Fizz, 4, Buzz

introduction

Votre tâche consiste à générer exactement la sortie suivante:

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

Défi

Ce défi est basé sur le défi Fizz Buzz, et voici un récapitulatif: sortez les nombres de 1 à 100 inclus, chaque nombre sur sa propre ligne, mais si le nombre est un multiple de 3, vous devez sortir "Fizz" au lieu de le numéro d'origine, si le nombre est un multiple de 5, vous devez sortir "Buzz" au lieu du numéro d'origine. Si le nombre est un multiple de 15, vous devez sortir "FizzBuzz" au lieu du nombre d'origine.

Cependant, en plus de l'exigence ci-dessus, vous devez également mettre en retrait chaque ligne en utilisant des espaces pour que chaque colonne contienne des caractères uniques (à l'exclusion des espaces et des retours à la ligne) uniquement. Les espaces ajoutés à chaque ligne sont le minimum requis pour que toutes les lignes apparaissent avant qu'il (inclus) ait des caractères uniques dans chaque colonne.

Par exemple, 1,2,Fizz,4ne nécessite pas de retrait parce qu'ils ont déjà des caractères uniques dans chaque colonne (colonne 1: 12F4, colonne2: i, colonne3: z, column4: z), mais lors de l' ajout Buzznous devons tiret par deux espaces , car sinon nous aurions deux z« s dans les 3e et 4e colonnes. Étant donné que deux espaces suffisent pour atteindre l'objectif, vous ne devez pas le mettre en retrait de trois espaces. 7et 8n'a pas besoin d'indentation, mais lors de la sortie, 11nous devons indenter d'un espace car la 1ère colonne a déjà un 1. 13doit ensuite être indenté de trois espaces, car maintenant la 1ère, la 2ème et la 3ème colonne ont toutes un 1. Le retrait des lignes restantes suit la même règle.

Pour simplifier le défi, la limite supérieure a été modifiée à 50.

Spécifications

  • Vous pouvez écrire un programme ou une fonction. Aucun d'eux ne doit prendre aucune entrée non vide. Prendre une entrée vide est très bien.

  • Comme il s'agit d'un défi KC, vous devez produire la sortie comme spécifié dans la section Introduction. Une seule nouvelle ligne de fin est très bien. Pas de nouvelles lignes de titre ni d'espaces de titre supplémentaires. Aucun espace de fin supplémentaire pour chaque ligne.

  • Votre programme peut quitter avec erreur ou avoir une sortie STDERR non vide tant que STDOUT est conforme à la spécification.

  • Il s'agit du intra-langue , le programme avec le plus petit nombre d'octets gagne dans sa langue.

  • Les failles par défaut s'appliquent.

Weijun Zhou
la source
2
La sortie donnée ne correspond pas exactement à la spécification, par exemple les lignes 12, 20, 35 et 50.
Bubbler
1
Mais le deuxième caractère des deux premières lignes est le retour chariot.
Accumulation
J'ai exclu des espaces, maintenant je dois également exclure les nouvelles lignes.
Weijun Zhou

Réponses:

9

Python 2 , 127 octets

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

Essayez-le en ligne!

Une table de recherche de cinquante octets semble nuire à la taille du code moins que la logique nécessaire pour suivre les caractères qui se sont produits dans chaque colonne.

Lynn
la source
1
La logique aurait été meilleure si nous devions imprimer jusqu'à 100 à la place ...
Bubbler
5

Python 2 , 167 166 163 161 161 157 octets

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

Essayez-le en ligne!

Modifications:

  • whileest plus court que for..range()d'un octet.
  • Merci à @ovs pour avoir rasé 3 octets. J'oublie toujours exec...
  • Astuce adaptée i%3/2de la réponse de Lynn (-2 octets).
  • @Lynn a suggéré a=map(set,[[]]*99), mais j'ai trouvé une autre façon d'utiliser evalet repravec les mêmes octets (-4 octets).

Utilisez une liste d'ensembles pour suivre les caractères utilisés pour chaque colonne et définir l'inégalité d'appartenance. Le reste suit la spécification exacte donnée.

Bubbler
la source
4

C (gcc) , 145 144 octets (143 pour 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));}

Essayez-le en ligne!

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
la source
3

Rubis , 129 octets

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

Essayez-le en ligne!

Double crédit revient à Lynn ici, pour l' approche de la table de recherche et l' algorithme fizzbuzz .

L'algorithme FizzBuzz est très intéressant, et il repose sur la remarquable coïncidence que tous les nombres positifs non composites inférieurs à 15 (autres que 3 et 5), lorsqu'ils sont élevés à la 4e puissance, sont 1 de plus qu'un multiple de 15. Dans fait:

 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

Les valeurs 3**4%15et 5**4%15sont exactement 4 écartées: la longueur de la chaîne "Fizz". Nous pouvons l'exploiter en les utilisant pour indexer à la fin d'une chaîne, d'au moins 9 caractères. Les multiples de 3 indexeront à partir du début de la chaîne et les multiples de 5 indexeront à partir de 5 caractères à partir de la fin. Tout autre nombre tentera d'indexer avant le début de la chaîne et échouera en retournant nil. Ensuite, bien sûr, 15 index à partir du 0e caractère. Le fait que "FizzBuzz" ne comporte que 8 caractères est un petit obstacle; nous utilisons un caractère de nouvelle ligne pour le remplir, qui sera plus tard ignoré par puts.

Il est possible que la table de recherche puisse être distancée par une approche plus procédurale, mais ma tentative a été de l'ordre de 190 octets.

benj2240
la source
2
Intéressant. Il convient de noter que le fait que tous les nombres copriment à 15 lorsqu'ils sont élevés à la 4e puissance égale à 1 modulo 15 peut être dérivé du petit théorème de Fermat.
Weijun Zhou
2

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

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

"

Essayez-le en ligne!

Le programme d'avertissement lui-même s'exécute une durée inacceptable

JavaScript (Node.js) , 132 octets par 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])

Essayez-le en ligne!

l4m2
la source
Votre réponse ne semble pas être la même que le lien TIO
Jo King
@JoKing TIO sort un tableau, et je ne sais pas si c'est autorisé
l4m2
2

Java (JDK 10) , 185 octets

v->{for(int n=0,l;n<50;System.out.printf((l>0?"%"+l:"%")+"s%s%n","",(n%3<1?"Fizz":"")+(n%5<1?"Buzz":n%3<1?"":n)))l="####%'##)+$-&'/()1*57$'9;&=()?*)A#EG$%IK+M%&O)*Q,U#".charAt(n++)-35;}

Essayez-le en ligne!

Crédits

Olivier Grégoire
la source
1

Haskell , 190 187 186 178 178 176 octets

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

Essayez-le en ligne!

La version légèrement plus lisible (et annotée):

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

Edit: j'ai fini par intégrer certaines fonctions dans la version golfée pour économiser plus d'octets.

Cristian Lupascu
la source
@Laikoni Droite. Fixé.
Cristian Lupascu
1

Jstx , 122 octets

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

Essayez-le en ligne!

Quantum64
la source