一半,一半,一半


33

请考虑以下数字顺序:

01个21个4341个83858781个163165167169161116131615161个32332532

它枚举单位间隔中的所有二进制分数。[01个

(为简化此挑战,第一个元素是可选的:您可以跳过它,并考虑序列以1/2开头。)

任务

编写一个程序(完整的程序或功能),以...

选择以下行为之一:

  • 输入n,输出序列的第n个元素(0索引或1索引);
  • 输入n,输出序列的前n个元素;
  • 不输入任何内容,输出可以一一取整的无限数序列;

规则

  • 您的程序至少应支持前1000个项目;
  • 您可以根据需要选择输出小数或分数(内置,整数对,字符串)。
    • 此问题中不允许输入/输出为二进制数字;
  • 这是,最短的代码获胜;
  • 不允许出现标准漏洞。

测试用例

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

这些示例基于0索引序列,其中包括前导0。您需要调整输入以适合您的解决方案。

阅读更多

  • OEIS A006257
    • 约瑟夫斯问题:。(以前为M2216)一种2ñ=2一种ñ-1个一种2ñ+1个=2一种ñ+1个
    • 0、1、1、3、1、3、5、7、1、3、5、7、9、11、13、15、1、3、5,...
  • OEIS A062383
    • :对于 Ñ > 0一个Ñ = 2 ø 2 Ñ + 1 一个ñ = 2 一个Ñ一种0=1个ñ>0一种ñ=2ØG2ñ+1个一种ñ=2一种ñ2
    • 1,2,4,4,8,8,8,8,16,16,16,16,16,16,16,32,32,32,...
  • A006257(n)/ A062383(n)=(0,0.1,0.01,0.11,0.001,...)枚举单位间隔[0,1)中的所有二进制分数。-Fredrik Johansson,2006年8月14日


4
“不输入任何内容,一个接一个地输出无限数序列 ”是否必须一对一地输出,还是我们也可以输出一个无限列表(可能在Haskell,Elixir,05AB1E等中使用)?
凯文·克鲁伊森

我可以输出字符串列表吗?例如"1/2" "1/4" "1/8"...
Barranka

@KevinCruijssen无限列表很好,只要take以后可以从中使用n个元素即可。
tsh

@Barranka我认为这是可以接受的。将分数打印到stdout并没有什么不同。
tsh

当您说不允许输入/输出为二进制数时,表示我们不能编写一个返回值if int的对的函数,或者不能使用使用IEEE binary64格式double的语言/实现编写返回a的函数?我希望您不是要想接受整数输入就必须解析ASCII字符串吗?普通的整数类型在诸如C之类的语言中是二进制的。或者您是说输入/输出不能是整数或ASCII零/一的数组或字符串?double
彼得·科德斯

Answers:


22

Haskell,25个字节

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

在线尝试!

输出小数,一个索引,不带初始零项。

将0.5加到输入,然后减半直到结果低于2,然后减1。使用无点表达式可节省1个字节

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

11

Java 10、68 64字节

首先尝试打码高尔夫!

选项1:找到第n个元素(1-索引)

-4个字节,感谢@Kevin Cruijssen

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

这是一种匿名方法,它通过从n中删除最高有效位,将其加倍并加一个,然后除以第二高位次幂来找到第n个项。

在线尝试!

代码演练:

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`

如果需要打印最终值而不是返回最终值,将进行编辑。


欢迎来到PPCG,很高兴与您在一起:)
Shaggy

嗨,欢迎来到PPCG!很好的第一答案,我+1。目前,它是相同的字节数作为我的Java的答案,但你仍然可以打高尔夫球你的答案的某些部分,使其比我短:该{}循环之后可以是;代替; 您可以在return; 之后删除空格;2.0可以2.; 和改变n>>x!=1;x++1<<x以及1<<x+1n>>x++!=1;1<<x-11<<x分别还可以节省一个字节。在线尝试:64个字节。入住愉快!
凯文·克鲁伊森

哦,如果您还没有看过:Java高尔夫技巧<all language>高尔夫技巧通读都非常有趣。:)
Kevin Cruijssen

看到我的30个字节的答案,最初是根据您的答案,但是打高尔夫球,打高尔夫球和打高尔夫球。
OlivierGrégoire18年

9

MathGolf5 4字节

╫\╨]

在线尝试!

操作员正常工作时的外观

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

在线尝试!

说明

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

我从这个问题中得到了启发来解决问题,我认为“自己的”解决方案约为10-12个字节。

我原本打算四舍五入到最接近的2的幂以返回数字本身(如果它是2的话),但是由于错误,它会四舍五入到2的下一个幂(例如4-> 8而不是4-> 4 )。稍后必须解决此问题,但是现在它为我节省了一个字节。


2
我不了解MathGolf,但是如果]除了格式化输出没有其他用途,我想说您不需要将其包括在字节数中。
毛茸茸的

2
我不确定。由于堆栈是作为连接字符串打印在输出上的,因此它输出带有1和2的堆栈为12的堆栈。如果仍然
有用,

我认为您应该将其保留。它有时会保存一个字节以将堆栈作为一个字符串输出,有时会花费您一个字节。
H.PWiz

@ H.PWiz是我最初的想法,因为使用您的语言优势似乎很公平。有些语言仅在完成后才打印堆栈的顶部,有些则将其打印为列表。通常这是1个字节的差异,但这是挑战的一部分。
maxb 18/09/14

8

Java 10、89 85 70 69 68字节

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

@Emigma的05AB1E答案的端口,因此也将无限期地输出小数。
-15个字节,感谢@Arnauld

在线尝试。

说明:

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
我多久能说出我一半的字节数?好吧,我认为这是第一次;-)
OlivierGrégoire18年

@OlivierGrégoireDang,现在这是一个令人印象深刻的Java答案。:)我看到您的37字节版本是对TCFP答案的评论,但您甚至剥离了更多字节。现在,在您的30字节版本中,它看起来非常简单,但是从初始版本开始打高尔夫球仍然很巧妙。做得好!
凯文·克鲁伊森



7

Java(JDK 10),30字节

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

在线尝试!

返回序列中的第n 项目。

该答案最初是TCFP Java答案一连串高尔夫球。最后,高尔夫球看起来不再像原始答案一样(尽管使用的数学是相同的),所以我决定将高尔夫球作为单独的答案发布,而不是简单地评论TCFP的答案。因此,如果您喜欢此答案,请同时支持TCFP的答案!;-)

中级高尔夫是:

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

我坐在这里,以为我的回答越短越好,您快来把它减少一半以上!惊人的东西,绝对值得我+1。
TCFP

@TCFP这是一个长达数小时的迭代过程。我实际上将每个中级高尔夫发布为您的答案的评论,但由于发现更好的高尔夫而将其删除。感谢您的称赞;-)
OlivierGrégoire18

6

05AB1E11 8字节

感谢Kevin Cruijssen保存了3个字节。

∞oDÅÉs/˜

在线尝试!

说明

∞         # 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个字节(从1开始的无限列表):∞oεDÅÉs/}˜
凯文·克鲁伊森

@KevinCruijssen:太好了!这是我以前从未见过的命令。谢谢:)
Emigna '18

1
嗯,和不错的方式挽救了两个多字节由于隐映射的..甚至都没有想过这个问题,哈哈..
凯文Cruijssen

1
:O这怎么可能。您将〜2页问题压缩为8个字节。
Cullub

我当时在考虑使用质数和列表,[1,2,4,4,8,8,8,8,16,16,...,2**n]并在正确的索引质数后面加上一个/...,但是效果不是很好。好吧,但是8-bytes不好。有点像9LoDÅP)ζ
魔术章鱼缸


5

PowerShell,40字节

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

在线尝试!

将无限序列输出为十进制值。给定语言限制,最终会遇到精度问题,但可以轻松处理前1000个条目。

从设置开始$i=2,然后进入for循环。每次迭代时,我们都会从构造一个范围,1..$i并使用提取出奇数值|?{$_%2}。它们被送入它们自己的内部循环,在这里我们将每个循环除以得到小数|%{$_/$i}。每次for迭代后,这些都将留在管道上并在管道被冲洗时输出。每次迭代,我们只是简单地增加$i通过$i*=2获得下一个去轮。


5

Haskell,35 32字节

编辑:-3个字节,感谢@ Delfad0r。

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

这是整数对的无限列表。

在线尝试!


5

Haskell,40个字节

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

在线尝试!

无限序列为整数对(从开始(1,2))。

@nimi的答案要长一些,但是方法完全不同,所以我还是决定将其发布。

该解决方案基于以下观察。

{1个21个4341个83858781个16316}
并执行以下步骤。

  • 替换每个数字 一世Ĵ 按照列表的顺序 {2一世-1个2Ĵ2一世+1个2Ĵ}
    {{1个434}{1个838}{5878}{1个16316}}
  • 将所有列表合并为一个序列:
    {1个4341个83858781个16316}
  • 1个2 在序列的开头:
    {1个21个4341个83858781个16316}

请注意,您如何回到开始的顺序!

该解决方案利用这一事实(连同Haskell的惰性)来计算序列s


4

Python 2-68 66字节

-2字节感谢Kevin

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

在线尝试!


您可以通过更改return 2*(n-a)为来打高尔夫球1个字节return(n-a)*2。您可以使用Python 2而不是3来节省一个额外的字节,所以return可以print(带括号)。
凯文·克鲁伊森

2
@KevinCruijssen对于不使用Python的人,您当然是比我更好的Python程序员。
Don Thousand

呵呵。:D这样的简单事情会带来经验。我认为我现在已经在这个网站上待了两年(编辑:自2016年4月起)。有时我甚至会建议用以前从未见过的语言写出来的答案。.一些基本的东西在大多数语言中都有效。例如,上周我建议为T-SQL答案打高尔夫球,而我曾经为Red答案打高尔夫球。xD
Kevin Cruijssen

2
使用lenbin代替44个字节log
ovs



4

R,42个字节

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

在线尝试!

返回一对Denominator,Numerator。使用公式 ñ=2ñ-2日志2ñ+1个 从约瑟夫斯序列和 d=2日志2ñ+1个从另一个序列。令人高兴的是,我们能够重用分母,因为这两个公式有很多共同点!



3

MATL,8字节

BnWGEy-Q

在线尝试!

返回分子,然后分母。使用与我的R答案相同的方法,尽管效率更高一些。

输入说明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

莎士比亚编程语言,426字节

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

在线尝试!

将序列无限地输出为两个数字,两个数字之间用空格隔开,每个项目之间用换行符隔开。


爱它。大声笑You be twice the sum of a cat
Cullub

实际上,这是“一只大猫的猫总和的两倍”(即出于某种原因10只)。
JosiahRyanW

2

Python 2,44字节

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

在线尝试!

函数返回一个元组(分子,分母)。输入0不会被处理(这是可选的)。


1
return 2*n-m+1,m可以print-~n+n-m,m节省2个字节。
凯文·克鲁伊森

2

Excel 48 28字节

由于tsh,节省了20个字节(!)

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

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

假设A1中的值,输出为十进制。如果希望输出为小数,则可以为输出单元格创建一个自定义格式为“ 0 / ### 0”,并将其显示为小数。

说明: 难以解释,因为采用了捷径可到达此公式。分子基本上是输入的左移,分母是输入数字的下一个2的幂。

我最初是从Excel内置的BITLSHIFT和BITRSHIFT函数开始的,但是它们会移位整个48位,这不是您想要的。函数DEC2BIN(和BIN2DEC)的限制是-512到511(10位),因此这是行不通的。取而代之的是,我不得不用原始数字的模数来重建数字,然后乘以2,然后加1(因为左位数字在移位前总是1)。

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

例子: 在此处输入图片说明


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

2

C ++,97 75 71字节

-26字节,感谢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;}

测试代码:

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

您可能只是省略了,if(!i)return 0;因为挑战中不需要0。
tsh

1
当尝试打高尔夫球一样的语言。您应该避免使用,while但请尝试forfor(;exp;)与相同,while(exp)但是您可以再写两个其他语句。选择?:而不是if else,在大多数情况下会更短一些。
tsh

1
我认为您不需要(...)周围的东西d-n-1
扎卡里


1

JavaScript(ES6),44个字节

返回 ñ-第一项,以1为索引。

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

在线尝试!





1

> <>19 18字节

使用由乔·金(Jing)固定的xnor的想法,可以更好地利用镜子,从而减少-1个字节,而乔·金(Jo King)!则另加-2个字节,因为多余了,;不是必需的。

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

在线尝试!


您应该先检查它是否小于2,否则第一个元素是-0.25修复相同数量的字节
Jo King

谢谢!我还通过重用镜像删除了另一个字节。
PidgeyUsedGust

你为什么要逆转病情?16个字节
Jo King

没注意到它会继续循环。允许我们没有正确完成吗?
PidgeyUsedGust

是啊,终止与错误是罚款,只要OP未指定其他
乔金


1

APL(Dyalog Unicode),15字节

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

在线尝试!

匿名前缀lambda。

感谢Adám提供4个字节,并感谢Cows quack提供2个字节。

怎么样:

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字节

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

在线尝试!

取消高尔夫:

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
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.