Metade, Metade Metade e Metade


33

Considere a seguinte sequência numérica:

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

Enumera todas as frações binárias no intervalo de unidades .[0,1)

(Para facilitar esse desafio, o primeiro elemento é opcional: você pode ignorá-lo e considerar que a sequência começa com 1/2.)

Tarefa

Escreva um programa (programa completo ou função) que ...

Escolha um destes comportamentos:

  • Entrada n, elemento de saída enésimo da sequência (indexado 0 ou indexado 1);
  • Entrada n, gera os primeiros n elementos da sequência;
  • Não introduza nada, produza a sequência numérica infinita que pode ser tirada uma a uma;

Regra

  • Seu programa deve pelo menos suportar os primeiros 1000 itens;
  • Você pode optar por imprimir decimais ou frações (interno, par inteiro, seqüências de caracteres) como desejar;
    • Entrada / Saída como dígitos binários não é permitida nesta pergunta;
  • Este é o , os códigos mais curtos vencem;
  • Falhas padrão não permitidas.

Casos de teste

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

Esses exemplos são baseados na sequência indexada em 0, com o 0 inicial incluído. Você precisaria ajustar a entrada para ajustar sua solução.

consulte Mais informação

  • OEIS A006257
    • Problema de Josefo: . (Anteriormente 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
    • a0=1 : para , ou .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, ...) enumera todas as frações binárias no intervalo de unidade [0, 1). - Fredrik Johansson, 14 de agosto de 2006


4
"Não introduza nada, produza a sequência numérica infinita, um por um " Tem que ser um por um ou também é permitido gerar uma lista infinita (possível em Haskell, Elixir, 05AB1E, etc.)?
Kevin Cruijssen

Posso gerar uma lista de strings? por exemplo"1/2" "1/4" "1/8"...
Barranka 14/09

A lista infinita @KevinCruijssen é boa, desde que você possa taken elementos dela mais tarde.
tsh

@ Barranka Eu acho que é aceitável. Isso não é diferente para imprimir frações em stdout.
tsh

Quando você diz que Entrada / Saída como números binários não é permitido , você quer dizer que não podemos escrever uma função que retorne um par se ints, ou a doubleem uma linguagem / implementação em que doubleuse o formato IEEE binary64 ? Espero que você não queira dizer que foi necessário analisar uma seqüência de caracteres ASCII se quisermos obter uma entrada inteira? Tipos inteiros normais são binários em idiomas como C. Ou você quer dizer que a entrada / saída não pode ser uma matriz ou sequência de números inteiros ou zeros / uns ASCII?
Peter Cordes

Respostas:


22

Haskell , 25 bytes

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

Experimente online!

Gera decimais, um indexado sem o termo zero inicial.

Adiciona 0,5 à entrada e, em seguida, reduz pela metade até que os resultados estejam abaixo de 2 e subtrai 1. O uso de uma expressão sem pontos salva 1 bytes sobre

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

11

Java 10, 68 64 bytes

Primeira tentativa no código de golfe!

Opção 1: encontre o n- ésimo elemento (indexado 1)

-4 bytes graças a @Kevin Cruijssen

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

Este é um método anônimo que encontra o n- ésimo termo removendo o bit mais significativo de n , dobrando-o e adicionando um, depois dividindo pela próxima potência mais alta de 2.

Experimente online!

Passo a passo do código:

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`

Editará se for necessário imprimir o valor final em vez de retorná-lo.


Bem-vindo ao PPCG, é bom tê-lo conosco :)
Shaggy

Olá, seja bem-vindo ao PPCG! Ótima primeira resposta, +1 de mim. Atualmente, é o mesmo número de bytes que a minha resposta Java, mas você ainda pode jogar algumas partes da sua resposta para torná-la mais curta que a minha: O {}depois do loop pode ser um ;; você pode remover o espaço após o return; 2.0pode ser 2.; E mudando o n>>x!=1;x++, 1<<xe 1<<x+1para n>>x++!=1;, 1<<x-1, 1<<xrespectivamente, também guarda um byte. Experimente online: 64 bytes . Aproveite sua estadia!
Kevin Cruijssen 14/09

Ah, e se você ainda não viu: Dicas para jogar golfe em Java e Dicas para jogar em <todos os idiomas> são bastante interessantes de se ler. :)
Kevin Cruijssen 14/09

Veja minha resposta de 30 bytes , originalmente baseada na sua, mas jogava golfe, jogava golfe e jogava golfe.
Olivier Grégoire

9

MathGolf , 5 4 bytes

╫\╨]

Experimente online!

Como seria o funcionamento correto do operador

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

Experimente online!

Explicação

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

Tirei minha inspiração desta questão para resolver o problema, minha solução "própria" era de 10 a 12 bytes, eu acho.

Eu pretendia que o arredondamento até a potência mais próxima de 2 retornasse o número em si, se fosse um número de dois, mas, devido a um erro, ele arredonda para a próxima potência de dois (por exemplo, 4 -> 8 em vez de 4 -> 4 ) Isso terá que ser corrigido mais tarde, mas agora me salva um byte.


2
Eu não conheço o MathGolf, mas se o ]objetivo não for outro senão formatar a saída, eu diria que você não precisa incluí-la na sua contagem de bytes.
Shaggy

2
Eu não tinha certeza disso. Desde a pilha é impresso na saída como uma string se juntou, ele gera uma pilha com os números 1 e 2, 12. se isso conta ainda vou remover um byte
maxb

Eu acho que você deve deixá-lo dentro. Às vezes, salva um byte para gerar a pilha como uma string, às vezes, custa um byte.
H.PWiz

@ H.PWiz esse era o meu pensamento original, pois parece justo usar os pontos fortes do seu idioma. Alguns idiomas imprimem apenas a parte superior da pilha quando terminados, alguns imprimem como uma lista. Normalmente, é uma diferença de 1 byte, mas faz parte do desafio.
maxb

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

Porto de @Emigma resposta 05AB1E 's , por isso saídas decimais indefinidamente também.
-15 bytes graças a @Arnauld .

Experimente online.

Explicação:

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
Com que frequência posso dizer que tenho metade da sua contagem de bytes? Bem, eu acho que esta é a primeira vez ;-)
Olivier Grégoire

@ OlivierGrégoire Dang, agora essa é uma resposta impressionante do Java. :) Vi sua versão de 37 bytes como comentário na resposta do TCFP, mas você ainda retirou mais bytes. Parece tão extremamente simples agora na sua versão de 30 bytes, mas ainda é engenhoso como você jogou a partir da versão inicial. Bem feito!
Kevin Cruijssen 17/09/09



7

Java (JDK 10) , 30 bytes

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

Experimente online!

Retorna o enésimo item na sequência.

Esta resposta é originalmente uma sucessão de campos de golfe da resposta Java do TCFP . No final, os campos não pareciam mais a resposta original (embora a matemática usada seja a mesma), então eu decidi postar os campos como uma resposta separada, em vez de simplesmente comentar a resposta do TCFP. Portanto, se você gosta desta resposta, suba também à resposta do TCFP ! ;-)

Os golfe intermediários foram:

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 eu estava sentado aqui, pensando que minha resposta era a mais curta possível; você vem e corta por mais da metade! Coisas incríveis, definitivamente merece um +1 de mim.
TCFP 17/09/18

@TCFP Foi um processo iterativo ao longo de várias horas. Na verdade, eu publiquei cada golfe intermediário como um comentário à sua resposta, mas os excluí porque encontrei melhores golfe. Obrigado pelo elogio ;-)
Olivier Grégoire

6

05AB1E , 11 8 bytes

Economizou 3 bytes graças a Kevin Cruijssen .

∞oDÅÉs/˜

Experimente online!

Explicação

∞         # 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 usando (lista infinita começando em 1):∞oεDÅÉs/}˜
Kevin Cruijssen 14/09

@KevinCruijssen: Cool! Esse é um comando que eu não tinha visto antes. Obrigado :)
Emigna 15/09/18

1
Ah, e boa maneira de poupar mais dois bytes devido ao mapeamento implícito .. ainda não tinha pensado sobre isso, lol ..
Kevin Cruijssen

1
: O como isso é possível. Você condensou a pergunta de ~ 2 páginas em 8 bytes.
Cullub

Eu estava pensando em usar os números primos e uma lista [1,2,4,4,8,8,8,8,16,16,...,2**n]e preceder o primo indexado correto seguido por um /... Mas isso não estava funcionando tão bem. Bem, mas não 8-bytesbem. Algo como 9LoDÅP)ζ.
Magic Octopus Urn


5

PowerShell , 40 bytes

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

Experimente online!

Produz a sequência infinita como valores decimais. Dadas as limitações de idioma, eventualmente ocorrerá problemas de precisão, mas lida facilmente com as primeiras 1000 entradas.

Inicia definindo $i=2e entra em um forloop. A cada iteração, construímos um intervalo 1..$ie extraímos os valores ímpares com |?{$_%2}. Esses são alimentados em seu próprio loop interno, onde dividimos cada um para obter o decimal |%{$_/$i}. Elas são deixadas no pipeline e produzidas quando o pipeline é liberado após cada foriteração. Cada iteração estamos simplesmente incrementar $ipor $i*=2para obter o próximo go-round.


5

Haskell, 35 32 bytes

Edit: -3 bytes graças a @ Delfad0r.

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

Esta é uma lista infinita de pares inteiros.

Experimente online!


5

Haskell , 40 bytes

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

Experimente online!

Sequência infinita como pares de números inteiros (a partir de (1,2)).

Um pouco mais do que a resposta de @ nimi , mas a abordagem é completamente diferente, então decidi publicá-la de qualquer maneira.

Esta solução é baseada na seguinte observação.

Considere a sequência infinita

{12,14,34,18,38,58,78,116,316,...}
e aplique as etapas a seguir.

  • Substitua todos os números Euj na sequência com a lista {2Eu-12j,2Eu+12j}:
    {{14,34},{18,38},{58,78},{116,316},...}
  • Junte todas as listas em uma única sequência:
    {14,34,18,38,58,78,116,316,...}
  • Adicionar 12 no início da sequência:
    {12,14,34,18,38,58,78,116,316,...}

Observe como você volta à sequência em que começou!

A solução explora esse fato (junto com a preguiça de Haskell) para calcular a sequência s.


4

Python 2-68 66 bytes

-2 bytes graças a Kevin

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

Experimente Online!


Você pode jogar golfe com 1 byte, alterando return 2*(n-a)para return(n-a)*2. E você pode salvar um byte adicional usando Python 2 em vez de 3, assim returnpode ser print(com parênteses).
Kevin Cruijssen 14/09

2
@KevinCruijssen Para alguém que não usa Python, você certamente é um programador de Python melhor do que eu.
18892 Don Thousand

Ele Ele. : D Coisas simples como essa vêm com a experiência, eu acho. Estou neste site há cerca de dois anos agora (EDIT: desde abril de 2016). Às vezes, até sugeri coisas ao golfe, para obter respostas escritas em idiomas que nunca tinha visto antes. Algumas coisas básicas funcionam na maioria dos idiomas. Por exemplo, na semana passada, sugeri um golfe para uma resposta T-SQL e uma vez sugeri um golfe em uma resposta vermelha . xD
Kevin Cruijssen

2
44 bytes usando lene em binvez de log.
ovs 15/09/18



4

R , 42 bytes

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

Experimente online!

Retorna um par Denominator,Numerator. Usa a fórmula N=2(n-2registro2(n))+1 da sequência Josephus e D=2registro2(n)+1da outra sequência. Felizmente, podemos reutilizar o denominador, pois as duas fórmulas têm muito em comum!



3

MATL , 8 bytes

BnWGEy-Q

Experimente online!

Retorna Numerador e Denominador. Usa o mesmo método da minha resposta R , embora seja um pouco mais eficiente.

Explicação, com entrada 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

Linguagem de programação de Shakespeare , 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.

Experimente online!

Produz a sequência infinitamente como os dois números separados por um espaço, com cada item sendo separado por uma nova linha.


Adoro. LolYou be twice the sum of a cat
Cullub 17/09/18

Na verdade, é "o dobro da soma de um gato, um gato grande" (ou seja, 10 por algum motivo).
JosiahRyanW


2

Excel 48 28 Bytes

Economizou 20 bytes (!) Graças 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))

Assume o valor em A1, a saída é decimal. Se você deseja que a saída esteja na fração, é possível criar um formato personalizado para a célula de saída como "0 / ### 0" e ela será exibida como fração.

Explicação: Difícil de explicar, pois existe um atalho para chegar a essa fórmula. Basicamente, o numerador fica um deslocamento à esquerda da entrada e o denominador é a próxima potência 2 maior que a entrada numérica.

Inicialmente, comecei com as funções incorporadas do Excel para BITLSHIFT e BITRSHIFT, mas elas deslocam os 48 bits inteiros, o que não é o que você deseja. As funções DEC2BIN (e BIN2DEC) têm um limite de -512 a 511 (10 bits), portanto, isso não funcionaria. Em vez disso, tive que reconstruir o número com um módulo do número original, depois duas vezes e depois adicionar 1 (já que o dígito esquerdo sempre seria 1 antes de um turno).

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

Exemplos: insira a descrição da imagem aqui


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

2

C ++, 97 75 71 bytes

-26 bytes graças 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;}

Código de teste:

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

Você pode simplesmente omitir, if(!i)return 0;já que 0 não é necessário no desafio.
tsh

1
Ao tentar jogar na linguagem C. Você deve evitar usar, whilemas tente for. for(;exp;)é o mesmo, while(exp)mas você pode escrever mais duas declarações nele. Prefira em ?:vez de if else, o que seria mais curto na maioria dos casos.
tsh

1
Eu não acho que você precise do (...)entorno d-n-1.
Zacharý 23/09/18






1

> <> , 19 18 bytes

Usando a idéia do xnor , corrigida por Jo King, -1 byte, fazendo melhor uso dos espelhos e outros -2 bytes por Jo King, porque !era supérfluo e; não é necessário.

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

Experimente online!


Você deve verificar se é menor que 2 primeiro, caso contrário, o primeiro elemento é -0.25. Fixar para a mesma quantidade de bytes
Jo Rei

Obrigado! Também consegui remover outro byte reutilizando os espelhos.
PidgeyUsedGust

Por que você inverteu a condição? 16 bytes
Jo King

Não percebeu que continuaria o ciclo. Temos permissão para não terminar adequadamente?
usar o seguinte código

Sim, terminar com um erro é bom, desde que o OP não especifique o contrário
Jo King


1

APL (Dyalog Unicode) , 15 bytes

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

Experimente online!

Prefixo anônimo lambda.

Agradecimentos a Adám por 4 bytes e a Vacas charlatão por 2 bytes.

Quão:

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 bytes

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

Experimente 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
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.