Metà, metà metà e metà


33

Considera la seguente sequenza numerica:

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

Enumera tutte le frazioni binarie nell'intervallo unitario [0,1) .

(Per facilitare questa sfida, il primo elemento è facoltativo: puoi saltarlo e considerare che la sequenza inizia con 1/2.)

Compito

Scrivi un programma (programma completo o una funzione) che ...

Scegli uno di questi comportamenti:

  • Input n, output ennesimo elemento della sequenza (0-indicizzato o 1-indicizzato);
  • Input n, output primi n elementi della sequenza;
  • Non inserire nulla, generare l'infinita sequenza numerica che si può prendere uno per uno;

Regola

  • Il tuo programma dovrebbe almeno supportare i primi 1000 articoli;
  • Puoi scegliere di produrre decimali o frazioni (built-in, coppia intera, stringhe) come preferisci;
    • Input / Output come cifre binarie non è consentito in questa domanda;
  • Questo è , vincono i codici più brevi;
  • Scappatoie standard non consentite.

Casi test

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

Questi esempi si basano su una sequenza con indice 0 con lo 0 iniziale incluso. Dovresti regolare l'input per adattare la tua soluzione.

Leggi di più

  • OEIS A006257
    • Problema di Giuseppe Flavio: . (Nome precedente: 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
    • : per n > 0 , a n = 2 l o g 2 n + 1 o 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, ...) enumera tutte le frazioni binarie nell'intervallo unitario [0, 1). - Fredrik Johansson, 14 agosto 2006


4
" Non inserire nulla, emette una sequenza di numeri infinita uno per uno " Deve essere uno per uno o è anche consentito emettere un elenco infinito (possibile in Haskell, Elixir, 05AB1E, ecc.)?
Kevin Cruijssen,

Posso generare un elenco di stringhe? ad es."1/2" "1/4" "1/8"...
Barranka,

@KevinCruijssen L'elenco infinito va bene finché non puoi taken elementi da esso in seguito.
TSH

@Barranka Penso che sia accettabile. Non è niente di diverso che stampare le frazioni su stdout.
TSH

Quando dici che Input / Output come numeri binari non sono consentiti , intendi che non possiamo scrivere una funzione che restituisce una coppia se ints, o un doublein una lingua / implementazione in cui doubleutilizza il formato IEEE binary64 ? Spero che tu non voglia dire che è stato necessario analizzare una stringa ASCII se vogliamo prendere un input intero? I tipi interi normali sono binari in linguaggi come C. O vuoi dire che l'input / output non può essere un array o una stringa di interi o zero / ASCII?
Peter Cordes,

Risposte:


22

Haskell , 25 byte

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

Provalo online!

Decimali di output, uno indicizzati senza il termine zero iniziale.

Aggiunge 0,5 all'input, quindi dimezza fino a quando i risultati non sono inferiori a 2, quindi sottrae 1. L'uso di un'espressione senza punti consente di risparmiare 1 byte

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

11

Java 10, 68 64 byte

Prima prova a code golf!

Opzione 1: trova l' elemento n -esimo (1 indicizzato)

-4 byte grazie a @Kevin Cruijssen

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

Questo è un metodo anonimo che trova il n -esimo termine rimuovendo il bit più significativo da n , raddoppiando e aggiungendo uno, successivamente diviso per il successivo più potenza di 2.

Provalo online!

Procedura dettagliata del codice:

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`

Modificherà se è necessario stampare il valore finale invece di restituirlo.


Benvenuto in PPCG, è un piacere averti con noi :)
Shaggy,

Ciao, benvenuto in PPCG! Ottima prima risposta, +1 da parte mia. Attualmente ha lo stesso numero di byte della mia risposta Java, ma puoi comunque giocare a golf alcune parti della tua risposta per renderla più breve della mia: Il {}ciclo successivo può essere ;invece un ; è possibile rimuovere lo spazio dopo il return; 2.0può essere 2.; E cambiando la n>>x!=1;x++, 1<<xe 1<<x+1per n>>x++!=1;, 1<<x-1, 1<<xsalva rispettivamente, anche un byte. Provalo online: 64 byte . Goditi la permanenza!
Kevin Cruijssen,

Oh, e se non l'hai ancora visto: suggerimenti per giocare a golf in Java e suggerimenti per giocare a golf in <tutte le lingue> sono entrambi piuttosto interessanti da leggere. :)
Kevin Cruijssen,

Vedi la mia risposta di 30 byte , originariamente basata sulla tua ma giocata a golf, giocata a golf e giocata a golf.
Olivier Grégoire,

9

MathGolf , 5 4 byte

╫\╨]

Provalo online!

Come sarebbe se l'operatore funzionasse correttamente

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

Provalo online!

Spiegazione

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

Mi sono ispirato a questa domanda per risolvere il problema, penso che la mia "soluzione" fosse di circa 10-12 byte.

Avevo previsto che il arrotondamento alla potenza più vicina di 2 restituisse il numero stesso se fosse un numero di due, ma a causa di un errore si arrotonda alla potenza successiva di due (ad esempio 4 -> 8 invece di 4 -> 4 ). Questo dovrà essere risolto in seguito, ma ora mi fa risparmiare un byte.


2
Non conosco MathGolf ma se ]non serve altro che formattare l'output, direi che non è necessario includerlo nel conteggio dei byte.
Shaggy,

2
Non ne ero sicuro. Poiché lo stack viene stampato in output come una stringa unita, genera uno stack con i numeri 1 e 2 come 12. Se questo conta ancora, rimuoverò un byte
maxb

Penso che dovresti lasciarlo. A volte salva un byte per generare lo stack come una stringa, a volte ti costerà un byte.
H.PWiz

@ H.PWiz era il mio pensiero originale, poiché mi sembra giusto usare i punti di forza della tua lingua. Alcune lingue stampano la parte superiore della pila solo al termine, altre la stampano come un elenco. Di solito è una differenza di 1 byte, ma fa parte della sfida.
max

8

Java 10, 89 85 70 69 68 byte

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

Porto di @Emigma risposta 05AB1E 's , quindi uscite decimali all'infinito pure.
-15 byte grazie a @Arnauld .

Provalo online.

Spiegazione:

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
Con quale frequenza posso dire che metà del conteggio dei byte? Bene, penso che questa sia la prima volta ;-)
Olivier Grégoire,

@ OlivierGrégoire Dang, ora che è un'impressionante risposta Java. :) Ho visto la tua versione a 37 byte come un commento sulla risposta di TCFP, ma hai anche eliminato più byte. Sembra così estremamente semplice ora nella tua versione da 30 byte, ma è ancora geniale come l'hai golfato dalla versione iniziale. Molto bene!
Kevin Cruijssen,



7

Java (JDK 10) , 30 byte

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

Provalo online!

Restituisce il n ° elemento nella sequenza.

Questa risposta è originariamente un susseguirsi di campi da golf della risposta Java del TCFP . Alla fine, i golf non sembravano più la risposta originale (anche se la matematica usata è la stessa), quindi ho deciso di pubblicare i golf come risposta separata invece di commentare semplicemente la risposta del TCFP. Quindi, se ti piace questa risposta, vota la risposta del TCFP ! ;-)

I golf intermedi erano:

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

E io ero seduto qui pensando che la mia risposta fosse la più breve possibile, tu vieni e la tagli di oltre la metà! Roba incredibile, merita sicuramente un +1 da parte mia.
TCFP,

@TCFP È stato un processo iterativo nell'arco di diverse ore. In realtà ho pubblicato ogni golf intermedio come commento alla tua risposta, ma li ho cancellati quando ho trovato dei golf migliori. Grazie per gli elogi ;-)
Olivier Grégoire,

6

05AB1E , 11 8 byte

Salvato 3 byte grazie a Kevin Cruijssen .

∞oDÅÉs/˜

Provalo online!

Spiegazione

∞         # 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 byte utilizzando (elenco infinito che inizia da 1):∞oεDÅÉs/}˜
Kevin Cruijssen,

@KevinCruijssen: Cool! Questo è un comando che non avevo mai visto prima. Grazie :)
Emigna,

1
Ah, e un bel modo di salvare altri due byte a causa della mappatura implicita .. Non ci avevo nemmeno pensato, lol ..
Kevin Cruijssen,

1
: O come è possibile. Hai condensato la domanda di ~ 2 pagine in 8 byte.
Cullub,

Stavo pensando di usare i numeri primi e un elenco di [1,2,4,4,8,8,8,8,16,16,...,2**n]e anteporre il numero primo indicizzato corretto seguito da un /... Ma non funzionava così bene. Bene, ma non 8-bytesbene. Qualcosa del genere 9LoDÅP)ζ.
Magic Octopus Urn,


5

PowerShell , 40 byte

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

Provalo online!

Emette la sequenza infinita come valori decimali. Date le limitazioni linguistiche, alla fine si verificheranno problemi di precisione, ma gestisce facilmente le prime 1000 voci.

Inizia impostando $i=2, quindi entra in un forciclo. Ogni iterazione, costruiamo un intervallo da 1..$ie tiriamo fuori i valori dispari con |?{$_%2}. Questi vengono inseriti nel loro ciclo interno, dove dividiamo ciascuno per ottenere il decimale |%{$_/$i}. Questi vengono lasciati sulla pipeline e inviati quando la pipeline viene scaricata dopo ogni foriterazione. Ogni iterazione stiamo semplicemente incrementando $ida $i*=2per ottenere il prossimo go-round.


5

Haskell, 35 32 byte

Modifica: -3 byte grazie a @ Delfad0r.

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

Questo è un elenco infinito di coppie di numeri interi.

Provalo online!


5

Haskell , 40 byte

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

Provalo online!

Sequenza infinita come coppie di numeri interi (a partire da (1,2)).

Un po 'più lungo della risposta di @nimi , ma l'approccio è completamente diverso, quindi ho deciso di pubblicarlo comunque.

Questa soluzione si basa sulla seguente osservazione.

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

Nota come torni alla sequenza con cui hai iniziato!

La soluzione sfrutta questo fatto (insieme alla pigrizia di Haskell) per calcolare la sequenza s.


4

Python 2 - 68 66 byte

-2 byte grazie a Kevin

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

Provalo online!


Puoi giocare a golf a 1 byte cambiando return 2*(n-a)in return(n-a)*2. E potresti salvare un byte aggiuntivo usando Python 2 anziché 3, quindi returnpuò essere print(con parentesi).
Kevin Cruijssen,

2
@KevinCruijssen Per qualcuno che non usa Python, sei sicuramente un programmatore Python migliore di me.
Don mille,

Hehe. : D Cose semplici come questa provengono dall'esperienza immagino. Sono su questo sito da circa due anni ormai credo (EDIT: da aprile 2016). A volte suggerisco persino di giocare a golf con risposte scritte in lingue che non avevo mai visto prima. Alcune cose di base funzionano nella maggior parte delle lingue. Per esempio, settimana scorsa ho suggerito un golf per una risposta T-SQL e una volta ho suggerito un golf in una risposta rossa . xD
Kevin Cruijssen,

2
44 byte usando lene bininvece di log.
Ovs,



4

R , 42 byte

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

Provalo online!

Restituisce una coppia Denominator,Numerator. Usa la formula N=2*(n-2log2(n))+1 dalla sequenza di Giuseppe Flavio e D=2log2(n)+1dall'altra sequenza. Fortunatamente siamo in grado di riutilizzare il denominatore poiché le due formule hanno molto in comune!



3

MATL , 8 byte

BnWGEy-Q

Provalo online!

Restituisce Numeratore, quindi Denominatore. Utilizza lo stesso metodo di mia risposta R , anche se è un po 'più efficiente.

Spiegazione, con 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

2

Shakespeare Programming Language , 426 byte

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

Provalo online!

Emette la sequenza all'infinito come entrambi i numeri separati da uno spazio, con ogni elemento separato da una nuova riga.


Lo adoro. LolYou be twice the sum of a cat
Cullub,

In realtà, è "il doppio della somma di un gatto un grosso gatto grande" (cioè 10 per qualche motivo).
JosiahRyanW,

2

Python 2 , 44 byte

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

Provalo online!

La funzione restituisce una tupla di (numeratore, denominatore). Un input di 0 non viene gestito (era facoltativo).


1
return 2*n-m+1,mpuò essere print-~n+n-m,mper salvare 2 byte.
Kevin Cruijssen,

2

Eccellere 48 28 byte

Risparmiato 20 byte (!) Grazie a tsh

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

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

Presuppone il valore in A1, l'output è in decimale. Se vuoi che l'output sia in frazione, puoi creare un formato personalizzato per la cella di output come "0 / ### 0" e lo mostrerà come frazione.

Spiegazione: Difficile da spiegare, poiché è stata presa una scorciatoia per arrivare a questa formula. Fondamentalmente il numeratore è un bit shift a sinistra dell'ingresso, e il denominatore è la potenza successiva di 2 superiore all'ingresso del numero.

Inizialmente ho iniziato con le funzioni integrate di Excel per BITLSHIFT e BITRSHIFT, ma queste sposteranno gli interi 48 bit che non sono quelli desiderati. Le funzioni DEC2BIN (e BIN2DEC) hanno un limite da -512 a 511 (10 bit), quindi non funzionerebbe. Invece ho dovuto ricostruire il numero con un modulo del numero originale, quindi due volte, quindi aggiungere 1 (poiché la cifra sinistra sarebbe sempre 1 prima di uno spostamento).

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

Esempi: inserisci qui la descrizione dell'immagine


Che dire =(A1+0.5)/2^INT(LOG(A1,2))-1?
TSH

2

C ++, 97 75 71 byte

-26 byte grazie a 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;}

Codice di prova:

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

Puoi semplicemente omettere if(!i)return 0;poiché 0 non è richiesto nella sfida.
TSH

1
Quando si tenta di giocare a golf in un linguaggio simile al C. Dovresti evitare di usare whilema prova for. for(;exp;)è uguale a while(exp)ma puoi scrivere altre due dichiarazioni in esso. Preferire ?:invece di if else, che sarebbe più breve nella maggior parte dei casi.
TSH

1
Non penso che tu abbia bisogno del (...)giro d-n-1.
Zacharý,


1

JavaScript (ES6), 44 byte

Restituisce il n-th term, 1-indexed.

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

Provalo online!



1

JavaScript (Node.js) , 30 byte

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

Provalo online! 0-indicizzati. Iniziato come una porta della mia risposta batch, ma sono stato in grado di calcolare in multipli di12 che ha salvato diversi byte.



1

> <> , 19 18 byte

Usando l'idea di xnor , risolto da Jo King, -1 byte sfruttando meglio i mirror e altri -2 byte da Jo King perché !era superfluo e ;non è necessario.

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

Provalo online!


Dovresti controllare prima che sia più piccolo di 2, altrimenti è il primo elemento -0.25. Risolto lo stesso numero di byte
Jo King,

Grazie! Sono anche riuscito a rimuovere un altro byte riutilizzando i mirror.
PidgeyUsedGust

Perché hai invertito la condizione? 16 byte
Jo King,

Non ho notato che avrebbe continuato il ciclo. Ci è permesso di non finire correttamente?
PidgeyUsedGust

Sì, terminare con un errore va bene finché l'OP non specifica diversamente
Jo King,


1

APL (Dyalog Unicode) , 15 byte

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

Provalo online!

Prefisso anonimo lambda.

Grazie ad Adám per 4 byte e al ciarlatano Cows per 2 byte.

Come:

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 byte

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

Provalo 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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.