Calcola la radice quadrata solo usando ++


13

Il tuo compito è calcolare la radice quadrata di un numero intero positivo senza utilizzare alcun operatore matematico per modificare il numero, ad esempio:

  • Impostazione di una variabile (es. SquareRoot = 5)
  • Aggiunta (A + B)
  • Sottrazione (AB)
  • Moltiplicazione (A * B)
  • Divisione (A / B)
  • Radici quadrate, cubiche, quarte ecc
  • esponenti

Gli operatori di confronto (come <,>, ==, ecc.) Non sono considerati "operatori matematici" ai fini di questa domanda e sono consentiti purché non modifichino il valore di una variabile.

L'unico operatore che sei in grado di utilizzare è ++. Sono presenti le seguenti eccezioni:

  • Se lo desideri, puoi inizializzare una variabile impostandola su 0.
  • Se la tua lingua non include la sintassi ++, puoi usare una sintassi equivalente, come foo + = 1 o foo = foo + 1
  • La radice quadrata dovrebbe essere calcolata ad almeno 6 cifre oltre il decimale (la posizione delle centinaia di migliaia) e emessa come un numero intero di decimali (es. Se inserisco 2 potrebbe risultare come 14142135624 o 1414213 a seconda dell'arrotondamento) . L'arrotondamento per eccesso o per difetto non è importante.

Le funzioni definite dall'utente non sono consentite. Inoltre, non è consentita la simulazione di funzioni con goto.

Sono interessato a vedere ciò che tutti inviano! Buona programmazione!

UNA PRECISAZIONE

Chiarire che il numero è un numero intero positivo. Puoi creare un codice che farebbe qualsiasi numero ma non è necessario.

CHIARIMENTO # 2

Chiarire che gli operatori di confronto sono ammessi.

CHIARIMENTO # 3

Aggiunta, sottrazione, moltiplicazione, divisione e funzioni per modificare i numeri non sono consentiti affatto , indipendentemente dal fatto che vengano salvati in una variabile o meno. Mi dispiace che ciò invalidi un paio di risposte esistenti, ma intendevo definire questo gruppo di operatori con "cambia il numero" al fine di prevenire le risposte del troll (es. Ho appena usato la funzione sqrt (), hai proibito solo l'aggiunta, moltiplicazione, divisione e sottrazione). Dispiace per la confusione.

CHIARIMENTO # 4

Chiarire che abbiamo bisogno di almeno 5 cifre. 10 cifre hanno causato l'esecuzione a lungo del codice.


1
No, - non è permesso, scusate la confusione! Inizialmente avevo in programma di avere ++ e - ma ho deciso di eliminarlo - all'ultimo minuto.
iggyvolz,

5
"senza usare alcun operatore matematico per cambiare il numero" - Penso che questo potrebbe aver bisogno di chiarimenti. Intendi dire che questi operatori potrebbero non essere usati affatto , o che potrebbero essere usati, ma solo se il risultato non viene salvato in una variabile, ad esempio while r*r<n*10e20:r+=1- abbastanza banale. Inoltre, potresti considerare di ridurre l'output richiesto a 10 ^ 8 o giù di lì. Innanzitutto, perché 10 ^ 10 è maggiore di 2 ^ 31 e, in secondo luogo, perché ci vorrà del tempo per incrementare così in alto.
primo

1
Perché mai vorresti "cambiare" qualsiasi variabile? Ragazzi imperativi avete strani modi di pensare ...
cessò di girare in senso antiorario il

4
Sto segnalando di chiudere questa domanda. A cambiamenti molto radicali alla domanda. In realtà dovresti ottenere questa domanda convalidata tramite Sandbox, altrimenti frustrerai le persone che investono nello sforzo di rispondere.
Abhijit,

3
Ridurre il numero di cifre richieste non ha senso senza limiti di tempo / memoria. Il mio codice può gestire 5 cifre, ma la mia macchina non ha abbastanza RAM.
Dennis,

Risposte:


13

Python 66

print'%.0f'%reduce(lambda a,b:abs(a)+1e10j,range(-2,input())).real

Produzione

>>> print'%.0f'%reduce(lambda a,b:abs(a)+1e10j,range(-2,input())).real
121
110000000000
>>> print'%.0f'%reduce(lambda a,b:abs(a)+1e10j,range(-2,input())).real
1000
316227766017

Questa soluzione utilizza Spirale di Teodoro su un piano complesso per ottenere il risultato.


2
Penso che dovrà essere avvolto int(...*1e10), altrimenti molto bello. Tuttavia, l'assunzione absdi un valore complesso è più o meno sqrtmascherata.
primo

1
@primo Non credo che ti sia permesso il *1e10...
Cruncher,

@primo: Invece di moltiplicare per 1e10, ho preso una strada leggermente diversa. E anche se sono d'accordo sul fatto che gli addominali possono essere sqrt sotto mentite spoglie, tuttavia ritengo che sia completamente legale come attualmente indicato nel problema.
Abhijit,

Vedo un downvote ed è abbastanza deprimente. Avevo una grande speranza per questa risposta, quindi chiunque abbia effettuato il downgrade, si prega di lasciare un commento.
Abhijit,

9
@iggyvolz: sono davvero sorpreso che tu continui ad espandere la tua domanda e ad aggiungere ulteriori restrizioni. Le persone investono tempo e fatica per scrivere una risposta e non puoi aspettarti che siano psichiche.
Abhijit,

6

Python, 184 caratteri

La seguente soluzione Python utilizza solo l'operatore di incremento e nessun altro operatore aritmetico. Tuttavia, con la precisione richiesta (10 cifre), l'esecuzione richiede un tempo incredibilmente lungo. È possibile testarlo con una precisione inferiore (3 cifre) riducendo 1e20a 1e6.

import sys;t=0
for _ in range(int(sys.argv[1])):
 for _ in range(int(1e20)):t+=1
q=0
while 1:
 z=0
 for _ in range(q):
  for _ in range(q):z+=1
 if z>=t:break
 q+=1
print(q)

Ungolfed:

import sys

# t = N * 100000000000000000000 (magnitude of twice the precision)
t = 0
for _ in range(int(sys.argv[1])):
    for _ in range(int(1e20)):
        t += 1
q = 0
while True:
    # z = q * q
    z = 0
    for _ in range(q):
        for _ in range(q):
            z += 1
    if z >= t:
        break
    q += 1
print(q)

Ho chiarito la domanda, puoi farlo con tutte le cifre che vuoi (almeno 5). Non ho familiarità con Python, ma presumo che int () sia solo un tipo caster? In tal caso, va bene perché non cambia il valore del numero.
iggyvolz,

@iggyvolz: giusto, è necessario per convertire il valore dell'argomento stringa (specificato nella riga di comando) in un numero intero. Una semplice funzione non sarebbe necessaria.
Greg Hewgill,

2

Fortran 73

read*,t;s=0;do while(abs(s*s/1e10-t)>1e-10);s=s+1;enddo;print*,s/1e5;end

Potrebbe volerci un attimo per determinare effettivamente una risposta per determinati valori, ma funzionerà di sicuro. Mentre io uso *e -, questi non cambiano alcun valore , solo il s=s+1reale cambia qualcosa.


Wow, suppongo che non pensassi di usare gli operatori per cambiare i valori statici. Va benissimo e +1 (se avessi 15 reputazione da votare)
iggyvolz

Questo utilizza l' *operatore, il che è chiaramente vietato. O sto in qualche modo fraintendendo le restrizioni date?
Greg Hewgill,

@GregHewgill: stati OP, senza utilizzare alcun operatore matematico per modificare il numero ; questi operatori non stanno modificando alcun valore.
Kyle Kanos,

7
Ma sta ancora usando l' *operatore per cambiare un numero, non stai semplicemente salvando il risultato da nessuna parte. Se l'OP voleva semplicemente rifiutare incarichi (diversi da s=s+1), allora perché menzionare tutti gli operatori aritmetici non ammessi?
Greg Hewgill,

1
@iggyvolz: cambiare le regole ~ 20 ore dopo è una cattiva forma. Non farlo e utilizzare invece la sandbox per risolvere i nodi del problema.
Kyle Kanos,

2

CJam, 26 byte

q~,1e20,m*,:N!{)_,_m*,N<}g

Provalo online. Incolla il codice , digita il numero intero desiderato in Input e fai clic su Esegui . Prima di farlo, suggerisco di passare 1e10a1e4 però.

L' interprete Java gestisce 1e6con l'ingresso "2" in circa 15 secondi. 1e20richiederà un enorme quantità di RAM.

Esempi

$ cjam <(echo 'q~,1e2,m*,:N!{)_,_m*,N<}g') <<< 4; echo
20
$ cjam <(echo 'q~,1e2,m*,:N!{)_,_m*,N<}g') <<< 2; echo
15
$ cjam <(echo 'q~,1e4,m*,:N!{)_,_m*,N<}g') <<< 4; echo
200
$ cjam <(echo 'q~,1e4,m*,:N!{)_,_m*,N<}g') <<< 2; echo
142
$ cjam <(echo 'q~,1e6,m*,:N!{)_,_m*,N<}g') <<< 4; echo
2000
$ cjam <(echo 'q~,1e6,m*,:N!{)_,_m*,N<}g') <<< 2; echo
1415

sfondo

Dato che non ci è permesso agli operatori matematici di cambiare i numeri, useremo gli operatori di rete per cambiare gli array.

Il codice inizia "moltiplicando" l'input ("i") per 1e20, ma senza alcuna moltiplicazione effettiva. Invece, inviamo un array contenente numeri interi "i", un array contenente 1e20 numeri interi, prendiamo il loro prodotto cartesiano e ne calcoliamo la lunghezza.

Quindi, spingiamo zero e incrementiamo fino a quando il prodotto dell'intero da solo (calcolato come sopra) non è più piccolo di i * 1e20 . Ciò provoca l'arrotondamento della radice quadrata.

Come funziona

q~     " Read for STDIN and interpret. ";
,      " Push an array containing that many integers. ";
1e20,  " Push the array [ 0   …   1e20 - 1]. ";
m*,:N  " Get the length of the cartesian product and save it in “N”. ";
!      " Logical NOT. Since the input is a positive integer, this pushes 0. " ;
{      " ";
  )    " Increment the integer on the stack.";
  _,   " Push an array containing that many integers. ";
  _m*, " Get the length of the cartesian product of the array by itself. ";
  N<   " If the product is smaller than the target value, push 1; otherwise push 0. ";
}g     " Repeat the loop if the result was 1. ";

1

Cobra - 62

Inserito prima della terza modifica, non più valido.

Non solo è corto, ma dovrebbe essere privo di trabocco se n < Decimal.maxValue

def f(n)
    r,e=0d,10000000000
    while r/e*r/e<n,r+=1
    print r

Ma tu hai usato r/e*r/e, che è chiaramente un ++operatore non matematico ...
nneonneo,

@nneonneo questo è stato pubblicato prima della terza modifica e non l'ho ancora cambiato
Οurous

0

Scala, 117

val z=BigInt(readLine+"0000000000")
print(Stream.from(1)find(x=>(BigInt(0)/:Stream.fill(x,x)(1).flatten){_+_}>=z)get)

Non termina in un lasso di tempo ragionevole, anche per 2 come input, ma funziona. Potresti notare che lo sto facendo _+_, ma che aggiunge sempre e solo 1, e Scala non ha ++comunque un operatore. Potrei salvare due caratteri sostituendo lo Stream interno con Elenco, ma rimarrebbe a corto di memoria. Come scritto, penso che si ridimensiona solo nel tempo di elaborazione, non nell'uso della memoria.


0

Haskell, 70 byte

s i|r<-[1..i]=foldl1(.)[(+1)|j<-r,k<-r]
f i=[j-1|j<-[0..],s j 0>=i]!!1

ffornisce la radice quadrata intera trovando il numero più grande il cui quadrato è minore o uguale all'input. La funzione di quadratura s iaumenta di uno per ogni elemento di una (i,i)matrice. (Digitato sul telefono, quindi potrebbe avere errori di battitura).


0

PHP, 124 byte

È un algoritmo esaustivo. Prova solo i numeri fino a quando il quadrato di quel numero è più grande del numero "goal" (che è il tempo di input 1E al number of decimalsquadrato (10.000 per un risultato decimale 2), quindi stampa l'ultimo numero.

for(;$a++<$z=$argv[1];)for(;$$a++<1e6;)$g++;for(;$b++<$g;$i=$x=0)for(;$i++<$b;)for($j=0;$j++<$b;)if(++$x>=$g)break 3;echo$b;

Esegui in questo modo ( -daggiunto solo per motivi estetici):

php -d error_reporting=32757 -r 'for(;$a++<$z=$argv[1];)for(;$$a++<1e6;)$g++;for(;$b++<$g;$i=$x=0)for(;$i++<$b;)for($j=0;$j++<$b;)if(++$x>=$g)break 3;echo"$b\n";' 2

Non raccomandare di provarlo con qualcosa di più di 3 decimali o un numero superiore a 10.

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.