最短の辞書編集上最小の生成文字列


16

文字列は、の無限の繰り返しの部分文字列である場合に文字列をx 生成します。たとえば、を生成します。yyxabcbcabcab

プログラムを作成して、入力を生成する最短の辞書編集上最小の文字列を見つけます。標準入力には1行のテキストが与えられます。生成文字列を標準出力に出力する必要があります。例えば:

入力

bcabcabca

出力

abc

最短のコードが優先されます。入力には文字a〜z(および必要に応じて末尾の改行)のみが含まれると想定できます。


出力は順不同ですか?出力はbacあなたの例ではなくabc
アリの

@GroovyUser:いいえ、入力はbacsの繰り返しパターンのサブストリングではありません。
キースランドール

ただし、入力はの部分文字列で構成できます(bca)^n。これはbca、の例と同じように有効ですabc
JAB

1
@JAB:bca語彙的には最小ではありません。
キースランドール

ああ、どういうわけかその部分を見逃した。
JAB

回答:


9

Ruby 1.9、40文字

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

入力が改行で終了しないと仮定します。また、大きな結果を得るにはおそらくとんでもなく遅いです。

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

2

Pythonの88 185の文字

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

出力:

bcabcabca
abc

aaa
a

abc
abc

cccbbcccbbcccbb
bbccc

barfoofoobarfoofoo
arfoofoob

bacabac
abacbac

一部の入力、たとえば「bacabac」に対して辞書的に最小の文字列を提供しません
ハワード

@Howardあなたは正しい。私は自分のコードを更新しましたが、今ではずっと長くなっていますが、文字列をbacabac正しく処理しています。
ベイダー

「ABACは」正しいだろう、@ yogsotothの回答を参照してください。bacabacの ABACを。
ハワード

2

Haskell、299128文字

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

jloyに感謝します!現在、バージョンはどちらもはるかに短く、正しいと思います。


1
したがって、良いニュースは、VenteroのRubyソリューションのようにstdinで入力を受け入れると、このソリューションを約91文字までゴルフできることです。残念ながら、入力cabcabcabcはを生成するabcabcため、この解決策はまだありません。q++q++q目的の結果を得るには、変更する必要があると思います。しかし、私が修正しようとした簡単な試みは、145文字にまで戻りました。(ネタバレはここにある:gist.github.com/1035161

ありがとう!すべての部分文字列を取得するためのinits << = tailsについては、相互作用についても知りませんでした。バージョンを少し変更して、文字を少し増やしました。ソートを削除し、filter(not.null)をfilter((/ =) "")で変更しました。再度、感謝します!
yogsototh

なぜ(/=)""条件が必要なのですか?何もしないようです。また、ラムダを取り除くと、.演算子を使用してwを完全に取り除き、メイン関数をmain=interact sに変更して、いくつかの文字を保存できます。
ローター

「bca」の答えは間違っていると思います。「abc」であるはずですが、現在は「bca」です。
ローター

可能な解決策の1つは、のpermutations代わりに使用することですtails
ローター

2

Python、121 137 129文字

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)

編集:JiminPが発見したバグを修正


うわー、素晴らしい!残念ながら、それaababは文字列のために印刷されますababa... :(
JiminP

OK、修正...長くなってきた:(
ジュールオレオン

2

Ruby 1.9、36

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

Venteroのソリューションと同じアプローチを使用します。


2

Python、 161159166140141134 132文字

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

編集:ジュール・オレオンのコメントを読んだ後、コードをゴルフ。bcdabcdab結果として生じる「バグ」を削除しましたabbc

EDIT2:JulesOlléonが発見したバグ(のabaa結果aaa)を修正しました。

私はPythonについてよく知らないので、このコードはおそらく「ゴルフではない」でしょう。

私はこのルールが大好きです:

入力にはa〜zの文字のみが含まれると仮定できます。

入力と出力

bcdabcd
abcd

bcabcabca
abc


abcdabcd
abcd

bcdabcdab
abcd

barfoofoobarfoofoobar
arfoofoob

cccbbcccbbcccbb
bbccc

aaaaaaaaaaaaaaaa
a

thequickbrownfox
brownfoxthequick

ababa
ab

abaa
aab

1
茶色のキツネ、速い!犬、怠け者!
JiminP

素敵なソリューション、かなり短く、おそらくここで最高の複雑さ!あなたはそれを少しゴルフすることができます-たとえば、文字列を比較するために「int」は必要ありません。「while i> 0」を「while i」に、「y = y + y」を「y * = 2」に置き換えます。
ジュールオレオン

実際に問題があります:ABAAのためには、AAAを印刷し...
ジュール・Olléon

@Julesコメントありがとうございます!私はそれについて考えていませんでした
...-JiminP

i-=1代わりに行うことができますi=i-1。増分についても同様です。
ロージャッカー

1

Mathematica 124バイト

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

空白と改行(行末にセミコロンが存在する場合)はMathematicaでは意味がなく、読みやすくするためにここに含まれています。

入力は、最初の行の引用符の間に入ります。関数としてリキャストする場合、次のような文字列入力を受け取ります。

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" *)

それは128バイトです。

Forループが最初かかるi入力の文字を少なくとも最大入力の長さにそれらを繰り返し、その後、入力結果のサブストリングであるか否かをチェックします。文字列のピリオドの長さを見つけると、StringPartitionコマンドはそのピリオドの2つのコピーを連結し、その長さのすべての部分文字列を取得し(基本的にすべての循環順列を取得し)、First@Sort辞書式順序でそれらの最初の1つを見つけます。


0

javascript 96文字。

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

ワーキングプランカー


1
コミュニティへようこそ!コードをテストすることはできませんでしたが、GET / POSTからコードを読み取り、alertまたはconsole.logで書き込むか、入力をパラメーターとして受け取り、出力を返す関数を提供できますか?
アーロン

@AaronGOUZITはpluckrを追加しました
ngLover

おかげで助かります。それでも、投稿したコードを単独で使用することはできないため、バイトカウントが不正になります。さらに重要なのは、コードが仕様を尊重していないことです。「生成文字列」ではなく、使用される一連の一意の文字を返すと思います。入力を取得します。更新されたコードを楽しみにしています!
アーロン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.