Рассчитать квадратный корень только с помощью ++


13

Ваша задача - вычислить квадратный корень из натурального числа без использования математических операторов для изменения числа, например:

  • Установка переменной (например, squareRoot = 5)
  • Дополнение (A + B)
  • Вычитание (АБ)
  • Умножение (A * B)
  • Отдел (A / B)
  • Квадрат, куб, четвертый и т. Д. Корни
  • Экспоненты

Операторы сравнения (такие как <,>, == и т. Д.) Не считаются «математическими операторами» для целей этого вопроса и допускаются, если они не изменяют значение переменной.

Единственный оператор, который вы можете использовать - это ++. Имеются следующие исключения:

  • При желании вы можете инициализировать переменную, установив ее в 0.
  • Если ваш язык не включает синтаксис ++, вы можете использовать эквивалентный синтаксис, такой как foo + = 1 или foo = foo + 1
  • Квадратный корень должен быть рассчитан по крайней мере на 6 цифр после десятичной точки (место в сто тысяч) и выведен как целое число десятичных дробей (например, если я введу 2, оно может выйти как 14142135624 или 1414213 в зависимости от округления) , Округление вверх или вниз не важно.

Пользовательские функции не допускаются. Кроме того, моделирование функций с помощью goto также не допускается.

Мне интересно посмотреть, что все представляют! Удачного кодирования!

ПОЯСНЕНИЯ

Уточните, что число является положительным целым числом. Вы можете сделать код, который будет делать любое число, но это не обязательно.

РАЗЪЯСНЕНИЕ № 2

Уточнить, что операторы сравнения разрешены.

РАЗЪЯСНЕНИЕ № 3

Сложение, вычитание, умножение, деление и функции на номера изменения не допускаются на всех , независимо от того, являются ли они сохраняются в переменной или нет. Я сожалею, что это делает недействительными пару существующих ответов, но я хотел определить эту группу операторов с помощью «изменить число», чтобы предотвратить ответы троллей (например, я только использовал функцию sqrt (), вы только запретили добавление, умножение, деление и вычитание). Извините за путаницу.

РАЗЪЯСНЕНИЕ № 4

Уточните, что нам нужно как минимум 5 цифр. 10 цифр заставили код работать долго.


1
Нет, - не допускается, извините за путаницу! Первоначально я планировал иметь ++ и - но я решил взять на вынос в последнюю минуту.
iggyvolz

5
«без использования каких-либо математических операторов для изменения числа» - думаю, это может потребовать уточнения. Вы имеете в виду , что эти операторы не могут быть использованы на всех , или, что они могут быть использованы, но только если результат не сохраняется в переменной, например while r*r<n*10e20:r+=1- довольно тривиальна. Кроме того, вы можете рассмотреть вопрос о снижении требуемой производительности до 10 ^ 8 или около того. Во-первых, потому что 10 ^ 10 больше, чем 2 ^ 31, а во-вторых, потому что потребуется некоторое время, чтобы увеличить этот максимум.
Примо

1
Зачем вам вообще хотеть «изменить» любую переменную? Вы императивные ребята странные способы мышления ...
перестала очередь counterclockwis

4
Я отмечаю, чтобы закрыть этот вопрос. К радикальным изменениям вопроса. На самом деле вы должны подтвердить этот вопрос через «Песочницу», иначе вы бы разочаровали людей, вкладывающих усилия в ответ.
Абхиджит

3
Сокращение количества требуемых цифр не имеет смысла без ограничений по времени и памяти. Мой код может обрабатывать 5 цифр, но моей машине не хватает оперативной памяти.
Деннис

Ответы:


13

Python 66

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

Выход

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

Это решение использует Спираль Феодора на сложной плоскости для достижения результата.


2
Я думаю, что это нужно будет завернуть, в int(...*1e10)противном случае очень приятно. Хотя принятие absкомплексного значения более или менее sqrtзамаскировано.
Примо

1
@ primo Я не думаю, что тебе позволено *1e10...
Cruncher

@primo: вместо умножения на 1e10 я выбрал немного другой маршрут. И хотя я согласен с тем, что abs может быть замаскированным, все же я чувствую его полностью законным, как в настоящее время указано в проблеме.
Абхиджит

Я вижу понижающий голос, и это довольно удручает. У меня была большая надежда на этот ответ, поэтому любой, кто проголосовал, пожалуйста, оставьте свой комментарий.
Абхиджит

9
@iggyvolz: Я очень удивлен, что вы продолжаете расширять свой вопрос и добавляете больше ограничений. Люди тратят время и силы, чтобы написать ответ, и вы не можете ожидать, что они будут психами.
Абхиджит

6

Python, 184 символа

Следующее решение Python использует только оператор приращения и никаких других арифметических операторов вообще. Однако с требуемой точностью (10 цифр) запуск занимает невероятно много времени. Вы можете проверить это с меньшей точностью (3 цифры), уменьшив 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)

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)

Я уточнил вопрос, вы можете сделать это с любым количеством цифр, как вы хотите (по крайней мере 5). Я не знаком с Python, но я предполагаю, что int () это просто тип заклинателя? Если это так, это нормально, потому что это не меняет значение числа.
iggyvolz

@iggyvolz: Точно, вам нужно преобразовать значение строкового аргумента (указанное в командной строке) в целое число. Простая функция не нуждается в этом.
Грег Хьюгилл

2

Фортран 73

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

Можно было бы найти ответ, чтобы на самом деле определить ответ для определенных значений, но это сработает наверняка. Хотя я использую *и -, они не меняют никаких значений , только s=s+1фактически что-то меняет.


Вау, думаю, я не думал об использовании операторов для изменения статических значений. Это прекрасно и +1 (если бы у меня было 15 репутации, чтобы поднять голос)
iggyvolz

Это использует *оператор, который довольно явно не разрешен. Или я как-то неправильно понимаю данные ограничения?
Грег Хьюгилл

@GregHewgill: OP-состояния без использования математических операторов для изменения числа ; эти операторы не меняют никаких значений.
Кайл Канос

7
Но он все еще использует *оператор для изменения числа, вы просто нигде не сохраняете результат. Если ОП хотел просто запретить присваивания (кроме s=s+1), то зачем упоминать все запрещенные арифметические операторы?
Грег Хьюгилл

1
@iggyvolz: Изменение правил ~ 20 часов спустя - плохая форма. Пожалуйста, не делайте этого и используйте песочницу, чтобы решить проблемы в вашей проблеме.
Кайл Канос

2

CJam, 26 байтов

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

Попробуйте онлайн. Вставьте код , введите желаемое число в поле ввода и нажмите « Выполнить» . Прежде чем сделать, я предлагаю перейти 1e10на 1e4хотя.

В интерпретатор Java ручки 1e6с входом «2» примерно за 15 секунд. 1e20потребуется огромное количество оперативной памяти.

Примеры

$ 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

Фон

Так как математические операторы не могут изменять числа, мы будем использовать пошаговые операторы для изменения массивов.

Код начинается с «умножения» ввода («i») на 1e20, но без какого-либо фактического умножения. Вместо этого мы помещаем массив, содержащий целые числа «i», массив, содержащий 1e20 целых чисел, берем их декартово произведение и вычисляем его длину.

Затем мы нажимаем ноль и увеличиваем до тех пор, пока произведение целого числа на себя (рассчитанное, как указано выше) не станет меньше, чем i * 1e20. Это приводит к округлению квадратного корня.

Как это устроено

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

Кобра - 62

Опубликовано до третьего редактирования, больше не действует.

Он не только короткий, но и не должен быть переполнен, если n < Decimal.maxValue

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

Но вы использовали r/e*r/e, что явно не ++математический оператор ...
nneonneo

@nneonneo это было опубликовано до третьего редактирования, и я еще не изменил его
Junurous

0

Скала, 117

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

Не заканчивается в разумные сроки, даже для 2 в качестве ввода, но это работает. Вы можете заметить, что я делаю _+_, но это только добавляет 1, и у Scala все равно нет ++оператора. Я мог бы сохранить два символа, заменив внутренний поток списком, но тогда ему не хватило бы памяти. Как написано, я думаю, что это масштабируется только во время обработки, а не использования памяти.


0

Haskell, 70 байт

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

fдает целочисленный квадратный корень, находя наибольшее число, квадрат которого меньше или равен входному значению. Функция возведения в квадрат s iувеличивается на единицу для каждого элемента (i,i)матрицы. (Напечатано на телефоне, поэтому может иметь опечатки).


0

PHP, 124 байта

Это исчерпывающий алгоритм. Он просто пробует числа до тех пор, пока квадрат этого числа не станет больше, чем число «цели» (которое является входным умножением на 1Е в number of decimalsквадрате (10.000 для 2 десятичного результата). Затем он печатает это последнее число.

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;

Запустите так ( -dдобавлено только по эстетическим соображениям):

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

Не рекомендую пробовать это с чем-то больше, чем 3 десятичных знака или число выше 10.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.