Bu FizzBuzz'a nasıl ulaştım?


21

FizzBuzz çok basittir, bahis geriye doğru yapabilirsiniz. Bu mücadelede, FizzBuzz dizesinin uzunluğu size verilecek ve bu dizgeyi üreten pozitif tamsayıyı vermelisiniz.

Açıklama

Bunu kesmek için n, aşağıdaki algoritma için bir FizzBuzz dizgisi oluşturulur.

Boş bir dizeyle başlayın ve her biri için i=1..n(dahil):

  1. Eğer ibölünemeyen bir 3tarafından 5, komuta FizzBuzzdizeye.
  2. Eğer isadece 3ek tarafından bölünebilir ise Fizz.
  3. Eğer isadece 5ek tarafından bölünebilir ise Buzz.
  4. Eğer ine ile bölünebilir, ekleme ondalık ifadesi i.

Yani örneğin FizzBuzz(15):

12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz

Size verilecek Length(FizzBuzz(n))ve belirlemelisiniz n. Girişin pozitif olduğunu ve her zaman bazı FizzBuzz dizesinin uzunluğu olacağını varsayabilirsiniz.

kurallar

Çözümünüz, standart olarak kabul edilebilir herhangi bir dilde eksiksiz bir program veya işlev tanımı olabilir. Programınız / fonksiyonunuz bağımsız değişkenleri alabilir ve standart olarak kabul edilmiş herhangi bir şekilde cevapları geri getirebilir . Standart boşluklar yasaktır.

Girişin pozitif ve geçerli olduğunu (bazı FizzBuzz dizesinin uzunluğunu açıklar) ve kendi dilinizde doğal olarak temsil edilebilecek en büyük tam sayıdan daha küçük olduğunu varsayabilirsiniz.

Bu kod golf, yani en kısa bayt sayısı kazanıyor.

Örnekler

İşte birkaç örnek vaka

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

Düzenle

Sabit son test durumu. @ SteadyBox'a teşekkür ederiz.


Ahh! Özyineleme yapmaya çalıştım ama numaralarım çok büyüktü ...
0WJYxW9FMN


3
@Toto Bu nasıl bir kopya?
AdmBorkBork

1
@Toto Bu hiç bir kopyası değil. Belki de kopya olmanın ne demek olduğunu okumalısın.
mbomb007

Yanıtlar:


8

Jöle ,  16  14 bayt

2 byte daha yeni dil özelliklerini kullanarak kaydedilen )için µ€ve Äiçin+\

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

Çevrimiçi deneyin! veya test durumlarına bakınız.

Nasıl?

Her öğenin 1girişe kadar olan uzunluklarının bir listesini oluşturur, ekleme yaparak azaltır ve ardından girişin bir temelli dizinini listede bulur. (Bu ayrıca geçersiz girişle sonuçlanır anlamına gelir.0 "listede değil" ).

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 bayt

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 bayt , dönüştürme doubleve geri alma sakıncası yoksa :

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

"İ" global bir değişken olduğunda "return i" gerekli olsa bile mi? gcc
-lm

@Rennex Bu return i;gereklidir, çünkü kod golfünde çıktı almak için standart olarak kabul edilmiş bir yöntemdir, ancak yalnızca global bir değişkeni değiştirmek değildir. Kullanmayı log10(i)+1düşündüm ama iki ya da geriye dönüştüğü için bazı sorunlara neden olabileceğini düşündüm (örneğin pow(i), tamsayılar ile güvenilir değil). Şimdi bir intkişinin temsil edebileceği tüm pozitif değerler için iyi çalıştığı anlaşılıyor , bu yüzden muhtemelen onu kullanabiliyorum. (Basit bir değerden büyük olan değerlerle int, bazen başarısız olur, ancak bu önemli değil.)
Steadybox

Hmm tamam. Bu golf kodunda yeniyim, ancak sorudaki kurallar bağlantısına baktım ve "İşlevler argümanlarını değiştirerek veya argümanları yazarak çıktı verebilir" diyor. Bu, en azından bir sonuç gösterici argümanının kullanılabileceği anlamına gelmiyor mu?
Rennex

@Rennex Evet, sanırım nbir işaretçi olarak girebilirim ve sonunda işaret ettiği değeri değiştirebilirim, ancak bu değerin basılabilmesi için çağrı sitesinde daha fazla kod gerektirir, bu yüzden hissediyor biraz da beni aldatıyor gibi.
Steadybox

6

MATL , 31 28 27 bayt

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

Çevrimiçi deneyin!

açıklama

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

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

Bu benim ilk çözümümden hem daha hızlı hem de daha kısa:

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

veya onu kısaltmak için çaresizce denemem:

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

açıklama

Girişe kadar en az Forartışa neden olan standart döngü . Tek ilginç bit, FizzBuzz dizisinin -inci teriminin uzunluğunu nasıl hesapladığım.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 bayt

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

Jonathan Allen'ın Jelly çözümü ile aynı fikri kullanır.

Matl.suever.net adresinde deneyin !


Şimdi 28'e kadar! : -PI yaklaşımlarımızın şimdi daha benzer olduğunu düşünüyorum
Luis Mendo

Ah, iyi iş! Evet, öyle gözüküyor :)
B. Mehta

3

Java 8, 100 97 bayt

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

Çıktı:

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 bayt

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

Test durumları


Aynı uzunlukta Alternatif ifade: (!(++k%3)+!(k%5)<<2||`${k}`.length).
Neil,

2

Javascript (ES6), 56 bayt

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 bayt

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

Özyinelemeli işlevi. 1000'in üzerindeki herhangi bir sonuç için özyineleme sınırının arttırılması gerekecek.

Açıklama:

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

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 bayt

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

Kısa (python-ish) açıklama:

{                                } / 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'i kullanarak örnek:

 f:{1+&x=+\{(#$x;4;8)+/~3 5!'x}'1+!x}
 ,/f'1 6 15 313 3677
1 3 6 100 1001

Programlama Bulmacaları ve Kod Golf'üne Hoş Geldiniz! Sırf bildiğiniz gibi, yanıtın düzenlenmesi durumunda, aşağı oylama Topluluk kullanıcısı tarafından otomatik olarak yayınlandı. Bunun bir hata olduğunu düşünüyorum .
Dennis,


1

Ruby, 69 66 bayt

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

Aslında, iç içe geçmiş üçlü operatör canavarlığından kaçınıyordum ve 69 bayta düştüm :

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

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

Bu @ Snowman'ın cevabının optimize edilmiş versiyonu


Bu döner son iki test durumları benim için yanlış sonuçlar: 100 yerine 75 ve 686 yerine 1001

1

Groovy, 76 bayt

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

Çoğunlukla @ Snowman'ın cevabıyla aynıdır , ancak bayt sayısını azaltmak için bazı Groovy sihir / farklılıkları kullanır.


0

Perl 6 , 55 52 bayt

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

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

Çevrimiçi deneyin!

Nasıl çalışır

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

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

Dene

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

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

Çevrimiçi deneyin ya da tüm test durumlarını doğrulayın .

Açıklama:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.