รวมพลังกับ n


14

คำสั่ง

เขียนโปรแกรมที่ได้รับการป้อนข้อมูลจำนวนเต็มn ( n >= 0) ผลลัพธ์ที่ได้มีขนาดเล็กที่สุดจำนวนเต็มบวก เมตรที่:

  • n = a[1]^b[1] + a[2]^b[2] + a[3]^b[3] + ... + a[k]^b[k]
  • aและbเป็นลำดับที่มีความยาวเท่ากัน
  • องค์ประกอบทั้งหมดของaน้อยกว่าm
  • องค์ประกอบทั้งหมดของbน้อยกว่าm
  • องค์ประกอบทั้งหมดของaมีที่แตกต่างกันและจำนวนเต็มa[x] >= 0
  • องค์ประกอบทั้งหมดของbมีที่แตกต่างกันและจำนวนเต็มb[x] >= 0
  • a[x]และb[x]ไม่ใช่ทั้งคู่ 0 (ตั้งแต่ 0 ^ 0 ไม่แน่นอน)

นี่คือซึ่งมีจำนวนน้อยที่สุดที่จะชนะ

ตัวอย่าง

In 0 -> Out 1
Possible Sum: 

In 1 -> Out 2
Possible Sum: 1^0

In 2 -> Out 3
Possible Sum: 2^1

In 3 -> Out 3
Possible Sum: 2^1 + 1^0

In 6 -> Out 4
Possible Sum: 2^2 + 3^0 + 1^1

In 16 -> Out 5
Possible Sum: 2^4

In 17 -> Out 4
Possible Sum: 3^2 + 2^3

In 23 -> Out 6
Possible Sum: 5^1 + 3^0 + 2^4 + 1^3

In 24 -> Out 5
Possible Sum: 4^2 + 2^3

In 27 -> Out 4
Possible Sum: 3^3

In 330 -> Out 7
Possible Sum: 6^1 + 4^3 + 3^5 + 2^4 + 1^0

เราควรจะสร้างลำดับของจำนวนเต็มที่ไม่ซ้ำกันและไม่เป็นลบซึ่งมีผลรวมไม่สิ้นสุดได้อย่างไร
feersum

นอกจากนี้กรณีแรกไม่สมเหตุสมผลเนื่องจากผลรวมของ 0 คำจะพอเพียง
feersum

@feersum ฉันไม่เข้าใจคำถามของคุณ ทางออกของฉันนี้คือการค้นหาของการรวมกันทั้งหมดกำลังดุร้ายที่m<2แล้วm<3แล้วm<4ฯลฯ nจนกว่าฉันจะหาผลรวมที่เท่าเทียมกัน นอกจากนี้ฉันคิดว่าการมีผลรวม0ไม่มีเงื่อนไข แต่แล้วผลลัพธ์คืออะไร m>
kukac67

1
สำหรับลำดับที่ จำกัด คุณมักจะทำสิ่งที่ชอบ n = a[1]^b[1] + a[2]^b[2] + ... + a[k]^b[k]คุณมักจะทำสิ่งที่ชอบ
ความผันผวน

1
เป็นคำถามที่ดี เพียงหนึ่งการเล่นโวหารในกรณีทดสอบครั้งแรก: aและbเป็นลำดับที่มีความยาว0ดังนั้นจึงไม่มีจำนวนเต็มที่mไม่ตรงตามข้อ จำกัด และเนื่องจากไม่มีจำนวนเต็มที่น้อยที่สุดคำตอบจึงไม่ได้ถูกกำหนด การแก้ไขที่เป็นไปได้ที่จะถามหาจำนวนธรรมชาติที่เล็กที่สุดm(ในกรณีที่คุณควรเปลี่ยนคำตอบที่คาดว่าจะมีการให้0) mหรือจำนวนเต็มบวกที่มีขนาดเล็กที่สุด
ปีเตอร์เทย์เลอร์

คำตอบ:


2

GolfScript (59 ตัวอักษร)

~:T),{),.0{2$0-{2${{4$2$^}2*@3$\?4$+f~}%\;~}%+\;\;}:f~T&}?)

การสาธิตออนไลน์

วิธีนี้ใช้การเรียกซ้ำเพื่อระบุค่าที่สามารถทำได้สำหรับการmค้นหาที่กำหนดและการค้นหาสิ่งแรกmที่ใช้งานได้ มันได้แรงบันดาลใจเล็กน้อยจากคำตอบของ xnorแต่มีความแตกต่างในการนำไปใช้

การผ่า

~:T                  # Evaluate input and store in T (for Target)
),{                  # Search [0 1 ... T] for the first m which matches a predicate
  ),.0               #   Push [0 ... m] to the stack twice and then 0
                     #   Stack holds: possibleAs possibleBs sum
  {                  #   Define the recursive function f
    2$0-{            #     Map over A in possibleAs (except 0)
      2${            #       Map over B in possibleBs (except 0)
        {4$2$^}2*    #         Duplicate respective possibles and remove selected values
        @3$\?4$+     #         Compute sum' = sum + A^B
        f            #         Recursive call gives an array [sums]
        ~            #         Push the sums to the stack individually
        }%           #       End map: this collects the sums into a combined array
      \;             #       Pop A, leaving just the combined [sums] inside the map
      ~              #       Repeat the trick: push to the stack individually
    }%               #     End map, collecting into a combined array
                     #     Stack now holds: possibleAs possibleBs sum [sums]
    +                #     Include the original sum in the array of reachable sums
    \;\;             #     Pop possibleAs and possibleBs
  }:f                #   End function definition
  ~                  #   Evaluate the function
  T&                 #   Test whether the sums contain T
}?                   # End search
)                    # Increment to get m

6

Python 120

f=lambda n,A,B:n*all(f(n-a**b,A-{a},B-{b})for a in A for b in B)
g=lambda n,m=1,M={0}:f(n,M-{0},M)and g(n,m+1,M|{m})or m

ฟังก์ชั่นfเป็นฟังก์ชั่นเสริมว่าการตรวจสอบว่าnสามารถไม่ได้แสดงเป็นผลรวมของอำนาจที่มีฐานที่แตกต่างกันจากและเลขยกกำลังจากA Bมันใช้กลยุทธ์แบบเรียกซ้ำโดยธรรมชาติ: nต้องไม่ใช่ศูนย์และเราลองทุกทางเลือกที่เป็นไปได้ของฐานและและเลขชี้กำลังและพวกเขาทั้งหมดต้องล้มเหลว เราลบออกจากรายการที่อนุญาตและลดลงnตามจำนวนเงินที่สอดคล้องกัน

ฟังก์ชั่นgเป็นฟังก์ชั่นหลัก มันค้นหาสิ่งmที่ได้ผล เป็นชุดของค่าอนุญาตให้ขึ้นไปM m-1เราลบ0เลขชี้กำลังที่อนุญาตให้หยุด0**0(ซึ่ง Python ประเมินเป็น 1) จากการใช้งาน นี้ไม่ได้เจ็บอะไรเพราะ0**xเป็นไร้ประโยชน์สำหรับทุกอื่น ๆ0x


คุณอาจจะเปลี่ยนไปn and all() n*all()
grc

@grc Ah จริง ๆ แล้วคุณไม่ต้องการการลัดวงจรเพราะมันออกมา ขอบคุณสำหรับการปรับปรุง
xnor

4

Python 2, 138 ไบต์

from itertools import*
S=lambda n,m=0,R=[]:m*any(n==sum(map(pow,*C))for k in R for C in product(*tee(permutations(R,k))))or S(n,m+1,R+[m])

(ขอบคุณ @Jakube สำหรับเคล็ดลับทั้งหมด)

ฉันไม่เคยเรียนรู้มากมายเกี่ยวกับitertoolsโมดูลอย่างที่ฉันมีจากคำถามนี้ กรณีสุดท้ายใช้เวลาประมาณหนึ่งนาที

เราเริ่มต้นด้วยการค้นหาm = 1และเพิ่มจำนวนจนกว่าเราจะได้คำตอบ เพื่อตรวจสอบวิธีการแก้ปัญหาที่เราทำซ้ำ:

  • k = 0 to m-1ซึ่งkเป็นจำนวนของข้อตกลงในการแก้ปัญหา
  • การรวมกันของคำที่เป็นไปได้ทั้งหมด (โดยซิปร่วมกันสองพีชคณิตย่อยของ[0, 1, ... m-1]ขนาดด้วยk) จากนั้นรวมและตรวจสอบว่าเรามีn

โปรดทราบว่าเราทำซ้ำkได้m-1ถึงแม้ว่าmจะเป็นคำศัพท์ทางเทคนิคโดยรวม แต่ก็มีวิธีแก้ปัญหาm-1ที่0^0ไม่อนุญาตและ0^bไม่มีส่วนร่วม สิ่งนี้สำคัญจริง ๆ เพราะ0^0ถือว่าเป็น 1 โดย Python ซึ่งดูเหมือนว่าเป็นปัญหา แต่กลับกลายเป็นว่าไม่ได้มีความสำคัญ!

นี่คือเหตุผล

สมมติว่าวิธีการแก้ปัญหาที่พบไม่สมควรใช้0^0เป็น 1 3^2 + 1^1 + 0^0 = 11เช่น เนื่องจากเราสร้างm-1ข้อกำหนดเท่านั้นจึงต้องมีบางอย่างที่jเราไม่ได้ใช้เป็นฐาน (ที่นี่j = 2) เราสามารถแลกเปลี่ยน base 0 jเพื่อรับโซลูชันที่ถูกต้องได้ที่นี่3^2 + 1^1 + 2^0 = 11ที่จะได้รับการแก้ปัญหาที่ถูกต้องที่นี่

มีเราซ้ำถึงทุกmแง่แล้วเราอาจจะได้รับการแก้ปัญหาที่ไม่ถูกต้องเช่นm = 2สำหรับผ่านn = 20^0 + 1^1 = 2


ทำได้ดีนี่. คุณสามารถบันทึก 4 ไบต์โดยใช้ imap imap(pow,C,D) ... for C,D in
Jakube

@Jakube ฉันจริงมองผ่านสำหรับ doc itertoolsที่เราพูด: PI มีการประหยัดอื่น tee-
Sp3000

ฉันด้วย. นอกจากนี้ความผิดพลาดของฉัน ทำไมมีคนแนะนำimapเมื่อมีmap? -1 ไบต์
Jakube

พารามิเตอร์เริ่มต้นสำหรับการอยู่แล้วtee n=2บันทึก 2 ไบต์
Jakube

@Jakube Ahaha ขอบคุณ นี่อาจเป็นครั้งแรกที่ฉันเคยใช้mapกับมันมากกว่าหนึ่งซ้ำแล้วซ้ำอีกและในความเป็นจริงคำถามนี้ทำให้ฉันมีความสุขเป็นครั้งแรก
Sp3000

4

GolfScript ( 90 84 ไบต์)

[0.,.]](~:T),(+{:x;{:|2,{:c)|=x),^{c[1$x]=:A^x^:-;[|~-+@A-?+@A+@]}%}/+~}%.[]*T&}?)\;

การสาธิตออนไลน์

การผ่า

[0.,.]             # Base case: [sum As Bs] is [0 [] []]
](~:T              # Collect it in an array of cases; fetch parameter, eval, store in T.
),(+               # Create array [1 2 ... T 0]. Putting 0 at the end means that it won't
                   # be reached except when T is 0, and nicely handles that special case.
{                  # Loop over the values from that array...
  :x;              #   ...assigning each in turn to x (and popping it from the stack)
  {                #   Stack holds array of [sum As Bs] cases; map them...

    :|             #     Store [sum As Bs] in |
    2,{:c          #     For c in [0 1]...
      )|=x),^      #       Get [0 1 ... x]^ either As or Bs, depending on c
      {            #       Map these legal new As or Bs respectively...
        c[1$x]=:A  #         Work out which of that value or x is the new A
        ^x^:-;     #         And the other one is the new B
        [          #         Begin gathering in an array
          |~       #           Push sum As Bs to the stack
          -+       #           Add - to Bs to get Bs'
          @A-?+    #           Rotate sum to top and add A^- to get sum'
          @A+      #           Rotate As to top and add A to get As'
          @        #           Final rotation to put elements in the right order
        ]          #         Gather in array [sum' As' Bs']
      }%           #       End map
    }/             #     End for
    +~             #     Push all the elements corresponding to x^B and A^x on to the stack
  }%               #   End map, collecting the untouched [sum As Bs] and all the new
                   #   [sum' As' Bs'] arrays into a new array of reached cases.
  .[]*T&           #   Flatten a copy of that array and filter to values equal to T.
                   #   This gives a truthy value iff we've found a way to make T.
}?                 # Loop until we get a truthy value, and push the corresponding x
)\;                # Increment to get the value of m and discard the array of cases

0เคล็ดลับที่สง่างามที่สุดคือการจัดการกรณีพิเศษสำหรับ


ฉันมีความสุขมากที่ CJam ในครั้งนี้ไม่ได้สั้นกว่ารุ่นไพ ธ อนมากนัก = P
flawr

@flawr นี่คือ GolfScript ไม่ใช่ CJam CJam อาจจะค่อนข้างสั้นกว่านี้สักหน่อยเพราะมีในตัวสำหรับผลิตภัณฑ์คาร์ทีเซียน และอาจเป็นเพราะความคิดของ xnor ที่มีฟังก์ชั่นวนซ้ำทำให้ GolfScript สั้นลงเช่นกัน
ปีเตอร์เทย์เลอร์

ขอโทษทีทำให้พวกเขางง =)
ข้อผิดพลาด

4

Haskell, 143 130

import Data.List
p n=head$[1..]>>=(\m->[m|let x=permutations[0..m-1]>>=inits,a<-x,b<-x,sum(zipWith(\x y->x^y*signum(x+y))a b)==n])

ตัวอย่างการใช้งาน: ->p 236

นี่เป็นการค้นหาแบบเดรัจฉานแบบง่ายๆ สำหรับรายชื่อทุกคน[0..0], [0..1], [0..2] ... [0..∞]ใช้เวลาส่วนเริ่มต้นทั้งหมดของพีชคณิต (เช่น [0..2]: พีชคณิต: [012], [102], [210], [120], [201], [021]กลุ่มเริ่มต้นสำหรับการเปลี่ยนแปลงที่ 1: [0], [01], [012]2: [1], [10], [102]ฯลฯ ) สำหรับการรวมกันของ 2 จากรายการเหล่านั้นจะคำนวณผลรวมของพลัง หยุดเมื่อคนแรกเท่ากับ n


คุณควรใช้มากกว่า>>= concatMapพวกมันเหมือนกัน แต่มีข้อโต้แย้งพลิก
ภูมิใจ Haskeller

@proudhaskeller: ใช่ขอบคุณ!
nimi

2

Python: 166 ตัวอักษร

from itertools import*;p=permutations
f=lambda n,r=[0]:any(n==sum(map(lambda x,y:(x+y>0)*x**y,a,b))for j in r for a,b in product(p(r,j),p(r,j)))*1or 1+f(n,r+[len(r)])

คำอธิบาย

ฟังก์ชั่นสร้างจำนวนเต็มเป็นไปได้ทั้งหมดที่สามารถแสดงเป็นผลรวมของอำนาจของของตัวเลขในf หากเริ่มต้นด้วยr r = [0]ถ้าใด ๆ ของจำนวนเต็มเหล่านั้นจะมีค่าเท่ากับnก็จะส่งกลับความยาวของมิฉะนั้นจะเรียกตัวเองซ้ำกับการขยายrr

การคำนวณจำนวนเต็มทั้งหมดที่สามารถแสดงเป็นผลรวมทำได้ด้วยสองลูป วงแรกคือวงfor j in rซึ่งบอกความยาวของนิพจน์ (2 ^ 3 + 1 ^ 2 มีความยาว 2) ห่วงภายใน iterates กว่ารวมกันทั้งหมดของพีชคณิตของความยาวr jฉันคำนวณผลรวมของพลัง


2

JavaScript (ES6) 219 224

ฟังก์ชั่นวนซ้ำ เริ่มต้นด้วย m = 1 ฉันลองรวมกันทั้งหมดของจำนวนเต็ม 1..m สำหรับฐานและ 0..m สำหรับเลขชี้กำลัง (0 ฐานไม่มีประโยชน์ให้ 0 ^ 0 == ไม่ได้กำหนด)
หากไม่พบวิธีแก้ไขให้เพิ่ม m แล้วลองอีกครั้ง
กรณีพิเศษสำหรับการป้อนข้อมูล 0 (ในความคิดของฉันที่เป็นข้อผิดพลาดในรายละเอียดต่อไป)

ฟังก์ชั่น C จะสร้างชุดค่าผสมทั้งหมดซ้ำจากความยาวที่กำหนดดังนั้น

C(3, [1,2,3]) --> [[3,2,1], [3,1,2], [2,3,1], [2,1,3], [1,3,2], [1,2,3]]

ระดับที่สามeveryใช้เพื่อรวมอาร์เรย์ a ของฐานและ b ของเลขชี้กำลัง (รวมถึงzipฟังก์ชันใน JavaScript) ใช้everyเพื่อหยุด แต่เนิ่น ๆ เมื่อมีวิธีแก้ปัญหาที่ไม่ได้ใช้องค์ประกอบทั้งหมดในสองอาร์เรย์

F=(n,j=1,k=[],
  C=(l,a,o=[],P=(l,a,i=l)=>{
    for(l||o.push(a);i--;)
      e=[...a],P(l-1,e.concat(e.splice(i,1)))
  })=>P(l,a)||o
)=>n&&C(k.push(j++),k)[E='every'](a=>C(j,[0,...k])[E](b=>a[E](x=>t-=Math.pow(x,b.pop()),t=n)))
?F(n,j,k):j

ทดสอบในคอนโซล FireFox / FireBug

;[0,1,2,3,6,16,17,23,24,27,330].map(x=>[x,F(x)])

เอาท์พุต

[[0, 1], [1, 2], [2, 3], [3, 3], [6, 4], [16, 5], [17, 4], [23, 6], [ 24, 5], [27, 4], [330, 7]]

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