Come sono finito con questo FizzBuzz?


21

FizzBuzz è così semplice, scommetto che puoi farlo all'indietro. In questa sfida, ti verrà data la lunghezza della stringa FizzBuzz e dovrai fornire il numero intero positivo che ha prodotto quella stringa.

Descrizione

Per scomporlo, una stringa FizzBuzz per nviene generata dal seguente algoritmo.

Inizia con una stringa vuota e, per ogni i=1..n(incluso):

  1. Se iè divisibile per 3e 5, aggiungi FizzBuzzalla stringa.
  2. Se iè solo divisibile per 3append Fizz.
  3. Se iè solo divisibile per 5append Buzz.
  4. Se non iè divisibile per nessuno dei due, aggiungi la rappresentazione decimale di i.

Quindi ad esempio FizzBuzz(15)è il seguente:

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

Ti verrà dato Length(FizzBuzz(n))e devi determinare n. Si può presumere che l'ingresso sia positivo e sarà sempre la lunghezza di una stringa FizzBuzz.

Regole

La soluzione può essere un programma completo o una definizione di funzione in qualsiasi linguaggio accettabile standard. Il tuo programma / funzione può accettare argomenti e restituire risposte in qualsiasi modo accettato normalmente . Sono vietate le scappatoie standard.

Si può presumere che l'input sia positivo e valido (descrive la lunghezza di una stringa FizzBuzz) ed è più piccolo dell'intero più grande rappresentabile nativamente nella propria lingua.

Questo è il golf del codice, quindi vince il conteggio dei byte più breve.

Esempi

Ecco alcuni esempi di casi

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

modificare

Risolto l'ultimo caso di prova. Grazie @SteadyBox.


Argh! Ho provato a fare la ricorsione, ma i miei numeri erano troppo grandi ...
0WJYxW9FMN


3
@Toto Come è un duplicato?
AdmBorkBork

1
@Toto Questo non è affatto un duplicato. Forse dovresti leggere su cosa significa essere un duplicato.
mbomb007,

Risposte:


8

Gelatina ,  16  14 byte

2 byte salvati utilizzando le funzionalità linguistiche più recenti )perµ€ e Äper+\

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

Provalo online! o vedere i casi di test .

Come?

Crea un elenco delle lunghezze di ogni elemento 1dall'input, riduce per addizione e quindi trova l'indice a base singola dell'input nell'elenco. (Ciò significa anche che si ottiene un input non valido 0, "non nell'elenco").

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)

11

C, 81 78 byte

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 byte se non ti dispiace convertire doublee tornare indietro:

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

"Return i" è richiesto anche quando "i" è una variabile globale? -) E potresti sostituire quella lunga chiamata snprintf con un log10 (i) +1, se quello si compila e è permesso ... Ha funzionato per me con gcc -lm
Rennex,

@Rennex return i;È necessario, perché questo è un modo standardizzato di output nel codice golf, mentre la modifica di una variabile globale non lo è. Ho preso in considerazione l'utilizzo log10(i)+1, ma ho pensato che potrebbe causare alcuni problemi a causa della conversione in double e back (ad esempio, pow(i)non è affidabile con i numeri interi). Sembra ora che funzioni bene per tutti i valori positivi che un intpuò rappresentare, quindi probabilmente potrei usarlo. (Con valori maggiori di quelli che un semplice intpuò contenere, a volte fallisce, ma non importa qui.)
Steadybox

Hmm va bene. Sono nuovo di questo codice golf, ma ho guardato il link delle regole nella domanda, e dice "Le funzioni possono essere emesse modificando i loro argomenti o scrivendo su argomenti". Ciò non significa che potrebbe essere usato almeno un argomento puntatore al risultato?
Rennex,

@Rennex Sì, immagino di poter prendere nin come puntatore e quindi modificare il valore che punta alla fine, ma ciò richiederebbe più codice nel sito di chiamata per poter stampare il valore, quindi sembra un po 'come tradirmi.
Steadybox,

6

MATL , 31 28 27 byte

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

Provalo online!

Spiegazione

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

4

Mathematica, 67 byte

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

Questo è sia più veloce che più breve della mia soluzione iniziale:

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

o il mio disperato tentativo di accorciarlo:

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

Spiegazione

ForCiclo standard che aumenta nfino s := Length(FizzBuzz(n))a quando non è almeno uguale all'ingresso #. L'unico bit interessante è il modo in cui calcolo la lunghezza del (n+1)termine della sequenza 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

3

MATL, 31 30 28 byte

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

Utilizza la stessa idea della soluzione Jelly di Jonathan Allen.

Provalo su matl.suever.net !


Fino a 28 ora! : -PI penso che i nostri approcci siano più simili ora
Luis Mendo,

Ah, ottimo lavoro! Sì, sembra così :)
B. Mehta,

3

Java 8, 100 97 byte

golfed:

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

Produzione:

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

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

Casi test


Espressione alternativa con la stessa lunghezza: (!(++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>


2

Python 3, 78 byte

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

Funzione ricorsiva. Sarà necessario aumentare il limite di ricorsione per qualsiasi risultato superiore a 1000.

Spiegazione:

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

1

Python, 93 byte

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

1

k, 33 byte

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

Breve spiegazione (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

Esempio con 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

Benvenuto in Programmazione di puzzle e codice golf! Proprio per questo sai, il downvote è stato lanciato automaticamente dall'utente della Community quando la risposta è stata modificata. Lo considero un bug .
Dennis,


1

Rubino, 69 66 byte

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

Inizialmente, evitavo la mostruosità dell'operatore ternario annidato e scendevo a 69 byte:

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

1

Java 8, 95 93 byte

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

Questa è la versione ottimizzata della risposta di @ Snowman


Ciò restituisce risultati errati per me negli ultimi due casi di test: 75 anziché 100 e 686 anziché 1001.

1

Groovy, 76 byte

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

Principalmente uguale alla risposta di @ Snowman , ma usa alcune magie / differenze Groovy per ridurre il conteggio dei byte.


0

Perl 6 , 55 52 byte

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

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

Provalo online!

Come funziona

{                                                  }  # 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.

0

Japt , 20 byte

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

Provalo

@µ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



0

05AB1E , 17 byte

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

Provalo online o verifica tutti i casi di test .

Spiegazione:

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.