Bagaimana saya bisa berakhir dengan FizzBuzz ini?

21

FizzBuzz sangat sederhana, bertaruh Anda bisa melakukannya mundur. Dalam tantangan ini, Anda akan diberikan panjang string FizzBuzz dan harus memberikan bilangan bulat positif yang menghasilkan string itu.

Deskripsi

Untuk memecah ini, string FizzBuzz untuk ndihasilkan oleh algoritma berikut.

Mulai dengan string kosong dan, untuk setiap i=1..n(inklusif):

  1. Jika idibagi oleh 3dan oleh 5, tambahkan FizzBuzzke string.
  2. Jika ihanya dapat dibagi oleh 3append Fizz.
  3. Jika ihanya dapat dibagi oleh 5append Buzz.
  4. Jika itidak dapat dibagi oleh keduanya, tambahkan representasi desimal dari i.

Jadi misalnya FizzBuzz(15)adalah sebagai berikut:

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

Anda akan diberikan Length(FizzBuzz(n))dan harus menentukan n. Anda dapat mengasumsikan bahwa inputnya positif dan akan selalu menjadi panjang dari beberapa string FizzBuzz.

Aturan

Solusi Anda dapat berupa program lengkap atau definisi fungsi dalam bahasa apa pun yang dapat diterima secara standar. Program / fungsi Anda dapat menerima argumen dan mengembalikan jawaban dengan cara apa pun yang diterima secara standar . Celah standar dilarang.

Anda dapat mengasumsikan bahwa inputnya positif dan valid (menggambarkan panjang beberapa string FizzBuzz) dan lebih kecil dari integer terbesar yang dapat diwakili secara asli dalam bahasa Anda.

Ini adalah kode golf, jadi byte-count paling pendek menang.

Contohnya

Berikut adalah beberapa contoh kasus

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

Edit

Memperbaiki kasus tes terakhir. Terima kasih @SteadyBox.

walpen
sumber
Argh! Saya mencoba melakukan rekursi tetapi jumlah saya terlalu besar ...
0WJYxW9FMN
Terkait . Terkait .
Digital Trauma
3
@Toto Bagaimana ini duplikat?
AdmBorkBork
1
@Toto Ini sama sekali bukan duplikat. Mungkin Anda harus membaca apa artinya menjadi duplikat.
mbomb007

Jawaban:

8

Jelly ,  16  14 byte

2 byte disimpan menggunakan lebih banyak fitur bahasa terbaru )untuk µ€dan Äuntuk+\

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

Cobalah online! atau lihat kasus uji .

Bagaimana?

Buat daftar panjang setiap item mulai 1dari input, kurangi dengan penambahan, lalu temukan indeks berbasis-satu dari input dalam daftar. (Ini juga berarti input yang tidak valid menghasilkan 0, "tidak ada dalam daftar").

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
sumber
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 jika Anda tidak keberatan mengonversi ke doubledan kembali:

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
sumber
Apakah "return i" bahkan diperlukan, ketika "i" adalah variabel global? -) Dan Anda dapat mengganti panggilan snprintf panjang itu dengan log10 (i) +1, jika itu mengkompilasi dan diizinkan ... Ini bekerja untuk saya dengan gcc -lm
Rennex
@Rennex return i;Diperlukan, karena itu adalah cara yang diterima secara standar untuk menghasilkan kode golf sedangkan hanya memodifikasi variabel global tidak. Saya mempertimbangkan untuk menggunakan log10(i)+1, tetapi saya pikir itu mungkin menyebabkan beberapa masalah karena konversi menjadi ganda dan kembali (misalnya pow(i)tidak dapat diandalkan dengan bilangan bulat). Tampaknya sekarang berfungsi dengan baik untuk semua nilai positif yang intdapat diwakili, jadi saya mungkin bisa menggunakannya. (Dengan nilai-nilai yang lebih besar dari yang intbisa ditahan, kadang-kadang gagal, tapi itu tidak masalah di sini.)
Steadybox
Hmm baiklah. Saya baru mengenal golf kode ini, tetapi saya melihat tautan aturan dalam pertanyaan, dan dikatakan "Fungsi dapat ditampilkan dengan mengubah argumen mereka atau menulis ke argumen". Bukankah itu berarti bahwa setidaknya argumen pointer hasil dapat digunakan?
Rennex
@Rennex Ya, saya kira saya bisa menerima nsebagai penunjuk dan kemudian hanya mengubah nilai yang ditunjuknya di akhir, tetapi itu akan membutuhkan lebih banyak kode di situs panggilan agar dapat mencetak nilai, jadi rasanya sedikit seperti menipu saya.
Steadybox
6

MATL , 31 28 27 byte

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

Cobalah online!

Penjelasan

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

Mathematica, 67 byte

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

Ini lebih cepat dan lebih pendek dari solusi awal saya:

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

atau upaya putus asa saya untuk mempersingkat:

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

Penjelasan

ForLoop standar yang bertambah nhingga s := Length(FizzBuzz(n))setidaknya sama dengan input #. Satu-satunya hal yang menarik adalah bagaimana saya menghitung panjang (n+1)jangka waktu -th dari urutan 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
sumber
3

MATL, 31 30 28 byte

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

Menggunakan ide yang sama dengan solusi Jelly Jonathan Allen.

Cobalah di matl.suever.net !

B. Mehta
sumber
Turun ke 28 sekarang! : -PI pikir pendekatan kami lebih mirip sekarang
Luis Mendo
Ah, kerja bagus! Ya, kelihatannya seperti ini :)
B. Mehta
3

Java 8, 100 97 byte

Golf:

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

Tidak Disatukan:

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

Keluaran:

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

sumber
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

Uji kasus

Arnauld
sumber
Ekspresi alternatif dengan panjang yang sama: (!(++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>

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

Fungsi rekursif. Perlu batas rekursi ditingkatkan untuk hasil di atas 1000.

Penjelasan:

# 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))))
Triggernometri
sumber
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
pengguna65823
sumber
1

k, 33 byte

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

Penjelasan singkat (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

Contoh menggunakan 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
sumber
Selamat Datang di Programming Puzzles & Code Golf! Asal tahu saja, downvote dilakukan secara otomatis oleh pengguna Komunitas ketika jawabannya diedit. Saya menganggap ini sebagai bug .
Dennis
1

dc , 76 70 byte

?sa0dsbsc[lc4+sc]sh[lbZ+sc]so[lcdlb1+ddsb3%0=h5%0=hlc=olcla!=y]dsyxlbp

Cobalah online!

R. Kap
sumber
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}

Awalnya, saya menghindari monstrositas operator ternary bersarang dan turun ke 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}
Rennex
sumber
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;}

Ini adalah versi optimal dari jawaban Snowman

Roman Gräf
sumber
Ini mengembalikan hasil yang salah bagi saya pada dua kasus uji terakhir: 75 bukannya 100, dan 686 bukannya 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;}

Sebagian besar sama dengan jawaban @ Snowman , tetapi menggunakan beberapa sihir / perbedaan Groovy untuk mengurangi jumlah byte.

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

Cobalah online!

Bagaimana itu bekerja

{                                                  }  # 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.
seseorang
sumber
0

Japt , 20 byte

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

Cobalah

@µ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
Shaggy
sumber
0

Perl 5 -p , 48 byte

$\++;($_-=4*(!($\%3)+!($\%5))||length$\)&&redo}{

Cobalah online!

Xcali
sumber
0

C (gcc) , 68 byte, stdout-pamming

  • Terima kasih kepada H.PWiz untuk pendekatan ini, menghemat enam byte.
f(n,j,r){for(r=j=0;!r;r=!n*j)n-=++j%3?j%5?printf("%d",j):4:j%5?4:8;}

Cobalah online!


C (gcc) , 74 byte

f(n,j,r){for(r=j=0;!r;r=!n*j)n-=++j%3?j%5?snprintf(0,0,"%d",j):4:j%5?4:8;}

Cobalah online!

Jonathan Frech
sumber
0

05AB1E , 17 byte

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

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

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
sumber