Tentukan apakah suatu angka 2017-friable tanpa bilangan primes dalam kode sumber Anda

41

Dari semua tahun saya membuat tantangan ini, 2017 adalah tahun pertama yang menjadi bilangan prima. Jadi pertanyaannya adalah tentang bilangan prima dan propertinya.

Tugas Anda adalah untuk menghasilkan program atau fungsi yang akan mengambil bilangan bulat positif besar yang sewenang-wenang sebagai input, dan menghasilkan atau mengembalikan apakah jumlahnya friable 2.017 - artinya, apakah faktor utama terbesar dalam jumlah itu adalah 2.017 atau kurang.


Beberapa contoh input dan outputnya:

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

Program Anda tidak harus benar-benar menampilkan truedan false- nilai-nilai yang benar atau salah, dan pada kenyataannya setiap dua keluaran berbeda yang konsisten di seluruh kasus benar dan salah baik-baik saja.


Namun, Anda tidak boleh menggunakan bilangan prima dalam kode sumber Anda. Primes datang dalam dua jenis:

  • Karakter, atau urutan karakter, yang mewakili literal bilangan prima.

    • Karakter 2, 3, 5, dan 7adalah ilegal dalam bahasa mana jumlahnya token valid.

    • Angka 141itu ilegal karena mengandung 41, meskipun 1dan 4sebaliknya valid.

    • Karakter Bdan D(atau bdan d) ilegal dalam bahasa di mana mereka biasanya digunakan sebagai 11 dan 13, seperti CJam atau Befunge.

  • Karakter yang memiliki nilai Unicode bernilai prima, atau berisi byte bernilai prima dalam penyandiannya.

    • Karakter %)+/5;=CGIOSYaegkmqtersebut ilegal di ASCII, serta karakter carriage return.

    • Karakter óini ilegal di UTF-8 karena penyandiannya ada 0xb3di dalamnya. Namun, dalam ISO-8859-1, penyandiannya sederhana 0xf3, yang komposit dan karenanya oke.

Kode terpendek untuk melakukan hal di atas dalam bahasa apa pun menang.

Joe Z.
sumber
Catatan: "rapuh" adalah perbaikan yang diadopsi dari "lancar" lama dan tidak deskriptif dalam konteks ini.
Greg Martin
1
Apakah nilai kebenaran dan kepalsuan harus konsisten? Atau dapatkah mereka berbeda selama mereka benar atau salah?
Luis Mendo
10
Kurangnya =aturan bahasa standar yang paling ...
Neil
4
-1 untuk do X tanpa tantangan Y. Ini benar-benar sangat sepele yang tersembunyi di balik sekumpulan pembatasan karakter yang tidak perlu
Downgoat
1
Saya tidak suka bagian tentang mereka menjadi besar secara sewenang-wenang. Akan lebih baik jika mereka naik ke 2 ^ 31-1.
Bijan

Jawaban:

37

Jelly , 8 byte

44‘²!*ḍ@

Cobalah online! Perhatikan bahwa test case 11111 dan di atasnya agak terlalu banyak untuk TIO.

Verifikasi

$ 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

Test case 999999 telah berjalan selama 13 jam. Saya pesimis tentang komputasi 2025! 4068289 ...

Bagaimana itu bekerja

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.
Dennis
sumber
22
Anda kejam dalam hal angka. :)
Greg Martin
3
@GregMartin bah. Saya telah melihat jawaban (dalam bahasa yang berbeda) di mana input ukuran 6 akan memonopoli memori selama beberapa jam, lalu macet. Saya hanya akan mengatakan: (2^n)!. Ini juga berlaku untuk input berukuran enam, tetapi setidaknya input berada dalam alfabet desimal daripada yang biner.
John Dvorak
Bukankah ini 13 byte? Dennis kau punya banyak reputasi sehingga aku yakin akulah yang membuat kesalahan di sini hahah 😬
Albert Renshaw
7
@AlbertRenshaw Memang itu akan menjadi 13 byte di UTF-8, tetapi Jelly menggunakan halaman kode kustom yang menyandikan semua karakter yang dipahami sebagai masing-masing byte tunggal.
Dennis
3
@Dennis tahu akan ada penjelasan; sangat keren untuk dipelajari, terima kasih!
Albert Renshaw
11

Jelly , 8 karakter, 14 byte UTF-8

Æf½ṀḤ<90

Cobalah online!

Jelly biasanya menggunakan codepage sendiri untuk program. Namun, sebagian besar builtin terkait prima dimulai dengan Æ, yaitu codepoint 13; tidak terlalu membantu. Untungnya, penerjemah juga mendukung UTF-8, yang memiliki penyandian yang lebih ramah.

Verifikasi

Program ini, di UTF-8, hexdumps seperti ini:

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

Verifikasi bahwa semua byte adalah komposit:

$ 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

Verifikasi bahwa semua titik kode Unicode adalah komposit:

$ 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

Satu-satunya token yang diuraikan sebagai angka adalah 90. Tak satu pun dari 9,, 0dan 90prima.

Penjelasan

Wawasan matematika utama di sini adalah bahwa 45² adalah 2025, yang jatuh dengan rapi antara 2017 (tahun berjalan) dan 2027 (perdana berikutnya). Dengan demikian, kita dapat mengambil akar kuadrat dari setiap faktor prima dari angka tersebut, dan melihat apakah ada yang melebihi 45. Sayangnya, kita tidak dapat menulis 45karena literal 5, jadi kita harus menggandakannya dan membandingkan dengan 90 sebagai gantinya.

Æ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.

sumber
2
Bukankah Jelly memerlukan flag (1 byte) untuk menggunakan UTF-8?
Luis Mendo
@LuisMendo: Penerjemah baris perintah tidak, tetapi penerjemah di Try It Online! dikonfigurasi secara berbeda dan tidak memerlukannya. Jadi ini hanya kasus memilih juru bahasa yang menginterpretasikan program Anda seperti yang Anda inginkan. (Bagaimanapun, bendera yang dimaksud, uadalah gabungan, jadi itu hanya masalah mengubah skor daripada sesuatu yang membatalkannya.)
10

Mathematica, 62 58 55 byte

Tiga byte terakhir yang disimpan sepenuhnya karena Martin Ender!

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

Fungsi tanpa nama mengambil argumen integer positif dan mengembalikan Trueatau False.

Algoritma rekursif, dengan #4<4menjadi basis kasus kebenaran (kita hanya perlu mengembalikan Truepada imput 1, tetapi kasus basis tambahan baik-baik saja). Jika tidak, kami menghitung pembagi terkecil-terkecil (yang seharusnya prima) dari input dengan Divisors[#][[6-4]]; jika lebih besar dari 2024 ( 44*46) maka kita keluar dengan False, kalau tidak kita memanggil fungsi secara rekursif (menggunakan #6set ke #0) pada input dibagi dengan faktor prima kecil ini #(yang harus kita ungkapkan sebagai #^-1kali input #4, karena /tidak diizinkan).

Secara struktural, babak pertama #4<4||#<44*46&&#6[#^-1#4]&adalah fungsi anonim enam argumen, yang disebut dengan argumen Divisors[#][[6-4]], Null, Null, #, Null, dan #0; ini adalah untuk mendapatkan sekitar larangan pada karakter 2, 3dan 5.

Versi sebelumnya, yang menyelamatkan empat byte dengan mengganti 8018-6000dengan 44*46, terinspirasi oleh ais523 Jelly jawaban (Martin Ender juga tampaknya terinspirasi oleh komentar ais523):

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

Ini sangat buruk: Saya masih tidak tahu cara untuk benar-benar menetapkan variabel di Mathematica di bawah batasan ini! Baik =dan edi Setdilarang. Menghindari +dan )juga merupakan masalah, tetapi tidak terlalu sulit untuk dikerjakan dengan mengorbankan lebih banyak byte.

Greg Martin
sumber
Anda mungkin dapat mengatur parameter lambda daripada variabel. (Yang mengatakan, #2juga akan dianulir, jadi Anda harus berhati-hati dengan bagaimana lambda Anda bersarang, dan kurangnya tanda kurung mungkin menyulitkan.)
Menerapkan saran @ ais523 menghemat tiga byte: #4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&melempar banyak peringatan karena sekarang mencoba Divisors[#][[2]]sebelum memastikan bahwa input lebih besar dari 1 (atau 3), tetapi hasilnya masih benar.
Martin Ender
Oh man, itu sangat licik.
Greg Martin
7

Haskell, 48 47 byte

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

Pada dasarnya terjemahan dari jawaban Dennis 'Jelly . xnatau menyimpan byte.

Digunakan […]!!0sebagai tanda kurung karena )dilarang, dan snd+ divModkarena mdi moddan remdilarang.

Lynn
sumber
Trik yang bagus dengan divMod! Saya pikir Anda dapat mengganti !!0<1dengan <[1]. Tapi kelihatannya itu itu korsleting untuk digunakan divsebagai [\p n->p^n`div`n*n>p^n-1]!!0$product[1..44*46].
xnor
Ada juga \n->[0|p<-[product[1..44*46]^n],0<-[p,p-n..0]], yang menggunakan bahwa output hanya perlu konsisten.
xnor
@xnor Jangan ragu untuk mempostingnya sebagai jawaban yang terpisah, saya pikir mereka cukup berbeda dari milik saya ^^
Lynn
6

Pyke, 10 8 7 9 byte

P_Z|hwMX<

Coba di sini!

Disimpan 1 byte dengan menggunakan cara Dennis menghasilkan 2025

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

Brachylog , 9 10 byte

*$ph$r*<90

Cobalah online!

Pada dasarnya menggunakan algoritma yang sama dengan jawaban saya yang lain. $phmenemukan hfaktor prima pertama ( $p); ini adalah faktor prima terbesar, karena daftar faktor prima Brachylog berubah dari terbesar ke terkecil. Lalu saya mengambil akar kuadrat ( $r), ganda ( *), dan menguji untuk melihat apakah itu kurang dari 90 ( <90).

Saya harus menggandakan input pertama karena 1 tidak memiliki faktor prima (dan dengan demikian tidak ada faktor prima pertama). Ini menambahkan faktor prima ekstra 2, yang tidak dapat memengaruhi apakah suatu angka gembur 2017, tetapi mencegah kegagalan saat menangani 1.


sumber
5

Sebenarnya , 9 byte

τyM:44u²≥

Terima kasih kepada Dennis untuk banyak byte!

Cobalah online!

Penjelasan:

τ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?
Mego
sumber
5

Mathematica, 66 74 byte

Terima kasih kepada Dennis untuk menunjukkan bahwa U+F4A1ini dilarang.

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

Penjelasan:

Divisors@#: Daftar pembagi bilangan bulat dari argumen pertama #.

0<1: Golf for True(juga menghindari penggunaan surat e).

Divisors@d^0: Daftar formulir {1, 1, ..., 1}dengan panjang sama dengan jumlah pembagi d.

Tr: Untuk daftar datar, Trkembalikan jumlah daftar itu. Dengan demikian Tr[Divisors@d^0]mengembalikan jumlah pembagi d.

Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]]: Fungsi anonim dengan dua argumen xdan d. Idenya adalah yang dmerupakan pembagi #dan kami menguji untuk melihat apakah itu komposit atau kurang dari atau sama dengan 2017(inklusif). 2017-Friability setara dengan semua pembagi yang memenuhi kondisi ini. Sebagai ais523 ditemukan, menjadi prima kurang dari atau sama dengan 2017setara dengan menjadi prima kurang dari 2025. Seperti yang ditunjukkan Greg Martin , cukup untuk menguji apakah itu kurang dari 2024=44*46. Argumen xbertindak sebagai akumulator untuk apakah semua pembagi yang dijumpai sejauh ini memenuhi properti ini. Kami kemudian meninggalkan Foldfungsi ini melalui semua pembagi #dengan nilai awalTrue, Karena kita memiliki akses ke tidak Mapatau /@.

ngenisis
sumber
1
Cara untuk berjuang melalui batasan!
Greg Martin
2

05AB1E , 10 byte

fθ46n99-›È

Mengembalikan 1 jika benar, 0 sebaliknya.

Cobalah online!

Penjelasan

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
Kaldo
sumber
Selamat datang di PPCG!
Martin Ender
1

MATL , 15 byte

t:\~ftZp*44QU<A

Output 0untuk non-2017-friable atau 1untuk 2017-friable.

Cobalah online! Atau verifikasi semua kasus uji .

Program ini memeriksa bahwa semua byte adalah komposit.

Penjelasan

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
Luis Mendo
sumber
1

Bash, 144 byte

Pengkodean 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`

Seperti biasa untuk shell, kode keluar menunjukkan berhasil (0) atau gagal (non-0).

Ini secara efektif merupakan pengejaan yang berbeda

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

Kami mendapatkan faktor terbesar dengan factor $1|grep -o '[0-9]*$'; yang tr -d :adalah untuk khusus-kasus untuk = input 1.

Ekspresi $[6*6*69-466]dievaluasi hingga 2018.

Itu sulit digunakan truntuk nama-nama perintah dan masih menggunakan substitusi perintah - saya tidak bisa menggunakan formulir bersarang $( ), jadi saya akhirnya menyalurkan ke Bash lain untuk mengevaluasi hasilnya.

Hasil tes:

$ 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

Konfirmasi kode karakter:

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

Pyth, 11 byte

!s>R^h44h1P

Cobalah online. Suite uji.

Gunakan trik Dennis untuk mendapatkan 2025, lalu periksa apakah tidak ada faktor input utama yang lebih besar.

PurkkaKoodari
sumber
0

Japt , 14 byte

k æ¨44*46 ?0:1

Mengembalikan 1 jika benar, 0 jika salah.

Coba di sini .

Oliver
sumber
kmemiliki nilai prima
Perwujudan Ketidaktahuan
0

Braingolf , 11 byte [sangat tidak bersaing]

VRp#ߢ-?0:1

Cobalah online!

Tidak dapat dibaca karena ߢsekrup dengan angka, namun masih berfungsi dalam juru bahasa.

Saya bahkan tidak memperhatikan batasan karakter ketika saya menulis ini, tetapi yang harus saya lakukan adalah mengubah karakter unicode yang aneh dari 2017 hingga 2018.

Mengingat 2018 bukan prima, setiap prima <= 2018juga<= 2017

Penjelasan

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
Skidsdev
sumber