フリードマン数を生成する


9

フリードマン数は、すべてのそれの桁に- (、/、*、+、^)基本的な数学演算を適用することで表現できる数です。操作は個々の数字に適用する必要はありませんが、すべての数字が関係している必要があります。つまり、121 = 11 ^ 2->すべての数字が関係しますが、1と1が一緒になって11になります。

括弧の使用は許可されていますが、自明な解決策x= (x)は有効な解決策ではありません。また、無効ですx= +x

  • 25 = 5 ^ 2
  • 121 = 11 ^ 2
  • 343 =(3 + 4)^ 3
  • 2048 =(8 ^ 4)/ 2 + 0

正の2つの整数を取り、その範囲内のフリードマン数の数(両端を含む)を出力するプログラムを記述し、式を含む数を後続の行に出力します。

入力-

n m    | n, m integers, n>=0, m>n

出力-

count    | number of Friedman numbers in the given range
fn1 exp1 | Friedman number, expression
fn2 exp2
fn3 exp3
.
.
.

7月29日日曜日00:00 GMTに投稿された最短コードが勝者となります。


2
フリードマン数の例をいくつか追加して、その/仕組みを説明できますか?たとえば何1/3ですか?
JPvdMerwe 2012

数字は、すべての桁に演算を適用して表現されます。つまり、25 = 5 ^
2、126

単項マイナスを許可しますか?例えば-5
JPvdMerwe 2012

@JPvdMerweは入力仕様をチェックしますが、そうする必要はありませんが、必要に応じてノックアウトしてください。単項プラスは許可されていませんが。つまり、+ 5は有効な解決策ではありません
elssar '19

1
分割に関するJPvdMerweの質問にまだ回答していません。正確でなければなりませんか?中間結果は非積分になりますか?
Peter Taylor、

回答:


3

Ruby、456 438 408 390 370 349 344 334 [固定]

g={}
f=->a,b{a.permutation(b).to_a.uniq.flatten.each_slice b}
F,T=$*
([F.to_i,10].max..T.to_i).map{|c|f[a="#{c}".split(''),v=a.size].map{|m|f[[?+,?-,?*,?/,'','**'],v-1].map{|w|(d=(s=m.zip(w)*'').size)==v&&next
0.upto(d){|y|y.upto(d+1){|u|begin(r=eval t="#{s}".insert(y,?().insert(u,?)))==c&&g[r]=t
rescue Exception
end}}}}}
p g.size,g

出力:

% ruby ./friedman-numbers.rb 1 300
9
{25=>"(5)**2", 121=>"(11)**2", 125=>"5**(2+1)", 126=>"(6)*21", 127=>"(2)**7-1", 128=>"2**(8-1)", 153=>"(3)*51", 216=>"6**(1+2)", 289=>"(9+8)**2"}

また、数値が大きい場合は比較的高速に動作します。

% time ruby friedman-numbers.rb 3863 3864   
1
{3864=>"(6**4-8)*3"}
ruby friedman-numbers.rb 3863 3864  14.05s user 0.17s system 99% cpu 14.224 total

1
私はそれを入力5 40で実行し、結果を得ました:[11, "11**1", 21, "21**1", 31, "31**1", 41, "41**1"]25そこに兆候はなく、正しい解決策(たとえば21)はだと思います2*121**1
Cristian Lupascu 2012

@ w0lfありがとうございます!私はそれを修正したと思います。
2012

はい、それは今うまくいきます。
クリスティアンルパスク2012

@ w0lfは必要に応じて多くの文字をフォーマット出力に追加しました
defhlt

あなたは置き換えることにより、2つの文字を得ることができ'+-*/'.chars.to_a+['','**']["+","-","*","/","","**"]
クリスティアンLupascu

4

Python 2.7-380 378 372 371 367 363 357 354 352 348 336文字

単純なブルートフォース検索。

from itertools import*
s=lambda x:[x]['1'>x>'0':]+['(%s%s%s)'%f for i in range(1,len(x))for f in product(s(x[:i]),'*/-+^',s(x[i:]))]
def E(e):
 try:return eval(e.replace("^","**"))
 except:0
A={i:e for i in range(input(),input()+1)for x in permutations(`i`)for e in s("".join(x))[x>='1':]if E(e)==i}
print len(A)
for v in A:print v,A[v]

実行例:

1
300
9
128 (2^(8-1))
289 ((9+8)^2)
216 (6^(1+2))
121 (11^2)
153 (3*51)
25 (5^2)
125 (5^(2+1))
126 (6*21)
127 ((2^7)-1)

説明:

s(x) は、一連の数字を含む文字列を受け取り、それらの数字をこの順序で使用してすべての式を返す関数です。

[x]['1'>x>'0':] xが「0」または「0」で始まらない一連の数字の場合、xを含むリストとして評価されます。それ以外の場合は、空のリストとして評価されます。基本的に、これはすべての桁を結合する場合を処理します。

['(%s%s%s)'%f for i in range(1,len(x))for f in product(s(x[:i]),'*/-+^',s(x[i:]))] 基本的に、xを2つの部分(両方とも長さがゼロでない部分)に分割し、各部分でs()を呼び出し、product()を使用してすべての結果をいくつかの演算子で結合します。

E(e) 基本的に安全な評価です。eが有効な場合はeの値を返し、それ以外の場合はNoneを返します。

A={i:e for i in range(input(),input()+1)for x in permutations(`i`)for e in s("".join(x))[x>='1':]if E(e)==i}

基本的に、このコードは範囲内のすべての数値を試し、桁を並べ替え、s()がその順列について生成する各式をテストします。xが「0」で始まらない場合、最初の式を無視します。 0 'の場合、最初の式は単にxになります。

代替バージョン-397文字

分数を使用する必要がある場合のコードは次のとおりです。

from fractions import*
from itertools import*
s=lambda x:["Fraction(%s)"%x]['1'>x>'0':]+['(%s%s%s)'%f for i in range(1,len(x))for f in product(s(x[:i]),'*/-+^',s(x[i:]))]
def E(e):
 try:return eval(e.replace("^","**"))
 except:0
A={i:e for i in range(input(),input()+1)for x in permutations(`i`)for e in s("".join(x))[x>='1':]if E(e)==i}
print len(A)
for v in A:print v,A[v].replace("Fraction","")

if len(x)<2機能が真実であるとは思いませんs。また、あなたは置き換えることができるformatとの"a[Fraction(%s)%s%s]='(%s%s%s)'"%(x[:i],o,v,x[:i],o,A)4つの文字を保存します。
beary605 2012

@ beary605:場合によっては、i = len(x)-1の場合はtrueになり、次の呼び出しで単一の文字が取得されます。2点目はありがとう!:)
JPvdMerwe 2012

ええと... except:0賢い..とても賢い 私は覚えています
Ev_genus

いくつかの例示的な出力を含めてください。
DavidC

1
いいえ、まだ実行中です。今はPCを移動する必要がありますが、数日間実行して、終了するかどうかを確認します。
JPvdMerwe 2012

3

Python3 (436) (434)(443)

大変でした。出力をよりネイティブにすると、一部の文字を節約できます。

from itertools import*
r={};k=product;m=map
q=lambda n,h=1:["("+i+c+j+")"for(i,j),c in k(chain(*[k(*m(q,f))for f in sum(([(x[:q],x[q:])for q in range(1,len(x))]for x in m("".join,permutations(n))),[])]),list("+-*/^")+[""]*h)]if 1<len(n)else[n]*h
a,b=m(int,m(input,"nm"))
for i,j in chain(*[k(q(str(n),0),[n])for n in range(a,b+1)]):
    try:exec("if eval(%r)==j:r[j]=i"%i.replace("^","**"))
    except:0
print(len(r))
for j,i in r.items():print(i,j)

出力

n100
m200
6
(2^(8-1)) 128
(3*(51)) 153
((11)^2) 121
(5^(1+2)) 125
(6*(21)) 126
((2^7)-1) 127

1
だからあなたはたくさんの巧妙なトリックを持っています。ただし、1から9を正しく処理しておらず、入力が包括的ではないことにも触れておきます。あなたは後にスペースを削除することによってものの2つの文字を削除することができます"("+i+c+j+")"し、交換するlen(n)>1ことにより、1<len(n)あなたはその式の後にスペースを削除することができた後。
JPvdMerwe 2012

公正。すべて修正、+ 7文字
Ev_genus 2012

最後の行for j in r:print(r[j],j)を7文字節約するために置き換えることができます。
JPvdMerwe 2012

1

Mathematicaの456 416 402 404 400 396文字

<< Combinatorica`; l = Length; p = Permutations; f = Flatten; c = Cases;
u[d_, o_, s_] := 
 Fold[#2[[1]] @@ If[s == 1, {#1, #2[[-1]]}, {#2[[-1]], #1}] &, 
 d[[1]], Thread@{o, Rest@d}];
q[t_, r_] := {u[t, #, r], u[HoldForm /@ t, #, r]} & /@ 
p[{Plus, Subtract, Times, Divide, Power}, {l@t - 1}];
v[m_, n_] := (t = Table[Union@
  c[f[{#~q~1, #~q~0} & /@ 
     f[p /@ c[
        FromDigits /@ # & /@ 
         f[SetPartitions /@ p@IntegerDigits@j, 1], x_ /; l@x > 1],
       1], 2], {j, _}], {j, m, n}]~f~1; {l@t}~Join~t)

v[1,300]//TableForm

出力

フリードマン出力

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