Как я закончил с этим 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.


Argh! Я пытался сделать рекурсию, но мои цифры были слишком большими ...
0WJYxW9FMN


3
@ Тото Как это дубликат?
AdmBorkBork

1
@ Тото Это совсем не дубликат. Может быть, вы должны прочитать о том, что значит быть дубликатом.
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
-lm

@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

Mathematica, 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

Использует ту же идею, что и решение Jonathan Allen's Jelly.

Попробуйте это на matl.suever.net !


До 28 сейчас! : -По-моему, сейчас наши подходы более похожи,
Луис Мендо,

Ах, хорошая работа! Да, похоже на это :)
Б. Мехта

3

Java 8, 100 97 байт

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

Выход:

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

Python 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

Python, 93 байта

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

к, 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

Добро пожаловать в Программирование Пазлов и Code Golf! Точно так же, вы знаете, что пользователь сообщества автоматически отбрасывал отрицательный ответ при редактировании ответа. Я считаю это ошибкой .
Деннис


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

По большей части совпадает с ответом @ Snowman , но использует некоторую магию / различия 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.