Самосумкові числа


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

Чи можемо ми прийняти дані як рядок, char-масив або цілий масив?
Kevin Cruijssen

1
@KevinCruijssen String - це нормально. char-масив або integer-масив не є.

Відповіді:


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

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

Ви не проти додати пояснення?
Йона

@Jonah Пояснення додано.
notjagan

1
Дякую. Цікаво, що в Pyth є примітив, який по суті вирішує проблему в./
Йона

12-байтна альтернатива: lef<.{TjQ;./(фільтр - власне підмножина - цифри введення)
Містер Xcoder

2

Математика, 78 байт

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

знаходить останній тестовий випадок за 5 сек


Трохи коротше: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}

Спробуйте в Інтернеті! (версія для гольфу)

Чистий алгоритм грубої сили, тому він насправді не вирішує всіх тестових випадків, і я думаю, що він намагався виділити 40 000 ГБ для останнього тестового випадку ...

Tв R за замовчуванням, щоб 1ми отримали помилку за одним, яку ми виправляємо на етапі повернення, але ми також отримуємо, 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

Спробуйте в Інтернеті! (менш гофрована версія)


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, які реально не дозволяють мені запускати це на найбільших входах. Отже, це не правильне рішення, насправді я розігрувався зі збільшенням межі рекурсії, що тільки призвело до сегментних помилок. Це потрібно робити або з циклом і стеком, або з набагато більшою кмітливістю для роботи в пітоні.

редагувати: Завдяки caird та Chas Brown за 13 байт!


Ви можете використовувати inputта вимагати, щоб вхід був оточений лапками.
caird coinheringaahing

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?
Zacharý

1
@ Zacharý Я хочу найкоротшу суму, тобто мінімальну кількість цифр. Спроби, які призводять до недійсного рішення, не повинні зараховуватися, тому для їх виключення вони набирають нескінченність, що не впливає на мінімум.
Ніл

О, не зрозумів, що це рекурсивно.
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 через часовий обмеження> _ <

Будь-які поради щодо гольфу вітаються!


0

Пітон 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в сумі їх повинно бути не більше (оскільки 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]

Спробуйте в Інтернеті! Ефективніший підхід перевіряє всі тестові випадки за одну секунду.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.