Ile sposobów pisać liczby jako sumy kwadratów?

12

Zadanie

Biorąc pod uwagę dwie liczby całkowite di n, znajdź liczbę sposobów wyrażenia njako sumę dkwadratów. Oznacza to, n == r_1 ^2 + r_2 ^2 + ... + r_d ^2że r_mjest to liczba całkowita dla wszystkich liczb całkowitych 1 ≤ m ≤ d. Zauważ, że zamiana dwóch różnych wartości (np. r_1I r_2) jest uważana za inną niż oryginalne rozwiązanie.

Na przykład liczbę 45 można zapisać jako sumę 2 kwadratów 8 różnych sposobów:

45
== (-6)^2 + (-3)^2
== (-6)^2 + 3^2
== (-3)^2 + (-6)^2
== (-3)^2 + 6^2
== 3^2 + (-6)^2
== 3^2 + 6^2
== 6^2 + (-3)^2
== 6^2 + 3^2

Zasady

  • Wbudowane rozwiązania są dozwolone, ale niekonkurujące (ahem, Mathematica )
  • Standardowe luki są również zabronione.
  • Wejścia mogą być odwrócone.

Przykład I / O

In:   d, n

In:   1, 0
Out:  1

In:   1, 2
Out:  0

In:   2, 2
Out:  4

In:   2, 45
Out:  8

In:   3, 17
Out:  48

In:   4, 1000
Out:  3744

In:   5, 404
Out:  71440

In:   11, 20
Out:  7217144

In:   22, 333
Out:  1357996551483704981475000

To jest , więc wygrane są przy użyciu najmniejszej ilości bajtów!

JungHwan Min
źródło
Dlaczego usunąć to i napisali nowy jednocześnie można edytować wpis, który usunięty?
Leaky Nun
@LeakyNun Moja przeglądarka zgłosiła błędy, gdy próbowałem to edytować, nawet przed jego usunięciem.
JungHwan Min
Powiązane
Luis Mendo
1
Nie, n oznacza 0, a nie d.
Leaky Nun
1
@DeadPossum Dla 1, 0testu, istnieje 1sposób, aby wyrazić 0jako sumę 1kwadratu: 0 == 0^2.
JungHwan Min

Odpowiedzi:

7

Python 3 , 125 bajtów

n,d=eval(input())
W=[1]+[0]*n
exec("W=[sum(-~(j>0)*W[i-j*j]for j in range(int(i**.5)+1))for i in range(n+1)];"*d)
print(W[n])

Wypróbuj online!

Kończy ostatnią próbę za 0,078 s. Złożoność naiwna to O ( d n 2 ).

Leaky Nun
źródło
5

Mathematica, 8 bajtów, niekonkurujące

SquaresR
alephalpha
źródło
3
Jakby to było nawet potrzebne ... nie dodaje niczego nowego do pytania. : P
Erik the Outgolfer
@EriktheOutgolfer Obwiniaj pytanie; stwierdza wyraźnie, że jest dozwolone.
JollyJoker
Te momenty, w których niezintegrowane rozwiązania prawie pobiły wbudowane: D
David Mulder
@JollyJoker Chodzi mi o to, że odpowiedzi powinny dodać coś do pytania, w przeciwnym razie dlaczego nawet je opublikować? * wzrusza ramionami: P
Erik the Outgolfer
@DavidMulder Na początku brakowało mi „prawie” i byłem trochę zszokowany…
Erik the Outgolfer
5

Galaretka , 9 bajtów

Nr⁸²ṗS€ċ⁸

Wypróbuj online!

Trwa ni dw tej kolejności.

Erik the Outgolfer
źródło
Ile lat zajmie wykonanie ostatniego testu?
Leaky Nun
@LeakyNun Nie wiem, to jest poza moim zrozumieniem ...
Erik the Outgolfer
4

MATL , 13 bajtów

y_t_&:Z^U!s=s

Dane wejściowe są nzatem d. W niektórych przypadkach testowych zabrakło pamięci.

Wypróbuj online!

Wyjaśnienie

Rozważmy wejść 17, 3.

y     % Implicit inputs. Duplicate from below
      % STACK: 17, 3, 17
_     % Negate
      % STACK: 17, 3, -17
t_    % Duplicate. Negate
      % STACK: 17, 3, -17, 17
&:    % Two-input range
      % STACK: 17, 3, [-17 -16 ... 17]
Z^    % Cartesian power. Gives a matrix where each Cartesian tuple is a row
      % STACK: 17, [-17 -17 -17; -17 -17 -16; ...; 17 17 17]
U     % Square, element-wise
      % STACK: 17, [289 289 289; 289 289 256; ...; 289 289 289]
!s    % Transpose. Sum of each column
      % STACK: 17, [867 834 ... 867]
=     % Equals?, element-wise
      % STACK: 17, [0 0 ... 0] (there are 48 entries equal to 1 in between)
s     % Sum. Implicit display
      % STACK: 48
Luis Mendo
źródło
3

Haskell , 43 bajty

0#0=1
d#n=sum[(d-1)#(n-k*k)|d>0,k<-[-n..n]]

Tylko twoja podstawowa rekurencja. Definiuje funkcję binarnej poprawki #. Wypróbuj online!

Wyjaśnienie

0#0=1            -- If n == d == 0, give 1.
d#n=             -- Otherwise,
 sum[            -- give the sum of
  (d-1)#(n-k*k)  -- these numbers
  |d>0,          -- where d is positive
   k<-[-n..n]]   -- and k is between -n and n.

Jeśli d == 0i n /= 0, jesteśmy w drugim przypadku, a warunek d>0powoduje, że lista jest pusta. Suma pustej listy wynosi 0, co w tym przypadku jest poprawnym wynikiem.

Zgarb
źródło
2

05AB1E , 10 bajtów

Ð(Ÿ²ã€nOQO

Przyjmuje argumenty jako n, a następnie d. Ma problemy z rozwiązywaniem większych przypadków testowych.

Wypróbuj online!

Wyjaśnienie

Ð(Ÿ²ã€nOQO   Arguments n, d
Ð            Triplicate n on stack
 (           Negate n
  Ÿ          Range: [-n ... n]
   ²ã        Caertesian product of length d
     €n      Square each number
       OQ    Sum of pair equals n
         O   Total sum (number of ones)
kalsowerus
źródło
2

Mathematica, 38 bajtów

Count[Tr/@Tuples[Range[-#,#]^2,#2],#]&

Czysta funkcja biorąc wejść w kolejności n, d. Range[-#,#]^2podaje zestaw wszystkich możliwych kwadratów, z dodatnimi kwadratami wymienionymi dwukrotnie, aby liczba była poprawna; Tuples[...,#2]produkuje d-tuple takich kwadratów; Tr/@sumuje każdy d-tuple; i Count[...,#]liczy, ile wyników jest równych n.

Pierwsze kilka przypadków testowych kończy się szybko, ale szacuję, że uruchomienie tego przypadku zajęłoby około pół roku 1000,4. Zastąpienie Range[-#,#](dłuższym, ale) bardziej sensownym Range[-Floor@Sqrt@#,Floor@Sqrt@#]przyspiesza obliczenia do około 13 sekund.

Greg Martin
źródło
1

Mathematica, 53 51 bajtów

SeriesCoefficient[EllipticTheta[3,0,x]^#,{x,0,#2}]&
alephalpha
źródło
1

Python 2, 138

Bardzo nieefektywne rozwiązanie z moim ukochanym eval. Dlaczego nie?
Wypróbuj online

lambda n,d:d and 4*eval(eval("('len({('+'i%s,'*d+'0)'+'for i%s in range(n)'*d+'if '+'i%s**2+'*d+'0==n})')%"+`tuple(range(d)*3)`),locals())

Wygenerował i ocenia kod w następujący sposób:

len({(i0,i1,0)for i0 in range(n)for i1 in range(n)if i0**2+i1**2+0==n})

Więc dla niektórych dużych d będzie działać bardzo długo i zużyje dużo pamięci, mając złożoność O (n ^ d)

Dead Possum
źródło
1

k , 23 bajty

{+/y=+/{x*x}y-!x#1+2*y}

Wypróbuj online! To prosty brutalny forcer.

zgrep
źródło
1

Pyth - 16 bajtów

lfqQsm*ddT^}_QQE

Spróbuj

To jest okropnie nieefektywne

Maria
źródło