Setengah, Setengah Setengah, dan, Setengah

33

Pertimbangkan urutan nomor berikut:

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

Ini menghitung semua fraksi biner dalam interval satuan .[0,1)

(Untuk membuat tantangan ini lebih mudah, elemen pertama adalah opsional: Anda dapat melewati dan mempertimbangkan urutan dimulai dengan 1/2.)

Tugas

Tulis program (selesaikan program atau fungsi) yang ...

Pilih salah satu dari perilaku ini:

  • Input n, output elemen n dari urutan (0-diindeks atau 1-diindeks);
  • Input n, output pertama n elemen urutan;
  • Masukkan apa-apa, output urutan nomor tak terbatas yang dapat Anda ambil dari satu per satu;

Aturan

  • Program Anda setidaknya harus mendukung 1000 item pertama;
  • Anda dapat memilih untuk menghasilkan desimal, atau fraksi (bawaan, bilangan bulat integer, string) sesuka Anda;
    • Input / Output sebagai digit biner tidak diperbolehkan dalam pertanyaan ini;
  • Ini adalah , kode terpendek menang;
  • Celah standar tidak diijinkan.

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

Contoh-contoh ini didasarkan pada urutan 0-diindeks dengan 0 terkemuka disertakan. Anda perlu menyesuaikan input untuk menyesuaikan solusi Anda.

Baca lebih lajut

  • OEIS A006257
    • Masalah Josephus: a2n=2an1,a2n+1=2an+1 . (Sebelumnya M2216)
    • 0, 1, 1, 3, 1, 3, 5, 7, 1, 3, 5, 7, 9, 11, 13, 15, 1, 3, 5, ...
  • OEIS A062383
    • : untuk n > 0 , a n = 2 l o g 2 n + 1 atau a n = 2 a na0=1n>0an=2log2n+1.an=2an2
    • 1, 2, 4, 4, 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, ...) menghitung semua fraksi biner dalam interval satuan [0, 1). - Fredrik Johansson, 14 Agustus 2006

tsh
sumber
4
"Tidak memasukkan apa pun, mengeluarkan urutan nomor tak terbatas satu per satu " Apakah harus satu-per-satu, atau apakah kita juga diizinkan untuk mengeluarkan daftar tanpa batas (mungkin dalam Haskell, Elixir, 05AB1E, dll.)?
Kevin Cruijssen
Bisakah saya menampilkan daftar string? misalnya"1/2" "1/4" "1/8"...
Barranka
@KevinCruijssen Daftar tak terbatas baik-baik saja selama Anda dapat taken elemen dari itu nanti.
tsh
@ Barranka saya pikir itu dapat diterima. Tidak ada bedanya dengan mencetak pecahan ke stdout.
tsh
Ketika Anda mengatakan Input / Output sebagai angka biner tidak diizinkan , Anda berarti kami tidak dapat menulis fungsi yang mengembalikan pasangan jika ints, atau doubledalam bahasa / implementasi di mana doublemenggunakan format IEEE binary64 ? Saya harap Anda tidak bermaksud harus mengurai string ASCII jika kami ingin mengambil input integer? Tipe integer normal adalah biner dalam bahasa seperti C. Atau apakah maksud Anda input / output tidak boleh berupa array atau string integer atau nol ASCII?
Peter Cordes

Jawaban:

22

Haskell , 25 byte

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

Cobalah online!

Output desimal, satu-diindeks tanpa istilah nol awal.

Menambahkan 0,5 ke input, lalu membagi dua hingga hasilnya di bawah 2, lalu kurangi 1. Menggunakan ekspresi pointfree menghemat 1 byte lebih dari

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

Java 10, 68 64 byte

Coba pertama kali di golf kode!

Opsi 1: temukan n elemen ke- (1-diindeks)

-4 byte terima kasih kepada @Kevin Cruijssen

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

Ini adalah metode anonim yang menemukan istilah ke- n dengan menghapus bit paling signifikan dari n , menggandakannya dan menambahkannya, kemudian membaginya dengan kekuatan tertinggi berikutnya 2.

Cobalah online!

Panduan kode:

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`

Akan mengedit jika perlu untuk mencetak nilai akhir alih-alih mengembalikannya.

TCFP
sumber
Selamat datang di PPCG, senang Anda bersama kami :)
Shaggy
Hai, selamat datang di PPCG! Jawaban pertama yang bagus, +1 dari saya. Saat ini itu adalah byte-count yang sama dengan jawaban Java saya, tetapi Anda masih bisa memasukkan beberapa bagian dari jawaban Anda untuk membuatnya lebih pendek daripada milik saya: The {}setelah loop dapat menjadi sebagai ;gantinya; Anda dapat menghapus ruang setelah return; 2.0bisa 2.; Dan mengubah n>>x!=1;x++, 1<<xdan 1<<x+1untuk n>>x++!=1;, 1<<x-1, 1<<xmasing-masing juga menghemat byte. Cobalah online: 64 byte . Selamat menikmati!
Kevin Cruijssen
Oh, dan jika Anda belum melihatnya: Tip untuk bermain golf di Jawa dan Tips untuk bermain golf di <semua bahasa> keduanya cukup menarik untuk dibaca. :)
Kevin Cruijssen
Lihat jawaban saya 30 byte , awalnya berdasarkan milik Anda tetapi golf, golf, dan golf.
Olivier Grégoire
9

MathGolf , 5 4 byte

╫\╨]

Cobalah online!

Bagaimana kelihatannya dengan operator yang bekerja dengan benar

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

Cobalah online!

Penjelasan

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

Saya mengambil inspirasi dari pertanyaan ini untuk menyelesaikan masalah, saya kira solusi "sendiri" sekitar 10-12 byte.

Saya bermaksud untuk putaran ke kekuatan terdekat 2 untuk mengembalikan nomor itu sendiri jika nomor dua, tetapi karena kesalahan itu putaran ke kekuatan dua berikutnya (misalnya 4 -> 8 bukannya 4 -> 4 ). Ini harus diperbaiki nanti, tetapi sekarang menghemat satu byte.

maks
sumber
2
Saya tidak tahu MathGolf tetapi jika ]melayani tidak ada tujuan lain selain memformat output, saya akan mengatakan Anda tidak perlu memasukkannya dalam jumlah byte Anda.
Shaggy
2
Saya tidak yakin tentang itu. Karena stack dicetak pada output sebagai string yang bergabung, ia mengeluarkan stack dengan angka 1 dan 2 sebagai 12. Jika itu masih dihitung saya akan menghapus byte
maxb
Saya pikir Anda harus meninggalkannya. Terkadang menyimpan byte untuk menampilkan stack sebagai satu string, kadang-kadang akan dikenakan biaya satu byte.
H.PWiz
@ H.Wiz itulah pemikiran orisinal saya, karena tampaknya adil menggunakan kekuatan bahasa Anda. Beberapa bahasa hanya mencetak bagian atas tumpukan setelah selesai, beberapa mencetaknya sebagai daftar. Biasanya perbedaan 1 byte, tetapi itu bagian dari tantangan.
Maks
8

Java 10, 89 85 70 69 68 bytes

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

Port of @Emigma's 05AB1E answer, so outputs decimals indefinitely as well.
-15 bytes thanks to @Arnauld.

Try it online.

Explanation:

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`
Kevin Cruijssen
sumber
1
How often can I say that I half your byte count? Well, I think this is the first time ;-)
Olivier Grégoire
@OlivierGrégoire Dang, now that is an impressive Java answer. :) I saw your 37-byte version as comment on TCFP's answer, but you even stripped off more bytes. It looks so extremely simple now in your 30-byte version, but it's still ingenious how you've golfed it from the initial version. Well done!
Kevin Cruijssen
7

Python 3, 33 bytes

lambda n:(8*n+4)/2**len(bin(n))-1

Try it online!

Outputs decimals, one-indexed without the initial zero term.

xnor
sumber
7

Java (JDK 10), 30 bytes

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

Try it online!

Returns the nth item in the sequence.

This answer is originally a succession of golfs of TCFP's Java answer. In the end, the golfs didn't look like the original answer anymore (though the math used is the same) so I decided to post the golfs as a separate answer instead of simply commenting on the TCFP's answer. So if you like this answer, go upvote TCFP's answer as well! ;-)

Intermediate golfs were:

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
Olivier Grégoire
sumber
And I was sitting here thinking my answer was as short as I could make it, you come along and cut it by more than half! Amazing stuff, definitely deserves a +1 from me.
TCFP
@TCFP It was an iterative process over the span of several hours. I actually posted each intermediate golfing as a comment to your answer, but deleted them as I found better golfs. Thanks for the praise ;-)
Olivier Grégoire
6

05AB1E, 11 8 bytes

Saved 3 bytes thanks to Kevin Cruijssen.

∞oDÅÉs/˜

Try it online!

Explanation

∞         # 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
Emigna
sumber
1
-1 byte by using (infinite list starting at 1): ∞oεDÅÉs/}˜
Kevin Cruijssen
@KevinCruijssen: Cool! That's a command I hadn't seen before. Thanks :)
Emigna
1
Ah, and nice way of saving two more bytes due to the implicit mapping.. Hadn't even thought about that, lol..
Kevin Cruijssen
1
:O how is this possible. You condensed the ~2 page question into 8 bytes.
Cullub
I was thinking using the prime numbers and a list of [1,2,4,4,8,8,8,8,16,16,...,2**n] and prepending the correct indexed prime followed by a /... But that wasn't working so well. Well, but not 8-bytes well. Something like 9LoDÅP)ζ.
Magic Octopus Urn
5

PowerShell, 40 bytes

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

Try it online!

Outputs the infinite sequence as decimal values. Given language limitations, will eventually run into precision problems, but easily handles the first 1000 entries.

Starts by setting $i=2, then enters a for loop. Each iteration, we construct a range from 1..$i and pull out the odd values with |?{$_%2}. Those are fed into their own inner loop, where we divide each to get the decimal |%{$_/$i}. Those are left on the pipeline and output when the pipeline is flushed after every for iteration. Each iteration we're simply incrementing $i by $i*=2 to get the next go-round.

AdmBorkBork
sumber
5

Haskell, 35 32 bytes

Edit: -3 bytes thanks to @Delfad0r.

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

This is an infinite list of integer pairs.

Try it online!

nimi
sumber
5

Haskell, 40 bytes

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

Try it online!

Infinite sequence as pairs of integers (starting from (1,2)).

Quite a bit longer than @nimi's answer, but the approach is completely different, so I decided to post it anyway.

This solution is based on the following observation.

Consider the infinite sequence

{12,14,34,18,38,58,78,116,316,}
and apply the following steps.

  • Replace every number ij in the sequence with the list {2i12j,2i+12j}:
    {{14,34},{18,38},{58,78},{116,316},}
  • Join all the lists into a single sequence:
    {14,34,18,38,58,78,116,316,}
  • Add 12 at the beginning of the sequence:
    {12,14,34,18,38,58,78,116,316,}

Notice how you get back to the sequence you started with!

The solution exploits this fact (together with Haskell's laziness) to compute the sequence s.

Delfad0r
sumber
4

Python 2 - 68 66 bytes

-2 bytes thanks to Kevin

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

Try it Online!

Don Thousand
sumber
You can golf 1 byte by changing return 2*(n-a) to return(n-a)*2. And you could save an additional byte by using Python 2 instead of 3, so return can be print (with parenthesis).
Kevin Cruijssen
2
@KevinCruijssen For someone who doesn't use Python, you certainly are a better Python programmer than me.
Don Thousand
Hehe. :D Simple things like this comes with experience I guess. I'm on this site for about two years now I think (EDIT: Since April 2016). I sometimes even suggests things to golf for answers that are written in languages I had never seen before.. Some basic things work in most languages. For example, last week I suggested a golf for a T-SQL answer, and I once suggested a golf in a Red answer. xD
Kevin Cruijssen
2
44 bytes using len and bin instead of log.
ovs
@ovs 42 bytes.
Jonathan Frech
4

Python 3, 53 51 bytes

  • Saved two bytes thanks to mypetlion; reusing default parameters to reset n.
def f(m=2,n=1):n<m and print(n/m)&f(m,2+n)or f(m+m)

Try it online!

Jonathan Frech
sumber
Swap the parameters to save 2 bytes: def f(m=2,n=1):n<m and print(n/m)&f(m,n+2)or f(m+m)
mypetlion
1
@mypetlion Cool, thank you!
Jonathan Frech
4

R, 42 bytes

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

Try it online!

Returns a pair Denominator,Numerator. Uses the formula N=2(n2log2(n))+1 from the Josephus sequence and D=2log2(n)+1 from the other sequence. Happily we are able to re-use the denominator as the two formulas have quite a lot in common!

Giuseppe
sumber
3

Racket, 92 91 bytes

(define(f k(m 2)(n 1))(if(> k 0)(if(=(+ n 1)m)(f(- k 1)(+ m m))(f(- k 1)m(+ n 2)))(/ n m)))

Try it online!

  • Saved a byte thanks to Giuseppe -- removing superfluous whitespace.
Jonathan Frech
sumber
3

MATL, 8 bytes

BnWGEy-Q

Try it online!

Returns Numerator, then Denominator. Uses the same method as my R answer, although it's a bit more efficient.

Explanation, with input 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
Giuseppe
sumber
2

Shakespeare Programming Language, 426 bytes

,.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.

Try it online!

Outputs the sequence infinitely as both numbers separated by a space, with each item being separated by a newline.

JosiahRyanW
sumber
Love it. Lol You be twice the sum of a cat
Cullub
Actually, it's "twice the sum ofa cat a big big cat" (i.e. 10 for some reason).
JosiahRyanW
2

Python 2, 44 bytes

def f(n):m=2**len(bin(n))/4;return 2*n-m+1,m

Try it online!

Function returns a tuple of (numerator, denominator). An input of 0 is not handled (it was optional).

Chas Brown
sumber
1
return 2*n-m+1,m can be print-~n+n-m,m to save 2 bytes.
Kevin Cruijssen
2

Excel 48 28 Bytes

Saved 20 bytes (!) thanks to tsh

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

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

Assumes value in A1, output is in decimal. If you want the output to be in fraction, you can create a custom format for the output cell as "0/###0" and it will show it as fraction.

Explanation: Difficult to explain, since there is a shortcut taken to get to this formula. Basically the numerator is a bit shift left of the input, and the denominator is the next power of 2 higher than the number input.

I originally started with Excel built in functions for BITLSHIFT and BITRSHIFT, but they will shift the entire 48 bits which is not what you want. The functions DEC2BIN (and BIN2DEC) have a limit of -512 to 511 (10 bits) so this wouldn't work. Instead I had to rebuild the number with a modulus of the original number, then times two, then add 1 (since the left digit would always be 1 before a shift).

=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. 

Examples: enter image description here

Keeta
sumber
What about =(A1+0.5)/2^INT(LOG(A1,2))-1?
tsh
2

C++, 97 75 71 bytes

-26 bytes thanks to tsh, ceilingcat, Zacharý

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

Testing code :

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';
HatsuPointerKun
sumber
You may just omit if(!i)return 0; since 0 is not required in the challenge.
tsh
1
When trying to golf C-like language. You should avoid using while but try for. for(;exp;) is as same as while(exp) but you can write two more other statement into it. Prefer ?: instead of if else, which would be shorter in most cases.
tsh
1
I don't think you need the (...) around d-n-1.
Zacharý
1

C (gcc), 63 bytes

No input, prints infinite sequence:

f(i,j){for(i=1,j=2;;i+=2,i>j&&(j*=2,i=1))printf("%d/%d ",i,j);}

Try it online!

Annyo
sumber
3
60 bytes.
Jonathan Frech
1
Building on @JonathanFrech 59 bytes
ceilingcat
1

JavaScript (ES6), 44 bytes

Returns the n-th term, 1-indexed.

f=(n,p=q=1)=>n?f(n-1,p<q-2?p+2:!!(q*=2)):p/q

Try it online!

Arnauld
sumber
1

Ruby, 42 bytes

1.step{|i|(1..x=2**i).step(2){|j|p [j,x]}}

Try it online!

Prints integer pairs infinitely, starting from 1/2.

Kirill L.
sumber
1

JavaScript (Node.js), 30 bytes

f=(n,d=.5)=>d>n?n/d:f(n-d,d*2)

Try it online! 0-indexed. Started out as a port of my Batch answer but I was able to calculate in multiples of 12 which saved several bytes.

Neil
sumber
1

><>, 19 18 bytes

Using xnor's idea, fixed by Jo King, -1 byte by making better use of the mirrors and another -2 bytes by Jo King because the ! was superfluous and ; is not required.

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

Try it online!

PidgeyUsedGust
sumber
You should be checking if it is smaller than 2 first, otherwise the first element is -0.25. Fix for the same amount of bytes
Jo King
Thanks! I also managed to remove another byte by reusing the mirrors.
PidgeyUsedGust
Why did you invert the condition? 16 bytes
Jo King
Didn't notice that it would continue the loop. Are we allowed to not properly finish?
PidgeyUsedGust
Yeah, terminating with an error is fine as long as the OP doesn't specify otherwise
Jo King
1

APL (Dyalog Unicode), 15 bytes

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

Try it online!

Anonymous prefix lambda.

Thanks to Adám for 4 bytes and to Cows quack for 2 bytes.

How:

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
J. Sallé
sumber
1

C# (.NET Core), 69 bytes

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

Try it online!

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