Il gioco delle targhe in Spagna


26

Questa domanda si basa su una domanda che ho posto in lingua spagnola . Sì, ho chiesto un algoritmo in lingua spagnola. :)

In Spagna, le attuali targhe hanno questo modello:

1234 XYZ

dove XYZ sono tre consonanti tratte dalla serie completa di consonanti spagnole (tranne "Ñ", credo).

A volte, quando viaggiamo con mia moglie, usiamo una partita. Quando vediamo una targa, prendiamo le sue tre consonanti e proviamo a formare una parola che contenga quelle tre consonanti, che appare nello stesso ordine della targa. Esempi (in spagnolo):

BCD
    BoCaDo (valid)
    CaBezaDa (not valid)
FTL
    FaTaL (valid)
    FLeTar (not valid)
FTR
    FleTaR (valid, wins)
    caFeTeRa (valid, loses)

Il vincitore è colui che utilizza il minor numero di personaggi, come puoi vedere nell'ultimo esempio.

La sfida

Scrivi il programma o la funzione più breve che riceve un elenco di parole e un insieme di tre consonanti e trova la parola più breve nell'elenco che contiene le tre consonanti nello stesso ordine. Ai fini di questo gioco, il caso non ha importanza.

  • L'input per l'elenco di parole (primo parametro) sarà un array del tuo stringtipo di lingua . Il secondo parametro (le tre consonanti) sarà un altro string. Se è meglio per la tua lingua, considera stringcon le tre consonanti l'ultimo elemento dell'intero elenco di parametri. L'output sarà un altro string.
  • Le parole nell'elenco delle parole non saranno inventate o infinite, saranno le parole che compaiono in qualsiasi dizionario standard. Se hai bisogno di un limite, supponi che nessuna parola nell'elenco di parole sia più lunga di 50 caratteri.
  • Se ci sono più parole della stessa lunghezza che potrebbero essere la risposta valida, puoi restituire una qualsiasi di esse. Assicurati solo di restituire solo una parola o una stringa vuota se nessuna parola corrisponde allo schema di tre consonanti.
  • Puoi ripetere le consonanti nel gruppo, quindi input validi per le tre consonanti sono entrambi FLRe GGG.
  • Le consonanti spagnole sono esattamente le stesse dell'inglese, con l'aggiunta di "Ñ". Le vocali sono le stesse dell'adorazione delle vocali stressate: "áéíóúü". Non ci saranno altri tipi di segni come "-" o "'".
  • Puoi supporre che il caso sarà sempre lo stesso sia nell'elenco delle parole che nelle tre consonanti.

Se vuoi testare il tuo algoritmo con una vera raccolta di parole spagnole, puoi scaricare un file (15,9 MB) da Dropbox con più di un milione di parole.

Casi test

Input: 'psr', {'hola' 'repasar' 'pasarais' 'de' 'caída' 'pequeñísimo' 'agüeros'}
Output: 'repasar'

Input: 'dsd', {'dedos' 'deseado' 'desde' 'sedado'}
Output: 'desde'

Input: 'hst', {'hastío' 'chest'}
Output: 'chest'

Questo è , quindi vince il programma più breve che mi aiuta a battere sempre mia moglie! :)


Per quanto tempo sono garantite le parole nell'elenco delle parole?
Neil,

2
Nelle targhe effettive, neanche la lettera Q è consentita; e W è, anche se non una vera lettera spagnola
Luis Mendo il

2
Possiamo assumere le parole nell'elenco e le tre lettere saranno tutte in un caso?
Jonathan Allan,

1
@LuisMendo W è una lettera spagnola dal 1969 .
walen

1
@walen Ecco perché ho detto "corretto" :-) Esiste in spagnolo, ma sembra straniero
Luis Mendo,

Risposte:


7

05AB1E , 10 8 byte

Salvato 2 byte grazie a Leo

ʒæså}éR`

Provalo online!

Spiegazione

ʒ         # filter list, keep only members for which the following is true
  så      # input is in the
 æ        # powerset of the current word
    }     # end filter
     é    # sort by length
      R   # reverse
       `  # push separately (shortest on top)

Avrei usato headalla fine il salvataggio di un byte ma che avrebbe prodotto un elenco vuoto se non ci fosse una corrispondenza.


3
3ù #keep only those of length 3Perchè ti serve?
Leo,

1
@Leo: no, è stato sciocco da parte mia. Grazie :)
Emigna il

6

MATL , 30 29 byte

xtog!s2$S"1G!'.*'Yc!@gwXXn?@.

Provalo online!

Spiegazione

x         % Implicitly take first input (string with three letters). Delete.
          % Gets copied into clipboard G, level 1
t         % Implicitly take second input (cell array of strings defining the
          % words). Duplicate
o         % Convert to numeric array of code points. This gives a matrix where
          % each string is on a row, right-padded with zeros
g         % Convert to logical: nonzeros become 1
!s        % Sum of each row. This gives the length of each word
2$S       % Two-input sort: this sorts the array of strings according to their
          % lengths in increasing order
"         % For each word in the sorted array
  1G      %   Push first input, say 'xyz'
  !       %   Transpose into a column vector of chars
  '.*'Yc  %   Concatenate this string on each row
  !       %   Transpose. This gives a char array which, when linearized in
          %   column-major order, corresponds to 'x.*y.*z.*'
  @g      %   Push corrent word
  w       %   Swap
  XX      %   Regexp matching. Gives a cell array with substrings that match
          %   the pattern 'x.*y.*z.*'
  n       %   Number of matchings
  ?       %   If non-zero
    @     %     Push cell array with current word, to be displayed as output
    .     %     Break loop
          %   Implicit end (if)
          % Implicit end (for)
          % Implicitly display stack

6

PHP , 111 byte

$y=array_map(str_split,preg_grep("#".chunk_split($_GET[1],1,".*")."#",$_GET[0]));sort($y);echo join($y[0]??[]);

Provalo online!


2
La targa dovrebbe essere una stringa, non un array. Ma non hai bisogno del modificatore.
Tito,

@Titus fixed !!
Jörg Hülsermann,

You can suppose the case will always be the same in both the word list and the three consonants.- non è necessario il modificatore regex. Hai provato wordwrapinvece join(str_split())?
Tito,

@Titus buona idea
Jörg Hülsermann,

5

Gelatina ,  12 11  10 byte

ŒPċðÐfLÞḣ1

Un programma completo che accetta un elenco di elenchi di caratteri minuscoli (le parole) e un elenco di caratteri minuscoli (le lettere) e stampa la prima delle parole più brevi che contengono una sotto-sequenza uguale alle lettere (o nulla se non esiste ).

Provalo online!

Come?

ŒPċðÐfLÞḣ1 - Main link: words; characters
   ðÐf     - filter keep words for which this is truthy:
ŒP         -   the power-set (all sub-sequences of the word in question)
  ċ        -   count (how many times the list of characters appears)
           - ...note 0 is falsey while 1, 2, 3, ... are truthy
       Þ   - sort by:
      L    -  length
        ḣ1 - head to index 1 (would use Ḣ but it yields 0 for empty lists)
           - implicit print (smashes together the list of lists (of length 1))

1
Se capisco correttamente la tua spiegazione, ciò rifiuterebbe una parola come "borracho" per una sequenza di consonanti di "brc", perché "brc" non è una sottostringa di "brrc"
Leo,

@Leo ah, sì, buona cattura, penso che fallirebbe ...
Jonathan Allan,

@Leo - beh, è ​​stato risolto (i controlli "esiste in" per l'intero gruppo di potenza di ogni parola) ma potrebbe non essere completamente giocato a golf ...
Jonathan Allan,

5

Pyth - 22 21 19 12 11 byte

h+f/yTQlDEk

-1 Grazie a Maltysen.

Accetta 2 righe come input. Il primo è la stringa di 3 lettere (minuscole) e il secondo è un elenco di parole minuscole.

Provalo qui

Spiegazione:

h+f/yTQlDEk
       lDE   # Sort word list by length
  f          # Filter elements T of the word list...
    yT       # by taking the powerset...
   /  Q      # and checking whether the 3-letter string Q is an element of that.
 +        k  # Add empty string to the list (in case no results found)
h            # And take the first result (the shortest)

Vecchia soluzione a 19 byte:

h+olNf/-T"aeiou"QEk                       

@JonathanAllan: risolto! Grazie per la segnalazione.
Maria,

1
@JonathanAllan: Sembra che abbia modificato la domanda per chiarire che in quel caso dovrebbe restituire una stringa vuota. Ho modificato la mia risposta di conseguenza.
Maria,

1
Abbiamo un meta operatore di ordinamento in D, quindi puoi sostituire olN con lD
Maltysen il

5

Brachylog v2, 11 byte

tlᵒ∋.&h⊆.∨Ẹ

Provalo online!

Invio di funzioni. (Il collegamento TIO ha un argomento della riga di comando per eseguire una funzione come se fosse un programma completo.)

Spiegazione

Ancora una traduzione diretta delle specifiche ...

tlᵒ∋.&h⊆.∨Ẹ
t            The last element of {standard input}
   ∋.        contains the return value as an element
     &       and
      h      the first element of {standard input}
       ⊆.    is a subsequence of the return value
         ∨   alternate behaviour if no solution is found:
          Ẹ  return empty string
  ᵒ          tiebreak override: favour answers that have a low
 l           length

In realtà puoi quasi rispondere h⊆.&t∋- scambiando l'ordine di valutazione significa che Brachylog sceglierà la risposta più breve per impostazione predefinita (poiché il primo vincolo che vede è , che ha il "più breve" piuttosto conveniente come un tiebreak predefinito) - ma in quel caso, Brachylog's purtroppo l'algoritmo di valutazione andrebbe in un ciclo infinito se la risposta non fosse effettivamente trovata. Quindi quasi la metà della risposta è dedicata alla gestione del caso in cui non esiste una risposta appropriata. Anche in questo caso, il lᵒtiebreak ha la precedenza (che è tecnicamente una specie, sfruttandoil tiebreak predefinito di preferire elementi più vicini all'inizio dell'elenco) è solo due byte; gli altri tre derivano dalla necessità di emettere una stringa vuota in particolare quando l'output non viene trovato, al contrario del valore sentinel predefinito "nessuna soluzione" di Brachylog (perché il finale .sarebbe implicito se non dovessimo seguirlo ).

È interessante notare che c'è una funzionalità precedentemente implementata in Brachylog che avrebbe salvato un byte qui. A un certo punto, si potrebbe estrarre elementi dal argomento di input utilizzando ?₁, ?₂ecc sintassi; ciò ti permetterebbe di riorganizzare il programma a tlᵒ∋.⊇?₁∨Ẹ, che è solo 10 byte. Sfortunatamente, l'implementazione che è stata utilizzata in realtà non ha funzionato (e ha causato la rottura di molti programmi altrimenti funzionanti), quindi è stata ripristinata. Tuttavia, puoi pensare al programma come "concettualmente" lungo 10 byte.


4

Haskell 129 125 74 byte

import Data.List
l#w=sortOn length[p|p<-w,isInfixOf l$filter(`elem`l)p]!!0

CREDITO a @nimi


1
È possibile sostituire il più a destra mape il filtercon una comprensione dell'elenco. Come hai già Data.Listin ambito, puoi usare sortOn lengthe selezionare la testa per trovare l'elemento con una lunghezza minima. Infine, crea yuna funzione infix. Tutto questo rende fe ksuperflue: l#w=sortOn length[p|p<-w,isInfixOf l$filter(`elem`l)p]!!0.
nimi,

hai ragione! Ho appena iniziato a giocare a golf! Grazie!
Davide Spataro,

1
Un altro: se si passa l'importazione Data.Lists, è possibile utilizzare argminal posto di sortOne salvare il !!0: l#w=argmin length[...]. Data.Listsha molte belle funzioni
nimi,

3

Perl, 53 byte

48 byte codice + 5 per -paF.

$"=".*";($_)=sort{$a=~y///c-length$b}grep/@F/,<>

Questo sfrutta il fatto che le liste interpolati in m//operatore utilizzano la $"variabile che cambia la stringa di input iniziale da psra p.*s.*rche viene poi abbinato per ogni parola aggiuntiva e viene ordinato in base length.

Provalo online!


Se inserisco "adsd" nel tuo elenco, il tuo programma non riesce a trovarlo. Il primo personaggio da trovare non deve necessariamente essere il primo nella parola.
Charlie,

@CarlosAlejo L'ingresso ha bisogno di una nuova riga finale, quindi funziona bene: provalo online! . Questo però mi ha preso alla sprovvista, poiché l' <<<operatore lo aggiunge alla riga di comando!
Dom Hastings,

3

JavaScript (ES6), 77 75 72 byte

Accetta le 3 consonanti ce l'elenco di parole lnella sintassi del curry (c)(l). Entrambi gli input sono previsti nello stesso caso.

c=>l=>l.map(w=>x=!w.match([...c].join`.*`)||!x[w.length]&&x?x:w,x='')&&x

Casi test


c=>l=>l.sort((a,b)=>a[b.length]&&1).find(w=>w.match(c.split``.join`.*`))per 72, credo
LarsW il

@LarsW Davvero, grazie! Comunque ho scelto un altro approccio per conformarmi alla nuova regola: o una stringa vuota se nessuna parola corrisponde allo schema di tre consonanti .
Arnauld,

3

R, 101 byte

Prima volta a giocare a golf! Sono sicuro che questo può essere condensato in qualche modo

Accetta la stringa xe un vettore di caratteri y di possibili input

w=pryr::f((b=y[sapply(gsub(paste('[^',x,']'),'',y),function(l)regexpr(x,l))>0])[which.min(nchar(b))])

Provalo online!

Modifica: la mia versione era 135, grazie Scrooble per il -34!


1
Benvenuti in PPCG! Sembra un frammento in cui l'input è in variabili hardcoded. Le risposte devono essere programmi completi o funzioni richiamabili. Puoi dare un'occhiata a questo (o ad altre risposte R) per possibili metodi I / O.
Martin Ender,

2

Retina , 58 byte

O#$^`¶.+
$.&
s`^((.)(.)(.).*¶(?-s:(.*\2.*\3.*\4.*)))?.*
$5

Provalo online! Prende le tre consonanti su una riga e quindi l'elenco di parole su tutte le righe successive. Spiegazione: Oordina l'elenco ¶.+escludendo la prima riga digitata #numericamente $per $.&lunghezza. Viene quindi cercata una corrispondenza per una linea che includa le tre consonanti in ordine. Se esiste una linea adatta rispetto all'ultima, ovvero la più corta, tale linea diventa l'uscita, altrimenti l'uscita è vuota. L' ?-s:opzione disattiva temporaneamente l'effetto in s`modo che sia abbinata solo una riga.


1
Non riesco a decidere se si tratta di tre ombelici o tre seni.
Charlie,

@CarlosAlejo Stai pensando a Eccentrica Gallumbits per caso?
Neil,

Stavo pensando all'alieno di Total Recall, ma Eccentrica potrebbe anche essere un'opzione ... :)
Charlie,

2
@CarlosAlejo Apparentemente Mary è un omaggio a Eccentrica Gallumbits.
Neil,

1

Pip , 17 byte

@:qJ`.*`N_FI#_SKg

Prende l'elenco di parole come argomenti della riga di comando e le consonanti di stdin. Provalo online!

Spiegazione

                   g is list of cmdline args (implicit)
              SKg  Sort g using this key function:
            #_      Length of each item (puts shortest words first)
          FI       Filter on this function:
  q                 Line of input
   J`.*`            joined on regex .* (turns "psr" into `p.*s.*r`)
        N_          Count regex matches in item (keeps only words that match)
@:                 Get first element of result (using : meta-operator to lower precedence)
                   If the list is empty, this will give nil, which results in empty output

1

Java 8, 132 126 byte

s->a->{String r="";for(String x:a)r=(x.length()<r.length()|r.isEmpty())&x.matches(r.format(".*%s.*%s.*%s.*",s))?x:r;return r;}

-6 byte grazie a @Nevay .

Spiegazione:

Provalo online.

s->a->{              // Method with two String-array parameters and String return-type
  String r="";       //  Result-String, starting empty
  for(String x:a)    //  Loop over the words
    r=(x.length()<r.length()
                     //   If a word is smaller than the current `r`,
      |r.isEmpty())  //   or `r` is still empty
      &x.matches(r.format(".*%s.*%s.*%s.*",s))?
                     //   And if the word is valid
       x             //    Change `r` to the current word
      :              //   Else:
       r;            //    Leave `r` the same
  return r;}         //  Return the result

1
126 byte:s->a->{String r="";for(String x:a)r=(x.length()<r.length()|r.isEmpty())&x.matches(r.format(".*%s.*%s.*%s.*",s))?x:r;return r;}
Nevay,


0

MATL , 28 27 26 byte

x"l1G@g3XNXm/@gn*v]&X<2Gw)

Provalo online!

x- Prendi implicitamente il primo input (stringa con tre lettere) ed eliminalo. Viene copiato negli Appunti G, livello 1 automaticamente (questa parte è stata ispirata dalla risposta di @Luis Mendo ).

" - Prendi implicitamente il secondo input (array di parole delle celle), iterando attraverso di esso.

l - Premere 1 per usarlo in seguito

1G - Premi il primo input (dì "psr")

@g - Spingi la parola corrente come matrice

3XN- nchoosek- Ottieni tutte le combinazioni di 3 lettere dalla parola

Xm- Verifica se il codice targa "psr" è una di queste combinazioni. Restituisce 0 per falso e 1 per vero.

/- Dividendo l'1 (che abbiamo spinto in precedenza) per questo risultato. Cambia gli 0 in Infs

@gn - Ottieni la lunghezza della parola corrente

*- Moltiplica la lunghezza per il risultato della divisione. Restituisce la lunghezza così com'è quando la parola contiene i 3 caratteri, altrimenti restituisceInf

v - concatena verticalmente questi risultati in un singolo array

] - anello chiuso

&X< - ottenere l'indice del valore minimo da quell'array, ovvero l'indice in cui è stata trovata la parola contenente le lettere e con lunghezza minima

2G - Premere di nuovo il secondo ingresso

w - Riporta l'indice minimo in cima allo stack

) - Indicizza in serie di parole con l'indice minimo, restituendo la parola valida con lunghezza minima

(Uscita implicita.)


Più vecchio:

x"@g1Gy3XNXm1w/wn*v]&X<2Gw)

x"@g1Gy3XNXm1w/wn*v]2Gw2$S1)
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.