Nếu chỉ có nội tại dành riêng cho máy cụ thể C # thì có một lệnh duy nhất có thể thực hiện điều này bằng ngôn ngữ lắp ráp x86 và trên hầu hết các kiến trúc bộ xử lý khác. Sau đó, bạn không chỉ có mã ngắn nhất, mà rất có thể là nhanh nhất.
Trong thực tế, làm cho mã này ngắn hơn là một vấn đề cực kỳ nhàm chán so với làm cho mã này nhanh . Có tất cả các loại giải pháp thực sự gọn gàng, hiệu quả, đôi chút, và bạn cũng có thể xem xét sử dụng bảng tra cứu.
Không ai trong số đó quan trọng cho việc chơi golf, mặc dù. Đối với tôi có vẻ như giải pháp hiện tại của bạn là tốt nhất bạn có thể làm. Tất nhiên, bạn có thể xóa khoảng trắng thừa:
k<1?0:(int)Math.Log(k&-k,2)+1
Cá nhân tôi sẽ viết nó như sau:
k>0?(int)Math.Log(k&-k,2)+1:0
bởi vì tôi nghĩ rằng sẽ rõ ràng hơn một chút khi có hướng của bài kiểm tra có điều kiện theo cách đó, cũng như so sánh nó với số không, nhưng tôi đoán đó là sáu cách một, nửa tá cách khác.
C # không hỗ trợ chuyển đổi ngầm từ int
đến bool
như C và C ++ làm, vì vậy bạn có thể không thực sự rút ngắn thử nghiệm có điều kiện thêm nữa.
Bạn cũng bị mắc kẹt với các diễn viên rõ ràng từ double
(như đã trả lại của tôi Math.Log
) đến int
, vì C # sẽ không cho phép điều này xảy ra ngầm. Tất nhiên, đó thường là một điều tốt bởi vì nó sẽ chỉ ra rằng bạn có một vấn đề hiệu suất lớn ở đây: quảng bá int
cho một double
, tính toán nhật ký của a double
, và sau đó chuyển đổi double
kết quả trở lại int
sẽ chậm một cách ồ ạt , vì vậy, đó thường là một điều gì đó mà bạn muốn tránh. Nhưng đây là những loại sai lầm bạn phải đưa ra khi chơi golf mã.
Ban đầu tôi nghĩ ra
k > 0
? ((k & -k) >> 1) + 1
: 0
(tất nhiên là không rõ ràng), điều này tránh việc lấy logarit và do đó là một sự cải thiện về kích thước và tốc độ mã. Thật không may, điều này không phải lúc nào cũng nhận được câu trả lời đúng và tôi cho rằng đó là một yêu cầu không linh hoạt. :-) Cụ thể, nó không thành công nếu giá trị đầu vào ( k
) là hệ số 8. Điều này có thể sửa được, nhưng không phải là không làm cho mã dài hơn Math.Log
phiên bản.