Найкоротший, лексикографічно найменший породжувальний рядок


16

Рядок x генерує рядок, yякщо yє підрядком нескінченного повторення x. Наприклад abcгенерує bcabcab.

Напишіть програму, щоб знайти найкоротший, лексикографічно найменший рядок, який генерує вхід. На стандартному введенні вам надається один рядок тексту. Ви повинні надрукувати генераційний рядок до стандартного виводу. Наприклад:

вхід

bcabcabca

вихід

abc

Найкоротший код виграє. Ви можете припустити, що вхід містить лише символи az (і новий край, якщо ви хочете).


Вихід повинен бути в будь-якому порядку? Скажімо, вихід може бути bacу вашому прикладі, а не abc?
Мураха

@GroovyUser: ні, вхід не є підрядком повторного шаблону bacs.
Кіт Рендалл

Але вхід може складатися з підрядка (bca)^n, що означає bca, що так само справедливо для даного прикладу abc.
JAB

1
@JAB: bcaне найменший лексикографічно.
Кіт Рендалл

Ах, я якось пропустив цю частину.
JAB

Відповіді:


9

Рубін 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

Пітон 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, 299 128 символів

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

Завдяки jloy! Зараз версія і набагато коротша, і я вважаю правильною.


1
Отже, гарна новина полягає в тому, що можна розіграти це рішення приблизно до 91 символу, якщо ви приймете вкладення на stdin, як у рішенні Ruby від Ventero. На жаль, вхід cabcabcabcвиробляє abcabc, тому такого рішення не зовсім існує. Думаю, вам потрібно буде змінити q++q++q, щоб отримати бажаний результат. Хоча моя швидка спроба виправити натрапили речі до 145 символів. (Спойлери тут: gist.github.com/1035161 )

Спасибі! Я не знав про взаємодію і ніколи, хоча про inits << = хвости, щоб отримати всі підрядки. Я трохи змінив вашу версію, щоб набрати трохи символів. Я видалив сортування та змінив фільтр (not.null) по фільтру ((/ /)) "". Знову дякую!
йогсот

Для чого потрібна (/=)""умова? Здається, нічого не робить. Також позбавлення від лямбдасів допомагає: ви можете повністю позбутися w за допомогою .оператора і змінити основну функцію, main=interact sщоб зберегти пару символів.
Ротсор

Я думаю, що відповідь на "bca" - неправильна. Це повинно бути "abc", але є "bca" зараз.
Ротсор

Одне можливе рішення - використовувати permutationsзамість цього tails.
Ротсор

2

Пітон, 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)

EDIT: виправлено помилку, яку помітив JiminP


Ого, це чудово! На жаль, він друкує aababдля рядка ababa... :(
JiminP

Гаразд, виправлено ... стає все довше :(
Jules Olléon

2

Рубін 1,9, 36

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

Використовується той же підхід, що і рішення Вентеро.


2

Пітон, 161 159 166 140 141 134 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 : Виправлена ​​помилка ( abaaрезультати в aaa), яку помітив Жуль Оллеон.

Я не знаю добре про Python, тому цей код, мабуть, "не в гольф".

Я люблю це правило:

Ви можете припустити, що вхід містить лише символи az ...

Входи та виходи

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".
Jules Olléon

Насправді є проблема: для абаа вона друкує ааа ...
Jules Olléon

@Jules Дякую за коментар! Я не думав про це ...
JiminP

Можна робити i-=1замість i=i-1. Так само для приросту.
Lowjacker

1

Математика 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команда об'єднує дві копії цього періоду і бере з нього всі підрядки (в основному отримує всі циклічні перестановки), після чого First@Sortзнаходить першу з них, коли лексикографічно впорядковано.


0

javas 96 символів.

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

Робочий Plunkr


1
Ласкаво просимо до громади! Я не міг протестувати ваш код, чи можете ви надати читання коду з GET / POST та запис із попередженням або console.log або функцію, яка приймає вхідний параметр і повертає вихід?
Аарон

@AaronGOUZIT додав pluckr
ngLover

Дякую, що допомагає. Тим не менш, код, який ви опублікували, не можна використовувати поодинці, так що обробляє кількість байтів. Що ще важливіше, я боюся, що ваш код не поважає специфікації: я вважаю, що ви повертаєте набір унікальних букв, що використовуються, а не "генеруючий рядок", який ми повинні мати можливість повторити (в цілому) з необов'язковим усіченням до отримати вхід. Я з нетерпінням чекаю вашого оновленого коду!
Аарон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.