Tìm số nguyên tố tiếp giáp lớn nhất trong một chuỗi


8

Công bằng mà nói, điều này dựa trên câu hỏi StackExchange - nhưng đây là một câu hỏi hay.

Thử thách khá đơn giản:

  1. Lấy một chuỗi các chữ số
  2. Tìm và in số nguyên tố tiếp giáp lớn nhất trong chuỗi

Ghi điểm:

  • Số lượng nhân vật thấp nhất sẽ thắng.
  • Victor có thể sẽ là một mục golf, nhưng chúng tôi sẽ không chống lại họ, vì tất cả chúng ta đều vui vẻ và học hỏi mọi thứ, đúng không.
  • Người chiến thắng chúng tôi được trao giải khi tôi nhận thấy rằng tôi chưa thực sự đánh dấu vào nút màu xanh lá cây.

Giả định:

  • Chuỗi chỉ là số
    • Nếu chuỗi chứa các chữ cái, bạn có thể có hành vi không xác định
  • Chuỗi chứa ít nhất 1 số nguyên tố
    • Nếu chuỗi không chứa 1 số nguyên tố hợp lệ, bạn có thể có hành vi không xác định
  • Tốc độ không phải là một hạn chế
    • Sử dụng một thuật toán nguyên tố ngắn hơn một thuật toán nhanh hơn.
    • Nếu mục nhập của bạn cuối cùng kết thúc, điều đó ổn, chỉ cần đảm bảo rằng nó sẽ có thể chứng minh được trước cái chết nhiệt của vũ trụ.
  • Độ dài của chuỗi có thể được giả sử dài dưới 15 ký tự

Ví dụ:

>> Input:  3571
<< Output: 3571

>> Input:  123
<< Output: 23

>> Input:  1236503
<< Output: 236503

>> Input:  46462
<< Output:  2

>> Input:  4684
<< Output: ValueError: max() arg is an empty sequence

>> Input:  460
<< Output: 0   # Note, zero is not a prime, but the above string has no valid prime

>> Input:  4601
<< Output: 601

>> Input:  "12 monkeys is a pretty good movie, but not as good as se7en"
<< Output: ValueError: Fight Club was also good, I find Brad Pitt to be a consistantly good actor.

Triển khai có thể:

  1. Tìm tất cả các chuỗi con của đầu vào, kiểm tra xem chúng có phải là số nguyên tố không. - Legostormtroopr (bản gốc)
  2. Tìm tất cả các số nguyên ít hơn đầu vào, kiểm tra xem chúng có trong đầu vào không, sau đó kiểm tra xem đó có phải là số nguyên tố không - Ben Reich
  3. Lấy danh sách tất cả các số nguyên tố nhỏ hơn đầu vào, kiểm tra xem nó có trong đầu vào không - daniero

1
Điều này có vẻ cơ bản giống như: tìm cách lặp lại qua từng chuỗi con của chuỗi và kiểm tra tính nguyên thủy của chuỗi con. Âm thanh như một vấn đề vui vẻ.
Justin

1
@Quincunx Đúng. Nhưng tôi muốn làm cho nó rõ ràng nhất có thể. Và cũng bỏ tham khảo văn hóa pop.

1
@Quincunx Đó không phải là thuật toán duy nhất có thể! Kiểm tra câu trả lời của tôi, có thể được mô tả là: Lặp lại tất cả các số nguyên nhỏ hơn đầu vào và xác định số lớn nhất vừa là chuỗi con của đầu vào vừa là số nguyên tố.
Ben Reich

@BenReich Hoặc như tôi đã làm, lặp đi lặp lại trên tất cả các số nguyên tố nhỏ hơn hoặc bằng với đầu vào trong và xem chúng nằm trong chuỗi.
daniero

1
Tại sao tôi quan tâm đến một sân chơi thậm chí? Chúng tôi biết kịch bản nào thắng, nhưng chiến thắng không phải là tất cả? Tạo mã ngắn nhất, thông minh nhất có thể bằng ngôn ngữ yêu thích của bạn.

Câu trả lời:


6

GolfScript 40 37

.{`\`?)}+\~),\,{.,(;\{\%!}+,,1=},)\;

Cái này nhìn vào tất cả các số nhỏ hơn hoặc bằng đầu vào, lọc xuống các số là chuỗi con của đầu vào, sau đó lọc tiếp theo các số nguyên tố. Sau đó, nó lấy phần tử lớn nhất như vậy (rõ ràng được đảm bảo có nhiều chữ số nhất).

Hãy chia nó thành hai phần chính:

.{`\`?)}+\~,\,

Phần mã này lọc xuống tất cả các chuỗi số nguyên có trong đầu vào. Nó sử dụng dấu trọng âm để biến số thành chuỗi, và sau đó ?để xác định chỉ mục của chuỗi con. Vì ?trả về -1trong trường hợp không có ngăn chặn, gia tăng sử dụng )sao cho đầu ra 0không phải là chuỗi con, sẽ hoạt động tốt với ,bộ lọc.

{.,(;\{\%!}+,,1=},

Phần mã này lọc xuống các số nguyên tố bằng cách đếm số lượng nhân tố nhỏ hơn số đã cho (một số nguyên chỉ là một yếu tố nếu number factor %!là 1. Một số nguyên tố sẽ có chính xác ít hơn 1 yếu tố 1=.

Vì các số theo thứ tự, hãy lấy số cuối cùng và xóa ngăn xếp bằng cách sử dụng )\;

Điều này rõ ràng là không hiệu quả nhất có thể (vì nó lặp đi lặp lại một cách không cần thiết trên tất cả các số nguyên ít hơn đầu vào), nhưng nó vẫn chấm dứt với đầu vào lớn như 1236503tương đối nhanh trên máy tính của tôi (1 phút).


1
Nhờ bạn, tôi đã cạo gần như nhiều câu trả lời như bạn đã sử dụng: P

1
Nếu đầu vào là số nguyên tố thì điều này sẽ không tìm thấy nó, bởi vì bộ lọc đầu tiên được áp dụng cho các số lên đến nhưng không bao gồm nó. Việc sửa chữa tốn một ký tự, nhưng có hai ký tự được lưu bằng cách lưu trữ đầu vào trong một biến thay vì nối với khối (vì cách đó giúp bạn loại bỏ một số lần lật).
Peter Taylor

4

Con trăn 2.7 - 84

Dưới đây là một triển khai tham chiếu để đánh bại, tôi đã sử dụng nó cho đầu ra ví dụ trong câu hỏi, do đó, nó đảm bảo hoạt động * Không phải là một đảm bảo thực tế

Cải thiện đáng xấu hổ dựa trên giải pháp tốt hơn nhiều so với giải pháp ban đầu của Ben Reich . Với sự hỗ trợ lớn từ Biến động

N=input()
print max(x for x in range(N+1)if(`x`in`N`)&all(x%i for i in range(2,x)))

Câu thần chú trước của dòng thứ hai bao gồm:

print max(x for x in range(N+1)if`x`in`N`and 0 not in(x%i for i in range(2,x)))
print max(x for x in range(N+1)if`x`in`N`and sum(x%i<1 for i in range(2,x))<1)

Phiên bản gốc - 143

N=`input()`
p=lambda n:[n%i for i in range(2,n)if n%i==0]
print max(int(N[j:i])for i in range(len(N)+1)for j in range(i)if not p(int(N[j:i])))

2
Loại bỏ pvà thay thế not p(x)bằng sum(x%i for i in range(2,x))<1- nó sẽ hoạt động và giúp bạn giảm xuống còn 86 ký tự.
Biến động

@Volatility Không hoàn toàn, sum(x%i for i in range(2,x))sẽ khá cao đối với hầu hết các số. Nhưng máy phát điện là một ý tưởng tuyệt vời và tôi đã đạt được nó đến 91.

Trên thực tế, bạn biết những gì, tôi nghĩ rằng bạn có thể sử dụng all(x%i for i in range(2,x))thay thế.
Biến động

Lưu thêm một lần nữa, cảm ơn :)

Chuyển sang allvà đặt dấu ngoặc vào (`x`in`N`)Lưu thêm một vài chi tiết nữa!

1

Ruby 61

Lấy tất cả các số nguyên tố lên đến N và xem chúng có trong chuỗi không

require'prime'
p Prime.each(gets.to_i).select{|i|~/#{i}/}.max

Tôi nghĩ rằng điều này chỉ hoạt động trên Ruby 1.9 và mới hơn, nhưng tôi không chắc chắn.


Chương trình của bạn trả về ví dụ kiểm tra cuối cùng là gì? Số nguyên tố, 2, nằm trong đó, nhưng không được công nhận (nếu tôi hiểu đúng các yêu cầu).
DavidC

1
@DavidCarraher: Giả định: Chuỗi chỉ là số; Nếu chuỗi chứa các chữ cái, bạn có thể có hành vi không xác định Tôi nghĩ rằng "hành vi không xác định" có nghĩa là nó có thể nhổ ra 2 hoặc nó có thể phun ra
Kyle Kanos

Kyle, quan sát rất tốt!
DavidC

1

Scala (83 ký tự)

Tôi không chắc chắn làm thế nào để cung cấp đầu vào cho chương trình vì vậy tôi coi đó nlà đầu vào. Đây là giải pháp thực tế (dựa vào đó độ dài của giải pháp được đánh giá). Dưới đây là một hình thức thực thi của giải pháp (chưa được đánh gôn) để thực hiện cùng với đầu ra (đối với các mẫu mà OP cung cấp).

Giải pháp:

n.inits.flatMap(_.tails.toList.init.map(BigInt(_))).filter(_ isProbablePrime 1).max

Giải pháp thực thi:

object A {
  def main(x:Array[String])=List("3571","123","23","1236503","46462","4684","460","4601","12 monkeys..").foreach(e=>println(e+" => "+q(e)))

  private def p(n: String)=n.inits.flatMap(_.tails.toList.init.map(BigInt(_))).filter(_ isProbablePrime 1).max
  private def q(n: String)=try p(n)catch{case e=>e.toString}
}

Đầu ra mẫu:

3571 => 3571
123 => 23
23 => 23
1236503 => 236503
46462 => 2
4684 => java.lang.UnsupportedOperationException: empty.max
460 => java.lang.UnsupportedOperationException: empty.max
4601 => 601
12 monkeys.. => java.lang.NumberFormatException: For input string: "12 "

Giải trình:

Các bước là khá thẳng về phía trước.

đầu vào -> Tìm tất cả các chuỗi con -> lọc các số nguyên tố -> tìm giá trị dài nhất

  • main(Array[String]): Phương thức cung cấp đầu vào mẫu và phương thức thực thi q(String)cho từng đầu vào
  • q(String): Kết hợp logic chương trình thực tế từ p(String)bất kỳ trường hợp ngoại lệ nào được báo cáo phù hợp. Giúp định dạng đầu ra tốt hơn vì các đầu vào không hợp lệ sẽ nhận được NumberFormatExceptions khi thiếu nguyên tố sẽ tạo ra mộtUnsupportedOperationException
  • p(String): Logic thực tế của chương trình. Hãy chia lời giải thích cho điều này thành nhiều phần
    • n.inits: Tạo một Iteratorlần lặp qua đầu vào Chuỗi ( n)
    • flatMap(f): Áp dụng một thao tác trên Iteratorvà đẩy kết quả vàoList
      • _.tails.toList.init.map(BigInt(_)): Tách Stringvà loại bỏ Strings trống từ kết quả List. Cuối cùng chuyển đổi Stringđến một BigIntmà là một tương đương java.math.BigInteger. Đối với lý do chơi golf, BigIntđược chọn (tên ngắn hơn).
    • filter(f): nếu ftrả về false, giá trị được xóa khỏi kết quảList
      • _ isProbablePrime 1: Dòng này có thể được viết dưới dạng _.isProbablePrime(1)nhưng biểu diễn được sử dụng tiết kiệm 1 byte. Dòng này thực sự kiểm tra xem giá trị có phải là số nguyên tố hay không (theo xác suất; vì certaintyđược đặt thành 1, thời gian thực hiện tăng lên nhưng hệ thống chắc chắn (ít nhiều) số đó là số nguyên tố.
    • max: Tìm giá trị tối đa (không Stringdựa trên chiều dài. Giá trị tối đa thực tế)

1

J ( 24 22)

Đọc từ bàn phím thực sự ngắn hơn so với xác định chức năng.

>./(*1&p:);".\.\1!:1[1

Kiểm tra:

   >./(*1&p:);".\.\1!:1[1
3571
3571
   >./(*1&p:);".\.\1!:1[1
46462
2
   >./(*1&p:);".\.\1!:1[1
1236503
236503
   >./(*1&p:);".\.\1!:1[1
4684
0
   >./(*1&p:);".\.\1!:1[1
4680
0
   >./(*1&p:);".\.\1!:1[1
twelve monkeys is a pretty good movie
__

Giải trình:

  • 1!:1[1: đọc một dòng văn bản từ bàn phím
  • ".\.\: đánh giá ( ".) của mỗi hậu tố ( \.) của từng tiền tố ( \) của chuỗi.
  • ;: làm phẳng ma trận
  • *1&p:: nhân từng giá trị với giá trị đó có phải là số nguyên tố hay không (vì vậy tất cả các giá trị không phải là số không)
  • >./: lấy giá trị lớn nhất trong danh sách

1

Haskell, 94

main=getLine>>=print.maximum.filter(\x->and$map((0/=).mod x)[2..x-1]).map read.init.scanr(:)[]


3
Muốn giải thích quá trình đằng sau việc này cho những người không làm Haskell?

@LegoStormtroopr Chắc chắn, tôi sẽ thử nó. main = getLine >>= print . maximum . filter isPrime . map read . allNumslà hình thức ban đầu. nó nhận được một dòng và cung cấp cho nó ( >>=) cho hàm kết hợp lớn - kết hợp với .toán tử infix, người chỉ cần đặt kết quả của hàm phải sang hàm trái. những thứ như (\x -> ...)là biểu thức lambda. tham số hàm được áp dụng mà không có dấu ngoặc đơn và các hàm có thể được áp dụng một phần ( (0/=)ví dụ: là hàm, kiểm tra nếu một số không bằng 0).
Vektorweg

allNums = init . scanr (:) []. scanrquét và init loại bỏ giá trị cuối cùng của kết quả scanr, là một chuỗi rỗng, không thể đọc được cho một Integer. map readđọc một danh sách các chuỗi đến các giá trị định mệnh của nó. trong trường hợp này là Integer hoặc một cái gì đó khác từ kiểu chữ Integral, vì isPrimecần một Integral. filter isPrimeThực hiện chính xác những gì mà nó nói. isPrime x = and $ map ((0/=). mod x) [2..(x-1)]có nghĩa là, đưa ra một danh sách từ 2 đến (x-1), thực hiện kiểm tra phân chia và sau đó áp dụng andcho danh sách Bool.
Vektorweg

có một số chức năng rõ ràng và mạnh mẽ hơn trong các mô-đun tiêu chuẩn khác, nhưng tôi đã cố gắng chỉ làm việc với mô-đun Prelude. ;)
Vektorweg

1

Perl 6 (40 ký tự, 41 byte)

$_=get;say max grep &is-prime,+«m:ex/.+/

Đầu getvào đầu tiên $_, điều này làm cho cuộc gọi regex khớp ngắn hơn. :excung cấp cho kết hợp đầy đủ cho regex, nó sẽ cung cấp cho tất cả các khả năng. Hyper op (hoặc +<<cũng hoạt động) sẽ tạo ra các số trong các đối tượng Match, chúng được truyền cho grepvới &is-primephụ làm bộ chọn. Cuối cùng lấy tối đa của danh sách còn lại và xuất nó.


0

Toán học 67 47

StringCases[#,a__/;PrimeQ@ToExpression@a]〚1〛&

Giải trình

Mã này là một hàm thuần túy. Nó không có tên. Trong đó, #đại diện cho chuỗi đầu vào đầy đủ.

StringCaseslấy đầu vào, # và kiểm tra các chuỗi con, atừ một ký tự trở lên (đó là lý do tại sao __ được sử dụng thay vì _) là các số nguyên tố; PrimeQ phải trả về True cho chuỗi con.

Tất cả các trường hợp thuận lợi, tức là các chuỗi con là số nguyên tố, theo mặc định được trả về trong một danh sách. 〚1〛hoặc [[1]]lấy phần đầu tiên, nghĩa là phần tử đầu tiên của danh sách các số nguyên tố đó. element[[1]]là tốc ký cho Part[element, 1]. Nếu có nhiều hơn một số nguyên tố, thì số đầu tiên sẽ là số nguyên tố dài nhất ( StringCaseskiểm tra các chuỗi con dài nhất trước).

Ví dụ

StringCases[#,a__/;PrimeQ@ToExpression@a]〚1〛&["1236503"]

"236503"

StringCases[#,a__/;PrimeQ@ToExpression@a]〚1〛&/@ 
{"1236503", "123", "46462", "4684", "460", "4601", 
"12 monkeys is a pretty good movie, but not as good as se7en"}

{"236503", "23", "2", {} [[1]], {} [[1]], "601", "2"}


Muốn giải thích quá trình đằng sau điều này cho những người không làm Mathicala?

1
Tôi phải nói rằng việc sử dụng các 〚1〛ký tự là tàn bạo đối với chúng tôi, phi toán học, lập trình viên. (gợi ý cho tôi một cách lo lắng rằng tôi sẽ bị mù, sau đó nhìn vào các dấu ngoặc khác với sự bối rối rằng chúng trông sắc nét, trong khi cái này thì không!)
eithed

〚1〛có dấu ngoặc kép và tương đương với [[1]]. Tôi đã sử dụng chúng bởi vì một dấu ngoặc kép được tính là một ký tự đơn.
DavidC

@David Carraher Vâng, nhưng tôi nghĩ bạn phải tính nó là hai byte để nó không thực sự giúp bạn tiết kiệm được gì.
Michael Stern

Nhưng tôi đang đếm các ký tự, không phải byte. Vui lòng giải thích.
DavidC

0

Perl 6 (50 ký tự, 51 byte)

say max +«get.match(/(.+)<?{(+$0).is-prime}>/,:ex)

ánh xạ các chuỗi thành số, maxđược số lớn nhất, getnhận được một dòng. /(.+)<?{(+$0).is-prime}>/là một biểu thức chính quy nhận được tất cả các số nguyên tố <?{}>là một xác nhận mã. is-primeIntphương thức lớp kiểm tra nếu số là số nguyên tố. Tôi cần truyền giá trị thành số bằng cách sử dụng +, bởi vì Strtheo mặc định. :excó nghĩa là nó cố gắng tìm TẤT CẢ các kết quả khớp (bao gồm cả các kết quả trùng lặp với các mục khác). Do lỗi Rakudo Perl, hiện tại không thể sử dụng m//ở đây.

Điều này hoạt động với bất kỳ số nào, và nếu bạn loại bỏ max(hoặc thay thế nó bằng sort), bạn sẽ nhận được danh sách tất cả các số nguyên tố trong số đó, để nhận thêm tiền thưởng (không phải điều này cho điểm, hoặc bất cứ điều gì). Ví dụ (với sorttrong trường hợp này):

1234567890
2 3 5 7 23 67 89 4567 23456789
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.