Circular Limited Sums

10

Wyzwanie

Wyobraźmy sobie Nliczbę liczb całkowitych od 0 do Mwłącznie i nazwijmy to F.

(M + 1) ** Nmożliwe Fs w sumie.

Ile takich Fspełnia wszystkie następujące nierówności (indeks jest oparty na jednym)?

  • F[n] + F[n+1] <= M dla 1 <= n < N
  • F[N] + F[1] <= M

Napisać program lub funkcję, która pobiera dwie liczby całkowite dodatnie N a Mi wysyła odpowiedź w dowolnej dogodnej postaci.

Przypadki testowe

(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

Wyjaśnienie

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)

Zasady

  • Jest to wyzwanie o . Złożoność czasowa kodu powinna być wielomianowa MiN (np. Nie można wygenerować wszystkich (M + 1) ** Nkrotek, a następnie sprawdzić warunek). Proszę wyjaśnić swoje podejście w swoim zgłoszeniu.
  • Obowiązują standardowe zasady . Najkrótsza odpowiedź w bajtach wygrywa.
Bubbler
źródło

Odpowiedzi:

7

Python z numpy , 59 bajtów

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

Wypróbuj online!

Używa mnożenia macierzy do zliczania ścieżek. Jeśli problemem jest precyzja zmiennoprzecinkowa, matmożna to określić mat(...,int).

xnor
źródło
Używanie mat(...,int)nie wydaje się działać w tych n=100przypadkach. Metoda jest poprawna (na przykład sympy do sumowania mocy pierwiastków charakterystycznego wielomianu działa, na przykład), ale numpy idzie gdzieś nie tak, jak rosną liczby (może to jest **operator mocy?)
Jonathan Allan
4

Pyth , 27 bajtów

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

Demonstracja

Oczekuje danych wejściowych w formacie:

M
N

Jest to klasyczne programowanie dynamiczne, nad lewym końcem ustawionych do tej pory wartości, prawym końcem i bieżącym rozmiarem.

Jak to działa, w pseudokodzie / Pythonie:

.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))

Qjest używany do M, zjest używany N, :jest fill, Njest left, Tjest right, Yjest gap.

isaacg
źródło
4

MATL , 13 12 bajtów

Q:&>~PiY^Xds

Wypróbuj online! To jest bezpośrednie tłumaczenie odpowiedzi Xnora na Python i mojej pierwszej odpowiedzi MATL, więc najprawdopodobniej nie jest optymalne. Np. Istnieje prawdopodobnie krótszy sposób, aby uzyskać górną lewą trójkątną matrycę jedności niż t&lYRP. Edycja: I okazuje się, że jest :&>~P. Dzięki Luis Mendo za -1 bajt!

               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
Laikoni
źródło
@LuisMendo Thanks! Chociaż jest to tylko jeden bajt, czy jest coś jeszcze, co można upuścić?
Laikoni
1
Nie, to wszystko, nie mogę liczyć :-D
Luis Mendo
2

Stax , 17 bajtów

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

Uruchom i debuguj

Rozpakowane, niepolowane i skomentowane, wygląda to tak.

^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

Uruchom ten

rekurencyjny
źródło
2

R , 72 bajty

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

Wypróbuj online!

Podejście do Xnora.

Nie udaje się w przypadku większych przypadków testowych, ponieważ R ma jedynie 32-bitową obsługę liczb całkowitych (są one rzutowane na wartość doublepo osiągnięciu maksymalnej wartości int), więc gmpwymagane byłoby użycie innej biblioteki arytmetycznej o dowolnej dokładności.

O dziwo, R nie ma operatora mocy macierzy, jak ^zawsze stosuje się elementarnie.

Giuseppe
źródło
Właściwie %^%w pakiecie jest poprawnie zaimplementowany operator expm, który pozwalałby na -5 bajtów , ale niestety nie jest on dostępny w TIO (musiałem przetestować lokalnie).
Kirill L.,
@KirillL. tak, rozważyłem to, ale myślę, że pozostanę przy mojej podstawowej odpowiedzi R. Możesz także zagrać w golfa do 60 bajtów, nie ładując całego pakietu:function(M,N)sum(diag(expm::`%^%`(outer(0:M,0:M,"+")<=M,N)))
Giuseppe