Generalizzazione delle abbreviazioni


14

Dato un input di un elenco di parole e le loro abbreviazioni, genera lo schema con cui le abbreviazioni possono essere formate.

Facciamo l'esempio di input di

potato ptao
puzzle pzze

come esempio (ovvero l'abbreviazione di potatois ptaoe l'abbreviazione di puzzleis pzze).

Considera tutti i modi possibili per ottenere ptaoda potato. Un modo possibile è quello di prendere la prima, la terza, la quarta e la sesta lettera, a cui faremo riferimento 1346. Ma dal momento che te oapparire più volte nella parola, ci sono più altri modi possibili per generare ptaoda potato: 1546, 1342, e 1542.

Analogamente, nota che pzzepuò essere generato da puzzleuna qualsiasi delle 1336, 1346, 1436, 1446. L'unico modello che queste due abbreviazioni hanno in comune è 1346; pertanto, questo deve essere l'output per questo input. Se sono possibili più pattern possibili, è possibile emetterne uno, alcuni o tutti (almeno uno).

Puoi presumere che:

  • Le parole e le abbreviazioni di input contengono solo lettere minuscole.

  • C'è almeno una coppia di parole / abbreviazioni nell'input.

  • È possibile che ogni abbreviazione sia formata dalla sua parola corrispondente.

  • Ci sarà sempre almeno un modello che forma ogni abbreviazione.

  • La lunghezza massima di ogni parola è di 9 caratteri.

L'input può essere preso come uno dei seguenti:

  • Matrice / elenco / matrice di tuple bidimensionali / ecc. [[word, abbr], [word, abbr], ...]

  • matrice / elenco monodimensionali piatti [word, abbr, word, abbr, ...]

  • stringa singola, delimitata da un singolo carattere che non è una lettera minuscola "word abbr word abbr"

  • hash / array associativo / ecc. {word => abbr, word => abbr, ...}

In una di queste opzioni di input, puoi anche scambiare l'ordine di word / abbr (descrivi completamente il formato di input nel tuo post).

L'output può essere dato come un singolo numero, una stringa delimitata da non cifre o un array / elenco / tupla / ecc. di numeri.

Poiché si tratta di , vincerà il codice più breve in byte.

Casi di test (ricorda che devi solo produrre risultati ≥1 se funzionano più pattern):

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

Giusto per essere sicuro di capire, il processo di abbreviazione può riordinare le lettere?
xnor

@xnor Corretto, come visto in molti dei casi di test.
Maniglia della porta

L'array 2D può avere l'altro orientamento? Ogni colonna, non ogni riga, conterrebbe una coppia di parole / abbrev
Luis Mendo

@DonMuesli No, non può.
Maniglia della porta

Possiamo usare l'indicizzazione zero, quindi stampare 0235 invece di 1346?
Denker

Risposte:


3

Pyth, 19 byte

mhh@Fd.TmmxkmbhdedQ

Provalo qui!

Prende un elenco nel seguente formato:

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

Soluzione alternativa a 17 byte che genera il risultato come elenco di indici a base zero che sono racchiusi in un elenco di 1 elemento:

m@Fd.TmmxkmbhdedQ

Spiegazione

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

Per prima cosa mappiamo ogni carattere dell'abbreviazione su un elenco degli indici di tutte le occorrenze nella parola che produce

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

Quindi trasponiamo questo elenco che ci dà

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

Quindi gli indici di ciascun carattere di ogni abbreviazione sono riuniti in un elenco.

Quindi non ci resta che trovare un indice comune in tutti quegli elenchi che produce:

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

Questo è l'output della mia soluzione alternativa a 17 byte sopra. Questo poi si trasforma in [1,3,4,6].

Analisi del codice

mhh@Fd.TmmxkmbhdedQ # Q = input

m Q # input mappa con d
        m ed # mappa ogni abbreviazione con k
            mbhd # mappa la parola all'elenco dei caratteri
         mxk # mappa ogni carattere di abbreviazione su un elenco di indici
      .T # Transpose
    Fd # Piega ogni elemento
   @ # e filtro in presenza
 hh # Prendi il primo elemento del risultato e incrementalo

Non potresti anche cancellare il dmdiritto prima del @?
Maniglia della porta

@Doorknob Posso. Grazie per averlo individuato!
Denker

3

MATL , 29 byte

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

L'input è un array 2D nel seguente formato:

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

Provalo online! ( il codice collegato include alcune modifiche dovute a cambiamenti nella lingua da quando è stata pubblicata questa risposta )

!       % 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

Il codice ha richiesto alcuni trucchi (e lunghi!) Coinvolti

  • Impedire che l'orientamento dei vettori prodotti da find( f) cambi a seconda della forma di input. Queste sono affermazioni X:wX:: forzare entrambi gli output in vettori di colonna.
  • Contrastare il comportamento predefinito "lavorare lungo la prima dimensione non singleton" della funzione min( X>). Queste sono affermazioni tv: concedere una copia di se stesso per assicurare almeno due righe);

2

Perl, 46 45 42 byte

Include +1 per -p

Fornire input come parole sequenziali su STDIN, ad es

perl -p abbrev.pl
prgrmming
prgmg
puzzles
pzzlz

Terminare STDIN con ^Do ^Zo qualsiasi altra cosa sia necessaria sul proprio sistema

abbrev.pl:

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

Spiegazione

Considera questo input (layout concettuale, non il vero modo di input per questo programma):

potatoes     ptao
puzzle       pzze

Il programma crea stringhe che rappresentano le colonne verticali delle stringhe complete indicizzate su un ID colonna

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

ecc. Fa lo stesso anche per le abbreviazioni, ma usando un ID diverso

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

Le parole vengono elaborate implicitamente una per una usando l' -popzione. Le stringhe delle colonne sono costruite usando concatenazioni ripetute mentre ogni parola è percorsa usando s#.# ...code.. #eg, quindi ogni colonna ha bisogno di un ID ripetibile. Uso meno il numero di colonna seguito dal numero di riga modulo 2. Il numero di colonna può essere costruito usando --$_quale inizia come la parola corrente che a causa dell'uso di solo a-zè garantita per valutare come 0 in un contesto numerico. Quindi capisco -1, -2, -3, .... Mi sarebbe davvero piaciuto usare 1, 2, 3, ..., ma l'utilizzo $_++avrebbe innescato l'incremento della stringa magica perl invece di un normale contatore numerico. Io non voglio usare$_ e non qualche altra variabile perché qualsiasi altra variabile dovrei inizializzare a zero in ogni ciclo che richiede troppi byte.

Il numero di riga modulo 2 è per assicurarsi che gli ID per la parola completa e gli ID per l'abbreviazione non si scontrino. Si noti che non posso usare la parola completa e l'abbreviazione su una stringa per avere un numero di colonna che passa sopra la stringa combinata perché le parole complete non hanno tutte la stessa lunghezza, quindi le colonne di parole abbreviate non si allineano. Inoltre, non posso inserire prima la parola abbreviata (hanno tutti la stessa lunghezza) perché ho bisogno che il conteggio della prima colonna delle parole complete sia 1.

Abuso lo spazio dei nomi globale perl attraverso un riferimento non rigoroso per costruire le stringhe di colonna come:

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

Successivamente, associo ogni stringa di colonna al primo numero di colonna in cui appare mai la stringa (il mapping già indicato sopra) abusando di nuovo dello spazio dei nomi globale perl (ma noto che i nomi non possono scontrarsi in modo che i globali non interferiscano l'uno con l'altro):

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

Devo negare $_perché come ho spiegato sopra conto le colonne come -1, -2, -3, .... L' ||=assicurarsi che solo la prima apparizione di una data colonna ottiene un nuovo numero di colonna, altrimenti il numero di colonna precedente è conservato e restituito come valore. Ciò accadrà in particolare per ogni parola abbreviata poiché la specifica garantisce che sia presente una colonna nelle parole complete che saranno apparse prima. Quindi nell'ultima parola abbreviata ogni lettera sarà sostituita dal numero di colonna nella parola intera che corrisponde alla colonna per tutte le parole abbreviate. Quindi il risultato dell'ultima sostituzione è il risultato finale desiderato. Quindi stampa se e solo se siamo alla fine dell'input:

$_ x=eof

L'assegnazione dell'indice di colonna creerà anche voci per colonne incomplete perché la colonna non è ancora completamente costruita o alcune parole sono più brevi e non raggiungono l'intera lunghezza della colonna. Questo non è un problema poiché le colonne necessarie in ogni parola abbreviata sono garantite avere una colonna corrispondente dalle parole complete che ha la massima lunghezza possibile (il numero di coppie attualmente viste), quindi queste voci extra non causano mai false corrispondenze.


1

Haskell, 74 byte

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

Il formato di input è un elenco di coppie di stringhe, ad esempio:

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

Come funziona: mapM(uguale a sequence . map) trasforma prima ogni coppia (w,a)in un elenco di elenchi di indici delle lettere nell'abbreviazione ( ' ':corregge l'indice nativo di Haskell basato su 0 su 1 basato), ad esempio ("potato", "ptao") -> [[1],[3,5],[4],[2,6]]e quindi in un elenco di tutte le combinazioni di questi dove l'elemento in posizione iè tratto dal isottomenu, ad es [[1,3,4,2],[1,3,4,6],[1,5,4,2],[1,5,4,6]]. foldl1 intersecttrova l'intersezione di tutti questi elenchi di elenchi.


0

ES6, 92 byte

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

Accetta input come una matrice di parole e una matrice di abbreviazioni. Restituisce una matrice di indici basati su 1 (che mi costa 2 byte dannazione). Nel caso di più soluzioni, vengono restituiti gli indici più alti.


0

Python 3, 210 byte

Non è una risposta impressionante vedere i punteggi migliori qui, ma questa è davvero una delle più folle comprensione della lista che io abbia mai fatto con Python. L'approccio è abbastanza diretto.

 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 funzione si aspetta sempre input come una matrice 2-D stringa come: [[word, abbr],...]e restituisce un elenco di numeri interi.

Ps: una spiegazione dettagliata in arrivo

Ps2: ulteriori suggerimenti sul golf sono i benvenuti!

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.