Połowa, pół połowa i pół


33

Rozważ następującą sekwencję numerów:

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

Wymienia wszystkie ułamki binarne w przedziale jednostkowym .[0,1)

(Aby ułatwić to wyzwanie, pierwszy element jest opcjonalny: Możesz go pominąć i rozważyć, że sekwencja zaczyna się od 1/2).

Zadanie

Napisz program (pełny program lub funkcję), który ...

Wybierz jedno z tych zachowań:

  • Wejście n, wyjście n-ty element sekwencji (indeksowane 0 lub indeksowane 1);
  • Wprowadź n, wyślij pierwsze n elementów sekwencji;
  • Nic nie wpisuj, wypisz nieskończoną sekwencję liczb, którą możesz brać jeden po drugim;

Reguła

  • Twój program powinien co najmniej wspierać pierwsze 1000 pozycji;
  • Możesz wybrać wyświetlanie liczb dziesiętnych lub ułamków (wbudowane, pary całkowite, łańcuchy) według własnego uznania;
    • Wejście / Wyjście jako cyfry binarne nie jest dozwolone w tym pytaniu;
  • To jest , wygrywanie najkrótszych kodów;
  • Standardowe luki zabronione.

Przypadki testowe

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

Przykłady te oparte są na sekwencji z indeksowaniem 0, w tym z wiodącym 0. Konieczne będzie dostosowanie danych wejściowych w celu dopasowania rozwiązania.

Czytaj więcej

  • OEIS A006257
    • Problem z Józefem Flawiuszem: . (Poprzednio M2216)a2n=2an1,a2n+1=2an+1
    • 0, 1, 1, 3, 1, 3, 5, 7, 1, 3, 5, 7, 9, 11, 13, 15, 1, 3, 5, ...
  • OEIS A062383
    • n > 0 a n = 2 l o g 2 n + 1 a n = 2 a na0=1 : dla , lub .n>0an=2log2n+1an=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, ...) wylicza wszystkie ułamki binarne w przedziale jednostkowym [0, 1). - Fredrik Johansson, 14 sierpnia 2006 r


4
Nic nie wkładaj, wypisz nieskończoną sekwencję liczb jeden po drugim ” Czy musi to być jeden po drugim, czy też wolno nam wypisać nieskończoną listę (możliwe w Haskell, Elixir, 05AB1E itp.)?
Kevin Cruijssen

Czy mogę wypisać listę ciągów? np."1/2" "1/4" "1/8"...
Barranka,

@KevinCruijssen Lista nieskończona jest w porządku, o ile takepóźniej możesz n elementów z niej.
tsh

@Barranka Myślę, że jest to do przyjęcia. To nic innego jak wydrukować ułamki na standardowe wyjście.
tsh

Kiedy mówisz, że wejście / wyjście jako liczby binarne jest niedozwolone , masz na myśli, że nie możemy napisać funkcji, która zwraca parę, jeśli ints, lub doublew języku / implementacji, w której doubleużywany jest format binarny IEEE ? Mam nadzieję, że nie masz na myśli, że musiałeś parsować ciąg ASCII, jeśli chcemy wziąć liczbę całkowitą? Normalne typy liczb całkowitych są binarne w językach takich jak C. Czy masz na myśli, że wejście / wyjście nie może być tablicą lub ciągiem liczb całkowitych lub zer / jedynek ASCII?
Peter Cordes,

Odpowiedzi:


22

Haskell , 25 bajtów

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

Wypróbuj online!

Generuje dziesiętne, zindeksowane bez początkowego terminu zerowego.

Dodaje 0,5 do danych wejściowych, następnie zmniejsza o połowę, aż wyniki będą niższe niż 2, a następnie odejmuje 1. Użycie wyrażenia bezcelowego oszczędza 1 bajt

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

11

Java 10, 68 64 bajtów

Najpierw spróbuj golfa code!

Opcja 1: znajdź n- ty element (1-indeksowany)

-4 bajty dzięki @Kevin Cruijssen

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

Jest to anonimowa metoda, która znajduje n- ty składnik, usuwając najbardziej znaczący bit z n , podwajając go i dodając jeden, a następnie dzieląc przez następną najwyższą potęgę 2.

Wypróbuj online!

Przewodnik po kodzie:

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`

Dokonuje edycji, jeśli konieczne jest wydrukowanie końcowej wartości zamiast jej zwracania.


Witamy w PPCG, dobrze cię mieć z nami :)
Shaggy

Cześć, witamy w PPCG! Świetna pierwsza odpowiedź, +1 ode mnie. Obecnie jest to ta sama liczba bajtów, co moja odpowiedź Java, ale nadal możesz zagrać w golfa w niektórych częściach swojej odpowiedzi, aby była krótsza niż moja: {}Pętla po może być ;zamiast tego; możesz usunąć spację po return; 2.0może być 2.; I zmianę n>>x!=1;x++, 1<<xi 1<<x+1do n>>x++!=1;, 1<<x-1, 1<<xodpowiednio również oszczędza bajt. Wypróbuj online: 64 bajty . Miłego pobytu!
Kevin Cruijssen

Aha, a jeśli jeszcze tego nie widziałeś: Porady dotyczące gry w golfa w Javie i Porady dotyczące gry w golfa w <wszystkich językach> są bardzo interesujące do przeczytania. :)
Kevin Cruijssen

Zobacz moją 30-bajtową odpowiedź, początkowo opartą na twojej, ale grała w golfa i grała w golfa.
Olivier Grégoire,

9

MathGolf , 5 4 bajtów

╫\╨]

Wypróbuj online!

Jak by to wyglądało, gdy operator działa poprawnie

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

Wypróbuj online!

Wyjaśnienie

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

Inspirację czerpałem z tego pytania, aby rozwiązać problem. Myślę, że moje „własne” rozwiązanie miało około 10-12 bajtów.

Zamierzałem, aby zaokrąglenie w górę do najbliższej potęgi 2 zwróciło samą liczbę, jeśli była to liczba dwa, ale z powodu błędu zaokrągla ona do następnej potęgi dwóch (np. 4 -> 8 zamiast 4 -> 4 ). To trzeba będzie naprawić później, ale teraz oszczędza mi to jeden bajt.


2
Nie znam MathGolf, ale jeśli ]nie służy to żadnemu innemu celowi niż sformatowanie danych wyjściowych, powiedziałbym, że nie trzeba uwzględniać ich w liczbie bajtów.
Shaggy

2
Nie byłem tego pewien. Ponieważ stos jest drukowany na wydruku jako połączony ciąg, wypisuje stos o liczbach 1 i 2 jako 12. Jeśli to nadal się liczy,
usunę

Myślę, że powinieneś to zostawić. Czasami zapisuje bajt, aby wyprowadzić stos jako jeden ciąg, czasem będzie cię to kosztować bajt.
H.PWiz

@ H.PWiz to było moje pierwotne myślenie, ponieważ użycie mocnych stron twojego języka wydaje się sprawiedliwe. Niektóre języki drukują górę stosu tylko po zakończeniu, inne drukują go jako listę. Zwykle jest to różnica 1-bajtowa, ale stanowi część wyzwania.
maxb

8

Java 10, 89 85 70 69 68 bajtów

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

Port odpowiedzi 05AB1E @Emigma , więc wypisuje również dziesiętne w nieskończoność.
-15 bajtów dzięki @Arnauld .

Wypróbuj online.

Wyjaśnienie:

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
Jak często mogę mówić, że liczę połowę twojego bajtu? Cóż, myślę, że to pierwszy raz ;-)
Olivier Grégoire,

@ OlivierGrégoire Dang, teraz jest to imponująca odpowiedź Java. :) Widziałem twoją 37-bajtową wersję jako komentarz do odpowiedzi TCFP, ale nawet usunąłeś więcej bajtów. Teraz wygląda tak niezwykle prosto w 30-bajtowej wersji, ale nadal jest genialny, jak grałeś w golfa od wersji początkowej. Dobra robota!
Kevin Cruijssen



7

Java (JDK 10) , 30 bajtów

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

Wypróbuj online!

Zwraca nty element w sekwencji.

Ta odpowiedź jest pierwotnie następstwem golfa odpowiedzi Java firmy TCFP . Ostatecznie golfy nie wyglądały już jak oryginalne odpowiedzi (choć zastosowana matematyka jest taka sama), więc postanowiłem opublikować golfa jako osobną odpowiedź zamiast po prostu komentować odpowiedź TCFP. Jeśli więc podoba ci się ta odpowiedź, idź głosować odpowiedź TCFP ! ;-)

Pośrednie pola golfowe to:

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

I siedziałem tutaj, myśląc, że moja odpowiedź jest tak krótka, jak tylko potrafię, przyjdź i przeciąć ją o ponad połowę! Niesamowite rzeczy, zdecydowanie zasługują na +1 ode mnie.
TCFP

@TCFP Był to proces iteracyjny na przestrzeni kilku godzin. Właściwie umieściłem każde pośrednie golfa jako komentarz do twojej odpowiedzi, ale usunąłem je, ponieważ znalazłem lepsze golfa. Dzięki za pochwałę ;-)
Olivier Grégoire,

6

05AB1E , 11 8 bajtów

Zaoszczędził 3 bajty dzięki Kevin Cruijssen .

∞oDÅÉs/˜

Wypróbuj online!

Wyjaśnienie

∞         # 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 bajt przy użyciu (nieskończona lista od 1):∞oεDÅÉs/}˜
Kevin Cruijssen

@KevinCruijssen: Cool! To polecenie, którego wcześniej nie widziałem. Dzięki :)
Emigna,

1
Ach, i fajny sposób na zaoszczędzenie jeszcze dwóch bajtów ze względu na ukryte mapowanie .. Nawet o tym nie myślałem, lol ..
Kevin Cruijssen

1
: O, jak to możliwe. Skondensowałeś ~ 2-stronicowe pytanie na 8 bajtów.
Cullub

Myślałem o użyciu liczb pierwszych i listy [1,2,4,4,8,8,8,8,16,16,...,2**n]poprawnych liczb pierwszych indeksowanych, a następnie o /… Ale to nie działało tak dobrze. No ale nie za 8-bytesdobrze. Coś jak 9LoDÅP)ζ.
Magic Octopus Urn


5

PowerShell , 40 bajtów

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

Wypróbuj online!

Zwraca nieskończoną sekwencję jako wartości dziesiętne. Biorąc pod uwagę ograniczenia językowe, w końcu wystąpią problemy z precyzją, ale z łatwością poradzi sobie z pierwszymi 1000 wpisami.

Zaczyna od ustawienia $i=2, a następnie wchodzi w forpętlę. Przy każdej iteracji konstruujemy zakres 1..$ii wyciągamy wartości nieparzyste za pomocą |?{$_%2}. Są one wprowadzane do ich własnej wewnętrznej pętli, gdzie dzielimy każdą z nich, aby uzyskać liczbę dziesiętną |%{$_/$i}. Zostają one pozostawione w potoku i wyprowadzane, gdy potok jest opróżniany po każdej foriteracji. Każdą iterację zwiększamy $i, $i*=2aby uzyskać kolejną rundę.


5

Haskell, 35 32 bajtów

Edycja: -3 bajty dzięki @ Delfad0r.

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

To nieskończona lista par liczb całkowitych.

Wypróbuj online!


5

Haskell , 40 bajtów

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

Wypróbuj online!

Nieskończona sekwencja jako pary liczb całkowitych (zaczynając od (1,2)).

Trochę dłużej niż odpowiedź @ nimi , ale podejście jest zupełnie inne, więc i tak zdecydowałem się opublikować.

To rozwiązanie opiera się na poniższej obserwacji.

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

  • ij{2i12j,2i+12j}
    {{14,34},{18,38},{58,78},{116,316},}
  • {14,34,18,38,58,78,116,316,}
  • 12
    {12,14,34,18,38,58,78,116,316,}

Zauważ, jak wróciłeś do sekwencji, którą zacząłeś!

Rozwiązanie wykorzystuje ten fakt (wraz z lenistwem Haskella) do obliczenia sekwencji s.


4

Python 2 - 68 66 bajtów

-2 bajty dzięki Kevinowi

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

Wypróbuj online!


Możesz zagrać w golfa 1 bajt, zmieniając return 2*(n-a)na return(n-a)*2. I możesz zapisać dodatkowy bajt, używając Pythona 2 zamiast 3, więc returnmożesz to zrobić print(z nawiasami).
Kevin Cruijssen

2
@KevinCruijssen Dla kogoś, kto nie używa Pythona, z pewnością jesteś lepszym programistą Python ode mnie.
Don Thousand

Hehe : D Proste rzeczy takie jak ta, jak sądzę, mają doświadczenie. Myślę, że jestem na tej stronie od około dwóch lat (EDIT: od kwietnia 2016 r.). Czasami nawet sugeruję golfowi odpowiedzi, które są napisane w językach, których nigdy wcześniej nie widziałem. Niektóre podstawowe rzeczy działają w większości języków. Na przykład w zeszłym tygodniu zasugerowałem golfa dla odpowiedzi T-SQL , a raz zasugerowałem golfa w odpowiedzi Red . xD
Kevin Cruijssen

2
44 bajty za pomocą leni binzamiast log.
ovs



4

R , 42 bajty

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

Wypróbuj online!

Denominator,NumeratorN=2(n2log2(n))+1D=2log2(n)+1



3

MATL , 8 bajtów

BnWGEy-Q

Wypróbuj online!

Zwraca licznik, a następnie mianownik. Używa tej samej metody, co moja odpowiedź R. Jednak jest ona nieco bardziej wydajna.

Objaśnienie, z wejściem 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

Język programowania Szekspira , 426 bajtów

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

Wypróbuj online!

Generuje sekwencję nieskończenie, ponieważ obie liczby są oddzielone spacją, a każdy element jest oddzielony znakiem nowej linii.


Kocham to. LolYou be twice the sum of a cat
Cullub

W rzeczywistości jest to „dwukrotność sumy dużego kota” (z jakiegoś powodu 10).
JosiahRyanW


2

Excel 48 28 bajtów

Zaoszczędzono 20 bajtów (!) Dzięki tsh

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

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

Przyjmuje wartość w A1, dane wyjściowe są dziesiętne. Jeśli chcesz, aby dane wyjściowe były ułamkowe, możesz utworzyć niestandardowy format dla komórki wyjściowej jako „0 / ### 0” i wyświetli się jako ułamek.

Objaśnienie: Trudne do wyjaśnienia, ponieważ zastosowano skrót, aby dostać się do tej formuły. Zasadniczo licznik jest nieco przesunięty w lewo od wejścia, a mianownik jest następną siłą o 2 wyższą niż wprowadzona liczba.

Pierwotnie zacząłem od wbudowanych funkcji Excela dla BITLSHIFT i BITRSHIFT, ale przesuną one całe 48 bitów, co nie jest tym, czego chcesz. Funkcje DEC2BIN (i BIN2DEC) mają limit od -512 do 511 (10 bitów), więc to nie zadziała. Zamiast tego musiałem odbudować liczbę z modułem oryginalnej liczby, następnie dwa razy, a następnie dodać 1 (ponieważ lewa cyfra zawsze będzie miała wartość 1 przed zmianą).

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

Przykłady: wprowadź opis zdjęcia tutaj


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

2

C ++, 97 75 71 bajtów

-26 bajtów dzięki 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;}

Kod testowy:

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

Możesz po prostu pominąć, if(!i)return 0;ponieważ 0 nie jest wymagane w wyzwaniu.
tsh

1
Podczas gry w golfa w języku C. Powinieneś unikać używania, whileale spróbuj for. for(;exp;)jest taki sam, while(exp)ale można do niego napisać jeszcze dwie inne instrukcje. Wolę ?:zamiast if else, co w większości przypadków byłoby krótsze.
tsh

1
Nie sądzę, że trzeba się (...)dookoła d-n-1.
Zacharý






1

> <> , 19 18 bajtów

Używając pomysłu xnora , naprawionego przez Jo Kinga, -1 bajt przez lepsze wykorzystanie kopii lustrzanych i kolejnych -2 bajtów przez Jo Kinga, ponieważ !był zbędny i ;nie jest wymagany.

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

Wypróbuj online!


Powinieneś sprawdzić, czy najpierw jest mniejsza niż 2, w przeciwnym razie pierwszy element to -0.25. Napraw tę samą liczbę bajtów
Jo King,

Dzięki! Udało mi się również usunąć kolejny bajt, ponownie wykorzystując kopie lustrzane.
PidgeyUsedGust

Dlaczego odwróciłeś warunek? 16 bajtów
Jo King

Nie zauważyłem, że będzie kontynuował pętlę. Czy wolno nam nie zakończyć poprawnie?
PidgeyUsedGust

Tak, zakończenie z błędem jest w porządku, o ile OP nie określi inaczej
Jo King


1

APL (Dyalog Unicode) , 15 bajtów

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

Wypróbuj online!

Anonimowy przedrostek lambda.

Dzięki Adámowi za 4 bajty i kwakowi Krowy za 2 bajty.

W jaki sposób:

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 Core) , 69 bajtów

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

Wypróbuj online!

Nie golfowany:

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
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.