Friedman sayıları üretme


9

Bir Friedman numarası , tüm basamaklarına temel matematik işlemleri (^, /, *, +, -) uygulanarak ifade edilebilen bir sayıdır. İşlemlerin her bir basamağa uygulanması gerekmez, ancak tüm rakamlar dahil edilmelidir. Yani, 121 = 11 ^ 2 -> tüm rakamlar dahil, ancak 1 ve 1 11 yapmak için bir araya getirildi.

Parantez kullanımına izin verilir, ancak önemsiz çözüm x= (x)geçerli bir çözüm değildir. Ayrıca geçerli değil x= +x,.

Örnekler

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

Pozitif iki tamsayı alacak ve bu aralıktaki (dahil) Friedman sayılarını ve sonraki satırlarda ifadeleri olan sayıları yazdıracak bir program yazın.

Giriş -

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

Çıktı -

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

29 Temmuz Pazar 00:00 GMT tarafından yayınlanan en kısa kod kazanan olacaktır.


2
Bazı örnek Friedman sayıları ekleyebilir ve nasıl /çalıştığını açıklayabilir misiniz? Mesela nedir 1/3?
19:12

Sayı, tüm basamaklarına işlemler uygulanarak ifade edilir. yani 25 = 5 ^ 2, 126 = 6 * 21, 343 = (3 + 4) ^ 3 vb.
elssar

Tekli eksi izin veriyor musunuz? örneğin -5?
19:12

Girdi şartnamesini kontrol ediyoruz, bunu yapmanıza gerek kalmayacaktı, ancak eğer isterseniz, kendinizi öldürün. Rağmen tek artıya izin verilmez. ie +5 geçerli bir çözüm değil
elssar

1
JPvdMerwe'un bölünme hakkındaki sorusunu yanıtlamadınız. Kesin olmalı mı? Ara sonuçlar ayrılmaz olabilir mi?
Peter Taylor

Yanıtlar:


3

Yakut, 456 438408390370349344334 [sabit]

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

Çıktı:

% 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"}

Ayrıca daha büyük sayılar için nispeten hızlı çalışır:

% 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
Ben girişli koştum 5 40ve sonuç var: [11, "11**1", 21, "21**1", 31, "31**1", 41, "41**1"]. 25Orada hiçbir iz ve ben doğru çözüm (örneğin için 21) olduğunu düşünüyorum 2*1, değil21**1
Cristian Lupascu

@ w0lf Teşekkürler! Bence tamir ettim.
12'de defhlt

Evet, şimdi harika çalışıyor.
Cristian Lupascu

@ w0lf, çıktıyı gerektiği gibi biçimlendirmek için birçok karakter ekledi
defhlt

Eğer değiştirerek 2 karakter kazanabilir '+-*/'.chars.to_a+['','**']ile["+","-","*","/","","**"]
Cristian Lupascu

4

Python 2.7-380378372371367363357354352 348336 karakter

Sadece basit bir kaba kuvvet araması.

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]

Örnek çalışma:

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)

Açıklama:

s(x) bir basamak dizisi içeren bir dize alan ve bu basamakları bu sırayı kullanarak tüm ifadeleri döndüren bir işlevdir.

[x]['1'>x>'0':] x '0' ise x içeren bir liste veya '0' ile başlamayan bir basamak dizisini değerlendirir; aksi takdirde boş bir liste olarak değerlendirilir. Temel olarak bu, tüm rakamları bir araya getirdiğim durumu ele alır.

['(%s%s%s)'%f for i in range(1,len(x))for f in product(s(x[:i]),'*/-+^',s(x[i:]))] temelde x'i iki parçaya ayırır (her ikisi de sıfırdan farklı uzunluktadır), her parçada s () öğesini çağırır ve product () öğesini kullanarak aralarındaki bazı işleçlerle tüm sonuçları birleştirir.

E(e) temelde güvenli bir değerlendirmedir. E geçerliyse e değerini, aksi halde Yok değerini döndürür.

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}

Temel olarak bu kod aralıktaki tüm sayıları dener, basamaklarına izin verir ve s () 'nin ürettiği her ifadeyi o permütasyon için test eder, x' 0 'ile başlamazsa ilk ifadeyi yok sayar, çünkü x' 0 'ise ilk ifade x olur.

Alternatif versiyon - 397 karakter

Kesirler kullanmanız gerekirse benim kodum:

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İşlevde asla doğru olacağını sanmıyorum s. Ayrıca, 4 karakter kaydetmek için formatile değiştirebilirsiniz "a[Fraction(%s)%s%s]='(%s%s%s)'"%(x[:i],o,v,x[:i],o,A).
beary605

@ beary605: Bazen, i = len (x) -1 olduğunda, bir sonraki çağrı tek bir karakter alır. İkinci noktaya gelince, teşekkürler! :)
JPvdMerwe

ha ... except:0akıllı ... çok akıllı. Hatırlayacağım
Ev_genus

Lütfen bazı açıklayıcı çıktılar ekleyin.
DavidC

1
Hayır, hala çalışıyor. Bilgisayarımı şimdi taşımam gerekiyor, ancak birkaç gün çalışmasına izin vereceğim ve bitip bitmediğini göreceğim.
JPvdMerwe

3

Python3 (436) [434) [443)

Zordu. Çıktıyı daha yerli yaparsam bazı karakterleri yedekleyebilirim.

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)

Çıktı

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
Yani bir sürü akıllı hile var; ancak, 1'den 9'a kadar doğru işlemediğinizi ve girdilerinizi içermediğini belirtmeliyim. Sen sonra boşluk kaldırarak 2 karakter olsa kaldırabilirsiniz "("+i+c+j+")"ve değiştirilmesi len(n)>1ile 1<len(n)bundan sonra bu ifadeden sonra boşluk kaldırabilirsiniz.
JPvdMerwe

Fuarı. Tümü düzeltildi, +7 karakter
Ev_genus

for j in r:print(r[j],j)7 karakteri kaydetmek için son satırı değiştirebilirsiniz .
JPvdMerwe

1

Mathematica 456 416 402 404 400 396 karakter

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

Örnek :

v[1,300]//TableForm

Çıktı :

friedman çıktı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.