Généralisation des abréviations

14

Étant donné l'entrée d'une liste de mots et de leurs abréviations, affichez le modèle par lequel les abréviations peuvent être formées.

Prenons l'exemple d'entrée de

potato ptao
puzzle pzze

à titre d'exemple (c'est-à-dire l'abréviation de potatois ptaoet l'abréviation de puzzleis pzze).

Considérez toutes les façons possibles d'obtenir ptaode potato. Une façon possible consiste à prendre les première, troisième, quatrième et sixième lettres, que nous appellerons 1346. Mais puisque tet oapparaissent plusieurs fois dans le mot, il existe plusieurs autres façons possibles de générerptao de potato: 1546, 1342et 1542.

De même, notez que vous pzzepouvez générer à partir puzzlede1336 , 1346, 1436, 1446. Le seul modèle que ces deux abréviations ont en commun est 1346; par conséquent, cela doit être la sortie de cette entrée. Si plusieurs modèles possibles sont possibles, vous pouvez en sortir n'importe lequel, certains ou tous (au moins un).

Vous pouvez supposer que:

  • Les mots et abréviations saisis ne contiennent que des lettres minuscules.

  • Il y a au moins une paire mot / abréviation dans l'entrée.

  • Il est possible que chaque abréviation soit formée à partir de son mot correspondant.

  • Il y aura toujours au moins un motif qui formera chaque abréviation.

  • La longueur maximale de chaque mot est de 9 caractères.

L'entrée peut être considérée comme l'un des éléments suivants:

  • Tableau 2 dimensions / liste / tableau de tuples / etc. [[word, abbr], [word, abbr], ...]

  • tableau / liste unidimensionnel plat [word, abbr, word, abbr, ...]

  • chaîne unique, délimitée par un caractère unique qui n'est pas une lettre minuscule "word abbr word abbr"

  • hachage / tableau associatif / etc. {word => abbr, word => abbr, ...}

Dans chacune de ces options de saisie, vous êtes également autorisé à permuter l'ordre des mots / abréviations (veuillez décrire complètement le format de saisie dans votre message).

La sortie peut être donnée sous la forme d'un nombre unique, d'une chaîne délimitée par des non-chiffres ou d'un tableau / liste / tuple / etc. des nombres.

Puisqu'il s'agit de , le code le plus court en octets gagnera.

Cas de test (rappelez-vous que vous devez uniquement générer des résultats ≥1 si plusieurs modèles fonctionnent):

In                                Out
--------------------------------------------------------
potato ptao puzzle pzze         | 1346
aabbcc abc fddeef def           | 246
prgrmming prgmg puzzles pzzlz   | 14353
aaaaa a bbbb b ccc c dd d e e   | 1
aaaaa a bbbb b ccc c            | 1, 2, 3
abcxyz zbcyax                   | 623514
abcxyz acbbacbcbacbbac          | 132213232132213
potato ptao                     | 1346, 1546, 1342, 1542
a aaaaa                         | 11111
Poignée de porte
la source
Juste pour être sûr que je comprends, le processus d'abréviation peut réorganiser les lettres?
xnor
@xnor Correct, comme on le voit dans plusieurs cas de test.
Poignée de porte
Le tableau 2D peut-il avoir l'autre orientation? Chaque colonne, pas chaque ligne, contiendrait une paire de mots / abréviations
Luis Mendo
@DonMuesli Non, ce n'est pas possible.
Poignée de porte
Peut-on utiliser l'indexation zéro, donc imprimer 0235 au lieu de 1346?
Denker

Réponses:

3

Pyth, 19 octets

[email protected]

Essayez-le ici!

Prend une liste au format suivant:

[["word","abbr"],["word","abbr"],...]

Solution alternative de 17 octets qui produit le résultat sous forme de liste d'index de base zéro qui sont enveloppés dans une liste à 1 élément:

[email protected]

Explication

Exemple: [["potato", "ptao"],["puzzle", "pzze"]]

D'abord, nous mappons chaque caractère de l'abréviation à une liste des indices de toutes les occurrences du mot qui donne

[[[0], [2, 4], [3], [1, 5]], [[0], [2, 3], [2, 3], [5]]]

Ensuite, nous transposons cette liste qui nous donne

[[[0], [0]], [[2, 4], [2, 3]], [[3], [2, 3]], [[1, 5], [5]]]

Ainsi, les indices de chaque caractère de chaque abréviation sont réunis dans une liste.

Ensuite, il suffit de trouver un index commun dans toutes ces listes qui donne:

[[0], [2], [3], [5]]

Ceci est la sortie de ma solution alternative de 17 octets ci-dessus. Cela se transforme alors en[1,3,4,6] .

Répartition du code

[email protected] # Q = entrée

m Q # entrée de carte avec d
        m ed # mappe chaque abréviation avec k
            mbhd # mapper le mot à la liste des caractères
         mxk # mappe chaque caractère d'abréviation à une liste d'indices
      .T # Transposer
    Fd # Pliez chaque élément
   @ # et filtrez la présence
 hh # Prendre le premier élément du résultat et l'incrémenter
Denker
la source
Ne pourriez-vous pas également supprimer le dmdroit avant le @?
Poignée de porte
@Doorknob je peux. Merci d'avoir repéré ça!
Denker
3

MATL , 29 octets

!"@Y:!=2#fX:wX:h]N$v1XQtv4#X>

L'entrée est un tableau 2D au format suivant:

{'potato' 'ptao'; 'puzzle' 'pzze'}

Essayez-le en ligne! ( le code lié inclut certaines modifications en raison de changements dans la langue depuis la publication de cette réponse )

!       % take input. Transpose
"       % for each column
  @Y:   %   push column. Unpack the two strings and push them onto the stack
  !     %   transpose second string
  =     %   matrix with all pairwise matchings of characters in word and abbreviation
  2#f   %   find row and col indices of those matchings
  X:    %   transform into column vector
  wX:   %   swap, transform into column vector
  h     %   concat into a two-col matrix
]       % end for
N$v     % concatenate all matrices containing the indices
1       % push 1
XQ      % build matrix adding 1 for each (row,col) index
tv      % concat vertically with itself, so that it has at least two rows.
        % This forces the following function to work on each col.
4#X>    % arg max of each col: position that produces a match in all pairs.
        % If there are several maximizers in each col this gives the first

Le code nécessitait quelques astuces (et longues!) Pour

  • Empêchez l'orientation des vecteurs produits par find( f) de changer en fonction de la forme d'entrée. Ce sont des instructions X:wX:: forcez les deux sorties à être des vecteurs de colonne.
  • Contrebalance le comportement par défaut «travailler le long de la première dimension non singleton» du minX> fonction ( ). Ce sont des déclarations tv: concaténer une copie de lui-même pour assurer au moins deux lignes);
Luis Mendo
la source
2

Perl, 46 45 42 octets

Comprend +1 pour -p

Donnez une entrée sous forme de mots séquentiels sur STDIN, par exemple

perl -p abbrev.pl
prgrmming
prgmg
puzzles
pzzlz

Mettre fin à STDIN avec ^D ou ^Zou tout ce qui est nécessaire sur votre système

abbrev.pl:

s#.#${${--$_.$.%2}.=$&}||=-$_#eg;$_ x=eof

Explication

Tenez compte de cette entrée (disposition conceptuelle, pas la véritable façon de saisir pour ce programme):

potatoes     ptao
puzzle       pzze

Le programme crée des chaînes représentant les colonnes verticales des chaînes complètes indexées sur un identifiant de colonne

id1    pp     -> 1
id2    ou     -> 2
id3    tz     -> 3
id4    az     -> 4
...

etc. Il fait de même pour les abréviations, mais en utilisant un identifiant différent

ID1    pp     -> 1
ID2    tz     -> 3
ID3    az     -> 4
ID4    oe     -> 6

Les mots sont implicitement traités un par un en utilisant l' -poption. Les chaînes de colonnes sont construites en utilisant des concaténations répétées pendant que chaque mot est parcouru en utilisant s#.# ...code.. #eg, donc chaque colonne a besoin d'un identifiant répétable. J'utilise moins le numéro de colonne suivi du numéro de ligne modulo 2. Le numéro de colonne peut être construit en utilisant --$_ce qui commence comme le mot courant qui, en raison de l'utilisation de only, a-zest garanti à évaluer comme 0 dans un contexte numérique. Alors je comprends -1, -2, -3, .... J'aurais vraiment aimé utiliser 1, 2, 3, ..., mais utiliser $_++déclencherait un incrément de chaîne magique perl au lieu d'un compteur numérique normal. Je le fais veux utiliser$_ et pas une autre variable car toute autre variable que je devrais initialiser à zéro dans chaque boucle qui prend trop d'octets.

Le numéro de ligne modulo 2 est de s'assurer que les identifiants du mot complet et les identifiants de l'abréviation ne s'affrontent pas. Notez que je ne peux pas utiliser le mot complet et l'abréviation sur une chaîne pour avoir un numéro de colonne sur la chaîne combinée car les mots complets n'ont pas tous la même longueur, donc les colonnes de mots abrégés ne s'alignent pas. Je ne peux pas non plus mettre le mot abrégé en premier (ils ont tous la même longueur) car j'ai besoin que le nombre de la première colonne des mots complets soit 1.

J'abuse l'espace de noms global perl à travers une référence non stricte pour construire les chaînes de colonnes comme:

${--$_.$.%2}.=$&

Ensuite, je mappe chaque chaîne de colonne au premier numéro de colonne dans lequel cette chaîne apparaît (le mappage déjà indiqué ci-dessus) en abusant à nouveau de l'espace de noms global perl (mais notez que les noms ne peuvent pas s'affronter afin que les globaux n'interfèrent pas les uns avec les autres):

${${--$_.$.%2}.=$&} ||= -$_

Je dois annuler $_parce que, comme je l'ai expliqué ci-dessus, je compte les colonnes comme -1, -2, -3, .... La ||=marque que seule la première apparition d'une colonne donnée obtient un nouveau numéro de colonne, sinon le numéro de colonne précédente est conservée et retournée comme valeur. Cela se produira en particulier pour chaque mot abrégé car la spécification garantit qu'il y a une colonne dans les mots complets qui sera apparue au préalable. Ainsi, dans le dernier mot abrégé, chaque lettre sera remplacée par le numéro de colonne du mot complet qui correspond à la colonne de tous les mots abrégés. Le résultat de la toute dernière substitution est donc le résultat final souhaité. Imprimez donc si et seulement si nous sommes à la fin de l'entrée:

$_ x=eof

L'affectation d'index de colonne créera également des entrées pour les colonnes incomplètes car la colonne n'est pas encore complètement construite ou certains mots sont plus courts et n'atteignent pas la longueur complète de la colonne. Ce n'est pas un problème car les colonnes nécessaires dans chaque mot abrégé sont garanties d'avoir une colonne correspondante parmi les mots complets qui a la longueur maximale possible (le nombre de paires actuellement vues) de sorte que ces entrées supplémentaires ne provoquent jamais de fausses correspondances.

Ton Hospel
la source
1

Haskell, 74 octets

import Data.List
foldl1 intersect.map(\(w,a)->mapM(`elemIndices`(' ':w))a)

Le format d'entrée est une liste de paires de chaînes, par exemple:

*Main > foldl1 intersect.map(\(w,a)->mapM(`elemIndices`(' ':w))a)  $ [("potato","ptao"),("puzzle","pzze")]
[[1,3,4,6]]

Comment cela fonctionne: mapM(identique à sequence . map) transforme d'abord chaque paire (w,a)en une liste de listes d'index des lettres dans l'abréviation ( ' ':fixe l'index natif de Haskell basé sur 0 à 1), par exemple ("potato", "ptao") -> [[1],[3,5],[4],[2,6]], puis en une liste de toutes les combinaisons de celles-ci où l'élément en position iest tiré de la ie sous-liste, par exemple [[1,3,4,2],[1,3,4,6],[1,5,4,2],[1,5,4,6]]. foldl1 intersecttrouve l'intersection de toutes ces listes de listes.

nimi
la source
0

ES6, 92 octets

(w,a)=>[...a[0]].map((_,i)=>[...w[0]].reduce((r,_,j)=>w.some((s,k)=>s[j]!=a[k][i])?r:++j,0))

Accepte l'entrée comme un tableau de mots et un tableau d'abréviations. Renvoie un tableau d'index basés sur 1 (ce qui me coûte 2 octets). Dans le cas de solutions multiples, les indices les plus élevés sont renvoyés.

Neil
la source
0

Python 3, 210 octets

Pas une réponse impressionnante en voyant les meilleurs scores ici, mais c'est vraiment l'une des compréhension de liste les plus folles que j'ai jamais faites avec Python. L'approche est assez directe.

 def r(p):
    z=[[[1+t[0]for t in i[0]if l==t[1]]for l in i[1]]for i in[[list(enumerate(w[0])),w[1]]for w in p]]
    return[list(set.intersection(set(e),*[set(i[z[0].index(e)])for i in z[1:]]))[0]for e in z[0]]

La fonction attend l'entrée toujours sous forme de tableau 2D comme: [[word, abbr],...]et renvoie une liste d'entiers.

Ps: Une explication détaillée à venir

Ps2: D'autres suggestions de golf sont les bienvenues!

Ioannes
la source