Circular Limited Sums


10

Herausforderung

Stellen wir uns ein NTupel von ganzen Zahlen zwischen 0 und Meinschließlich vor und nennen wir es F.

Insgesamt sind s (M + 1) ** Nmöglich F.

Wie viele solcher Fs erfüllen alle folgenden Ungleichungen (Index ist einsbasiert)?

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

Schreiben Sie ein Programm oder eine Funktion, die zwei positive ganze Zahlen akzeptiert N und Mdie Antwort in einer beliebigen Form ausgibt.

Testfälle

(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

Erläuterung

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)

Regeln

  • Dies ist eine Herausforderung mit . Die zeitliche Komplexität Ihres Codes sollte in Mund polynomisch seinN (z. B. können Sie nicht alle (M + 1) ** NTupel generieren und dann nach der Bedingung suchen). Bitte erläutern Sie Ihren Ansatz in Ihrer Einreichung.
  • Es gelten die Standardregeln für . Die kürzeste Antwort in Bytes gewinnt.

Antworten:


7

Python mit Numpy , 59 Bytes

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

Probieren Sie es online aus!

Verwendet die Matrixmultiplikation, um Pfade zu zählen. Wenn die Float-Genauigkeit ein Problem darstellt, kann matdies angegeben werden mat(...,int).


Die Verwendung mat(...,int)scheint für die n=100Fälle nicht zu funktionieren . Die Methode ist korrekt (die Verwendung von Sympy zum Summieren der Potenzen der Wurzeln des charakteristischen Polynoms funktioniert beispielsweise), aber Numpy geht irgendwo schief, wenn die Zahlen zunehmen (vielleicht ist es der Potenzoperator **?)
Jonathan Allan

4

Pyth , 27 Bytes

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

Demonstration

Erwartet Eingaben im Format:

M
N

Dies ist eine klassische dynamische Programmierung über dem linken Ende der bisher festgelegten Werte, dem rechten Ende und der aktuellen Größe der Lücke.

Wie es funktioniert, in Pseudocode / 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))

Qwird verwendet für M, zwird verwendet für N, :ist fill, Nist left, Tist right, Yist gap.


4

MATL , 13 12 Bytes

Q:&>~PiY^Xds

Probieren Sie es online aus! Dies ist eine direkte Übersetzung der Python-Antwort von xnor und meiner ersten MATL-Antwort, daher ist sie höchstwahrscheinlich nicht optimal. ZB gibt es wahrscheinlich einen kürzeren Weg, um eine dreieckige Matrix von oben links zu erhalten als t&lYRP. Edit: Und es stellt sich heraus, dass es nämlich gibt :&>~P. Vielen Dank an Luis Mendo für -1 Byte!

               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 Danke! Obwohl es nur ein Byte ist oder gibt es noch etwas, das gelöscht werden kann?
Laikoni

1
Nein, das ist es, ich kann nicht zählen :-D
Luis Mendo

2

Stax , 17 Bytes

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

Führen Sie es aus und debuggen Sie es

Ausgepackt, ungolfed und kommentiert sieht es so aus.

^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

Führen Sie diesen aus


2

R , 72 Bytes

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

Probieren Sie es online aus!

Ports xnors Ansatz.

Schlägt für größere Testfälle fehl, da R nur 32-Bit-Integer-Unterstützung bietet (sie werden umgewandelt, doublesobald der maximale int-Wert erreicht ist), sodass die Verwendung einer gmpanderen Arithmetikbibliothek mit beliebiger Genauigkeit erforderlich wäre.

Seltsamerweise fehlt R ein ^Matrixleistungsoperator , wie immer elementweise.


Eigentlich gibt es einen ordnungsgemäß implementierten %^%Operator im Paket expm, der -5 Bytes zulässt , aber leider ist er auf TIO nicht verfügbar (ich musste lokal testen).
Kirill L.

@ KirillL. Ja, ich hatte darüber nachgedacht, aber ich denke, ich werde bei meiner Basis-R-Antwort bleiben. Sie können das auch auf 60 Bytes reduzieren, indem Sie nicht das gesamte Paket laden:function(M,N)sum(diag(expm::`%^%`(outer(0:M,0:M,"+")<=M,N)))
Giuseppe
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.