Problema para filtrar matriz de sequências para remover duplicatas com sequências deslocadas

Problema para filtrar matriz de sequências para remover duplicatas com sequências deslocadas

Tive alguns problemas para fazer uma comparação de listas para remover duplicatas. Meu array é composto por sequências de valores ternários como este:

{0, 0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1}  
{0, 0, 2, 0, 2, 2, 2, 1, 1, 0, 2, 1, 2}  
{0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0}  
{0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1}  
{0, 1, 2, 1, 0, 0, 1, 0, 1, 1, 1, 2, 2}    
{0, 2, 0, 2, 2, 2, 1, 1, 0, 2, 1, 2, 0}  
{0, 2, 1, 2, 0, 0, 2, 0, 2, 2, 2, 1, 1}  
{0, 2, 2, 2, 1, 1, 0, 2, 1, 2, 0, 0, 2}  
{1, 0, 0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2}  
{1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0, 0}  
{1, 0, 2, 1, 2, 0, 0, 2, 0, 2, 2, 2, 1}  
{1, 1, 0, 2, 1, 2, 0, 0, 2, 0, 2, 2, 2}  
{1, 1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 0}  
{1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 0, 1}  
{1, 2, 0, 0, 2, 0, 2, 2, 2, 1, 1, 0, 2}  
{1, 2, 1, 0, 0, 1, 0, 1, 1, 1, 2, 2, 0}  
{1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 0, 1, 1}  
{2, 0, 0, 2, 0, 2, 2, 2, 1, 1, 0, 2, 1}

Tentei com um loop while encontrar duplicatas com a ajuda de um subscrito testsequence.sh que é um wrapper de script do Mathematica para identificar se duas sequências são iguais:

{0, 0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1}  
{0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1, 0}

Esses dois são iguais com um deslocamento para a esquerda; meu subscrito retorna 1 nesse caso e o subscrito é usado assim:

./testsequence.sh "`echo ${foundsequence[0]}`" "`echo ${foundsequence[1]}`"

Minha primeira tentativa com o loop while comparou apenas a primeira sequência com outras, removendo apenas metade das duplicatas.

O bom resultado deve ser:

{0, 0, 1, 0, 1, 1, 1, 2, 2, 0, 1, 2, 1}  
{0, 0, 2, 0, 2, 2, 2, 1, 1, 0, 2, 1, 2}  

Como são as duas únicas sequências únicas na lista.

Esteja ciente de que as sequências na matriz não têm comprimento fixo. Eles podem variar de 2 a 121 ou até mais em comprimento. É por isso que quero manter meus subscritos para comparar duas linhas do array.

Responder1

Aqui está um loop bash que lê a entrada de um arquivo chamado 'input' em um array chamado input, depois faz um loop sobre esse array e testa para ver se aquela sequência específica já foi vista antes; se não foi visto, imprime o valor. Em seguida, ele gira essa sequência por todas as 13 posições, adicionando esses valores a uma matriz associativa de rotação conhecida. Simplifiquei os dados para mostrar o método; você pode pegar o shell loop e ajustar a entrada ou saída conforme necessário.

#!/usr/bin/env bash
readarray -t input < input
declare -A rotations
for((i=0; i < ${#input[*]}; i++))
do
  x=${input[i]}
  [[ ${rotations[$x]:-0} -eq 0 ]] && printf "%s\n" "$x"
  for((r=0; r < 13; r++))
  do
    new=${x:r}${x:0:r}
    rotations[$new]=1
  done
done

Dados de entrada de amostra (copiados da pergunta e depois simplificados):

0010111220121
0020222110212
0101112201210
0111220121001
0121001011122
0202221102120
0212002022211
0222110212002
1001011122012
1011122012100
1021200202221
1102120020222
1112201210010
1122012100101
1200202221102
1210010111220
1220121001011
2002022211021

Exemplo de saída:

0010111220121
0020222110212

informação relacionada