이 FizzBuzz를 어떻게 끝냈습니까?


21

FizzBuzz는 매우 간단합니다. 거꾸로 할 수 있습니다. 이 도전에서는 FizzBuzz 문자열의 길이가 주어지며 해당 문자열을 생성 한 양의 정수를 제공해야합니다.

기술

이를 분해하기 위해 n다음 알고리즘에 의해 FizzBuzz 문자열 이 생성됩니다.

빈 문자열로 시작하고 모든 i=1..n것을 포함하여 다음을 수행하십시오.

  1. 경우 i로 나눌 3에 의해 5, APPEND FizzBuzz문자열.
  2. append i로만 나눌 수 있다면 .3Fizz
  3. append i로만 나눌 수 있다면 .5Buzz
  4. i둘 다로 나눌 수없는 경우 의 10 진수 표시를 추가하십시오 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입력에서 입력 까지 모든 항목의 길이 목록을 작성하고 추가하여 줄인 다음 목록에서 입력의 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;}

"i"가 전역 변수 일 때 "return i"가 필요한가요?-) 그리고 긴 snprintf 호출을 log10 (i) +1로 바꿀 수 있습니다. gcc -lm
Rennex

@Rennex return i;전역 변수를 수정하는 것만으로는 그렇지 않지만 코드 골프에서 출력되는 표준 적으로 허용되는 방식이기 때문에 The 가 필요합니다. 을 사용하는 것을 고려 log10(i)+1했지만 double 및 back으로 변환하여 일부 문제가 발생할 수 있다고 생각했습니다 (예 : 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증가하는 표준 루프 는 적어도 입력과 같습니다 . 유일한 재미있는 점 은 FizzBuzz 시퀀스 의- 번째 항의 길이를 계산하는 방법입니다ns := Length(FizzBuzz(n))#(n+1)

                ++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의 Jelly 솔루션과 동일한 아이디어를 사용합니다.

matl.suever.net에서 사용해보십시오 !


지금 28 세까지! : -PI는 우리의 접근 방식이 이제 더 비슷하다고 생각합니다.
Luis Mendo

아, 잘 했어! 그래, 그 것처럼 보인다 :)
B. Mehta

3

자바 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

자바 스크립트 (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).
Neil

2

자바 스크립트 (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

파이썬, 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

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

프로그래밍 퍼즐 및 코드 골프에 오신 것을 환영합니다! 알다시피, downvote는 커뮤니티 사용자가 답변을 편집 할 때 자동으로 전송되었습니다. 나는 이것이 버그라고 생각한다 .
Dennis


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

자바 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의 답변 의 최적화 된 버전입니다


마지막 두 테스트 사례에 대해 잘못된 결과가 반환됩니다. 100 대신 75, 1001 대신 686

1

그루비, 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

펄 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.