Кругові обмежені суми


10

Виклик

Давайте уявимо N-набір цілих чисел між 0 і Mвключно, і назвемо це F.

Всього (M + 1) ** Nможливих Fs.

Скільки таких Fs задовольняють усі наступні нерівності (індекс одноосновний)?

  • F[n] + F[n+1] <= M для 1 <= n < N
  • F[N] + F[1] <= M

Написати програму або функцію , яка приймає два позитивних цілих чисел N і , Mі виводить відповідь у будь-якій зручній формі.

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

(N,M) => Answer

(1,1) => 1
(2,1) => 3
(3,1) => 4
(4,1) => 7

(1,2) => 2
(2,2) => 6
(3,2) => 11
(4,2) => 26

(10,3) => 39175
(10,4) => 286555
(10,5) => 1508401

(25,3) => 303734663372
(25,4) => 43953707972058
(25,5) => 2794276977562073

(100,3) => 8510938110502117856062697655362747468175263710
(100,4) => 3732347514675901732382391725971022481763004479674972370
(100,5) => 60964611448369808046336702581873778457326750953325742021695001

Пояснення

M (max value of element) = 1

F[1] + F[1] <= 1; F = [0]
(1,1) => 1

F[1] + F[2] <= 1; F = [0,0], [0,1], [1,0]
(2,1) => 3

F = [0,0,0], [0,0,1], [0,1,0], [1,0,0]
(3,1) => 4

F = [0,0,0,0], [0,0,0,1], [0,0,1,0], [0,1,0,0], [0,1,0,1], [1,0,0,0], [1,0,1,0]
(4,1) => 7

---

M = 2

F[1] + F[1] <= 2; F = [0], [1]
(1,2) => 2

F = [0,0], [0,1], [0,2], [1,0], [1,1], [2,0]
(2,2) => 6

F = [0,0,0], [0,0,1], [0,0,2], [0,1,0], [0,1,1], [0,2,0], [1,0,0], [1,0,1],
[1,1,0], [1,1,1], [2,0,0]
(3,2) => 11

(4,2) => 26 (left as exercise for you)

Правила

  • Це виклик з . Тимчасова складність коду повинна бути многочленом MіN (наприклад , ви не можете створити всі (M + 1) ** Nкортежі , а потім перевірити умови). Будь ласка, поясніть свій підхід у поданні.
  • Діють стандартні правила . Виграє найкоротша відповідь у байтах.

Відповіді:


7

Python з numpy , 59 байт

lambda M,N:trace(mat(tri(M+1)[::-1])**N)
from numpy import*

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

Для підрахунку шляхів використовується матричне множення. Якщо точність поплавця є проблемою, matможна вказати mat(...,int).


Використання, mat(...,int)здається, не працює для n=100справ. Метод правильний (наприклад, симпатія для підсумовування потужностей коренів характерного многочлена працює, наприклад), але нуме десь йде не так, як числа збільшуються (можливо, це **оператор електроенергії?)
Джонатан Аллан

4

Піт , 27 байт

.N?Ys:RTtYh-QNgQ+NTs:Rdtszh

Демонстрація

Очікує введення у форматі:

M
N

Це класичне динамічне програмування, розташоване на лівому кінці значень, встановлених дотепер, правому кінці та поточному розмірі розриву.

Як це працює, у псевдокоді / Python:

.N          | define memoized fill(left, right, gap):
?           | if cap > 0 then
s:RTtY      | sum(fill(i, right, gap - 1)
h-QN        |     for i in range(M - left + 1))
gQ+NT       | else M >= left + right
            | output:
s:Rdtsz     | sum(fill(i, i, N - 1)
h           |     for i in range(M + 1))

Qвикористовується для M, zвикористовується для N, :це fill, Nце left, Tце right, Yце gap.


4

MATL , 13 12 байт

Q:&>~PiY^Xds

Спробуйте в Інтернеті! Це прямий переклад відповіді Python xnor і моя перша відповідь MATL, тому, швидше за все, це не оптимально. Наприклад, існує, швидше, коротший спосіб отримати верхньо-ліву трикутну матрицю з одиниць, ніж t&lYRP. Правка: І виявляється, є, а саме :&>~P. Дякуємо Луїсу Мендо за -1 байт!

               M is the first input and N the second
Q:             increment M and generate range from 1 to M+1
  &>           compare vector element wise with itself with greater-than function
               results in a upper-right triangular matrix
    ~          inverse to get lower-left triangular matrix
     P         flip rows to get upper-left triangular matrix
      i        input N
       Y^      take the matrix to the power of N
         Xds   compute the sum of the main diagonal

@LuisMendo Дякую! Хоча це лише один байт або є щось інше, що можна скинути?
Лайконі

1
Ні, це все, я не можу порахувати :-D
Луїс Мендо

2

Стакс , 17 байт

°(√&╒íƽ╨⌂'├╖▼1_Z

Запустіть і налагоджуйте його

Розпакований, неозорений та коментований, це виглядає приблизно так.

^1](    [1, 0, ... 0] with M zeroes
:)      get all rotations of the array
{       begin block
  {:+rm map each array to reverse(prefixSums(arr))
},v*    execute preceding block N-1 times
F       for each array, execute the rest of the program
  iT    remove the last i elements from the array, where i is the iteration index
  F+    add the remaining elements to the running total
        implicitly print output

Виконати цей


2

R , 72 байти

function(M,N)sum(diag(Reduce(`%*%`,rep(list(outer(0:M,0:M,"+")<=M),N))))

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

Підхід xnor підхід.

Збій для більших тестових випадків, оскільки R має лише 32-бітну цілочисельну підтримку (вони отримують літ до doubleдосягнення максимального значення int), тому потрібно використовувати gmpабо іншу арифметичну бібліотеку довільної точності.

Як не дивно, R не вистачає матричного оператора живлення, як ^завжди застосовується елементарно.


Насправді %^%в пакеті є належним чином реалізований оператор, expmякий дозволив би байт -5 , але, на жаль, він не доступний у TIO (мені довелося перевірити локально).
Кирило Л.

@KirillL. так, я це врахував, але я думаю, я буду дотримуватися своєї базової відповіді R. Також ви можете пограти в гольф до 60 байт, не завантажуючи весь пакет:function(M,N)sum(diag(expm::`%^%`(outer(0:M,0:M,"+")<=M,N)))
Джузеппе
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.