Суммируйте свои полномочия


14

Направления

Напишите программу, которая, учитывая входное целое число n ( n >= 0), выводит наименьшее положительное целое число m, где:

  • 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без терминов, но каков результат? м>?
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

Питон, 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 может ли она быть выражена как сумма степеней с различными основаниями от и показателями от . Он использует естественную рекурсивную стратегию: должен быть ненулевым, и мы пробуем каждый возможный выбор базисной и и экспонентной величин, и все они должны потерпеть неудачу. Мы удаляем их из разрешенных списков и уменьшаем на соответствующую сумму.ABnn

Функция gявляется основной функцией. Он ищет, mчто работает. Mэто набор допустимых значений до m-1. Мы удаляем 0из разрешенных показателей, чтобы остановить 0**0(что Python оценивается в 1) от использования. Это ничего не повредит, потому 0**xчто это бесполезно 0для всех остальных x.


Возможно, вы могли бы изменить n and all()на n*all().
grc

@grc Ах, тебе не нужно короткое замыкание, потому что оно дно. Спасибо за улучшение.
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что Python рассматривает его как 1, что кажется проблемой, но, оказывается, это не имеет значения!

Вот почему

Предположим, что найденное решение ошибочно использует 0^01, например 3^2 + 1^1 + 0^0 = 11. Так как мы генерируем только m-1термины, должны быть некоторые, которые jмы не используем в качестве основы (здесь j = 2). Мы можем поменять базу 0, jчтобы получить правильное решение, здесь 3^2 + 1^1 + 2^0 = 11.

Если бы мы повторили все mтермины, то, возможно, мы получили бы неправильные решения, такие как m = 2for n = 2, via 0^0 + 1^1 = 2.


Хороший. Вы можете сохранить 4 байта, используя imap. imap(pow,C,D) ... for C,D in
Якуб

@Jakube Я на самом деле просматриваю документ, itertoolsпока мы говорим: у PI уже есть другая экономия - tee.
Sp3000

Я тоже. Также моя ошибка. Зачем кому-то предлагать imap, когда есть map?? -1 байт
Якуб

Параметр по умолчанию для teeуже n=2. Сохраняет 2 байта.
Якуб

@Jakube Ахаха, спасибо. Это, наверное, первый раз, когда я использовал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 на этот раз не намного короче стандартного python = P
flawr

@ Flawr, это GolfScript, а не CJam. CJam, вероятно, может быть немного короче, потому что он имеет встроенную для декартовых продуктов. И может быть, идея xnor о рекурсивной функции также дает более короткий GolfScript.
Питер Тейлор

Ой извините, просто перепутал их =)
flawr

4

Хаскелл, 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 23-> 6.

Это простой перебор. Для каждого списка [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, он возвращает длину r, в противном случае он вызывает себя рекурсивно с расширением r.

Вычисление всех целых чисел, которое может быть выражено как сумма, выполняется с помощью двух циклов. Первый цикл - это for j in r, который сообщает нам длину выражения (2 ^ 3 + 1 ^ 2 имеет длину 2). Внутренний цикл повторяется по всем комбинациям перестановок rдлины j. Для каждого я рассчитываю сумму полномочий.


2

JavaScript (ES6) 219 224

Рекурсивная функция. Начиная с m = 1, я пробую все комбинации целого числа 1..m для оснований и 0..m для показателей (0 оснований бесполезно, учитывая 0 ^ 0 == undefined).
Если решение не найдено, увеличьте 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]]

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.