パーティションの逆数


21

n> 77が与えられた場合、セットの合計がnに等しく、セットの逆数の合計が1になるように、明確な正の整数のセットを見つけるプログラムまたは関数を記述します。

80の例:

80 = 2 + 4 + 10 + 15 + 21 + 28⟶1/2 + 1/4 + 1/10 + 1/15 + 1/21 + 1/28 = 1

プログラムまたは関数は、(理論的には)n <2 32で動作する必要があり、浮動小数点の丸め誤差は許されません。n> 77のすべてのソリューションが存在することに注意してください。


バイト単位の最短コードが優先されます。

ボーナスインセンティブがあります。任意のnで機能し、log(n)を実行する最小のソリューションに賞金を授与しますnが小さい場合高速である必要があります(私の判断で決定されます)。はい、これは可能です。


3
そのような分解は常に存在することが保証されていますか?それを保証する数論的定理はありますか?
ルイスメンドー

と思われているすべてのn> 77のために。(私はすべての詳細をチェックしませんでした。)それはあなたの挑戦の説明にあるべきだった...
flawr

1
@flawr、私は彼がその参照を含めなかったのは、それがO(log n)アルゴリズムを与えるためだと推測します。
ピーターテイラー

1
それでも、彼はこのセットが指定されたnに対して存在することを言及すべきでした。(タイトルをグーグル検索すると、最初のページでその論文を見つけました。)
flawr

1
@flawr、それを見つけるのに約10分かかりました。私はエジプトの分数のページを介してそれに到達し、10秒で私を忍者しました。
ピーターテイラー

回答:


3

Mathematica、54バイト

Select[IntegerPartitions@#,Unequal@@#&&Tr[1/#]==1&,1]&

ほぼ非効率ですが、n = 78約9秒で解決します。

結果は、シングルトンリストにラップされたリストとして返されます。例:

{{45, 12, 9, 5, 4, 3}}

非常に大きなnで機能するのだろうか。
-njpipeorgan

@njpipeorgan十分なメモリと時間があれば、はい。
マーティンエンダー

IntegerPartition [n]の長さの推定値を見つけました。これは、exp = sqrt(n))のオーダーで、n = 2 ^ 30で〜10 ^ 10 ^ 4.5です。数学(または任意のアーキテクチャ)が配列を保持できるとは本当に信じていません。
njpipeorgan

@njpipeorganチャレンジは、アルゴリズムが理論上、実際にではなく理論的に2 ^ 32まで動作する必要があることを明示的に述べています(チャレンジがプログラムが合理的な時間とメモリですべての入力を実際に終了することを明示的に要求しない限り、通常コードゴルフで想定されているように) )。
マーティンエンダー

4

Python 3、7306 1995バイト

このソリューションはlog(n)の複雑さで実行されます(私が知る限り)。

def i(s,t):
 for n in s[::-1]:t=t.replace(*n)
 return [[]]*78+[list(bytearray.fromhex(a))for a in t.split(",")]
def f(n):
 g,h=lambda c,n:c+[[[2],[3,7,78,91]][n[len(c)]%2]+[i*2for i in c[-1]]],lambda n:[]if n<78 else h((n-[2,179][n%2])//2)+[n]
 v=h(n);c=[i([['g',',03040'],['h',',,0306080'],['i',',020'],['j','b0c1'],['k','21'],['l','60'],['m','30'],['n','141'],['o','k24'],['p',',g'],['q','618'],['r','0c0'],['s','1e'],['t',',0ml'],['u','283c'],['v','e0f1'],['w','2a38'],['x','80'],['y','a0'],['z','01'],['A','50'],['B','24'],['C','i40'],['D','plb1'],['E','gl'],['F','48'],['G','bre1'],['H','28'],['I','6k'],['J','416s'],['K',',040Al'],['L','90'],['M','2a'],['N','54'],['O','k6o'],['P','3c'],['Q','il'],['R','18'],['S','px'],['T','im'],['U','70'],['V','b1'],['W','23'],['X','pj'],['Y','hj'],['Z','0n']],'020lxycHTaRHCyf1517CyfneC91k51cCLdneQU912MCyf0dBiALyf2dClfPEyfneT9s2dELdneEjIgmLydHg5rd14BKLardsE3n8sQ9rd1517Q9rdneplmdRBgUmcRMC5sPEyf102bgA6sPE91z2miAj41IQmc0dRBQUen7spl31z82bT9RFT3wE7neMgmyf0dRBgUmaHMELc1b36EUdBMQLyfs2d,C710M2bgLardRHT3BFQ9rf0dPQ7rdBMQm9Rs2d,0mAl9100d142bE710M2bQmc0fRPtxarfn8sEc1k4sBTfnePExcwtxarf1k8BExcuT3kkT91663C51964,0mAl71k4BMELe12NTcRwQjOT820ltmarf1z8mExeRNCqBFtmyjIHKLa100ds2bQU91bM36garf1k4sBTcRBFgxarfwE91keB2dtUxcn8sME9nbs36gm9rduC5R78,0mAUyf0d14BME91kbB36QLc12AB2dgyjqkHEUeMNT9157eQU9RMFT8s78C8neuixLc1zk4AtUxc1z8Mmt8re0fn8sWhLyc1bH36pl8neu,Kxycsw,iAxc1420l,K8ren8NS9n81bs36hc0vz8WmYzqkmhyv2WBHhyVOHXkJoSjIwSjIuSvz4WASVZIAXZ6skmSj6oFXzOmplvcsW46D61csk46plv8WBFDqoF,tarvk8WBH,tyjkqoHhGqkN,tmvZ8sWmhVZqskmpc0vZ8WAXZqkAplbnImASbn6skwSbn6skuSVOwSVOupGONSbn6soFpyVkJk5aSj6sk78YJkuDkIP5aYOuhvzk4WBAhVzk416oA,tyjkJ265a,,0mxyjk41q53sYzIHmPXkqowXkqouhyVqoHFYz6omFhb0e1zqkmNSyVIP78YJ20klpyVOHwYk620olpc0vz8WBmFXzqomFpG61ckH38PhyjIP78Yz620kmlDkImLDzINUhGIuNDzIA78hb0e1ZIANYkqk366chG6oFNXkJkP5ahVZ6somFSb0e1620kNlhVk41qomADzIFLXkqso78pGqoFNXzkImP5a,tyjk620oHlhG620kNlXzqskm78,tjZqskHmPYqouFD6sku78YzqkNU,tjZqsomF')[v[0]]]
 for o in range(len(v)-1):c=g(c,v)
 return c[-1]

f(2**32 - 1)ほぼ瞬時に実行するテストできます

この論文を計算方法に使用ました。この方法では、168から偶数のない78から334までのnの所定の値に対して大量のデータの塊があります。自分で作りました。

圧縮方法は、文字列の置換ルールのリストを持つことでした。ルールを定義することを考慮して、すべてのコンテンツを最も削減する文字列置換ルールを見つけるメソッドを作成しました。その後、これ以上ルールを作成できなくなるまでこれを再帰的に適用しました(文字gzとAZを使用しました)。置換するために作成した文字列は、各数値の16進値のコンマ区切りリストでした。振り返ってみると、それらを16進数値に変換することは賢明な選択ではなかったかもしれません。16進数を使用すると3桁の数字だけが保存されますが、1桁の数字には0が追加されるので、おそらく10進数のままにしておく方が短いでしょう。

cを設定した行には、置換ルールのリストとそれを実行するテキストが表示されます。一部のルールには他のルールから作成された文字が含まれるため、ルールも逆に適用する必要があります。

このコードには、リストのリストを単一のリストに変えてから、別の方法でルールにアクセスしてテキストを


1
n=218出力[2]は予想されますか?
officialaimm

1
いいえ、その理由が少し後でわかります。謝罪いたします。最初に圧縮したデータにエラーがある可能性があります。
キャメロンAavik

1

Haskell、93バイト

import Data.List
import Data.Ratio
p n=[x|x<-subsequences[2..n],sum x==n,1==sum(map(1%)x)]!!0

ひどく遅い1ですが、一定のメモリで実行されます。自明な解決策:すべての部分列[2..n]の逆数の合計と合計を確認します。

1つではなくすべてのソリューションを返すのは3バイト短くなります:削除するだけです!!0(注意:実行時間は常にチャート外になります)。


1実行時間は、結果がサブシーケンスのリストに表示される早さに依存します。Haskellの遅延は、最初の一致が見つかった場合に検索を停止します。コンパイルすると、p 89(結果:[3,4,6,9,18,21,28])35代で私の(4歳の)ラップトップで実行されます。他の値、さらに小さい値でも、数時間かかる場合があります。


0

ジュリア、77バイト

n->collect(filter(i->i==∪(i)&&sum(j->Rational(1,j),i)==1,partitions(n)))[1]

これは、整数を受け入れて整数配列を返す非効率的なラムダ関数です。呼び出すには、変数に割り当てます。

を使用して整数のパーティションを取得しpartitionsます。次に、逆数の合計が1になる一意の要素を持つパーティションのみにパーティションのセットをフィルター処理します。丸め誤差が発生しないように、ジュリアのRational型を使用して逆数を構築します。filterイテレータを返すのでcollect、配列にする必要があります。これにより、配列の配列(要素が1つのみ)が得られるため、を使用して最初の配列を取得できます[1]

今、私が非効率と言うとき、私はそれを意味します。これをn = 80で実行するには、コンピューターで39.113秒かかり、13.759 GBのメモリを割り当てます。

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