Passa il cerchio dei quadrati delle unità di conteggio


24

Scrivere un programma o una funzione a cui viene dato un raggio intero r restituisce il numero di unità quadrate del cerchio con raggio r centrato sull'origine che attraversa. Se il cerchio passa esattamente attraverso un punto sulla griglia che non conta come passaggio attraverso i quadrati delle unità adiacenti.

Ecco un'illustrazione per r = 5 :

illustrazione Illustrazione di Kival Ngaokrajang, trovata su OEIS

Esempi:

0 → 0
1 → 4
4 → 28
5 → 28
49 → 388
50 → 380
325 → 2540
5524 → 44180
5525 → 44020



@Luke Ho appena cercato questo, ma sembra usare una definizione leggermente diversa (almeno non è d'accordo N = 50).
Martin Ender,

1
@smls Contando nel riquadro di delimitazione. Assicurati di non contare i quadrati in cui il cerchio tocca solo un angolo. I numeri su OEIS sono sbagliati, ho una correzione in corso di revisione al momento.
orlp

2
Ho l'impulso improvviso di costruire di nuovo cupole in Minecraft ...
Patrick Roberts,

2
Sei un compagno visualizzatore di 3Blue1Brown?
nitro2k01

Risposte:


12

Python 2 , 54 byte

f=lambda r,x=0:r-x and-~((r*r-x*x)**.5%1>0)*4+f(r,x+1)

Provalo online!

Meno golf (55 byte) ( TIO )

lambda r:8*r-4*sum((r*r-x*x)**.5%1==0for x in range(r))

Ciò stima l'output come 8*r, quindi corregge gli incroci dei vertici. Il risultato è 8*r-g(r*r), dove g(x)conta il numero di modi per scrivere xcome somma di due quadrati (tranne g(0)=0).

Se il cerchio non attraversasse mai alcun vertice, il numero di celle toccate equivarrebbe al numero di spigoli incrociati. Il cerchio passa attraverso 2*rle griglie verticali e 2*rle griglie orizzontali, passando ognuna in entrambe le direzioni, per un totale di 8*r.

Ma ogni incrocio su un vertice conta come due incroci di bordo mentre si entra in una sola nuova cella. Quindi, compensiamo sottraendo il numero di incroci di vertici. Ciò include i punti su assi come (r,0)pure le triple di Pitagora come (4,3)per r=5.

Contiamo per un singolo quadrante i punti (x,y)con x>=0e y>0con x*x+y*y==n, quindi moltipliciamo per 4. Facciamo questo contando il numero di sqrt(r*r-x*x)quel numero intero xnell'intervallo [0,r).


5

Mathematica, 48 byte

4Count[Range@#~Tuples~2,l_/;Norm[l-1]<#<Norm@l]&

Guarda il primo quadrante e conta il numero di celle della griglia per le quali l'input cade tra le norme degli angoli in basso a sinistra e in alto a destra della cella (moltiplicando il risultato per 4, ovviamente).


Un altro metodo si 8#-SquaresR[2,#^2]Sign@#&basa sul post di xnor
miglia

@miles Oh wow, non avevo idea che SquaresResistesse. Sentiti libero di postarlo tu stesso (o lascia che xnor lo pubblichi).
Martin Ender,


3

Gelatina , 21 13 12 11 byte

R²ạ²Æ²SạḤ×4

Provalo online!

Come funziona

R²ạ²Æ²SạḤ×4  Main link. Argument: r

R            Range; yield [1, 2, ..., r].
 ²           Square; yield [1², 2², ..., r²].
   ²         Square; yield r².
  ạ          Absolute difference; yield [r²-1², r²-2², ..., r²-r²].
    Ʋ       Test if each of the differences is a perfect square.
      S      Sum, counting the number of perfect squares and thus the integer
             solutions of the equation x² + y² = r² with x > 0 and y ≥ 0.
        Ḥ    Un-halve; yield 2r.
       ạ     Subtract the result to the left from the result to the right.
         ×4  Multiply by 4.

2

Perl 6, 61 byte

->\r{4*grep {my &n={[+] $_»²};n(1 X+$_)>r²>.&n},(^r X ^r)}

Come funziona

->\r{                                                    } # Lambda (accepts the radius).
                                                (^r X ^r)  # Pairs from (0,0) to (r-1,r-1),
                                                           #   representing the bottom-left
                                                           #   corners of all squares in
                                                           #   the top-right quadrant.
       grep {                                 }            # Filter the ones matching:
             my &n={[+] $_»²};                             #   Lambda to calculate the norm.
                              n(1 X+$_)>r²                 #   Top-right corner is outside,
                                          >.&n             #   and bottom-left is inside.
     4*                                                    # Return length of list times 4.

1

AWK, 90 byte

{z=$1*$1
for(x=$1;x>=0;x--)for(y=0;y<=$1;y++){d=z-x*x-y*y
if(d>0&&d<2*(x+y)+2)c++}$0=4*c}1

Uso:

awk '{z=$1*$1
    for(x=$1;x>=0;x--)for(y=0;y<=$1;y++){d=z-x*x-y*y
    if(d>0&&d<2*(x+y)+2)c++}$0=4*c}1' <<< 5525

Basta una semplice ricerca attraverso il quadrante 1 per trovare tutte le caselle che intersecheranno il cerchio. La simmetria consente di moltiplicare per 4. Potrebbe andare da -$1 to $1, ma ciò richiederebbe più byte e sarebbe meno efficiente. Ovviamente questo non è il tempo più efficiente degli algoritmi, ma ci vogliono solo circa 16 secondi per eseguire il case 5525 sulla mia macchina.


1

Haskell, 74 byte

f n=sum[4|x<-[0..n],y<-[0..n],(1+n-x)^2+(1+n-y)^2>n^2,(n-x)^2+(n-y)^2<n^2]

Abbastanza semplice, conta il numero di quadrati tra (0,0) e (n, n) dove la parte inferiore sinistra è all'interno del cerchio e la parte superiore destra è esterna al cerchio, quindi moltiplica per 4.


0

Pyth , 29 byte

Lsm*ddb*4lf}*QQrhyTym+1dT^UQ2

Provalo!

Spiegazione

Lsm*ddb*4lf}*QQrhyTym+1dT^UQ2  # implicit input: Q
Lsm*ddb                        # define norm function
 s                             # sum
  m   b                        #     map each coordinate to
   *dd                         #                            its square
                         ^UQ2  # cartesian square of [0, 1, ..., Q - 1]
                               #     -> list of coordinates of all relevant grid points
          f                    # filter the list of coordinates T where:
           }*QQ                # square of Q is in
               r               #     the range [
                hyT            #         1 + norm(T),
                               #                  ^ coordinate of lower left corner
                   ym+1dT      #         norm(map({add 1}, T))
                               #              ^^^^^^^^^^^^^^^ coordinate of upper right corner
                               #     ) <- half-open range
         l                     # size of the filtered list
                               #     -> number of passed-through squares in the first quadrant
       *4                      # multiply by 4
                               # implicit print

0

Lotto, 147 byte

@set/an=0,r=%1*%1
@for /l %%i in (0,1,%1)do @for /l %%j in (0,1,%1)do @set/a"i=%%i,j=%%j,a=i*i+j*j-r,i+=1,j+=1,a&=r-i*i-j*j,n-=a>>31<<2
@echo %n%

In qualche modo ispirato dalle risposte di AWK e Haskell.


Sono contento di poter in qualche modo ispirare qualcuno :)
Robert Benson,

0

Utilità Bash + Unix, 127 byte

c()(d=$[(n/r+$1)**2+(n%r+$1)**2-r*r];((d))&&echo -n $[d<0])
r=$1
bc<<<`for((n=0;n<r*r;n++));{ c 0;c 1;echo;}|egrep -c 01\|10`*4

Provalo online!

Basta passare attraverso tutti i punti nel primo quadrante, contarli e moltiplicarli per 4. Può essere molto lento, ma funziona.


0

JavaScript (ES7), 76 byte

n=>4*(G=k=>k<n?Math.ceil((n**2-k++**2)**0.5)-(0|(n**2-k**2)**0.5)+G(k):0)(0)

Puoi forse radere via un paio di byte ricorrendo dal nbasso al 0?
Neil

@Neil ci ho provato ma non sono riuscito a vedere un modo. Volevo usare solo una funzione, ma ho ancora bisogno di memorizzare sia il nraggio che l' kiterazione e tutti i tentativi sono usciti negli stessi byte
George Reith

@Neil Ah Capisco di cosa stai parlando k<n?...ma perdo su quei byte che riordinano n**2-k++**2perché la precedenza dell'operatore è sbagliata quando si va in retromarcia e la sottrazione non è commutativa, quindi la parte sinistra deve sempre avere k-1e ha bisogno di parentesi. A meno che tu non abbia trovato un modo?
George Reith,

Ah, ho trascurato la sottrazione ... forse puoi moltiplicare il tutto per -4 anziché 4 per aggirare questo? (Anche se questo potrebbe ancora rovinare il tuo risparmio ...)
Neil,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.