Comment en suis-je arrivé à ce FizzBuzz?

21

FizzBuzz est si simple, je parie que vous pouvez le faire à l'envers. Dans ce défi, vous recevrez la longueur de la chaîne FizzBuzz et devez donner l'entier positif qui a produit cette chaîne.

La description

Pour décomposer cela, une chaîne FizzBuzz pour nest générée par l'algorithme suivant.

Commencez avec une chaîne vide et, pour chaque i=1..n(inclus):

  1. Si iest divisible par 3et par 5, ajoutez FizzBuzzà la chaîne.
  2. Si iest juste divisible par 3ajouter Fizz.
  3. Si iest juste divisible par 5ajouter Buzz.
  4. Si in'est divisible par aucun, ajoutez la représentation décimale de i.

Par exemple, FizzBuzz(15)voici ce qui suit:

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

On vous donnera Length(FizzBuzz(n))et vous devrez déterminer n. Vous pouvez supposer que l'entrée est positive et sera toujours la longueur d'une chaîne FizzBuzz.

Règles

Votre solution peut être un programme complet ou une définition de fonction dans n'importe quelle langue standard acceptable. Votre programme / fonction peut accepter des arguments et renvoyer des réponses de toute manière standard acceptée . Les failles standard sont interdites.

Vous pouvez supposer que l'entrée est positive et valide (décrit la longueur d'une chaîne FizzBuzz) et est plus petite que le plus grand entier représentable nativement dans votre langue.

C'est le golf par code, donc le nombre d'octets le plus court l'emporte.

Exemples

Voici quelques exemples de cas

Length(FizzBuzz(n)) -> n
1                   -> 1
6                   -> 3
15                  -> 6
313                 -> 100
3677                -> 1001

modifier

Correction du dernier cas de test. Merci @SteadyBox.

walpen
la source
Argh! J'ai essayé de faire la récursivité mais mes chiffres étaient trop gros ...
0WJYxW9FMN
Connexes . Connexes .
Digital Trauma
3
@Toto Comment est-ce un doublon?
AdmBorkBork du
1
@Toto Ce n'est pas du tout un doublon. Vous devriez peut-être lire ce que signifie être un doublon.
mbomb007

Réponses:

8

Gelée ,  16  14 octets

2 octets enregistrés à l'aide de fonctionnalités linguistiques plus récentes )pour µ€etÄ pour+\

3,5ḍS×4oDL$)Äi

Essayez-le en ligne!ou consultez les cas de test .

Comment?

Construit une liste des longueurs de chaque élément de 1à l'entrée, réduit par addition, puis trouve l'index à base unique de l'entrée dans la liste. (Cela signifie également qu'une entrée non valide entraîne 0«pas dans la liste»).

3,5ḍS×4oDL$)Äi - Main link: theLength
           )    - perform the chain to the left for each (€) in
                     implicit range from 1 to the input and
                     pass the result into the monadic chain (µ) to the right
3,5            - 3 paired with 5: [3,5]
   ḍ           - divides?  for a multiple of 15 [1,1]; sum = 2; times 4 = 8
    S          - sum       for a multiple of  5 [0,1]; sum = 1; times 4 = 4
     ×4        - times 4   for a multiple of  3 [1,0]; sum = 1; times 4 = 4
                           for none of those    [0,0]; sum = 0; times 4 = 0
          $    - last two links as a monad
        D      -     to decimal digit list
         L     -     length - e.g. 313 -> [3,1,3] -> 3
       o       - logical or: replace a 0 with the decimal length, keep the 4s and 8s
            Ä  - reduce with addition: e.g. [1,1,4,1, 4, 4, 1, 1, 4, 4, 2, 4, 2 ,2, 8]
                                         -> [1,2,6,7,11,15,16,17,21,25,27,31,33,35,43]
             i - index of theLength in that list (e.g. 15 is at index 6)
Jonathan Allan
la source
11

C, 81 78 octets

l,i;f(n){for(l=i=0;l<n;l+=++i%3?i%5?snprintf(0,0,"%d",i):4:i%5?4:8);return i;}

68 octets si cela ne vous dérange pas de convertir en aller double-retour:

l,i;f(n){for(l=i=0;l<n;l+=++i%3?i%5?log10(i)+1:4:i%5?4:8);return i;}
Steadybox
la source
Est-ce que "return i" est même requis, quand "i" est une variable globale? -) Et vous pouvez remplacer ce long appel snprintf par un log10 (i) +1, si cela se compile et est autorisé ... Cela a fonctionné pour moi avec gcc -lm
Rennex
@Rennex Le return i;est nécessaire, car il s'agit d'un moyen généralement accepté de sortir dans le code golf alors que seule la modification d'une variable globale ne l'est pas. J'ai envisagé d'utiliser log10(i)+1, mais j'ai pensé que cela pourrait causer des problèmes en raison de la conversion en double et en arrière (par exemple, ce pow(i)n'est pas fiable avec des entiers). Il semble maintenant que cela fonctionne bien pour toutes les valeurs positives qu'un an intpeut représenter, donc je pourrais probablement l'utiliser. (Avec des valeurs plus grandes qu'un simple intpeut contenir, il échoue parfois, mais cela n'a pas d'importance ici.)
Steadybox
Hmm, d'accord. Je suis nouveau dans ce golf de code, mais j'ai regardé le lien des règles dans la question, et il dit "Les fonctions peuvent sortir en modifiant leurs arguments ou en écrivant des arguments". Cela ne signifie-t-il pas qu'au moins un argument de pointeur de résultat pourrait être utilisé?
Rennex
@Rennex Ouais, je suppose que je pourrais prendre le npointeur et ensuite juste modifier la valeur vers laquelle il pointe à la fin, mais cela nécessiterait plus de code sur le site d'appel afin de pouvoir imprimer la valeur, donc on se sent un peu comme me tromper.
Steadybox
6

MATL , 31 28 27 octets

`@:tI5h!\XJA)VXznJ~z4*+G-}@

Essayez-le en ligne!

Explication

`        % Do...while
  @:     %   Push array [1 2 ...k], where k is iteration index
  t      %   Duplicate  
  I5h!   %   Push column vector [3; 5]
  \      %   Modulo, with broadcast. Gives 2 × k matrix
  XJ     %   Copy into clipboard J
  A      %   Row vector that contains true for columns that contain two nonzeros
  )      %   Index with that vector. This keeps numbers that are non-fizz/buzz
  V      %   Convert to string. This inserts spaces between numbers
  Xzn    %   Number of nonspace characters
  J      %   Push 2 × k matrix resulting from modulo operation again
  ~z     %   Number of zeros
  4*     %   Multiply by 4. Gives number of characters corresponding to fizz/buzz
  +      %   Add
  G-     %   Subtract input. This is the loop condition: exit if 0
}        % Finally (execute right before exiting loop)
  @      %   Push current iteration index
         % End (implicit)
         % Display (implicit)
Luis Mendo
la source
4

Mathematica, 67 octets

(For[n=s=0,s<#,s+=Tr[4Boole[{3,5}∣++n]]/. 0:>IntegerLength@n];n)&

C'est à la fois plus rapide et plus court que ma solution initiale:

1//.x_/;Sum[Tr[4Boole[{3,5}∣n]]/. 0:>IntegerLength@n,{n,x}]!=#:>x+1&

ou ma tentative désespérée de le raccourcir:

(s=0;1)//.x_/;(s+=Tr[4Boole[{3,5}∣x]]/. 0:>IntegerLength@x)!=#:>x+1&

Explication

ForBoucle standard qui s'incrémente njusqu'à ce qu'elle s := Length(FizzBuzz(n))soit au moins égale à l'entrée #. Le seul (n+1)élément intéressant est la façon dont je calcule la longueur du -ème terme de la séquence FizzBuzz

                ++n                           Preincrement n
          {3,5}∣                              Test for divisibility by 3 and 5 (returns a list)
    Boole[         ]                          Convert True to 1 and False to 0
   4                                          Multiply by 4
Tr[                 ]                         Sum
                     /.                       Replace
                        0                     0 (leading space is necessary or it thinks we are dividing by 0.0)
                         :>                   with
                           IntegerLength@n    the number of digits in n
ngenisis
la source
3

MATL, 31 30 28 octets

:tI5h!\~s4*t~b10&YlkQ*+YsG=f

Utilise la même idée que la solution Jelly de Jonathan Allen.

Essayez-le sur matl.suever.net !

B. Mehta
la source
Jusqu'à 28 maintenant! : -PI pense que nos approches sont plus similaires maintenant
Luis Mendo
Ah, bon travail! Oui, on dirait ça :)
B. Mehta
3

Java 8, 100 97 octets

Golfé:

l->{int i=0;for(String s="";s.length()<l;)s+=++i%15<1?"12345678":i%5<1||i%3<1?"1234":i;return i;}

Non golfé:

import java.util.function.*;

public class HowDidIEndUpWithThisFizzBuzz {

  public static void main(String[] args) {
    for (final int[] data : new int[][] { { 1, 1 }, { 6, 3 }, { 15, 6 },
        { 313, 100 }, { 3677, 1001 } }) {
      final int fizzBuzzLength = data[0];
      final int expected = data[1];
      final int actual = f(l -> {
        int i = 0;
        for (String s = ""; s.length() < l;) {
          s += (++i % 15 < 1 ? "12345678" : (i % 5 < 1 || i % 3 < 1 ? "1234" : i));
        }
        return i;
      } , fizzBuzzLength);
      System.out.println("Length(FizzBuzz(n)) -> " + fizzBuzzLength);
      System.out.println("Expected            -> " + expected);
      System.out.println("Actual              -> " + actual);
      System.out.println();
    }

  }

  private static int f(IntFunction<Integer> function, int fizzBuzzLength) {
    return function.apply(fizzBuzzLength);
  }
}

Sortie:

Length(FizzBuzz(n)) -> 1
Expected            -> 1
Actual              -> 1

Length(FizzBuzz(n)) -> 6
Expected            -> 3
Actual              -> 3

Length(FizzBuzz(n)) -> 15
Expected            -> 6
Actual              -> 6

Length(FizzBuzz(n)) -> 313
Expected            -> 100
Actual              -> 100

Length(FizzBuzz(n)) -> 3677
Expected            -> 1001
Actual              -> 1001

la source
2

JavaScript (ES6), 62 57 octets

f=(n,k=0)=>n?f(n-(++k%3?k%5?`${k}`.length:4:k%5?4:8),k):k

Cas de test

Arnauld
la source
Expression de remplacement de même longueur: (!(++k%3)+!(k%5)<<2||`${k}`.length).
Neil
2

Javascript (ES6), 56 octets

f=(x,s=i=0)=>s[x]?i:f(x,s+[++i%3?i%5?i:1e3:i%5?1e3:1e7])
<!-- snippet demo: -->
<input list=l oninput=console.log(f(this.value))>
<datalist id=l><option value=1><option value=6><option value=15><option value=313><option value=3677></datalist>

nderscore
la source
2

Python 3, 78 octets

f=lambda i,n=1,s=0:~-n*(s==i)or f(i,n+1,s+(4*((n%3<1)+(n%5<1))or len(str(n))))

Fonction récursive. Il faudra augmenter la limite de récursivité pour tout résultat supérieur à 1000.

Explication:

# i = length of final string
# n = current number in sequence, starting with 1
# s = length of current string, starting with 0
f=lambda i,n=1,s=0: \

# if s==1, this will evaluate to n+1, which is NOT 0, and will return
# else, it will evaluate to (n+1)*0, and trigger the second half of the OR clause
~-n*(s==i)or \

# recursively call the next iteration, with the next number in the sequence
f(i,n+1, \ 

# increase s by 4 if Fizz or Buzz, 8 if FizzBuzz, or len(n) if number
s+(4*((n%3<1)+(n%5<1))or len(str(n))))
Triggernométrie
la source
1

Python, 93 octets

def g(n,c=0,a=[4,0]):
 while n:c+=1;s=a[c%3>0]+a[c%5>0];s+=(s<1)*len(str(c));n-=s
 return c
user65823
la source
1

k, 33 octets

{1+&x=+\{(#$x;4;8)+/~3 5!'x}'1+!x}

Brève explication (python-ish):

{                                } / function(x):
                             1+!x  /   array from 1 to x, inclusive
                            '      /   for y in array:
        {                  }       /     function(y):
         (#$x;4;8)                 /       yield [ len(str(y), 4, 8 ][
                  +/~3 5!'x        /         sum([not(y mod 3), not(y mod 5)])
                                   /       ]
      +\                           /   cumulative sum of result of for loop
 1+&x=                             /   get index of x in cumulative sum, add one

Exemple utilisant kmac 2016.06.28:

 f:{1+&x=+\{(#$x;4;8)+/~3 5!'x}'1+!x}
 ,/f'1 6 15 313 3677
1 3 6 100 1001
zgrep
la source
Bienvenue sur Programmation Puzzles & Code Golf! Juste pour que vous le sachiez, le downvote a été automatiquement casté par l'utilisateur de la communauté lorsque la réponse a été modifiée. Je considère cela comme un bug .
Dennis
1

dc , 76 70 octets

?sa0dsbsc[lc4+sc]sh[lbZ+sc]so[lcdlb1+ddsb3%0=h5%0=hlc=olcla!=y]dsyxlbp

Essayez-le en ligne!

R. Kap
la source
1

Rubis, 69 66 octets

->n{i=0;(i+=1;n-=i%3>0?i%5>0?i.to_s.size: 4:i%5>0?4:8)while n>0;i}

À l'origine, j'évitais la monstruosité de l' opérateur ternaire imbriqué et je suis descendu à 69 octets:

->n{i=0;(i+=1;n-=(x=[i%3,i%5].count 0)>0?4*x:i.to_s.size)while n>0;i}
Rennex
la source
1

Java 8, 95 93 octets

l->{int j=0,i=0;for(;j<l;)j+=++i%15<1?8:i%3<1||i%5<1?4:Math.floor(Math.log10(i)+1);return i;}

Ceci est la version optimisée de la réponse de @ Snowman

Roman Gräf
la source
Cela renvoie des résultats incorrects pour moi sur les deux derniers cas de test: 75 au lieu de 100 et 686 au lieu de 1001.
1

Groovy, 76 octets

def f(n){i=0;for(s='';s.size()<n;)s+=++i%15<1?"1"*8:i%5<1||i%3<1?"1"*4:i;i;}

Généralement identique à la réponse de @ Snowman , mais utilise une certaine magie / différences Groovy pour réduire le nombre d'octets.

TheJizel
la source
0

Perl 6 , 55 52 octets

{1+first $_,:k,[\+] map {4*($_%%3+$_%%5)||.chars},1..*}

{(0,{my \i=++$;$_+(4*(i%%3+i%%5)||i.chars)}...$_)-1}

Essayez-le en ligne!

Comment ça marche

{                                                  }  # A lambda.
  0                                                   # Start with 0.
   ,{                                     }           # Use the iteration formula...
     my \i=++$;                                       #   Fetch current index.
               $_+(                      )            #   Last element plus:
                   4*(i%%3+i%%5)                      #     Fizz/Buzz/FizzBuzz length,
                                ||i.chars             #     or number length.
                                           ...$_      # ...until the input is reached.
 (                                              )-1   # Sequence length minus 1.
smls
la source
0

Japt , 20 octets

@µ35ìx_XvZÃ*4ªXìÊ}f1

Essayez-le

@µ35ìx_XvZÃ*4ªXìÊ}f1     :Implicit input of integer U
@                        :Function taking an integer X as argument
 µ                       :  Decrement U by
  35ì                    :    Digit array of 35
     x                   :    Reduce by addition
      _                  :    After passing each Z through the following function
       XvZ               :      Is X divisible by Z?
          Ã              :    End reduce
           *4            :    Multiply by 4
             ª           :    Logical OR with
              Xì         :      Digit array of X
                Ê        :      Length
                 }       :End function
                  f1     :First integer >=1 that returns a falsey value (i.e, 0) when passed through that function
Hirsute
la source
0

05AB1E , 17 octets

Lε35SÖ4*OygM}.¥sk

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

L          # Create a list in the range [1, (implicit) input]
           #  i.e. 15 → [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
 ε         # Map each value to:
  35S      #  Push 35 as digit list: [3,5]
     Ö     #  Check if the current value is divisible by these (1 if truthy; 0 if falsey)
      4*   #  Multiply both by 4
        O  #  And take the sum of that
           #   i.e. 2 → [0,0] → [0,0] → 0
           #   i.e. 9 → [1,0] → [4,0] → 4
           #   i.e. 10 → [0,1] → [0,4] → 4
           #   i.e. 15 → [1,1] → [4,4] → 8
  yg       #  Push the current value again, and pop and push it's length
           #   i.e. 2 → 1
           #   i.e. 15 → 2
  M        #  And then push the largest value on the stack
           #   i.e. 0 and 1 → 1
           #   i.e. 8 and 2 → 8
 }.¥       # After the map: undelta the list (starting from 0)
           #  i.e. [1,1,4,1,4,4,1,1,4,4,2,4,2,2,8]
           #   → [0,1,2,6,7,11,15,16,17,21,25,27,31,33,35,43] 
    sk     # Swap to get the (implicit) input, and get its 0-based index in the list
           #  i.e. 15 → 6
           # (after which the result is output implicitly)
Kevin Cruijssen
la source