Corda generatrice più corta, lessicograficamente più piccola


16

Una stringa x genera una stringa yse yè una sottostringa di una ripetizione infinita di x. Ad esempio abcgenera bcabcab.

Scrivi un programma per trovare la stringa più breve, lessicograficamente più piccola, che genererà l'input. In input standard viene fornita una singola riga di testo. È necessario stampare la stringa di generazione sull'output standard. Per esempio:

ingresso

bcabcabca

produzione

abc

Il codice più corto vince. Puoi supporre che l'input contenga solo i caratteri az (e una nuova riga finale se vuoi).


L'output dovrebbe essere in qualsiasi ordine? Dire che l'output può essere bacnel tuo esempio anziché abc?
Formica,

@GroovyUser: no, l'input non è una sottostringa di uno schema ripetuto di bacs.
Keith Randall,

Ma l'input potrebbe consistere in una sottostringa di (bca)^n, il che significa che bcaè valido per l'esempio dato come abc.
JAB

1
@JAB: bcanon è il più piccolo lessicograficamente.
Keith Randall,

Ah, in qualche modo mi mancava quella parte.
JAB,

Risposte:


9

Ruby 1.9, 40 caratteri

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

Presuppone che l'input non sia terminato da una nuova riga. Inoltre è probabilmente ridicolmente lento per risultati più grandi.

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

2

Python 88 185 caratteri

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

Produzione:

bcabcabca
abc

aaa
a

abc
abc

cccbbcccbbcccbb
bbccc

barfoofoobarfoofoo
arfoofoob

bacabac
abacbac

Non ti fornisce la stringa lessicograficamente più piccola per alcuni input, ad esempio "bacabac"
Howard,

@Howard hai ragione. Ho aggiornato il mio codice, ora è molto più lungo, ma gestisce le stringhe in modo bacabaccorretto.
Vader,

"abac" sarebbe corretto, vedi la risposta di @ yogsototh: un bacabac abac.
Howard,

2

Haskell, 299 128 caratteri

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

Grazie a Jloy! Ora la versione è molto più corta e credo sia corretta.


1
Quindi, la buona notizia è che è possibile golfare questa soluzione fino a circa 91 caratteri se si accetta input su stdin come nella soluzione Ruby di Ventero. Sfortunatamente, l'input cabcabcabcproduce abcabc, quindi questa soluzione non è del tutto presente. Penso che dovrai modificare q++q++qper ottenere il risultato desiderato. Il mio rapido tentativo di risolvere il problema ha riportato a 145 caratteri. (Gli spoiler sono qui: gist.github.com/1035161 )

Grazie! Non sapevo di interagire né mai di inits << = code per ottenere tutte le sottostringhe. Ho leggermente modificato la tua versione per ottenere un po 'di personaggi. Ho rimosso l'ordinamento e modificato il filtro (not.null) per filtro ((/ =) ""). Grazie ancora!
Yogsototh,

Perché hai bisogno di (/=)""condizioni? Non sembra fare nulla. Inoltre, sbarazzarsi di lambda aiuta: è possibile sbarazzarsi di w usando l' .operatore e modificare la funzione principale main=interact sper salvare un paio di personaggi.
Rotsor,

Penso che la risposta per "bca" sia sbagliata. Dovrebbe essere "abc", ma ora è "bca".
Rotsor,

Una possibile soluzione è utilizzare permutationsinvece di tails.
Rotsor,

2

Python, 121 137 129 caratteri

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: corretto il bug individuato da JiminP


Wow, è fantastico! Sfortunatamente, stampa aababper stringa ababa... :(
JiminP

Ok, risolto ... si sta allungando :(
Jules Olléon

2

Ruby 1.9, 36

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

Utilizza lo stesso approccio della soluzione Ventero.


2

Pitone, 161 159 166 140 141 134 132 caratteri

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 : golfato il codice dopo aver letto il commento di Jules Olléon. Rimosso un "bug" che bcdabcdabrisulta abbc.

EDIT2 : corretto il bug ( abaarisultati aaa) individuato da Jules Olléon.

Non conosco bene Python, quindi questo codice probabilmente non è "golfato".

Adoro questa regola:

Si può presumere che l'input contenga solo i caratteri az ...

Entrate uscite

bcdabcd
abcd

bcabcabca
abc


abcdabcd
abcd

bcdabcdab
abcd

barfoofoobarfoofoobar
arfoofoob

cccbbcccbbcccbb
bbccc

aaaaaaaaaaaaaaaa
a

thequickbrownfox
brownfoxthequick

ababa
ab

abaa
aab

1
Brown fox, il veloce! Cane, il pigro!
JiminP,

Bella soluzione, piuttosto breve e probabilmente la migliore complessità qui! Potresti golf un po '- per esempio, non hai bisogno di "int" per confrontare le stringhe; e sostituisci "while i> 0" con "while i" e "y = y + y" con "y * = 2".
Jules Olléon,

In realtà c'è un problema: per abaa stampa aaa ...
Jules Olléon il

@Jules Grazie per il commento! Non ci avevo pensato ...
JiminP,

Puoi fare i-=1invece di i=i-1. Allo stesso modo per l'incremento.
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]

Gli spazi bianchi e le nuove righe (in presenza di punti e virgola alle estremità delle righe) non hanno significato in Mathematica e sono inclusi qui per la leggibilità.

L'input va tra le virgolette nella prima riga. Se rifuso come una funzione, questo accetta l'input di stringa in questo modo:

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

quindi sono 128 byte.

Il Forloop prende i primi icaratteri dell'input e li ripete almeno fino alla lunghezza dell'input, quindi controlla se l'input è una sottostringa del risultato. Avendo trovato la lunghezza del periodo della stringa, il StringPartitioncomando concatena due copie di quel periodo e prende tutte le sottostringhe di quella lunghezza (fondamentalmente ottiene tutte le permutazioni cicliche), quindi First@Sorttrova la prima quando viene ordinata lessicograficamente.


0

javascript 96 caratteri.

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

Working Plunkr


1
Benvenuto nella community! Non ho potuto testare il tuo codice, potresti fornire la lettura del codice da GET / POST e la scrittura con alert o console.log o una funzione che prende l'input come parametro e restituisce l'output?
Aaron,

@AaronGOUZIT ha aggiunto pluckr
ngLover il

Grazie, aiuta. Tuttavia, il codice che hai pubblicato non può essere utilizzato da solo, in modo da ingannare il conteggio dei byte. Ancora più importante, temo che il tuo codice non rispetti le specifiche: credo che tu restituisca un insieme di lettere univoche utilizzate anziché una "stringa generatrice", che dovremmo essere in grado di ripetere (nel suo insieme) con troncamento facoltativo a ottenere l'input. Non vedo l'ora di vedere il tuo codice aggiornato!
Aaron,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.