สร้างหมายเลขฟรีดแมน


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

เขียนโปรแกรมที่จะใช้จำนวนเต็มบวกสองจำนวนแล้วพิมพ์จำนวนของตัวเลขฟรีดแมนในช่วงนั้น (รวม) และตัวเลขด้วยนิพจน์ในบรรทัดถัดไป

อินพุต -

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

รหัสที่สั้นที่สุดที่ลงรายการบัญชีในวันอาทิตย์ที่ 29 กรกฎาคม 00:00 น. GMT จะเป็นผู้ชนะ


2
คุณสามารถเพิ่มตัวอย่างตัวเลข Friedman และอธิบายวิธีการ/ทำงานได้หรือไม่ ยกตัวอย่างเช่นสิ่งที่เป็น1/3?
JPvdMerwe

จำนวนจะถูกแสดงโดยใช้การดำเนินการกับทุกหลักมัน เช่น 25 = 5 ^ 2, 126 = 6 * 21, 343 = (3 + 4) ^ 3 และอื่น ๆ
elssar

คุณอนุญาตให้มีการลบเอกหรือไม่? เช่น-5?
JPvdMerwe

@JPvdMerwe ตรวจสอบข้อกำหนดการป้อนข้อมูลคุณไม่จำเป็นต้องทำเช่นนั้น แต่ถ้าคุณต้องการ แม้ว่าจะไม่ได้รับอนุญาต เช่น +5 ไม่ใช่โซลูชันที่ถูกต้อง
elssar

1
คุณยังไม่ได้ตอบคำถามเกี่ยวกับการหารของ JPvdMerwe มันจะต้องแน่นอน? ผลลัพธ์ระดับกลางสามารถเป็นแบบไม่อินทิกรัลได้หรือไม่?
ปีเตอร์เทย์เลอร์

คำตอบ:


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*1ไม่ใช่21**1
Cristian Lupascu

@ w0lf ขอบคุณ! ฉันคิดว่าฉันได้แก้ไขแล้ว
defhlt

ใช่มันใช้งานได้ดีในขณะนี้
Cristian Lupascu

@ w0lf เพิ่มอักขระจำนวนมากเพื่อจัดรูปแบบเอาต์พุตตามต้องการ
defhlt

คุณสามารถรับ 2 ตัวอักษรโดยแทนที่'+-*/'.chars.to_a+['','**']ด้วย["+","-","*","/","","**"]
Cristian 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 ถ้า x เป็น '0' หรือลำดับของตัวเลขที่ไม่ได้ขึ้นต้นด้วย '0' มิฉะนั้นจะประเมินเป็นรายการว่าง โดยทั่วไปจะจัดการกรณีที่ฉันเข้าร่วมตัวเลขทั้งหมดเข้าด้วยกัน

['(%s%s%s)'%f for i in range(1,len(x))for f in product(s(x[:i]),'*/-+^',s(x[i:]))] โดยทั่วไปแบ่งพาร์ติชัน x ออกเป็นสองส่วน (ทั้งสองมีความยาวไม่เป็นศูนย์), เรียก s () ในแต่ละส่วนและรวมผลลัพธ์ทั้งหมดพร้อมกับโอเปอเรเตอร์บางส่วนระหว่างพวกเขาโดยใช้ผลิตภัณฑ์ ()

E(e) เป็นหลักฐานที่ปลอดภัย มันจะคืนค่าของ e ถ้า e นั้นถูกต้องและไม่มีอย่างอื่น

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' เพราะถ้า x ไม่เริ่มต้นด้วย ' 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

@ beary605: มันเป็นความจริงบางครั้งเมื่อ i = len (x) -1 ดังนั้นการโทรครั้งต่อไปจะได้รับอักขระเดี่ยว สำหรับจุดที่สองขอบคุณ! :)
JPvdMerwe

ฮะ ... except:0สมาร์ท .. ฉลาดมาก ฉันจะจำได้
Ev_genus

โปรดรวมเอาท์พุทที่เป็นตัวอย่างบางส่วน
DavidC

1
ไม่ยังคงทำงานอยู่ ฉันต้องย้ายพีซีตอนนี้ แต่ฉันจะปล่อยให้มันทำงานสองสามวันและดูว่ามันจะเสร็จหรือไม่
JPvdMerwe

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 chars โดยการลบช่องว่างหลังจาก"("+i+c+j+")"และแทนที่len(n)>1ด้วย1<len(n)หลังจากที่คุณสามารถลบช่องว่างหลังจากการแสดงออก
JPvdMerwe

ธรรม แก้ไขตัวละครทั้งหมด +7 ตัว
Ev_genus

คุณสามารถแทนที่บรรทัดสุดท้ายด้วยfor j in r:print(r[j],j)เพื่อบันทึก 7 ตัวอักษร
JPvdMerwe

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

ผลผลิต :

ผลผลิต Friedman

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.