分数フレンジー!


9

編集:私はこれが終了しないことについて多くのコメントを受け取っています-私は私に与えた最初の人にFF(3)(正しい答えでそれを提供するように)「正解」タグを与えるか、それFF(3)が本当に無期限に爆破することを証明します。

仕事:

あなたの仕事はFF(n)、正の整数を与えられた分数フレンジー関数()の逆数のリストを生成する可能な限り最小のプログラムを作ることnです。

前書き:

FF関数を紹介する前に、まずエジプトの分数について説明する必要があります。

エジプトの分数:

エジプトの分数は、分数を個別の単位分数の合計として表す方法5/8です1/2 + 1/8。したがって、分数を表す1つの方法はです。それは他の分数の合計ではありません

1/4 + 1/4 + 1/8
1/2 + 1/16 + 1/16

すべての分数が異なるわけではないためです(1/4最初の例と1/162番目の例で繰り返されます)。

エジプトの分数の定義では、単位分数にも負の分母の使用を含めています。

FF関数:

FF(Fraction Frenzy)関数は次のように記述されます:

FF(1)エジプトの分数1/2 + 1/3 + 1/5 + 1/-30です。

FF(2)FF(1)単独で「乗算」に等しい(FF(1)「二乗」):

  (1/2 + 1/3 + 1/5 + 1/-30)(1/2 + 1/3 + 1/5 + 1/-30)
= 1/4 + 1/6 + 1/10 + 1/-60 + 1/6 + 1/9 + 1/15 + 1/-90 +
  1/10 + 1/15 + 1/25 + 1/-150 + 1/-60 + 1/-90 + 1/-150 + 1/900

分数には「繰り返し」があるため、これはまだ完全に削減されたエジプトの分数ではありません。それらを減らすために、次の手順が実行されます。

  1. すべての「類似した」単位分数を合計します。
  2. 最も単純な形態に和を減らす-ので、例えば、ステップの合計が場合1である2/6に低減することができます、1/3
  3. すべての分母が区別されるまで、1と2を繰り返します。たとえば、分母が繰り返されるとは1/2 + 2/3 + 1/5対照的に1/2 + 1/3 + 1/33です。
  4. 絶対値が等しい1つの正の分数と1つの負の分数のペアがある場合は、両方を削除します(たとえば1/-5、両方を削除する1/5必要があります)。
  5. 分数が単位ではなく、それ以上削減できない場合は、分母を同じ分母で単位分数に分割し、1つの分数をそのままにします。他のものを使用して、それらを乗算しFF(1)ます(1/2 + 1/3 + 1/5 + 1/-30)
  6. 最終的な端数の合計が有効なエジプトの端数になるまで、手順1〜5を繰り返します。つまり、すべての端数は互いに異なり、それらはすべて単位の端数になります。

これはの削減ですFF(2)

  1/4 + 1/6 + 1/10 + 1/-60 + 1/6 + 1/9 + 1/15 + 1/-90 +
  1/10 + 1/15 + 1/25 + 1/-150 + 1/-60 + 1/-90 + 1/-150 + 1/900
= 1/4 + 2/6 + 1/9 + 2/10 + 2/15 + 1/25 + 2/-60 + 2/-90 + 2/-150 + 1/900 (step 1)
= 1/4 + 1/3 + 1/9 + 1/5 + 2/15 + 1/25 + 1/-30 + 1/-45 + 1/-75 + 1/900   (step 2)
= 1/3 + 1/4 + 1/5 + 1/9 + 1/15 + 1/15(1/2 + 1/3 + 1/5 + 1/-30) +        (step 5)
  1/25 + 1/-30 + 1/-45 + 1/-75 + 1/900
= 1/3 + 1/4 + 1/5 + 1/9 + 1/15 + 1/30 + 1/45 + 1/75 + 1/-450 +
  1/25 + 1/-30 + 1/-45 + 1/-75 + 1/900
= 1/3 + 1/4 + 1/5 + 1/9 + 1/15 + 1/25 + 1/-450 + 1/900                  (step 4)

すべての場合n(を除く1FF(n)は、「squaring」によって定義されFF(n-1)ます。

入出力:

整数を指定するとn、のすべての逆数のリストを出力し、FF(n)絶対値の昇順で並べ替えます。

1 -> [2, 3, 5, -30]
# 1/2 + 1/3 + 1/5 + 1/-30 = FF(1), reciprocals = [2, 3, 5, -30]

2 -> [3, 4, 5, 9, 15, 25, -450, 900]

区切り文字を含む文字列、またはリストの言語の解釈を使用することが許可されているため、これらの出力はすべてinputで受け入れられます1

2 3 5 -30   (Space-delimited)
2,3,5,-30   (Comma-delimited)
[2 3 5 -30] (Lisp-like lists)
etc. etc.

スペック:

  • FF(n)上記の指定どおりに関数の結果を出力する必要があります。
  • 入力は正の整数であることが保証されます。ゼロ未満になることはなく、小数(または小数)になることもありません。

これはなので、バイト単位の最短コードが優先されます。


4
好奇心から、これは終了することが保証されていますか?
マーティンエンダー2017


FF(3)が爆破しているようです。サンドボックスに投稿する前に、FF(10)までこれをテストしませんでしたか?
Peter Taylor


2
エジプトの分数には負の値がなかったため、実際にはエジプトの分数ではありません。
mbomb007

回答:


1

Haskell、365バイト

import Data.Function;import Data.List;import Data.Ratio;n=numerator;d=denominator
r=until=<<((==)=<<)$filter(/=0).map(sum).groupBy((==)`on`d).sortBy(compare`on`d)
p s=let(o,q)=span((<2).abs.n)s in case q of []->o;(a:b)->let j=a-1%d a*signum a in p.r$o++[a-j]++map(*j)e++b
s s=(*)<$>s<*>s;e=(1%)<$>[2,3,5,-30];f=iterate(p.r.s)e;o i=[abs(d q)*signum(n q)|q<-f!!(i-1)]

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


うーん…私は最大の非ユニットを分割し、提示されたとおりに一度に再チェックすると明らかに無限ループに遭遇し、再チェックする前に最小の非ユニットを左方向に逆にまたはグローバルにすべての非ユニットに分割するとすでにそうでしたが、おそらく私はすべきです有限のFF(3)に到達するのに十分な数を他のものをキャンセルするかどうかの間から、非決定的に非ユニットを選択するのに失敗しませんか?
ローマンチボッラ2017

使用(1%)<$>[2,4,6,12]1としてのみ😠FF(4)〜FF(3)からnonterminationをprocrastinates
ローマCzyborra

(1%)<$>[2,3,10,15]または(1%)<$>[3,4,6,8,12,24]全て🤔では改善が得られていない
ローマCzyborra
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.