Як я закінчився цим FizzBuzz?


21

FizzBuzz настільки простий, ставка, що ви можете це зробити назад. У цьому виклику вам буде задана довжина рядка FizzBuzz і ви повинні дати додатне ціле число, яке створило цей рядок.

Опис

Щоб розбити це, рядок FizzBuzz для nгенерується за допомогою наступного алгоритму.

Почніть з порожнього рядка і для кожного i=1..n(включно):

  1. Якщо iділиться на 3і на 5, додайте FizzBuzzдо рядка.
  2. Якщо iпросто ділиться 3додаванням Fizz.
  3. Якщо iпросто ділиться 5додаванням Buzz.
  4. Якщо iне ділиться на жодне, додайте десяткове представлення i.

Так, наприклад FizzBuzz(15), наступне:

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

Вам дадуть Length(FizzBuzz(n))і повинні визначитись n. Ви можете припустити, що введення є позитивним і завжди буде довжиною деякої строки FizzBuzz.

Правила

Ваше рішення може мати повну програму чи визначення функції будь-якою стандартно прийнятною мовою. Ваша програма / функція може приймати аргументи і повертати відповіді будь-яким стандартно прийнятим способом . Стандартні лазівки заборонені.

Ви можете припустити, що введення є позитивним та дійсним (описує довжину деякого рядка FizzBuzz) і менше, ніж найбільше ціле число, яке може бути представлене на вашій мові.

Це кодовий гольф, тому найкоротші виграші в байті.

Приклади

Ось кілька прикладів випадків

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

Редагувати

Виправлений останній тестовий випадок. Дякуємо @SteadyBox.


Арг! Я спробував зробити рекурсію, але моє число було занадто великим ...
0WJYxW9FMN


3
@Toto Як це дублікат?
AdmBorkBork

1
@Toto Це зовсім не дублікат. Можливо, вам слід прочитати, що означає дублікат.
mbomb007

Відповіді:


8

Желе ,  16  14 байт

2 байти, збережені за допомогою новіших мовних функцій )для µ€та Äдля+\

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

Спробуйте в Інтернеті! або переглянути тестові приклади .

Як?

Створює список довжин кожного елемента від 1введення, зменшує додавання і потім знаходить в списку єдиний індекс введення. (Це також означає, що недійсний вхід призводить до 0"не в списку").

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 байт

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 байт, якщо ви не проти перетворитись на doubleта назад:

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", коли "i" є глобальною змінною? -) І ви можете замінити цей довгий дзвінок snprintf на log10 (i) +1, якщо це компілюється і дозволено ... Це працювало для мене з gcc -lm
Rennex

@Rennex return i;Потрібно, тому що це стандартно прийнятий спосіб виводу в гольф коду, тоді як лише модифікація глобальної змінної не є. Я розглядав можливість використання log10(i)+1, але вважав, що це може викликати деякі проблеми через перетворення в подвійний і зворотний (наприклад pow(i), не є надійним для цілих чисел). Зараз здається, що він чудово працює для всіх позитивних значень, які intможе представляти, тому я, ймовірно, міг би його використовувати. (Зі значеннями, що перевищують просту int, вона інколи не спрацьовує, але це не має значення.)
Steadybox

Хм, добре. Я новачок у цьому коді гольфу, але я переглянув посилання на правила у питанні, і там написано: "Функції можуть виводитись, змінюючи свої аргументи або записуючи аргументи". Чи це не означає, що принаймні аргумент вказівника може бути використаний?
Rennex

@Rennex Так, я думаю, я міг би взяти nв якості вказівника, а потім просто змінити значення, на яке вказує в кінці, але це вимагатиме більше коду на сайті виклику, щоб мати можливість надрукувати значення, так що це відчувається трохи схоже на обман мені.
Steadybox

6

MATL , 31 28 27 байт

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

Спробуйте в Інтернеті!

Пояснення

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

Математика, 67 байт

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

Це і швидше, і коротше, ніж моє початкове рішення:

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

або моя відчайдушна спроба скоротити це:

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

Пояснення

Стандартний Forцикл, який збільшується nдо тих пір s := Length(FizzBuzz(n)), як мінімум, дорівнює вхідному #. Єдиний цікавий біт - це те, як я обчислюю тривалість (n+1)-го терміну послідовності 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 байт

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

Використовується та ж ідея, що і рішення Джонатана Аллена в желе.

Спробуйте це на matl.suever.net !


Зараз до 28! : - Я думаю, зараз наші підходи
схожіші

Ах, гарна робота! Так, схоже на це :)
Б. Мехта

3

Java 8, 100 97 байт

Гольф:

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

Безголівки:

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

Вихід:

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 байт

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

Тестові кейси


Альтернативне вираз з тією ж довжиною: (!(++k%3)+!(k%5)<<2||`${k}`.length).
Ніл

2

Javascript (ES6), 56 байт

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

Пітон 3, 78 байт

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

Рекурсивна функція. Буде потрібно обмеження рекурсії, збільшене для будь-якого результату вище 1000.

Пояснення:

# 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

k, 33 байти

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

Коротке пояснення (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

Приклад використання 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

Ласкаво просимо до головоломки програмування та коду для гольфу! Тільки щоб ви знали, користувач спільноти автоматично передав голосову заяву під час редагування відповіді. Я вважаю це помилкою .
Денніс


1

Рубі, 69 66 байт

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

Спочатку, я уникав вкладеної трехкомпонентного оператора жахливості і отримав до 69 байт:

->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 байт

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

Це оптимізована версія відповіді @ Snowman


Це повертає невірні результати для двох останніх тестових випадків: 75 замість 100 та 686 замість 1001.

1

Groovy, 76 байт

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

В основному те саме, що відповідь @ Сніговика , але використовує деякі магії / відмінності Groovy, щоб зменшити кількість байтів.


0

Perl 6 , 55 52 байти

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

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

Спробуйте в Інтернеті!

Як це працює

{                                                  }  # 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 байт

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

Спробуй це

@µ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 байт

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

Спробуйте в Інтернеті чи перевірте всі тестові випадки .

Пояснення:

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.