Tìm kiếm các lựa chọn thay thế ngắn hơn cho `phạm vi (Hoài)`


8

Giải pháp tốt nhất mà tôi đã tìm thấy cho đến nay cho một câu đố đang golf Tôi đang làm việc trên bao gồm hai chứ không phải chất béo tìm lời gọi của range. Tôi rất mới về môn đánh gôn, đặc biệt là về Python, vì vậy tôi có thể sử dụng một vài mẹo.

Các mảnh có liên quan là đây

[x for x in range(n+1,7**6)if`x`==`x`[::-1]*all(x%i for i in range(2,x))]

Giới hạn trên của đầu tiên rangekhông phải là một sắc nét. Nó phải có ít nhất 98.690, và tất cả con người khác bằng (golf-khôn ngoan, đó là), nhỏ hơn sự khác biệt giữa giới hạn trên và 98.690 thì càng tốt, hiệu suất-khôn ngoan 1 . Tôi đang sử dụng 7 6 (= 117649) vì đây 7**6là biểu thức Python ngắn nhất tôi có thể đưa ra phù hợp với hóa đơn.

Ngược lại, giới hạn thấp hơn trong lần đầu tiên range, cũng như cả hai giới hạn ở lần thứ hai, đều vững chắc. IOW, chương trình (ở dạng hiện tại) sẽ tạo ra kết quả không chính xác nếu những giới hạn đó được thay đổi.

Có cách nào để rút ngắn một hoặc cả hai biểu thức

range(n+1,7**6)
range(2,x)

?

BTW, trong trường hợp này, bí danh range, nói, rkhông thu được gì:

r=range;rr
rangerange

EDIT: FWIW, chương trình đầy đủ là thế này:

p=lambda n:[x for x in range(n+1,7**6)if`x`==`x`[::-1]*all(x%i for i in range(2,x))][0]

p(n)nên là số nguyên tố palindromic nhỏ nhất lớn hơn n. Ngoài ra, pkhông nên đệ quy. Cảnh báo: Nó đã chậm một cách khó hiểu!


1 Vâng, tôi biết: hiệu suất không liên quan đến môn đánh gôn, nhưng đó là lý do tại sao tôi viết "tất cả những thứ khác đều bình đẳng (đó là thông thái, đó là)". Ví dụ, sự lựa chọn của tôi 7**6, và không phải là sự thay thế rõ ràng hơn, nhưng hiệu quả kém hơn, "tương đương với golf" 9**9. Tôi thực sự muốn chạy mã golf của mình, điều đó có nghĩa là không để hiệu suất giảm xuống đến mức phải mất nhiều năm để chạy mã. Nếu tôi có thể giúp nó, tất nhiên.


1
fwiw, bạn có thể làm cho bạn nhanh hơn nhiều cho mục đích thử nghiệm bằng cách sử dụng máy phát điện; nó tương đương ngoại trừ điều đó : p=lambda n:(x for x in xrange(n+1,7**6)if`x`==`x`[::-1]*all(x%i for i in xrange(2,x))).next(). Tất nhiên, trong khi tại đó, cũng có thể thay đổi xrange(2,x)để xrange(2,int(x**.5+1))và làm thử nghiệm của bạn rất nhanh. Rõ ràng mã này tương đương với mã của bạn, chỉ dài hơn và nhanh hơn.
Justin

1
Không thể đưa ra nhiều thủ thuật chơi golf tốt với một đoạn ngắn bị cô lập khỏi bối cảnh của nó. Các chương trình chơi golf tốt nhất thường tạo ra các kết nối đáng ngạc nhiên giữa các phần khác nhau của chương trình. Ví dụ, một biến bị loại bỏ dường như vô dụng có thể chứng minh khóa hoặc hai vòng không liên quan kết hợp thành một.
frageum

@feersum: Tôi đã đăng toàn bộ (trong một EDIT) cách đây khá lâu. Đó là trước khi bạn đăng bình luận của bạn. Bạn không thấy nó à?
kjo

@FryAmTheEggman: vâng, tuyên bố của câu đố là nó phải là một hàm, và tệ hơn nữa, hàm này không thể được đệ quy.
kjo

1
Bạn có thể muốn xem tại đây
Beta Decay

Câu trả lời:


7

Làm cho nó một vòng lặp duy nhất

Như vậy, bạn có hai vòng lặp: một vòng lặp xcó thể là các số nguyên tố palindromic, một vòng lặp khác iđể kiểm tra xem có phải xlà số nguyên tố của phép chia không. Như bạn nhận thấy, các vòng lặp là Python mất nhiều ký tự, thường để viết range, nhưng cũng để viết while _:hoặc for x in _. Vì vậy, một giải pháp Python được đánh gôn nên sử dụng càng ít vòng càng tốt.

Nhận xét của frageum "Các chương trình chơi golf tốt nhất thường tạo ra các kết nối đáng ngạc nhiên giữa các phần khác nhau của chương trình" rất có thể áp dụng ở đây. Việc kiểm tra chính có thể giống như một chương trình con riêng biệtall(x%i for i in range(2,x)) là biểu thức cổ điển. Nhưng chúng ta sẽ làm theo cách khác.

Ý tưởng là sử dụng Định lý Wilson . Đối với mỗi nguyên tố tiềm năng k, chúng tôi giữ một sản phẩm đang hoạt động (k-1)!và kiểm tra xem đó có phải là bội số của không k. Chúng tôi có thể theo dõi (k-1)!trong khi chúng tôi kiểm tra tiềm năng ktrở thành những người chơi chính bằng cách giữ một sản phẩm đang chạyP .

Trên thực tế, chúng ta sẽ sử dụng phiên bản mạnh hơn của Định lý Wilson (k-1)! % kbằng 0 cho tổng hợp kvà chỉ cho các số tổng hợp, ngoại trừ k=4cho 2, và do đó chính xác (k-1)!**2 % kbằng 0với các số tổng hợp. Chúng tôi sẽ cập nhật Pđể bằng k!**2thông qua bản cập nhật P*=k*k.

(Xem câu trả lời này cho phương thức này được sử dụng để tìm các số nguyên tố trong Python.)

Để tất cả chúng cùng nhau:

def p(n):
 k=P=1
 while(`k`!=`k`[::-1])+(k<=n)+(P%k==0):P*=k*k;k+=1
 return k

Điều này chưa được đánh gôn hoàn toàn - điều kiện đặc biệt được viết không hiệu quả. Chúng ta có thể nén điều kiện để kiểm tra đó klà một bảng màu trong khi tại thời điểm đó thực thi các điều kiện khác thông qua một bất đẳng thức chuỗi.

def p(n):
 k=P=1
 while`k`*(P%k>0>n-k)!=`k`[::-1]:P*=k*k;k+=1
 return k

1
một giải pháp rực rỡ. Tôi rất biết ơn khi thấy nó, mặc dù nó đi vào một lĩnh vực ngoài tầm với của tôi ... Cho đến nay, những cải tiến của tôi trong môn đánh gôn chỉ là vấn đề chọn các thủ thuật như sử dụng backticks thay vì str, nhưng những mánh khóe này chỉ có một nhiều ... những cải tiến lớn đến từ các thuật toán tốt hơn, như mọi khi.
kjo

1
Theo giải pháp của FryAmTheEggman, người ta có thể viết lại điều kiện như `k`*(k>n)*(P%k>0)!=`k`[::-1], nó sẽ tắt 4
kjo

1
@kjo Có, và thậm chí tương tự hơn nếu bạn xâu chuỗi các bất đẳng thức thành một. Bạn cũng nên kiểm tra Python Golf Practice để xem các thủ thuật như thế này
xnor

Điều đó được thực hiện rất độc đáo! cảm ơn tất cả! đây là một chủ đề rất bắt mắt đối với tôi ... độ dài giải pháp ngắn nhất mà tôi biết, đối với Python 2.7 và 3.3 tương ứng, ngắn hơn 28 và 32 ký tự so với phiên bản tôi đã đăng ban đầu (nỗ lực tuyệt đối nhất của tôi) và Khi tôi tìm thấy về điều này, tôi đã hoài nghi; tôi nghĩ rằng phải có một số trò chơi xấu ở đâu đó (ví dụ bằng kỹ thuật đảo ngược chương trình thử nghiệm giải pháp tự động). nhưng sau khi thấy các chuyên gia ở đây nhanh chóng cạo tới 16 ký tự từ nỗ lực tốt nhất của tôi, giờ tôi sẵn sàng tin vào những con số đó.
kjo

@kjo Tôi rất vui khi bạn thấy điều kỳ diệu của môn đánh gôn. Bạn đang nói có một giải pháp 55 char? Nếu vậy, tôi tò mò. Đây có phải là một vấn đề golf vô chính phủ? Bạn có thể vui lòng liên kết với tôi để báo cáo vấn đề? Có thể có các phím tắt có thể từ các khoảng trống trong các trường hợp thử nghiệm, đặc biệt là ngoại lệ với số 4.
xnor

3

AFAIK, không thực sự.

Phạm vi thường được sử dụng trong các sân golf python vì đây là cách ngắn nhất để tạo danh sách các số tăng / giảm.

Điều đó nói rằng, nó dường như ngắn hơn một chút (7 byte) để tránh sử dụng phạm vi và thay vào đó gọi một vòng lặp while:

def p(n):
    n+=1
    while`n`*all(n%i for i in range(2,n))!=`n`[::-1]:n+=1
    return n

Cảm ơn @xnor (như mọi khi) đã cải thiện logic của điều kiện while :)


@kjo Không có rắc rối :) Bạn có thể muốn thêm những gì bạn đã nói với tôi về việc nó phải là một hàm không đệ quy cho câu hỏi, vì nếu không thì câu trả lời này khá kém;)
FryAmTheEggman

2
Bạn có thể lưu vào điều kiện bằng cách phủ nhận nó : while(`n`!=`n`[::-1])+0in(n%i for i in range(2,n)):n+=1. Tôi dường như không thể thoát khỏi cặp parens đầu tiên do các vấn đề ưu tiên của nhà điều hành.
xnor

2
Thoát khỏi parens:while`n`*all(n%i for i in range(2,n))!=`n`[::-1]:n+=1
xnor

@FryAmTheEggman: bạn rất thích thể thao! xong
kjo

1

Khi sử dụng các thuật toán lặp như phương pháp Newton hoặc tính toán fractals, trong đó bạn thường cần thực hiện các lần lặp mà không thực sự quan tâm đến chỉ mục, bạn có thể lưu một số ký tự bằng cách lặp qua các chuỗi ngắn thay thế.

for i in range(4):x=f(x)
for i in'asdf':x=f(x)

Tại bảy lần lặp này, hòa vốn với range. Để lặp lại nhiều hơn, hãy sử dụng phân tích ngược và số lượng lớn

for i in`9**9**5`:pass

Điều này chạy 56349 lần, đủ cho tất cả các mục đích thực tế. Chơi xung quanh với các số và toán tử cho phép bạn mã hóa một loạt các số theo cách này.


Mặc dù điều này rất thú vị, nhưng bạn có thể thấy khá rõ rằng anh ấy quan tâm đến chỉ số (vì ứng cử viên chính là chỉ số). Tôi nghĩ rằng điều này phù hợp hơn khi là một phần của câu trả lời này trên trang mẹo thay thế :) (Cũng lưu ý rằng '1'*4nó ngắn hơn 'asdf')
FryAmTheEggman
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.