จำนวนเต็มรากที่สองของจำนวนเต็ม [ปิด]


12

ปัญหา:

ในภาษาที่คุณเลือกให้เขียนฟังก์ชันที่สั้นที่สุดที่ส่งคืนพื้นของสแควร์รูทของจำนวนเต็ม 64 บิตที่ไม่ได้ลงนาม

กรณีทดสอบ:

ฟังก์ชั่นของคุณจะต้องทำงานอย่างถูกต้องสำหรับอินพุตทั้งหมด แต่นี่คือบางส่วนที่ช่วยอธิบายแนวคิด:

               INPUT ⟶ OUTPUT

                   0 ⟶  0
                   1 ⟶  1
                   2 ⟶  1
                   3 ⟶  1
                   4 ⟶  2
                   8 ⟶  2
                   9 ⟶  3
                  15 ⟶  3
                  16 ⟶  4
               65535 ⟶ 255
               65536 ⟶ 256
18446744073709551615 ⟶ 4294967295

กฎ:

  1. คุณสามารถตั้งชื่อฟังก์ชั่นของคุณได้ตามใจชอบ (ฟังก์ชั่นที่ไม่ระบุชื่อไม่ระบุชื่อหรือแลมบ์ดานั้นใช้ได้ตราบใดที่ยังเรียกได้)
  2. การนับจำนวนตัวละครเป็นสิ่งที่สำคัญที่สุดในการท้าทายนี้ แต่การใช้งานจริงก็มีความสำคัญเช่นกัน ฉันแน่ใจว่าคุณสามารถสแกนซ้ำ ๆ เพื่อหาคำตอบในเวลา O ()n) ด้วยจำนวนอักขระที่น้อยมาก แต่เวลา O (log (n)) จะดีกว่าจริง ๆ (นั่นคือสมมติว่าค่าอินพุตเป็น n ไม่ใช่ความยาวบิตของ n)
  3. คุณอาจต้องการที่จะใช้ฟังก์ชั่นการใช้จำนวนเต็มอย่างหมดจดและ / หรือแบบบูลเลขคณิต อย่างไรก็ตามหากคุณต้องการใช้การคำนวณเลขทศนิยมจริง ๆ แล้วก็ถือว่าใช้ได้ตราบใดที่คุณไม่เรียกใช้ฟังก์ชันไลบรารี ดังนั้นการบอกว่าreturn (n>0)?(uint32_t)sqrtl(n):-1;ใน C นั้นถูก จำกัด แม้ว่ามันจะให้ผลลัพธ์ที่ถูกต้องก็ตาม หากคุณกำลังใช้เลขคณิตจุดลอยตัวคุณอาจใช้*, /, +, -และการยกกำลัง (เช่น**หรือ^ถ้าเป็นในตัวผู้ประกอบการในภาษาของคุณเลือก แต่การยกกำลังเพียงอำนาจไม่น้อยกว่า 1 ) ข้อ จำกัด นี้เพื่อป้องกัน "การโกง" โดยการโทรsqrt()หรือตัวแปรหรือเพิ่มค่าให้กับพลังงาน½
  4. หากคุณกำลังใช้การดำเนินการจุดลอยตัว (ดู # 3) คุณไม่จำเป็นต้องให้ประเภทการคืนเป็นจำนวนเต็ม เฉพาะที่ค่าส่งคืนเป็นจำนวนเต็มเช่น floor (sqrt (n)) และสามารถเก็บค่า 32- บิตที่ไม่ได้ลงนามใด ๆ
  5. หากคุณกำลังใช้ C / C ++ คุณอาจถือว่าการดำรงอยู่ของไม่ได้ลงนาม 64 บิตและ 32 บิตจำนวนเต็มประเภทเช่นที่uint64_tและตามที่กำหนดในuint32_t stdint.hมิฉะนั้นตรวจสอบให้แน่ใจว่าประเภทจำนวนเต็มของคุณสามารถถือจำนวนเต็ม 64 บิตที่ไม่ได้ลงชื่อใด ๆ
  6. หากคำแนะนำของคุณไม่รองรับจำนวนเต็ม 64- บิต (ตัวอย่างเช่น Brainfuck มีเพียงจำนวนเต็ม 8 บิตเท่านั้น) ให้ทำตามนั้นและระบุข้อ จำกัด ในหัวข้อคำตอบของคุณ ที่กล่าวว่าหากคุณสามารถหาวิธีเข้ารหัสจำนวนเต็ม 64 บิตและรับสแควร์รูทอย่างถูกต้องโดยใช้เลขคณิตพื้นฐาน 8 บิตแล้วเพิ่มพลังให้คุณมากขึ้น!
  7. ขอให้สนุกและสร้างสรรค์!

7
"แต่เวลา O (log₄ (n)) จะดีกว่าจริงๆ" - ดีกว่ามากแค่ไหน? มีโบนัสหรือไม่? นั่นเป็นข้อกำหนดที่ยากไหม มันเป็นความท้าทายที่แยกจากกันหรือไม่? นั่นเป็นเพียงความคิดที่ดีที่ไม่ส่งผลกระทบต่อการให้คะแนนจริง ๆ หรือ
John Dvorak

3
โดยปกติจะใช้ขนาดของอินพุตมากกว่าค่าอินพุตเพื่อรับความซับซ้อนของอัลกอริทึม ในแง่นั้นอัลกอริธึมที่เพิ่มขึ้นและลองใหม่เป็นเลขชี้กำลังเป็นเลขชี้กำลังในความเร็ว
John Dvorak

3
อืมม O(log_2 n) === O(log_4 n)... log_4(n) = log_2(n) / log_2(2) = log_2(n) / 2
John Dvorak

1
2/4 นับหรือไม่
Milo

1
ชนิดข้อมูลจุดลอยตัวส่วนใหญ่ไม่จำเป็นต้องมีความแม่นยำสำหรับงานนี้ 53 บิตที่สำคัญไม่เพียงพอสำหรับช่วงอินพุตทั้งหมด
user2357112 รองรับ Monica

คำตอบ:


14

CJam, 17 (หรือ 10) ไบต์

{_1.5#\/i}

ลองใช้งานออนไลน์โดยตรวจสอบกรณีทดสอบ:

[0 1 2 3 4 8 9 15 16 65535 65536 18446744073709551615]{_1.5#\/i}%N*

มันจะไม่ผ่านการทดสอบกรณีที่ผ่านมาเนื่องจากการปัดเศษปัญหา แต่เนื่องจาก18446744073709551615ไม่ได้เป็นจำนวนเต็มใน CJam (เป็นบิ๊กจำนวนเต็ม ) เรายังคงดีใช่มั้ย?

หากไม่ได้รหัสต่อไปนี้ (และอีกต่อไปเล็กน้อย) จะแก้ไขข้อผิดพลาดเหล่านั้น:

{__1.5#\/i_2#@>-}

ไม่ใช่ทางออกที่สั้นที่สุดอีกต่อไป แต่น่าสนใจ

มันทำงานอย่างไร

__    " Duplicate the integer twice. ";
1.5#  " Raise to power 1.5. Note that, since 1.5 > 1, this doesn't break the rules. ";
\     " Swap the result with the original integer. ";
/     " Divide. ";
i     " Cast to integer. ";
_2#   " Push square of a copy. ";
@     " Rotate the orginal integer on top of the stack. ";
>-    " If the square root has been rounded up, subtract 1. ";

ฮ่าฮ่าฮ่า! อ๊ะโอเคคุณมาหาฉันได้ไหม ฉันควรจะบอกว่าไม่มีพลังเศษส่วน แต่รหัสของคุณเป็นไปตามกฎที่ระบุไว้แน่นอนดังนั้นฉัน upvoting มัน :)
ทอดด์เลห์แมน

2
CJam มีทศนิยมความแม่นยำโดยพลการหรือไม่เพื่อครอบคลุมช่วงอินพุตทั้งหมด?
isaacg

นอกจากนี้แฮ็คที่ดีในการใช้ NaN -> 0 เมื่อส่งไปยัง int
isaacg

ความคิดที่เรียบร้อยก็ยังสามารถแสดงใน J <.@%~^&1.5ในที่แน่นอนเดียวกันนับจำนวนตัวอักษร: ฉันสามารถโพสต์สิ่งนี้เป็นคำตอบที่แยกจากกันได้หรือไม่ (เนื่องจากเป็นพอร์ตของคุณแน่นอน)
Sepıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs: เอาเลย แต่ฉันเพิ่งพบว่าวิธีแก้ปัญหาของฉันอาจปัดอย่างไม่ถูกต้องสำหรับคนจำนวนมากรวมถึงกรณีทดสอบครั้งสุดท้าย ในการป้องกันของฉันก็ผ่านการตรวจสอบของฉันเพียงเพราะ4294967295และ4294967296ดูมากคล้ายกัน ...
เดนนิส

10

Haskell, 28 26

ฉันเชื่อว่านี่เป็นรายการสั้นที่สุดจากภาษาใด ๆ ที่ไม่ได้ออกแบบมาสำหรับการเล่นกอล์ฟ

s a=[x-1|x<-[0..],x*x>a]!!0

มันชื่อฟังก์ชั่นsที่มีพารามิเตอร์และผลตอบแทนที่หนึ่งลบหมายเลขแรกที่มีตารางมีค่ามากกว่าa aทำงานช้าอย่างไม่น่าเชื่อ (O (sqrt n) อาจจะ?)


1
ดัชนีรายการ ( [...]!!0) จะสั้นกว่าหัวหรือไม่
isaacg

@isaacg ใช่แล้ว ขอบคุณ :-)
Zaq

7

Golfscript, 17 ตัวอักษร

{).,{.*1$<},,\;(}

ฉันสามารถตั้งชื่อฟังก์ชั่นของฉันในแบบที่ฉันชอบได้ แต่ฉันตัดสินใจไม่ตั้งชื่อเลย เพิ่มตัวละครสองตัวเพื่อตั้งชื่อเพิ่มสามตัวเพื่อตั้งชื่อและไม่ทิ้งไว้บนสแต็กลบหนึ่งตัวอักษรหากมีโปรแกรมเต็มรูปแบบก็โอเค

สิ่งที่น่ารังเกียจนี้ไม่ได้ทำงานในเวลาลอการิทึมในค่าของอินพุตไม่ใช่ในเวลา O (sqrt n) มันต้องใช้เวลาจำนวนมากในการสร้างผลลัพธ์แบบเชิงเส้น นอกจากนี้ยังใช้พื้นที่มาก น่ากลัวอย่างแน่นอน แต่ ... นี่คือรหัสกอล์ฟ

อัลกอริทึมคือ:

n => [0..n].filter(x => x*x < n+1).length - 1

ฉันรักมัน!! เยี่ยมมาก! นั่นเป็นสิ่งที่ผิดปกติอย่างสวยงาม
ทอดด์เลห์แมน

7

Pyth , 14 ตัวอักษร

DsbR;fgb*TTL'b

จัดให้มีฟังก์ชั่นที่มีชื่อ, ซึ่งคำนวณรากที่สองโดยการกรองรายการจาก 0 ถึง n สำหรับสแควร์ที่มีขนาดใหญ่กว่าการป้อนข้อมูลจากนั้นพิมพ์หมายเลขดังกล่าวที่ผ่านมา ไม่ใช้การยกกำลังหรือการลอย

Dsb       def s(b):
R;        return last element of
f         filter(lambda T:
gb*TT                     b>=T*T,
L'b                       range(b+1))

ตัวอย่างการใช้งาน:

python3 pyth.py <<< "DsbR;fgb*TTL'b       \msd[0 1 2 3 4 8 9 15 16 65535 65536"
[0, 1, 1, 1, 2, 2, 3, 3, 4, 255, 256]

7

Retina (ไม่ใช่การแข่งขัน - ภาษานั้นใหม่กว่าความท้าทาย), 43

ในขณะที่ทำงานกับคำตอบนี้มันเกิดขึ้นกับฉันว่าวิธีที่คล้ายกันสามารถใช้ในการคำนวณรากที่สองจำนวนเต็มโดยใช้เรตินา:

.+
$*
^
1:
+`(1+):(11\1)
1 $2:
1+:$|:1+

1+

สิ่งนี้ขึ้นอยู่กับความจริงที่ว่าสี่เหลี่ยมที่สมบูรณ์แบบอาจแสดงเป็น1+3+5+7+...และโดยข้อพิสูจน์ว่าจำนวนคำในนิพจน์นี้คือรากที่สอง

ลองออนไลน์ (เพิ่มบรรทัดแรกเพื่ออนุญาตให้มีการทดสอบหลายชุด)

เห็นได้ชัดว่าเนื่องจากทศนิยมเป็น unary conversion สิ่งนี้จะใช้ได้กับอินพุตที่ค่อนข้างเล็กเท่านั้น


4
(ภาษาใหม่กว่าความท้าทาย)
mbomb007

@ mbomb007 ยุติธรรมเพียงพอ - แก้ไขหัวเรื่อง คำตอบนี้อยู่ในหมวดหมู่ "เพราะสามารถทำได้" และไม่ได้หมายถึงการแข่งขันในความท้าทายด้วยวิธีที่มีความหมายใด ๆ
บาดเจ็บทางระบบดิจิทัล

1
ฉันรู้ว่าสิ่งที่คุณหมายถึง
mbomb007

6

Perl, 133 อักขระ

ไม่ใช่ที่สั้นที่สุด แต่ใช้อัลกอริธึมแบบดิจิตัลเพื่อจัดการกับขนาดอินพุตใด ๆ และทำงานในเวลา O (log n) แปลงได้อย่างอิสระระหว่าง numbers-as-strings และ numbers-as-numbers เนื่องจากผลิตภัณฑ์ที่ใหญ่ที่สุดที่เป็นไปได้คือรูทจนถึงขณะนี้ที่มีจตุรัสของตัวเลขหลักเดียวจึงควรสามารถใช้สแควร์รูทของตัวเลขสูงสุด 120 บิตหรือมากกว่านั้นในระบบ 64 บิต

sub{($_)=@_;$_="0$_"if(length)%2;$a=$r="";while(/(..)/g){
$a.=$1;$y=$d=0;$a<($z=$_*(20*$r+$_))or$y=$z,$d=$_ for 1..9;$r.=$d;$a-=$y}$r}

คลายการบีบอัดนั่นคือ:

sub {
  my ($n) = @_;
  $n = "0$n" if length($n) % 2; # Make an even number of digits
  my ($carry, $root);
  while ($n =~ /(..)/g) { # Take digits of $n two at a time
    $carry .= $1;         # Add them to the carry
    my ($product, $digit) = (0, 0);
    # Find the largest next digit that won't overflow, using the formula
    # (10x+y)^2 = 100x^2 + 20xy + y^2 or
    # (10x+y)^2 = 100x^2 + y(20x + y)
    for my $trial_digit (1..9) {
      my $trial_product = $trial_digit * (20 * $root + $trial_digit);
      if ($trial_product <= $carry) {
        ($product, $digit) = ($trial_product, $trial_digit);
      } 
    } 
    $root .= $digit;
    $carry -= $product;
  } 
  return $root;
}

ดี! ฉันสงสัยว่าเมื่อมีคนจะโพสต์คำตอบ Perl BTW ทำงานเพื่อพูดif length%2แทนif(length)%2หรือไม่ นั่นจะกำจัดตัวละคร 1 ตัว นอกจากนี้มันจะทำงานเพื่อพูด$y=$z,$d=$_ ifแทน($y,$d)=($z,$_)ifหรือไม่ ฉันคิดว่ามันจะสามารถกำจัดตัวละครได้อีก 3 ตัว
ทอดด์เลห์แมน

และนี่กำลังจะผิดเพี้ยนไปนิดหน่อย แต่ฉันคิดว่าคุณสามารถกำจัดได้อีก 1 โดยการเขียนforลูปใหม่เป็น:$a<($z=$_*(20*$r+$_))or$y=$z,$d=$_ for(1..9);
Todd Lehman

ข้อเสนอแนะแรกไม่ทำงาน (พยายามใช้ความยาวของแฮชที่ตั้งชื่อ%2) แต่ข้อเสนออื่น ๆ นั้นใช้ได้ ฉันจะทำงานกับพวกเขาใน.
ฮอบส์

1
@ToddLehman postfix forไม่จำเป็นต้องใช้วงเล็บ การเพิ่มเข้าไปในคำแนะนำของคุณทำให้ฉันมีอักขระทั้งหมด 6 ตัว ขอบคุณ!
ฮอบส์

5

Matlab (56) / อ็อกเทฟ (55)

มันทำงานออกรากที่สองโดยใช้วิธีการจุดคงที่ มันมาบรรจบกันในขั้นสูงสุด 36 ขั้นตอน (สำหรับ 2 ^ 64-1 เป็นอาร์กิวเมนต์) แล้วตรวจสอบว่ามันเป็นหนึ่งในรากที่เป็นไปได้ 'ที่ต่ำกว่า' เนื่องจากใช้ 36 การวนซ้ำเสมอจึงมีรันไทม์ของ O (1) = P

อาร์กิวเมนต์จะถือว่าเป็น uint64

MATLAB:

function x=q(s)
x=1
for i = 1:36
    x = (x+s/x)/2
end
if x*x>s
    x=x-1
end

Octave:

function x=q(s)
x=1
for i = 1:36
    x = (x+s/x)/2
end
if x*x>s
    x-=1
end

นี่เป็นวิธีการใหม่สำหรับฉันและมันก็เจ๋งมาก +1
seequ

1
โดยทั่วไปแล้วจะเป็นen.wikipedia.org/wiki/…ซึ่งเป็นหนึ่งในวิธีการคำนวณที่เก่าแก่ที่สุดที่รู้จักกันซึ่งคาดว่ามีอายุประมาณ 3700 ปี มันสามารถเป็นธรรมโดยen.wikipedia.org/wiki/Banach_fixed-point_theoremซึ่งมีหลักฐานง่ายที่น่าแปลกใจก็ = ดีจริงๆ)
flawr

5

Ruby - 36 ตัวอักษร

s=->n{g=n;g=(g+n/g)/2 while g*g>n;g}

ทำได้ดีมาก! เวลาดำเนินการกรณีที่เลวร้ายที่สุดคืออะไร?
ทอดด์เลห์แมน

ในกรณีที่ g * g <n และคำตอบยังไม่ใกล้เคียงกับค่าที่ต้องการ? สคริปต์จะไม่หยุดหรือไม่
WallyWest

1
@ToddLehman ฉันไม่รู้จริงๆ : - / นี่คือวิธีการที่บาบิโลน นี่คือสิ่งที่ดูเหมือนจะเป็นหลักฐานที่ดีของความซับซ้อนเฉลี่ย การคาดเดาเริ่มต้นของตัวเลขนั้นค่อนข้างแย่ แต่ฉันต้องนั่งลงแล้วคลานไปหาข้อพิสูจน์เพื่อทำความเข้าใจกรณีที่เลวร้ายที่สุด จะให้มันไปเมื่อฉันมีเวลาว่าง :-)
OI

@WallyWest ความเข้าใจของฉันคือwhileลูปจะสิ้นสุดลงอย่างแม่นยำเมื่อ g ลู่เข้าหาพื้น (√n) ซึ่งเป็นค่าที่ต้องการ คุณเห็นกรณีที่สิ่งนี้จะไม่เป็นจริงหรือไม่?
OI

4

Python (39)

f=lambda n,k=0:k*k>n and k-1or f(n,k+1)

วิธีการเรียกซ้ำแบบธรรมชาติ นับจำนวนสแควร์รูทที่มีศักยภาพจนกระทั่งสี่เหลี่ยมจัตุรัสสูงเกินไปจากนั้นลดลง 1 ให้ใช้Stackless Pythonหากคุณกังวลเกี่ยวกับความลึกของสแต็ก

and/orสำนวนเทียบเท่ากับผู้ประกอบการที่ประกอบไปด้วยเป็น

f=lambda n,k=0:k-1 if k*k>n else f(n,k+1)

แก้ไข:ฉันแทนจะได้รับ25 ตัวอักษรโดยการใช้ประโยชน์จากกฎ "คุณอาจจะใช้*, /, +, -และการยกกำลัง (เช่น**หรือ^ถ้ามันยกกำลังในตัวผู้ประกอบการในภาษาของคุณเลือก แต่ของอำนาจไม่น้อยกว่า 1) " (แก้ไข: Dennisเห็นได้ชัดว่าพบและใช้ประโยชน์จากเคล็ดลับนี้แล้ว)

lambda n:n**1.5//max(n,1)

ฉันใช้ตัวดำเนินการหารจำนวนเต็ม//ของ Python 3 เพื่อปัดเศษ น่าเสียดายที่ฉันใช้ตัวอักษรจำนวนมากในกรณีที่n=0ไม่ให้แบ่งด้วย 0 ข้อผิดพลาด ถ้าไม่ใช่เพราะฉันทำได้ 18 ตัวอักษร

lambda n:n**1.5//n 

กฎไม่ได้บอกว่าฟังก์ชั่นจะต้องตั้งชื่อ (ขึ้นอยู่กับว่าคุณตีความ "คุณสามารถตั้งชื่อฟังก์ชั่นของคุณทุกอย่างที่คุณชอบ") แต่ถ้าเป็นเช่นนั้นมันก็คือตัวละครอีกสองตัว


- ขอบคุณฉันจะอธิบายให้ชัดเจน มันจะต้องมีฟังก์ชั่นเท่านั้น ไม่จำเป็นต้องตั้งชื่อ ดังนั้นแลมบ์ดาฟังก์ชั่นก็ใช้ได้ ฉันจะพูดถึงเรื่องนี้ตั้งแต่เริ่มต้นถ้าฉันคิดถึงมัน ฉันคิดมากเกินไปในแง่ของ C เมื่อฉันโพสต์คำถาม
ทอดด์เลห์แมน

4

C99 (58 ตัวอักษร)

นี่เป็นตัวอย่างของคำตอบที่ฉันไม่คิดว่าจะเป็นคำตอบที่ดีแม้ว่ามันจะน่าสนใจสำหรับฉันจากมุมมองของรหัสกอล์ฟเพราะมันผิดปกติมากและฉันแค่คิดว่ามันสนุกที่จะโยนลงไปในรายการ:

ดั้งเดิม: 64 ตัวอักษร

uint64_t r(uint64_t n){uint64_t r=1;for(;n/r/r;r++);return r-1;}

เหตุผลที่สิ่งนี้แย่มากก็คือมันทำงานในเวลา O (√n) มากกว่าเวลา O (log (n)) (โดยที่ n คือค่าอินพุต)

แก้ไข: 63 ตัวอักษร

การเปลี่ยนr-1ไป--rและติดต่อไปยังreturn:

uint64_t r(uint64_t n){uint64_t r=1;for(;n/r/r;r++);return--r;}

แก้ไข: 62 ตัวอักษร

การย้ายการเพิ่มขึ้นของลูปไปที่ด้านในของเงื่อนไขของลูป (หมายเหตุ: สิ่งนี้มีพฤติกรรมไม่รับประกันเนื่องจากลำดับของการดำเนินการที่เกี่ยวข้องกับตัวดำเนินการ preincrement คือคอมไพเลอร์เฉพาะ):

uint64_t r(uint64_t n){uint64_t r=0;for(;n/++r/r;);return--r;}

แก้ไข: 60 ตัวอักษร

การเพิ่มtypedefเพื่อซ่อนuint64_t(ให้เครดิตแก่ผู้ใช้technosaurusสำหรับคำแนะนำนี้)

typedef uint64_t Z;Z r(Z n){Z r=0;for(;n/++r/r;);return--r;}

แก้ไข: 58 ตัวอักษร

ตอนนี้ต้องพารามิเตอร์ที่สองถูกส่งผ่านเป็น 0 ในการอุทธรณ์ของฟังก์ชั่นเช่นแทนเพียงr(n,0) r(n)ตกลงสำหรับชีวิตของฉัน ณ จุดนี้ฉันไม่เห็นวิธีการบีบอัดนี้อีกต่อไป ... ใคร?

typedef uint64_t Z;Z r(Z n,Z r){for(;n/++r/r;);return--r;}

หากคุณมีความเต็มใจที่จะเรียกมันว่า C ++ uint64_t s(uint64_t n){for(uint64_t r=n;--n>r/n;);return n;}และลดลงมากกว่าที่เพิ่มขึ้นคุณจะสามารถที่จะโกนคู่ของตัวอักษร:
Forsk

@Fors - วิธีการที่ดี! แต่น่าเสียดายที่จะไม่ทำให้เกิดการหารด้วยศูนย์สำหรับการป้อนข้อมูลของ 1? นอกจากนี้มันจะทำอะไรกับอินพุต 0? เพราะ--nเมื่อn==0จะเป็น –1 และสิ่งเหล่านี้เป็นค่าที่ไม่ได้ลงชื่อดังนั้น –1 จะเป็น2⁶⁴ – 1
ทอดด์เลห์แมน

1
#define Z uint64_t ... หรือ typedef จะช่วยคู่รัก
technosaurus

@technosaurus - อ่าใช่นั่นประหยัด 2. ขอบคุณ :-)
ทอดด์เลห์แมน

1
การแสดงออกn/++r/rมีพฤติกรรมที่ไม่ได้กำหนด ....
aschepler

4

Golfscript - 14 ตัวละคร

{.,\{\.*<}+?(}

พบจำนวนน้อยที่สุดiน้อยกว่าการป้อนข้อมูลที่n กลับn < i*ii - 1

กล่าวคือ [0..n-1].first(i => n < i*i) - 1

คำอธิบายสำหรับผู้ที่ไม่รู้จัก Golfscript เช่นกันสำหรับการโทรตัวอย่างด้วยอินพุต5:

.        //Duplicate input.  Stack: 5 5
,        //Get array less than top of stack.  Stack: 5 [0 1 2 3 4]
\        //Switch top two elements of stack.  Stack: [0 1 2 3 4] 5
{\.*<}+  //Create a block (to be explained), and prepend the top of the stack.  
         //Stack: [0 1 2 3 4]{5\.*<}
?        //Find the first element of the array for which the block is true. 
         //So, find the first element of [0 1 2 3 4] for which {5\.*<} evaluates to true.
         //The inner block squares a number and returns true if it is greater than the input.
(        //Decrement by 1 

โอ้โหนั่นสั้นกว่าคำตอบ Golfscript ที่ดีที่สุด 3 ตัวก่อนหน้านี้ เยี่ยมมาก!
ทอดด์เลห์แมน

การแก้ไขสิ่งนี้เพื่อให้คำตอบที่ถูกต้องสำหรับอินพุต1อาจใช้เวลาสองตัวอักษร
Peter Taylor

4

Haskell, 147 138 134 128 ไบต์

ไม่ใช่รหัสที่สั้นที่สุดในโลก แต่มันทำงานใน O (log n) และตามจำนวนที่กำหนดเอง:

h x=div(x+1)2
n%(g,s)|g*g<n=(g+s,h s)|g*g>n=(g-s,h s)|0<1=(g,0)
f(x:r@(y:z:w))|x==z=min x y|0<1=f r
s n=fst$f$iterate(n%)(n,h n)

นี่เป็นการค้นหาแบบไบนารีของช่วง [0..n] เพื่อค้นหาการประมาณที่ต่ำที่สุดถึง sqrt (n) นี่คือรุ่นที่ไม่ได้รับการอวด:

-- Perform integer division by 2, rounding up
half x = x `div` 2 + x `rem` 2

-- Given a guess and step size, refine the guess by adding 
-- or subtracting the step as needed.  Return the new guess
-- and step size; if we found the square root exactly, set
-- the new step size to 0.
refineGuess n (guess, step)
    | square < n  =  (guess + step, half step)
    | square > n  =  (guess - step, half step)
    | otherwise   =  (guess, 0)
    where square = guess * guess     

-- Begin with the guess sqrt(n) = n and step size (half n),
-- then generate the infinite sequence of refined guesses.
-- 
-- NOTE: The sequence of guesses will do one of two things:
--         - If n has an integral square root m, the guess 
--           sequence will eventually be m,m,m,...
--         - If n does not have an exact integral square root,
--           the guess sequence will eventually alternate
--           L,U,L,U,.. between the integral lower and upper
--           bounds of the true square root.
--        In either case, the sequence will reach periodic
--        behavior in O(log n) iterations.
guesses n = map fst $ iterate (refineGuess n) (n, half n)

-- Find the limiting behavior of the guess sequence and pick out
-- the lower bound (either L or m in the comments above)
isqrt n = min2Cycle (guesses n)
    where min2Cycle (x0:rest@(x1:x2:xs))
            | x0 == x2    =   min x0 x1
            | otherwise   =   min2Cycle rest

แก้ไข:บันทึกสองไบต์ด้วยการแทนที่ส่วนคำสั่ง "เป็นอย่างอื่น" ด้วย "0 <1" เป็นเวอร์ชันที่สั้นกว่าของ "True" และอีกสองสามรายการโดยการฝัง g * g

นอกจากนี้หากคุณมีความสุขกับ O (sqrt (n)) คุณก็สามารถทำได้

s n=(head$filter((>n).(^2))[0..])-1

สำหรับ 35 ตัวอักษร แต่มันสนุกขนาดไหน?

แก้ไข 2:ฉันเพิ่งรู้ว่าเนื่องจากคู่เรียงลำดับตามพจนานุกรมแทนที่จะทำ min2Cycle แผนที่ fst ฉันทำได้แค่ fst min2Cycle ในรหัส golfed แปลว่าแทนที่ f $ map fst ด้วย fst $ f ประหยัด 4 ไบต์ขึ้นไป

แก้ไข 3:บันทึกอีกหกไบต์ด้วยความภาคภูมิใจขอ!


1
คุณสามารถแทนที่ (div x 2 + rem x 2) ด้วย div (x + 1) 2 ที่ฟังก์ชัน "half" ของคุณ
ภูมิใจ haskeller

จริง ๆ แล้วฉันมีทางออกของตัวเองซึ่งมี 49 ตัวอักษรและแก้ปัญหาใน O (log n) แต่ฉันมีเพียง 2 upvotes ;-( ฉันไม่เข้าใจว่าทำไม
ภูมิใจ haskeller

4

JavaScript 91 88 86:ปรับให้เหมาะกับความเร็ว

function s(n){var a=1,b=n;while(Math.abs(a-b)>1){b=n/a;a=(a+b)/2}return Math.floor(a)}

JavaScript 46:ไม่เหมาะสำหรับความเร็ว

function s(n){a=1;while(a*a<=n)a++;return a-1}

นี่คือ JSFiddle: http://jsfiddle.net/rmadhuram/1Lnjuo4k/


1
ยินดีต้อนรับสู่ PPCG! คุณสามารถใช้ <s> 91 </s> <s> 88 </s> เพื่อขีดฆ่าได้ ฉันพยายามทำการแก้ไข แต่คุณกำลังแก้ไขในเวลาเดียวกันดังนั้นฉันจะให้คุณทำ
Rainbolt

1
หรือคุณสามารถทำได้ด้วยตัวละคร 41 ตัวดังนี้:function s(n){for(a=1;++a*a<n;);return a}
Rhubarb Custard

4

C 95 97

แก้ไข Typedef แนะนำโดย @Michaelangelo

นี่ควรจะเป็นการใช้อัลกอริทึมนกกระสามากขึ้นหรือน้อยลง การเล่นโวหารเพียงอย่างเดียวคือในการคำนวณค่าเฉลี่ยหลีกเลี่ยงล้นจำนวนเต็ม: a = (m + n) / 2 ไม่ทำงานสำหรับตัวเลข biiiig

typedef uint64_t Z;
Z q(Z x)
{
   Z n=1,a=x,m=0;
   for(;a-m&&a-n;) n=a,m=x/n,a=m/2+n/2+(m&n&1);
   return a;
}

ใช้งานได้ดีกับการหลีกเลี่ยงการล้น - ไม่เพียง แต่ทำอย่างถูกต้องเท่านั้น แต่ยังต้องระวังที่จะคิดในตอนแรกและทดสอบมัน ชื่นชมอย่างแน่นอน
ทอดด์เลห์แมน

BTW มันเป็นเรื่องตลกที่การแบ่งสรรราคาแพงสำหรับซีพียูบางตัว แม้ว่าอัลกอริทึมนี้จะเรียกใช้งานขั้นตอนครึ่งลูกคิดอัลกอริทึมประมาณครึ่ง แต่ก็มีรันไทม์ที่ช้ากว่าอัลกอริทึมลูกคิดประมาณ 5 เท่าเมื่อฉันเปรียบเทียบกับ CPU Core i7 ของฉันซึ่งไม่ชอบการแบ่ง อย่างไรก็ตาม แต่ runtime ไม่สำคัญที่นี่ - ขนาดเท่านั้น :) ทำงานได้ดีมาก !!!
ทอดด์เลห์แมน

4

C # 64 62 55

เนื่องจากนี่เป็น (และฉันแย่มากในวิชาคณิตศาสตร์) และ runtime เป็นเพียงข้อเสนอแนะฉันได้ทำวิธีที่ไร้เดียงสาที่ทำงานในเวลาเชิงเส้น:

decimal f(ulong a){var i=0m;while(++i*i<=a);return--i;}

( ทดสอบบน dotnetfiddle )

แน่นอนว่ามันช้ามากสำหรับอินพุตที่ใหญ่ขึ้น


1
คุณอาจจะสามารถสลัดตัวละครโดยการเปลี่ยนreturn i-1เป็นreturn--i?
ทอดด์เลห์แมน

ในนิพจน์i*i<=aนั้นรับประกันได้ว่าเป็นเลขจำนวนเต็มของชนิดปกติหรือไม่? (ฉันไม่คุ้นเคยกับ C #.) ถ้าเป็นเช่นนั้นและถ้า C # ช่วยให้การแปลงจำนวนเต็มส่อไปบูลเช่น C a/i/iไม่แล้วคุณอาจจะสามารถบันทึกตัวละครตัวหนึ่งมากขึ้นโดยการเปลี่ยนที่
ทอดด์เลห์แมน

1
@ToddLehman ที่เกิดขึ้นจริงจะได้รับการแก้ไขจุดเลขคณิต ( Decimalค่าสูงสุดที่สูงขึ้นและความแม่นยำ) UInt64.MaxValueเพื่อหลีกเลี่ยงการล้นตั้งแต่ผลคูณที่อาจจะไปขั้นตอนหนึ่งที่ผ่านมา แต่ C # ไม่มีการแปลงเป็นบูลีนโดยปริยาย ฉันควรจะสามารถเปลี่ยนได้returnแม้ว่าขอบคุณ ฉันจะทำเมื่อฉันกลับไปที่คอมพิวเตอร์
Bob

3

Clojure - 51 หรือ 55 ไบต์

ตรวจสอบตัวเลขทั้งหมดจาก n 0 x^2 <= nให้คนแรกที่ รันไทม์คือO(n - sqrt n)

ไม่มีชื่อ:

(fn[x](first(filter #(<=(* % %)x)(range x -1 -1))))

ตั้งชื่อ:

(defn f[x](first(filter #(<=(* % %)x)(range x -1 -1))))

ตัวอย่าง:

(map (fn[x](first(filter #(<=(* % %)x)(range x -1 -1)))) (range 50))
=> (0 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 7)


3

คอบร้า - 62

do(n as uint64)as uint64
    o=n-n
    while o*o<n,o+=1
    return o

รุ่นที่ - 74

set a=0
:1
set /ab=%a%*%a%
if %b% LSS %1 set /aa=%a%+1&goto 1
echo %a%

3

Haskell, 53 50 49 ตัวอักษร, O (บันทึก n)

s n=until((<=n).(^2))(\g->g-1-div(g^2-n-1)(2*g))n

วิธีนี้ใช้วิธีการ newton-raphson แม้ว่ามันจะค้นหาจำนวนเต็มแทนการลอย wiki: http://en.wikipedia.org/wiki/Newton%27s_method

ความซับซ้อนดูเหมือนจะเกี่ยวกับ O (log n) แต่มีหลักฐานหรือไม่ กรุณาตอบในความคิดเห็น


\g->div(n+g^2)$2*gบันทึก 7 ไบต์
Anders Kaseorg

3

J (10)

ได้แรงบันดาลใจอย่างมากจากคำตอบของ @Dennis :

<.@%~^&1.5

และอีกเล็กน้อย แต่มีประสิทธิภาพที่ดีขึ้น (ฉันสงสัย):

<.@(-:&.^.)

floor(halve under log)

ในการดำเนินการชิ้นส่วนที่ถูกเยื้องคืออินพุต:

   f=:<.@%~^&1.5
   f 0 8 12 16
0 2 3 4
   g=:<.@(-:&.^.)
   g 0 8 12 16
0 2 3 4

คุณจะดำเนินการนี้สำหรับจำนวนเต็มที่กำหนดได้อย่างไร
เดนนิส

1
@Dennis ดูคำตอบ
Sepıʇǝɥʇuʎs

3

APL - 12 ตัวอักษร 19 ไบต์

{⌊(⍵*1.5)÷⍵}

ตัวอย่างการใช้:

{⌊(⍵*1.5)÷⍵}17

ส่งคืน 4

ทดสอบเวกเตอร์

{⌊(⍵*1.5)÷⍵}¨0 1 2 3 4 8 9 15 16 65535 65536 18446744073709551615

ผลตอบแทน

1 1 1 1 2 2 3 3 4 255 256 4294967296

ลองออนไลน์

ขอบคุณมากสำหรับ : ผู้ใช้ "ssdecontrol" สำหรับอัลกอริทึม


1
ยินดีต้อนรับสู่ PPCG! ปกติแล้วเราจะให้คะแนน APL เป็นหนึ่งไบต์ต่อตัวอักษร ไม่จำเป็นต้องนับใน UTF-8 เว้นแต่ความท้าทายจะระบุไว้ การเข้ารหัสที่มีอยู่ใด ๆ ก็ใช้ได้และมีเพจรหัส APL เก่าจากหลังในวันที่ใช้ไบต์เดียวสำหรับอักขระแต่ละตัว ความจริงที่ว่า APL มี ASCII ไว้ก่อนหน้านั้นเป็นเหตุผลที่ไม่ดีที่จะลงโทษสำหรับการใช้อักขระที่ไม่ใช่ ASCII ;) (ที่กล่าวมานี้ความท้าทายค่อนข้างเก่าดูเหมือนว่าจะทำคะแนนโดยตัวละครอยู่แล้ว).
มาร์ตินเอนเดอร์

@MartinEnder ขอบคุณสำหรับการต้อนรับที่อบอุ่นและเคล็ดลับ :)
QuantumKarl

1
01! การใช้Dyalog APLคุณสามารถตั้งค่า⎕DIV←1(ซึ่งหลาย ๆ ใช้เป็นค่าเริ่มต้น) เพื่อให้ได้ผลลัพธ์ที่ถูกต้อง
อดัม

2

C99 (108 ตัวอักษร)

นี่คือวิธีการแก้ปัญหาของตัวเองใน C99 ซึ่งดัดแปลงมาจากอัลกอริทึมในบทความเกี่ยวกับวิกิพีเดีย ฉันแน่ใจว่าต้องเป็นไปได้ที่จะทำได้ดีกว่านี้ในภาษาอื่น

แข็งแรงเล่นกอล์ฟ:

uint64_t s(uint64_t n){uint64_t b=1,r=0;while(n/b/4)b*=4;for(;b;b/=4,r/=2)n>=r+b?r+=b,n-=r,r+=b:0;return r;}

กอล์ฟบางส่วน:

uint64 uint64_sqrt(uint64 n)
{
  uint64 b = 1, r = 0;
  while (b <= n / 4)
    b *= 4;
  for (; b; b /= 4, r /= 2)
    if (n >= r + b)
      { r += b; n -= r; r+= b; }
  return r;
}

Ungolfed:

uint64_t uint64_sqrt(uint64_t const n)
{
  uint64_t a, b, r;

  for (b = 1; ((b << 2) != 0) && ((b << 2) <= n); b <<= 2)
    ;

  a = n;
  r = 0;
  for (; b != 0; b >>= 2)
  {
    if (a >= r + b)
    {
      a -= r + b;
      r = (r >> 1) + b;
    }
    else
    {
      r >>= 1;
    }
  }

  // Validate that r² <= n < (r+1)², being careful to avoid integer overflow,
  // which would occur in the case where n==2⁶⁴-1, r==2³²-1, and could also
  // occur in the event that r is incorrect.
  assert(n>0? r<=n/r : r==0);  // Safe way of saying r*r <= n
  assert(n/(r+1) < (r+1));     // Safe way of saying n < (r+1)*(r+1)

  return r;
}

1
ข้อเสนอแนะ: ไม่มีความจำเป็นในการใช้a n
edc65

อ่าใช่ ขอบคุณ. ในฉบับดั้งเดิมของฉันฉันได้รับการดูแลnก่อนที่จะกลับมาฉันสามารถยืนยัน (ไม่แสดง) ที่ r ^ 2 <= n <(r + 1) ^ 2 ด้วยการละเว้นการยืนยันนั้นจำเป็นต้องใช้เวลานานกว่าnเดิม
ทอดด์เลห์แมน

@ edc65 - ขอบคุณอีกครั้งสำหรับการชี้ให้เห็น ฉันอัปเดตรหัสของฉันเพื่อสะท้อนถึงสิ่งนั้นรวมถึงเพิ่มเทคนิคการเล่นกอล์ฟอื่น ๆ นอกจากนี้ยังเพิ่มการยืนยันเดิมและทำconstในรุ่น ungolfed
ทอดด์เลห์แมน

2

JavaScript 73 81 (เพื่อให้สอดคล้องกับข้อกำหนดหมายเลข 64- บิต)

n=prompt();g=n/3;do{G=g,g=(n/g+g)/2}while(1E-9<Math.abs(G-g))alert(Math.floor(g))

การติดตั้งอัลกอริทึมของ Heron of Alexandria ...


ดี! ใช้ได้กับอินพุตจำนวนเต็ม 64 บิตที่ไม่ได้ลงชื่อทั้งหมดหรือไม่
ทอดด์เลห์แมน

ลองเป็นฉันอาจดูเหมือนว่าจะทำงานได้ถึง 32 บิต ... ความผิดหวังของฉันมาก ...
WallyWest

แน่นอนที่สุด | 0 ตัดค่าใด ๆ เป็น 32 บิต ใช้ Math.floor แทนไหม
edc65

@ edc65 คุณถูกต้องจริง ๆ แล้ว|0ส่งผลกระทบมากถึง 32 บิตในขณะที่Math.floorมีประสิทธิภาพมากขึ้นที่ 64- บิต ... ฉันได้อัปเดตโค้ดของฉันโดยต้องใช้อักขระเพิ่มอีก 8 ตัวเพื่อที่จะทำเช่นนั้น ...
WallyWest

@ edc65 ฉันเพิ่งคิดว่า ... ~~ x จะทำงานใน 64 บิตได้หรือไม่
WallyWest

2

Powershell (52) จำกัด เฉพาะ Int32 (-2,147,483,648 ถึง 2,147,483,647)

function f($n){($n/2)..0|%{if($_*$_-le$n){$_;exit}}}

ฉันกรีดร้องที่ Powershell ตอนนี้พยายามทำให้กรณีทดสอบสุดท้ายทำงาน แต่ไม่ว่าฉันจะทำอะไร Powershell จบลงด้วยการใช้ตัวแปรไปป์ $ _ เป็น Int32 และฉันไม่สามารถหาวิธีแก้ไขได้ในตอนนี้

ดังนั้นฉันจะ จำกัด คำตอบของฉันในตอนนี้ หากฉันสามารถหาวิธีที่ดีกว่าในการจัดการกับ uint64s ฉันจะแก้ไข (กรณีทดสอบสุดท้ายมีขนาดใหญ่เกินไปสำหรับ Int64 แบบปกติของ Powershell!)

ต่อไปนี้เป็นกรณีทดสอบสองสามข้อ (โดยมีเอาต์พุตเพิ่มเล็กน้อยที่ฉันใช้ในการติดตามเวลา)

f 17
4
Elapsed Time: 0.0060006 seconds

f 65
8
Elapsed Time: 0.0050005 seconds

f 65540
256
Elapsed Time: 1.7931793 seconds

f 256554
506
Elapsed Time: 14.7395391 seconds

ฉันไม่รู้ O () ของฉัน แต่ดูเหมือนว่าจะกระโดดได้อย่างน่าทึ่ง


2

Caveat: ตั้งแต่ปี 2011 R ไม่มีการสนับสนุนในตัวสำหรับจำนวนเต็ม 64 บิตเหมือนที่ฉันคิดเอาไว้ คำตอบเหล่านี้อาจไม่ถูกต้องในด้านเทคนิคนั้น แต่จากนั้น R ได้เปลี่ยนแปลงไปมากในช่วง 3 ปีที่ผ่านมา


R, 85

ใช้วิธีการของนิวตัน:

function(n){s=F
x=n
y=(1/2)*(x+n/x)
while(abs(x-y)>=1){x=y
y=(1/2)*(x+n/x)}
trunc(y)}

ซึ่งมาบรรจบกันเป็นสองเท่า +2 ตัวอักษรเพื่อกำหนดฟังก์ชั่นให้กับตัวแปรสำหรับการเปรียบเทียบ:

microbenchmark(q(113424534523616))
# Unit: microseconds
#                expr    min      lq median      uq    max neval
#  q(113424534523616) 24.489 25.9935 28.162 29.5755 46.192   100

R, 37

กำลังดุร้าย:

function(n){t=0
while(t^2<n) t=t+1
t}

และตรวจสอบเดียวกัน:

microbenchmark::microbenchmark(q(113424534523616),times=1)
# Unit: seconds
#                 expr      min       lq   median       uq      max neval
#   q(113424534523616) 4.578494 4.578494 4.578494 4.578494 4.578494     1

R, 30

ราคาถูก / สดใสเคล็ดลับการยกกำลัง :

function(n) trunc(n^(1.5)/n)

ซึ่งยังเกิดขึ้นจะเร็วมาก (แม้ว่าจะไม่เร็วเท่าในตัว):

microbenchmark(q(113424534523616),sqrt(113424534523616))
# Unit: nanoseconds
#                   expr min    lq median    uq  max neval
#     z(113424534523616) 468 622.5  676.5 714.5 4067   100
#  sqrt(113424534523616)  93 101.0  119.0 160.5 2863   100


2

dc, 50 ไบต์

dc -e"?dsist[lt2/dstd*li<B]dsBx[lt1+dstd*li!<A]dsAxlt1-f"

เว้นระยะและอธิบาย:

               # The idea here is to start with the input and reduce it quickly until it is
               # less than what we want, then increment it until it's just right
?              # Take input from stdin
d si st        # Duplicate input, store in `i' and in `t'
[              # Begin macro definition (when I write in dc, "macro"=="function")
 lt            # Load t, our test term
 2/            # Divide t by two
 d st          # Store a copy of this new term in `t'
 d*            # Duplicate and multiply (square)
 li<B          # Load i; if i<(t^2), execute B
] d sB x       # Duplicate, store function as `B', and execute
               # Loop ends when t^2 is less than i
[              # Begin macro definition
 lt            # Load t, our test term
 1+            # Increment
 d st          # Store a copy of this new term in `t'
 d*            # Duplicate and multiply (square)
 li!<A         # Load i; if i>=(t^2), execute A
] d sA x       # Duplicate, store function as `A', and execute
               # Loop ends when t^2 == i+1
lt 1- f        # Load t, decrement, and dump stack

เอ่อดูเหมือนว่ากรณีทดสอบสุดท้ายจะล่ม ฉันจะพยายามแก้ไข
Joe

การแก้ไข ตอนนี้ยอมรับอินพุตที่มีขนาดใหญ่มาก การแก้ไขทำให้ฉันสามารถลบรหัสที่น่าเกลียดบางส่วนได้ในตอนแรก
Joe

2

C, 139 137 136 ไบต์

การลองครั้งแรกของฉันที่การตีกอล์ฟ ดูเหมือนว่าจะสั้นที่สุดใน C ที่เหมาะกับความต้องการ "ประสิทธิภาพ" เนื่องจากทำงานได้O(log n)ทันเวลาโดยใช้การเพิ่มและเลื่อนบิตเท่านั้น แม้ว่าฉันจะแน่ใจว่ามันจะสั้นกว่านี้ ...

มันควรจะทำงานเพียงแค่ปรับให้ค่าจำนวนเต็มขนาดใหญ่เกินไปตราบใดที่ส่วนหนึ่งจะถูกเปลี่ยนเป็นa=32a=NUMBITS/2

typedef uint64_t x;x f(x o){x a=32,t=0,r=0,y=0,z;for(;a--+1;){z=(x)3<<2*a;y*=2;t++<r?y++,r-=t++:t--;t*=2;r*=4;r+=(o&z)>>2*a;}return y;}

เยี่ยมมาก! ฉันไม่ได้ทำการทดสอบ แต่รหัสดูน่าสนใจ มีเหตุผลที่คุณเขียน(t++)แทนที่จะเพียงt++มอบหมายให้r?
ทอดด์เลห์แมน

1
@ToddLehman Nope เพิ่งพลาดที่จะนำออกไป รับได้สวย!
คริส

BTW ฉันรักเป็นวิธีที่จะหลีกเลี่ยงการเขียนa--+1 a-- != UINT64_C(-1)คุณเรียนรู้ที่หลอกลวงที่ไหนสักแห่งหรือคิดค้นมันเอง?
ทอดด์เลห์แมน

1
@ToddLehman ขอบคุณ! ฉันคิดออกเอง
คริส

1

C - 50 (61 ไม่มีทั่วโลก)

typedef uint64_t T;T n,i;f(){while(++i*i<=n);--i;}

มันใช้ตัวแปรส่วนกลางเป็นพารามิเตอร์และส่งคืนค่าเพื่อประหยัดพื้นที่

ไม่มีเวอร์ชันทั่วโลก:

typedef uint64_t T;T f(T n){T i=0;while(++i*i<=n);return--i;}

1
ฉันไม่คิดว่าการใช้ตัวแปรทั่วโลกนั้นถูกกฎหมาย อย่างน้อยก็บอกได้ว่านานแค่ไหนที่จะถูกต้องตามกฎหมายและให้รุ่นที่ถูกต้อง
ภูมิใจ haskeller

@proud haskeller ทำไมตัวแปรทั่วโลกถึงถูกแบน?
mantale

@mantal เนื่องจากคุณต้องระบุโปรแกรม / วิธีที่รันได้
Marciano ลด

@ Marciano และให้รหัสที่ให้นั้นสามารถเรียกใช้ได้
mantale

1

C ++ 125

int main()
{
uint64_t y;cin>>y;
double x=y/2,d,z;
while((d=(x*x-y))>0.5)
{
d<0?x+=0.5:x-=0.5;
}
cout<<(uint64_t)x;
}

ดี! แล้วx+=(d<0)-0.5;... บันทึกได้อีก 5 ตัวอักษร?
ทอดด์เลห์แมน

BTW นี่ไม่ใช่ (แต่ควร) ในรูปแบบของฟังก์ชั่นดังที่กล่าวไว้ในคำสั่งปัญหา (โอเคในทางเทคนิคใช่mainเป็นฟังก์ชั่น แต่มันก็ไม่สามารถเรียกได้จากภายในโปรแกรมเหมือนf(y)จะเป็น)
ทอดด์เลห์แมน

ฉันคิดว่าคุณสามารถละเว้นคู่ในสุดของวงเล็บและเขียนแทนwhile((d=x*x-y)>0.5) while((d=(x*x-y))>0.5)บันทึกได้อีก 2 ตัวอักษร :)
ทอดด์เลห์แมน

ทุกๆ 0.5 สามารถเปลี่ยนเป็น. 5
Yytsi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.