Yarım, Yarım Yarım ve Yarım


33

Aşağıdaki sayı sırasını göz önünde bulundurun:

0,12,14,34,18,38,58,78,116,316,516,716,916,1116,1316,1516,132,332,532,...

Birim aralığındaki tüm ikili fraksiyonları numaralandırır .[0,1)

(Bu mücadeleyi kolaylaştırmak için ilk eleman isteğe bağlıdır: Bunu atlayabilir ve dizinin 1/2 ile başladığını düşünebilirsiniz.)

Görev

Bir program (tam program veya bir fonksiyon) yazın ki ...

Bu davranışlardan birini seçin:

  • Giriş n, dizinin nth elemanı (0 indeksli veya 1 indeksli);
  • Giriş n, dizinin ilk n elemanlarını;
  • Hiçbir şey girmeyin, birer birer alabileceğiniz sonsuz sayı sırasını verin;

Kural

  • Programınız en azından ilk 1000 öğeyi desteklemelidir;
  • İstediğiniz gibi ondalık sayıları veya kesirleri (yerleşik, tam sayı çifti, dizeleri) çıkarmayı seçebilirsiniz;
    • İkili basamaklı giriş / çıkış bu soruya izin verilmez;
  • Bu , en kısa kod kazanır;
  • Standart boşluklar izin verilmedi.

testcases

input output
1     1/2     0.5
2     1/4     0.25
3     3/4     0.75
4     1/8     0.125
10    5/16    0.3125
100   73/128  0.5703125
511   511/512 0.998046875
512   1/1024  0.0009765625

Bu örnekler, öncü 0'ın dahil olduğu 0 indeksli diziye dayanmaktadır. Çözümünüzü sığdırmak için girişi ayarlamanız gerekir.

Daha fazla oku

  • OEIS A006257
    • Josephus sorunu: . (Eski adıyla M2216)bir2n=2birn-1,bir2n+1=2birn+1
    • 0, 1, 1, 3, 1, 3, 5, 7, 1, 3, 5, 7, 9, 11, 13, 15, 1, 3, 5, ...
  • OEIS A062383
    • bir0=1 : , veya .n>0birn=2lOg2n+1birn=2birn2
    • 1, 2, 4, 4, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32, ...
  • A006257 (n) / A062383 (n) = (0, 0.1, 0.01, 0.11, 0.001, ...) birim aralıktaki bütün ikili fraksiyonları numaralandırır [0, 1). - Fredrik Johansson, 14 Ağustos 2006


4
" Hiçbir şey girmeyin, sonsuz sayı sırasını birer birer çıktılayın" Birer birer olmak zorunda mıyız, yoksa sonsuz bir liste çıkarmamıza izin veriyor mu (Haskell, Elixir, 05AB1E, vb. Mümkün)?
Kevin Cruijssen 14:18

Dizelerin bir listesini çıkarabilir miyim? eg"1/2" "1/4" "1/8"...
Barranka

@KevinCruijssen Sonsuz liste takedaha sonra n öğelerini ekleyebildiğiniz sürece iyidir .
tsh

@Barranka Kabul edilebilir olduğunu düşünüyorum. Bu kesirleri stdout'a yazdırmaktan farklı bir şey değildir.
tsh

Derken ikili sayı olarak giriş / çıkış izin verilmez , biz bir işlev yazamaz anlamına döndürdüğü bir çift eğer intler veya doublebir dil / uygulanmasında doubleIEEE binary64 biçimi kullanır ? Umarım demek istemiyorsanız, bir tamsayı girişi almak istiyorsak ASCII dizesini ayrıştırmak zorunda kaldık mı? Normal tamsayı türleri, C gibi dillerde ikilidir. Yoksa giriş / çıkışın bir tamsayı dizisi veya bir dize olamayacağını mı demek istiyorsunuz?
Peter Cordes

Yanıtlar:


22

Haskell , 25 bayt

pred.until(<2)(/2).(+0.5)

Çevrimiçi deneyin!

İlk sıfır terimi olmadan tek indeksli ondalık sayıları çıkarır.

Girdiye 0,5 ekler, ardından sonuçlar 2'nin altına düşene kadar yarıya düşer, sonra 1'i çıkarır. Noktasız ifade kullanmak 1 bayttan fazla tasarruf sağlar

f n=until(<2)(/2)(n+0.5)-1

11

Java 10, 68 64 bayt

İlk önce golf kodunu deneyin!

Seçenek 1: n. Öğeyi bulun (1 indeksli)

@Kevin Cruijssen sayesinde -4 bayt

n->{int x=0;for(;n>>++x!=1;);return((~(1<<x)&n)*2.+1)/(1<<x+1);}

Bu, n'den en önemli biti n'den çıkartarak , iki katına çıkarıp bir tane ekleyerek ve ardından en yüksek 2 gücüne bölerek bulduğu anonim bir yöntemdir .

Çevrimiçi deneyin!

Kod girişi:

n->{                      // builds anonymous function with input n
int x=0;                  // stores floor of log(n) (base 2) for most significant digit
for(;n>>++x!=1;);         // calculates floor of log(n) by counting right shifts until 1
return((~(1<<x)&n)        // removes most significant digit of n
*2.+1)                     // multiplies 2 and adds 1 to get the odd numerator
/(1<<x+1);}               // divides by the next highest power of 2 and returns`

Döndürmek yerine son değeri yazdırmak gerekirse, bu düzenleme yapar.


PPCG hoş geldiniz, iyi :) bizimle olman
Shaggy

Merhaba, PPCG'ye hoş geldiniz! Büyük ilk cevap, benden +1. Şu anda Java cevabımla aynı byte-count, ancak cevabımın benden daha kısa olması için hala cevabınızın bazı kısımlarını golf oynayabilirsiniz: Döngüden {}sonra bir olabilir ;; sonra boşlukları kaldırabilirsiniz return; 2.0olabilir 2.; Ve değişen n>>x!=1;x++, 1<<xve 1<<x+1hiç n>>x++!=1;, 1<<x-1, 1<<xsırasıyla aynı zamanda bir bayt kaydeder. Çevrimiçi deneyin: 64 bayt . Kaldınız!
Kevin Cruijssen

Eğer henüz görmediyseniz Oh, ve: İpuçları Java golf için ve <tüm dillerde> içinde golf için ipuçları okumaya hem oldukça ilginçtir. :)
Kevin Cruijssen 14:18

Aslen seninkilere göre olan ama golf oynadığı ve golf oynadığı 30 baytlık cevabımı gör .
Olivier Grégoire

9

MathGolf , 5 4 bayt

╫\╨]

Çevrimiçi deneyin!

Operatör düzgün çalışıyorsa nasıl görünür

╫\)╨]   (")" adds 1 to TOS, making rounding behave as expected)

Çevrimiçi deneyin!

açıklama

╫     Left-rotate all bits in input
 \    Swap top two elements on stack, pushing the input to the top
  ╨   Round up to nearest power of 2
   ]  Wrap in array (just for pretty printing)

Sorunu çözmek için bu sorudan ilham aldım , “kendi” çözümümün sanırım yaklaşık 10-12 bayt oldu.

Sayıyı iki sayı olsaydı geri döndürmek için turun 2'ye en yakın güce gelmesini istemiştim, ancak bir hata nedeniyle ikilik bir sonraki güce dönüyor (ör. 4 -> 4 yerine 4 -> 8 ). Bu daha sonra düzeltilmek zorunda kalacak, ama şimdi beni bir bayt kurtarıyor.


2
MathGolf'u tanımıyorum ama ]çıktıları biçimlendirmekten başka bir amaç yoksa, bayt sayınıza dahil etmeniz gerekmediğini söyleyebilirim.
Shaggy

2
Bundan emin değildim. Yığın birleştirilmiş bir dizge olarak çıktıya yazdırıldığından, 1 ve 2 sayıları 12 olan bir yığın çıkarır. Eğer hala
sayılırsa

Sanırım onu ​​içeride bırakmalısınız. Yığını tek bir dize olarak çıkarmak için bazen bir bayt kazandırır, bazen size bir bayt mal olur.
H.PWiz

@ H.PWiz, orijinal düşüncemdi, çünkü dilinizin güçlü yanlarını kullanmak adil görünüyor. Bazı diller yığının üst kısmını yalnızca bittiğinde yazdırırken, bazıları liste halinde yazdırır. Genellikle 1 baytlık bir fark, ancak bu zorluğun bir parçası.
maxb

8

Java 10, 89 85 70 69 68 bayt

v->{for(float j,t=2;;t*=2)for(j=1;j<t;j+=2)System.out.println(j/t);}

@Emigma Limanı'nın 05AB1E cevabı limitidir , bu nedenle ondalık değerleri de süresiz olarak verir. @Arnauld
sayesinde -15 bayt .

Çevrimiçi deneyin.

Açıklama:

v->{                      // Method with empty unused parameter and no return-type
  for(float j,t=2;;       //  Loop `t` from 2 upwards indefinitely,
                   t*=2)  //  doubling `t` after every iteration
    for(j=1;j<t;          //   Inner loop `j` in the range [1, `t`),
                j+=2)     //   in steps of 2 (so only the odd numbers)
      System.out.println( //    Print with trailing new-line:
        j/t);}            //     `j` divided by `t`

1
Bayt sayınızın yarısını ne kadar sık ​​kullandığımı söyleyebilirim? Bence bu ilk kez ;-)
Olivier Grégoire

@ OlivierGrégoire Dang, şimdi bu etkileyici bir Java cevabı. :) 37-bayt versiyonunuzu TCFP'nin cevabı üzerine yorum olarak gördüm, fakat daha çok bayttan bile kurtuldunuz. Artık 30 baytlık versiyonunuzda oldukça basit görünüyor, ancak ilk versiyondan nasıl golf oynadığınızı hala zekice görüyorsunuz. Aferin!
Kevin Cruijssen



7

Java (JDK 10) , 30 bayt

n->(n+.5)/n.highestOneBit(n)-1

Çevrimiçi deneyin!

Dizideki n'inci öğeyi döndürür .

Bu cevap aslında TCFP'nin Java cevabının golf sayısının artmasıdır . Sonunda, golf artık orijinal cevaba benzemiyordu (kullanılan matematik aynı olsa da), ben de sadece TCFP'nin cevabı üzerine yorum yapmak yerine golfleri ayrı bir cevap olarak kaydetmeye karar verdim. Öyleyse bu cevabı sevdiysen, TCFP'nin cevabını da yükselt ! ;-)

Orta düzey golf sahaları:

n->{int x=0;for(;n>>++x!=1;);return((~(1<<x)&n)*2.+1)/(1<<x+1);} // 64 bytes (TCFP's answer when I started golfing)
n->{int x=0;for(;n>>++x!=1;);x=1<<x;return((~x&n)*2.+1)/x/2;}    // 61 bytes
n->{int x=n.highestOneBit(n);return((~x&n)*2.+1)/x/2;}           // 54 bytes
n->{int x=n.highestOneBit(n);return((~x&n)+.5)/x;}               // 50 bytes
n->((n&~(n=n.highestOneBit(n)))+.5)/n                            // 37 bytes
n->(n-(n=n.highestOneBit(n))+.5)/n                               // 34 bytes
n->(n+.5)/n.highestOneBit(n)-1                                   // 30 bytes, current score

Ve burada oturuyordum, cevabımın yapabildiğim kadar kısa olduğunu düşünürdüm, sen gelip yarıdan fazla kestin! Şaşırtıcı şeyler, kesinlikle benden bir + 1 hak ediyor.
TCFP

@TCFP Birkaç saat süren yinelemeli bir işlemdi. Aslında ara golf oynamayı cevabınıza yorum olarak gönderdim, ancak daha iyi golf bulduğum için sildim. Övgüleriniz için teşekkürler ;-)
Olivier Grégoire

6

05AB1E , 11 8 bayt

Kevin Cruijssen sayesinde 3 bayt kaydedildi .

∞oDÅÉs/˜

Çevrimiçi deneyin!

açıklama

∞         # start an infinite list [1...
 o        # calculate 2**N
  D       # duplicate
   ÅÉ     # get a list of odd numbers up to 2**N
     s/   # divide each by 2**N
       ˜  # flatten

1
-1 bayt kullanarak (1'den başlayan sonsuz liste):∞oεDÅÉs/}˜
Kevin Cruijssen 14:18

@KevinCruijssen: Harika! Bu daha önce görmediğim bir komut. Thanks :)
Emigna 15:18

1
Ah, ve örtük haritalama nedeniyle iki bayt daha tasarruf etmenin güzel bir yolu .. Bunu düşünmedim bile, lol ..
Kevin Cruijssen

1
: Ey bu nasıl mümkün olabilir? ~ 2 sayfalık soruyu 8 bayta yoğunlaştırdınız.
Cullub

Asal sayıları ve [1,2,4,4,8,8,8,8,16,16,...,2**n]doğru indekslenmiş asalların bir listesini kullanarak ve hazırlamayı düşünüyordum /. Eh, ama 8-bytesiyi değil . Gibi bir şey 9LoDÅP)ζ.
Magic Octopus Urn,


5

PowerShell , 40 bayt

for($i=2;;$i*=2){1..$i|?{$_%2}|%{$_/$i}}

Çevrimiçi deneyin!

Sonsuz diziyi ondalık değer olarak verir. Verilen dil kısıtlamaları, sonuçta hassas problemlerle karşılaşacak, ancak ilk 1000 girişi kolayca gerçekleştirebilecek.

Ayar ile başlar $i=2, sonra bir fordöngüye girer . Her yinelemede, bir aralık oluştururuz 1..$ive tek değerleri ile çıkarırız |?{$_%2}. Bunlar, her birini ondalık virgül almak için böldüğümüz kendi iç döngülerine beslenir |%{$_/$i}. Bunlar, her fortekrarlamadan sonra boru hattı boşaltıldığında boru hattında bırakılır ve çıktı alınır . Biz sadece artan ediyoruz Her yineleme $itarafından $i*=2sonraki go-yuvarlak alır.


5

Haskell, 35 32 bayt

Düzenleme: @ Delfad0r sayesinde -3 bayt.

[(y,2^x)|x<-[1..],y<-[1,3..2^x]]

Bu tamsayı çiftlerinin sonsuz bir listesidir.

Çevrimiçi deneyin!


5

Haskell , 40 bayt

s=(1,2):[(i*2+u,j*2)|(i,j)<-s,u<-[-1,1]]

Çevrimiçi deneyin!

Tam sayı çiftleri olarak sonsuz dizi (baştan başlar (1,2)).

@ Nimi'nin cevabından biraz daha uzun , ama yaklaşım tamamen farklı, bu yüzden yine de göndermeye karar verdim.

Bu çözüm aşağıdaki gözlemlere dayanmaktadır.

{12,14,34,18,38,58,78,116,316,...}

  • benj{2ben-12j,2ben+12j}
    {{14,34},{18,38},{58,78},{116,316},...}
  • {14,34,18,38,58,78,116,316,...}
  • ekle12
    {12,14,34,18,38,58,78,116,316,...}

Başladığınız diziye nasıl geri döndüğünüze dikkat edin!

Çözüm, bu gerçeği (Haskell'in tembelliğiyle birlikte) diziyi hesaplamak için kullanır s.


4

Python 2 - 68 66 bayt

Kevin sayesinde -2 bayt

from math import*
def g(n):a=2**floor(log(n,2));print(n-a)*2+1,2*a

Çevrimiçi Deneyin!


Sen değiştirerek golf 1 byte can return 2*(n-a)için return(n-a)*2. Ve 3 yerine Python 2 kullanarak ek bir bayttan tasarruf returnedebilirsiniz , böylece print(parantez içinde) olabilir.
Kevin Cruijssen 14:18

2
@KevinCruijssen Python kullanmayan biri için kesinlikle benden daha iyi bir Python programcısısınız.
Don Bin

Hehe. : D Bunun gibi basit şeyler sanırım deneyim ile geliyor. Yaklaşık iki yıldır bu sitedeyim sanırım (EDIT: Nisan 2016'dan beri). Bazen daha önce hiç görmediğim dillerde yazılmış cevaplar için golf oynamalarını bile öneririm. Bazı temel şeyler çoğu dilde çalışır. Örneğin, geçen hafta bir T-SQL cevabı için bir golf önerdim ve bir keresinde Red cevabında bir golf önerdim . xD
Kevin Cruijssen 14:18

2
44 bayt kullanarak lenve binyerine log.
ovs



4

R , 42 bayt

function(n)c(y<-2^(log2(n)%/%1)*2,2*n-y+1)

Çevrimiçi deneyin!

Denominator,NumeratorN-=2*(n-2günlük2(n))+1D=2günlük2(n)+1



3

MATL , 8 bayt

BnWGEy-Q

Çevrimiçi deneyin!

Pay, ardından Payda'yı döndürür. Biraz daha verimli olsa da, R cevabımdakiyle aynı yöntemi kullanıyor .

Açıklama ile giriş 5:

           # implicit input 5
B          # convert to array of bits
           # STACK: [[1 0 1]]
n          # length (place of Most Significant Bit)
           # STACK: [3]
W          # elementwise raise 2^x
           # STACK: [8]
G          # paste input
           # STACK: [8, 5]
E          # double
           # STACK: [8, 10]
y          # copy from below
           # STACK: [8, 10, 8]
-          # subtract
           # STACK: [8, 2]
Q          # increment
           # STACK: [8, 3]
           # implicit end of program, display stack contents

2

Shakespeare Programlama Dili , 426 bayt

,.Ajax,.Ford,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:You be the sum ofyou a cat.Ford:You cat.Scene V:.Ford:Is twice you nicer I?If solet usScene X.You be twice you.Let usScene V.Scene X:.Ford:Remember twice you.You be the sum oftwice the remainder of the quotient betweenI you a cat.Open heart.You big big big big big cat.Speak thy.Recall.Open heart.You be twice the sum ofa cat a big big cat.Speak thy.Let usAct I.

Çevrimiçi deneyin!

Her öğenin bir yeni satır ile ayrıldığı, diziyi aralıksız olarak her iki sayı da boşlukla ayrılmış olarak verir.


Sevdim. LolYou be twice the sum of a cat
Cullub

Aslında, "bir kedinin toplamının iki katı büyük bir kedi" (yani bir nedenden ötürü 10).
JosiahRyanW


2

Excel 48 28 Bayt

Tsh sayesinde 20 bayt (!) Kaydedildi

=(A1+0.5)/2^INT(LOG(A1,2))-1

= MOD (A1 + 0.5,2 ^ (INT (LOG (A1,2)))) / 2 ^ INT (LOG (A1,2))

A1'de değer varsayar, çıktı ondalıktır. Çıktının kesirli olmasını istiyorsanız, çıktı hücresi için "0 / ### 0" şeklinde özel bir biçim oluşturabilirsiniz ve bu kesir olarak gösterecektir.

Açıklama: Açıklamak zor, çünkü bu formüle ulaşmak için bir kestirme yol var. Temelde paytör girişin bir miktar kaydırmasıdır ve payda sayı girişinden 2 daha sonraki güçtür.

Başlangıçta BITLSHIFT ve BITRSHIFT işlevlerinde yerleşik olan Excel ile başladım, ancak istedikleri olmayan 48 bitin tamamını değiştirecekler. DEC2BIN (ve BIN2DEC) işlevleri -512 ila 511 (10 bit) sınırına sahiptir, bu yüzden bu işe yaramaz. Bunun yerine, sayıyı orijinal sayının bir modülü ile yeniden oluşturmam gerekiyordu, sonra iki kez, sonra 1 ekledim (çünkü sol basamak bir vardiyadan önce 1 olacaktı).

=MOD(A1                        Use MOD for finding what the right digits are
       +0.5                    this will later add the left "1" to the right digits
           ,2^INT(LOG(A1,2)))) Take Log base 2 number of digits on the right
                               this creates the numerator divided by 2 (explained later)
/ 2^INT(LOG(A1,2))             The denominator should be 2^ (Log2 + 1) but instead of 
                               adding a 1 here, we cause the numerator to be divided by 2 instead
                               This gives us a fraction.  In the numerator, we also added .5
                               instead of 1 so that we wouldn't need to divide it in both the
                               numerator and denominator
Then tsh showed how I could take the int/log out of the mod and remove it from numerator/denominator. 

Örnekler: görüntü tanımını buraya girin


Ne hakkında =(A1+0.5)/2^INT(LOG(A1,2))-1?
tsh

2

C ++, 97 75 71 bayt

-26 bayt tsh, ceilingcat, Zacharý sayesinde

float f(int i){float d=2,n=1;while(--i)n=d-n==1?d*=2,1:n+2;return n/d;}

Test kodu:

std::cout << "1\t:\t" << f(1) << '\n';
std::cout << "2\t:\t" << f(2) << '\n';
std::cout << "3\t:\t" << f(3) << '\n';
std::cout << "4\t:\t" << f(4) << '\n';
std::cout << "10\t:\t" << f(10) << '\n';
std::cout << "100\t:\t" << f(100) << '\n';
std::cout << "511\t:\t" << f(511) << '\n';
std::cout << "512\t:\t" << f(512) << '\n';

Sadece if(!i)return 0;meydan okumaya gerek olmadığından ihmal edebilirsiniz .
tsh

1
C benzeri dili golf yapmaya çalışırken. Kullanmaktan kaçınmalısınız whileama deneyin for. for(;exp;)aynıdır, while(exp)ancak içine iki başka ifade daha yazabilirsiniz. ?:Bunun yerine, if elseçoğu durumda daha kısa olanı tercih edin .
tsh

1
(...)Etrafa ihtiyacın olduğunu sanmıyorum d-n-1.
Zacharý






1

> <> , 19 18 bayt

Xnor'ın fikrini kullanarak , Jo King tarafından düzeltildi, -1 byte, aynalardan ve Jo King tarafından -2 byte'dan daha iyi yararlanılarak yapıldı, çünkü !gereksiz ve ;gerekli değildi.

2*1+\1-n
2:,2/?(

Çevrimiçi deneyin!


İlk önce 2'den küçük olup olmadığını kontrol etmelisiniz, aksi takdirde ilk öğedir -0.25. Aynı miktarda bayt için düzelt
Jo King

Teşekkürler! Ayrıca aynaları tekrar kullanarak başka bir byte'ı kaldırmayı da başardım.
PidgeyUsedGust 18:18

Neden durumu tersine çevirdin? 16 bayt
Jo King,

Döngü devam edeceğini fark etmedi. Düzgün bir şekilde bitirememe izin veriliyor mu?
PidgeyUsedGust

Evet, OP aksini belirtmediği sürece bir hata ile sonlandırmak gayet iyi
Jo King,


1

APL (Dyalog Unicode) , 15 bayt

1-⍨.5∘+÷2*∘⌊2⍟⊢

Çevrimiçi deneyin!

Anonim önek lambda.

Adám'a 4 bayt ve İnekler'e 2 bayt için teşekkür ederiz.

Nasıl:

1-⍨.5∘+÷2*∘⌊2⍟⊢  Anonymous lambda, argument   10
            2⍟⊢  Log (⍟) of  in base 2. 210  3.32192809489...
                 Floor. 3.32192809489...  3
        2*∘       Take that power of 2. 2³  8
       ÷          Use that as denominator
   .5∘+            + 0.5  10.5. Using that as numerator: 10.5÷8  1.3125
1-⍨               Swap the arguments (⍨), then subtract. 1-⍨1.3125  1.3125-1  0.3125

1

C # (.NET Çekirdeği) , 69 bayt

a=>{int b=1,c=2;while(a-->1){b+=2;if(b>c){b=1;c*=2;}}return b+"/"+c;}

Çevrimiçi deneyin!

Ungolfed:

a=> {
    int b = 1, c = 2;   // initialize numerator (b) and denominator (c)
    while (a-- > 1)     // while a decrements to 1
    {
        b += 2;         // add 2 to b
        if (b > c)      // if b is greater than c:
        {
            b = 1;      // reset numerator to 1
            c *= 2;     // double denominator
        }
    }
    return b + "/" + c; // return fraction as string
}
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.