Calculez la racine carrée uniquement à l'aide de ++

13

Votre tâche consiste à calculer la racine carrée d'un entier positif sans utiliser d'opérateurs mathématiques pour modifier le nombre, tels que:

  • Définition d'une variable (ex. SquareRoot = 5)
  • Addition (A + B)
  • Soustraction (AB)
  • Multiplication (A * B)
  • Division (A / B)
  • Racines carrées, cubiques, quatrièmes, etc.
  • Exposants

Les opérateurs de comparaison (tels que <,>, ==, etc.) ne sont pas considérés comme des "opérateurs mathématiques" aux fins de cette question et sont autorisés tant qu'ils ne modifient pas la valeur d'une variable.

Le seul opérateur que vous pouvez utiliser est ++. Les exceptions suivantes sont en place:

  • Si vous le souhaitez, vous pouvez initialiser une variable en la mettant à 0.
  • Si votre langue n'inclut pas la syntaxe ++, vous pouvez utiliser une syntaxe équivalente, telle que foo + = 1 ou foo = foo + 1
  • La racine carrée doit être calculée à au moins 6 chiffres au-delà de la décimale (la centaine de milliers) et sortie comme un nombre entier de décimales (par exemple, si j'entre 2, elle pourrait apparaître comme 14142135624 ou 1414213 selon l'arrondi) . Arrondir vers le haut ou vers le bas n'est pas important.

Les fonctions définies par l'utilisateur ne sont pas autorisées. De plus, la simulation de fonctions avec goto n'est pas autorisée non plus.

Je suis intéressé de voir ce que tout le monde soumet! Bon codage!

CLARIFICATION

Précisez que ce nombre est un entier positif. Vous êtes invités à créer un code qui ferait n'importe quel nombre mais ce n'est pas nécessaire.

CLARIFICATION # 2

Précisez que les opérateurs de comparaison sont autorisés.

CLARIFICATION # 3

L'addition, la soustraction, la multiplication, la division et les fonctions de modification des nombres ne sont pas autorisées du tout , qu'elles soient enregistrées ou non dans une variable. Je suis désolé que cela invalide quelques réponses existantes, mais je voulais définir ce groupe d'opérateurs avec "changer le nombre" afin d'empêcher les réponses de troll (par exemple, je viens d'utiliser la fonction sqrt (), vous avez seulement interdit l'ajout, multiplication, division et soustraction). Désolé pour la confusion.

CLARIFICATION # 4

Précisez que nous avons besoin d'au moins 5 chiffres. 10 chiffres ont fait fonctionner le code pendant une longue période.

iggyvolz
la source
1
Non, - n'est pas autorisé, désolé pour la confusion! J'avais initialement prévu d'avoir ++ et - mais j'ai décidé de retirer à la dernière minute.
iggyvolz
5
"sans utiliser d'opérateurs mathématiques pour changer le nombre" - je pense que cela pourrait nécessiter des éclaircissements. Voulez-vous dire que ces opérateurs ne peuvent pas être utilisés du tout , ou, qu'ils peuvent être utilisés, mais uniquement si le résultat n'est pas enregistré dans une variable, par exemple while r*r<n*10e20:r+=1- assez trivial. Vous pouvez également envisager de réduire la sortie requise à 10 ^ 8 environ. Premièrement, parce que 10 ^ 10 est plus grand que 2 ^ 31, et deuxièmement, parce qu'il faudra un certain temps pour augmenter ce niveau.
primo
1
Pourquoi voudriez-vous jamais "changer" une variable? Vous les gars impératifs avez d'étranges façons de penser ...
cessé de tourner dans le sens inverse des aiguilles d'une montre
4
Je signale pour fermer cette question. Trop de changements radicaux à la question. Vous devriez réellement faire valider cette question via Sandbox, sinon vous frustreriez les gens qui investissent des efforts pour y répondre.
Abhijit
3
Réduire le nombre de chiffres requis n'a pas de sens sans limites de temps / mémoire. Mon code peut gérer 5 chiffres, mais ma machine n'a pas assez de RAM.
Dennis

Réponses:

13

Python 66

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

Production

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

Cette solution utilise Spiral of Theodorus sur un plan complexe pour obtenir le résultat.

Abhijit
la source
2
Je pense que cela devra être enveloppé int(...*1e10), sinon très agréable. Cependant, la prise absd'une valeur complexe est plus ou moins sqrtdéguisée.
primo
1
@primo Je ne pense pas que vous soyez autorisé à *1e10...
Cruncher
@primo: Au lieu de multiplier par 1e10, j'ai pris un chemin un peu différent. Et bien que je convienne que les abdos peuvent être déguisés, je pense pourtant que c'est complètement légal comme indiqué actuellement dans le problème.
Abhijit
Je vois un downvote, et c'est assez déprimant. J'avais beaucoup d'espoir pour cette réponse, donc toute personne qui a voté en bas, veuillez laisser un commentaire.
Abhijit
9
@iggyvolz: Je suis vraiment surpris que vous continuiez à développer votre question et à ajouter plus de restrictions. Les gens investissent du temps et des efforts pour rédiger une réponse et vous ne pouvez pas vous attendre à ce qu'ils soient psychiques.
Abhijit
6

Python, 184 caractères

La solution Python suivante utilise uniquement l'opérateur d'incrémentation et aucun autre opérateur arithmétique. Cependant, avec la précision requise (10 chiffres), l'exécution prend un temps incroyablement long. Vous pouvez le tester avec une précision inférieure (3 chiffres) en réduisant 1e20à 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)

Non golfé:

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
la source
J'ai clarifié la question, vous pouvez le faire avec autant de chiffres que vous le souhaitez (au moins 5). Je ne suis pas familier avec python, mais je suppose que int () n'est qu'un caster de type? Si c'est le cas, c'est très bien car cela ne change pas la valeur du nombre.
iggyvolz
@iggyvolz: Oui, vous en avez besoin pour convertir la valeur de l'argument chaîne (spécifiée sur la ligne de commande) en entier. Une fonction simple n'en aurait pas besoin.
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

Cela pourrait prendre beaucoup de temps pour déterminer une réponse pour certaines valeurs, mais cela fonctionnera à coup sûr. Bien que j'utilise *et -, cela ne change aucune valeur , seul le s=s+1change réellement quoi que ce soit.

Kyle Kanos
la source
Wow, je suppose que je n'ai pas pensé à utiliser des opérateurs pour changer les valeurs statiques. C'est parfaitement bien et +1 (si j'avais 15 points de réputation à voter)
iggyvolz
Cela utilise l' *opérateur, ce qui n'est clairement pas autorisé. Ou est-ce que je comprends mal les restrictions données?
Greg Hewgill
@GregHewgill: états OP, sans utiliser d'opérateurs mathématiques pour changer le nombre ; ces opérateurs ne modifient aucune valeur.
Kyle Kanos
7
Mais cela utilise toujours l' *opérateur pour changer un nombre, vous n'enregistrez simplement le résultat nulle part. Si l'OP voulait simplement interdire les affectations (autres que s=s+1), alors pourquoi mentionner tous les opérateurs arithmétiques interdits?
Greg Hewgill
1
@iggyvolz: Changer les règles ~ 20 heures plus tard est une mauvaise forme. Veuillez ne pas faire cela et utiliser le bac à sable pour résoudre les problèmes de votre problème à la place.
Kyle Kanos
2

CJam, 26 octets

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

Essayez-le en ligne. Collez le code , saisissez l'entier souhaité dans Entrée et cliquez sur Exécuter . Avant de le faire, je suggère de passer 1e10à 1e4bien.

L' interpréteur Java gère l' 1e6entrée «2» en 15 secondes environ. 1e20nécessitera une énorme quantité de RAM.

Exemples

$ 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

Contexte

Comme nous ne sommes pas autorisés à changer d'opérateur mathématique, nous allons utiliser des opérateurs setwise pour changer les tableaux.

Le code commence par "multiplier" l'entrée ("i") par 1e20, mais sans multiplication réelle. Au lieu de cela, nous poussons un tableau contenant des entiers «i», un tableau contenant 1e20 entiers, prenons leur produit cartésien et calculons sa longueur.

Ensuite, nous poussons zéro et incrémentons jusqu'à ce que le produit de l'entier lui-même (calculé comme ci-dessus) ne soit plus inférieur à i * 1e20. Cela provoque l'arrondi de la racine carrée.

Comment ça fonctionne

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
la source
1

Cobra - 62

Publié avant la troisième édition, n'est plus valide.

Non seulement il est court, mais il doit être sans débordement si n < Decimal.maxValue

def f(n)
    r,e=0d,10000000000
    while r/e*r/e<n,r+=1
    print r
Οurous
la source
Mais vous avez utilisé r/e*r/e, qui est clairement un ++opérateur non mathématique ...
nneonneo
@nneonneo, cela a été publié avant le troisième montage, et je ne l'ai pas encore changé
Ο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)

Ne se termine pas dans un délai raisonnable, même pour 2 en entrée, mais cela fonctionne. Vous remarquerez peut-être que je fais _+_, mais cela n'ajoute que 1, et Scala n'a pas d' ++opérateur de toute façon. Je pouvais enregistrer deux caractères en remplaçant le flux interne par List, mais cela manquerait de mémoire. Tel qu'il est écrit, je pense que cela ne prend en compte que le temps de traitement et non l'utilisation de la mémoire.

Joe K
la source
0

Haskell, 70 octets

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

fdonne la racine carrée entière en trouvant le plus grand nombre dont le carré est inférieur ou égal à l'entrée. La fonction de quadrature s iaugmente de un pour chaque élément d'une (i,i)matrice. (Tapé sur le téléphone, il pourrait donc y avoir des fautes de frappe).

Michael Klein
la source
0

PHP, 124 octets

C'est un algorithme exhaustif. Il essaie simplement les nombres jusqu'à ce que le carré de ce nombre soit plus grand que le nombre "objectif" (qui est le temps d'entrée 1E au number of decimalscarré (10 000 pour un résultat 2 décimal). Ensuite, il imprime ce dernier nombre.

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;

Exécutez comme ceci ( -dajouté pour des raisons esthétiques uniquement):

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

Je ne recommande pas d'essayer cela avec plus de 3 décimales ou un nombre supérieur à 10.

aross
la source