Tôi đã thực hiện chương trình Haskell (chưa được xử lý) sau đây cho thử thách chơi gôn mã khi tính toán giá trị đầu tiên của A229037 .
Đây là giải pháp đề xuất của tôi để tính giá trị thứ :
a n | n<1 = 0
| n<3 = 1
| otherwise = head (goods n)
goods n = [x | x <- [1..], isGood x n]
isGood x n = and [ x - a(n-k) /= a(n-k) - a(n-k-k) || a(n-k-k) == 0 | k <- [1..n] ]
Lưu ý rằng Haskell không tự động lưu trữ hoặc ghi nhớ các giá trị này.
Trang OEIS cho chuỗi cung cấp thực tế là , do đó, có thể được thay thế bởi vì thuật toán sẽ không bao giờ đạt đến lớn hơn .x n + 1[1..]
[1..(n+1)/2]
Cố gắng đếm các cuộc gọi hàm, tôi đã rút ra giới hạn trên , số lượng cuộc gọi hàm mà thuật toán thực hiện cho một đầu vào :n
Tôi đã cắm công thức cuối cùng vào Mathematica:
RSolve[{T[n] == 2*T[n - 1]*n*(n + 1), T[1] == 1}, T[n], n]
Và nhận được, sau một chút đơn giản hóa:
Tỷ lệ trung bình giữa thời gian thực hiện chương trình Haskell này, với là và độ lệch chuẩn của các tỷ lệ là khoảng . (Thật kỳ lạ, biểu đồ nhật ký của các tỷ lệ dường như là một đường thẳng).2.0 ⋅ 10 39 6.0 ⋅ 10 39
Các tỷ lệ với dòng đầu tiên, xác định , có độ lệch trung bình và tiêu chuẩn lần lượt là và , nhưng cốt truyện của nó nhảy rất nhiều.
Làm thế nào tôi có thể có được một ràng buộc tốt hơn về độ phức tạp thời gian của thuật toán này?
Đây là thuật toán trong C hợp lệ (trừ khai báo chuyển tiếp), mà tôi tin là gần tương đương với mã Haskell:
int a(int n){
if (n < 1) {
return 0;
} else if (n < 3) {
return 1;
} else {
return lowestValid(n);
}
}
int lowestValid(int n){
int possible = 1; // Without checking, we know that this will not exceed (n+1)/2
while (notGood(possible, n)) {
possible++;
}
return possible;
}
int notGood(int possible, int n){
int k = 1;
while (k <= n) {
if ( ((possible - a(n-k)) == (a(n-k) - a(n-2*k))) && (a(n-2*k) != 0) ) {
return 1;
} else {
k++;
}
}
return 0;
}
Phiên bản C mất khoảng 5 phút để tính toán và phiên bản Haskell mất khoảng tương tự cho .
Lần đầu tiên của các phiên bản:
Haskell: [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0e-2,3.0e-2,9.0e-2,0.34,1.42,11.77,71.68,184.37,1815.91]
C: [2.0e-6, 1.0e-6, 1.0e-6, 2.0e-6, 1.0e-6, 6.0e-6, 0.00003,0.00027, 0.002209, 0.005127, 0.016665, 0.080549, 0.243611, 0.821537, 4.56265, 24.2044, 272.212]