Vấn đề:
Trong lựa chọn ngôn ngữ của bạn, hãy viết hàm ngắn nhất trả về sàn của căn bậc hai của một số nguyên 64 bit không dấu.
Các trường hợp thử nghiệm:
Chức năng của bạn phải hoạt động chính xác cho tất cả các đầu vào, nhưng đây là một số giúp minh họa ý tưởng:
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
Quy tắc:
- Bạn có thể đặt tên cho chức năng của bạn bất cứ điều gì bạn thích. (Các chức năng không tên, ẩn danh hoặc lambda đều ổn, miễn là chúng có thể gọi được bằng cách nào đó.)
- Số lượng nhân vật là điều quan trọng nhất trong thử thách này, nhưng thời gian chạy cũng rất quan trọng. Tôi chắc chắn rằng bạn có thể quét ngược lên để tìm câu trả lời trong thời gian O (√n) với số lượng ký tự rất nhỏ, nhưng thời gian O (log (n)) sẽ thực sự tốt hơn (nghĩa là giả sử giá trị đầu vào là n, không phải là một bit dài của n).
- Bạn có thể sẽ muốn thực hiện hàm bằng cách sử dụng hoàn toàn số nguyên và / hoặc số học boolean. Tuy nhiên, nếu bạn thực sự muốn sử dụng các phép tính dấu phẩy động, thì điều đó cũng tốt miễn là bạn gọi không có chức năng thư viện. Vì vậy, chỉ cần nói
return (n>0)?(uint32_t)sqrtl(n):-1;
trong C là vượt quá giới hạn mặc dù nó sẽ tạo ra kết quả chính xác. Nếu bạn đang sử dụng dấu chấm động số học, bạn có thể sử dụng*
,/
,+
,-
, và lũy thừa (ví dụ,**
hoặc^
nếu đó là một built-in điều hành bằng ngôn ngữ của bạn lựa chọn, nhưng chỉ lũy thừa quyền lực không nhỏ hơn 1 ). Hạn chế này là để ngăn chặn "gian lận" bằng cách gọisqrt()
hoặc một biến thể hoặc nâng giá trị lên sức mạnh. - Nếu bạn đang sử dụng các phép toán dấu phẩy động (xem # 3), bạn không yêu cầu loại trả về là số nguyên; chỉ có điều rằng giá trị trả về là một số nguyên, ví dụ: floor (sqrt (n)) và có thể giữ bất kỳ giá trị 32 bit không dấu nào.
- Nếu bạn đang sử dụng C / C ++, bạn có thể giả sử sự tồn tại của các loại số nguyên 64 bit và 32 bit không dấu, ví dụ,
uint64_t
vàuint32_t
như được định nghĩa trongstdint.h
. Mặt khác, chỉ cần đảm bảo loại số nguyên của bạn có khả năng chứa bất kỳ số nguyên không dấu 64 bit nào. - Nếu ngôn ngữ của bạn không hỗ trợ số nguyên 64 bit (ví dụ: Brainfuck rõ ràng chỉ có hỗ trợ số nguyên 8 bit), thì hãy cố gắng hết sức với điều đó và nêu giới hạn trong tiêu đề câu trả lời của bạn. Điều đó nói rằng, nếu bạn có thể tìm ra cách mã hóa số nguyên 64 bit và lấy chính xác căn bậc hai của nó bằng số học nguyên thủy 8 bit, thì sẽ tiếp thêm sức mạnh cho bạn!
- Hãy vui vẻ và sáng tạo!
O(log_2 n) === O(log_4 n)
. log_4(n) = log_2(n) / log_2(2) = log_2(n) / 2