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


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

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

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.


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


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.


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

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.


0

javascript 96 Karakter.

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

Plunkr bekerja


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.