Summiere die Kräfte zu n

14

Richtungen

Schreiben Sie ein Programm, das bei einer eingegebenen Ganzzahl n ( n >= 0) die kleinste positive Ganzzahl m ausgibt, wobei:

  • n = a[1]^b[1] + a[2]^b[2] + a[3]^b[3] + ... + a[k]^b[k]
  • aund bsind endliche Folgen gleicher Länge
  • Alle Elemente von asind kleiner alsm
  • Alle Elemente von bsind kleiner alsm
  • Alle Elemente von asind verschieden und ganze Zahlena[x] >= 0
  • Alle Elemente von bsind verschieden und ganze Zahlenb[x] >= 0
  • a[x]und b[x]sind nicht beide 0 (da 0 ^ 0 unbestimmt ist)

Das ist , also gewinnen die wenigsten Bytes.

Beispiele

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
kukac67
quelle
Wie sollen wir eine Folge eindeutiger, nichtnegativer Ganzzahlen mit einer nicht unendlichen Summe erstellen?
Feersum
Auch der erste Fall macht keinen Sinn, da eine Summe mit 0 Termen ausreichen würde.
Feersum
@feersum Ich verstehe deine Frage nicht ganz. Meine Lösung ist eine Brute-Force-Methode aller Kombinationen , in denen m<2dann m<3anschließend m<4usw. , bis ich eine Summe finden , das gleich n. Ich habe auch darüber nachgedacht, die Summe für 0keine Terme zu haben, aber was ist dann die Ausgabe? m>?
kukac67
1
Für endliche Sequenzen würden Sie normalerweise so etwas tun n = a[1]^b[1] + a[2]^b[2] + ... + a[k]^b[k].
Volatility
1
Gute Frage. Nur eine Frage zum ersten Testfall: aund bsind endliche Folgen von Längen 0, so dass es keine Ganzzahl mgibt, die die Bedingungen nicht erfüllt, und da es keine kleinste Ganzzahl gibt, ist die Antwort nicht definiert. Mögliche Korrekturen wären, nach der kleinsten natürlichen Zahl m(in diesem Fall sollten Sie die erwartete Antwort dort auf ändern 0) oder nach der kleinsten positiven Ganzzahl zu fragen m.
Peter Taylor

Antworten:

2

GolfScript (59 Zeichen)

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

Online-Demo

Dies verwendet die Rekursion, um die Werte aufzulisten, die für eine gegebene Zahl erreichbar sind, mund sucht nach der ersten, mdie funktioniert. Es ist leicht von der Antwort von xnor inspiriert , aber in der Implementierung sehr unterschiedlich.

Präparation

~: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
Peter Taylor
quelle
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

Die Funktion fist eine Hilfsfunktion, die prüft, ob nsie nicht als Summe von Potenzen mit unterschiedlichen Basen von Aund Exponenten von ausgedrückt werden kann B. Es verwendet eine natürliche rekursive Strategie:n muss ungleich Null sein, und wir versuchen jede mögliche Wahl von Basis und Exponent, und alle müssen scheitern. Wir entfernen sie aus den erlaubten Listen und verringern sie num den entsprechenden Betrag.

Die Funktion gist die Hauptfunktion. Es sucht nach einem m, der funktioniert. Mist die Menge der zulässigen Werte bis zu m-1. Wir entfernen 0aus den erlaubten Exponenten, um 0**0die Verwendung zu stoppen (was Python mit 1 bewertet). Das tut nichts weh, weil 0**xes 0für alle anderen nutzlos ist x.

xnor
quelle
Sie könnten wahrscheinlich ändern n and all()zu n*all().
grc
@grc Ah, du brauchst den Kurzschluss eigentlich nicht, weil er am Ende ist. Danke für die Verbesserung.
xnor
4

Python 2, 138 Bytes

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

(Danke an @Jakube für alle Tipps)

Ich habe noch nie so viel über das gelernt itertools Modul wie aus dieser einen Frage. Der letzte Fall dauert ungefähr eine Minute.

Wir beginnen mit der Suche m = 1und dem Inkrementieren, bis wir eine Lösung erhalten. Um nach einer Lösung zu suchen, wiederholen wir Folgendes:

  • k = 0 to m-1, wo kist die Anzahl der Begriffe in der Lösung
  • Alle möglichen Kombinationen von Begriffen (durch Zusammenzippen von zwei Permutationen von Teilmengen [0, 1, ... m-1]mit der Größe k), dann Summieren und Überprüfen, ob wir habenn

Beachten Sie, dass wir kbis zu iterieren m-1- obwohl technische mBegriffe insgesamt möglich sind, gibt es immer eine Lösung mit m-1Begriffen, die 0^0nicht zulässig sind und 0^bnichts beitragen. Das ist eigentlich wichtig, weil0^0 es von Python als 1 behandelt wird, was ein Problem zu sein scheint, aber es stellt sich heraus, dass es keine Rolle spielt!

Hier ist der Grund.

Angenommen, eine fälschlicherweise gefundene Lösung wird 0^0als 1 verwendet, z 3^2 + 1^1 + 0^0 = 11. Da wir nur m-1Begriffe generieren , muss es einige geben, die jwir nicht als Basis verwenden (hier j = 2). Wir können die Basis 0 für austauschenj , um eine gültige Lösung zu erhalten3^2 + 1^1 + 2^0 = 11 .

Wenn wir alle mBegriffe durchlaufen hätten, hätten wir möglicherweise falsche Lösungen wie m = 2für n = 2, via erhalten 0^0 + 1^1 = 2.

Sp3000
quelle
Schön. Sie können jedoch mit imap 4 Bytes einsparen. imap(pow,C,D) ... for C,D in
Jakube
@Jakube Ich suche gerade in der Dokumentation nach itertools: PI hat bereits eine weitere Speicherung - tee.
Sp3000,
Ich auch. Auch mein Fehler. Warum würde jemand vorschlagen imap, wenn es das gibt map?? -1 Byte
Jakube
Der Standardparameter für teeist bereits n=2. Spart 2 Bytes.
Jakube
@ Jakube Ahaha danke. Dies ist wahrscheinlich das erste Mal, dass ich mapmit mehr als einem Iterable gearbeitet habe, und in der Tat bringt diese Frage eine Menge Neuerungen für mich hervor.
Sp3000,
4

GolfScript ( 90 84 Bytes)

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

Online-Demo

Präparation

[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

Der eleganteste Trick ist die Behandlung des Sonderfalls für 0.

Peter Taylor
quelle
Ich bin wirklich froh, dass CJam diesmal nicht so viel kürzer ist als Standard Python = P
Fehler
@flawr, das ist GolfScript, nicht CJam. CJam kann wahrscheinlich etwas kürzer sein, da es für kartesische Produkte eingebaut ist. Und es könnte sein, dass xnors Idee einer rekursiven Funktion auch ein kürzeres GolfScript ergibt.
Peter Taylor
Oh sorry, nur verwirrt =)
Fehler
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])

Anwendungsbeispiel: p 23-> 6.

Dies ist eine einfache Brute-Force-Suche. [0..0], [0..1], [0..2] ... [0..∞]Nehmen Sie für jede Liste alle Anfangssegmente der Permutationen (z. B. [0..2]: Permutationen:, [012], [102], [210], [120], [201], [021]Anfangssegmente für 1. Permutation :, [0], [01], [012]2.: [1], [10], [102]usw.). Berechnen Sie für jede Kombination von 2 dieser Listen die Summe der Potenzen. Stoppen Sie, wenn der erste gleich n ist.

nimi
quelle
Sie sollten >>=eher als verwenden concatMap. Sie sind genauso, aber mit umgedrehten Argumenten.
stolzer Haskeller
@ proudhaskeller: Ja, danke!
Nimi
2

Python: 166 Zeichen

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

Erläuterung

Die Funktion ferzeugt alle möglichen ganzen Zahlen, die als Summe der Potenzen von Zahlen in ausgedrückt werden können r. Beginnt mit r = [0]. Wenn eine dieser ganzen Zahlen gleich ist, ngibt sie die Länge von zurück r, andernfalls ruft sie sich rekursiv mit einer erweiterten Zahl auf r.

Die Berechnung aller ganzen Zahlen, die als Summe ausgedrückt werden können, erfolgt mit zwei Schleifen. Die erste Schleife ist die for j in r, die die Länge des Ausdrucks angibt (2 ^ 3 + 1 ^ 2 hat Länge 2). Die innere Schleife durchläuft alle Kombinationen von Permutationen rmit unterschiedlicher Länge j. Für jeden berechne ich die Summe der Kräfte.

Jakube
quelle
2

JavaScript (ES6) 219 224

Rekursive Funktion. Beginnend mit m = 1, versuche ich alle Kombinationen der Ganzzahl 1..m für Basen und 0..m für Exponenten (0 Base ist nutzlos, wenn 0 ^ 0 == undefiniert ist).
Wenn keine Lösung gefunden wird, erhöhen Sie m und versuchen Sie es erneut.
Sonderfall für Eingang 0 (meiner Meinung nach ist das ohnehin ein Fehler in der Spezifikation)

Die C-Funktion generiert rekursiv alle Kombinationen aus einem Array vorgegebener Länge, so dass

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

Die dritte Ebene everywird verwendet, um das Array a von Basen und b von Exponenten zusammenzufassen ( zipin JavaScript gibt es keine Funktion). Verwenden Sie every, um vorzeitig anzuhalten, wenn eine Lösung vorliegt, bei der nicht alle Elemente in den beiden Arrays verwendet werden.

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

Test In FireFox / Firebug - Konsole

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

Ausgabe

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

edc65
quelle