String penghasil yang terpendek, terkecil secara leksikografis

16

Sebuah string x menghasilkan sebuah string yjika ymerupakan sebuah substring dari pengulangan tak terbatas x. Misalnya abcmenghasilkan bcabcab.

Tulis sebuah program untuk menemukan string terpendek, leksikografis terkecil yang akan menghasilkan input. Anda diberi input standar satu baris teks. Anda harus mencetak string penghasil ke output standar. Sebagai contoh:

memasukkan

bcabcabca

keluaran

abc

Kode terpendek menang. Anda dapat berasumsi bahwa input hanya berisi karakter az (dan baris baru tambahan jika Anda mau).

Keith Randall
sumber
Output harus dalam urutan apa pun? Katakanlah output bisa bacdalam contoh Anda, bukan abc?
Semut
@GroovyUser: tidak, input bukan substring dari pola bacs yang berulang .
Keith Randall
Tetapi input dapat terdiri dari substring (bca)^n, yang artinya bcasama validnya dengan contoh yang diberikan abc.
JAB
1
@ JAB: bcabukan yang terkecil secara leksikografis.
Keith Randall
Ah, entah bagaimana aku melewatkan bagian itu.
JAB

Jawaban:

9

Ruby 1.9, 40 karakter

gets;a=?a;a.next!until(a*~/$/)[$_];$><<a

Mengasumsikan input tidak diakhiri oleh baris baru. Juga mungkin sangat lambat untuk hasil yang lebih besar.

$ echo -n "bcabcabca" | ruby genlex.rb 
abc
$ echo -n "barfoobarfoobarfoo" | ruby1.9 genlex.rb 
arfoob
Ventero
sumber
2

Python 88 185 karakter

import re
s=raw_input()
m=s.index(min(s))
s=s[m:]+s[:m]
i=0
while s.replace(s[:i],''):i+=1
m=min(s[:i])
s=re.findall('%s[\w]*?(?=%s|$)'%(m,m),s[:i])
m=s.index(min(s))
print ''.join(s[m:]+s[:m])

Keluaran:

bcabcabca
abc

aaa
a

abc
abc

cccbbcccbbcccbb
bbccc

barfoofoobarfoofoo
arfoofoob

bacabac
abacbac
Vader
sumber
Tidak memberi Anda string terkecil secara leksikografis untuk beberapa input, misalnya "bacabac"
Howard
@ Bagaimana Anda benar. Saya telah memperbarui kode saya, sekarang jauh lebih lama, tetapi menangani string seperti bacabacdengan benar.
Vader
"abac" benar, lihat jawaban @ yogsototh: a bacabac abac.
Howard
2

Haskell, 299 128 karakter

import Data.List
main=interact(\z->minimum$filter(\w->isInfixOf z$concat$replicate(length z)w) $filter((/=)"")$inits=<<tails z)

Terima kasih kepada jloy! Sekarang versi keduanya jauh lebih pendek dan saya percaya benar.

yogsototh
sumber
1
Jadi, kabar baiknya adalah bahwa mungkin untuk menurunkan solusi ini ke sekitar 91 karakter jika Anda menerima input pada stdin seperti dalam solusi Ruby Ventero. Sayangnya, input cabcabcabcmenghasilkan abcabc, jadi solusi ini tidak cukup ada. Saya pikir Anda harus memodifikasi q++q++quntuk mendapatkan hasil yang diinginkan. Namun, upaya cepat saya untuk memperbaiki hal-hal yang terbentur mencapai 145 karakter. (Spoiler ada di sini: gist.github.com/1035161 )
Terima kasih! Saya tidak tahu tentang berinteraksi dan tidak pernah tentang inits << = ekor untuk mendapatkan semua substring. Saya sedikit mengubah versi Anda untuk mendapatkan sedikit karakter. Saya menghapus sort dan mengubah filter (not.null) dengan filter ((/ =) ""). Terima kasih lagi!
yogsototh
Mengapa Anda membutuhkan (/=)""kondisi? Sepertinya tidak melakukan apa-apa. Selain itu, menghilangkan lambdas membantu: Anda dapat menyingkirkan w sama sekali menggunakan .operator dan mengubah fungsi utama main=interact suntuk menyimpan beberapa karakter.
Rotsor
Saya pikir jawaban untuk "bca" salah. Seharusnya "abc", tetapi "bca" sekarang.
Rotsor
Salah satu solusi yang mungkin adalah menggunakan permutationsalih-alih tails.
Rotsor
2

Python, 121 137 129 karakter

s=raw_input()
n=len(s)
l=[(s+s)[i/n:i/n+i%n+1]for i in range(n*n)]
print min(filter(lambda x:(x*len(s)).find(s)+1,sorted(l)),key=len)

EDIT: memperbaiki bug yang ditemukan oleh JiminP

Jules Olléon
sumber
Wow itu bagus! Sayangnya, ia mencetak aababuntuk string ababa... :(
JiminP
Oke, sudah ... sudah mulai :(
Jules Olléon
2

Ruby 1.9, 36

$><<(?a..gets).find{|s|(s*~/$/)[$_]}

Menggunakan pendekatan yang sama dengan solusi Ventero.

Lowjacker
sumber
2

Python, 161 159 166 140 141 134 132 karakter

y=raw_input();i=n=l=len(y)
while i:
 if (y[:i]*l)[:l]==y:n=i
 i-=1
x=y[:n];y=x*2
while i<n:
 x=min(x,y[i:i+n])
 i+=1
print x

EDIT : Memutar kode setelah membaca komentar Jules Olléon. Menghapus 'bug' yang bcdabcdabmenghasilkan abbc.

EDIT2 : Memperbaiki bug ( abaahasil dalam aaa) yang terlihat oleh Jules Olléon.

Saya tidak tahu tentang Python dengan baik, jadi kode ini mungkin 'tidak golf'.

Saya suka aturan ini:

Anda dapat menganggap input hanya berisi karakter ...

Input & Output

bcdabcd
abcd

bcabcabca
abc


abcdabcd
abcd

bcdabcdab
abcd

barfoofoobarfoofoobar
arfoofoob

cccbbcccbbcccbb
bbccc

aaaaaaaaaaaaaaaa
a

thequickbrownfox
brownfoxthequick

ababa
ab

abaa
aab
JiminP
sumber
1
Rubah coklat, cepat! Anjing, si malas!
JiminP
Solusi yang bagus, cukup singkat dan mungkin kompleksitas terbaik di sini! Anda bisa sedikit golf - misalnya, Anda tidak perlu "int" untuk membandingkan string; dan ganti "while i> 0" dengan "while i" dan "y = y + y" oleh "y * = 2".
Jules Olléon
Sebenarnya ada masalah: untuk abaa itu mencetak aaa ...
Jules Olléon
@Jules Terima kasih atas komentarnya! Saya tidak memikirkan yang itu ...
JiminP
Anda dapat melakukan i-=1bukan i=i-1. Begitu juga untuk increment.
Lowjacker
1

Mathematica 124 byte

x = StringLength@(y = "");
For[i = 1, ! (s = y~StringTake~i)~StringRepeat~x~StringContainsQ~y,i++];
First@Sort@StringPartition[s <> s, i, 1]

Spasi dan baris baru (dengan adanya titik koma di ujung garis) tidak memiliki arti dalam Mathematica dan disertakan di sini untuk keterbacaan.

Input masuk di antara tanda kutip di baris pertama. Jika disusun kembali sebagai fungsi, itu membutuhkan input string seperti:

f=(x=StringLength@(y=#);For[i=1,!(s=y~StringTake~i)~StringRepeat~x~StringContainsQ~y,i++];First@Sort@StringPartition[s<>s,i,1])&

f@"bca"

(* "abc" *)

f@"abaa"

(* "aab" *)

maka itu 128 byte.

The ForLoop mengambil pertama ikarakter input dan mengulangi mereka setidaknya sampai panjang input, kemudian memeriksa apakah input adalah substring dari hasilnya. Setelah menemukan panjang periode string, StringPartitionperintah merangkai dua salinan periode itu dan mengambil semua substring dari panjangnya (pada dasarnya mendapatkan semua permutasi siklik), kemudian First@Sortmenemukan yang pertama dari mereka ketika dipesan secara leksikografis.

LLlAMnYP
sumber
0

javascript 96 Karakter.

var temp = {},len = str.length;
for(i in str) 
temp[str[i]] = true;
Object.keys(temp).join(""); 

Plunkr bekerja

ngLover
sumber
1
Selamat datang di komunitas! Namun saya tidak dapat menguji kode Anda, dapatkah Anda memberikan pembacaan kode dari GET / POST dan menulis dengan alert atau console.log atau fungsi yang mengambil input sebagai parameter dan mengembalikan output?
Aaron
@AaronGOUZIT menambahkan pluckr
ngLover
Terima kasih, itu membantu. Namun, kode yang Anda posting tidak dapat digunakan sendiri, sehingga menipu jumlah byte. Lebih penting lagi, saya khawatir kode Anda tidak menghormati spesifikasi: Saya yakin Anda mengembalikan satu set huruf unik yang digunakan daripada "menghasilkan string", yang harus dapat kami ulangi (secara keseluruhan) dengan pemotongan opsional untuk dapatkan input. Saya tak sabar untuk melihat kode Anda yang diperbarui!
Aaron