Sumuj moce do n

14

Kierunki

Napisz program, który podając liczbę całkowitą wejściową n ( n >= 0), wypisuje najmniejszą dodatnią liczbę całkowitą m, gdzie:

  • n = a[1]^b[1] + a[2]^b[2] + a[3]^b[3] + ... + a[k]^b[k]
  • ai bsą skończonymi sekwencjami o tej samej długości
  • wszystkie elementy asą mniejsze niżm
  • wszystkie elementy bsą mniejsze niżm
  • wszystkie elementy aróżne i liczb całkowitycha[x] >= 0
  • wszystkie elementy bróżne i liczb całkowitychb[x] >= 0
  • a[x]i b[x]oba nie są równe 0 (ponieważ 0 ^ 0 jest nieokreślone)

To jest , więc wygrywa najmniej bajtów.

Przykłady

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
źródło
Jak mamy stworzyć sekwencję unikatowych, nieujemnych liczb całkowitych, które mają nieskończoną sumę?
feersum
Również pierwszy przypadek nie ma sensu, ponieważ wystarczyłaby suma z 0 terminami.
feersum
@feersum Nie do końca rozumiem twoje pytanie. Moje rozwiązanie tego problemu jest poszukiwanie brute force wszystkich kombinacjach, gdzie m<2następnie m<3następnie m<4itd aż znajdę pewną sumę, która jest równa n. Pomyślałem też o tym, żeby suma 0nie zawierała żadnych terminów, ale jaka jest wynik? m>?
kukac67
1
W przypadku sekwencji skończonych zwykle zrobiłbyś coś takiego n = a[1]^b[1] + a[2]^b[2] + ... + a[k]^b[k].
Zmienność
1
Fajne pytanie. Tylko jeden spór w pierwszym przypadku testowym: ai bsą skończonymi sekwencjami długości 0, więc nie ma liczby całkowitej, mktóra nie spełnia ograniczeń, a ponieważ nie ma najmniejszej liczby całkowitej, odpowiedź nie jest zdefiniowana. Możliwe poprawki polegałyby na zapytaniu o najmniejszą liczbę naturalną m(w takim przypadku powinieneś zmienić tam oczekiwaną odpowiedź 0) lub o najmniejszą dodatnią liczbę całkowitą m.
Peter Taylor

Odpowiedzi:

2

GolfScript (59 znaków)

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

Demo online

Używa rekurencji, aby wyliczyć wartości osiągalne dla danej mi szuka pierwszej, mktóra działa. Jest lekko inspirowany odpowiedzią xnor, ale różni się implementacją.

Sekcja

~: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
źródło
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

Ta funkcja fjest funkcją pomocniczą, która sprawdza, czy nien może być wyrażona jako suma mocy o odrębnych podstawach i wykładnikach . Wykorzystuje naturalną strategię rekurencyjną: musi być niezerowa, a my próbujemy każdego możliwego wyboru podstawy i wykładnika i wszystkie one muszą zawieść. Usuwamy je z dozwolonych list i zmniejszamyABnn o odpowiednią kwotę.

Ta funkcja gjest główną funkcją. Szuka tego, mktóry działa. Mto zestaw dozwolonych wartości do m-1. Usuwamy 0z dozwolonych wykładników, aby zatrzymać 0**0(które Python ocenia na 1) przed użyciem. To nic nie boli, ponieważ 0**xjest bezużyteczne 0dla wszystkich innych x.

xnor
źródło
Prawdopodobnie możesz zmienić n and all()na n*all().
grc
@grc Ach, tak naprawdę nie potrzebujesz zwarcia, ponieważ jest ono na dole. Dzięki za ulepszenie.
xnor
4

Python 2, 138 bajtów

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

(Dzięki @Jakube za wszystkie wskazówki)

Nigdy się tak dużo nie nauczyłem itertools module, jak z tego jednego pytania. Ostatni przypadek zajmuje około minuty.

Zaczynamy od wyszukiwania m = 1i zwiększania, aż do uzyskania rozwiązania. Aby sprawdzić rozwiązanie, powtarzamy:

  • k = 0 to m-1, gdzie kjest liczba terminów w rozwiązaniu
  • Wszystkie możliwe kombinacje terminów (poprzez spakowanie razem dwóch kombinacji podzbiorów o [0, 1, ... m-1]rozmiarze k), a następnie zsumowanie i sprawdzenie, czy mamyn

Pamiętaj, że iterujemy kdo m-1- nawet jeśli technicznie mwarunki są w sumie możliwe, zawsze istnieje rozwiązanie z m-1warunkami, które 0^0są niedozwolone i 0^bnic nie wnoszą. Jest to w rzeczywistości ważne, ponieważ 0^0Python traktuje je jako 1, co wydaje się problemem, ale okazuje się, że nie ma to znaczenia!

Dlatego.

Załóżmy, że rozwiązanie znalezione błędnie używa 0^0jako 1, np 3^2 + 1^1 + 0^0 = 11. Ponieważ generujemy tylko do m-1warunków, muszą istnieć takie j, których nie używamy jako podstawy (tutaj j = 2). Możemy zamienić podstawową 0 na, jaby uzyskać prawidłowe rozwiązanie tutaj3^2 + 1^1 + 2^0 = 11 .

Gdybyśmy powtórzyć do wszystkich mkategoriach, a następnie możemy zdobyć niewłaściwych rozwiązań jak m = 2dla n = 2pośrednictwem 0^0 + 1^1 = 2.

Sp3000
źródło
Niezłe. Możesz jednak zapisać 4 bajty, używając imap. imap(pow,C,D) ... for C,D in
Jakube,
@Jakube Tak naprawdę przeglądam dokument itertoolsw trakcie, gdy mówimy: PI już ma kolejny zapis - tee.
Sp3000,
Ja też. Również mój błąd. Dlaczego ktoś miałby sugerować imap, skoro jest map? -1 bajt
Jakube,
Domyślny parametr teeto już n=2. Oszczędza 2 bajty.
Jakube,
@Jakube Ahaha dzięki. To chyba pierwszy raz, kiedy użyłem mapwięcej niż jednej iteracji, a tak naprawdę to pytanie przyniosło mi wiele nowości.
Sp3000,
4

GolfScript ( 90 84 bajtów)

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

Demo online

Sekcja

[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

Najbardziej elegancką sztuczką jest obsługa specjalnego etui 0.

Peter Taylor
źródło
Bardzo się cieszę, że CJam nie jest tym razem o wiele krótszy niż standardowy python = P
flawr
@flawr, to jest GolfScript, a nie CJam. CJam może być prawdopodobnie nieco krótszy, ponieważ ma wbudowane produkty kartezjańskie. Być może pomysł Xnora na funkcję rekurencyjną daje również krótszy GolfScript.
Peter Taylor
Och, przepraszam, po prostu ich pomieszałem =)
wada
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])

Przykład użycia: p 23-> 6.

Jest to proste wyszukiwanie brutalnej siły. Dla każdej listy [0..0], [0..1], [0..2] ... [0..∞]weź wszystkie początkowe segmenty permutacji (np. [0..2]: permutacje:, [012], [102], [210], [120], [201], [021]początkowe segmenty dla 1. permutacji:, [0], [01], [012]2.: [1], [10], [102]itd.). Dla każdej kombinacji 2 z tych list oblicz sumę mocy. Zatrzymaj się, gdy pierwszy będzie równy n.

nimi
źródło
powinieneś >>=raczej użyć niż concatMap. są takie same, ale z odrzuconymi argumentami.
dumny haskeller
@proudhaskeller: Tak, dziękuję!
nimi
2

Python: 166 znaków

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

Wyjaśnienie

Funkcja ftworzy wszystkie możliwe liczby całkowite, które można wyrazić jako sumę potęg liczb w r. Jeśli zaczyna się od r = [0]. Jeśli którakolwiek z tych liczb całkowitych jest równa n, zwraca długość r, w przeciwnym razie wywołuje się rekurencyjnie z rozszerzeniem r.

Obliczanie wszystkich liczb całkowitych, które można wyrazić jako sumę, odbywa się za pomocą dwóch pętli. Pierwsza pętla to ta for j in r, która mówi nam o długości wyrażenia (2 ^ 3 + 1 ^ 2 ma długość 2). Wewnętrzna pętla przechodzi przez wszystkie kombinacje permutacji rdługości j. Dla każdego obliczam sumę mocy.

Jakube
źródło
2

JavaScript (ES6) 219 224

Funkcja rekurencyjna. Zaczynając od m = 1, wypróbowuję wszystkie kombinacje liczb całkowitych 1..m dla zasad i 0..m dla wykładników (0 podstawa jest bezużyteczna, biorąc pod uwagę 0 ^ 0 == niezdefiniowany).
Jeśli nie znaleziono rozwiązania, zwiększ m i spróbuj ponownie.
Specjalny przypadek dla wejścia 0 (moim zdaniem i tak jest to błąd w specyfikacji)

Funkcja C rekurencyjnie generuje wszystkie kombinacje z tablicy o podanej długości, dzięki czemu

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

Trzeci poziom everysłuży do skompresowania tablicy a podstaw i b wykładników ( zipw JavaScript nie ma żadnej funkcji). Używanie, everyaby zatrzymać wcześnie, gdy istnieje rozwiązanie nie wykorzystujące wszystkich elementów w dwóch tablicach.

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

Testuj w konsoli FireFox / FireBug

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

Wynik

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

edc65
źródło