Karekökünü yalnızca ++ kullanarak hesaplayın


13

Göreviniz, sayıyı değiştirmek için herhangi bir matematiksel işleç kullanmadan pozitif bir tamsayının karekökünü hesaplamaktır:

  • Bir değişken ayarlama (örn. SquareRoot = 5)
  • İlave (A + B)
  • Çıkarma (AB)
  • Çarpma (A * B)
  • Bölüm (A / B)
  • Kare, küp, dördüncü vb. Kökler
  • Üslü

Karşılaştırma işleçleri (<,>, ==, vb.) Bu sorunun amaçları için "matematik işleçleri" olarak kabul edilmez ve bir değişkenin değerini değiştirmedikleri sürece bunlara izin verilir.

Kullanabileceğiniz tek operatör ++. Aşağıdaki istisnalar mevcuttur:

  • İsterseniz, bir değişkeni 0 olarak ayarlayarak başlatabilirsiniz.
  • Diliniz ++ sözdizimini içermiyorsa, foo + = 1 veya foo = foo + 1 gibi eşdeğer bir sözdizimi kullanabilirsiniz.
  • Karekök ondalık basamaktan en az 6 basamağa (yüz binlerce yer) kadar hesaplanmalı ve tam ondalık sayı olarak çıkarılmalıdır (örn. 2 girersem yuvarlamaya bağlı olarak 14142135624 veya 1414213 olarak ortaya çıkabilir) . Yukarı veya aşağı yuvarlama önemli değildir.

Kullanıcı tanımlı işlevlere izin verilmez. Ayrıca, goto ile simüle fonksiyonlarına da izin verilmez.

Herkesin ne gönderdiğini görmek istiyorum! Mutlu kodlama!

AÇIKLAMA

Bu sayının pozitif bir tam sayı olduğunu netleştirin. Herhangi bir sayı yapacak bir kod yapabilirsiniz, ancak gerekli değildir.

AÇIKLAMA # 2

Karşılaştırma işleçlerine izin verildiğini netleştirin.

AÇIKLAMA # 3

Toplama, çıkarma, çarpma, değişim numaralarına bölünme ve işlevleri izin verilmez hiç bakmaksızın bir değişken ya da değil kaydedilir bakılmaksızın,. Üzgünüm, bu birkaç mevcut cevabı geçersiz kılıyor, ancak trol cevaplarını önlemek için bu operatör grubunu "sayıyı değiştir" ile tanımlamak istedim (örneğin, sadece sqrt () işlevini kullandım, yalnızca eklemeyi yasakladınız, çarpma, bölme ve çıkarma). Karışıklık için özür dilerim.

AÇIKLAMA # 4

En az 5 rakama ihtiyacımız olduğunu netleştirin. 10 hane kodun uzun süre çalışmasına neden oldu.


1
Hayır, - izin verilmiyor, karışıklık için özür dilerim! Başlangıçta ++ olmasını planladım ve - ama son dakikada dışarı çıkmaya karar verdim.
iggyvolz

5
"herhangi bir matematiksel işleç kullanmadan sayıyı değiştirmek için" - Bunun açıklığa ihtiyacı olabilir düşünüyorum. Bu operatörler kullanılamaz anlamına mı hiç , ya onlar kullanılabileceğini, ancak yalnızca sonuç, örneğin bir değişkene kaydedilmez while r*r<n*10e20:r+=1oldukça önemsiz -. Ayrıca, gerekli çıkışı 10 ^ 8 veya daha düşük bir değere düşürmeyi düşünebilirsiniz. Birincisi, 10 ^ 10, 2 ^ 31'den daha büyük ve ikincisi, çünkü bu yüksekliği artırmak biraz zaman alacaktır.
primo

1
Neden olur hiç "değişim" hiç bir değişkenin ister misin? Sen şart adamlar düşünce garip yolları var ...
dönüş durdurdu counterclockwis

4
Bu soruyu kapatmak için işaretliyorum. Soruda çok radikal değişikliklere. Bu soruyu Sandbox aracılığıyla doğrulamanız gerekir, aksi takdirde cevaplamak için çaba harcayan insanları hayal kırıklığına uğratırsınız.
Abhijit

3
Gerekli basamak sayısını azaltmak zaman / bellek sınırlaması olmadan anlamsızdır. Kodum 5 basamaklı işleyebilir, ancak makinemde yeterli RAM yok.
Dennis

Yanıtlar:


13

Python 66

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

Çıktı

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

Bu çözüm , sonuca ulaşmak için Spiral of Theodorus'u karmaşık bir düzlemde kullanır.


2
Bunun sarılı olması gerektiğini düşünüyorum int(...*1e10), aksi takdirde çok güzel. Rağmen, abskarmaşık bir değer almak aşağı yukarı sqrtkılık değiştirmiş.
primo

1
@primo Ben izin verildi sanmıyorum *1e10...
Cruncher

@primo: 1e10 ile çarpmak yerine biraz farklı bir rota izledim. Ve abs'in kılık değiştirmiş olabileceğini kabul etsem de, şu anda problemde belirtildiği gibi tamamen yasal olduğunu hissediyorum.
Abhijit

Bir aşağılık görüyorum ve oldukça iç karartıcı. Bu cevap için büyük bir umudum vardı, bu yüzden aşağı düşen herhangi biri, lütfen bir yorum bırakın.
Abhijit

9
@iggyvolz: Sorunuzu genişletmeye ve daha fazla kısıtlama eklemeye devam etmenize gerçekten şaşırdım. İnsanlar bir cevap yazmak için zaman ve çaba harcıyorlar ve sizlerin psikolojik olmasını beklemiyorsunuz.
Abhijit

6

Python, 184 karakter

Aşağıdaki Python çözümü yalnızca arttırma işlecini kullanır ve başka hiçbir aritmetik işleç kullanmaz. Ancak, gerekli hassasiyetle (10 basamaklı), çalışması imkansız uzun zaman alır. Bu azaltarak daha az hassas (3 basamak) ile test edilebilir 1e20için 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)

Soruyu açıklığa kavuştum, istediğiniz kadar basamağa yapabilirsiniz (en az 5). Ben piton aşina değilim, ama int () sadece bir tip tekeri olduğunu varsayalım? Eğer öyleyse, bu iyidir çünkü sayının değerini değiştirmez.
iggyvolz

@iggyvolz: Doğru, dize bağımsız değişken değerini (komut satırında belirtilen) bir tam sayıya dönüştürmeniz gerekir. Basit bir fonksiyon buna ihtiyaç duymaz.
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

Belirli değerler için bir cevap belirlemek için bir loooong alabilir, ancak kesin olarak işe yarayacaktır. Ben *ve kullanırken -, bunlar herhangi bir değeri değiştirmez , sadece s=s+1aslında bir şey değiştirir.


Vay canına, sanırım statik değerleri değiştirmek için operatörleri kullanmayı düşünmedim. Bu mükemmel para cezası ve +1 (oy vermek için 15 şöhretim olsaydı)
iggyvolz

Bu, *açıkça izin verilmeyen operatörü kullanır . Yoksa verilen kısıtlamaları bir şekilde yanlış mı anlıyorum?
Greg Hewgill

@GregHewgill: OP , sayıyı değiştirmek için herhangi bir matematiksel işleç kullanmadan belirtir ; bu operatörler herhangi bir değer değiştirmez.
Kyle Kanos

7
Ama bu hala *bir sayıyı değiştirmek için operatörü kullanıyor , sonucu hiçbir yere kaydetmiyorsunuz. OP basitçe izin vermeme istiyorsa atamaları (dışındaki s=s+1), sonra neden tüm izin verilmeyen aritmetik operatörleri söz?
Greg Hewgill

1
@iggyvolz: Kuralların 20 saat sonra değiştirilmesi kötü bir formdur. Lütfen bunu yapmayın ve bunun yerine probleminizdeki karışıklıkları çözmek için korumalı alanı kullanın.
Kyle Kanos

2

CJam, 26 bayt

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

Çevrimiçi deneyin. Yapıştır Kod , istenen tamsayı yazın Giriş ve tıklayın Çalıştır . Bunu yapmadan önce, ben değiştirmenizi öneriyoruz 1e10için 1e4olsa.

Java yorumlayıcısı kolları 1e6yaklaşık 15 saniye içinde girdi “2” ile. büyük miktarda RAM 1e20gerektirecektir .

Örnekler

$ 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

Arka fon

Matematiksel işleçlerin sayıları değiştirmesine izin verilmediğimizden, dizileri değiştirmek için düzgün işleçler kullanacağız.

Kod, girişi (“i”) 1e20 ile "çarparak", ancak gerçek bir çarpma olmadan başlar. Bunun yerine, “i” tamsayıları içeren bir dizi, 1e20 tamsayıları içeren bir dizi itiyoruz, kartezyen ürünlerini alıyor ve uzunluğunu hesaplıyoruz.

Ardından, tamsayının tek başına (yukarıda hesaplandığı gibi) ürünü artık daha küçük olmayana kadar sıfırı iter ve arttırırız i * 1e20. Bu karekökün yuvarlanmasına neden olur.

Nasıl çalışır

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

Kobra - 62

Üçüncü düzenlemeden önce yayınlandı, artık geçerli değil.

Sadece kısa değil, aynı zamanda taşma olmamalıdır n < Decimal.maxValue

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

Ama kullandınız r/e*r/e, ki bu açıkça ++matematik olmayan bir operatör ...
nneonneo

@nneonneo Bu, üçüncü düzenlemeden önce gönderildi ve henüz değiştirmedim
Ο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)

Giriş olarak 2 için bile makul bir sürede bitmez, ancak çalışır. Yaptığımı fark edebilirsiniz _+_, ancak bu sadece 1 ekler ve Scala'nın bir ++operatörü yoktur. İç Akışı List ile değiştirerek iki karakter kaydedebilirim, ancak daha sonra bellek tükenir. Yazıldığı gibi, sadece bellek kullanımında değil, yalnızca işlem süresinde ölçeklendiğini düşünüyorum.


0

Haskell, 70 bayt

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

fkaresi girdiye eşit veya daha küçük olan en büyük sayıyı bularak tam sayı karekökü verir. Kareleme işlevi s i, bir (i,i)matrisin her elemanı için bir artar . (Telefonda yazıldığından yazım hataları olabilir).


0

PHP, 124 bayt

Kapsamlı bir algoritma. Sadece bu sayının karesi "hedef" sayıdan daha büyük olana kadar sayıları dener number of decimals.

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;

Böyle çalıştırın ( -dsadece estetik nedenlerle eklendi):

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

Bunu 3 ondalık basamaktan veya 10'dan büyük bir sayıyla denemenizi önermeyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.