Substrings de identificação exclusiva mais curtas

23

Dada uma lista de seqüências de caracteres, substitua cada sequência por uma de suas subseqüências não vazias, que não é uma subseqüência de nenhuma das outras seqüências da lista e o mais curta possível.

Exemplo

Dada a lista ["hello","hallo","hola"], "hello"deve ser substituído por apenas "e"como este substring não está contido no "hallo"e "hola"e é o mais curto possível. "hallo"Pode ser substituído por um ou outro "ha"ou "al"e "hola"por qualquer um dos "ho", "ol"ou "la".

Regras

  • Você pode assumir que as seqüências de caracteres não estarão vazias e conterão apenas caracteres alfabéticos do mesmo caso.
  • Você pode assumir que existe uma substring para cada string da lista, ou seja, nenhuma string da lista será uma substring de qualquer uma das outras strings.
  • A entrada e a saída podem estar em qualquer formato razoável.
  • Isso é , então tente usar o mínimo de bytes possível no idioma de sua escolha.

Casos de teste

Apenas uma saída possível é fornecida na maioria dos casos.

["ppcg"] -> ["p"] (or ["c"] or ["g"])
["hello","hallo","hola"] -> ["e","ha","ho"]
["abc","bca","bac"] -> ["ab","ca","ba"]
["abc","abd","dbc"] -> ["abc","bd","db"]
["lorem","ipsum","dolor","sit","amet"] -> ["re","p","d","si","a"]
["abc","acb","bac","bca","cab","cba"] -> ["abc","acb","bac","bca","cab","cba"]

Relacionado: Substring de identificação mais curta - idéia semelhante, mas regras mais envolvidas e formato complicado.

Laikoni
fonte
Por que não é ""(string vazia) a identificação exclusiva para o "ppcg"caso único ?
MooseBoys
2
@MooseBoys Dada uma lista de strings, substitua cada corda por um de seus não-vazias substrings
Mr. Xcoder

Respostas:

4

Python 2 , 116 bytes

def f(a):g=lambda s,S:s not in`set(a)-{S}`[3:]and min(s,g(s[1:],S),g(s[:-1],S),key=len)or S;return[g(s,s)for s in a]

Experimente online!

Chas Brown
fonte
4

Pitão , 12 bytes

mhf!ts}LTQ.:

Experimente aqui!

Como funciona

Basicamente, filtra as substrings de cada uma que ocorrem apenas em uma das strings da lista (ou seja, é exclusiva dessa string) e obtém a primeira.

mhf!ts}LTQ.:     Full program, Q=eval(stdin_input())
m         .:     Map over Q and obtain all the substrings of each.
  f              And filter-keep those that satisfy (var: T)...
      }LTQ       ... For each string in Q, yield 1 if it contains T, else 0.
   !ts           ... Sum the list, decrement and negate. 
 h               Head. Yields the first valid substring, which is always the shortest.
Mr. Xcoder
fonte
4

Prolog (SWI) , 175 163 bytes

S/L/R:-sub_string(S,_,L,_,R).
[H|T]+[I|R]:-string_length(H,L),between(1,L,X),H/X/I,T+R.
R+R.
L-R:-L+R,forall(member(E,L),findall(_,(member(F,R),\+ \+ E/_/F),[_])).

Experimente online!

A maioria das coisas aqui deve ser bastante óbvia, mas:

Explicação

Assinaturas: ( += entrada, ?= opcional, -= saída, := expressão)

  • sub_string(+String, ?Before, ?Length, ?After, ?SubString)
  • string_length(+String, -Length)
  • member(?Elem, ?List)
  • between(+Low, +High, ?Value)
  • findall(+Template, :Goal, -Bag)
  • forall(:Cond, :Action)

\+ \+é justo not not(isto é, converte uma correspondência em booleano (neste caso, impede que ela combine ambos os ps ppcgseparadamente))

Somente ASCII
fonte
A ferramenta certa para o trabalho: P exceto para o fato de que é mente-blowingly detalhado
ASCII-only
4

J , 30 29 25 bytes

1(|:(0{-.&,)"_1]\.)<\\.&>

Experimente online!

                   <\\.&>        a 3-dimensional array of substrings
1 |:                             transpose each matrix to sort the substrings by length
1              ]\.               all choices where one word is missing
    (0{-.&,)"_1                  for every matrix, flatten, remove substrings
                                  that are present in the corresponding complement,
                                  pick first
FrownyFrog
fonte
3

JavaScript (ES6), 93 bytes

a=>a.map(s=>(L=s.length,g=n=>a.every(S=>S==s|!~S.search(u=s.substr(n%L,n/L+1)))?u:g(n+1))(0))

Experimente online!

Quão?

Para cada string s de comprimento L na matriz de entrada a [] e começando com n = 0 , usamos a função recursiva g () para gerar todas as substrings u de s com:

u = s.substr(n % L, n / L + 1)

Por exemplo, com s = "abc" e L = 3 :

 n | n%L | floor(n/L+1) | u
---+-----+--------------+-------
 0 |  0  |       1      | "a"
 1 |  1  |       1      | "b"
 2 |  2  |       1      | "c"
 3 |  0  |       2      | "ab"
 4 |  1  |       2      | "bc"
 5 |  2  |       2      | "c"
 6 |  0  |       3      | "abc"
 7 |  1  |       3      | "bc"
 8 |  2  |       3      | "c"

Algumas substrings são geradas várias vezes, mas isso não importa. O importante é que todas as substrings de comprimento N tenham sido geradas antes de qualquer substring de comprimento N + 1 .

Paramos o processo assim que você não puder ser encontrado em nenhuma outra string S em [] , o que é garantido que acontece quando u == s no pior caso, conforme a regra de desafio nº 2:

nenhuma string na lista será uma substring de qualquer uma das outras strings

Portanto, no exemplo acima, as etapas 7 e 8 nunca serão processadas.

Arnauld
fonte
2

PowerShell , 107 bytes

($a=$args)|%{$(for($i=0;$i++-lt($g=($s=$_)|% Le*)){0..($g-$i)|%{$s|% s*g $_ $i}|?{!($a-match$_-ne$s)}})[0]}

Experimente online!

Explicação

Para cada sequência fornecida (e designe toda a matriz $a):

  • Faça um forloop sobre cada comprimento de substring (baseado em 1) da string (atribuindo a própria string $se o comprimento a $g)
  • Para cada comprimento ( $i):
    • Faça um loop de índice, de 0 a comprimento - e $i, em seguida, para cada índice:
      • Obter a substring da string atual ( $s) na posição $_(índice) e no comprimento$i
      • Passe essa substring para Where-Object( ?) e retorne-a se:
        • O subconjunto de array ( $a) que não contém a cadeia atual $s, não possui uma correspondência para a substring atual$_

De volta ao nível da sequência, temos todas as subseqüências dessa sequência que não foram encontradas nas outras. Portanto, pegue a primeira, [0]pois precisamos apenas de uma delas e continue com a próxima.

briantist
fonte
0

C # (compilador interativo do Visual C #) , 149 bytes

a=>a.Select(s=>{var t=s;for(int j=0,k,l=s.Length;j++<l;)for(k=-1;j+k++<l;)if(!a.Where(u=>s!=u&u.Contains(t=s.Substring(k,j))).Any())j=k=l;return t;})

Experimente online!

Menos golfe ...

// a is an input array of strings
a=>
  // iterate over input array   
  a.Select(s=>{
    // t is the result string
    var t=s;
    // j is the substring length
    for(int j=0,k,l=s.Length;j++<l;)
      // k is the start index
      for(k=-1;j+k++<l;)
        // LINQ query to check if substring is valid
        // the tested string is collected in t
        if(!a.Where(u=>s!=u&u.Contains(t=s.Substring(k,j))).Any())
          // break loops
          j=k=l;
    // return result
    return t;
  })
dana
fonte