Không phân nhánh


14

Bất cứ ai tham gia tối ưu hóa mã ở mức độ thấp đều biết về sự nguy hiểm của việc phân nhánh, được thực hiện dưới dạng câu lệnh if, vòng lặp hoặc câu lệnh chọn, khả năng hiểu sai nhánh là một điều lãng phí đồng hồ khủng khiếp.

Các vấn đề đơn giản có thể được giải quyết tốt hơn nhiều với số học đơn giản, vì vậy hãy làm điều đó.

Đối với các vấn đề sau, tất cả các biến là số nguyên không dấu 32 bit và mã được phép duy nhất là các câu lệnh được đặt đơn giản chỉ liên quan đến các toán tử sau:

+ addition
- subtraction
* multiplication
/ integer division, rounds down, division by 0 not allowed
% modulo
& binary and
| binary or
^ binary exclusive or
>> bitshift right
<< bitshift left

Logic operators, return 1 if the expression is true and 0 if it is false.
== equal
!= not equal
< less than
<= less than or equal
> greater than
>= greater than or equal

Set operator
=

Mỗi dòng phải bao gồm một định danh biến được theo sau bởi một toán tử tập hợp, theo sau là một biểu thức.

Một biểu thức có thể không chứa các toán tử tập bổ sung, nhưng có thể chứa các định danh biến, số bằng chữ và dấu ngoặc đơn.

Điểm đánh gôn chỉ được tính số lượng người điều khiển.

Thí dụ:

myvar = ( ( ( foo + 5 ) * bar ) % 7 ) == 3

Có số điểm 5 nhà khai thác.

Một giải pháp có thể bao gồm nhiều biến như tác giả thấy phù hợp.
Các biến chưa được đặt có giá trị 0.
Tràn và underflow được cho phép, tất cả số âm underflow, vì vậy 3 - 54294967294, thậm chí như một phần của một tuyên bố lớn hơn.

Nhiệm vụ 1: Tối đa

Hai giá trị, AB, tồn tại trong phạm vi, làm cho RESULTbiến chứa giá trị lớn nhất trong số các giá trị đó khi chương trình kết thúc.

Nhiệm vụ 2: Trung bình

Ba giá trị, A, BC, tồn tại trong phạm vi, làm cho RESULTbiến chứa trung bình của những giá trị khi chấm dứt chương trình.

Nhiệm vụ 3: Căn bậc hai

Một giá trị, Atồn tại trong phạm vi, làm cho RESULTbiến chứa căn bậc hai của A, được làm tròn xuống, khi chương trình kết thúc.

Bạn có thể đăng câu trả lời cho một hoặc hai câu hỏi, đối với một số bạn chỉ cần tìm giải pháp hợp lệ sẽ là một thách thức.


Nhà điều hành unary ở đâu? Tôi không quan tâm -nhưng ~có thể tốt (ngay cả khi tôi không biết để làm gì).
John Dvorak

Chắc chắn, 0xFFFF_FFFF_FFFF_FFFF ^ x0 - x. Làm thế nào tôi có thể quên?
John Dvorak

@JanDvorak Nó đưa ra mô tả ngắn nhất, vì logic hoàn chỉnh không phải !cũng khá tầm thường : x == 0.
aaaaaaaaaaaa

Hành vi của chia cho số không là gì?
John Dvorak

Trong Mathicala (a> b) trả về Đúng hoặc Sai. Boole chuyển đổi Sai thành 0 và Đúng thành 1. Sử dụng có hợp pháp Boole[a-b]không?
DavidC

Câu trả lời:


5

Nhiệm vụ 3, 23 ops

x = (A >> 16) + A / ((A >> 13) + 511) + 15
x = (x + A/x) >> 1
x = (x + A/x) >> 1
x = (x + A/x) >> 1
RESULT = x - (x > A/x)

Sử dụng phương pháp của Newton, như các giải pháp khác làm, với một hạt giống được lựa chọn khéo léo hơn. Bit đầu tiên A >> 16giữ cho đỉnh của phạm vi hạnh phúc, bit thứ hai A / ((A >> 13) + 511)giữ giữa phạm vi hạnh phúc và bit cuối cùng 15ở dưới cùng và cũng ngăn phân chia cho các lỗi không (15 là giá trị lớn nhất có thể cho phép 0hội tụ chính xác - giảm một nửa ba lần trừ hiệu chỉnh bằng 0). Đối với các giá trị đầu vào 225, 275625, 82137969, 2908768489(và các giá trị lân cận), hạt giống ban đầu là chính xác. Tất cả các trường hợp cạnh (hình vuông hoàn hảo, hình vuông hoàn hảo + 1 và hình vuông hoàn hảo - 1) trên phạm vi 0 .. 2**32-1đã được kiểm tra và là chính xác.

Một vài nhận xét về các quy tắc:
Cho phép tràn và tràn, tất cả các số âm đều tràn, vì vậy 3 - 5 là 4294967294, thậm chí là một phần của câu lệnh lớn hơn .

Đó là chút cuối cùng hóa ra là một cái gì đó của một kẻ giết người đổi mới. Ban đầu, tôi đã thử một giải pháp bằng cách sử dụng một hình thức tổng quát của phương pháp Halley , nhưng nhận ra rằng nó không hợp lệ với các hạn chế nêu trên. Lặp lại (như áp dụng cho căn bậc hai) là:

x = x * (3*A + x*x) / (A + 3*x*x)

Lặp đi lặp lại này có những phẩm chất tốt đẹp mà Newton không có. Nó hội tụ một cách lập phương (chứ không phải theo phương pháp bậc hai), nó hội tụ từ bên trên hoặc bên dưới (chứ không chỉ từ bên trên), và nó không nhạy cảm với một hạt giống được chọn kém (nếu phép lặp của Newton được cung cấp một hạt giống quá thấp, nó sẽ rất nhiều bắn vào điểm hội tụ, và sau đó cần phải làm việc trở lại).

Phương pháp của Newton cũng có một vấn đề (ít nhất là khi xử lý các số nguyên) rằng nó sẽ thường đạt tới một x sao cho A / x - x = 2 - trong trường hợp này, nó sẽ hội tụ đến một giá trị lớn hơn gốc số nguyên thích hợp, mà cần phải được sửa chữa cho; Phương pháp của Halley không cần điều chỉnh như vậy. Nhưng thật không may, giá trị của 3*A + x*xwill thường sẽ lớn hơn không gian số nguyên 32 bit được phép.

Có một số thuật toán gốc thứ n tổng quát khác , nhưng tất cả chúng đều có chung đặc điểm này:

x = x + x*(v - x**n)/(v*n)
x = (x*(n+1) - x**(n+1)/v)/n
x = ((n-2)*x + (4*v*x)/(v + x**n))/n
x = x*((n+2)*v + (n-2)*x**n)/(v + x**n)/n
x = ((n-2)*x + (n*x*v)/(v + (n-1)*x**n))/(n-1)
x = ((n-2)*x + x*((n*2-1)*v + x**n)/(v + (n*2-1)*x**n))/(n-1)

x = x + 2*x*(v - x**n)/(v + x**n)/n
x = x + x*31*(v - x**n)/(10*v + 21*x**n)/n
x = x + x*561*(v - x**n)/(181*v + 380*x**n)/n
x = x + x*1153*(v - x**n)/(372*v + 781*x**n)/n

vv Hầu hết trong số này hiển thị hội tụ khối hoặc bậc hai. Bốn phần cuối cùng là một phần của một loạt các phép lặp hội tụ về sự hội tụ tứ phương. Nhưng trong Praxis, phương pháp của Newton sẽ giúp bạn có được những gì bạn cần với ít thao tác hơn, trừ khi bạn cần tính toán hàng trăm chữ số.


Khá đẹp, nhưng thất bại trong 4294967295. Về quy tắc, họ phải chặt chẽ để làm cho nó thú vị. Bạn có thể tranh luận những tiền đề chính xác nào tạo ra thách thức tốt nhất, nhưng cuối cùng, điều quan trọng hơn nhiều là các quy tắc rõ ràng và không mơ hồ, hơn chính xác những gì chúng cho phép.
aaaaaaaaaaaa

Tôi không nghĩ Halley sẽ có giá trị dù sao đi nữa, từ một dự đoán xa, nó sẽ cải thiện ít hơn một chút so với hệ số 3, Newton làm ít hơn một chút so với hệ số 2. Tương tự từ một dự đoán tốt, Halley sẽ nhân ba độ chính xác, Newton sẽ nhân đôi nó. Vì vậy, một lần lặp Halley có giá trị khá chính xác là các log(3)/log(2) ~= 1.585lần lặp Newton.
aaaaaaaaaaaa

@eBusiness Ban đầu tôi có 2 Halley với hạt giống được chọn tương tự với tổng số 25 ops - có lỗi khi A = 0- vì vậy thực tế nó ngắn hơn. Khoảng 4294967295 , đó là một sự giám sát: vì 65536² 0 , việc lặp lại điều chỉnh không chính xác. Tôi sẽ xem nếu tôi có thể tìm thấy một sự thay thế.
Primo

@eBusiness cố định.
primo

Căn bậc hai đẹp nhất của gói, công việc tốt, và một huy hiệu chiến thắng chính thức.
aaaaaaaaaaaa

5

65 (61) hoạt động (5 + 13 + 47 (43))

Nhiệm vụ 1 - Tối đa (A, B)

RESULT = A + (B - A) * (A <= B)

Đây là giải pháp rõ ràng. Bạn cần sự phân công, bạn cần so sánh, bạn cần nhân so sánh với một cái gì đó, bội số không thể là một trong các biến và sản phẩm không thể là kết quả.

Nhiệm vụ 2 - Giữa (A, B, C)

RESULT = A                               \
       + (B - A) * (A > B) ^ (B <= C)    \
       + (C - A) * (A > C) ^ (C <  B)

Đây là một cải tiến so với giải pháp 15-op trước đây của tôi, điều hòa cả ba biến - điều này đã lưu hai phép trừ, nhưng nó đã giới thiệu một bài kiểm tra tính trung tâm khác. Bản thân bài kiểm tra rất đơn giản: một phần tử nằm ở giữa chính xác, một phần tử khác nằm ở trên.

Nhiệm vụ 3 - sqrt (A)

X1     = 1024 + A / 2048
X2     = (X1  + A / X1 ) / 2
...
X10    = (X9 + A / X9 ) / 2
RESULT = X16 - (X16 * X16 > A)

Mười một vòng xấp xỉ newton. Hằng số ma thuật 1024 đã bị WolframW đánh bại (và 512 gây ra phép chia cho 0 cho a = 0 trước khi a = 2 ** 32 hội tụ), nhưng nếu chúng ta có thể định nghĩa 0/0 là 0, mười lần lặp sẽ hoạt động với giá trị bắt đầu trong số 512. Tôi thừa nhận rằng yêu cầu mười lần lặp của tôi không hoàn toàn trong sạch, nhưng tôi vẫn yêu cầu chúng trong ngoặc đơn. Tuy nhiên, tôi sẽ phải điều tra nếu chín là có thể.Giải pháp của WolframH chín lần lặp.


Tôi nghĩ rằng dòng đầu tiên của Nhiệm vụ 3 là không đúng: hằng số thứ hai phải gấp 4 lần hằng số thứ nhất (để có Newton "thuần túy").
Phục hồi Monica

@WolframH Một dự đoán ban đầu tốt hơn có thể giải thích tại sao tôi lãng phí chu kỳ. Bạn đã nghĩ ra 4 * ở đâu? Điều này trông giống như hai lần lặp lại thành một.
John Dvorak

(1024 + A/1024)/2 == (512 + A/2048)(giống như X0 = 1024, và sau đó bắt đầu Newton).
Phục hồi Monica

Giải pháp hay cho Nhiệm vụ 1. Trứng của Columbus.
DavidC

@DavidCarraher tất nhiên, giải pháp chính xác sẽ là MOV RESULT, A; CMP A,B; CMOVA RESULT, B;-)
John Dvorak

5

Toán tử 1: 5

RESULT = B ^ (A ^ B)*(A > B)

Toán tử 2: 13

RESULT = B ^ (A ^ B)*(A > B) ^ (A ^ C)*(A > C) ^ (B ^ C)*(B > C)

Toán tử 3: 27

g = 47|((0x00ffffff & A)>>10)|(A>>14)
r = (g + A/g)/3
r = (r + A/r)>>1
r = (r + A/r)>>1
r = (r + A/r)>>1
RESULT = r - (r*r-1>=A)

5

Nhiệm vụ 3, 39 Hoạt động

EDIT: Thay đổi dòng cuối cùng; Xem ý kiến.

Đây là một thực hiện của phương pháp Newthon. Đã thử nghiệm với tất cả các ô vuông dương, và cũng với các ô vuông dương trừ đi một, và cũng có một triệu số ngẫu nhiên trong phạm vi từ 0 đến 2 ^ 32-1. Giá trị bắt đầu có vẻ buồn cười là viết tắt của (1022 + A/1022) / 2, nó cần số lần lặp ít nhất (tôi nghĩ), và cũng làm RESULTcho A=0đúng (sẽ không phải là trường hợp 1024thay thế 1022).

r = (511 + A/2044)
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
r = (r + A/r) / 2
RESULT = r - (r > A/r)

Tôi có nên giữ bản sao kém hơn của phương pháp của newton đã được tối ưu hóa song song với phương pháp của bạn và đăng một khoảng thời gian kha khá sau đó không? Những bộ óc vĩ đại nghĩ giống nhau và giải pháp phân chia thành hai hai câu trả lời là không tốt, nhưng đó là tình trạng hiện tại là gì, như bạn chưa trả lời # 2.
John Dvorak

@JanDvorak: Cảm ơn bạn đã hỏi thăm. Không sao nếu bạn đặt phương pháp ngắn hơn một chút vào câu trả lời của bạn. Ngoài ra, cảm ơn vì đã cung cấp tín dụng cho tôi :-)
Phục hồi lại

Thử rất tốt, nhưng không thành công cho đầu vào 4294965360 đến 4294967295.
aaaaaaaaaaaa

@eBusiness: Bạn nhận được kết quả gì cho những đầu vào đó? Tôi nhận được 65535 trong các bài kiểm tra của mình, điều đó là ổn.
Phục hồi Monica

Tôi nhận được 65536. Có thể bạn không sử dụng định dạng số nguyên quy định.
aaaaaaaaaaaa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.