Berechnen Sie die Quadratwurzel nur mit ++

13

Ihre Aufgabe ist es, die Quadratwurzel einer positiven Ganzzahl zu berechnen, ohne mathematische Operatoren zum Ändern der Zahl zu verwenden, z.

  • Variable setzen (zB squareRoot = 5)
  • Zusatz (A + B)
  • Subtraktion (AB)
  • Multiplikation (A * B)
  • Abteilung (A / B)
  • Quadrat-, Würfel-, vierte usw. Wurzeln
  • Exponenten

Vergleichsoperatoren (wie <,>, == usw.) werden für die Zwecke dieser Frage nicht als "mathematische Operatoren" betrachtet und sind zulässig, solange sie den Wert einer Variablen nicht ändern.

Der einzige Operator, den Sie verwenden können, ist ++. Folgende Ausnahmen bestehen:

  • Wenn Sie möchten, können Sie eine Variable initialisieren, indem Sie sie auf 0 setzen.
  • Wenn Ihre Sprache die ++ - Syntax nicht enthält, können Sie eine äquivalente Syntax verwenden, z. B. foo + = 1 oder foo = foo + 1
  • Die Quadratwurzel sollte mit mindestens 6 Stellen nach der Dezimalstelle (der Hunderttausenderstelle) berechnet und als ganze Zahl der Dezimalstellen ausgegeben werden (z. B. wenn ich 2 eingebe, könnte dies je nach Rundung 14142135624 oder 1414213 lauten). . Auf- oder Abrunden ist nicht wichtig.

Benutzerdefinierte Funktionen sind nicht erlaubt. Außerdem ist das Simulieren von Funktionen mit goto nicht erlaubt.

Ich bin gespannt, was alle einreichen! Viel Spaß beim Codieren!

KLÄRUNG

Stellen Sie sicher, dass diese Zahl eine positive ganze Zahl ist. Sie können gerne Code erstellen, der eine beliebige Zahl enthält, dies ist jedoch nicht erforderlich.

ERKLÄRUNG 2

Stellen Sie klar, dass Vergleichsoperatoren zulässig sind.

ERKLÄRUNG 3

Addition, Subtraktion, Multiplikation, Division und Funktionen Änderungsnummern sind nicht erlaubt überhaupt , und zwar unabhängig davon , ob sie zu einer Variablen gespeichert werden oder nicht. Es tut mir leid, dass dies ein paar vorhandene Antworten ungültig macht, aber ich wollte diese Gruppe von Operatoren mit "Nummer ändern" definieren, um Trollantworten zu verhindern (z. B. ich habe gerade die Funktion sqrt () verwendet, Sie haben nur das Hinzufügen verboten, Multiplikation, Division und Subtraktion). Entschuldigung für die Verwirrung.

ERKLÄRUNG 4

Stellen Sie sicher, dass wir mindestens 5 Ziffern benötigen. 10 Ziffern führten dazu, dass der Code lange Zeit ausgeführt wurde.

iggyvolz
quelle
1
Nö, - ist nicht erlaubt, sorry für die Verwirrung! Ich hatte ursprünglich geplant, ++ zu haben und - aber ich entschied mich dafür - in letzter Minute herauszunehmen.
Iggyvolz
5
"ohne mathematische Operatoren zu verwenden, um die Zahl zu ändern" - ich denke, das muss geklärt werden. Wollen Sie damit sagen , dass diese Betreiber können nicht verwendet werden , überhaupt , oder, dass sie verwendet werden können, aber nur , wenn das Ergebnis nicht auf eine Variable gespeichert, zum Beispiel while r*r<n*10e20:r+=1- ziemlich trivial. Sie können auch in Betracht ziehen, die erforderliche Ausgabe auf etwa 10 ^ 8 zu reduzieren. Erstens, weil 10 ^ 10 größer als 2 ^ 31 ist, und zweitens, weil es eine Weile dauern wird, bis das Hoch erhöht wird.
Primo
1
Warum sollten Sie jemals eine Variable "ändern" wollen? Ihr imperativen Jungs habt seltsame Denkweisen ...
hört auf, gegen den Uhrzeigersinn am
4
Ich melde mich, um diese Frage zu schließen. Zu radikale Änderungen an der Frage. Sie sollten diese Frage tatsächlich über Sandbox validieren lassen, da Sie sonst den Aufwand für die Beantwortung von Fragen zunichte machen.
Abhijit
3
Das Verringern der Anzahl der erforderlichen Stellen ist ohne Zeit- / Speicherbegrenzung bedeutungslos. Mein Code kann 5 Ziffern verarbeiten, aber mein Computer verfügt nicht über genügend RAM.
Dennis

Antworten:

13

Python 66

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

Ausgabe

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

Diese Lösung verwendet Spiral of Theodorus in einer komplexen Ebene, um das Ergebnis zu erzielen.

Abhijit
quelle
2
Ich denke, das muss eingewickelt werden int(...*1e10), sonst sehr schön. Die Einnahme abseines komplexen Wertes ist jedoch mehr oder weniger sqrtverdeckt.
Primo
1
@primo Ich glaube nicht, dass du das darfst *1e10...
Cruncher
@primo: Anstatt mit 1e10 zu multiplizieren, habe ich einen etwas anderen Weg eingeschlagen. Und obwohl ich damit einverstanden bin, dass Bauchmuskeln in Verkleidung sind, fühle ich mich dennoch völlig legal, wie derzeit im Problem angegeben.
Abhijit
Ich sehe eine Ablehnung und es ist ziemlich deprimierend. Ich hatte große Hoffnung auf diese Antwort, also hinterlasse bitte einen Kommentar, wenn jemand einen Downvot durchgeführt hat.
Abhijit
9
@iggyvolz: Ich bin wirklich überrascht, dass Sie Ihre Frage ständig erweitern und weitere Einschränkungen hinzufügen. Die Leute investieren Zeit und Mühe, um eine Antwort zu schreiben, und Sie können nicht erwarten, dass sie psychisch sind.
Abhijit
6

Python, 184 Zeichen

Die folgende Python-Lösung verwendet nur den Inkrement-Operator und überhaupt keine anderen arithmetischen Operatoren. Mit der erforderlichen Genauigkeit (10 Stellen) dauert die Ausführung jedoch unglaublich lange. Sie können es mit geringerer Präzision testen (3 Stellen) durch Reduktion 1e20zu 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)
Greg Hewgill
quelle
Ich habe die Frage geklärt, Sie können so viele Ziffern eingeben, wie Sie möchten (mindestens 5). Ich kenne mich mit Python nicht aus, gehe aber davon aus, dass int () nur ein Typ-Caster ist. Wenn ja, ist das in Ordnung, weil es den Wert der Zahl nicht ändert.
Iggyvolz
@iggyvolz: Richtig, das benötigen Sie, um den in der Befehlszeile angegebenen Stringargumentwert in eine Ganzzahl umzuwandeln. Eine einfache Funktion würde das nicht brauchen.
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

Es kann einige Zeit dauern, bis eine Antwort für bestimmte Werte gefunden wurde, aber es wird auf jeden Fall funktionieren. Während ich *und benutze -, ändern diese keine Werte , nur die s=s+1tatsächlich etwas.

Kyle Kanos
quelle
Wow, ich glaube, ich habe nicht daran gedacht, Operatoren zum Ändern statischer Werte zu verwenden. Das ist vollkommen in Ordnung und +1 (wenn ich 15 Reputation hätte, um zu stimmen)
iggyvolz
Hierfür wird der *Operator verwendet, der eindeutig nicht zulässig ist. Oder verstehe ich die gegebenen Einschränkungen irgendwie falsch?
Greg Hewgill
@GregHewgill: OP-Zustände, ohne mathematische Operatoren zum Ändern der Zahl zu verwenden ; Diese Operatoren ändern keine Werte.
Kyle Kanos
7
Dabei wird der *Operator immer noch zum Ändern einer Zahl verwendet. Sie speichern das Ergebnis nur nirgendwo. Wenn das OP Zuweisungen (mit Ausnahme von) einfach nicht zulassen wollte s=s+1, warum dann alle nicht zulässigen arithmetischen Operatoren erwähnen?
Greg Hewgill
1
@iggyvolz: Ändern der Regeln ~ 20 Stunden später ist eine schlechte Form. Bitte mach das nicht und benutze den Sandkasten Sie stattdessen , um die Knicke in Ihrem Problem herauszufinden.
Kyle Kanos
2

CJam, 26 Bytes

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

Probieren Sie es online aus. Fügen Sie den Code ein , geben Sie die gewünschte Ganzzahl in die Eingabe ein und klicken Sie auf Ausführen . Bevor Sie das tun, empfehlen ändere ich 1e10zu 1e4though.

Der Java-Interpreter verarbeitet die 1e6Eingabe "2" in ca. 15 Sekunden. 1e20wird eine große Menge an RAM benötigen .

Beispiele

$ 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

Hintergrund

Da es mathematischen Operatoren nicht erlaubt ist, Zahlen zu ändern, werden wir Setwise-Operatoren verwenden, um Arrays zu ändern.

Der Code beginnt mit der "Multiplikation" der Eingabe ("i") mit 1e20, jedoch ohne tatsächliche Multiplikation. Stattdessen pushen wir ein Array mit “i” ganzen Zahlen, ein Array mit 1e20 ganzen Zahlen, nehmen ihr kartesisches Produkt und berechnen dessen Länge.

Dann drücken wir Null und inkrementieren, bis das Produkt der ganzen Zahl für sich (wie oben berechnet) nicht mehr kleiner als ist i * 1e20. Dadurch wird die Quadratwurzel aufgerundet.

Wie es funktioniert

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. ";
Dennis
quelle
1

Cobra - 62

Gepostet vor der dritten Bearbeitung, nicht mehr gültig.

Es ist nicht nur kurz, es sollte auch überlauffrei sein, wenn n < Decimal.maxValue

def f(n)
    r,e=0d,10000000000
    while r/e*r/e<n,r+=1
    print r
Οurous
quelle
Aber Sie haben verwendet r/e*r/e, was eindeutig ein nicht ++mathematischer Operator ist ...
nneonneo
@nneonneo dies wurde vor der dritten Bearbeitung gepostet, und ich habe es noch nicht geändert
Ο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)

Ist nicht in angemessener Zeit fertig, auch nicht für 2 als Eingabe, aber es funktioniert. Sie werden vielleicht bemerken, dass ich es tue _+_, aber das fügt immer nur 1 hinzu und Scala hat ++sowieso keinen Operator. Ich könnte zwei Zeichen speichern, indem ich den inneren Stream durch List ersetze, aber dann würde der Speicher knapp. Wie geschrieben, denke ich, skaliert es nur in der Verarbeitungszeit, nicht in der Speichernutzung.

Joe K
quelle
0

Haskell, 70 Bytes

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

fGibt die ganzzahlige Quadratwurzel an, indem die größte Zahl ermittelt wird, deren Quadrat kleiner oder gleich der Eingabe ist. Die Quadrierungsfunktion s ierhöht sich für jedes Element einer (i,i)Matrix um eins . (Am Telefon getippt, könnte also Tippfehler enthalten).

Michael Klein
quelle
0

PHP, 124 Bytes

Es ist ein vollständiger Algorithmus. Es werden nur Zahlen ausprobiert, bis das Quadrat dieser Zahl größer ist als die "Ziel" -Zahl (das sind die Eingabezeiten 1E im number of decimalsQuadrat (10.000 für ein Ergebnis mit zwei Dezimalstellen). Anschließend wird die letzte Zahl gedruckt.

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;

Laufen Sie wie folgt ( -dnur aus ästhetischen Gründen hinzugefügt):

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

Versuchen Sie dies nicht mit mehr als 3 Dezimalstellen oder einer Zahl über 10.

aross
quelle