Implementa funzionalità simili a t9


10

La tua sfida oggi è implementare una funzionalità simile al t9 .

Implementerai una funzione che avrà solo 2 parametri.
Riceverai 1 numero di telefono in una stringa e il contenuto di un file di testo con un elenco di parole (non assumere uno stile di nuova riga specifico).
È possibile utilizzare il collegamento https://raw.githubusercontent.com/eneko/data-repository/master/data/words.txt per testare la funzionalità oppure utilizzare /usr/share/dict/words(selezionare Un file di testo con un elenco di parole [chiuso] per ulteriori informazioni informazione).

Puoi presumere che riceverai sempre almeno 2 numeri.

Dato il numero, leggerai da un elenco di parole e restituirai le parole che iniziano con le lettere che si associano a quelle parole. Ciò significa che l'input dovrebbe essere solo numeri da 2 a 9.
Puoi fare tutto ciò che vuoi se ricevi input non validi.

Se non viene trovata alcuna corrispondenza, è possibile restituire un elenco vuoto, null/ nilo 0.

Ricorda che i tasti del cellulare sono associati ai loro caratteri equivalenti:

  • 0 e 1 non sono validi
  • 2 corrispondenze [abc]
  • 3 abbinati [def]
  • 4 partite [ghi]
  • 5 partite [jkl]
  • 6 partite [mno]
  • 7 corrispondenze [pqrs]
  • 8 partite [tuv]
  • e 9 partite [wxyz]

Esempi:

f('52726')
//returns ["Japan","japan","Japanee","Japanese","Japanesque"...,"larbowlines"]

f('552')
//returns ["Kjeldahl","kjeldahlization","kjeldahlize"...,"Lleu","Llew"]

f('1234')
//makes demons fly out your nose or divide by 0

f('9999')
//returns ["Zyzzogeton"]

f('999999')
//returns [] or null/nil or 0

Dopo aver eseguito la funzione, è possibile stamparla nel modo desiderato.

Regole:

  • Le scappatoie standard sono NON VALIDE
  • Devi restituire qualcosa, anche se è null/ nil
    Javascript restituirà undefinedse non restituisci qualcosa, quindi questa regola.
  • Non è possibile utilizzare o implementare nuovamente le risposte degli altri o copiare la mia implementazione.
  • Si può presumere, per Javascript, che il browser sarà già aperto e che innerText/ textContentdell'elemento automatico verrà passato come secondo parametro
  • Per le lingue compilate, non è possibile passare argomenti speciali al compilatore
  • È possibile ricevere il nome del file tramite argomenti del compilatore
  • Variabili, macro, variabili globali, costanti, classi non standard e tutto l'ordinamento che passa altri valori all'interno della funzione saranno considerati non validi.
  • In Javascript, le variabili senza la parola chiave varrendono il codice non valido
  • La tua funzione sarà nominata f
  • Puoi solo e avere solo 2 argomenti sulla tua funzione
  • Cerca di mantenere il codice per meno di 500 secondi per l'esecuzione.
  • Non devi preoccuparti di spazi bianchi
  • È necessario utilizzare solo caratteri stampabili ASCII .
    Le eccezioni sono le lingue che usano solo caratteri non stampabili (APL e spazi bianchi sono 2 esempi).

punteggio:

  • Il numero più basso di byte vince
  • Avere caratteri ASCII non validi nella tua risposta, verrà conteggiato come la risposta codificata in UTF-32
    L'eccezione alla codifica farà sì che la tua risposta venga conteggiata dai caratteri .
  • Conta solo il corpo della funzione, non contare nient'altro che fai al di fuori di esso
  • Bonus del -30% se crei un sistema di previsione basato sul vicinato o sulle parole più comuni
  • Bonus di -20% in termini di dimensioni se si restituiscono solo le prime 5 corrispondenze per ogni lettera corrispondente al primo numero (ad esempio: 245 restituirà 5 parole che iniziano con 'a', 5 che iniziano con 'b' e 5 che iniziano con 'c' ).

Ecco un esempio di implementazione, usando Javascript:

function f(phone, words)
{
    var keypad=['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz'];
    var regex='';

    for(var i=0,l=phone.length;i<l;i++)
    {
        regex+='['+keypad[phone[i]]+']';
    }

    var regexp=new RegExp('\\s('+regex+'[a-z]*)\\s','gi');

    return words.match(regexp);
}

Per eseguirlo, aprire il collegamento dell'elenco ed eseguire, ad esempio:

f('9999',document.getElementsByTagName('pre')[0].innerText);
//returns [" Zyzzogeton "]

Questo esempio è stato testato e funziona con Opera 12.17 64 bit su Windows 7 Home Edition 64 bit.


Il secondo argomento del programma è un nome file che contiene le parole o l'elenco di parole stesse?
Ottimizzatore

@ MartinBüttner UTF-8 non è ingiusto (conta ancora i caratteri ASCII come 1 byte), ma ho cambiato la regola.
Ismael Miguel,

@Optimizer Il secondo argomento è un elenco di parole. È possibile passare il nome file su un argomento del compilatore e leggere il file, se lo si desidera. Ma l'unica cosa che conta è il corpo della funzione.
Ismael Miguel,

@ MartinBüttner Contando come ASCII, viene contato come byte. Vuoi che dica che il codice APL avrà 1 byte della dimensione di 8 bit?
Ismael Miguel,

2
-1 per restrizioni inadeguate
AJMansfield l'

Risposte:


3

CJam, 28 byte

q~{el{'h-_9/-D+3/}%s1$#!},p;

Accetta input sotto forma di "<number>" [<list of words>]

Esempio:

"52726" ["Japan" "japan" "Japanee" "Japanese" "Japanesque" "larbowlines" "ablution" "ablutionary" "abluvion" "ably" "abmho" "Abnaki" "abnegate"]

Produzione:

["Japan" "japan" "Japanee" "Japanese" "Japanesque" "larbowlines"]

Per ora non ci sono bonus.

Prova qui il codice online ma per misurazioni del tempo effettivo, eseguilo sul compilatore Java

Si noti che CJam rappresenta liste vuote come ""

Per convertire l'elenco di parole non elaborato in elenco CJam, utilizzare il seguente codice con l'elenco di parole come input:

qN/p

"Riceverai 1 numero di telefono in una stringa e il contenuto di un file di testo con un elenco di parole" -> puoi implementare, su un blocco diverso, il codice necessario per leggere il file in un elenco utilizzabile?
Ismael Miguel,

@IsmaelMiguel Intendi non la parte di questo codice, ma solo un codice di aiuto per convertire l'elenco nel formato corretto?
Ottimizzatore

Esattamente. Quale codice non è sufficiente per dimostrare che può utilizzare un elenco di parole come esempi forniti. Ma ho votato comunque, volevo solo quel codice di supporto.
Ismael Miguel,

Puoi aggiungerlo alla risposta? Come modifica, in una parte diversa
Ismael Miguel, il

Esattamente. Ecco di cosa sto parlando! Vediamo se riesci a ottimizzarlo ulteriormente
Ismael Miguel,

2

Java: 395

Ciò forma un modello regex basato sulle lettere consentite per ciascun numero, quindi si attacca su un. * Alla fine per abbinare i seguenti caratteri.

Ecco la versione golfata:

static ArrayList<String> f(String n,ArrayList<String> d){String[] k={"","","([A-Ca-c])","([D-Fd-f])","([G-Ig-i])","([J-Lj-l])","([M-Om-o])","([P-Sp-s])","([T-Vt-v])","([W-Zw-z])"};String r="";for(int i=0;i<n.length();++i)r+=k[n.charAt(i)-'0'];r += ".*";Pattern p=Pattern.compile(r);ArrayList<String> a=new ArrayList<String>();for(String w:dictionary)if(p.matcher(w).matches())a.add(w);return a;}

Ed ecco la versione non golfata per la lettura

public static ArrayList<String> f(String phoneNumber, ArrayList<String> dictionary) {

    String[] KEY_VALUES = {"", "", "([A-Ca-c])", "([D-Fd-f])", "([G-Ig-i])",
                                            "([J-Lj-l])", "([M-Om-o])", "([P-Sp-s])",
                                            "([T-Vt-v])", "([W-Zw-z])"};

    String regex = "";
    for (int i = 0; i < phoneNumber.length(); ++i) {
        regex += KEY_VALUES[phoneNumber.charAt(i) - '0'];
    }
    regex += ".*";
    Pattern p = Pattern.compile(regex);
    ArrayList<String> answers = new ArrayList<String>();
    for (String word : dictionary) {
        if (p.matcher(word).matches()) {
            answers.add(word);
        }
    }
    return answers;
}

Il tuo codice va contro la regola numero 7: "Le variabili, le macro, le variabili globali, le costanti, le classi non standard e tutto l'ordinamento che passa altri valori all'interno della funzione saranno considerati non validi." e va un po 'contro la regola numero 3: "Non puoi usare o reimplementare le risposte degli altri o copiare la mia implementazione", ma sul tuo codice è un po' discutibile. E va anche contro la regola 9: "La tua funzione sarà nominata f".
Ismael Miguel,

@IsmaelMiguel Oops. La regola 7 può essere facilmente risolta spostando la costante all'interno della funzione. Lo stavo tirando fuori dalla funzione per un migliore stile di programmazione. La regola 9 è anche una soluzione semplice. Confesso di non aver letto la tua risposta, quindi non ho tentato intenzionalmente di copiarla. Posso rimuovere la mia risposta se pensi che sia troppo vicino per il concorso.
Brian J,

La tua risposta è a posto Hai un bug sul tuo codice. Sull'ultima costante ( ([W-Zw-z)]) dovrebbe essere ([W-Zw-z]). E su Code-golf non devi preoccuparti degli stili di programmazione e delle buone pratiche: il tuo codice deve semplicemente fare la cosa con i parametri richiesti. Se controlli la mia risposta, si vedrà questa linea: $s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];. Questo è un terribile "crimine" in PHP. Fondamentalmente sto forzando PHP a convertire costanti inesistenti in stringhe. Questo è perfettamente accettabile. Vedrai anche che non sto nemmeno impostando la variabile $tsu un array prima di usarla come tale
Ismael Miguel,

@IsmaelMiguel Buona cattura dell'errore regex. Grazie per segnalarlo. Proverò a golf davvero domani; forse trovare alcuni esempi Java su questo sito.
Brian J,

Non sono un programmatore Java, ma ti dico alcune cose. È possibile controllare codegolf.stackexchange.com/questions/6671/… per ottenere alcuni suggerimenti. I suggerimenti generali includono la rimozione di spazi bianchi inutili (newline, spazi, tab), nomi di variabili di una lettera e fanno tutto il possibile per ridurre il più possibile le dimensioni del codice.
Ismael Miguel,

1

C # .NET 4.5 235

Questo dovrebbe funzionare:

IEnumerable<string>F(string n,string d){IEnumerable<string>w=d.Split(null).ToList();string[]a={"","","abc","def","ghi", "jkl","mno","pqrs","tuv","wxyz"};foreach(var i in n){w=w.Where(x=>x.IndexOfAny(a[i-'0'].ToArray())>0);}return w;}

Benvenuti in PPCG. Il codice funzionerà, ma è comunque necessario ridurlo molto di più. Rimuovendo tutti gli spazi bianchi inutili (spazi, tabulazioni, nuove righe) sono riuscito a ridurre il codice a 167 byte. Questo codice può essere ridotto molto di più, ne sono sicuro. Ti consiglio di leggere codegolf.stackexchange.com/questions/173/… per abbreviare ulteriormente il tuo codice. Per aiutarti un po ', l'elenco delle parole è una stringa separata da nuove righe e sembra che tu abbia già la possibilità di usarne una foreach. Se ti aspetti che sia già IEnumerable, includi il codice usato fuori
Ismael Miguel, l'

@IsmaelMiguel TY Lo guarderò. Elenco sono un IEnumerable non c'è codice al di fuori di quello che ho pubblicato.
Chaossie,

Se osservi le specifiche della funzione, vedrai che il secondo parametro è anche una stringa. (Citando: "Riceverai 1 numero di telefono in una stringa e il contenuto di un file di testo con un elenco di parole (non assumere uno stile newline specifico).") E hai 1 spazio bianco inutile sul tuo avar.
Ismael Miguel,

Ho notato i miglioramenti sulla tua domanda e ti ho dato un voto positivo. Ma puoi ancora salvare un byte sul tuo avar. Ma vedo davvero notevoli miglioramenti! Continua così.
Ismael Miguel,

1

Python 2 (155 byte)

Dovrebbe funzionare anche in Python 3 con le sostituzioni appropriate ( string-> bytes, bprefisso sulle stringhe, ecc.).

Non ero sicuro che avere la maketranschiamata al di fuori della funzione fosse considerata "corretta"; in caso contrario, la funzione è di 134 byte con lo spostamento all'interno.

EDIT: abbandonato un byte da una stupida svista.

Con maketrans67 byte preparati :

from string import maketrans
t=maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')

def f(n,w):
    return[x for x in w.split()if x.lower().translate(t).startswith(n)]

Con maketransnel corpo, 134 byte:

from string import maketrans

def f(n,w):
    return[x for x in w.split()if x.lower().translate(maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')).startswith(n)]

Con importe maketransnel corpo, 155 byte:

def f(n,w):
    return[x for x in w.split()if x.lower().translate(__import__('string').maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')).startswith(n)]

Chiamata di prova:

print f('9999',open('words.txt','rt').read())

Fa maketransparte del corpo della funzione. Dovresti spostarlo. Non so se sia nemmeno possibile, ma puoi provare a usare direttamente il import. Penso di averlo visto da qualche parte ... Ma il tuo codice è davvero carino!
Ismael Miguel,

Intendi spostare l'importazione e chiamare nel corpo? Sì, penso che si possa fare anche questo.
criptych sta con Monica l'

Ci stavo pensando t=(from stirng import maketrans)([...]). Non ho idea se sia possibile. Ma forse puoi usare il from string import as x t=x([...])che non sono sicuro che sia possibile anche: /
Ismael Miguel l'

La versione corretta è l'ultima. Ma la risposta così com'è è accettabile secondo me. +1 per __import__('string').maketran.
Ismael Miguel,

Ok grazie. Ho rimosso le risposte non valide.
criptych sta con Monica l'

0

PHP 5.4+ (171 186-20% = 148,8 byte):

Bene, questa è una risposta abbastanza grande, ma bene.

Spero che questo porti più persone a rispondere.

Questa funzione si aspetta che il grezzo contenuto in fase di lettura.

Ecco il codice:

function f($_,$a){$s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];$a=preg_split('@\r\n|\r|\n@',$a);for($i=0;$c=$_[$i];++$i)foreach($a as$k=>$v)if(!strpos(1..$s[$c],$v[$i])||$t[$v[0]]++>4)unset($a[$k]);return$a;}

Funziona verificando che la lettera sia nell'elenco delle lettere consentite.

Esempio: l'input 36farebbe verificare se 1abcha la prima lettera della parola e quella 1defdella seconda lettera.

Aggiungo 1quindi non controlla se la lettera è in prima posizione (che ritornerebbe 0e che valuterebbe false). if(!strpos(1..$s[$c],$v[$i]))o if(!strpos($c.$s[$c],$v[$i]))avrà lo stesso effetto, ma il 1 confonde di più e mi piace.

In caso contrario, rimuoverà la parola.

Senza parole, restituisce un array vuoto.

Per testarlo online, vai su http://writecodeonline.com/php/ e crea una semplice variabile con una parola per riga.

Un esempio verificabile:

function f($_,$a)
{
    $s=array(2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz);
    $a=preg_split('@\r\n|\r|\n@',$a);

    for($i=0;$c=$_[$i];++$i)
        foreach($a as$k=>$v)
            if(!strpos(1..$s[$c],$v[$i]) || $t[$v[0]]++>4)
                unset($a[$k]);
    return$a;
}

$lines=<<<WORDS
one
two
three
four
five
six
seven
eight
nine
ten
WORDS;

var_dump(f('36',$lines));

Questo dovrebbe produrre:

array(1) {
    [3]=>
      string(4) "four"
}

Per lavorare su versioni php precedenti, sostituisci $s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];con$s=array(2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz);


Per il bonus del 20%:

Per ridurre il codice ho semplicemente aggiunto ||$t[$v[0]]++>4, che controlla quante volte è stata utilizzata la prima lettera.

In php, $tnon è necessario definirlo, contribuendo a ridurre un grosso blocco di 37,2 byte.

Per vedere questo effetto, usa la seguente variabile come secondo argomento:

$lines=<<<WORDS
one
two
three
four
five
six
seven
eight
nine
ten
twelve
time
tutor
test
truth
WORDS;
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.