Обчисліть квадратний корінь, лише використовуючи ++


13

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

  • Встановлення змінної (напр. SquareRoot = 5)
  • Додавання (A + B)
  • Віднімання (AB)
  • Множення (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
Чому ви взагалі хочете взагалі "змінити" будь-яку змінну? Ви, імперативні хлопці, володієте дивними способами мислення ...
перестали повертати контр годинник

4
Я прагну закрити це питання. На багато радикальних змін у питанні. Насправді вам слід перевірити це питання через Sandbox, інакше ви змусите людей вкладати зусилля для відповіді.
Абхіджіт

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

Відповіді:


13

Пітон 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 може бути замаскованим, але я вважаю його цілком законним, як зараз зазначено в проблемі.
Абхіджіт

Я бачу знищення, і це досить гнітюче. Я покладав велику надію на цю відповідь, тому будь-хто, хто виступає проти, залиште коментар.
Abhijit

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

6

Пітон, 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)

Безголівки:

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

Ви можете взяти loooong, щоб фактично визначити відповідь на певні значення, але це буде працювати точно. Хоча я *і використовую -, це не змінює жодних значень , лише 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

Спробуйте в Інтернеті. Вставте код , введіть потрібне ціле число в Input і натисніть кнопку « Виконати» . Перед тим, як робити, я пропоную зміна 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 це було розміщено до третього редагування, і я його ще не змінив
Οurous

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 байти

Це вичерпний алгоритм. Він просто пробує числа до тих пір, поки квадрат цього числа не буде більшим за число "цілі" (це вхідний час 1E у 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

Не рекомендуйте пробувати це з чим-небудь десятковою цифрою чи цифрою, що перевищує 10.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.