Làm thế nào tôi kết thúc với FizzBuzz này?


21

FizzBuzz rất đơn giản, đặt cược bạn có thể làm điều đó ngược lại. Trong thử thách này, bạn sẽ được cung cấp độ dài của chuỗi FizzBuzz và phải đưa ra số nguyên dương tạo ra chuỗi đó.

Sự miêu tả

Để phá vỡ điều này, một chuỗi FizzBuzz cho nđược tạo bởi thuật toán sau.

Bắt đầu với một chuỗi rỗng và, cho mọi i=1..n(bao gồm):

  1. Nếu ichia hết cho 3và theo 5, nối FizzBuzzvào chuỗi.
  2. Nếu ichỉ là chia hết bằng cách 3chắp thêm Fizz.
  3. Nếu ichỉ là chia hết bằng cách 5chắp thêm Buzz.
  4. Nếu ichia hết cho cả hai, nối thêm biểu diễn thập phân của i.

Vì vậy, ví dụ như FizzBuzz(15)sau:

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

Bạn sẽ được đưa ra Length(FizzBuzz(n))và phải xác định n. Bạn có thể cho rằng đầu vào là dương và luôn luôn là độ dài của một số chuỗi FizzBuzz.

Quy tắc

Giải pháp của bạn có thể là một chương trình hoàn chỉnh hoặc một định nghĩa chức năng trong bất kỳ ngôn ngữ tiêu chuẩn nào được chấp nhận. Chương trình / chức năng của bạn có thể đưa ra các đối số và trả về các câu trả lời theo bất kỳ cách nào được chấp nhận tiêu chuẩn . Sơ hở tiêu chuẩn bị cấm.

Bạn có thể giả sử rằng đầu vào là dương và hợp lệ (mô tả độ dài của một số chuỗi FizzBuzz) và nhỏ hơn số nguyên lớn nhất có thể biểu thị nguyên gốc trong ngôn ngữ của bạn.

Đây là mã golf, vì vậy chiến thắng đếm byte ngắn nhất.

Ví dụ

Dưới đây là một số trường hợp ví dụ

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

Chỉnh sửa

Đã sửa trường hợp kiểm tra lần cuối. Cảm ơn @SteadyBox.


Argh! Tôi đã cố gắng thực hiện đệ quy nhưng số của tôi quá lớn ...
0WJYxW9FMN


3
@Toto Đây là bản sao như thế nào?
admBorkBork

1
@Toto Đây hoàn toàn không phải là một bản sao. Có lẽ bạn nên đọc lên những gì có nghĩa là một bản sao.
mbomb007

Câu trả lời:


8

Thạch ,  16  14 byte

2 byte được lưu bằng các tính năng ngôn ngữ gần đây hơn )cho µ€Ächo+\

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

Hãy thử trực tuyến! hoặc xem các trường hợp thử nghiệm .

Làm sao?

Xây dựng một danh sách độ dài của mỗi mục từ 1đầu vào, giảm bằng cách thêm và sau đó tìm chỉ mục một dựa trên đầu vào trong danh sách. (Điều này cũng có nghĩa là kết quả đầu vào không hợp lệ trong 0"không có trong danh sách").

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 nếu bạn không ngại chuyển đổi sang doublevà quay lại:

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

Là "return i" thậm chí là bắt buộc, khi "i" là biến toàn cục? -) Và bạn có thể thay thế cuộc gọi snprintf dài đó bằng log10 (i) +1, nếu điều đó biên dịch và được phép ... Nó hoạt động với tôi gcc -lm
Rennex

@Rennex Điều return i;này là cần thiết, bởi vì đó là một cách được chấp nhận tiêu chuẩn để xuất ra trong mã golf trong khi chỉ sửa đổi một biến toàn cục thì không. Tôi đã cân nhắc sử dụng log10(i)+1, nhưng tôi nghĩ nó có thể gây ra một số vấn đề vì chuyển đổi thành gấp đôi và ngược lại (ví dụ: pow(i)không đáng tin cậy với số nguyên). Bây giờ có vẻ như nó hoạt động tốt cho tất cả các giá trị tích cực mà một người intcó thể đại diện, vì vậy tôi có thể có thể sử dụng nó. (Với các giá trị lớn hơn đơn giản intcó thể giữ, đôi khi nó không thành công, nhưng điều đó không thành vấn đề ở đây.)
Steadybox 23/2/2017

Hừm, được rồi Tôi mới chơi golf mã này, nhưng tôi đã xem liên kết quy tắc trong câu hỏi và thông báo "Các hàm có thể xuất ra bằng cách sửa đổi các đối số của chúng hoặc viết ra các đối số". Điều đó không có nghĩa là ít nhất một đối số con trỏ kết quả có thể được sử dụng?
Rennex

@Rennex Vâng, tôi đoán rằng tôi có thể lấy ncon trỏ làm con trỏ và sau đó chỉ sửa đổi giá trị mà nó trỏ đến ở cuối, nhưng điều đó sẽ đòi hỏi nhiều mã hơn tại trang web cuộc gọi để có thể in giá trị, vì vậy nó cảm thấy một chút như lừa dối tôi
Steadybox

6

MATL , 31 28 27 byte

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

Hãy thử trực tuyến!

Giải trình

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

Toán học, 67 byte

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

Đây là cả nhanh hơn và ngắn hơn so với giải pháp ban đầu của tôi:

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

hoặc nỗ lực tuyệt vọng của tôi để rút ngắn nó:

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

Giải trình

ForVòng lặp tiêu chuẩn tăng ncho đến khi s := Length(FizzBuzz(n))ít nhất bằng với đầu vào #. Điều thú vị duy nhất là cách tôi tính độ dài của (n+1)thuật ngữ thứ-thứ tự của chuỗi 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

Sử dụng ý tưởng tương tự như giải pháp Jelly của Jonathan Allen.

Hãy thử nó trên matl.suever.net !


Xuống 28 ngay! : -PI nghĩ rằng cách tiếp cận của chúng tôi giống nhau hơn bây giờ
Luis Mendo

À, làm tốt lắm! Vâng, có vẻ như vậy :)
B. Mehta

3

Java 8, 100 97 byte

Chơi gôn

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

Ung dung:

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

Đầu ra:

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

Các trường hợp thử nghiệm


Biểu thức thay thế có cùng độ dài : (!(++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))))

Hàm đệ quy. Sẽ cần giới hạn đệ quy tăng cho bất kỳ kết quả nào trên 1000.

Giải trình:

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

Giải thích ngắn gọ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

Ví dụ sử dụng 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

Chào mừng bạn đến với Câu đố lập trình & Code Golf! Chỉ để bạn biết, downvote đã được người dùng Cộng đồng tự động sử dụng khi câu trả lời được chỉnh sửa. Tôi coi đây là một lỗi .
Dennis


1

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

Ban đầu, tôi đã tránh sự quái dị của toán tử ternary lồng nhau và giảm xuống còn 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;}

Đây là phiên bản tối ưu hóa câu trả lời của @ Snowman


Điều này trả về kết quả không chính xác cho tôi trong hai trường hợp thử nghiệm cuối cùng: 75 thay vì 100 và 686 thay vì 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;}

Chủ yếu giống như câu trả lời của @ Snowman , nhưng sử dụng một số phép thuật / khác biệt Groovy để cắt giảm số lượng 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}

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Thử nó

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

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.