Xác định xem một số có phải là số 2017 không có số nguyên tố trong mã nguồn của bạn không


41

Trong tất cả những năm tôi đã thực hiện thử thách này, 2017 là năm đầu tiên đó là một con số chính. Vì vậy, câu hỏi sẽ là về số nguyên tố và tính chất của chúng.

Nhiệm vụ của bạn là tạo ra một chương trình hoặc hàm sẽ lấy một số nguyên dương lớn tùy ý làm đầu vào, và đầu ra hoặc trả về cho dù số đó có phải là 2.017 hay không - nghĩa là, cho dù hệ số nguyên tố lớn nhất trong số đó là 2.017 hay ít hơn.


Một số ví dụ đầu vào và đầu ra của chúng:

1 (has no prime factors)
true

2 (= 2)
true

80 (= 2 x 2 x 2 x 2 x 5)
true

2017 (= 2017)
true

2019 (= 3 x 673)
true

2027 (= 2027)
false

11111 (= 41 x 271)
true

45183 (= 3 x 15061)
false

102349 (= 13 x 7873)
false

999999 (= 3 x 3 x 3 x 7 x 11 x 13 x 37)
true

1234567 (= 127 x 9721)
false

4068289 (= 2017 x 2017)
true

Chương trình của bạn không phải xuất ra theo nghĩa đen truefalse- bất kỳ giá trị trung thực hoặc giả nào, và trên thực tế, bất kỳ hai đầu ra khác nhau nào phù hợp giữa các trường hợp đúng và sai đều ổn.


Tuy nhiên, bạn không được sử dụng bất kỳ số nguyên tố nào trong mã nguồn của mình. Số nguyên tố có hai loại:

  • Các ký tự, hoặc chuỗi các ký tự, đại diện cho chữ số nguyên tố.

    • Các nhân vật 2, 3, 5, và 7là bất hợp pháp trong ngôn ngữ mà con số này là thẻ hợp lệ.

    • Số 141này là bất hợp pháp vì nó chứa 41, mặc dù 14có giá trị khác.

    • Các ký tự BD(hoặc bd) là bất hợp pháp trong các ngôn ngữ mà chúng thường được sử dụng là 11 và 13, chẳng hạn như CJam hoặc Befunge.

  • Các ký tự có giá trị Unicode có giá trị chính hoặc chứa các byte có giá trị chính trong mã hóa của chúng.

    • Các nhân vật %)+/5;=CGIOSYaegkmqlà bất hợp pháp trong ASCII, cũng như nhân vật trở về xe ngựa.

    • Ký tự ónày là bất hợp pháp trong UTF-8 vì mã hóa của nó có 0xb3trong đó. Tuy nhiên, trong ISO-8859-1, mã hóa của nó chỉ đơn giản 0xf3, là hỗn hợp và do đó ổn.

Mã ngắn nhất để làm điều trên trong bất kỳ ngôn ngữ nào sẽ thắng.


Lưu ý bên lề: "đáng tin cậy" là một cải tiến đang được áp dụng so với "trơn tru" cũ và không mô tả trong bối cảnh này.
Greg Martin

1
Các giá trị trung thực và giả có cần phải nhất quán? Hoặc họ có thể thay đổi miễn là chúng là sự thật hoặc giả?
Luis Mendo

10
Việc thiếu các =quy tắc trong hầu hết các ngôn ngữ tiêu chuẩn ...
Neil

4
-1 cho một X làm mà không có thách thức Y. Nó thực sự khá tầm thường ẩn đằng sau một loạt các hạn chế nhân vật khá không cần thiết
Downgoat

1
Tôi không thích phần chúng lớn một cách tùy tiện. Sẽ tốt hơn nếu họ tăng lên 2 ^ 31-1.
Bijan

Câu trả lời:


37

Thạch , 8 byte

44‘²!*ḍ@

Hãy thử trực tuyến! Lưu ý rằng các trường hợp kiểm tra 11111 trở lên là quá nhiều cho TIO.

xác minh

$ source="34,34,fc,82,21,2a,d5,40"
$ xxd -ps -r > 2017.jelly <<< $source
$ xxd -g 1 2017.jelly
0000000: 34 34 fc 82 21 2a d5 40                          44..!*.@
$ eval printf '"%d "' 0x{$source}; echo # Code points in decimal
52 52 252 130 33 42 213 64
$ test_cases="1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289"
$ for n in $test_cases; do printf "%11d: %d\n" $n $(jelly f 2017.jelly $n); done
      1: 1
      2: 1
     80: 1
   2017: 1
   2019: 1
   2027: 0
  11111: 1
  45183: 0
 102349: 0

Trường hợp thử nghiệm 999999 đã chạy được 13 giờ. Tôi bi quan về điện toán 2025! 4068289 ...

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

44‘²!*ḍ@  Main link. Argument: n

44        Yield 44.
  ‘       Increment to yield 45.
   ²      Square to yield 2025.
          Note that no integers in [2018, ..., 2025] are prime numbers.
    !     Take the factorial of 2025.
     *    Raise it to the n-th power.
          This repeats all prime factors in 2025! at least n times, so the result
          will be divisible by n if (and only if) all of its prime factors fall
          in the range [1, ..., 2025].
      ḍ@  Test the result for divisibility by n.

22
Bạn thật tàn nhẫn với những con số. :)
Greg Martin

3
@GregMartin bah. Tôi đã thấy một câu trả lời (bằng một ngôn ngữ khác) trong đó đầu vào có kích thước 6 sẽ hog bộ nhớ trong vài giờ, sau đó sụp đổ. Tôi sẽ chỉ nói : (2^n)!. Điều này cũng khao khát các đầu vào sáu kích thước, nhưng ít nhất các đầu vào nằm trong một bảng chữ cái thập phân chứ không phải là một nhị phân.
John Dvorak

Đây có phải là 13 byte không? Dennis bạn có rất nhiều danh tiếng đến nỗi tôi chắc chắn tôi là người mắc lỗi ở đây hahah 😬
Albert Renshaw

7
@AlbertRenshaw Nó thực sự sẽ là 13 byte trong UTF-8, nhưng Jelly sử dụng một trang mã tùy chỉnh mã hóa tất cả các ký tự mà nó hiểu là một byte đơn lẻ.
Dennis

3
@Dennis biết sẽ có một lời giải thích; rất tuyệt để tìm hiểu về, cảm ơn!
Albert Renshaw

11

Jelly , 8 ký tự, 14 byte UTF-8

Æf½ṀḤ<90

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

Jelly thường sử dụng codepage riêng cho các chương trình. Tuy nhiên, hầu hết các nội dung liên quan đến chính của nó bắt đầu bằng Æ, đó là mã số 13; không hữu ích lắm May mắn thay, trình thông dịch cũng hỗ trợ UTF-8, có mã hóa thân thiện hơn.

xác minh

Chương trình này, trong UTF-8, hexdumps như thế này:

00000000: c386 66c2 bde1 b980 e1b8 a43c 3930  ..f........<90

Xác minh rằng tất cả các byte là hỗn hợp:

$ for x in c3 86 66 c2 bd e1 b9 80 e1 b8 a4 3c 39 30; do factor $((0x$x)); done
195: 3 5 13
134: 2 67
102: 2 3 17
194: 2 97
189: 3 3 3 7
225: 3 3 5 5
185: 5 37
128: 2 2 2 2 2 2 2
225: 3 3 5 5
184: 2 2 2 23
164: 2 2 41
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

Xác minh rằng tất cả các điểm mã Unicode là hỗn hợp:

$ perl -Mutf8 -E '$a = ord, print `factor $a` for split //, "Æf½ṀḤ<90"'
198: 2 3 3 11
102: 2 3 17
189: 3 3 3 7
7744: 2 2 2 2 2 2 11 11
7716: 2 2 3 643
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

Mã thông báo duy nhất được phân tích cú pháp dưới dạng số 90. Không ai trong số 9, 090là nguyên tố.

Giải trình

Cái nhìn sâu sắc toán học chính ở đây là 45² là năm 2025, nằm gọn giữa năm 2017 (năm hiện tại) và 2027 (nguyên tố tiếp theo). Do đó, chúng ta có thể lấy căn bậc hai của mọi thừa số nguyên tố của số và xem có vượt quá 45. Thật không may, chúng ta không thể viết 45do nghĩa đen 5, vì vậy chúng ta phải nhân đôi nó và so sánh với 90 thay vào đó.

Æf½ṀḤ<90
Æf        In the list of prime factors,
  ½       taking the square root of each element
   Ṁ      then taking the largest element
    Ḥ     and doubling it
     <90  produces a result less than 90.

2
Không Jelly yêu cầu một cờ (1 byte) để sử dụng UTF-8?
Luis Mendo

@LuisMendo: Trình thông dịch dòng lệnh thực hiện, nhưng trình thông dịch tại Dùng thử trực tuyến! được cấu hình khác nhau và không yêu cầu nó. Vì vậy, đây chỉ là một trường hợp chọn trình thông dịch phiên dịch chương trình của bạn theo cách bạn muốn. (Trong mọi trường hợp, cờ trong câu hỏi, ulà hỗn hợp, do đó, vấn đề chỉ là thay đổi điểm số chứ không phải là điều gì đó làm mất hiệu lực của nó.)

10

Toán học, 62 58 55 byte

Ba byte cuối cùng được lưu hoàn toàn là do Martin Ender!

#4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&

Hàm không tên lấy một đối số nguyên dương và trả về Truehoặc False.

Thuật toán đệ quy, với #4<4trường hợp cơ sở trung thực (chúng ta chỉ cần nó trả Truevề giá trị 1, nhưng các trường hợp cơ sở bổ sung là ổn). Mặt khác, chúng tôi tính toán ước số nhỏ thứ hai (nhất thiết phải là số nguyên tố) của đầu vào với Divisors[#][[6-4]]; nếu nó lớn hơn 2024 ( 44*46) thì chúng ta thoát ra False, nếu không, chúng ta gọi hàm đệ quy (sử dụng #6set thành #0) trên đầu vào chia cho thừa số nguyên tố nhỏ này #(mà chúng ta phải biểu thị bằng số #^-1lần đầu vào #4, vì /không được phép).

Về mặt cấu trúc, nửa đầu #4<4||#<44*46&&#6[#^-1#4]&là một chức năng ẩn danh trong sáu đối số, được gọi với các đối số Divisors[#][[6-4]], Null, Null, #, Null, và #0; này là để có được xung quanh việc cấm các nhân vật 2, 35.

Phiên bản trước, đã lưu bốn byte bằng cách thay thế 8018-6000bằng 44*46, lấy cảm hứng từ câu trả lời Jelly của ais523 (Martin Ender dường như cũng được truyền cảm hứng từ một bình luận ais523):

#<4||Divisors[#][[6-4]]<44*46&&#0[Divisors[#][[6-4]]^-1#]&

Điều này khá khó chịu: Tôi vẫn không biết cách thực sự đặt biến trong Mathicala theo những hạn chế này! Cả =etrong Setđều không được phép. Tránh +)cũng là một vấn đề, nhưng không quá khó để khắc phục với chi phí nhiều byte hơn.


Bạn có thể có thể đặt tham số lambda chứ không phải là một biến. (Điều đó nói rằng, #2cũng sẽ không được phép, vì vậy bạn phải cẩn thận với cách lambdas của bạn lồng vào nhau và việc thiếu dấu ngoặc đơn có thể gây khó khăn.)

Việc thực hiện đề xuất của @ ais523 giúp tiết kiệm ba byte: #4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&đưa ra một loạt các cảnh báo vì hiện tại nó đã cố gắng Divisors[#][[2]]trước khi đảm bảo rằng đầu vào lớn hơn 1 (hoặc 3), nhưng kết quả vẫn đúng.
Martin Ender

Ôi trời, thật là xảo quyệt.
Greg Martin

7

Haskell, 48 47 byte

\n->[snd$[product[1..44*46]^n]!!0`divMod`n]<[1]

Về cơ bản là một bản dịch của câu trả lời Dennis 'Jelly . xnor đã lưu một byte.

Sử dụng […]!!0làm dấu ngoặc đơn vì )bị cấm và snd+ divModmtrong modrembị cấm.


Thủ thuật hay với divMod! Tôi nghĩ bạn có thể thay thế !!0<1bằng <[1]. Nhưng có vẻ như nó được rút ngắn để sử dụng divnhư [\p n->p^n`div`n*n>p^n-1]!!0$product[1..44*46].
xnor

Ngoài ra \n->[0|p<-[product[1..44*46]^n],0<-[p,p-n..0]], sử dụng các đầu ra chỉ cần nhất quán.
xnor

@xnor Hãy thoải mái đăng những câu đó dưới dạng câu trả lời riêng biệt, tôi nghĩ chúng đủ khác biệt so với của tôi ^^
Lynn

6

Pyke, 10 8 7 9 byte

P_Z|hwMX<

Hãy thử nó ở đây!

Đã lưu 1 byte bằng cách sử dụng cách tạo 2025 của Dennis

P         -     factors(input)
 _        -    reversed(^)
  Z|      -   ^ or 0
    h     -  ^[0] or 1
        < - ^ < V
     wM   -  ⁴45 (ord("M")-32)
       X  -  ^**2

5

Brachylog , 9 10 byte

*$ph$r*<90

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

Về cơ bản sử dụng thuật toán tương tự như câu trả lời khác của tôi. $phtìm hthừa số nguyên tố ( $p) đầu tiên ( ); đây là yếu tố chính lớn nhất, vì danh sách nhân tố chính của Brachylog đi từ lớn nhất đến nhỏ nhất. Sau đó, tôi lấy căn bậc hai ( $r), double ( *) và kiểm tra xem nó có nhỏ hơn 90 ( <90) không.

Tôi đã phải tăng gấp đôi đầu vào trước vì 1 không có thừa số nguyên tố (và do đó không có thừa số nguyên tố đầu tiên). Điều này bổ sung thêm hệ số nguyên tố bổ sung là 2, không thể ảnh hưởng đến việc một số có phải là số 2017 hay không, nhưng ngăn ngừa sự cố khi xử lý 1.


5

Trên thực tế , 9 byte

τyM:44u²≥

Cảm ơn Dennis vì rất nhiều byte!

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

Giải trình:

τyM:44u²≥
τyM        largest prime factor of 2*input (doubled to deal with edge case of n = 1)
   :44u²   2025 (2027 is the next prime after 2017, so any number in [2017, 2026] can be used here - 2025 is very convenient)
        ≥  is 2025 greater than or equal to largest prime factor?

5

Toán học, 66 74 byte

Cảm ơn Dennis vì đã chỉ ra điều đó U+F4A1bị cấm.

Fold[Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]],0<1,Divisors@#]&

Giải trình:

Divisors@#: Danh sách các ước số nguyên của đối số đầu tiên #.

0<1: Golf cho True(cũng tránh sử dụng chữ cái e).

Divisors@d^0: Danh sách biểu mẫu {1, 1, ..., 1}có độ dài bằng số ước của d.

Tr: Đối với danh sách phẳng, Trtrả về tổng của danh sách đó. Do đó Tr[Divisors@d^0]trả về số lượng ước của d.

Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]]: Hàm ẩn danh với hai đối số xd. Ý tưởng là dmột ước số #và chúng tôi kiểm tra xem liệu nó có phải là tổng hợp hoặc nhỏ hơn hoặc bằng 2017(bao gồm). 2017-friability tương đương với tất cả các ước số thỏa mãn điều kiện này. Như ais523 đã phát hiện ra, là một số nguyên tố nhỏ hơn hoặc bằng 2017tương đương với một số nguyên tố nhỏ hơn 2025. Như Greg Martin đã chỉ ra, nó đủ để kiểm tra xem nó có nhỏ hơn không 2024=44*46. Đối số xđóng vai trò là người tích lũy cho dù tất cả các ước số gặp phải cho đến nay có thỏa mãn tính chất này hay không. Sau đó, chúng tôi đã để lại Foldhàm này thông qua tất cả các ước của #giá trị bắt đầuTrue, vì chúng tôi có quyền truy cập vào Mapcũng không /@.


1
Cách để chiến đấu thông qua các hạn chế!
Greg Martin

2

05AB1E , 10 byte

fθ46n99-›È

Trả về 1 nếu đúng, 0 nếu không.

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

Giải trình

f          # Push the list of prime factors (ordered)
 θ         # Get the last element
  46n99-   # Push 2017 (46² - 99)
        >  # Push 1 if the last prime factor is greater than 2017, 0 otherwise
         È # Is the resulting number even ? Transforms 1 to 0 and 0 to 1.
           # Implicit display

Chào mừng đến với PPCG!
Martin Ender

1

MATL , 15 byte

t:\~ftZp*44QU<A

Đầu ra 0cho sản phẩm không phải là 2017 hoặc 1cho năm 2017.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Chương trình này kiểm tra rằng tất cả các byte là hỗn hợp.

Giải trình

t       % Implicit input n. Duplicate
:       % Range [1 2 ... n]
\       % Modulo. Gives 0 for divisors of n
~f      % Indices of zero values
t       % Duplicate
Zp      % Is-prime. Gives 1 for primes, 0 for composites
*       % Multiply
44QU    % 44, add 1, square: 2025
<       % Less than, element-wise
A       % True (1) if all entries are nonzero

1

Bash, 144 byte

Mã hóa ASCII:

{
printf '[ '
`tr D-Z _-z <<<KFH`tor $1|tr -d :|`tr B-Z _-z <<<JUH`p -o '[0-9]*$'
printf ' -lt $[24*86-46] ]'
}|tr \\n \ |`tr B-Z _-z <<<EDVK`

Như thường lệ đối với shell, mã thoát cho biết thành công (0) hoặc thất bại (không phải 0).

Đây thực sự là một cách viết khác nhau của

[ factor $1|tr -d :|grep -o '[0-9]*$' -lt 2018 ]

Chúng tôi có được yếu tố lớn nhất với factor $1|grep -o '[0-9]*$'; những tr -d :là đặc biệt hợp cho = đầu vào 1.

Biểu thức $[6*6*69-466]đánh giá đến năm 2018.

Thật khó để sử dụng trcho các tên lệnh và vẫn sử dụng thay thế lệnh - Tôi không thể sử dụng hình thức lồng nhau $( ), vì vậy tôi đã kết thúc đường ống vào một Bash khác để đánh giá kết quả.

Kết quả kiểm tra:

$ for i in 1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289; do printf '%d %s\n' $i `./105241.sh $i  && echo true || echo false`; done
1 true
2 true
80 true
2017 true
2019 true
2027 false
11111 true
45183 false
102349 false
999999 true
1234567 false
4068289 true

Xác nhận mã ký tự:

$ grep -v '^#' ./105241.sh | perl -n -Mutf8 -E '$a = ord, print `factor $a` for split //, $_' | grep -v ': .* ' | wc -l
0




0

Braingolf , 11 byte [rất không cạnh tranh]

VRp#ߢ-?0:1

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

Không thể đọc được do các ߢốc vít với các số, tuy nhiên vẫn hoạt động trong một trình thông dịch.

Tôi thậm chí không nhận thấy các hạn chế về ký tự khi tôi viết điều này, nhưng tất cả những gì tôi phải làm là thay đổi ký tự unicode kỳ lạ từ năm 2017 sang 2018.

Cho năm 2018 không phải là số nguyên tố, bất kỳ số nguyên tố nào <= 2018cũng là<= 2017

Giải trình

VRp#ߢ-?0:1  Implicit input from command-line args
VR            Create stack2, return to stack1
  p           Split last item into prime factors, push each one to stack in asc order
   #ߢ         Push 2018
     -      Subtract last 2 items (highest prime factor - 2017)
      ?     If last item > 0..
       0    ..push 1
        :   Else..
         1  ..Push 1
            Implicit output of last item on stack
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.