Substrings únicas mais curtas

29

Entrada

Uma sequência alfanumérica s.

Saída

A cadeia mais curta que ocorre exatamente uma vez como uma substring (contígua) s. Ocorrências sobrepostas são contadas como distintas. Se houver vários candidatos do mesmo tamanho, você deve enviar todos eles na ordem da ocorrência. Nesse desafio, a cadeia vazia ocorre n + 1vezes em uma cadeia de comprimento n.

Exemplo

Considere a string

"asdfasdfd"

A cadeia vazia ocorre 10 vezes nela, portanto, não é candidata a ocorrência única. Cada uma das letras "a", "s", "d", e "f"ocorre pelo menos duas vezes, para que eles não são candidatos também. As subsequências "fa"e "fd"ocorrem apenas uma vez e por esta ordem, enquanto todas as outras subsequências de comprimento dois ocorrer duas vezes. Assim, a saída correta é

["fa","fd"]

Regras

Ambas as funções e programas completos são permitidos, e brechas padrão não são. A formatação exata da saída é flexível, dentro do razoável. Em particular, não é permitido produzir saída para a sequência vazia, mas gerar um erro não é. A menor contagem de bytes vence.

Casos de teste

"" -> [""]
"abcaa" -> ["b","c"]
"rererere" -> ["ererer"]
"asdfasdfd" -> ["fa","fd"]
"ffffhhhhfffffhhhhhfffhhh" -> ["hffff","fffff","hhhhh","hfffh"]
"asdfdfasddfdfaddsasadsasadsddsddfdsasdf" -> ["fas","fad","add","fds"]

Entre os melhores

Aqui está o placar por idioma que prometi.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>site = 'meta.codegolf',postID = 5314,isAnswer = true,QUESTION_ID = 45056;jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)<\\/code><\/pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>

Zgarb
fonte
Alguma limitação nas funções internas combinatórias?
Martin Ender
3
@ MartinBüttner Neste desafio, tudo vai bem. Se isso obtiver respostas suficientes, colocarei uma tabela de classificação por idiomas, para que mesmo os idiomas mais mal equipados possam ter uma competição significativa.
Zgarb 27/01
Deseja usar meu snippet de cabeçalho de código de golfe ? Então você não precisaria monitorar todas as edições para manter a tabela de líderes atualizada. Se você fizer isso, eu posso adicioná-lo para você e examinaria as respostas para fazê-las corresponder ao formato do cabeçalho.
Martin Ender
@ MartinBüttner Obrigado, eu apreciaria isso!
Zgarb
Tudo feito! Deixe-me saber se algo não funcionar. (Sinta-se livre para reutilizá-la para os seus desafios no futuro.)
Martin Ender

Respostas:

3

Pitão, 27 26 bytes

&zhfTmf!/>zhxzYYm<>zkdUzUz

Experimente aqui.

Observe que, devido a um erro no compilador on-line, a caixa de seqüência de caracteres vazia funciona apenas corretamente na versão da linha de comando, que pode ser encontrada aqui.

Você também pode curar o bug, fornecendo uma nova linha como entrada para o compilador online.

Explicação:

                                   z = input(), implicit.
&z                                 Prints empty string if input is empty.
  hfT                              Take the first non-empty list from
     m                  Uz         A list of list of substrings of z, divided by length
                m<>zkdUz           with some shorter strings repeated later, to no effect.
      f                            Where the substrings are filtered on
       !/      Y                   There being 0 occurrences of the substring in
         >z                        The slice of z
           hxzY                    from the character after the first character
                                   of the first occurrence of the substring in z
                                   to the end of z.
isaacg
fonte
Falha na entrada da string vazia.
Optimizer
@ Optimizer Eu acho que é um bug no compilador online, na verdade. Funciona na versão da linha de comando. De fato, znenhuma entrada falha online, por isso é definitivamente um erro no intérprete.
Isaacg
Não dá EOF?
Optimizer
O @Optimizer Pyth espera uma entrada terminada de nova linha, que pode ser o que está dando errado.
Isaacg
Então, passar uma string vazia nem é possível?
Optimizer
13

Python 3, 124 123 111 96 bytes

f=lambda s,n=1:[x for x in[s[i:i+n]for i in range(len(s)+1)]if s.find(x)==s.rfind(x)]or f(s,n+1)

Procura cadeias de caracteres de modo que a primeira ocorrência da esquerda seja igual à primeira ocorrência da direita. O +1no rangeé para acomodar a caixa de seqüência de caracteres vazia.

Agora, se apenas o Python tivesse um .count()que contasse correspondências sobrepostas , isso teria sido um pouco menor.

Sp3000
fonte
6

Mathematica, 95 94 79 bytes

Cases[Tally@StringCases[#,___,Overlaps->All],{s_,1}:>s]~MinimalBy~StringLength&

StringCasesme fornece todas as substrings possíveis, Tallye Casesfiltram as que aparecem mais de uma vez e MinimalByencontram as que são mais curtas.

Martin Ender
fonte
Não há um extra &no final do código?
David G. Stork
Rapaz, você é rápido!
David G. Stork
4

GolfScript, 44 bytes

:S;-1:x{;S,x):x-),{S>x<}%:^1/{^\/,2=},.!}do`

Recebe a entrada como uma string no stdin e gera uma sintaxe de matriz dupla: por exemplo [["b"] ["c"]]. Demonstração online

Dissecação

:S;          # Store input in S and pop it
-1:x         # Store -1 in x
{            # do-while loop
  ;          #   Pop x the first time and [] every subsequent time
  S,x):x-),  #   Increment x and build an array [0 1 ... len(S)-x]
  {S>x<}%    #   Map that array to [substr(S,0,x) substr(S,1,x) ...]
  :^         #   Store in ^ (to avoid the token coalescing with the next char)
  1/         #   Split by length 1 to iterate over 1-elt arrays rather than strings
  {^\/,2=},  #   Filter to arrays which occur exactly once as a subarray of ^
  .!         #   Duplicate and test emptiness
}do          # end do-while loop: loop if the filtered array is empty
`            # Stringify for output

Isso é organizado de modo que nenhum caso especial seja necessário para a sequência vazia (que eu incluí como um caso de teste na demonstração online vinculada acima).

Peter Taylor
fonte
3

CJam, 52 43 40 bytes

]]q:Q,,{)Q,1$-),f{Q><}:R{R\a/,2=},}%{}=p

Entrada é a sequência sem aspas

Explicação :

]]                                       "For empty string input case";
  q:Q                                    "Read the input and store in Q";
     ,,                                  "Take length of input and 0 to length array";
       {                          }%     "Map the above array on this code block";
        )Q                               "Increment the number in the current iteration, L";
         Q,1$                            "Take input's length and copy the above number";
             -)                          "Get upper limit of next loop to get substrings";
               ,f{   }                   "Get 0 to above number array and for each";
                  Q><                    "Get the L length substring at Ith index where";
                                         "I loops from 0 to Q, - L + 1";
                      :R                 "Store this list of substring of length L in R";
                        {R\a/,2=},       "Filter to get unique substrings";
                                    {}=  "Get the first non empty substring array";
                                         "This leaves nothing on stack if all are empty";
                                       p "Print the top stack element. At this point, its";
                                         "Either the first non empty substring array or";
                                         "the ]] i.e. [""] which we added initially";

Exemplo:

asdfdfasddfdfaddsasadsasadsddsddfdsasdf

Saída

["fas" "fad" "add" "fds"]

Experimente online aqui

Optimizer
fonte
3

Scala, 120 bytes

readLine.inits.flatMap(_.tails).toList.groupBy(l=>l).filter(x=>x._2.length<2).map(_._1).groupBy(_.length).minBy(_._1)._2

Comecei com 140, que pelo menos já se encaixa em um tweet.

(                                        // added for comments
 readLine                                // input
.inits.flatMap(_.tails).toList           // get all substrings of that string
.groupBy(l=>l).filter(x=>x._2.length<2)  // remove substrings that occur more than once
.map(_._1).groupBy(_.length)             // take the substring and group by length
.minBy(_._1)._2                          // take the list of shortest substrings
)
Dominik Müller
fonte
Eu me pergunto? Por que não (_)funciona apenas como a identidade em vez de l=>l?
haskeller orgulhoso
Eu também me pergunto. De alguma forma list.groupBy(_)é o mesmo que x => list.groupBy(x). Não faço ideia por que eles implementaram dessa maneira.
Dominik Müller
3

JavaScript (ES6), 109 110

Edite a pesquisa em vez de indexOf, pois a sequência de entrada é alfanumérica. Obrigado @IsmaelMiguel

Função recursiva, procurando substrings começando com o comprimento 1 e subindo.

F=(s,n=1,r)=>
s?[...s].map((a,i)=>~s.indexOf(a=s.substr(i,n),s.search(a)+1)?r:r=[...r||[],a])&&r||F(s,n+1):[s]

Ungolfed e explicou

 F = function(s, n=1) { // start with length 1
   var i, a, p, r;
   if (s == "") // special case for empty input string
     return [s];
   for (i = 0; i < s.length; i++) 
   // for each possibile substring of length n
   // (should stop at s.length-n+1 but going beyond is harmless)
   // Golfed: "[...s].map((a,i)" ... using i, a is overwrittem
   {
     a = s.substr(i, n); // substring at position i
     p = s.search(a); // p is the first position of substring found, can be i or less
     p = s.indexOf(a, p + 1) // p is now the position of a second instance of substring, or -1 if not found
     if (~p) // ~p is 0 if p is -1
     {
       ; // found more than once, do nothing
     }
     else
     {
       r = r || []; // if r is undefined, then it becomes an empty array
       r.push(a); // save substring 
       // Golfed: "r=[...r||[],a]"
     }
   }
   if (r) // if found some substring, saved in r
   {
     return r;
   }
   return F(s, n+1) // recursive retry for a bigger length
 }

Teste no console do FireFox / FireBug

;["", "abcaa", "rererere", "asdfasdfd", "ffffhhhhfffffhhhhhfffhhh", 
 "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"]
.forEach(x=>console.log(x,F(x)))

Saída

 [""]
abcaa ["b", "c"]
rererere ["ererer"]
asdfasdfd ["fa", "fd"]
ffffhhhhfffffhhhhhfffhhh ["hffff", "fffff", "hhhhh", "hfffh"]
asdfdfasddfdfaddsasadsasadsddsddfdsasdf ["fas", "fad", "add", "fds"]
edc65
fonte
Usar .search vez de .indexOfe você economiza 2 bytes.
Ismael Miguel
@IsmaelMiguel não, porque 1) de pesquisa não tem um deslocamento parâmetro 2) busque esperar uma expressão regular, e irá falhar com caracteres especiais como * [] e assim por diante.
edc65
11
Mas, no primeiro, você pode substituí-lo com segurança (no seu s.indexOf(a)+1). Enquanto é ter que não vai funcionar com esses caracteres, você não precisa se preocupar! Citando o OP: " Input: An alphanumeric string s."
Ismael Miguel
@IsmaelMiguel certo, obrigado. Faltou a restrição 'alfanumérica'
edc65
11
@IsmaelMiguel Não encontrei uma maneira ... Preciso de verdade ou falsidade, e qualquer array (mesmo vazio []) é um valor
verdadeiro
3

Java, 168 176 233

Aqui está um exemplo de loop aninhado bastante básico.

void n(String s){for(int l=0,i=0,t=s.length(),q=0;l++<t&q<1;i=0)for(String b;i<=t-l;)if(s.indexOf(b=s.substring(i,i+++l),s.indexOf(b)+1)<0){System.out.println(b);q++;}}

Ou um pouco mais legível:

void t(String s){
    for(int l=0,i=0,t=s.length(),q=0;l++<t&q<1;i=0)
        for(String b;i<=t-l;)
            if(s.indexOf(b=s.substring(i,i++ +l),s.indexOf(b)+1)<0){
                System.out.println(b);
                q++;
            }
}
Geobits
fonte
Se você deseja legibilidade, divida- +++se para mostrar se isso é + ++ou ++ +não ajudaria ... E se você deseja salvar mais alguns bytes, pode haver uma maneira de fazer isso inicializando q=1, substituindo q++por q=te substituindo l++<t&q<1por algo parecido t>l+=q. Provavelmente, é necessário ajustar uma ou duas outras compensações para fazê-la funcionar.
Peter Taylor
@ Peter Bem, por legível, eu quis dizer principalmente "Não preciso rolar horizontalmente", mas esclarei o +++. Eu tenho tentado ajustá-lo (especialmente q, o que parece um pouco inútil), mas ainda não encontrei nada sólido.
Geobits
@PeterTaylor Devido às regras de lexing do Java, +++sempre resolve ++ +.
FUZxxl
@ FuZxxl, duvido que até a maioria dos usuários de Java saiba disso, e há muitas pessoas neste site que não conhecem Java.
Peter Taylor
11
Usando indexOf com offset em vez de lastIndexOf deve cortar 1 byte (ver minha resposta javascript)
edc65
3

Haskell, 169 162 155 153 151 138 120 115

import Data.List
l=length
q k=filter$(==)k.l
p y=q(minimum.map l$y)$y
f x=p$concat$q 1$group$sort$(tails x>>=inits)

Para usá-lo:

f "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"

Que dá:

["add","fad","fas","fds"]

Btw. Eu odeio a última linha do meu código (repetição de h y). Alguém sugere se livrar disso?

RobAu
fonte
11
Que tal você definir g y=q(minimum.(map l)$y)$y(os parênteses são map lrealmente necessários?) E depois f=g.concat.q 1.group.sort.concatMap inits.tails?
FUZxxl
11
Usar em >>=vez de concatMap, ou seja, f x=p$concat$q 1$group$sort$(tails x>>=inits)salva 2 bytes. Por que a Data.Ordimportação?
N
11
Os parênteses qsão desnecessários, pois você pode escrever filter$(==)k.l, assim como o último $e os espaços antes de ys p. Você também pode remover o ponto e vírgula após as importações ( Data.Ordparece realmente desnecessário).
Zgarb
O compilador Leksah não aceita $seguido por um não-espaço. Ele vai economizar alguns bytes, mas está na especificação de idioma?
Robau
11
O GHC aceitará.
Zgarb
3

J, 61 58 44 42 40 38 37 bytes

[:>@{.@(#~#@>)#\<@(~.#~1=#/.~)@(]\)]

Aqui está uma versão dividida em componentes individuais da solução:

unqs =. ~. #~ 1 = #/.~               NB. uniques; items that appear exactly once
allsbsq =. #\ <@unqs@(]\) ]        NB. all unique subsequences
shrtsbsq =. [: >@{.@(#~ #@>) allsbsq NB. shortest unique subsequence
  • x #/. ycalcula para cada elemento distinto xa frequência com que ocorre y. Se usarmos isso como y #/. y, obtemos o para cada elemento distinto em ysua contagem. Por exemplo, a #/. apara a =. 1 2 2 3 4 4rendimentos 1 2 1 2.
  • 1 = yverifica quais itens ysão iguais a 1. Por exemplo, 1 = a #/. arendimentos1 0 1 0 .
  • u~é o reflexo de um verbo monádico u. Isto é, u~ yé o mesmo que y u y. Assim, #/.~ yé o mesmo que #/.~ y. Quando aplicado a um verbo diádico, u~é o passivo de u. Ou seja, x u~ yé o mesmo que y u x. Estes são usados ​​em muitos outros lugares que não menciono explicitamente.
  • ~. yé o de y, um vetor com duplicatas removidas. Por exemplo, ~. aproduz 1 2 3 4.
  • x # y( cópia ) seleciona entre yos itens nos índices em que xcontém a 1.
  • Assim, (1 = y #/. y) # (~. y)cria um vetor daqueles elementos yque aparecem apenas uma vez. Na notação tácita, esse verbo é escrito como ~. #~ 1 = #/.~; vamos chamar esta fraseunqs para o resto da explicação.
  • x ]\ ycria um xpor 1 + y - xconjunto de todos os infixos do vector yde comprimento x. Por exemplo, 3 ]\ 'asdfasdfdrendimentos

    asd
    sdf
    dfa
    fas
    asd
    sdf
    dfd
    
  • # yé a contagem do ynúmero de elementos em y.

  • u\ yaplica u- se a cada prefixo de y. Aliás, #\ ycria um vetor de números inteiros de 1para #y.
  • < ycoloca yem uma caixa. Isso é necessário porque as matrizes não podem ser irregulares e calculamos uma matriz de sufixos de diferentes comprimentos; uma matriz em caixa conta como um escalar.
  • Assim, (i. # y) <@:unqs@(]\) ygera um vetor de #ymatrizes in a box do comprimento k (para todos os 0 ≤ k < #y) infixes de y que ocorrem exatamente uma vez. A forma tácita desse verbo é i.@# <@unqs@(]\) ]ou i.@# <@(~. #~ 1 = #/.~)@(]\) ]se não usarmos o unqsnome. Vamos chamar esta frase allsbsqpara o restante desta explicação. Por exemplo, allsbsq 'asdfasdfd'produz:

    ┌┬─┬──┬───┬────┬─────┬──────┬───────┬────────┐
    ││ │fa│dfa│sdfa│asdfa│asdfas│asdfasd│asdfasdf│
    ││ │fd│fas│dfas│sdfas│sdfasd│sdfasdf│sdfasdfd│
    ││ │  │dfd│fasd│dfasd│dfasdf│dfasdfd│        │
    ││ │  │   │sdfd│fasdf│fasdfd│       │        │
    ││ │  │   │    │asdfd│      │       │        │
    └┴─┴──┴───┴────┴─────┴──────┴───────┴────────┘
    
  • (#@> y) # ytoma do vetor de matrizes in a box yaquelas que não estão vazias.

  • {. ypega o primeiro elemento do vetor y.
  • > yremove a caixa de y.
  • Assim, > {. (#@> y) # ygera a primeira matriz não vazia não caixa do vetor de matrizes em caixa y. Esta frase está escrita >@{.@(#~ #@>)em notação tácita.
  • Finalmente, [: >@{.@(#~ #@>) allsbsqreúne a frase anterior com allsbsqpara criar uma solução para o problema que temos. Aqui está a frase completa com espaços:

    [: >@{.@(#~ #@>) i.@# <@(~. #~ 1 = #/.~)@(]\) ]
    
FUZxxl
fonte
2

Haskell, 135 bytes

import Data.List
f ""=[""]
f g=map(snd)$head$groupBy(\a b->fst a==fst b)$sort[(length y,y)|[y]<-group$sort[x|x@(_:_)<-tails g>>=inits]]
nimi
fonte
2

PHP, 171 152 134 125

function f($s){while(!$a&&++$i<strlen($s))for($j=0;$b=substr($s,$j++,$i);)strpos($s,$b)==strrpos($s,$b)&&($a[]=$b);return$a;}

http://3v4l.org/RaWTN

Stephen
fonte
Você não precisa definir explicitamente $j=0. Adiante, você tem substr($s,$j++,$i). Sem definir $j, você pode reescrever isso substr($s,0+$j++,$i)e salvar 2 bytes. Por que é que? Bem, pela primeira vez, $jserá null. E você será efetivamente passando nullpara substr, que eu não acho que vai funcionar bem. Usar 0+$j++converterá nullpara 0. Se você perceber que não é necessário, vá em frente sem ele e remova a $j=0peça.
Ismael Miguel
Tentei isso; não funciona porque o PHP não possui escopo forte, portanto $jnão é limpo e reinicializado para cada iteração do while()loop. Portanto, embora seja nulo (e, portanto, seria convertido em 0uma $j++chamada) na primeira vez, em futuras iterações do loop externo, ele permanece no valor que era antes. Não é tanto inicializar como redefinir. Obrigado pela sugestão :-)
Stephen
Aqui, ofereço-lhe uma solução de 141 bytes de comprimento: function f($s){$l=strlen($s);while(!$a&&++$i<$l)for($j=0;$j<$l;)($b=substr($s,$j++,$i))&(strpos($s,$b)==strrpos($s,$b)&&($a[]=$b));return$a;}Alterações: TODO seu ||1, usado bit a bit &( AND) em vez de &&em um só lugar, moveu a $j<$l&&[...]peça para fora de for(economizando 2 bytes) e removeu alguns parênteses desnecessários.
Ismael Miguel
11
Um 134 bytes de comprimento presente para você: function f($s){$l=strlen($s);while(!$a&&++$i<$l)for($j=0;$j<$l;)strpos($s,$b=substr($s,$j++,$i))==strrpos($s,$b)&&($a[]=$b);return$a;}as alterações feitas no código anterior: mudou o $b=substr($s,$j++,$i)em strpos($s,$b)tornando-se strpos($s,$b=substr($s,$j++,$i)), removeu parenthesys mais desnecessários e removeu o desnecessário &.
Ismael Miguel
11
Gerenciado um pouco mais de corte :-) substr($s,$j++,$i)retorna ""quando $jatinge o comprimento da sequência e falsedepois, para que a atribuição também possa servir como quebra condicional do loop. Depois, há apenas um uso $lrestante, para que também possa ser consolidado.
Stephen
2

Groovy (regex Java na implementação Oracle), 124

c={m=it=~/(?=(.*?)(?=(.*))(?<=^(?!.*\1(?!\2$)).*))/;o=m.collect({it[1]});o.findAll({it.size()==o.min({it.size()}).size()});}

Testado no Groovy 2.4 + Oracle JRE 1.7. O regex deve funcionar para Java 6 a Java 8, pois o bug que permite que o código acima funcione não foi corrigido. Não tenho certeza para a versão anterior, pois há um bug no Java 5 que foi corrigido no Java 6.

O regex encontra a string mais curta que não possui uma substring duplicada em outro lugar, em todas as posições da string de entrada. O código externo cuida da filtragem.

(?=(.*?)(?=(.*))(?<=^(?!.*\1(?!\2$)).*))
  • Como as cordas podem se sobrepor, eu cerco a coisa toda no futuro (?=...).
  • (.*?) pesquisas da substring mais curta
  • (?=(.*)) captura o restante da string para marcar a posição atual.
  • (?<=^(?!.*\1(?!\2$)).*)é uma emulação de look-behind de comprimento variável, que tira proveito do bug de implementação que permite (?<=.*)passar na verificação de comprimento.
  • (?!.*\1(?!\2$))simplesmente verifica se você não encontra a mesma substring em outro lugar. Ele (?!\2$)rejeita a posição original em que a substring é correspondida.

    O limite da construção de pesquisa externa não se aplica à construção de pesquisa aninhada. Portanto, a antecipação negativa aninhada (?!.*\1(?!\2$))na verdade verifica toda a cadeia de caracteres, não apenas até o limite direito da antecipação .

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
fonte
2

Rebol, 136 bytes

f: func[s][repeat n length? b: copy s[unless empty? x: collect[forall s[unless find next find b t: copy/part s n t[keep t]]][return x]]]

Ungolfed:

f: func [s] [
    repeat n length? b: copy s [
        unless empty? x: collect [
            forall s [
                unless find next find b t: copy/part s n t [keep t]
            ]
        ][return x]
    ]
]

Exemplo de uso:

>> f ""       
== none

>> f "abcaa"
== ["b" "c"]

>> f "rererere"
== ["ererer"]

>> f "asdfasdfd"
== ["fa" "fd"]

>> f "ffffhhhhfffffhhhhhfffhhh"
== ["hffff" "fffff" "hhhhh" "hfffh"]

>> f "asdfdfasddfdfaddsasadsasadsddsddfdsasdf"
== ["fas" "fad" "add" "fds"]


NB Suponho que o cerne do código seja como a findpeça está funcionando. Espero que isso ajude a explicar ...

>> find "asdfasdfd" "df"
== "dfasdfd"

>> next find "asdfasdfd" "df"
== "fasdfd"

>> find next find "asdfasdfd" "df" "df"
== "dfd"

>> ;; so above shows that "df" is present more than once - so not unique
>> ;; whereas below returns NONE because "fa" found only once - ie. bingo!

>> find next find "asdfasdfd" "fa" "fa"
== none
draegtun
fonte
1

Haskell, 119

f s=[r|n<-[1..length s],l<-[map(take n)$take(length s-n+1)$iterate(drop 1)s],r<-[[j|j<-l,[j]==[r|r<-l,r==j]]],r/=[]]!!0
orgulhoso haskeller
fonte
você pode colocar q = lengthem algum lugar e uso q, raspa alguns bytes
Robau
1

Braquilog , 10 bytes

sᶠ≡ᵍ~gˢlᵍt

Experimente online!

sᶠ            The list of every substring of the input
  ≡ᵍ          grouped by identity,
    ~gˢ       with length-1 groups converted to their elements and other groups discarded,
       lᵍ     and grouped by their length,
         t    has the output as its last group.

Embora naturalmente não classifique pelo valor que agrupa, em vez de ordenar os grupos pela primeira ocorrência de cada valor, as primeiras ocorrências de todos os comprimentos estão em ordem decrescente. Não tenho 100% de certeza de que a filtragem de exclusividade não possa atrapalhar isso, mas ainda não criei um caso de teste.

String não relacionada
fonte
1

05AB1E , 10 bytes

Œʒ¢}é.γg}н

Não gera nada para uma sequência vazia.

Experimente online ou verifique todos os casos de teste .

Explicação:

Œ           # Get all substrings of the (implicit) input-String
 ʒ          # Filter it by:
  ¢         #  Count how many times the current substring occurs in the (implicit) input-String
            #  (only 1 is truthy in 05AB1E, so the filter will leave unique substrings)
          # After the filter: sort the remaining substrings by length
     g}   # Then group them by length as well
         н  # And only leave the first group containing the shortest substrings
            # (which is output implicitly as result)

Isso tira vantagem do fato de o 05AB1E ter apenas um 1valor verdadeiro e todo o resto como falsey. A substring única mais curta é sempre garantida para ocorrer exatamente uma vez para todas as sequências de entrada possíveis. (Para uma string de entrada contendo apenas os mesmos caracteres (ie aaaaa), as próprias strings de entrada como substring ocorrem apenas uma vez, o resultado é o seguinte ["aaaaa"]. Para uma String de entrada com padrão de repetição (ie "abcabc"), ainda existem substrings exclusivos que apenas ocorrer uma vez ( ["abca","abcab","abcabc","bca","bcab","bcabc","ca","cab","cabc"]), então isso resultará em ["ca"].)

Kevin Cruijssen
fonte
0

Python 2, 150

import re
a=input()
r=range
l=len(a)
d=0
for i in r(l):
 if d:break
 for j in r(l-i):
  k=a[j:i+j+1]
  if len(re.findall("(?="+k+")",a))<2:d=1;print k
KSFT
fonte
Na área cinza, ele deve imprimir "", mas você não imprime nada.
Jakube 27/01
11
@Jakube "A formatação exata da saída é flexível"
KSFT 27/01/15
Mas você não tem saída nenhuma.
Jakube 27/01
2
@Jakube A saída é a string vazia, como deveria ser. Eu simplesmente não tenho aspas.
KSFT 27/01
11
@Jakube Eu vou permitir isso, já que a string vazia é um caso especial de qualquer maneira.
Zgarb 27/01