Проблема монети


20

Фон

Офіційною грошовою одиницею уявної нації Golfenistan є foo , і в обігу є лише три види монет: 3 foos, 7 foos та 8 foos. Видно, що за ці монети неможливо сплатити певні суми, наприклад, 4 фути. Тим не менш, всі великі суми можуть бути сформовані. Ваше завдання - знайти найбільшу суму, яку неможливо сформувати разом з монетами (5 футів у цьому випадку), яка відома як проблема монети .

Вхідні дані

Ваша інформація - це список натуральних чисел, що представляють значення монет в обігу. Про це гарантовано дві речі:L = [n1, n2, ..., nk]

  • GCD елементів Lдорівнює 1.
  • L не містить числа 1.

Він може бути несортованим та / або містити дублікати (думаю, монети спеціального видання).

Вихідні дані

Оскільки GCD Lдорівнює 1, кожне досить велике ціле число mможе бути виражене як негативна лінійна комбінація його елементів; Іншими словами, у нас є

 m = a1*n1 + a2*n2 + ... + ak*nk 

для деяких цілих чисел . Ваш вихід є найбільшим цілим числом, яке не може бути виражено у цій формі. Як підказку, відомо, що вихід завжди менший за , якщо і є максимальними і мінімальними елементами ( посилання ).ai ≥ 0(n1 - 1)*(nk - 1)n1nkL

Правила

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

Після того як я опублікував цей виклик, користувач @vihan вказав, що стек Overflow має точний дублікат . Виходячи з цього обговорення в Meta , цей виклик не буде видалений як дублікат; проте я прошу, щоб усі відповіді, засновані на версіях версії SO, цитували оригінали, надавали статус спільноти Wiki та були видалені, якщо автор-оригінал хоче опублікувати свою відповідь тут.

Випробування

[3, 7, 8] -> 5
[25, 10, 16] -> 79
[11, 12, 13, 14, 13, 14] -> 43
[101, 10] -> 899
[101, 10, 899] -> 889
[101, 10, 11] -> 89
[30, 105, 70, 42] -> 383
[2, 51, 6] -> 49

5
FrobeniusNumberв Математиці.
алефалфа

3
Існує спосіб кращої верхньої межі, знайдений у цій статті, який визначає (p - 1)(q - 1)як верхню межу, де pі qє найменшим і найбільшим елементом набору.
orlp

2
Чи є обмеження часу роботи або використання пам'яті?
Денніс

1
На переповнюванні стека виникло таке питання про кодовий гольф, як цей час назад
Downgoat

1
У мене є 13-байтне рішення Pyth, яке можна зробити [2,3]за розумну кількість часу і більше нічого. [2,5]створило б близько мільйона списків Python в пам'яті.
isaacg

Відповіді:


4

Pyth, 23 байти

ef!fqTs.b*NYQY^UTlQS*FQ

Це дуже повільно, оскільки він перевіряє всі цінності аж до добутку всіх монет. Ось версія, яка майже однакова, але 1) зменшує набір монет на ті, що не діляться одна від одної, і 2) перевіряє лише значення до (max(coins) - 1) * (min(coins) - 1)(47 байт):

=Qu?.A<LiHdG+GHGQYef!fqTs.b*NYQY^UTlQS*thSQteSQ

Пояснення

                   S            range 1 to
                    *FQ         product of input
 f                             filter by
               UT                range 0 to T 
              ^  lQ              cartesian power by number of coins
   f                            filter by
      s.b*NYQY                   sum of coin values * amounts
    qT                           equals desired number T
  !                             nothing matching that filter
e                             take last (highest) element

8

Perl, 60 54 51 байт

50 байт коду + 1 байт командного рядка

$.*=$_,$r.=1x$_."|"}{$_=$.while(1x$.--)=~/^($r)+$/

Продовжуйте займатися гольфом та опублікуйте пояснення пізніше. Основний підхід полягає в тому, щоб дозволити двигуну регулярних операцій виконувати важку роботу з узгодженням рядків. Наприклад, він побудує регулярний вираз, подібний до ^(.{3})*(.{7})*(.{8})*$та збігається з рядком довжини, nде nсходить від добутку входів, поки він не збігається.

Зауважте, що це стане експоненціально повільним у міру збільшення кількості аргументів.

Використання: аргументи зачитуються з STDIN (новий рядок відокремлено), наприклад:

printf "101\n10" | perl -p entry.pl

3

R , 84 78 байт

Для довільного введення копріум, а1,а2,, Сума Фробеніуса наведена за

a=scan();max((1:(b<-min(a)*max(a)))[-colSums(combn(outer(a,0:b),sum(!!a)))])

Спробуйте в Інтернеті!

оскільки він завжди менший за добуток крайності аi's. Тоді питання поєднання всіх можливих комбінацій (і більше) у межах цього діапазону. Дякуємо Коулу Беку за те, що він запропонував outer"без" і colSumsзамість "застосувати (..., 2, сума)".

Більш швидка, але довша (на два байти) версія враховує лише max(a):

a=scan();max((1:(min(a)*(b<-max(a))))[-apply(combn(outer(a,0:b,"*"),sum(!!a)),2,sum)])

Трохи більш коротка версія (78 байт) , який частіше за все займає надто увійти або занадто багато місця , щоб працювати на Спробувати онлайн є

a=scan();max((1:(b<-prod(a)))[-apply(combn(outer(a,0:b,"*"),sum(!!a)),2,sum)])

1

Python2, 188 187 байт

def g(L):
 M=max(L);i=r=0;s=[0]*M;l=[1]+s[1:]
 while 1:
    if any(all((l+l)[o:o+min(L)])for o in range(M)):return~-s[r]*M+r
    if any(l[(i-a)%M]for a in L):l[i]=1
    else:r=i
    s[i]+=1;i=(i+1)%M

Другий відступ подається у вигляді 4 пробілів на SO, це повинні бути вкладки.

Насправді "швидке" рішення, а не груба сила, використовує "метод Вільфа", як описано тут .


1

Javascript ES6, 120 130 126 128 127 125 символів

f=a=>`${r=[1|a.sort((a,b)=>a-b)]}`.repeat(a[0]*a[a.length-1]).replace(/./g,(x,q)=>r[q]|a.map(x=>r[q+x]|=r[q])).lastIndexOf(0)

Альтернативна версія 126 символів:

f=a=>{r=[1];a.sort((a,b)=>a-b);for(q=0;q<a[0]*a[a.length-1];++q)r[q]?a.map(x=>r[q+x]=1):r[q]=0;return r.join``.lastIndexOf(0)}

Тест:

"[3, 7, 8] -> 5\n\
[25, 10, 16] -> 79\n\
[11, 12, 13, 14, 13, 14] -> 43\n\
[101, 10] -> 899\n\
[101, 10, 899] -> 889\n\
[101, 10, 11] -> 89\n\
[30, 105, 70, 42] -> 383\n\
[2, 51, 6] -> 49".replace(/(\[.*?\]) -> (\d+)/g, function (m, t, r) {
  return f(JSON.parse(t)) == r
})

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