Temukan prime contiguous terbesar dalam sebuah string

8

Dalam keadilan, ini didasarkan pada pertanyaan StackExchange - tapi itu pertanyaan yang bagus.

Tantangannya cukup sederhana:

  1. Ambil serangkaian angka
  2. Temukan dan cetak nomor prima bersebelahan terbesar dalam string

Mencetak:

  • Jumlah karakter terendah menang.
  • Victor kemungkinan akan menjadi entri skrip golf tetapi kami tidak akan menentangnya, karena kita semua bersenang-senang dan mempelajari banyak hal, benar.
  • Pemenang kami akan diberikan ketika saya melihat bahwa saya belum mencentang tombol hijau.

Asumsi:

  • String hanya berupa angka
    • Jika string berisi huruf, Anda mungkin memiliki perilaku tidak terdefinisi
  • String berisi setidaknya 1 prime
    • Jika string tidak mengandung 1 bilangan prima yang valid, Anda mungkin memiliki perilaku tidak terdefinisi
  • Kecepatan bukanlah kendala
    • Gunakan algoritma prima yang lebih pendek daripada yang lebih cepat.
    • Jika entri Anda akhirnya selesai, tidak apa-apa, pastikan itu akan terbukti terjadi sebelum panasnya kematian alam semesta.
  • Panjang string dapat diasumsikan kurang dari 15 karakter

Sebagai contoh:

>> Input:  3571
<< Output: 3571

>> Input:  123
<< Output: 23

>> Input:  1236503
<< Output: 236503

>> Input:  46462
<< Output:  2

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

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

>> Input:  4601
<< Output: 601

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

Kemungkinan implementasi:

  1. Temukan semua substring dari input, periksa apakah mereka prima. - Legostormtroopr (asli)
  2. Temukan semua bilangan bulat kurang dari input, periksa apakah mereka ada di input kemudian periksa apakah bilangan prima - Ben Reich
  3. Ambil daftar semua bilangan prima kurang dari input, periksa apakah ada di input - daniero
Komunitas
sumber
1
Ini pada dasarnya seperti: menemukan cara pengulangan pada setiap substring dari string, dan periksa keutamaan substring. Kedengarannya seperti masalah yang menyenangkan.
Justin
1
@ Quincunx Benar. Tapi saya ingin membuatnya sesederhana mungkin. Dan juga menjatuhkan referensi budaya pop.
1
@ Quincunx Bukan hanya itu algoritma yang mungkin! Lihat jawaban saya, yang dapat digambarkan sebagai: Iterasi atas semua bilangan bulat kurang dari input, dan tentukan yang terbesar yang merupakan substring dari input dan prima.
Ben Reich
@ Ben Reich Atau seperti yang saya lakukan, beralih ke semua bilangan prima kurang dari atau sama dengan input dan melihat mereka berada di string.
daniero
1
Mengapa saya peduli dengan bidang yang sama? Kita tahu skrip mana yang menang, tetapi menang bukanlah segalanya? Buat kode tersingkat dan terpintar mungkin dalam bahasa favorit Anda.

Jawaban:

6

GolfScript 40 37

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

Ini terlihat pada semua angka yang kurang dari atau sama dengan input, memfilter ke bawah ke nomor yang merupakan substring dari input, dan kemudian menyaring lebih jauh ke bilangan prima. Kemudian, dibutuhkan elemen seperti terbesar (yang jelas dijamin memiliki angka paling banyak).

Mari kita bagi menjadi dua bagian utama:

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

Bagian dari kode ini menyaring ke semua string integer yang terkandung dalam input. Ia menggunakan aksen kubur untuk mengubah angka menjadi string, dan kemudian ?untuk menentukan indeks substring. Karena ?pengembalian -1dalam hal tidak ada kontainmen, tambahkan menggunakan )sehingga output 0untuk non-substring, yang akan berperilaku baik dengan ,penyaringan.

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

Bagian dari kode ini menyaring ke bilangan prima dengan menghitung jumlah faktor kurang dari angka yang diberikan (bilangan bulat adalah faktor hanya jika number factor %!adalah 1. Bilangan prima akan memiliki tepat 1 faktor yang benar-benar kurang dari itu sendiri, demikian juga 1=.

Karena angkanya berurutan, ambil yang terakhir dan kosongkan tumpukan menggunakan )\;

Ini jelas tidak seefisien mungkin (karena agak tidak perlu berulang pada semua bilangan bulat kurang dari input), tetapi masih berakhir dengan input besar seperti 1236503relatif cepat di komputer saya (1 menit).

Ben Reich
sumber
1
Terima kasih kepada Anda, saya mencukur jawaban sebanyak yang Anda gunakan: P
1
Jika inputnya prima maka ini tidak akan menemukannya, karena filter pertama diterapkan ke angka hingga tetapi tidak termasuk itu. Biaya perbaikan satu karakter, tetapi ada dua karakter yang akan disimpan dengan menyimpan input dalam variabel daripada menyatu dengan blok (karena dengan cara itu Anda menghilangkan beberapa kesalahan).
Peter Taylor
4

Python 2.7 - 84

Berikut ini adalah implementasi referensi untuk dikalahkan, saya menggunakannya untuk output contoh dalam pertanyaan, jadi ini dijamin untuk bekerja * Bukan jaminan yang sebenarnya

Peningkatan tanpa malu berdasarkan solusi yang jauh lebih baik dari Ben Reich daripada yang asli saya. Dengan bantuan utama dari Volatilitas

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

Mantra sebelumnya dari baris kedua meliputi:

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

Versi asli - 143

N=`input()`
p=lambda n:[n%i for i in range(2,n)if n%i==0]
print max(int(N[j:i])for i in range(len(N)+1)for j in range(i)if not p(int(N[j:i])))
Komunitas
sumber
2
Singkirkan pdan ganti not p(x)dengan sum(x%i for i in range(2,x))<1- itu akan bekerja dan membuat Anda turun ke 86 karakter.
Volatilitas
@Vatilitas Tidak cukup, sum(x%i for i in range(2,x))akan cukup tinggi untuk sebagian besar angka. Tapi generatornya adalah ide bagus dan saya mendapatkannya di 91.
Sebenarnya, Anda tahu, saya pikir Anda bisa menggunakannya all(x%i for i in range(2,x)).
Volatilitas
Menghemat satu lagi, terima kasih :)
Beralih ke alldan tanda kurung Simpan (`x`in`N`)beberapa lagi juga!
1

Ruby 61

Ambil semua bilangan prima hingga N dan lihat apakah semuanya ada dalam string

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

Saya pikir ini hanya berfungsi pada Ruby 1.9 dan yang lebih baru, tapi saya tidak yakin.

daniero
sumber
Apa yang dikembalikan program Anda untuk contoh tes terakhir? Perdana, 2, ada di dalamnya, tetapi tidak harus diakui (jika saya memahami persyaratan dengan benar).
DavidC
1
@ David Carraher: Asumsi: String hanya angka; Jika string berisi huruf, Anda mungkin memiliki perilaku tidak terdefinisi. Saya pikir "perilaku tidak terdefinisi" berarti bahwa ia dapat meludahkan 2 atau bisa meludahkan bubur
Kyle Kanos
Kyle, observasi yang sangat bagus!
DavidC
1

Scala (83 karakter)

Saya tidak yakin bagaimana memberikan input ke program sehingga saya anggap nsebagai input. Inilah solusi aktual (berdasarkan pada mana panjang solusi dievaluasi). Di bawah ini adalah bentuk solusi yang dapat dieksekusi (yang belum golf) untuk dieksekusi bersama dengan output (untuk sampel memberikan OP miliki).

Larutan:

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

Solusi yang dapat dieksekusi:

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

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

Output sampel:

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

Penjelasan:

Langkah-langkahnya cukup lurus ke depan.

input -> Temukan semua substring -> filter non primes -> cari nilai terpanjang

  • main(Array[String]): Metode memberikan input sampel dan menjalankan metode q(String)untuk setiap input
  • q(String): Membungkus logika program aktual dari p(String)sehingga setiap pengecualian dilaporkan dengan tepat. Membantu dalam memformat output lebih baik karena input yang tidak valid akan mendapatkan NumberFormatExceptiondi mana kekurangan prima akan melemparUnsupportedOperationException
  • p(String): Logika aktual dari program. Mari kita bagi penjelasan ini menjadi beberapa bagian
    • n.inits: Membuat sebuah Iteratoruntuk mengulangi input String ( n)
    • flatMap(f): Menerapkan operasi pada Iteratordan mendorong hasilnya menjadi aList
      • _.tails.toList.init.map(BigInt(_)): Membagi Stringdan menghapus kosong Stringdari resultan List. Akhirnya mengkonversi Stringke BigIntyang setara dengan java.math.BigInteger. Untuk alasan bermain golf, BigIntdipilih (nama pendek).
    • filter(f): jika fkembali false, nilai dihapus dari resultanList
      • _ isProbablePrime 1: Baris ini bisa saja ditulis _.isProbablePrime(1)tetapi representasi yang digunakan menyimpan 1 byte. Baris ini benar-benar memeriksa apakah nilainya prima (probabilistically; karena certaintydiatur ke 1, waktu eksekusi naik tetapi sistem memastikan (lebih atau kurang) bahwa jumlahnya adalah bilangan prima.
    • max: Menemukan nilai maksimum (bukan Stringberdasarkan panjang. Nilai maks aktual)
j_textz
sumber
1

J ( 24 22)

Membaca dari keyboard sebenarnya lebih pendek daripada mendefinisikan suatu fungsi.

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

Uji:

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

Penjelasan:

  • 1!:1[1: membaca sebaris teks dari keyboard
  • ".\.\: evaluasi ( ".) dari setiap akhiran ( \.) dari setiap awalan ( \) dari string.
  • ;: ratakan matriks
  • *1&p:: kalikan setiap nilai dengan apakah itu prima atau tidak (jadi semua nonprima akan menjadi nol)
  • >./: dapatkan nilai terbesar dalam daftar
marinus
sumber
1

Haskell, 94

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

Vektorweg
sumber
3
Ingin menjelaskan proses di balik ini untuk mereka yang tidak melakukan Haskell?
@LegoStormtroopr Tentu, saya mencobanya. main = getLine >>= print . maximum . filter isPrime . map read . allNumsadalah bentuk aslinya. itu mendapat garis dan memberikan ( >>=) ke fungsi gabungan besar - dikombinasikan dengan .operator infiks, yang hanya menempatkan hasil dari fungsi yang tepat ke fungsi kiri. hal-hal seperti (\x -> ...)adalah ekspresi lambda. parameter fungsi diterapkan tanpa tanda kurung dan fungsi dapat diterapkan secara parsial ( (0/=)misalnya fungsi, yang memeriksa apakah angka bukan 0).
Vektorweg
allNums = init . scanr (:) []. scanrpemindaian dan init menghapus nilai terakhir dari hasil scanr, yang merupakan string kosong, yang tidak dapat dibaca ke Integer. map readmembaca daftar string ke nilai yang ditentukan. dalam hal ini Integer atau sesuatu yang lain dari typeclass Integral, karena isPrimememerlukan Integral. filter isPrimetidak persis, apa yang dikatakannya. isPrime x = and $ map ((0/=). mod x) [2..(x-1)]berarti, diberi daftar dari 2 hingga (x-1), lakukan pemeriksaan divisi dan kemudian terapkan andke daftar Bool.
Vektorweg
ada beberapa fungsi yang lebih jelas dan kuat dalam modul standar lainnya, tetapi saya mencoba untuk bekerja dengan modul Prelude saja. ;)
Vektorweg
1

Perl 6 (40 karakter, 41 byte)

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

getInput pertama $_, ini membuat panggilan pertandingan regex lebih pendek. :exmemberikan pencocokan lengkap untuk regex, itu akan memberikan semua kemungkinan. Hyper op (atau +<<berfungsi juga) akan membuat angka dari objek Match, yang diteruskan grepdengan &is-primesub sebagai pemilih. Akhirnya ambil maksimum dari daftar yang tersisa dan keluarkan.

Ayiko
sumber
0

Mathematica 67 47

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

Penjelasan

Kode adalah fungsi murni. Tidak memiliki nama. Di dalamnya, #mewakili string input penuh.

StringCases mengambil input, #, dan memeriksa substring, a dari satu karakter atau lebih (itu sebabnya __ digunakan alih-alih _) yang merupakan bilangan prima; PrimeQ harus mengembalikan True untuk substring.

Semua kasus yang menguntungkan, yaitu substring yang merupakan bilangan prima, secara default dikembalikan dalam daftar. 〚1〛, atau [[1]]mengambil bagian pertama, yaitu, elemen pertama dari daftar bilangan prima. element[[1]]adalah singkatan Part[element, 1]. Jika ada lebih dari satu prime, yang pertama akan menjadi prime terpanjang ( StringCasesperiksa substring terpanjang terlebih dahulu).

Contohnya

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

"236503"

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

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

DavidC
sumber
Ingin menjelaskan proses di balik ini untuk mereka yang tidak melakukan Mathematica?
1
Saya harus mengatakan bahwa penggunaan 〚1〛karakter adalah sadis pada kita, non-Mathematica, programmer. (isyarat saya dengan panik khawatir bahwa saya akan buta, kemudian melihat kurung lain dengan kebingungan bahwa mereka terlihat tajam, sedangkan yang ini tidak!)
eithed
〚1〛memiliki kurung ganda dan setara dengan [[1]]. Saya menggunakannya karena braket ganda dianggap sebagai satu karakter.
DavidC
@ David Carraher Ya, tapi saya pikir Anda harus menghitungnya sebagai dua byte sehingga tidak benar-benar menyelamatkan Anda apa pun.
Michael Stern
Tapi saya menghitung karakter, bukan byte. Tolong jelaskan.
DavidC
0

Perl 6 (50 karakter, 51 byte)

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

memetakan string ke angka, maxmendapatkan angka terbesar, getmenerima garis. /(.+)<?{(+$0).is-prime}>/adalah ekspresi reguler yang mendapatkan semua bilangan prima <?{}>adalah pernyataan kode. is-primeadalah Intmetode kelas yang memeriksa apakah angka adalah bilangan prima. Saya perlu memberikan nilai ke angka dengan menggunakan +, karena ini Strsecara default. :exberarti mencoba untuk menemukan SEMUA cocok (termasuk yang tumpang tindih dengan yang lain). Karena bug Rakudo Perl, saat ini mustahil digunakan di m//sini.

Ini berfungsi untuk nomor apa pun, dan jika Anda menghapus max(atau menggantinya dengan sort) Anda akan mendapatkan daftar semua bilangan prima dalam nomor tersebut, untuk bonus tambahan (bukan berarti ini memberikan poin, atau apa pun). Misalnya (dengan sortdalam hal ini):

1234567890
2 3 5 7 23 67 89 4567 23456789
Konrad Borowski
sumber