Giải pháp khác
Đây là, theo tôi, một trong những vấn đề thú vị nhất trên trang web. Tôi cần phải cảm ơn deadcode vì đã đưa nó trở lại đầu trang.
^((^|xx)(^|\3\4\4)(^|\4x{12})(^x|\1))*$
39 byte , không có bất kỳ điều kiện hoặc xác nhận ... sắp xếp. Các thay thế, như chúng đang được sử dụng ( ^|
), là một loại điều kiện theo cách, để chọn giữa "lần lặp đầu tiên" và "không phải lần lặp đầu tiên".
Regex này có thể được nhìn thấy để làm việc ở đây: http://regex101.com/r/qA5pK3/1
Cả PCRE và Python đều diễn giải chính xác regex và nó cũng đã được thử nghiệm trong Perl lên đến n = 128 , bao gồm n 4 -1 và n 4 +1 .
Định nghĩa
Kỹ thuật chung giống như trong các giải pháp khác đã được đăng: xác định biểu thức tự tham chiếu mà trên mỗi lần lặp tiếp theo khớp với độ dài bằng với số hạng tiếp theo của hàm chênh lệch chuyển tiếp, D f , với bộ định lượng không giới hạn ( *
). Một định nghĩa chính thức của hàm chênh lệch chuyển tiếp:
Ngoài ra, các hàm chênh lệch bậc cao hơn cũng có thể được xác định:
Hoặc, nói chung hơn:
Hàm khác biệt chuyển tiếp có rất nhiều tính chất thú vị; đó là để giải trình tự đạo hàm là gì đối với các hàm liên tục. Ví dụ: D f của đa thức bậc n sẽ luôn là đa thức bậc 1 và với mọi i , nếu D f i = D f i + 1 , thì hàm f là hàm mũ, theo cách tương tự rằng đạo hàm của e x bằng chính nó. Hàm rời rạc đơn giản nhất mà f = D f là 2 n .
f (n) = n 2
Trước khi chúng tôi kiểm tra giải pháp trên, chúng ta hãy bắt đầu với một thứ dễ dàng hơn một chút: một regex khớp với các chuỗi có độ dài là một hình vuông hoàn hảo. Kiểm tra chức năng khác biệt chuyển tiếp:
Có nghĩa là, lần lặp đầu tiên phải khớp với chuỗi có độ dài 1 , chuỗi thứ hai có độ dài 3 , chuỗi thứ ba có độ dài 5 , v.v. và nói chung, mỗi lần lặp phải khớp với chuỗi dài hơn hai lần so với trước. Regex tương ứng theo gần như trực tiếp từ tuyên bố này:
^(^x|\1xx)*$
Có thể thấy rằng lần lặp đầu tiên sẽ chỉ khớp với một x
lần lặp và mỗi lần lặp tiếp theo sẽ khớp với một chuỗi dài hơn hai lần trước đó, chính xác như được chỉ định. Điều này cũng ngụ ý một bài kiểm tra vuông hoàn hảo ngắn đáng kinh ngạc trong perl:
(1x$_)=~/^(^1|11\1)*$/
Regex này có thể được khái quát hóa hơn nữa để phù hợp với bất kỳ độ dài n- chéo nào:
Số tam giác:
^(^x|\1x{1})*$
Số vuông:
^(^x|\1x{2})*$
Số ngũ giác:
^(^x|\1x{3})*$
Số lục giác:
^(^x|\1x{4})*$
v.v.
f (n) = n 3
Chuyển sang n 3 , một lần nữa kiểm tra chức năng khác biệt chuyển tiếp:
Có thể không rõ ràng ngay lập tức về cách thực hiện điều này, vì vậy chúng tôi cũng kiểm tra chức năng khác biệt thứ hai:
Vì vậy, hàm khác biệt chuyển tiếp không tăng theo hằng số, mà là giá trị tuyến tính. Thật tuyệt khi giá trị ban đầu (' -1 th') của D f 2 bằng 0, giúp lưu một khởi tạo trên lần lặp thứ hai. Regex kết quả là như sau:
^((^|\2x{6})(^x|\1))*$
Lặp lại đầu tiên sẽ khớp với 1 , như trước, lần thứ hai sẽ khớp với chuỗi 6 dài hơn ( 7 ), lần lặp thứ ba sẽ khớp với chuỗi 12 dài hơn ( 19 ), v.v.
f (n) = n 4
Hàm chênh lệch chuyển tiếp cho n 4 :
Hàm khác biệt chuyển tiếp thứ hai:
Hàm khác biệt chuyển tiếp thứ ba:
Bây giờ thì xấu xí. Các giá trị ban đầu cho D f 2 và D f 3 lần lượt là khác không, 2 và 12 , sẽ cần phải được tính. Bây giờ bạn có thể nhận ra rằng regex sẽ theo mô hình này:
^((^|\2\3{b})(^|\3x{a})(^x|\1))*$
Vì D f 3 phải khớp với độ dài 12 trên lần lặp thứ hai, nên a nhất thiết phải là 12 . Nhưng vì nó tăng thêm 24 mỗi thuật ngữ, nên việc lồng sâu hơn tiếp theo phải sử dụng giá trị trước đó hai lần, ngụ ý b = 2 . Điều cuối cùng cần làm là khởi tạo D f 2 . Vì D f 2 ảnh hưởng trực tiếp đến D f , cuối cùng là thứ chúng ta muốn khớp, nên giá trị của nó có thể được khởi tạo bằng cách chèn trực tiếp nguyên tử thích hợp vào regex, trong trường hợp này (^|xx)
. Regex cuối cùng sau đó trở thành:
^((^|xx)(^|\3\4{2})(^|\4x{12})(^x|\1))*$
Đơn đặt hàng cao hơn
Một đa thức bậc 5 có thể được khớp với biểu thức chính sau:
^((^|\2\3{c})(^|\3\4{b})(^|\4x{a})(^x|\1))*$
f (n) = n 5 là một phép trừ khá dễ dàng, vì các giá trị ban đầu cho cả hai hàm chênh lệch chuyển tiếp thứ hai và thứ tư đều bằng 0:
^((^|\2\3)(^|\3\4{4})(^|\4x{30})(^x|\1))*$
Trong sáu đa thức bậc:
^((^|\2\3{d})(^|\3\4{c})(^|\4\5{b})(^|\5x{a})(^x|\1))*$
Đối với đa thức bậc 7:
^((^|\2\3{e})(^|\3\4{d})(^|\4\5{c})(^|\5\6{b})(^|\6x{a})(^x|\1))*$
v.v.
Lưu ý rằng không phải tất cả các đa thức đều có thể được khớp chính xác theo cách này, nếu bất kỳ hệ số cần thiết nào là không nguyên. Ví dụ, n 6 yêu cầu a = 60 , b = 8 và c = 3/2 . Điều này có thể được giải quyết xung quanh, trong trường hợp này:
^((^|xx)(^|\3\6\7{2})(^|\4\5)(^|\5\6{2})(^|\6\7{6})(^|\7x{60})(^x|\1))*$
Ở đây tôi đã thay đổi b thành 6 và c thành 2 , có cùng sản phẩm với các giá trị đã nêu ở trên. Điều quan trọng là sản phẩm không thay đổi, vì a · b · c · Quang điều khiển hàm chênh lệch không đổi, cho đa thức bậc sáu là D f 6 . Có hai nguyên tử khởi tạo: một để khởi tạo D f thành 2 , như với n 4 và cái còn lại để khởi tạo hàm khác biệt thứ năm thành 360 , đồng thời thêm hai từ còn thiếu từ b .