半分、半分半分、そして半分


33

次の番号シーケンスを検討してください。

012143418385878116316516716916111613161516132332532

単位区間内のすべてのバイナリ分数を列挙します。[01

(この課題を簡単にするために、最初の要素はオプションです:スキップして、シーケンスが1/2で始まると考えることができます。)

仕事

プログラム(完全なプログラムまたは関数)を書く...

次の動作のいずれかを選択します。

  • 入力n、シーケンスの出力n番目の要素(0インデックスまたは1インデックス);
  • 入力n、シーケンスの最初のn個の要素を出力します。
  • 何も入力せず、1つずつ取得できる無限数列を出力します。

ルール

  • あなたのプログラムは少なくとも最初の1000項目をサポートする必要があります。
  • 必要に応じて、小数または小数(組み込み、整数ペア、文字列)を出力することを選択できます。
    • この質問では、2進数としての入力/出力は許可されていません。
  • これは、最短のコードが勝ちます。
  • 標準の抜け穴は許可されていません。

テストケース

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)a2n=2an1a2n+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:のための、又は。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、...)は、単位区間[0、1)のすべての2進小数を列挙します。-フレドリックヨハンソン、2006年8月14日


4
何も入力せず、1つずつ無限数列を出力する」1つずつである必要がありますか、または無限リスト(Haskell、Elixir、05AB1Eなどで可能)を出力することもできますか?
ケビンクルイッセン

文字列のリストを出力できますか?例"1/2" "1/4" "1/8"...
Barranka

@KevinCruijssen無限リストは、後でリストtakeからn個の要素ができる限り問題ありません。
tsh

@Barranka許容範囲内だと思います。それは分数を標準出力に出力するのと何も変わりません。
tsh

入力/出力を2進数として許可しないと言う場合、intsの場合にペアを返す関数、またはIEEE binary64形式を使用doubleする言語/実装でa を返す関数を作成できないことを意味しdoubleます。整数入力を取得する場合、ASCII文字列を解析する必要があったことを意味しないことを願っていますか?通常の整数型は、Cのような言語ではバイナリです。または、入力/出力が整数またはASCIIゼロ/ 1の配列または文字列であってはいけないということですか?
ピーター

回答:


22

Haskell、25バイト

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

オンラインでお試しください!

最初のゼロ項なしで1から始まる小数を出力します。

入力に0.5を加算し、結果が2未満になるまで半分にし、1を減算します。ポイントフリーの式を使用すると、1バイト節約できます

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

11

Java 10、68 64バイト

最初にコードゴルフをお試しください!

オプション1:n番目の要素を見つける(1-indexed)

@Kevin Cruijssenのおかげで-4バイト

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

これが見つかった匿名メソッドであるNから最上位ビットを除去することにより、目の用語を、Nを2の次に高い電力で割り、それを倍加し、一方を添加します。

オンラインでお試しください!

コードウォークスルー:

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へようこそ、私たちと一緒にいてくれてうれしいです:)
シャギー

こんにちは、PPCGへようこそ!すばらしい最初の答え、私からの+1。現在、Javaの回答と同じバイトカウントですが、回答の一部をゴルフでより短くすること{}ができます。アフターループを;代わりに使用できます。return;の後のスペースを削除できます。2.0することができます2.; そして、変更n>>x!=1;x++1<<xおよび1<<x+1n>>x++!=1;1<<x-11<<xそれぞれもバイトを保存します。オンラインで試してみてください:64バイト。滞在を楽しんで!
ケビンクルーイッセン

あなたはまだそれを見ていない場合はああ、と:ヒントJavaでゴルフのために<すべての言語>でのゴルフのためのヒントをお読み両方かなり興味深いものです。:)
ケビンクルーイッセン

もともとはあなたのものに基づいていたが、ゴルフとゴルフとゴルフをした私の30バイトの答えをご覧ください。
オリヴィエグレゴワール

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のべき乗に切り上げることを意図していましたが、ミスのために2のべき乗に丸められます(たとえば、4-> 4の代わりに4-> 8 )。これは後で修正する必要がありますが、今では1バイト節約できます。


2
MathGolfはわかりませんが]、出力の書式設定以外の目的がない場合は、バイトカウントに含める必要はありません。
シャギー

2
私はそれについて確信がありませんでした。スタックが参加した文字列として出力にプリントされているのでそれはまだ私がバイト削除いたしカウントした場合、それは数字1と12と2とのスタックを出力
MAXB

スタックを1つの文字列として出力するために1バイトを節約することもあれば、1バイトかかることもあります。
H.PWiz

@ H.PWizそれは私の元々の考えでした。あなたの言語の長所を使うのが公平だからです。一部の言語は、終了時にスタックの最上部のみを印刷し、一部はリストとして印刷します。通常、これは1バイトの違いですが、これは課題の一部です。
maxb

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回答のポート。したがって、小数も無期限に出力します。@Arnauldの
おかげで-15バイト。

オンラインでお試しください。

説明:

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égoireDang、今では印象的なJavaの回答です。:) TCFPの回答に対するコメントとして37バイトバージョンを見ましたが、さらにバイトを削除しました。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これは、数時間にわたる反復プロセスでした。実際に各中間ゴルフをあなたの答えへのコメントとして投稿しましたが、より良いゴルフを見つけたのでそれらを削除しました。賞賛に感謝;-)
オリビエグレゴワール

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/}˜
Kevin Cruijssen

@KevinCruijssen:かっこいい!それは私が前に見たことがなかったコマンドです。ありがとう:)
エミグナ

1
さらに2つの節約のああ、そして良い方法暗黙的なマッピングのためにバイト...でも...笑、そのことについて考えていなかった
ケビンCruijssen

1
:Oこれはどのように可能ですか。〜2ページの質問を8バイトに圧縮しました。
カラブ

私は、素数とリストを使用し[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}}

オンラインでお試しください!

無限シーケンスを10進数値として出力します。言語の制限を考えると、最終的に精度の問題が発生しますが、最初の1000エントリを簡単に処理できます。

を設定して開始し$i=2forループに入ります。各反復で、から範囲を構築1..$iし、で奇数の値を引き出します|?{$_%2}。それらは独自の内部ループに送られ、それぞれを分割して小数を取得します|%{$_/$i}。これらはパイプラインに残され、各for反復後にパイプラインがフラッシュされるときに出力されます。各反復は、次のラウンドを取得するために単純に増分$i$i*=2ています。



5

Haskell、40バイト

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

オンラインでお試しください!

(から始まる(1,2))整数のペアとしての無限シーケンス。

@nimiの答えよりもかなり長いですが、アプローチは完全に異なるため、とにかく投稿することにしました。

このソリューションは、次の観察に基づいています。

{12143418385878116316}

  • j{212j2+12j}
    {{1434}{1838}{5878}{116316}}
  • {143418385878116316}
  • 追加12
    {12143418385878116316}

開始したシーケンスに戻る方法に注目してください!

ソリューションは、この事実を(Haskellの怠inessとともに)利用して、シーケンスを計算しますs


4

Python 2-68 66バイト

-ケビンのおかげで2バイト

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プログラマーです。
ドンサウザンド

へへ。:Dこのような単純なことは、私が推測する経験を伴っています。私はこのサイトに約2年間います(編集:2016年4月以降)。私は時々、今まで見たことのない言語で書かれた答えをゴルフに提案することさえあります。たとえば、先週、私はT-SQLの答えにゴルフを提案し、かつて赤の答えにゴルフを提案しました。xD
ケビンクルーイッセン

2
代わりにlenとを使用した44バイトbinlog
ovs


4

Pythonの353の 51バイト

def f(m=2,n=1):n<m and print(n/m)&f(m,2+n)or f(m+m)

オンラインでお試しください!


パラメーターを交換して2バイトを保存しますdef f(m=2,n=1):n<m and print(n/m)&f(m,n+2)or f(m+m)
。– mypetlion

1
@mypetlionクール、ありがとう!
ジョナサンフレッチ

4

R、42バイト

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

オンラインでお試しください!

Denominator,NumeratorN=2n2ログ2n+1D=2ログ2n+1



3

MATL、8バイト

BnWGEy-Q

オンラインでお試しください!

Numerator、Denominatorを返します。R answerと同じ方法を使用しますが、少し効率的です。

説明、入力あり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
カラブ

実際には、「猫の合計の2倍の大きな猫」​​(つまり、何らかの理由で10匹)です。
-JosiahRyanW


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の値を想定し、出力は10進数です。出力を分数で表示する場合は、出力セルのカスタム形式を「0 / ### 0」として作成すると、分数として表示されます。

説明: この式に到達するためのショートカットがあるため、説明するのは困難です。基本的に、分子は入力の左ビットシフトであり、分母は数値入力より次に大きい2のべき乗です。

私はもともとBITLSHIFTおよびBITRSHIFTのExcel組み込み関数を使用していましたが、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、Zacharyのおかげ

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
ゴルフのようなCのような言語。使用は避けてwhileくださいforfor(;exp;)と同じwhile(exp)ですが、さらに2つのステートメントを記述できます。の?:代わりにif else、ほとんどの場合は短くなります。
tsh

1
(...)周りは必要ないと思うd-n-1
ザカリー






1

> <>19 18バイト

使用XNORのアイデアので、鏡とジョー・キング他-2バイトをより有効に利用することによって、ジョー・キングにより固定、-1バイトを!余分だったし、;必要とされていませんが。

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

オンラインでお試しください!


最初に2より小さいかどうかを確認する必要があり-0.25ます。そうでない場合、最初の要素はです。同じバイト数の修正
ジョーキング

ありがとう!また、ミラーを再利用して別のバイトを削除することもできました。
PidgeyUsedGust

なぜ条件を逆転させたのですか?16バイト
ジョーキング

ループが続くことに気づかなかった。適切に終了しないことは許されますか?
PidgeyUsedGust

ええ、OPで特に指定しない限り、エラーで終了しても問題ありません
ジョーキング


1

APL(Dyalog Unicode)、15バイト

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

オンラインでお試しください!

匿名プレフィックスラムダ。

4バイトのAdámと2バイトのCows quackに感謝します。

どうやって:

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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.