Wie bin ich zu diesem FizzBuzz gekommen?

21

FizzBuzz ist so einfach, dass Sie es wahrscheinlich rückwärts machen können. In dieser Herausforderung erhalten Sie die Länge der FizzBuzz-Zeichenfolge und müssen die positive Ganzzahl angeben, die diese Zeichenfolge erzeugt hat.

Beschreibung

Um dies aufzuschlüsseln, ein FizzBuzz-String für n wird vom folgenden Algorithmus generiert.

Beginnen Sie mit einem leeren String und für jeden i=1..n(inklusive):

  1. Wenn dies idurch 3und durch teilbar ist 5, hängen Sie es FizzBuzzan die Zeichenfolge an.
  2. If iist nur durch 3Append teilbar Fizz.
  3. If iist nur durch 5Append teilbar Buzz.
  4. Wenn idurch keine teilbar ist, hängen Sie die Dezimalrepräsentation von an i.

Zum Beispiel FizzBuzz(15)ist das folgende:

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

Sie werden gegeben Length(FizzBuzz(n))und müssen bestimmen n. Sie können davon ausgehen, dass die Eingabe positiv ist und immer der Länge einer FizzBuzz-Zeichenfolge entspricht.

Regeln

Ihre Lösung kann ein vollständiges Programm oder eine Funktionsdefinition in einer beliebigen Standardsprache sein. Ihr Programm / Ihre Funktion kann Argumente aufnehmen und Antworten auf jede übliche Weise zurückgeben . Standardlücken sind verboten.

Sie können davon ausgehen, dass die Eingabe positiv und gültig ist (beschreibt die Länge einiger FizzBuzz-Zeichenfolgen) und kleiner als die größte in Ihrer Sprache nativ darstellbare Ganzzahl ist.

Dies ist Codegolf, also gewinnt die kürzeste Anzahl an Bytes.

Beispiele

Hier sind einige Beispielfälle

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

Bearbeiten

Letzter Testfall behoben. Vielen Dank @SteadyBox.

walpen
quelle
Argh! Ich habe versucht, eine Rekursion
durchzuführen,
Verwandte . Verwandte .
Digital Trauma
3
@Toto Wie ist das ein Duplikat?
AdmBorkBork
1
@Toto Dies ist überhaupt kein Duplikat. Vielleicht sollten Sie nachlesen, was es bedeutet, ein Duplikat zu sein.
mbomb007

Antworten:

8

Jelly ,  16 bis  14 Bytes

2 Byte, die mit neueren Sprachfunktionen )für µ€und Äfür gespeichert wurden+\

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

Probieren Sie es online! oder sehen Sie die Testfälle .

Wie?

Erstellt eine Liste der Längen aller Elemente von 1bis zur Eingabe, verringert sich durch Addition und findet dann den einbasierten Index der Eingabe in der Liste. (Dies bedeutet auch, dass eine ungültige Eingabe zu 0"Nicht in Liste" führt.)

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
quelle
11

C 81 78 Bytes

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 Bytes, wenn Sie nichts dagegen haben, nach doubleund zurück zu konvertieren :

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
quelle
Ist "return i" überhaupt erforderlich, wenn "i" eine globale Variable ist? -) Und Sie könnten diesen langen snprintf-Aufruf durch ein log10 (i) +1 ersetzen, wenn dies kompiliert und zulässig ist ... Es hat bei mir funktioniert gcc-lm
Rennex
@Rennex Das return i;wird benötigt, da dies eine allgemein akzeptierte Methode für die Ausgabe in Code Golf ist, während nur das Ändern einer globalen Variablen dies nicht ist. Ich habe überlegt, es zu verwenden log10(i)+1, aber ich dachte, es könnte einige Probleme verursachen, weil es in double und back konvertiert wird (z. B. pow(i)ist nicht zuverlässig mit ganzen Zahlen). Es scheint jetzt aber, dass es gut für alle positiven Werte funktioniert, die eine intDose darstellen kann, also könnte ich es wahrscheinlich verwenden. (Bei Werten, die größer sind als ein einfacher Wert int, schlägt dies manchmal fehl, aber das spielt hier keine Rolle.)
Steadybox
Hmm, OK. Ich bin neu in diesem Code Golf, aber ich habe mir den Regel-Link in der Frage angesehen und es heißt "Funktionen können ausgegeben werden, indem ihre Argumente geändert werden oder wenn sie in Argumente geschrieben werden". Bedeutet das nicht, dass mindestens ein Ergebniszeigerargument verwendet werden könnte?
Rennex
@Rennex Ja, ich denke, ich könnte das nals Zeiger nehmen und dann nur den Wert ändern, auf den es am Ende zeigt, aber das würde mehr Code auf der Aufrufseite erfordern, um den Wert drucken zu können, so wie es sich anfühlt Ein bisschen wie Betrug für mich.
Steadybox
6

MATL , 31 28 27 Bytes

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

Probieren Sie es online!

Erläuterung

`        % 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
quelle
4

Mathematica, 67 Bytes

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

Dies ist sowohl schneller als auch kürzer als meine ursprüngliche Lösung:

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

oder mein verzweifelter Versuch, es zu verkürzen:

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

Erläuterung

Die Standardschleife For, die nbis zum Inkrementieren verwendet s := Length(FizzBuzz(n))wird, entspricht mindestens der Eingabe #. Das einzig interessante ist, wie ich die Länge des (n+1)-ten Terms der FizzBuzz-Sequenz berechne

                ++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
Genisis
quelle
3

MATL, 31 30 28 Bytes

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

Verwendet die gleiche Idee wie Jonathan Allens Jelly-Lösung.

Probieren Sie es auf matl.suever.net !

B. Mehta
quelle
Jetzt bis 28! : -Ich denke, unsere Ansätze sind jetzt ähnlicher
Luis Mendo
Ah, gute Arbeit! Ja, sieht so aus :)
B. Mehta
3

Java 8, 100 97 Bytes

Golf gespielt:

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

Ungolfed:

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

Ausgabe:

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

quelle
2

JavaScript (ES6), 62.57 Byte

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

Testfälle

Arnauld
quelle
Alternativer Ausdruck mit der gleichen Länge: (!(++k%3)+!(k%5)<<2||`${k}`.length).
Neil
2

Javascript (ES6), 56 Byte

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
quelle
2

Python 3, 78 Bytes

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

Rekursive Funktion. Muss das Rekursionslimit für alle Ergebnisse über 1000 erhöht werden.

Erläuterung:

# 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))))
Triggernometrie
quelle
1

Python, 93 Bytes

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
quelle
1

k, 33 Bytes

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

Kurze (python-ish) Erklärung:

{                                } / 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

Beispiel mit 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
quelle
Willkommen bei Programming Puzzles & Code Golf! Nur damit Sie wissen, wurde die Downvote automatisch vom Community-Benutzer abgegeben, als die Antwort bearbeitet wurde. Ich halte das für einen Bug .
Dennis
1

Ruby, 69 66 Bytes

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

Ursprünglich habe ich die verschachtelte Monstrosität von ternären Operatoren vermieden und bin auf 69 Bytes heruntergekommen:

->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
quelle
1

Java 8, 95 93 Bytes

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

Dies ist die optimierte Version der Antwort von @ Snowman

Roman Gräf
quelle
Dies gibt falsche Ergebnisse für mich in den letzten beiden Testfällen zurück: 75 anstelle von 100 und 686 anstelle von 1001.
1

Groovy, 76 Bytes

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

Meistens die gleiche Antwort wie bei @ Snowman , verwendet jedoch einige groovige Magie / Unterschiede, um die Anzahl der Bytes zu verringern.

TheJizel
quelle
0

Perl 6 , 55 52 Bytes

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

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

Probieren Sie es online!

Wie es funktioniert

{                                                  }  # 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
quelle
0

Japt , 20 Bytes

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

Versuch es

@µ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
Zottelig
quelle
0

05AB1E , 17 Bytes

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

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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
quelle