Đây có phải là số nguyên tố?


195

Dù bạn có tin hay không, chúng ta vẫn chưa có một thử thách golf mã cho một bài kiểm tra nguyên thủy đơn giản . Mặc dù nó có thể không phải là thử thách thú vị nhất, đặc biệt đối với các ngôn ngữ "thông thường", nó có thể không cần thiết trong nhiều ngôn ngữ.

Mã Rosetta có các danh sách theo ngôn ngữ của các cách tiếp cận thành ngữ để kiểm tra tính nguyên thủy, một cách sử dụng thử nghiệm Miller-Rabin cụ thể và một cách khác sử dụng phân chia thử nghiệm . Tuy nhiên, "thành ngữ nhất" thường không trùng với "ngắn nhất". Trong nỗ lực biến Câu đố lập trình và Code Golf trở thành trang web dành cho môn đánh gôn, thử thách này tìm cách biên soạn một danh mục về cách tiếp cận ngắn nhất trong mọi ngôn ngữ, tương tự như "Xin chào, Thế giới!" Golf bạn một quine cho tốt tuyệt vời! .

Hơn nữa, khả năng thực hiện kiểm tra tính nguyên thủy là một phần định nghĩa của chúng tôi về ngôn ngữ lập trình , do đó, thách thức này cũng sẽ đóng vai trò là một thư mục của các ngôn ngữ lập trình đã được chứng minh.

Bài tập, nhiệm vụ

Viết một chương trình đầy đủ , với một số nguyên dương n nghiêm ngặt làm đầu vào, xác định xem n là số nguyên tố và in một giá trị trung thực hoặc sai lệch tương ứng.

Đối với mục đích của thử thách này, một số nguyên là số nguyên tố nếu nó có chính xác hai ước số dương. Lưu ý rằng điều này loại trừ 1 , người là ước số duy nhất tích cực.

Thuật toán của bạn phải có tính xác định (nghĩa là tạo ra đầu ra chính xác với xác suất 1) và theo lý thuyết, nên hoạt động cho các số nguyên lớn tùy ý. Trong thực tế, bạn có thể giả định rằng đầu vào có thể được lưu trữ trong loại dữ liệu của bạn, miễn là chương trình hoạt động cho các số nguyên từ 1 đến 255.

Đầu vào

  • Nếu ngôn ngữ của bạn có thể đọc từ STDIN, chấp nhận đối số dòng lệnh hoặc bất kỳ hình thức nhập khác của người dùng, bạn có thể đọc số nguyên dưới dạng biểu diễn thập phân của nó, biểu diễn đơn nhất (sử dụng ký tự bạn chọn), mảng byte (lớn hoặc ít endian) hoặc byte đơn (nếu đây là loại dữ liệu lớn nhất trong ngôn ngữ của bạn).

  • Nếu (và chỉ nếu) ngôn ngữ của bạn không thể chấp nhận bất kỳ loại đầu vào nào của người dùng, bạn có thể mã hóa cứng đầu vào trong chương trình của mình.

    Trong trường hợp này, số nguyên được mã hóa cứng phải dễ dàng trao đổi. Đặc biệt, nó có thể chỉ xuất hiện ở một nơi duy nhất trong toàn bộ chương trình.

    Để ghi điểm, hãy gửi chương trình tương ứng với đầu vào 1 .

Đầu ra

Đầu ra phải được ghi vào STDOUT hoặc thay thế gần nhất.

Nếu có thể, đầu ra chỉ nên bao gồm một giá trị trung thực hoặc sai lệch (hoặc biểu diễn chuỗi của nó), tùy ý theo sau bởi một dòng mới.

Ngoại lệ duy nhất cho quy tắc này là đầu ra liên tục của trình thông dịch ngôn ngữ của bạn không thể bị loại bỏ, chẳng hạn như lời chào, mã màu ANSI hoặc thụt lề.

Quy tắc bổ sung

  • Đây không phải là tìm kiếm ngôn ngữ với cách tiếp cận ngắn nhất để kiểm tra chính, đây là tìm kiếm cách tiếp cận ngắn nhất trong mọi ngôn ngữ. Do đó, không có câu trả lời sẽ được đánh dấu là chấp nhận.

  • Đệ trình trong hầu hết các ngôn ngữ sẽ được ghi bằng byte theo mã hóa có sẵn từ trước, thường (nhưng không nhất thiết) UTF-8.

    Ví dụ, ngôn ngữ Piet sẽ được ghi bằng codel, đây là lựa chọn tự nhiên cho ngôn ngữ này.

    Một số ngôn ngữ, như Thư mục , có một chút khó khăn để ghi điểm. Nếu nghi ngờ, xin vui lòng hỏi về Meta .

  • Không giống như các quy tắc thông thường của chúng tôi, vui lòng sử dụng ngôn ngữ (hoặc phiên bản ngôn ngữ) ngay cả khi nó mới hơn thử thách này. Nếu bất cứ ai muốn lạm dụng điều này bằng cách tạo ra một ngôn ngữ trong đó chương trình trống thực hiện kiểm tra tính nguyên thủy, thì xin chúc mừng bạn đã mở đường cho một câu trả lời rất nhàm chán.

    Lưu ý rằng phải có một thông dịch viên để trình có thể được kiểm tra. Được phép (và thậm chí được khuyến khích) tự viết trình thông dịch này cho một ngôn ngữ chưa được thực hiện trước đó.

  • Nếu ngôn ngữ bạn chọn là một biến thể tầm thường của ngôn ngữ khác (có khả năng phổ biến hơn) đã có câu trả lời (nghĩ phương ngữ BASIC hoặc SQL, shell Unix hoặc dẫn xuất Brainfuck tầm thường như Headsecks hoặc Unary), hãy xem xét thêm ghi chú vào câu trả lời hiện có cùng một hoặc một giải pháp rất giống nhau cũng là ngắn nhất trong ngôn ngữ khác.

  • Các chức năng tích hợp để kiểm tra tính nguyên thủy được cho phép. Thử thách này có nghĩa là lập danh mục giải pháp ngắn nhất có thể có trong mỗi ngôn ngữ, vì vậy nếu sử dụng ngôn ngữ tích hợp trong ngôn ngữ của bạn ngắn hơn, hãy sử dụng nó.

  • Trừ khi chúng được ghi đè trước đó, tất cả các quy tắc tiêu chuẩn sẽ được áp dụng, bao gồm http://meta.codegolf.stackexchange.com/q/1061 .

Là một lưu ý phụ, xin vui lòng không downvote câu trả lời nhàm chán (nhưng hợp lệ) trong các ngôn ngữ không có nhiều để chơi golf; những câu hỏi này vẫn hữu ích cho câu hỏi này vì nó cố gắng biên dịch một danh mục đầy đủ nhất có thể. Tuy nhiên, chủ yếu thực hiện các câu trả lời trong các ngôn ngữ mà tác giả thực sự phải nỗ lực để đánh gôn.

Mục lục

Đoạn trích Stack ở cuối bài đăng này tạo ra danh mục từ các câu trả lời a) dưới dạng danh sách các giải pháp ngắn nhất cho mỗi ngôn ngữ và b) dưới dạng bảng xếp hạng tổng thể.

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề, sử dụng mẫu Markdown sau:

## Language Name, N bytes

nơi Nlà kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh bại chúng thông qua. Ví dụ:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Nếu bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vì điểm của bạn là tổng của hai tệp hoặc bạn muốn liệt kê riêng các hình phạt cờ của thông dịch viên), hãy đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề:

## Perl, 43 + 2 (-p flag) = 45 bytes

Bạn cũng có thể đặt tên ngôn ngữ thành liên kết sau đó sẽ hiển thị trong đoạn trích:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


Tôi có thể lấy đầu vào làm số âm không, trong đó abs (đầu vào) sẽ là số tôi đang kiểm tra?
Stan Strum

Không, đầu vào là một số nguyên dương hoàn toàn.
Dennis

1
@LyndonWhite Điều này được dự định là một danh mục (như của Hello Hello, Thế giới!, Bài kiểm tra tính nguyên thủy, vì vậy một định dạng đệ trình thống nhất có vẻ thích hợp hơn. Đó là một trong hai quyết định về thử thách này mà tôi rất tiếc, cái còn lại chỉ cho phép thử nghiệm tính nguyên thủy xác định.
Dennis

1
@Shaggy Có vẻ như là một câu hỏi cho meta.
Dennis

1
Vâng, đó là những gì tôi đã nghĩ. Tôi sẽ cho phép bạn làm vinh dự, coi đó là thử thách của bạn.
Xù xì

Câu trả lời:


226

Chào thế giới! , 13

hello, world!

83
Bạn, giống như, chỉ cần tạo ngôn ngữ này, chỉ cho trình này? ;)
Sản phẩm điện tử

41
@ETHproductions Hình như cam kết mới nhất là 10 ngày trước.
Geobits

39
Tôi đã hy vọng có ngôn ngữ ở trạng thái tốt hơn một chút trước khi liên kết với nó ở bất cứ đâu, nhưng thử thách này đã được đăng và tôi không thể cưỡng lại.
lịch sử

31
Tôi gần như sẽ nói rằng treo trên đầu vào 1 là chức năng chính xác.
iamnotmaynard

22
Phần tốt nhất về điều này là chương trình không chỉ là một chương trình tích hợp, mỗi nhân vật đóng một phần của riêng mình để có được kết quả chính xác.
Sản xuất ETH

157

Lục giác , 29 byte

.?'.).@@/'/.!.>+=(<.!)}($>(<%

Phiên bản dễ đọc của mã này là:

   . ? ' .
  ) . @ @ /
 ' / . ! . >
+ = ( < . ! )
 } ( $ > ( <
  % . . . .
   . . . .

Giải thích: Nó kiểm tra nếu có một số từ 2 đến n-1 người chia n.

Khởi tạo:

Viết n vào một ô nhớ và n-1 trong một ô khác:

   . ? ' .
  . . . . .
 . . . . . .
+ = ( . . . .
 . . . . . .
  . . . . .
   . . . .

Trường hợp đặc biệt n = 1:

In 0 và chấm dứt

   . . . .
  . . . @ .
 . . . ! . .
. . . < . . .
 . . . . . .
  . . . . .
   . . . .

Vòng lặp

Tính n% a và giảm a. Chấm dứt nếu a = 1 hoặc n% a = 0.

   . . . .
  ) . . . /
 ' / . . . >
. . . . . . .
 } ( $ > ( <
  % . . . .
   . . . .

Trường hợp a = 1:

Tăng 0 lên 1, in và chấm dứt. (Con trỏ lệnh chạy theo hướng NE và các vòng từ góc phía đông đến góc phía tây nam. Và $ đảm bảo rằng nó bỏ qua lệnh tiếp theo)

   . . . .
  . . . @ .
 . . . ! . .
. . . < . . )
 . . $ . . <
  . . . . .
   . . . .

Trường hợp a% n = 0:

In 0 và chấm dứt (Con trỏ lệnh đang chạy SW và vòng lặp lên đầu đến @

   . . . .
  . . @ . .
 . . . . . >
. . . . . ! .
 . . . . . .
  . . . . .
   . . . .

61
Holy crap, đó là một bài viết đầu tiên ấn tượng. :) Tôi sẽ đưa tiền thưởng ngay bây giờ (Tôi sẽ trao thưởng sau 7 ngày, để thu hút sự chú ý hơn vào câu trả lời của bạn). Chào mừng đến với PPCG!
Martin Ender

35
Câu trả lời chính xác! +1 cho " Phiên bản có thể đọc được của mã này là: <...> " :-)
bất cứ lúc nào

68

Lục giác , 218 92 58 55 byte

Lưu ý: Câu trả lời này đã được đánh mạnh mẽ bằng giải pháp 4 chiều dài của Etoplay.

)}?}.=(..]=}='.}.}~./%*..&.=&{.<......=|>(<..}!=...&@\[

Chương trình Hexagony đầu tiên không tầm thường (tức là phi tuyến tính)! Nó dựa trên cách tiếp cận bình phương giống như câu trả lời Mê cung của Sp3000 . Sau khi bắt đầu với một hình lục giác có kích thước 10, tôi đã quản lý để nén nó xuống kích thước 5. Tuy nhiên, tôi đã có thể sử dụng lại một số mã trùng lặp và vẫn còn khá nhiều mã không có mã, vì vậy kích thước 4 có thể chỉ có khả năng.

Giải trình

Để hiểu được mã, trước tiên chúng ta cần mở ra. Hexagony đệm bất kỳ mã nguồn nào cho số lục giác trung tâm tiếp theo với no-ops ( .) 61. Sau đó, nó sắp xếp lại mã thành một hình lục giác thông thường có kích thước tương ứng:

     ) } ? } .
    = ( . . ] =
   } = ' . } . }
  ~ . / % * . . &
 . = & { . < . . .
  . . . = | > ( <
   . . } ! = . .
    . & @ \ [ .
     . . . . .

Điều này khá nặng nề với các đường dẫn thực hiện chéo và chồng chéo và nhiều con trỏ lệnh (IP). Để giải thích cách thức hoạt động của nó, trước tiên chúng ta hãy xem xét một phiên bản không được chỉnh sửa trong đó luồng điều khiển không đi qua các cạnh, chỉ có một IP được sử dụng và các đường dẫn thực hiện càng đơn giản càng tốt:

             . . . . . . . . . . . . .
            . . . . . . . . . . . . . .
           . . . . . . . . . . . . . . .
          . . . . . . . . . . @ . . . . .
         . . . . . . . . . . ! . . . . . .
        . . . . . . . . . . % . . . . . . .
       . . . . . . . . . . ' . . . . . . . .
      . . . . . . . . . . & . . . . . . . . .
     . . . . . . . . . . { . . . . . . . . . .
    . . . . . . . . . . * . . . . . . . . . . .
   . . . . . . . . . . = . . . . . . . . . . . .
  . . . . . . . . . . } . . . . . . . . . . . . .
 ) } ? } = & { < . . & . . . . . . . . . . . . . .
  . . . . . . . > ( < . . . . . . . . . . . . . .
   . . . . . . = . . } . . . . . . . . . . . . .
    . . . . . } . . . = . . . . . . . . . . . .
     . . . . | . . . . | . . . . . . . . . . .
      . . . . * . . . ) . . . . . . . . . . .
       . . . . = . . & . . . . . . . . . . .
        . . . . > } < . . . . . . . . . . .
         . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . .
           . . . . . . . . . . . . . . .
            . . . . . . . . . . . . . .
             . . . . . . . . . . . . .

Lưu ý bên lề: đoạn mã trên bắt đầu bằng việc thực thi dòng đầu tiên, chứa đầy các lệnh không hoạt động. Sau đó, khi IP chạm vào rìa phía đông bắc, nó sẽ nằm ở góc ngoài cùng bên trái (nơi )), nơi mã thực tế bắt đầu.

Trước khi chúng tôi bắt đầu, một từ về bố cục bộ nhớ của Hexagony. Nó hơi giống băng của Brainfuck trên steroid. Trên thực tế, đó không phải là một cuộn băng, mà chính là một lưới lục giác (một vô hạn), trong đó mỗi cạnh có một giá trị nguyên, ban đầu là 0 (và trái ngược với Brainfuck tiêu chuẩn, các giá trị được ký các số nguyên có độ chính xác tùy ý). Đối với chương trình này, chúng tôi sẽ sử dụng bốn cạnh:

nhập mô tả hình ảnh ở đây

Chúng tôi sẽ tính toán giai thừa trên mép Một , đếm ngược đầu vào của chúng tôi trên mép C và lưu trữ một bản sao của các đầu vào (đối với modulo) trên mép D . B được sử dụng như một cạnh tạm thời cho các tính toán.

Con trỏ bộ nhớ (MP) bắt đầu ở cạnh A và chỉ về hướng bắc (điều này rất quan trọng để di chuyển MP xung quanh). Bây giờ đây là bit đầu tiên của mã:

)}?}=&{

)tăng cạnh A thành 1cơ sở của giai thừa. }làm cho MP rẽ phải, tức là di chuyển đến cạnh C (chỉ về hướng đông bắc). Ở đây chúng tôi đọc đầu vào là một số nguyên với ?. Sau đó, chúng tôi rẽ phải sang cạnh D với }. =đảo ngược MP, như vậy mà nó trỏ vào đỉnh chia sẻ với C . &sao chép giá trị từ C (đầu vào) vào D - giá trị được sao chép từ bên trái vì giá trị hiện tại là không dương (không). Cuối cùng, chúng tôi làm cho MP rẽ trái trở lại C với {.

Tiếp theo, <về mặt kỹ thuật là một nhánh, nhưng chúng tôi biết rằng giá trị hiện tại là dương, vì vậy IP sẽ luôn rẽ phải về phía >. Chi nhánh nhấn từ các hành vi bên như một tấm gương, như vậy mà IP di chuyển theo chiều ngang một lần nữa, về phía (, mà decrements giá trị trong C .

Các chi nhánh tiếp theo, <thực sự một chi nhánh bây giờ. Đây là cách chúng tôi lặp từ n-1xuống đến 1. Trong khi giá trị hiện tại trong C là dương, IP sẽ rẽ phải (để thực hiện vòng lặp). Khi chúng ta chạm 0, nó sẽ rẽ trái.

Chúng ta hãy nhìn vào "cơ thể" vòng lặp. Đây |là những chiếc gương đơn giản, ><cũng được sử dụng làm gương một lần nữa. Điều đó có nghĩa là cơ thể vòng lặp thực sự sôi xuống

}=)&}=*}=

}di chuyển MP sang cạnh B , =đảo ngược hướng của nó để đối mặt với đỉnh ABC . )tăng giá trị: điều này chỉ phù hợp với lần lặp đầu tiên, trong đó giá trị của B vẫn bằng 0: chúng tôi muốn đảm bảo rằng nó dương, sao cho lệnh tiếp theo &sao chép đúng hàng xóm, tức là A , tức là giá trị hiện tại của giai thừa tính toán, vào B .

}sau đó di chuyển MP sang A , =đảo ngược nó một lần nữa để đối mặt với đỉnh chung. *nhân với cả hàng xóm, tức là cạnh BC và lưu trữ các kết quả trong một . Cuối cùng, chúng ta có một cái khác }=để trở về C , vẫn đối mặt với đỉnh ABC .

Tôi hy vọng bạn có thể thấy cách này tính giai thừa của n-1trong Một .

Vì vậy, bây giờ chúng ta đã làm điều đó, bộ đếm vòng lặp trong C bằng không. Chúng tôi muốn bình phương giai thừa và sau đó lấy modulo với đầu vào. Đó là những gì mã này làm:

&}=*{&'%!@

Kể từ khi C là số không, &bản sao những người hàng xóm bên trái, tức là giai thừa trong Một . }=*chuyển sang B và lưu trữ các sản phẩm của hai bản sao của giai thừa (tức là hình vuông) trong B . {di chuyển trở lại C , nhưng không đảo ngược MP. Chúng ta biết rằng giá trị hiện tại bây giờ là tích cực, vì vậy &bản đầu vào từ D vào C . 'MP ngược bên phải, tức là vào Một . Hãy nhớ rằng, bình phương của giai thừa là tại B và đầu vào là trong C . Vì vậy, %tính toán (n-1)!^2 % n, chính xác những gì chúng ta đang tìm kiếm.!in kết quả dưới dạng số nguyên (0 hoặc 1) và @chấm dứt chương trình.


Được rồi, nhưng đó là phiên bản vô văn hóa. Còn phiên bản chơi golf thì sao? Bạn cần biết thêm hai điều về Hexagony:

  1. Các cạnh bao quanh. Nếu IP chạm một cạnh của hình lục giác, nó sẽ nhảy sang cạnh đối diện. Điều này không rõ ràng khi IP chạm thẳng vào một góc, do đó, việc đánh vào một góc cũng đóng vai trò như một nhánh: nếu giá trị hiện tại là dương, IP sẽ nhảy sang cạnh lưới bên phải, nếu không thì sang bên trái.
  2. Thực tế có 6 IP. Mỗi người trong số họ bắt đầu ở một góc khác nhau, di chuyển dọc theo cạnh theo chiều kim đồng hồ. Mỗi lần chỉ có một trong số họ hoạt động, điều đó có nghĩa là bạn có thể bỏ qua 5 IP khác nếu bạn không muốn. Bạn có thể chuyển sang IP tiếp theo (theo thứ tự theo chiều kim đồng hồ) với ]và trước đó với IP trước [. (Bạn cũng có thể chọn một địa chỉ cụ thể với #, nhưng đó là vào thời điểm khác.)

Ngoài ra còn có một vài lệnh mới trong đó: \/là các gương như thế |, và ~nhân giá trị hiện tại lên -1.

Vậy làm thế nào để phiên bản không được dịch cho người chơi golf? Mã thiết lập tuyến tính )}?}=&{và cấu trúc vòng lặp cơ bản có thể được tìm thấy ở đây:

        ) } ? } .  ->
       . . . . . .
      . . . . . . .
     . . . . . . . .
->  . = & { . < . . .
     . . . . . > ( <
      . . . . . . .
       . . . . . .
        . . . . .

Bây giờ thân vòng lặp đi qua các cạnh một vài lần, nhưng quan trọng nhất là tính toán thực tế được chuyển sang IP trước đó (bắt đầu ở góc bên trái, di chuyển theo hướng đông bắc):

        ) . . . .
       = . . . ] .
      } = . . } . .
     ~ . / . * . . .
    . . . . . . . . .
     . . . = . > ( <
      . . } . = . .
       . & . \ [ .
        . . . . .

Sau khi bật ra khỏi nhánh về phía đông nam, IP quấn quanh rìa đến hai =góc ở góc trên bên trái (mà cùng với nhau là một no-op), sau đó bật ra khỏi /. Việc ~đảo ngược dấu hiệu của giá trị hiện tại, điều này rất quan trọng cho các lần lặp lại tiếp theo. IP bao bọc xung quanh cùng một lần nữa và cuối cùng đạt đến [nơi kiểm soát được bàn giao cho IP khác.

Cái này bây giờ thực thi ~}=)&}=*}mà không xóa bỏ phủ định và sau đó chỉ chạy phần thân vòng lặp không có dấu (trừ đi =). Cuối cùng, nó chạm vào ]tay nào điều khiển trở lại IP ban đầu. . thay vì phía đông nam.)

Khi IP ban đầu tiếp tục điều khiển, nó sẽ bật ra \, thực hiện phần còn lại =và sau đó nhấn >để đưa vào vòng lặp tiếp theo.

Bây giờ phần thực sự điên rồ: điều gì xảy ra khi vòng lặp chấm dứt?

        ) . . . .
       . ( . . ] =
      . . ' . } . }
     . . . % * . . &
    . . . . . . . . .
     . . . = | . . <
      . . } ! . . .
       . & @ . . .
        . . . . .

IP di chuyển theo hướng đông bắc <và quấn quanh theo đường chéo phía đông bắc. Vì vậy, nó kết thúc trên cùng một đường dẫn thực thi với thân vòng lặp ( &}=*}]). Điều này thực sự khá tuyệt, bởi vì đó chính xác là mã chúng tôi muốn thực thi tại thời điểm này, ít nhất là nếu chúng tôi thêm mã khác =}(vì }=}tương đương với {). Nhưng làm thế nào để điều này không thực sự đi vào vòng lặp trước đó một lần nữa? Bởi vì ]những thay đổi đối với IP tiếp theo hiện là IP (chưa được sử dụng) bắt đầu ở góc trên bên phải, di chuyển về phía tây nam. Từ đó, IP tiếp tục dọc theo cạnh, kết thúc ở góc trên cùng bên trái, di chuyển xuống đường chéo, bật ra |và chấm dứt @trong khi thực hiện bit cuối cùng của mã tuyến tính:

=}&)('%!@

(Tất nhiên )(là không có - tôi phải thêm ()nó đã có sẵn.)

Phù ... thật là một mớ hỗn độn ...


Đẹp! Làm thế nào mới này? Ngoài ra, bạn có thể muốn tạo một trang esolang bất cứ khi nào bạn có được một bản phát hành ổn định
mbomb007

18
@ mbomb007 Tôi đã triển khai ngôn ngữ này hai ngày trước (và đã thiết kế nó hơn hai hoặc ba ngày trước đó). Và vâng, tôi chắc chắn sẽ thêm một trang esolang, nhưng tôi nghĩ rằng thông số kỹ thuật chưa ổn định 100% (vẫn còn 3 lệnh chưa được gán). Khi tôi cảm thấy rằng nó ổn định hơn, tôi sẽ thêm nó vào cả esolang và bài meta của chúng tôi.
Martin Ender

Dưới hex mở rộng, nó được bọc ở góc ngoài cùng bên trái (the 1) . Bạn 1đang nói gì về đó?
mbomb007

@ mbomb007 cố định. Đã )từng là a 1.
Martin Ender

5
+1 chỉ cho mức độ chi tiết trong giải thích của bạn về cách thức hoạt động. Nếu nhiều ngôn ngữ đi kèm với một ví dụ chi tiết nhiều người có thể sử dụng chúng: D
jdarling

66

Bình thường, 4 byte

}QPQ

In Truehoặc False.


12
Tôi biết rằng điều này đã cũ nhưng bây giờ bạn cũng có thể làm điều đó như thế này: P_Q và lưu 1 byte.
drobilc

14
Bây giờ có thể vớiP_
Blue

3
@drobilc Bạn có thể cắt Q, dưới dạng EOF khi hàm đang mong đợi một đối số, nó sử dụng đầu vào
Stan Strum

55

Võng mạc , 16 byte

^(?!(..+)\1+$)..

Hãy thử trực tuyến!

Hãy bắt đầu với một cổ điển: phát hiện các số nguyên tố với biểu thức chính quy . Đầu vào phải được đưa ra một cách đơn nhất , sử dụng bất kỳ ký tự có thể in lặp lại. Bộ thử nghiệm bao gồm một chuyển đổi từ thập phân sang đơn nguyên để thuận tiện.

Một chương trình Retina bao gồm một dòng duy nhất coi dòng đó là regex và in số lượng khớp được tìm thấy trong đầu vào, sẽ là 0 dành cho các số tổng hợp và 1cho các số nguyên tố.

Lookahead đảm bảo rằng đầu vào không phải là hỗn hợp: quay lui sẽ thử mọi chuỗi con có thể (ít nhất là 2 ký tự) (..+), sau đó lookahead cố gắng khớp với phần còn lại của đầu vào bằng cách lặp lại những gì đã chụp ở đây. Nếu điều này là có thể, điều đó có nghĩa là đầu vào có ước số lớn hơn 1, nhưng nhỏ hơn chính nó. Nếu đó là trường hợp tiêu cực làm cho trận đấu thất bại. Đối với các số nguyên tố không có khả năng như vậy, và trận đấu tiếp tục.

Vấn đề duy nhất là cái nhìn này cũng chấp nhận 1, vì vậy chúng tôi loại trừ điều đó bằng cách khớp ít nhất hai ký tự với ...


Đó thực sự là một biểu thức bất quy tắc, vì các số nguyên tố không tạo thành một ngôn ngữ thông thường.
PyRulez

@PyRulez Hầu hết các hương vị regex trong thế giới thực mạnh hơn rất nhiều so với khái niệm lý thuyết về các biểu thức thông thường. Tôi đã cải thiện từ ngữ mặc dù.
Martin Ender

1
Các động cơ "regex" mạnh nhất hiện đang mở có khả năng nhận dạng tương đương với động cơ tự động giới hạn tuyến tính. Regex vấn đề tiêu chuẩn, đệ quy mẫu, giao diện không giới hạn và giao diện không giới hạn là tất cả những gì bạn cần để phân tích cú pháp theo ngữ cảnh (mặc dù phản hồi và như vậy thường giúp làm phức tạp việc phân tích cú pháp hiệu quả) và một số có tất cả. Đừng để tôi bắt đầu với các công cụ cho phép bạn nhúng mã vào biểu thức chính quy.
eaglgenes101

52

CJam, 4 byte

qimp

CJam có một toán tử tích hợp để thử nghiệm tính nguyên thủy.


18
Ngoài ra:limp
Sp3000

43
pimpcjam của tôi
flawr

12
pimpkhách quan hơn là ma cô
MickLH

1
Bạn cũng có thể làml~mp
Bò lang băm

12
@Cyoce, qđọc một dòng đầu vào, iphân tích cú pháp dưới dạng số nguyên và mpđược tích hợp sẵn. CJam có hai nhóm tích hợp hai char: nhóm "mở rộng" bắt đầu evà nhóm "toán học" bắt đầum
Peter Taylor

48

HTML + CSS, tối đa 254 + n * 28 byte

Chúng ta có thể kiểm tra tính nguyên thủy bằng cách sử dụng các biểu thức thông thường. Mozilla có @document, được định nghĩa là:

@document [ <url> | url-prefix(<string>) | domain(<string>) | regexp(<string>) ]# {
  <group-rule-body>
}

Để lọc các yếu tố thông qua CSS dựa trên URL hiện tại. Đây là một lần duy nhất, vì vậy chúng tôi phải thực hiện hai bước:

  1. Nhận đầu vào từ người dùng. Đầu vào này bằng cách nào đó phải được phản ánh trong URL hiện tại.
  2. Trả lời người dùng bằng mã càng ít càng tốt.

1. Bắt đầu vào

Cách ngắn nhất tôi có thể tìm để nhận đầu vào và chuyển nó vào URL là một GET biểu mẫu với các hộp kiểm. Đối với regex, chúng ta chỉ cần một số chuỗi duy nhất để đếm số lần xuất hiện.

Vì vậy, chúng tôi bắt đầu với điều này (61 byte):

<div id=q><p id=r>1<p id=s>0</div><form method=GET action=#q>

Chúng tôi có hai <p>s duy nhất để cho biết số đã nhập có phải là số nguyên tố (1) hay không (0). Chúng tôi cũng xác định hình thức và đó là hành động.

Tiếp theo là n hộp kiểm tối đa có cùng tên (n max * 28 byte):

<input type=checkbox name=i>

Tiếp theo là phần tử gửi (34 byte):

<input name=d value=d type=submit>

2. Hiển thị câu trả lời

Chúng tôi cần CSS (159 byte) để chọn <p>hiển thị (1 hoặc 0):

#q,#s,#q:target{display:none}#q:target{display:block}@-moz-document regexp(".*\\?((i=on&)?|(((i=on&)(i=on&)+?)\\4+))d=d#q$"){#s{display:block}#r{display:none}}

»Hãy thử tại codepen.io (chỉ firefox)


12
+1: Đây là hành vi lạm dụng HTML yêu thích mọi thời đại của tôi và là thứ khiến tôi yêu thích codegolf.
con mèo

Điều này chắc chắn rất thú vị, nhưng tôi không chắc liệu nó có thỏa mãn các quy tắc của thử thách này hay không. Cụ thể, tôi không nghĩ rằng nó tuân thủ thuật toán của bạn [...], theo lý thuyết, nên hoạt động cho các số nguyên lớn tùy ý. Bạn không thể sử dụng regex trên giá trị của trường đầu vào sao?
Dennis

@Dennis Có lẽ. Có lẽ là thậm chí. Nhưng điều đó sẽ không giải quyết được vấn đề bạn đề cập. Tôi để nó ở đây như một mục không cạnh tranh, bởi vì đây là thử thách về chủ đề nhất cho điều đó.
mınxomaτ

Tại sao không? Nếu bạn có một số unary trong trường đầu vào, mã của bạn sẽ không còn phụ thuộc vào số tối đa.
Dennis

5
Hừm, tôi đã nghĩ về điều này nhiều hơn một chút và thực sự không có sự khác biệt giữa việc chỉ có x hộp kiểm và trình thông dịch chỉ có số y-bit. Bỏ qua bình luận trước đây của tôi.
Dennis


40

Lục giác , 28 byte

Etoplay hoàn toàn phản bội tôi về câu hỏi này , tôi cảm thấy rằng tôi phải vượt qua câu trả lời khác của anh ấy .

?\.">"!*+{&'=<\%(><.*.'(@>'/

Hãy thử trực tuyến!

Tôi sử dụng Định lý Wilson, giống như Martin đã làm trong câu trả lời của mình : Cho n, tôi xuất(n-1!)² mod n

Ở đây, chương trình đã mở ra:

   ? \ . "
  > " ! * +
 { & ' = < \
% ( > < . * .
 ' ( @ > ' /
  . . . . .
   . . . .

Và đây là phiên bản dễ đọc :

Rất dễ đọc

Giải trình:

Chương trình có ba bước chính: Khởi tạo , Nhân tốĐầu ra .

Mô hình bộ nhớ của Hexagony là một lưới lục giác vô hạn. Tôi đang sử dụng 5 vị trí bộ nhớ, như thể hiện trong sơ đồ này:

Ký ức

Tôi sẽ đề cập đến các vị trí này (và các số nguyên được lưu trữ trong chúng) bằng nhãn của chúng trên sơ đồ đó.

Khởi tạo:

Khởi tạo

Con trỏ lệnh ( IP ) bắt đầu ở góc trên cùng bên trái, đi về hướng Đông. Con trỏ bộ nhớ ( MP ) bắt đầu ở IN .

Đầu tiên, ?đọc số từ đầu vào và lưu nó vào IN . Các IP nằm trên con đường màu xanh, thể hiện qua \. Trình tự "&(di chuyển MP trở lại và sang trái (sang A ), sao chép giá trị từ IN sang A và giảm giá trị của nó.

Các IP sau đó thoát ra một mặt của hình lục giác và tái đi vào phía bên kia (vào con đường màu xanh lá cây). Nó thực thi '+trong đó di chuyển các MP để B và bản sao những gì đã ở A . <chuyển hướng IP sang phía tây.

Yếu tố:

Tôi tính giai thừa theo một cách cụ thể, để bình phương nó dễ dàng. Tôi lưu trữ n-1!trong cả BC như sau.

yếu tố

Con trỏ lệnh bắt đầu trên đường dẫn màu xanh, hướng về phía Đông.

='đảo ngược hướng của MP và di chuyển nó ngược trở lại để C . Điều này tương đương với {=nhưng có được =nó hữu ích sau này.

&{bản sao giá trị từ A đến C , sau đó di chuyển MP trở lại Một . Các IP sau đó đi theo con đường màu xanh lá cây, không làm gì, trước khi đến con đường đỏ, đánh \và đi vào con đường màu da cam.

Với (>, chúng tôi giảm A và chuyển hướng IP East. Ở đây, nó chạm vào một nhánh : <. Đối với A tích cực , chúng tôi tiếp tục dọc theo con đường màu cam. Nếu không thì IP sẽ được hướng Đông Bắc.

'*di chuyển MP để B và lưu trữ Một * C trong B . Đây là (n-1)*(n-2)nơi đầu vào ban đầu n. Các IP sau đó đi vào trở lại vào vòng lặp ban đầu và tiếp tục decrementing và nhân cho đến khi A đạt 0. (tính toán n-1!)

NB : Trên các vòng lặp sau, &lưu giá trị từ B trong C , dưới dạng C có giá trị dương được lưu trữ trong đó. Điều này là rất quan trọng để tính giai thừa.

Đầu ra:

Đầu ra

Khi A đạt tới 0. Chi nhánh chỉ đạo IP dọc theo đường dẫn màu xanh thay thế.

=*đảo ngược MP và lưu trữ các giá trị của B * C trong Một . Sau đó, IP thoát khỏi hình lục giác và nhập lại vào đường dẫn màu xanh lá cây; thi công "%. Thao tác này sẽ chuyển MP sang OUT và tính toán A mod IN , hoặc (n-1!)² mod n.

Các {"hoạt động sau đây là không hoạt động, vì chúng triệt tiêu lẫn nhau. !in đầu ra cuối cùng và *+'(được thực hiện trước khi chấm dứt : @.

Sau khi thực hiện, (với đầu vào là 5) bộ nhớ trông như thế này:

Bộ nhớ2

Những hình ảnh đẹp của dòng điều khiển được thực hiện bằng cách sử dụng Hexagony Coloror của Timwi's .

Cảm ơn Martin Ender vì đã tạo ra tất cả các hình ảnh, vì tôi không thể làm điều đó trên PC của mình.


Bạn đang sử dụng những gì cho các sơ đồ bộ nhớ? Tôi đã xem IDE bí truyền nhưng tôi không thể chạy nó ...
NieDzejkob

@NieDzejkob tốt hơn hết là bạn nên hỏi Martin trong trò chuyện, vì dù sao anh ấy cũng làm chúng cho tôi.
H.PWiz

@NieDzejkob Vâng, sơ đồ bộ nhớ có thể được xuất từ ​​EsoIDE. chat.stackexchange.com/rooms/27364/ cấp nếu bạn muốn trò chuyện thêm về điều này.
Martin Ender

34

Lưỡi liềm Mornington , 2448 byte

Chúng tôi sẽ trở lại London!

Take Northern Line to Bank
Take Circle Line to Bank
Take District Line to Parsons Green
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upney
Take District Line to Hammersmith
Take Circle Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Circle Line to Victoria
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take Circle Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Victoria
Take Circle Line to Temple
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Victoria
Take Circle Line to Aldgate
Take Circle Line to Victoria
Take Circle Line to Victoria
Take District Line to Upminster
Take District Line to Embankment
Take Circle Line to Embankment
Take Northern Line to Angel
Take Northern Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Aldgate
Take Circle Line to Cannon Street
Take District Line to Upney
Take District Line to Cannon Street
Take District Line to Acton Town
Take District Line to Acton Town
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Hammersmith
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Ruislip
Take Piccadilly Line to Ruislip
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Aldgate
Take Circle Line to Aldgate
Take Circle Line to Cannon Street
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Mornington Crescent

Timwi đã rất tốt khi triển khai các trạm lưu lượng điều khiển TempleAngeltrong IDE bí truyền cũng như thêm phân tích cú pháp đầu vào và số nguyên vào đặc tả ngôn ngữ.

Cái này có lẽ được chơi golf tốt hơn "Xin chào, Thế giới!", Vì lần này tôi đã viết một kịch bản CJam để giúp tôi tìm ra con đường ngắn nhất giữa hai trạm bất kỳ. Nếu bạn muốn sử dụng nó (mặc dù tôi không biết tại sao mọi người muốn ...), bạn có thể sử dụng trình thông dịch trực tuyến . Dán mã này:

"Mornington Crescent"
"Cannon Street"
]qN/{'[/0=,}$:Q;{Q{1$#!}=\;_oNo'[/1>{']/0="[]"\*}%}%:R;NoQ{R\f{f{\#)}:+}:*},N*

Ở đây hai dòng đầu tiên là các trạm bạn muốn kiểm tra. Ngoài ra, dán nội dung của pastebin này vào cửa sổ đầu vào.

Đầu ra sẽ hiển thị cho bạn dòng nào khả dụng tại hai trạm và sau đó là danh sách tất cả các trạm kết nối hai trạm, được sắp xếp theo độ dài của tên trạm. Nó hiển thị tất cả trong số chúng, bởi vì đôi khi tốt hơn là sử dụng tên dài hơn, vì nó cho phép một dòng ngắn hơn hoặc vì trạm đặc biệt (như Ngân hàng hoặc Đền thờ) nên bạn muốn tránh nó. Có một số trường hợp cạnh mà hai trạm không được kết nối bởi bất kỳ trạm nào khác (đáng chú ý là các đường Metropolitan và Quận không bao giờ giao nhau), trong trường hợp đó, bạn sẽ phải tìm ra điều gì khác. ;)

Đối với mã MC thực tế, nó dựa trên cách tiếp cận bình phương như nhiều câu trả lời khác vì MC có phép nhân, chia và modulo. Ngoài ra, tôi hình dung rằng một vòng lặp sẽ thuận tiện.

Một vấn đề là các vòng lặp là các vòng lặp do, và giảm dần và tăng là tốn kém, vì vậy tôi không thể dễ dàng tính toán (n-1)!(cho n > 0). Thay vào đó, tôi đang tính toán n!và sau đó chia ncho cuối. Tôi chắc chắn có một giải pháp tốt hơn cho việc này.

Khi tôi bắt đầu viết bài này, tôi đã hình dung rằng việc lưu trữ -1trong Hammersmith sẽ là một ý tưởng hay để tôi có thể giảm giá rẻ hơn, nhưng cuối cùng, điều này có thể có chi phí cao hơn tiết kiệm. Nếu tôi tìm thấy sự kiên nhẫn để làm lại điều này, tôi có thể thử chỉ giữ một -1xung quanh trong Upminster để tôi có thể sử dụng Hammersmith cho một cái gì đó hữu ích hơn.


10
London turing đã hoàn thành chưa?
Rohan Jhunjhunwala

1
@RohanJhunjhunwala có lẽ
Martin Ender

Ồ Tôi thích nhìn thấy những câu hỏi cũng nghĩ ra. Tôi đặc biệt thích nhìn thấy những câu hỏi mà bạn phải viết một chương trình để viết một chương trình.
Rohan Jhunjhunwala

27

Brachylog (V2), 1 byte

Hãy thử trực tuyến!

Brachylog (V1), 2 byte

#p

Điều này sử dụng vị ngữ tích hợp #p - Prime , ràng buộc đầu vào của nó là số nguyên tố.

Brachylog là nỗ lực của tôi trong việc tạo ra phiên bản Code Golf của Prolog, đó là ngôn ngữ golf mã khai báo sử dụng quay lui và hợp nhất.

Giải pháp thay thế không tích hợp: 14 byte

ybbrb'(e:?r%0)

Đây là một sự cố của mã ở trên:

y            The list [0, …, Input]
bbrb         The list [2, …, Input - 1]
'(           True if what's in the parentheses cannot be proven; else false
     e           Take an element from the list [2, …, Input - 1]
     :?r%0       The remainder of the division of the Input but that element is 0
)

1
Bạn cũng có thể muốn chỉnh sửa phiên bản Brachylog 2 này vào bài viết, bây giờ cú pháp ngắn hơn một byte.

1
@ ais523 Đúng, xong.
Gây tử vong

Brachylog 2 có trả lời hoãn thử thách không?
Scott Milner

1
@ScottMilner Có, nhưng điều này được cho phép rõ ràng trong thử thách này: "Không giống như các quy tắc thông thường của chúng tôi, hãy thoải mái sử dụng ngôn ngữ (hoặc phiên bản ngôn ngữ) ngay cả khi nó mới hơn thử thách này"
Fatalize

26

Haskell, 49 byte

Sử dụng hệ quả của xnor cho Định lý Wilson :

main=do n<-readLn;print$mod(product[1..n-1]^2)n>0

Nó sẽ không ngắn hơn để làm gì main=interact$\n-> ...?
John Dvorak

2
Ngược lại, không! Hãy xem xét rằng bạn cần interact...readở đó một nơi nào đó, điều này làm cho nó dài hơn nhiều so với chỉ readLn. Thông thường doký hiệu có thể ngắn gọn hơn bạn mong đợi, đặc biệt khi thay thế là lambda.
Lynn

24

Mê cung , 29 byte

1
?
:
}  +{%!@
(:'(
 } {
 :**

Đọc một số nguyên từ STDIN và đầu ra ((n-1)!)^2 mod n. Định lý Wilson khá hữu ích cho thử thách này.

Chương trình bắt đầu ở góc trên bên trái, bắt đầu bằng 1 nhân số đỉnh của ngăn xếp lên 10 và thêm 1. Đây là cách xây dựng số lượng lớn của Labyrinth, nhưng vì các ngăn xếp của Labyrinth chứa đầy số không, nên hiệu ứng cuối cùng như thể chúng ta chỉ cần đẩy 1.

?sau đó đọc ntừ STDIN và :sao chép nó. }chuyển nsang ngăn xếp phụ, được sử dụng ở cuối cho modulo. (sau đó giảmn và chúng tôi đã sẵn sàng để bắt đầu tính giai thừa bình phương.

Thứ hai của chúng tôi : (trùng lặp) nằm ở một ngã ba, và ở đây các tính năng điều khiển luồng của Labyrinth được sử dụng. Tại một điểm nối sau khi một lệnh được thực thi, nếu đỉnh của ngăn xếp là dương, chúng ta rẽ phải, đối với âm, chúng ta rẽ trái và về 0, chúng ta đi thẳng về phía trước. Nếu bạn cố xoay nhưng va vào tường, Labyrinth sẽ khiến bạn rẽ theo hướng khác.

n = 1, vì đỉnh của ngăn xếp bị ngiảm, hoặc 0, chúng ta đi thẳng về phía trước. Sau đó, chúng tôi đạt được một no-op 'theo sau bởi một sự sụt giảm khác (đặt chúng tôi vào -1. Điều này là âm, vì vậy chúng tôi rẽ trái, thực hiện dấu +cộng ( -1 + 0 = -1), {để chuyển ntrở lại từ ngăn xếp phụ sang chính và %modulo ( -1 % 1 = 0). Sau đó, chúng tôi đầu ra với !và chấm dứt với @.

n > 1, ở giây thứ hai :chúng ta rẽ phải. Sau đó, }chúng tôi chuyển bộ đếm vòng lặp được sao chép của mình sang ngăn xếp phụ, nhân đôi :và nhân hai lần **, trước khi chuyển bộ đếm trở lại {và giảm dần (. Nếu chúng tôi vẫn tích cực, chúng tôi sẽ cố rẽ phải nhưng không thể, vì vậy Labyrinth khiến chúng tôi rẽ trái, tiếp tục vòng lặp. Mặt khác, đỉnh của ngăn xếp là bộ đếm vòng lặp của chúng tôi đã được giảm xuống 0, mà chúng tôi +thêm vào tính toán của chúng tôi ((n-1)!)^2. Cuối cùng, chúng tôi thay đổi ntrở lại với {sau đó modulo %, đầu ra !và chấm dứt @.

Tôi đã nói rằng đó 'là một no-op, nhưng nó cũng có thể được sử dụng để gỡ lỗi. Chạy với -dcờ để xem trạng thái của ngăn xếp mỗi khi 'vượt qua!


2
Bình phương giai thừa là một mẹo thực sự hay :)
Lynn

@Mauris Cảm ơn! Tôi cần phải cung cấp tín dụng khi đến hạn - tôi lần đầu tiên nhìn thấy mánh khóe được sử dụng bởi xnor tại đây
Sp3000

5
Yay, câu trả lời Labyrinth đầu tiên không phải do tôi viết! :)
Martin Ender

24

Tiện ích Bash + GNU, 16

  • 4 byte được lưu nhờ @Dennis

  • Lưu 2 byte nhờ @Lekensteyn

factor|awk NF==2

Đầu vào là một dòng được lấy từ STDIN. Đầu ra là chuỗi rỗng cho falsey và chuỗi không trống cho sự thật. Ví dụ:

$ ./pr.sh <<< 1
$ ./pr.sh <<< 2
2: 2
$ ./pr.sh <<< 3
3: 3
$ ./pr.sh <<< 4
$

2
Thật tuyệt, đã học về một coreutil khác. Bạn có thể tách hai ký tự bằng cách đếm số lượng trường:factor|awk NF==2
Lekensteyn

@Lekensteyn - cảm ơn - vì một số lý do tôi đã bỏ lỡ bình luận của bạn trước đó :)
Chấn thương kỹ thuật số

Tôi sẽ đăng một cái gì đó tương tự, chỉ lâu hơn và không có AWK. Làm rất tốt
David Conrad

21

Java, 126 121 byte

Tôi đoán chúng ta cần một câu trả lời Java cho bảng điểm ... vì vậy đây là một vòng phân chia thử nghiệm đơn giản:

class P{public static void main(String[]a){int i=2,n=Short.valueOf(a[0]);for(;i<n;)n=n%i++<1?0:n;System.out.print(n>1);}}

Như thường lệ đối với Java, yêu cầu "chương trình đầy đủ" làm cho điều này lớn hơn nhiều so với nếu nó là một hàm, chủ yếu là do mainchữ ký.

Ở dạng mở rộng:

class P{
    public static void main(String[]a){
        int i=2,n=Short.valueOf(a[0]);
        for(;i<n;)
            n=n%i++<1?0:n;
        System.out.print(n>1);
    }
}

Chỉnh sửa: Đã sửa và lấy lại bởi Peter trong các bình luận. Cảm ơn!


Buggy: nó báo cáo rằng 1là số nguyên tố. Nếu không, sẽ có một tiết kiệm 4 char bằng cách loại bỏ pvà nóifor(;i<n;)n=n%i++<1?0:n;System.out.print(n>0);
Peter Taylor

2
OTOH class P{public static void main(String[]a){int i=2,n=Short.valueOf(a[0]);for(;i<n;)n=n%i++<1?0:n;System.out.print(n>1);}}hoạt động
Peter Taylor

6
thay đổi dòng 3 thành 'dài i = 2, n = Long.valueOf (a [0]); `dẫn đến không thay đổi về độ dài nhưng phạm vi đầu vào hợp lệ rộng hơn.
James K Polk

4
Thay vì .valueOfbạn có thể sử dụng new, như trong new Short(a[0]), hoặc new Long(a[0]), ngắn hơn một chút.
ECS

3
Bạn có thể lưu 4 byte bằng cách sử dụng một giao diện và bỏ công cụ publicsửa đổi.
RamenChef

18

Brain-Flak , 112 108 byte

({}[()]){((({})())<>){{}<>(({}<(({}[()])()<>)>)<>)<>{({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}}}<>{{}}([]{})

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Ban đầu, ngăn xếp thứ nhất sẽ chứa một số nguyên dương n , ngăn xếp thứ hai sẽ trống.

Chúng tôi bắt đầu bằng cách giảm n như sau.

(
  {}      Pop n.
  [()]    Yield -1.
)       Push n - 1.

n = 1

Nếu n = 1 bằng 0, vòng lặp while

{
  ((({})())<>)
  {
    {}<>(({}<(({}[()])()<>)>)<>)<>{({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}
  }
}

được bỏ qua hoàn toàn. Cuối cùng, mã còn lại được thực thi.

<>    Switch to the second stack (empty).
{}    Pop one of the infinite zeroes at the bottom.
{<>}  Switch stacks while the top on the active stack is non-zero. Does nothing.
(
  []    Get the length of the active stack (0).
  {}    Pop another zero.
)     Push 0 + 0 = 0.

n> 1

Nếu n - 1 khác không, chúng ta nhập vòng lặp mà n = 1 bỏ qua. Nó không phải là một vòng lặp "thực sự"; mã chỉ được thực hiện một lần. Nó đạt được những điều sau đây.

{                   While the top of the active stack is non-zero:
  (
    (
      ({})                Pop and push n - 1.
      ()                  Yield 1.
    )                   Push n - 1 + 1 = n.
    <>                  Switch to the second stack. Yields 0.
  )                   Push n + 0 = n.
                      We now have n and k = n - 1 on the first stack, and n on
                      the second one. The setup stage is complete and we start
                      employing trial division to determine n's primality.
  {                   While the top of the second stack is non-zero:
    {}                  Pop n (first run) or the last modulus (subsequent runs),
                        leaving the second stack empty.
    <>                  Switch to the first stack.
    (
      (
        {}                  Pop n from the first stack.
        <
          (
            (
              {}              Pop k (initially n - 1) from the first stack.
              [()]            Yield -1.
            )               Push k - 1 to the first stack.
            ()              Yield 1.
            <>              Switch to the second stack.
          )               Push k - 1 + 1 = k on the second stack.
        >               Yield 0.
      )               Push n + 0 = n on the second stack.
      <>              Switch to the first stack.
    )               Push n on the first stack.
    <>              Switch to the second stack, which contains n and k.
                    The first stack contains n and k - 1, so it is ready for
                    the next iteration.
    {({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}  Compute and push n % k.
  }               Stop if n % k = 0.
}               Ditto.

n% k được tính bằng thuật toán mô đun 42 byte từ câu trả lời kiểm tra khả năng phân chia của tôi .

Cuối cùng, chúng tôi giải thích các kết quả để xác định tính nguyên thủy của n .

<>    Switch to the first stack, which contains n and k - 1, where k is the
      largest integer that is smaller than n and divides n evenly.
      If (and only if) n > 1 is prime, k = 1 and (thus) k - 1 = 0.
{     While the top of the first stack is non-zero:
  {}    Pop it.
}     This pops n if n is prime, n and k - 1 if n is composite.
(
  []    Yield the height h of the stack. h = 1 iff n is prime).
  {}    Pop 0.
)     Push h + 0 = h.

2
Bạn không cần phải bật 0 cuối cùng trên ngăn xếp, vì số 1 trung thực trên đầu là đủ; bạn có thể lưu hai byte theo cách đó bằng cách loại bỏ cuối cùng {}.
Steven H.

1
Hừm, tôi rách nát. Một mặt, câu hỏi nói rằng đầu ra chỉ nên bao gồm một giá trị trung thực hoặc giả và 1 0hai giá trị. Mặt khác, chúng tôi sẽ chấp nhận các mảng miễn là ngôn ngữ coi chúng là sự thật hoặc giả và nhiều mục ngăn xếp là thứ gần nhất mà Brain-Flak phải đối mặt với mảng. Có thể có giá trị đưa điều này đến meta.
Dennis

Tôi đã xác minh với người tạo ra Brain-Flak 1 0là sự thật. chat.stackexchange.com/transcript/message/32746241#32746241
Steven H.

3
Thảo luận meta có liên quan: Sự thật trong Brain-Flak và các ngôn ngữ dựa trên stack tương tự
Dennis

17

R, 37 29 byte

n=scan();cat(sum(!n%%1:n)==2)

Sử dụng bộ phận dùng thử. scan()đọc một số nguyên từ STDIN và cat()ghi vào STDOUT.

Chúng tôi tạo ra một vectơ có độ dài nbao gồm các số nguyên 1 đến nmodulo n. Chúng tôi kiểm tra xem mỗi là 0 bằng cách phủ định (! giá trị có ), trả về giá trị logic có đúng khi số đó bằng 0 và sai khi nó lớn hơn 0. Tổng của một vectơ logic là số phần tử thực và cho các số nguyên tố mà chúng tôi mong đợi các mô đun khác không duy nhất là 1 và ndo đó chúng tôi hy vọng tổng là 2.

Đã lưu 8 byte nhờ flodel!


Với f=function(x)sum(!x%%1:x)==2bạn có thể làm điều đó trong 28 byte.
Mutador

2
@ AndréMuta Đối với thử thách này, tất cả các bài nộp phải là chương trình đầy đủ thay vì chỉ là các chức năng. Nhờ đề nghị mặc dù.
Alex A.

17

TI-BASIC, 12 byte

2=sum(not(fPart(Ans/randIntNoRep(1,Ans

Khá đơn giản. randIntNoRep(cho một hoán vị ngẫu nhiên của tất cả các số nguyên từ 1 đến Ans.

Điều này uốn cong các quy tắc một chút; bởi vì danh sách trong TI-BASIC bị giới hạn ở 999 yếu tố tôi đã giải thích

giả sử rằng đầu vào có thể được lưu trữ trong kiểu dữ liệu của bạn

như có nghĩa là tất cả các kiểu dữ liệu có thể được giả sử để chứa đầu vào. OP đồng ý với cách giải thích này.

Một giải pháp 17 byte thực sự hoạt động lên đến 10 ^ 12 hoặc hơn:

2=Σ(not(fPart(Ans/A)),A,1,Ans

@toothbrush TI-BASIC là một ngôn ngữ được mã hóa , vì vậy mỗi mã thông báo ở đây là một byte, ngoại trừ randIntNoRep(hai byte .
lirtosiast

+1 Ah, tôi chưa bao giờ thấy TL-BASIC trước đây. Cảm ơn đã cho tôi biết
Bàn chải đánh răng

1
Mặc dù, nó một chút không công bằng, đúng không ...? Tôi nên viết một ngôn ngữ chơi gôn chỉ cần 1-4 byte (ID câu hỏi) và sau đó là các tham số. Nó sẽ chọn câu trả lời hàng đầu bằng ngôn ngữ mà nó hiểu, thực hiện nó (truyền bất kỳ tham số nào) và trả về kết quả ... Tôi tự hỏi liệu điều đó có vi phạm quy tắc không? :-)
Bàn chải đánh răng

@tooth Brush Để bảo vệ TI-BASIC: đối với người phiên dịch, không công bằng hơn các lệnh một ký tự của Pyth và CJam, và TI-BASIC dễ đọc hơn.
lirtosiast

1
Thật. Tôi không thích những loại ngôn ngữ đó, vì các giải pháp trong hầu hết các ngôn ngữ khác đều dài hơn ... mặc dù gần đây tôi đã đánh bại CJam bằng VB6 ! : -]
Bàn chải đánh răng

15

PARI / GP, 21 byte

print(isprime(input))

Hoạt động cho các đầu vào lớn một cách lố bịch, bởi vì loại điều này là những gì PARI / GP được tạo ra cho.


6
isprimekhông có bằng chứng nguyên thủy APR-CL, do đó làm chậm khá nhiều vì đầu vào rất lớn. ispseudoprime(input)thực hiện một bài kiểm tra chính có thể xảy ra AES BPSW, sẽ nhanh hơn nhiều cho hơn 100 chữ số. Vẫn chưa có phản ứng mẫu nào được biết đến sau 35 năm. Phiên bản 2.1 trở về trước của Pari, từ trước năm 2002, sử dụng một phương pháp khác có thể dễ dàng đưa ra kết quả sai, nhưng không ai nên sử dụng phương pháp đó.
DanaJ

15

TI-BASIC, 24 byte

Lưu ý rằng các chương trình TI-Basic sử dụng hệ thống mã thông báo, vì vậy việc đếm các ký tự không trả về giá trị byte thực tế của chương trình.

Upvote câu trả lời của Thomas Kwa , nó là vượt trội.

:Prompt N
:2
:While N≠1 and fPart(N/Ans
:Ans+1
:End
:N=Ans

Mẫu vật:

N=?1009
                         1
N=?17
                         1
N=?1008
                         0
N=?16
                         0

Bây giờ trả về 0nếu không phải là số nguyên tố, hoặc 1nếu có.


3
Không phải căn bậc hai chỉ là một tối ưu hóa mà bạn không thực sự cần cho chương trình là chính xác sao?
Martin Ender

Tại sao bạn cần phải chia cho hai?
Geobits

Tôi luôn thích câu trả lời TI-BASIC.
Grant Miller

15

Mèo xếp chồng , 62 + 4 = 66 byte

*(>:^]*(*>{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}*<)]*(:)*=<*)>]

Cần được chạy với các -lncờ dòng lệnh (do đó +4 byte). In 0cho số tổng hợp và 1cho số nguyên tố.

Hãy thử trực tuyến!

Tôi nghĩ rằng đây là chương trình Stack Mèo không tầm thường đầu tiên.

Giải trình

Giới thiệu về Stack Stack nhanh chóng:

  • Stack Mèo hoạt động trên một băng vô hạn của các ngăn xếp, với một đầu băng chỉ vào một ngăn xếp hiện tại. Mỗi ngăn xếp ban đầu được lấp đầy với một số lượng không giới hạn. Nói chung tôi sẽ bỏ qua các số không này trong từ ngữ của tôi, vì vậy khi tôi nói "đáy của ngăn xếp" tôi có nghĩa là giá trị khác không thấp nhất và nếu tôi nói "ngăn xếp trống rỗng", ý tôi là chỉ có các số không trên đó.
  • Trước khi chương trình bắt đầu, a -1được đẩy lên ngăn xếp ban đầu, và sau đó toàn bộ đầu vào được đẩy lên trên đó. Trong trường hợp này, do-n cờ, đầu vào được đọc dưới dạng số nguyên thập phân.
  • Vào cuối chương trình, ngăn xếp hiện tại được sử dụng cho đầu ra. Nếu có một cái -1ở phía dưới, nó sẽ bị bỏ qua. Một lần nữa, do-n cờ, các giá trị từ ngăn xếp được in đơn giản dưới dạng số nguyên thập phân được phân tách bằng dòng.
  • Stack Mèo là một ngôn ngữ chương trình có thể đảo ngược: mọi đoạn mã đều có thể được hoàn tác (không có Stack Mèo theo dõi lịch sử rõ ràng). Cụ thể hơn, để đảo ngược bất kỳ đoạn mã nào, bạn chỉ cần phản chiếu nó, ví dụ như <<(\-_)trở thành (_-/)>>. Mục tiêu thiết kế này đặt ra các hạn chế khá nghiêm trọng đối với các loại toán tử và cấu trúc luồng điều khiển tồn tại trong ngôn ngữ và loại chức năng nào bạn có thể tính toán trên trạng thái bộ nhớ chung.
  • Trên hết, mọi chương trình Stack Mèo phải tự đối xứng. Bạn có thể nhận thấy rằng đây không phải là trường hợp của mã nguồn trên. Đây là những gì -lcờ dành cho: nó hoàn toàn phản chiếu mã bên trái, sử dụng ký tự đầu tiên cho trung tâm. Do đó chương trình thực tế là:

    [<(*>=*(:)*[(>*{[[>[:<[>>_(_-<<(-!>)>(>-)):]<^:>!->}<*)*[^:<)*(>:^]*(*>{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}*<)]*(:)*=<*)>]
    

Lập trình hiệu quả với toàn bộ mã rất không tầm thường và không trực quan và chưa thực sự tìm ra cách con người có thể làm điều đó. Chúng tôi đã buộc phải lập trình như vậy cho các nhiệm vụ đơn giản hơn, nhưng sẽ không thể đến bất cứ nơi nào gần đó bằng tay. May mắn thay, chúng tôi đã tìm thấy một mô hình cơ bản cho phép bạn bỏ qua một nửa chương trình. Mặc dù điều này chắc chắn là không tối ưu, nhưng hiện tại đây là cách duy nhất được biết để lập trình hiệu quả trong Stack Mèo.

Vì vậy, trong câu trả lời này, mẫu của mẫu đã nói là mẫu này (có một số thay đổi trong cách thực hiện):

[<(...)*(...)>]

Khi chương trình bắt đầu, băng ngăn xếp trông như thế này (đối với đầu vào 4, giả sử):

     4    
... -1 ...
     0
     ^

Việc [di chuyển đỉnh của ngăn xếp sang trái (và đầu băng dọc) - chúng tôi gọi đây là "đẩy". Và <di chuyển đầu băng một mình. Vì vậy, sau hai lệnh đầu tiên, chúng ta đã gặp tình huống này:

...   4 -1 ...
    0 0  0
    ^

Bây giờ, (...)một vòng lặp có thể được sử dụng khá dễ dàng như một điều kiện: vòng lặp được nhập và chỉ còn lại khi đỉnh của ngăn xếp hiện tại là dương. Vì hiện tại nó bằng không, chúng tôi bỏ qua toàn bộ nửa đầu của chương trình. Bây giờ lệnh trung tâm là *. Điều này chỉ đơn giản XOR 1, tức là nó bật một chút ít quan trọng nhất của đỉnh ngăn xếp và trong trường hợp này biến 0thành 1:

... 1 4 -1 ...
    0 0  0
    ^

Bây giờ chúng ta bắt gặp hình ảnh phản chiếu của (...). Lần này phía trên cùng của ngăn xếp là tích cực và chúng tôi làm nhập mã. Trước khi chúng tôi xem xét những gì diễn ra bên trong dấu ngoặc đơn, hãy để tôi giải thích cách chúng tôi kết thúc ở cuối: chúng tôi muốn đảm bảo rằng ở cuối khối này, chúng tôi lại có đầu băng trên một giá trị dương (để vòng lặp kết thúc sau một lần lặp duy nhất và được sử dụng đơn giản như một điều kiện tuyến tính), rằng ngăn xếp bên phải giữ đầu ra và bên phải ngăn xếp đó giữ a -1. Nếu đó là trường hợp, chúng tôi rời khỏi vòng lặp, >di chuyển lên giá trị đầu ra và ]đẩy nó lên -1để chúng tôi có một ngăn xếp sạch cho đầu ra.

Đó là điều đó. Bây giờ bên trong dấu ngoặc đơn, chúng ta có thể làm bất cứ điều gì chúng ta muốn kiểm tra tính nguyên thủy miễn là chúng ta đảm bảo rằng chúng ta thiết lập mọi thứ như được mô tả trong đoạn trước ở cuối (có thể dễ dàng thực hiện với một số thao tác đẩy và băng đầu). Lần đầu tiên tôi thử giải quyết vấn đề với định lý của Wilson nhưng kết thúc tốt hơn 100 byte, bởi vì tính toán giai đoạn bình phương thực sự khá tốn kém trong Stack Mèo (ít nhất là tôi đã không tìm thấy một cách ngắn). Vì vậy, tôi đã đi với bộ phận thử nghiệm thay thế và điều đó thực sự đơn giản hơn nhiều. Hãy nhìn vào bit tuyến tính đầu tiên:

>:^]

Bạn đã thấy hai trong số các lệnh đó. Ngoài ra, :hoán đổi hai giá trị trên cùng của ngăn xếp hiện tại và ^XOR giá trị thứ hai thành giá trị trên cùng. Điều này tạo ra :^một mô hình chung để nhân đôi một giá trị trên một ngăn xếp trống (chúng ta kéo một số 0 lên trên giá trị và sau đó biến số 0 thành 0 XOR x = x). Vì vậy, sau này, phần băng của chúng tôi trông như thế này:

         4    
... 1 4 -1 ...
    0 0  0
         ^

Thuật toán phân chia thử nghiệm mà tôi đã triển khai không hoạt động cho đầu vào 1, vì vậy chúng ta nên bỏ qua mã trong trường hợp đó. Chúng tôi có thể dễ dàng ánh xạ 1tới 0và mọi thứ khác theo các giá trị tích cực *, vì vậy đây là cách chúng tôi làm điều đó:

*(*...)

Đó là chúng ta biến 1thành 0, bỏ qua một phần lớn của mã nếu chúng ta thực sự nhận được 0, nhưng bên trong chúng ta ngay lập tức hoàn tác *để chúng ta lấy lại giá trị đầu vào. Chúng ta chỉ cần đảm bảo một lần nữa rằng chúng ta kết thúc một giá trị dương ở cuối dấu ngoặc đơn để chúng không bắt đầu lặp. Trong điều kiện, chúng ta di chuyển một ngăn xếp đúng với >và sau đó bắt đầu vòng phân chia thử nghiệm chính:

{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}

Dấu ngoặc (trái ngược với dấu ngoặc đơn) xác định một loại vòng lặp khác: đó là vòng lặp do-while, nghĩa là nó luôn chạy trong ít nhất một lần lặp. Sự khác biệt khác là điều kiện kết thúc: khi vào vòng lặp Stack Cat ghi nhớ giá trị trên cùng của ngăn xếp hiện tại ( 0trong trường hợp của chúng tôi). Vòng lặp sau đó sẽ chạy cho đến khi cùng một giá trị này được nhìn thấy ở cuối vòng lặp. Điều này thuận tiện cho chúng tôi: trong mỗi lần lặp, chúng tôi chỉ cần tính phần còn lại của ước số tiềm năng tiếp theo và di chuyển nó lên ngăn xếp này, chúng tôi sẽ bắt đầu vòng lặp. Khi chúng ta tìm thấy một ước số, phần còn lại là 0và vòng lặp dừng lại. Chúng tôi sẽ thử các ước số bắt đầu từ n-1và sau đó giảm chúng xuống 1. Điều đó có nghĩa là a) chúng tôi biết điều này sẽ chấm dứt khi chúng tôi đạt được1muộn nhất và b) sau đó chúng ta có thể xác định xem số đó có phải là số nguyên tố hay không bằng cách kiểm tra ước số cuối cùng mà chúng ta đã thử (nếu đó là 1số nguyên tố, nếu không thì không).

Chúng ta hãy đi đến đó. Có một phần tuyến tính ngắn ở đầu:

<-!<:^>[:

Bạn biết những gì hầu hết những điều đó làm bây giờ. Các lệnh mới là -!. Mèo Stack không có toán tử tăng hoặc giảm. Tuy nhiên, nó có -(phủ định, tức là nhân với -1) và !(bitwise KHÔNG, tức là nhân với -1và giảm). Chúng có thể được kết hợp thành một mức tăng !-hoặc giảm -!. Vì vậy, chúng tôi giải mã bản sao ntrên đầu trang -1, sau đó tạo một bản sao khác ntrên ngăn xếp bên trái, sau đó lấy bộ chia thử nghiệm mới và đặt nó bên dưới n. Vì vậy, trong lần lặp đầu tiên, chúng ta nhận được điều này:

      4       
      3       
... 1 4 -1 ...
    0 0  0
      ^

Trong các lần lặp tiếp theo, ý 3chí sẽ được thay thế bằng ước số thử nghiệm tiếp theo, v.v. (trong khi hai bản sao nsẽ luôn có cùng giá trị tại thời điểm này).

((-<)<(<!-)>>-_)

Đây là tính toán modulo. Vì các vòng lặp chấm dứt trên các giá trị dương, ý tưởng là bắt đầu từ -nvà liên tục thêm ước số thử nghiệm dvào nó cho đến khi chúng ta nhận được giá trị dương. Khi chúng tôi làm, chúng tôi trừ kết quả dvà điều này cho chúng tôi phần còn lại. Một mẹo nhỏ ở đây là chúng ta không thể đặt một -nchồng lên trên ngăn xếp và bắt đầu một vòng lặp thêm d: nếu đỉnh của ngăn xếp là âm, vòng lặp sẽ không được nhập. Đó là những hạn chế của một ngôn ngữ lập trình đảo ngược.

Vì vậy, để khắc phục vấn đề này, chúng tôi bắt đầu với ntrên cùng của ngăn xếp, nhưng chỉ phủ nhận nó ở lần lặp đầu tiên. Một lần nữa, điều đó nghe có vẻ đơn giản hơn hóa ra là ...

(-<)

Khi đỉnh của ngăn xếp là dương (tức là chỉ trong lần lặp đầu tiên), chúng ta phủ nhận nó với -. Tuy nhiên, chúng tôi không thể làm (-)vì sau đó chúng tôi sẽ không rời khỏi vòng lặp cho đến khi -được áp dụng hai lần. Vì vậy, chúng tôi di chuyển một ô còn lại <bởi vì chúng tôi biết có một giá trị dương ở đó (cái 1). Được rồi, vì vậy bây giờ chúng tôi đã phủ nhận đáng tin cậy ntrong lần lặp đầu tiên. Nhưng chúng ta có một vấn đề mới: đầu băng bây giờ ở một vị trí khác trên lần lặp đầu tiên so với mọi đầu khác. Chúng ta cần củng cố điều này trước khi chúng ta tiếp tục. Tiếp theo <di chuyển đầu băng bên trái. Tình huống trên lần lặp đầu tiên:

        -4       
         3       
...   1  4 -1 ...
    0 0  0  0
    ^

Và trên lần lặp thứ hai (hãy nhớ rằng chúng tôi đã thêm dmột lần vào -nbây giờ):

      -1       
       3       
... 1  4 -1 ...
    0  0  0
    ^

Điều kiện tiếp theo hợp nhất các đường dẫn này một lần nữa:

(<!-)

Trong lần lặp đầu tiên, đầu băng chỉ vào 0, vì vậy điều này được bỏ qua hoàn toàn. Trên các lần lặp tiếp theo, đầu băng chỉ vào một cái, vì vậy chúng tôi thực hiện điều này, di chuyển sang bên trái và tăng ô ở đó. Vì chúng ta biết ô bắt đầu từ 0, nên nó sẽ luôn dương để chúng ta có thể rời khỏi vòng lặp. Điều này đảm bảo chúng ta luôn kết thúc hai ngăn xếp bên trái của ngăn xếp chính và bây giờ có thể di chuyển trở lại với >>. Sau đó, vào cuối vòng lặp modulo, chúng tôi làm -_. Bạn đã biết -. _là để trừ đi ^XOR là gì : nếu đỉnh của ngăn xếp là avà giá trị bên dưới là bnó thay thế abằng b-a. Vì lần đầu tiên chúng tôi phủ nhận a, -_thay thế abằng b+a, do đó thêmd vào tổng số chạy của chúng tôi.

Sau khi vòng lặp kết thúc (chúng tôi đã đạt đến giá trị dương), băng trông như thế này:

        2       
        3       
... 1 1 4 -1 ...
    0 0 0  0
        ^

Giá trị bên trái nhất có thể là bất kỳ số dương nào. Trong thực tế, đó là số lần lặp lại trừ đi một lần. Bây giờ có một bit tuyến tính ngắn khác:

_<<]>:]<]]

Như tôi đã nói trước đây, chúng ta cần trừ kết quả dđể có được phần còn lại thực tế ( 3-2 = 1 = 4 % 3), vì vậy chúng ta chỉ cần làm _lại một lần nữa. Tiếp theo, chúng ta cần dọn sạch ngăn xếp mà chúng ta đã tăng ở bên trái: khi chúng ta thử ước số tiếp theo, nó cần phải bằng 0 lần nữa, để lần lặp đầu tiên hoạt động. Vì vậy, chúng tôi di chuyển đến đó và đẩy giá trị dương đó lên ngăn xếp trợ giúp khác <<]và sau đó di chuyển trở lại vào ngăn xếp hoạt động của chúng tôi với ngăn xếp khác >. Chúng tôi kéo lên dvới :và đẩy nó trở lại vào -1với ]và sau đó chúng tôi di chuyển phần còn lại vào ngăn xếp có điều kiện của chúng tôi với <]]. Đó là kết thúc của vòng phân chia thử nghiệm: điều này tiếp tục cho đến khi chúng ta nhận được phần còn lại bằng 0, trong trường hợp đó, ngăn xếp bên trái chứanƯớc số lớn nhất (khác n).

Sau khi vòng lặp kết thúc, ngay *<trước khi chúng ta nối các đường dẫn với đầu vào 1lại. Đơn *giản chỉ cần biến số 0 thành a 1, chúng ta sẽ cần một chút, sau đó chúng ta chuyển sang ước số <(để chúng ta ở trên cùng một ngăn xếp như với đầu vào 1).

Tại thời điểm này, nó giúp so sánh ba loại đầu vào khác nhau. Đầu tiên, trường hợp đặc biệt n = 1mà chúng tôi chưa thực hiện bất kỳ nội dung phân chia thử nghiệm nào:

         0    
... 1 1 -1 ...
    0 0  0
         ^

Sau đó, ví dụ trước của chúng tôi n = 4, một số tổng hợp:

    2           
    1    2 1    
... 1 4 -1 1 ...
    0 0  0 0
         ^

Và cuối cùng, n = 3một số nguyên tố:

    3           
    1    1 1    
... 1 3 -1 1 ...
    0 0  0 0
         ^

Vì vậy, đối với các số nguyên tố, chúng ta có một số 1trên ngăn xếp này và đối với các số tổng hợp, chúng ta có một 0hoặc một số dương lớn hơn 2. Chúng tôi biến tình huống này thành 0hoặc 1chúng tôi cần với đoạn mã cuối cùng sau đây:

]*(:)*=<*

]chỉ cần đẩy giá trị này sang bên phải. Sau đó *được sử dụng để đơn giản hóa tình hình có điều kiện rất nhiều: do chuyển đổi qua lại các bit quan trọng nhất, chúng tôi rẽ 1(nguyên tố) vào 0, 0(composite) vào giá trị tích cực 1, và tất cả các giá trị tích cực khác sẽ vẫn còn dương tính. Bây giờ chúng ta chỉ cần phân biệt giữa 0và tích cực. Đó là nơi chúng ta sử dụng cái khác (:). Nếu đỉnh của ngăn xếp là 0(và đầu vào là số nguyên tố), thì điều này chỉ đơn giản là bỏ qua. Nhưng nếu đỉnh của ngăn xếp là dương (và đầu vào là số hỗn hợp) thì điều này sẽ hoán đổi nó với 1, vì vậy bây giờ chúng ta có 0kết hợp và1cho các số nguyên tố - chỉ có hai giá trị riêng biệt. Tất nhiên, chúng trái ngược với những gì chúng ta muốn đầu ra, nhưng điều đó dễ dàng được sửa với cái khác *.

Bây giờ, tất cả những gì còn lại là để khôi phục mô hình các ngăn xếp được dự kiến ​​bởi khung xung quanh của chúng tôi: đầu băng trên một giá trị dương, kết quả ở trên cùng của ngăn xếp bên phải và một -1ngăn xếp bên phải của ngăn xếp đó . Đây là những gì =<*dành cho. =hoán đổi đỉnh của hai ngăn xếp liền kề, do đó di chuyển -1sang bên phải của kết quả, ví dụ cho đầu vào 4lại:

    2     0       
    1     3       
... 1 4   1 -1 ...
    0 0 0 0  0
          ^

Sau đó, chúng ta chỉ cần di chuyển sang trái <và biến số 0 thành một với *. Và đó là điều đó.

Nếu bạn muốn tìm hiểu sâu hơn về cách chương trình hoạt động, bạn có thể sử dụng các tùy chọn gỡ lỗi. Hoặc thêm -dcờ và chèn "bất cứ nơi nào bạn muốn để xem trạng thái bộ nhớ hiện tại, ví dụ như thế này hoặc sử dụng -Dcờ để có được một dấu vết hoàn chỉnh của toàn bộ chương trình . Ngoài ra, bạn có thể sử dụng EswericIDE của Timwi's , bao gồm trình thông dịch Stack Mèo với trình gỡ lỗi từng bước.


3
>:^]nên là biểu tượng chính thức của Stack Mèo
Alex A.

14

Haskell, 54 byte

import Data.Numbers.Primes
main=readLn>>=print.isPrime

Không có gì nhiều để giải thích.


1
Điểm số tương tự có thể đạt được (mặc dù rất kém hiệu quả) mà không cần các thư viện bên ngoài, sử dụng định lý của Wilson:main=do n<-readLn;print$n>1&&mod(product[1..n-1]+1)n<1
Lynn

9
Chúng tôi thậm chí có thể làm ngắn hơn: main=do n<-readLn;print$mod(product[1..n-1]^2)n>0là 49 byte.
Lynn

4
@Mauris: Hay đấy. Xin vui lòng gửi nó như là một câu trả lời riêng biệt.
nimi

14

Ruby, 15 + 8 = 23 byte

p$_.to_i.prime?

Chạy mẫu:

bash-4.3$ ruby -rprime -ne 'p$_.to_i.prime?' <<< 2015
false

Heheh, tôi biết sẽ có một tích hợp trong Ruby ở đâu đó, nhưng tôi không thể bận tâm tìm kiếm nó, vì vậy tôi đã trả lời trong C. +1.
Cấp sông St

@steveverrill, tôi biết điều đó vì nó là một trợ giúp lớn cho Project Euler.
manatwork

14

JavaScript, 39 36 byte

Đã lưu 3 byte nhờ vào ETHproductions:

for(i=n=prompt();n%--i;);alert(1==i)

Hiển thị đúng cho một số nguyên tố, sai khác.

Các cho vòng lặp kiểm tra tất cả các số i từ n-1 cho đến khi tôi là một số chia. Nếu số chia đầu tiên được tìm thấy là 1 thì đó là số nguyên tố.


Giải pháp trước đó (39 byte):

for(i=n=prompt();n%--i&&i;);alert(1==i)

Làm thế nào để lại một bài kiểm tra không cần thiết:

for(i=2,n=prompt();n%i>0&&i*i<n;i++);alert(n%i>0) //49: Simple implementation: loop from 2 to sqrt(n) to test the modulo.
for(i=2,n=prompt();n%i>0&&i<n;i++);alert(n==i)    //46: Replace i*i<n by i<n (loop from 2 to n) and replace n%i>0 by n==i
for(i=2,n=prompt();n%i&&i<n;i++);alert(n==i)      //44: Replace n%i>0 by n%i
for(i=2,n=prompt();n%i&&i++<n;);alert(n==i)       //43: Shorten loop increment
for(i=n=prompt();n%--i&&i>0;);alert(1==i)         //41: Loop from n to 1. Better variable initialization.
for(i=n=prompt();n%--i&&i;);alert(1==i)           //39: \o/ Replace i>0 by i

Tôi chỉ đăng giải pháp 39 byte vì câu trả lời JavaScript tốt nhất đã là 40 byte.


2
Chào mừng bạn đến với Câu đố lập trình & Code Golf!
Dennis

2
Câu trả lời chính xác! Các &&ikhông thực sự làm bất cứ điều gì trong chương trình này, vì vậy bạn có thể loại bỏ nó.
Sản xuất ETH

nên thêm n>1vào điều kiện cuối cùng, nếu bạn không muốn 1là số nguyên tố.
Tít

1
@Titus Nếu đầu vào là 1vòng lặp for sẽ thực hiện n%--imột lần: 1%0trả về NaNvà dừng vòng lặp. Khi alertđược gọi ilà đã tương đương với 0rất 1==ilợi nhuận false.
Hedi

2
i <2 (và một số văn bản)
Scheintod 16/03/18

13

Ốc, 122

Đầu vào nên được đưa ra trong unary. Các chữ số có thể là bất kỳ kết hợp các ký tự ngoại trừ dòng mới.

^
..~|!(.2+~).!~!{{t.l=.r=.}+!{t.!.!~!{{r!~u~`+(d!~!.r~)+d~,.r.=.(l!~u~)+(d!~l~)+d~,.l.},l=(.!.)(r!~u~)+(d!~!.r~)+d~,.r.!.

Trong ngôn ngữ khớp mẫu 2D này, trạng thái chương trình chỉ bao gồm vị trí lưới hiện tại, tập hợp các ô đã được khớp và vị trí trong mã mẫu. Việc đi lại trên một quảng trường trùng khớp cũng là bất hợp pháp. Đó là khó khăn, nhưng có thể lưu trữ và lấy thông tin. Hạn chế đối với việc di chuyển lên một ô phù hợp có thể được khắc phục bằng cách quay lại, dịch chuyển tức thời ( t) và xác nhận ( =, !) khiến lưới không được sửa đổi sau khi hoàn thành.

Hệ số 25

Hệ số cho một số hỗn hợp lẻ bắt đầu bằng cách đánh dấu một số tập hợp các ô không liền kề nhau (màu xanh trong sơ đồ). Sau đó, từ mỗi ô màu vàng, chương trình xác minh rằng có một số lượng ô không màu xanh bằng nhau ở hai bên của ô màu xanh liền kề bằng cách đảo qua lại giữa hai bên. Biểu đồ hiển thị mẫu này cho một trong bốn ô màu vàng phải được kiểm tra.

Mã chú thích:

^                         Match only at the first character
..~ |                     Special case to return true for n=2
!(.2 + ~)                 Fail for even numbers
. !~                      Match 1st character and fail for n=1
!{                        If the bracketed pattern matches, it's composite.
  (t. l=. r=. =(.,~) )+   Teleport to 1 or more chars and match them (blue in graphic)
                          Only teleport to ones that have an unmatched char on each side.
                          The =(.,~) is removed in the golfed code. It forces the
                          teleports to proceed from left to right, reducing the
                          time from factorial to exponential.
  !{                      If bracketed pattern matches, factorization has failed.
    t . !. !~             Teleport to a square to the left of a blue square (yellow in diagram)
    !{                    Bracketed pattern verifies equal number of spaces to
                          the left or right of a blue square.
      {              
        (r!~ u~)+         Up...
        (d!~!. r~)+       Right...
        d~,               Down...
        . r . =.          Move 1 to the right, and check that we are not on the edge;
                          otherwise d~, can fall off next iteration and create and infinite loop
        (l!~ u~)+         Up...
        (d!~ l~)+         Left...
        d ~,              Down...
        . l .             Left 1
      } ,                 Repeat 0 or more times
      l  =(. !.)          Check for exactly 1 unused char to the left
      (r!~ u~)+           Up...
      (d!~!. r~)+         Right...
      d ~,                Down...
      . r . !.
    }
  }
}

13

C, 67 byte

i,n;main(p){for(scanf("%d",&i),n=i;--i;p=p*i*i%n);putchar(48+p%n);}

In !1(một giá trị falsey, theo định nghĩa của Peter Taylor ) 0 nếu (n-1)!^2 == 0 (mod n), và 1nếu không.

EDIT : Sau một số cuộc thảo luận trong trò chuyện,puts("!1"+p%n) dường như được coi là một chút gian lận, vì vậy tôi đã thay thế nó. Kết quả là một byte dài hơn.

EDIT : Đã sửa cho các đầu vào lớn.

Giải pháp ngắn hơn

56 byte : Theo khuyến nghị trong các bình luận của pawel.boczarski, tôi có thể lấy đầu vào bằng unary bằng cách đọc số lượng đối số dòng lệnh:

p=1,n;main(i){for(n=--i;--i;p=p*i*i%n);putchar(48+p%n);}

gọi chương trình như

$ ./a.out 1 1 1 1 1
1                        <-- as 5 is prime

51 byte : Nếu bạn cho phép "đầu ra" bằng mã trả về:

p=1,n;main(i){for(n=--i;--i;p=p*i*i%n);return p%n;}

Giải pháp của bạn có thể được thực hiện ngắn hơn bằng cách sử dụng biểu diễn đơn nguyên (số lượng đối số dòng lệnh), như trong giải pháp của tôi được đăng. Bạn có thể tắt một số byte trong cuộc gọi scanf.
pawel.boczarski

puts("!1"+p%n)Làm thế nào bạn có thể làm a+bcho char*các giá trị?
Erik the Outgolfer

Nếu chuỗi "!1"bắt đầu tại địa chỉ a, thì tại a+1bạn sẽ tìm thấy chuỗi "1".
Lynn

@Lynn Ồ, tôi nghĩ rằng nó là cho nối (yeah, tốt rời khỏi đó để strcat(const char*,const char*).)
Erik các Outgolfer

Bạn có thể đổi p=p*i*i%nthànhp*=i*i%n
Albert Renshaw

12

Python 3, 59 byte

Bây giờ sử dụng input()thay vì đối số dòng lệnh. Cảm ơn @Beta Decay

n=int(input())
print([i for i in range(1,n)if n%i==0]==[1])

Lấy đầu vào sử dụng input()sẽ ngắn hơn nhiều
Phân rã Beta

Cảm ơn, tôi đã viết bằng cách sử dụng input (), nhưng tôi quên làm mới câu trả lời của mình. Cảm ơn một lần nữa!
uno20001

4
52 byte : n=m=int(input()),print(all(n%m for m in range(2,n)))
John Lyon

1
Bạn nghiêm túc chứ. Chi thêm 25 ký tự cho một tăng tốc bậc hai khập khiễng? Ở đây chúng tôi ghét byte . Chúng ta dành mỗi giờ, phút và giây trong cuộc sống để thoát khỏi byte thứ mười chín. (Đùa thôi. Nhưng chúng tôi không tối ưu hóa thời gian làm tăng thời lượng chương trình.)
CalculatorFeline

2
Sử dụng n%i<1thay thế.
Erik các Outgolfer

12

APL, 40 13 byte

2=+/0=x|⍨⍳x←⎕

Phân chia thử nghiệm với thuật toán tương tự như câu trả lời R của tôi . Chúng tôi gán xcho đầu vào từ STDIN ( ) và lấy phần còn lại để xchia cho mỗi số nguyên từ 1 đến x. Mỗi phần còn lại được so sánh với 0, cung cấp cho chúng ta một vectơ của số 0 và số 0 cho biết số nguyên nào chia x. Điều này được tóm tắt bằng cách sử dụng +/để có được số lượng ước. Nếu con số này là chính xác 2, điều này có nghĩa là các ước số duy nhất là 1 xvà do đó xlà số nguyên tố.



12

Lập trình siêu mẫu C ++. 166 131 119 byte.

Mã biên dịch nếu hằng số là một số nguyên tố và không biên dịch nếu tổng hợp hoặc 1.

template<int a,int b=a>struct t{enum{x=t<a,~-b>::x+!(a%b)};};
template<int b>struct t<b,0>{enum{x};};
int _[t<1>::x==2];

(tất cả các dòng mới, ngoại trừ dòng cuối cùng, được loại bỏ trong phiên bản "thực").

Tôi cho rằng "thất bại trong việc biên dịch" là giá trị trả về falsey cho ngôn ngữ lập trình siêu dữ liệu. Lưu ý rằng nó không liên kết (vì vậy nếu bạn cho nó là số nguyên tố, bạn sẽ gặp lỗi liên kết) dưới dạng chương trình C ++ đầy đủ.

Giá trị cần kiểm tra là số nguyên trên "dòng" cuối cùng.

ví dụ sống .

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.