Самосуммированные числа

12

Преобразовать число в сумму цифр

Не любая сумма: нам нужна самая короткая сумма
Не любые цифры: вы можете использовать только цифры номера

Пример
Вам будет предоставленыкачестве ввода целого числаn>0

Давайте скажем n=27. Вы должны выразить 27в виде суммы , используя только цифры [2,7] , в кратчайший возможный способ. Вам не нужно использовать все цифры данного номера!

Так 27=2+2+2+7+7+7. Затем взять эти цифры и считать их : [2,2,2,7,7,7].
Окончательный ответ за n=27это6

Еще один пример для n=195того , чтобы получить кратчайшую сумму мы должны использовать следующие цифры:
[5,5,5,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]и ответ является23

Соревнование

Получив целое число n>0, выведите минимальное количество цифр (содержащихся в числе), которые суммируются до этого числа.

Тестовые случаи

Input->Output

1->1  
2->1  
10->10  
58->8  
874->110  
1259->142  
12347->1765  
123456->20576  
3456789->384088  

Это Самый короткий ответ в байтах побеждает!


источник
Есть ли числа, которые нельзя суммировать для себя / будут ли они вводиться?
Стивен
1
@Stephen Они все могут!
7
@Stephen Потому что каждое число может быть выражено как d_0 + 10 * d_1 + 100 * d_2 и т. Д ...
geokavel
Можем ли мы принять входные данные как строку, массив символов или массив целых чисел?
Кевин Круйссен
1
@KevinCruijssen Строка в порядке. char-массив или целочисленный массив не являются.

Ответы:

4

Шелуха , 12 байт

Lḟo=⁰ΣṁΠḣ∞d⁰

Обрабатывает двузначные числа довольно быстро. Попробуйте онлайн!

объяснение

Lḟo=⁰ΣṁΠḣ∞d⁰  Input is n, say n = 13.
          d⁰  Digits of n: [1,3]
         ∞    Repeat infinitely: [[1,3],[1,3],[1,3],[1,3]...
        ḣ     Prefixes: [[],[[1,3]],[[1,3],[1,3]],[[1,3],[1,3],[1,3]],...
      ṁ       Map and concatenate
       Π      Cartesian product: [[],[1],[3],[1,1],[3,1],[1,3],[3,3],[1,1,1],[3,1,1],...
 ḟo           Find the first element
     Σ        whose sum
   =⁰         equals n: [3,3,3,3,1]
L             Return its length: 5
Zgarb
источник
2

Pyth , 12 байт

lef!-TsM`Q./

Попробуйте онлайн!

К сожалению, это ошибки памяти на входах, таких как 58.

объяснение

lef!-TsM`Q./
          ./    All lists of integers that sum to [the input]
  f             Filter for:
    -TsM`Q           Remove all occurrences of the digits in the input
   !                 Check if falsey (i.e. an empty list)
le              Length of the last occurrence, which is the shortest because all the
                filtered partitions share the same digit pool
notjagan
источник
Вы не против добавить объяснение?
Иона
@Jonah Объяснение добавлено.
Notjagan
1
Благодарю. Интересно, что у Пита есть примитив, который, по сути, решает эту проблему./
Иона
12-байтовая альтернатива: lef<.{TjQ;./(фильтр - правильное подмножество - цифр ввода)
г-н Xcoder
2

Mathematica, 78 байт

(t=1;While[(s=IntegerPartitions[x=#,t,IntegerDigits@x])=={},t++];Tr[1^#&@@s])&  

находит последний контрольный пример за 5 секунд

J42161217
источник
Немного короче:Length@IntegerPartitions[#, All, Sort@DeleteCases[0]@IntegerDigits@#, 1][[1]] &
Куба
2

R , 78 байт

function(n){while(all(F-n)){F=outer(F,n%/%10^(0:nchar(n))%%10,"+")
T=T+1}
T-1}

Попробуйте онлайн! (версия для гольфа)

Алгоритм чистой грубой силы, поэтому он не решает все тестовые случаи, и я думаю, что он попытался выделить 40000 ГБ для последнего тестового примера ...

Tв R по умолчанию 1мы получаем ошибку «off-by-one», которую исправляем на шаге возврата, но мы также получаем, Fкакие значения по умолчанию 0окупаются.

Нежелательное объяснение:

function(n){
 d <- n%/%10^(0:nchar(n))%%10   # digit list with a 0 appended at end
 d <- unique(d[d>0])            # filter zeros (not technically necessary)
                                # and get unique digits
 x <- 0                         # storage for sums
 i <- 0                         # counter for number of sums done
 while(!any(x==n)){             # until we find a combination
  x <- outer(x,d,"+")           # take all sums of x and d, store as x
  i <- i + 1}                   # increment counter
i}                              # return counter

Попробуйте онлайн! (меньше версия для гольфа)

Giuseppe
источник
2

Python 2, 168 155 144 байта

Это не самое короткое время, которое может быть, но оно лучше всего, и не очень плохо, с точки зрения времени выполнения.

n=input()
g=sorted(set(n)-{0})[::-1]
def h(k):
 if k<0:return
 if`k`in g:return 1
 for d in g:
  f=h(k-int(d))
  if f:return 1+f
print h(int(n)) 

Цель filter(None...состоит в том, чтобы удалить 0 как цифру, что я узнал, что мог сделать, делая это.

Самая большая проблема - это кадры стека Python, которые реально не позволяют мне запускать это на самых больших входах. Таким образом, это не правильное решение, на самом деле, я поиграл с увеличением предела рекурсии, который просто привел к сбоям сегмента. Это должно быть сделано либо с помощью цикла и стека, либо с гораздо большим умом, чтобы работать в Python.

редактирование: благодаря Кэрду и Чэсу Брауну за 13 байтов!

Backerupper
источник
Вы можете использовать inputи требовать, чтобы ввод был заключен в кавычки.
Caird Coneheringaahing
2
Совершенно допустимо потерпеть неудачу из-за физических ограничений, если это удается в теории, что и происходит.
Джонатан Аллан
Сохранить 9 байт, заменяя filter(None,sorted(map(int,set(n)))[::-1])с sorted(set(map(int,n))-{0})[::-1](хотя Noneвещь довольно хорошо знать).
Час Браун
@ChasBrown В большинстве случаев вы можете использовать filter(len,...)для списков и строк, а также filter(abs,...)для целых чисел и чисел с плавающей точкой.
овс
0

JavaScript (ES6), 82 байта

f=(n,l=0,a=n,[c,...b]=a)=>n?1/c?Math.min(!+c|+c>n?1/0:f(n-c,l+1,a),f(n,l,b)):1/0:l
<input type=number oninput=o.textContent=f(this.value)><pre id=o>

Принимает ввод в виде строки.

Нил
источник
Можете ли вы объяснить, почему вы используете 1/0?
Захари
1
@ Zacharý Я хочу самую короткую сумму, то есть минимальное количество цифр. Попытки, которые приводят к неверному решению, не должны учитываться, поэтому, чтобы исключить их, они получают бесконечность, которая не влияет на минимум.
Нил
О, не понял, что это рекурсивно.
Захари
@ Zacharý В f=начале это большая подсказка, так как она вам не нужна для нерекурсивных лямбд.
Нил
0

Рубин , 70 байт

->n{w,s=n.digits,0;s+=1while !w.product(*[w]*s).find{|x|x.sum==n};s+1}

Очень медленно, попробуйте все возможные комбинации, увеличивая размер, пока мы не найдем решение.

Спасибо Денису за Ruby 2.4 на TIO.

Попробуйте онлайн!

гигабайт
источник
0

Желе , 23 байта

D;0ṗµḟ€0
ÇS€=µT
Çị1ĿL€Ṃ

Попробуйте онлайн!

Это настолько неэффективно, что не запускается для тестовых случаев после третьего на TIO из-за ограничения по времени> _ <

Любые советы по гольфу приветствуются!

Zachary
источник
0

Python 2 , 183 176 172 166 161 байт

def f(n,D=0,p=0,b=0):
	D=D or set(map(int,`n`))-{0}
	d=min(D);c=0;D=D-{d}
	q=[p+n/d,b][n%d>0]
	while c<min(D or{0}):q=b=f(n-c*d,D,p+c,b);c+=1
	return[q,b][q>b>0]

Попробуйте онлайн!

Дольше, чем другой ответ Python, но выполняет все тестовые примеры вместе взятые плюс 987654321за секунду на TIO.

Используется тот факт, что если d1<d2цифры являются цифрами, то d2-1 d1в сумме должно быть не более s (поскольку d2экземпляры d1можно заменить на d1экземпляры d2для более короткой суммы). Таким образом, сортируя цифры в порядке возрастания, можно рассмотреть «только» максимально 9! = 362880возможную сумму; и максимальная глубина рекурсии 9(независимо от значения n).

Час Браун
источник
0

Haskell , 91 байт

f n=[read[c]|c<-show n,c>'0']#n!!0
s#n|n>0,x:m<-(s#).(n-)=<<s=[1+minimum(x:m)]|1<3=[0|n==0]

Попробуйте онлайн! Пример использования: f 58доходность 8. Быстрый для двузначных чисел, ужасно медленный для больших входов.

Функция fпреобразует входной номер nв список цифр при фильтрации нулей. Затем этот список и nсам передаются (#)функции, которая возвращает одноэлементный список. !!0возвращает элемент этого одноэлементного списка.

(#)использует одиночные и пустые списки в качестве типа параметра. Учитывая ввод n=58и s=[5,8], идея состоит в том, чтобы вычесть все цифры sиз n, затем рекурсивно применить (#)и проверить, какая цифра привела к минимальному количеству шагов, и вернуть один плюс этот минимум в качестве результата. Первая часть вычисляется (s#).(n-)=<<s, что так же, как concat(map(s#)(map(n-)s)). Таким образом, в нашем примере сначала [58-5,58-8]вычисляется, а затем [[5,8]#53,[5,8]#50]результаты в [[7],[7]]или [7,7]после concat. Результат сопоставляется с шаблоном, x:mчтобы убедиться, что в списке есть хотя бы один элемент (в minimumпротивном случае происходит сбой), затем одноэлементный список, равный 1, и минимум результата будут перенастроены. Еслиnбыло меньше нуля или рекурсивный вызов возвратил пустой список, мы находимся в ошибочной ветви поиска и возвращается пустой список. Если n==0ветка прошла успешно и [0]возвращается.


Haskell , 101 байт

f n=[d|d<-[9,8..1],show d!!0`elem`show n]#n!!0
s@(d:r)#n|n>=d,[x]<-s#(n-d)=[x+1]|1<3=r#n
s#n=[0|n==0]

Попробуйте онлайн! Способ более эффективный, проверяет все тестовые случаи за одну секунду.

На этот раз список цифр ввода вычисляется в порядке убывания, что позволяет (#)пытаться использовать наибольшую цифру как можно чаще, затем вторую по величине и так до тех пор, пока не будет найдено решение. Первое решение, найденное таким образом, также гарантированно будет самым маленьким.

Laikoni
источник