Regex (Bản thảo), 276 205 201 193 189 byte
So sánh bội số (số mũ) của các yếu tố nguyên tố khác nhau là một vấn đề thú vị để giải quyết với biểu thức ECMAScript - việc thiếu các phản hồi tồn tại qua các vòng lặp khiến cho việc đếm bất cứ điều gì trở thành một thách thức. Ngay cả khi tính các đặc điểm số trong câu hỏi là có thể, thường thì một cách tiếp cận gián tiếp hơn làm cho golf tốt hơn.
Cũng như các bài đăng regex ECMA khác của tôi, tôi sẽ đưa ra cảnh báo spoiler: Tôi khuyên bạn nên học cách giải quyết các vấn đề toán học đơn phương trong biểu thức chính của ECMAScript. Đó là một hành trình hấp dẫn đối với tôi và tôi không muốn làm hỏng nó cho bất kỳ ai có khả năng muốn thử nó, đặc biệt là những người quan tâm đến lý thuyết số. Xem bài đăng trước đó để biết danh sách các vấn đề được đề xuất liên quan đến spoiler để giải quyết từng vấn đề một.
Vì vậy, đừng đọc thêm nữa nếu bạn không muốn một số phép thuật regex unary tiên tiến được làm hỏng cho bạn . Nếu bạn thực sự muốn tự mình tìm ra phép thuật này, tôi khuyên bạn nên bắt đầu bằng cách giải quyết một số vấn đề trong biểu thức ECMAScript như được nêu trong bài đăng được liên kết ở trên.
Trọng tải chính từ một regex mà tôi đã phát triển trước đây hóa ra rất phù hợp với thử thách này. Đó là regex tìm ra số nguyên tố có bội số cao nhất . Giải pháp đầu tiên của tôi là rất lâu và sau đó tôi đã chơi nó theo từng giai đoạn, đầu tiên viết lại nó để sử dụng cái nhìn phân tử , và sau đó chuyển nó trở lại ECMAScript đơn giản bằng cách sử dụng một kỹ thuật tiên tiến để giải quyết vấn đề thiếu cái nhìn phân tử , và sau đó đánh golf xuống nhỏ hơn nhiều so với giải pháp ECMAScript ban đầu.
Phần từ regex đó áp dụng cho vấn đề này là bước đầu tiên, tìm thấy Q, yếu tố nhỏ nhất của N chia sẻ tất cả các yếu tố chính của nó. Khi chúng ta có số này, tất cả những gì chúng ta phải làm để chỉ ra rằng N là "số mũ không đổi" được chia N cho Q cho đến khi chúng ta không thể kéo dài hơn nữa; nếu kết quả là 1, tất cả các số nguyên tố đều có bội số bằng nhau.
Sau khi gửi câu trả lời bằng thuật toán được phát triển trước đó của tôi để tìm Q, tôi nhận ra rằng nó có thể được tính theo một cách hoàn toàn khác: Tìm hệ số không vuông góc lớn nhất của N (sử dụng thuật toán tương tự như biểu thức chính số của số Carmichael của tôi ). Hóa ra, điều này không gây khó khăn gì cả * về việc bước đi xung quanh việc thiếu giao diện phân tử và giao diện có chiều dài thay đổi (không cần phải sử dụng kỹ thuật nâng cao được sử dụng trước đây) và ngắn hơn 64 byte! Ngoài ra, nó giúp loại bỏ sự phức tạp của việc xử lý N và số nguyên tố N không vuông như các trường hợp đặc biệt khác nhau, giảm thêm 7 byte từ giải pháp này.
(Vẫn còn những vấn đề khác đòi hỏi kỹ thuật tiên tiến trước đây được sử dụng để đánh bại tính toán của Q, nhưng hiện tại không có vấn đề nào được thể hiện qua các bài đăng PPCG của tôi.)
Tôi đặt bài kiểm tra bội số trước bài kiểm tra số nguyên tố liên tiếp vì bài kiểm tra chậm hơn nhiều; đặt các thử nghiệm có thể thất bại nhanh hơn trước tiên làm cho regex nhanh hơn cho đầu vào được phân phối đồng đều. Nó cũng tốt hơn để đặt nó lên hàng đầu, bởi vì nó sử dụng nhiều phản hồi hơn (sẽ tốn nhiều tiền hơn nếu chúng là hai chữ số).
Tôi đã có thể giảm 4 byte từ regex này (193 → 189) bằng một thủ thuật được tìm thấy bởi Grimy có thể rút ngắn phân chia trong trường hợp thương số được đảm bảo lớn hơn hoặc bằng số chia.
^(?=(|(x+)\2*(?=\2$))((?=(xx+?)\4*$)(?=(x+)(\5+$))\6(?!\4*$))*x$)(?=.*$\2|((?=((x*)(?=\2\9+$)x)(\8*$))\10)*x$)(?!(((x+)(?=\13+$)(x+))(?!\12+$)(x+))\11*(?=\11$)(?!(\15\14?)?((xx+)\18+|x?)$))
Hãy thử trực tuyến!
# For the purposes of these comments, the input number = N.
^
# Assert that all of N's prime factors are of equal multiplicity
# Step 1: Find Q, the largest square-free factor of N (which will also be the smallest
# factor of N that has all the same prime factors as N) and put it in \2.
# If N is square-free, \2 will be unset.
(?=
# Search through all factors of N, from largest to smallest, searching for one that
# satisfies the desired property. The first factor tried will be N itself, for which
# \2 will be unset.
(|(x+)\2*(?=\2$)) # for factors < N: \2 = factor of N; tail = \2
# Assert that tail is square-free (its prime factors all have single multiplicity)
(
(?=(xx+?)\4*$) # \4 = smallest prime factor of tail
(?=(x+)(\5+$)) # \5 = tail / \4 (implicitly); \6 = tool to make tail = \5
\6 # tail = \5
(?!\4*$) # Assert that tail is no longer divisible by \4, i.e. that that
# prime factor was of exactly single multiplicity.
)*x$
)
# Step 2: Require that either \2 is unset, or that the result of repeatedly
# dividing tail by \2 is 1.
(?=
.*$\2
|
(
# In the following division calculation, we can skip the test for divisibility
# by \2-1 because it's guaranteed that \2 <= \8. As a result, we did not need to
# capture \2-1 above, and can use a better-golfed form of the division.
(?=
( # \8 = tail / \2
(x*) # \9 = \8-1
(?=\2\9+$)
x
)
(\8*$) # \10 = tool to make tail = \8
)
\10 # tail = \8
)*
x$ # Require that the end result is 1
)
# Assert that there exists no trio of prime numbers such that N is divisible by the
# smallest and largest prime but not the middle prime.
(?!
( # \11 = a factor of N
( # \12 = a non-factor of N between \11 and \13
(x+)(?=\13+$) # \13 = a factor of N smaller than \11
(x+) # \14 = tool (with \15) to make tail = \13
)
(?!\12+$)
(x+) # \15 = tool to make tail = \12
)
\11*(?=\11$) # tail = \11
# Assert that \11, \12, and \13 are all prime
(?!
(\15\14?)? # tail = either \11, \12, or \13
((xx+)\18+|x?)$
)
)
* Nó vẫn sạch hơn với giao diện phân tử, không có trường hợp đặc biệt nào cho N không có hình vuông. Điều này giảm 6 byte, mang lại giải pháp 195 187 183 byte :
^(?=(?*(x+))\1*(?=\1$)((?=(xx+?)\3*$)(?=(x+)(\4+$))\5(?!\3*$))*x$)(?=((?=((x*)(?=\1\8+$)x)(\7*$))\9)*x$)(?!(((x+)(?=\12+$)(x+))(?!\11+$)(x+))\10*(?=\10$)(?!(\14\13?)?((xx+)\17+|x?)$))
# For the purposes of these comments, the input number = N.
^
# Assert that all of N's prime factors are of equal multiplicity
# Step 1: Find Q, the largest square-free factor of N (which will also be the smallest
# factor of N that has all the same prime factors as N) and put it in \1.
(?=
(?*(x+)) # \1 = proposed factor of N
\1*(?=\1$) # Assert that \1 is a factor of N; tail = \1
# Assert that tail is square-free (its prime factors all have single multiplicity)
(
(?=(xx+?)\3*$) # \3 = smallest prime factor of tail
(?=(x+)(\4+$)) # \4 = tail / \3 (implicitly); \5 = tool to make tail = \4
\5 # tail = \4
(?!\3*$) # Assert that tail is no longer divisible by \3, i.e. that that
# prime factor was of exactly single multiplicity.
)*x$
)
# Step 2: Require that the result of repeatedly dividing tail by \1 is 1.
(?=
(
# In the following division calculation, we can skip the test for divisibility
# by \1-1 because it's guaranteed that \2 <= \8. As a result, we did not need to
# capture \1-1 above, and can use a better-golfed form of the division.
(?=
( # \7 = tail / \1
(x*) # \8 = \7-1
(?=\1\8+$)
x
)
(\7*$) # \9 = tool to make tail = \7
)
\9 # tail = \7
)*
x$ # Require that the end result is 1
)
# Assert that there exists no trio of prime numbers such that N is divisible by the
# smallest and largest prime but not the middle prime.
(?!
( # \10 = a factor of N
( # \11 = a non-factor of N between \10 and \12
(x+)(?=\12+$) # \12 = a factor of N smaller than \10
(x+) # \13 = tool (with \14) to make tail = \12
)
(?!\11+$)
(x+) # \14 = tool to make tail = \11
)
\10*(?=\10$) # tail = \10
# Assert that \10, \11, and \12 are all prime
(?!
(\14\13?)? # tail = either \10, \11, or \12
((xx+)\17+|x?)$
)
)
Ở đây, nó được chuyển đến giao diện có chiều dài thay đổi:
Regex (ECMAScript 2018), 198 195 194 186 182 byte
^(?=(x+)(?=\1*$)(?<=^x((?<!^\5*)\3(?<=(^\4+)(x+))(?<=^\5*(x+?x)))*))((?=((x*)(?=\1\8+$)x)(\7*$))\9)*x$(?<!(?!(\14\16?)?((xx+)\12+|x?)$)(?<=^\13+)((x+)(?<!^\15+)((x+)(?<=^\17+)(x+))))
Hãy thử trực tuyến!
# For the purposes of these comments, the input number = N.
^
# Assert that all of N's prime factors are of equal multiplicity
# Step 1: Find Q, the largest square-free factor of N (which will also be the smallest
# factor of N that has all the same prime factors as N) and put it in \1.
(?=
(x+)(?=\1*$) # \1 = factor of N; head = \1
(?<= # This is evaluated right-to-left, so please read bottom to top.
^x
(
(?<!^\5*) # Assert that head is no longer divisible by \6, i.e. that
# that prime factor was of exactly single multiplicity.
\3 # head = \4
(?<=(^\4+)(x+)) # \4 = head / \5 (implicitly); \3 = tool to make head = \4
(?<=^\5*(x+?x)) # \5 = smallest prime factor of head
)*
)
)
# Step 2: Require that the result of repeatedly dividing tail by \1 is 1.
(
# In the following division calculation, we can skip the test for divisibility
# by \1-1 because it's guaranteed that \2 <= \8. As a result, we did not need to
# capture \1-1 above, and can use a better-golfed form of the division.
(?=
( # \7 = tail / \1
(x*) # \8 = \7-1
(?=\1\8+$)
x
)
(\7*$) # \9 = tool to make tail = \7
)
\9 # tail = \7
)*
x$ # Require that the end result is 1
# Assert that there exists no trio of prime numbers such that N is divisible by the
# smallest and largest prime but not the middle prime.
# This is evaluated right-to-left, so please read bottom to top, but switch back to
# reading top to bottom at the negative lookahead.
(?<!
# Assert that \13, \15, and \17 are all prime.
(?!
(\14\16?)? # tail = either \13, \15, or \17
((xx+)\12+|x?)$
)
(?<=^\13+)
( # tail = \13
(x+) # \14 = tool to make tail = \15
(?<!^\15+)
(
(x+) # \16 = tool (with \14) to make tail = \17
(?<=^\17+)(x+) # \17 = a factor of N smaller than \13
) # \15 = a non-factor of N between \13 and \17
) # \13 = a factor of N
)