¿Cómo terminé con este FizzBuzz?

21

FizzBuzz es tan simple, apuesto a que puedes hacerlo al revés. En este desafío, se le dará la longitud de la cadena FizzBuzz y deberá dar el entero positivo que produjo esa cadena.

Descripción

Para desglosar esto, una cadena FizzBuzz para n se genera el siguiente algoritmo.

Comience con una cadena vacía y, para cada i=1..n(inclusive):

  1. Si ies divisible por 3y por 5, anexados FizzBuzza la cadena.
  2. Si ies simplemente divisible por 3agregar Fizz.
  3. Si ies simplemente divisible por 5agregar Buzz.
  4. Si ies divisible por ninguno de los dos, agregue la representación decimal de i.

Entonces, por ejemplo, FizzBuzz(15)es el siguiente:

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

Se le dará Length(FizzBuzz(n))y debe determinar n. Puede suponer que la entrada es positiva y siempre tendrá la longitud de una cadena de FizzBuzz.

Reglas

Su solución puede ser un programa completo o una definición de función en cualquier lenguaje estándar aceptable. Su programa / función puede tomar argumentos y devolver respuestas de cualquier manera estándar aceptada . Las lagunas estándar están prohibidas.

Puede suponer que la entrada es positiva y válida (describe la longitud de alguna cadena de FizzBuzz) y es más pequeña que el entero más grande representable de forma nativa en su idioma.

Este es el código de golf, por lo que el conteo de bytes más corto gana.

Ejemplos

Aquí hay algunos casos de ejemplo

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

Editar

Se corrigió el último caso de prueba. Gracias @SteadyBox.

Walpen
fuente
Argh! Intenté hacer recursión pero mis números eran demasiado grandes ...
0WJYxW9FMN
Relacionados . Relacionados .
Trauma digital
3
@Toto ¿Cómo es esto un duplicado?
AdmBorkBork
1
@Toto Esto no es en absoluto un duplicado. Tal vez deberías leer sobre lo que significa ser duplicado.
mbomb007

Respuestas:

8

Jalea ,  16  14 bytes

2 bytes guardados con funciones de idioma más recientes )para µ€y Äpara+\

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

Pruébalo en línea! o ver los casos de prueba .

¿Cómo?

Crea una lista de las longitudes de cada elemento desde 1la entrada, la reduce por adición y luego encuentra el índice basado en uno de la entrada en la lista. (Esto también significa que una entrada no válida da como resultado 0"no en la lista").

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
fuente
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 si no te importa convertir doubley volver:

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
fuente
¿Incluso se requiere "return i" cuando "i" es una variable global? gcc -lm
Rennex
@Rennex The return i;es necesario, porque esa es una forma estándar aceptada de generar en el golf de código, mientras que solo modificar una variable global no lo es. Pensé en usar log10(i)+1, pero pensé que podría causar algunos problemas debido a la conversión a doble y viceversa (por ejemplo, pow(i)no es confiable con enteros). Ahora parece que funciona bien para todos los valores positivos que intpuede representar, por lo que probablemente podría usarlo. (Con valores mayores que los que intpuede contener un simple , a veces falla, pero eso no importa aquí.)
Steadybox
Mmm, ok. Soy nuevo en este código de golf, pero miré el enlace de reglas en la pregunta, y dice "Las funciones pueden salir modificando sus argumentos o escribiendo argumentos". ¿No significa eso que al menos podría utilizarse un argumento puntero de resultado?
Rennex
@Rennex Sí, supongo que podría tomarlo ncomo un puntero y luego modificar el valor al que apunta al final, pero eso requeriría más código en el sitio de la llamada para poder imprimir el valor, por lo que parece un poco como engañarme
Steadybox
6

MATL , 31 28 27 bytes

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

Pruébalo en línea!

Explicación

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

Mathematica, 67 bytes

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

Esto es más rápido y más corto que mi solución inicial:

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

o mi intento desesperado de acortarlo:

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

Explicación

ForBucle estándar que aumenta nhasta que s := Length(FizzBuzz(n))es al menos igual a la entrada #. Lo único interesante es cómo calculo la longitud del (n+1)enésimo término de la secuencia 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
fuente
3

MATL, 31 30 28 bytes

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

Utiliza la misma idea que la solución Jelly de Jonathan Allen.

¡Pruébalo en matl.suever.net !

B. Mehta
fuente
¡Hasta 28 ahora! : -PI creo que nuestros enfoques son más similares ahora
Luis Mendo
Ah, buen trabajo! Sí, parece :)
B. Mehta
3

Java 8, 100 97 bytes

Golfizado:

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

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

Salida:

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

fuente
2

JavaScript (ES6), 62 57 bytes

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

Casos de prueba

Arnauld
fuente
Expresión alternativa con la misma longitud: (!(++k%3)+!(k%5)<<2||`${k}`.length).
Neil
2

Javascript (ES6), 56 bytes

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

Función recursiva. Necesitará aumentar el límite de recursividad para cualquier resultado superior a 1000.

Explicación:

# 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))))
Triggernometry
fuente
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
usuario65823
fuente
1

k, 33 bytes

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

Breve explicación (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

Ejemplo usando 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
fuente
¡Bienvenido a Programming Puzzles & Code Golf! Para que lo sepas, el usuario de la comunidad emitió automáticamente el voto negativo cuando se editó la respuesta. Considero que esto es un error .
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}

Originalmente, estaba evitando la monstruosidad del operador ternario anidado y obtuve 69 bytes:

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

Esta es la versión optimizada de la respuesta de @ Snowman

Roman Gräf
fuente
Esto me devuelve resultados incorrectos en los dos casos de prueba finales: 75 en lugar de 100 y 686 en lugar de 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;}

Principalmente lo mismo que la respuesta de @ Snowman , pero usa algunas magias / diferencias Groovy para reducir el conteo de bytes.

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

Pruébalo en línea!

Cómo funciona

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

Japt , 20 bytes

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

Intentalo

@µ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
Lanudo
fuente
0

05AB1E , 17 bytes

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

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

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
fuente