En kısa, sözlükbilimsel olarak en küçük üretim dizesi


16

Bir dize , sonsuz tekrarının alt dizesi ise dize x oluşturur . Örneğin üretir .yyxabcbcabcab

Girdiyi oluşturacak en kısa, sözlüksel olarak en küçük dizeyi bulmak için bir program yazın. Standart girişte tek bir metin satırı verilir. Oluşturma dizesini standart çıktıya yazdırmalısınız. Örneğin:

giriş

bcabcabca

çıktı

abc

En kısa kod kazanır. Girdinin yalnızca az karakterlerini (ve isterseniz bir satırsonu satırını) içerdiğini varsayabilirsiniz.


Çıktı herhangi bir sırada olmalıdır? Diyelim ki çıktı bacsenin yerine örnekte olabilir abcmi?
Ant'in

@ GroovyUser: hayır, girdi, tekrarlanan bacs deseninin bir alt dizesi değil .
Keith Randall

Ancak, giriş olabilir altmetni oluşur (bca)^naracı, bcasadece belirli bir örnek için geçerli olduğu gibi abc.
JAB

1
@JAB: bcasözlükbilimsel olarak en küçük değil.
Keith Randall

Ah, bir şekilde o kısmı özledim.
JAB

Yanıtlar:


9

Yakut 1.9, 40 karakter

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

Girdinin bir satırsonu tarafından sonlandırılmadığını varsayar. Ayrıca büyük sonuçlar için muhtemelen gülünç derecede yavaştır.

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

Çıktı:

bcabcabca
abc

aaa
a

abc
abc

cccbbcccbbcccbb
bbccc

barfoofoobarfoofoo
arfoofoob

bacabac
abacbac

Bazı girdiler için sözlükbilimsel olarak en küçük dizeyi vermez, örneğin "bacabac"
Howard

@ Haklısın. Kodumu güncelledim, şimdi çok daha uzun, ancak dizeleri bacabacdoğru şekilde işler .
Vader

"abak" doğru olur, bakınız @ yogsototh'un cevabı: bir bacabak abaktı.
Howard

2

Haskell, 299128 karakter

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

Jloy'a teşekkürler! Şimdi sürüm hem çok daha kısa hem de doğru olduğuna inanıyorum.


1
Yani iyi haber, Ventero'nun Ruby çözümünde olduğu gibi stdin girdisini kabul ederseniz bu çözümü yaklaşık 91 karaktere kadar golf oynamak mümkün. Ne yazık ki, girdi cabcabcabcüretiyor abcabc, bu nedenle bu çözüm tam olarak orada değil. q++q++qİstenen sonucu elde etmek için değişiklik yapmanız gerektiğini düşünüyorum . Çabuk şeyleri düzeltmeye yönelik hızlı girişimim 145 karaktere kadar geri döndü. (Spoiler burada: gist.github.com/1035161 )

Teşekkürler! Ben etkileşim hakkında hiçbir şey bilmiyordum ne de inits hakkında asla << = tüm alt dizeleri almak için kuyrukları. Sürümünüzü biraz karakter kazanmak için biraz değiştirdim. Sıralamayı kaldırdım ve filtreyi (not.null) filtreye ((/ =) "") göre değiştirdim. Tekrar teşekkürler!
yogsototh

Neden (/=)""koşula ihtiyacınız var ? Hiçbir şey yapmıyor gibi görünüyor. Ayrıca, lambdaslardan kurtulmak yardımcı olur: .operatörü kullanarak w'den tamamen kurtulabilir ve main=interact sbirkaç karakteri kaydetmek için ana işlevi değiştirebilirsiniz .
Rotsor

"Bca" cevabının yanlış olduğunu düşünüyorum. "Abc" olmalıdır, ama şimdi "bca" dır.
Rotsor

Olası bir çözüm permutationsyerine kullanmaktır 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: JiminP tarafından tespit edilen hata düzeltildi


Vay canına, harika! Ne yazık ki, aababdize için yazdırır ababa... :(
JiminP

Tamam, düzeltildi ... uzuyor :(
Jules Olléon

2

Yakut 1.9, 36

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

Ventero'nun çözümü ile aynı yaklaşımı kullanır.


2

Python, 16115616616140140 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 : Jules Olléon yorum okuduktan sonra kodu golf. bcdabcdabSonuç olarak ortaya çıkan bir 'hata' kaldırıldı abbc.

EDIT2 : Hata düzeltildi (abaaaaa Jules Olléon tarafından tespit edilen sonuç ) düzeltildi.

Python hakkında iyi bilmiyorum, bu yüzden bu kod muhtemelen 'golf değil'.

Bu kuralı seviyorum:

Girdinin yalnızca az karakter içerdiğini varsayabilirsiniz ...

Girişler ve Çıkışlar

bcdabcd
abcd

bcabcabca
abc


abcdabcd
abcd

bcdabcdab
abcd

barfoofoobarfoofoobar
arfoofoob

cccbbcccbbcccbb
bbccc

aaaaaaaaaaaaaaaa
a

thequickbrownfox
brownfoxthequick

ababa
ab

abaa
aab

1
Kahverengi tilki, çabuk! Köpek, tembel!
JiminP

Güzel bir çözüm, oldukça kısa ve muhtemelen burada en iyi karmaşıklık! Biraz golf olabilir - örneğin, dizeleri karşılaştırmak için "int" gerekmez; ve "i> 0" yerine "ise" "ve" y = y + y "yerine" y * = 2 "yazın.
Jules Olléon

Aslında bir sorun var: abaa için aaa yazdırıyor ...
Jules Olléon

@Jules Yorum için teşekkürler! Bunu düşünmedim ...
JiminP

Bunun i-=1yerine yapabilirsiniz i=i-1. Aynı şekilde artış için.
Lowjacker

1

Mathematica 124 bayt

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

Beyaz alan ve satırsonlarının (satır sonlarında noktalı virgül varsa) Mathematica'da bir anlamı yoktur ve okunabilirlik için buraya dahil edilmiştir.

Giriş, ilk satırdaki tırnak işaretleri arasına girer. İşlev olarak yeniden ayarlarsa, dize girdisi şöyle olur:

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

o zaman 128 bayt.

ForHalkası, birinci alan igiriş karakterleri ve en azından yukarı giriş uzunluğu bunları tekrar, daha sonra, giriş sonucu de bir alt etmediğini kontrol eder. Dizenin süresinin uzunluğunu bulduktan sonra, StringPartitionkomut o dönemin iki kopyasını birleştirir ve o uzunluktaki tüm alt dizeleri ondan alır (temelde tüm döngüsel permütasyonları alır), sonra First@Sortsözlükbilimsel olarak sipariş edildiğinde ilkini bulur.


0

javascript 96 Karakterler.

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

Çalışma Plunkr


1
Topluluğa hoş geldiniz! Kodunuzu test edemedim, GET / POST'tan kod okuma ve uyarı veya console.log ile yazma veya parametre olarak girişi alan ve çıkışı döndüren bir işlev sağlayabilir misiniz?
Aaron

@AaronGOUZIT ekledi pluckr
ngLover

Teşekkürler, bu yardımcı olur. Yine de, gönderdiğiniz kod tek başına kullanılamaz, böylece bayt sayısını hile yapar. Daha da önemlisi, kodunuzun özelliklere saygı duymadığından korkuyorum: İsteğe bağlı kesme ile (bir bütün olarak) tekrarlayabilmemiz gereken bir "oluşturma dizesi" yerine bir dizi benzersiz harf döndürdüğünüze inanıyorum. girdiyi elde eder. Güncellenmiş kodunuzu görmek için sabırsızlanıyorum!
Aaron
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.