Implementieren Sie t9-ähnliche Funktionen


10

Ihre heutige Herausforderung besteht darin, eine t9- ähnliche Funktionalität zu implementieren .

Sie implementieren eine Funktion, die nur 2 Parameter hat.
Sie erhalten 1 Telefonnummer in einer Zeichenfolge und den Inhalt einer Textdatei mit einer Liste von Wörtern (nehmen Sie keinen bestimmten Zeilenumbruchstil an).
Sie können den Link https://raw.githubusercontent.com/eneko/data-repository/master/data/words.txt verwenden , um die Funktionalität zu testen, oder verwenden Sie /usr/share/dict/words(überprüfen Sie eine Textdatei mit einer Liste von Wörtern [geschlossen] für weitere Informationen Information).

Sie können davon ausgehen, dass Sie immer mindestens 2 Nummern erhalten.

Wenn Sie die Anzahl angeben, lesen Sie aus einer Liste von Wörtern und geben die Wörter zurück, beginnend mit den Buchstaben, die diesen Wörtern zugeordnet sind. Dies bedeutet, dass die Eingabe nur Zahlen von 2 bis 9 sein sollte.
Sie können tun, was Sie wollen, wenn Sie eine ungültige Eingabe erhalten.

Wenn keine Übereinstimmung gefunden wird, können Sie eine leere Liste zurückgeben, null/ niloder 0.

Denken Sie daran, dass die Handytasten den entsprechenden Zeichen zugeordnet sind:

  • 0 und 1 sind ungültig
  • 2 Treffer [abc]
  • 3 übereinstimmend [def]
  • 4 Spiele [ghi]
  • 5 Treffer [jkl]
  • 6 Treffer [mno]
  • 7 Treffer [pqrs]
  • 8 Spiele [tuv]
  • und 9 Übereinstimmungen [wxyz]

Beispiele:

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

Nachdem Sie Ihre Funktion ausgeführt haben, können Sie sie nach Belieben drucken.

Regeln:

  • Standardlücken sind UNGÜLTIG
  • Sie müssen etwas zurückgeben, auch wenn es null/ nil
    Javascript zurückgibt, undefinedwenn Sie etwas nicht zurückgeben, daher diese Regel.
  • Sie können die Antworten anderer nicht verwenden oder erneut implementieren oder meine Implementierung kopieren.
  • Sie können für Javascript davon ausgehen, dass der Browser bereits geöffnet ist und das innerText/ textContentdes automatischen Elements als 2. Parameter übergeben wird
  • Für kompilierte Sprachen können Sie keine speziellen Argumente an den Compiler übergeben
  • Sie können den Dateinamen über Compiler-Argumente erhalten
  • Variablen, Makros, globale Variablen, Konstanten, nicht standardmäßige Klassen und alle Sortierungen, die andere Werte innerhalb der Funktion übergeben, werden als ungültig betrachtet.
  • In Javascript machen Variablen ohne das Schlüsselwort varIhren Code ungültig
  • Ihre Funktion wird benannt f
  • Sie können nur und nur 2 Argumente für Ihre Funktion haben
  • Versuchen Sie, Ihren Code für die Ausführung unter 500 Sekunden zu halten.
  • Sie müssen sich keine Gedanken über Leerzeichen machen
  • Sie dürfen nur ASCII- druckbare Zeichen verwenden.
    Ausnahmen sind Sprachen, die nur nicht druckbare Zeichen verwenden (APL und Leerzeichen sind zwei Beispiele).

Wertung:

  • Die niedrigste Anzahl von Bytes gewinnt
  • Wenn Ihre Antwort ungültige ASCII- druckbare Zeichen enthält, gilt dies als die Antwort, die in UTF-32
    codiert wird. Die Ausnahme von der Codierung führt dazu, dass Ihre Antwort nach Zeichen gezählt wird .
  • Nur der Funktionskörper zählt, nichts anderes, was Sie außerhalb tun
  • Bonus von -30%, wenn Sie ein Vorhersagesystem erstellen, das auf der Nachbarschaft oder den häufigsten Wörtern basiert
  • Ein Bonus von -20%, wenn Sie nur die ersten 5 Übereinstimmungen für jeden Buchstaben zurückgeben, der der ersten Zahl entspricht (z. B.: 245 würde 5 Wörter zurückgeben, die mit 'a' beginnen, 5, die mit 'b' beginnen, und 5, die mit 'c beginnen'). ).

Hier ist ein Beispiel für eine Implementierung mit 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);
}

Öffnen Sie zum Ausführen den Listenlink und führen Sie beispielsweise Folgendes aus:

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

Dieses Beispiel wurde getestet und funktioniert unter Opera 12.17 64-Bit unter Windows 7 Home Edition 64-Bit.


Ist das zweite Argument für das Programm ein Dateiname, der die Wörter oder die Liste der Wörter selbst enthält?
Optimierer

@ MartinBüttner UTF-8 ist nicht unfair (es zählt immer noch ASCII-Zeichen als 1 Byte), aber ich habe die Regel geändert.
Ismael Miguel

@Optimizer Das 2. Argument ist eine Liste der Wörter. Sie können den Dateinamen über ein Compiler-Argument übergeben und die Datei lesen, wenn Sie möchten. Aber das einzige, was zählt, ist der Funktionskörper.
Ismael Miguel

@ MartinBüttner Beim Zählen als ASCII wird es als Byte gezählt. Sie möchten, dass ich sage, dass der APL-Code 1 Byte mit einer Größe von 8 Bit hat?
Ismael Miguel

2
-1 für unangemessene Einschränkungen
AJMansfield

Antworten:


3

CJam, 28 Bytes

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

Nimmt Eingaben in Form von "<number>" [<list of words>]

Beispiel:

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

Ausgabe:

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

Ich werde vorerst keinen Bonus bekommen.

Probieren Sie den Code hier online aus, aber führen Sie ihn für tatsächliche Zeitmessungen auf dem Java-Compiler aus

Beachten Sie, dass CJam leere Listen wie darstellt ""

Verwenden Sie zum Konvertieren der Rohwortliste in eine CJam-Liste den folgenden Code mit der Wortliste als Eingabe:

qN/p

"Sie erhalten 1 Telefonnummer in einer Zeichenfolge und den Inhalt einer Textdatei mit einer Liste von Wörtern." -> Können Sie in einem anderen Block den erforderlichen Code implementieren, um die Datei in eine verwendbare Liste einzulesen?
Ismael Miguel

@IsmaelMiguel Du meinst nicht den Teil dieses Codes, sondern nur einen Hilfecode, um die Liste in das richtige Format zu konvertieren?
Optimierer

Genau. Was Ihr Code nicht ausreicht, um zu beweisen, dass er eine Liste von Wörtern als Beispiele verwenden kann. Aber ich habe trotzdem gestimmt, ich wollte nur diesen Hilfecode.
Ismael Miguel

Können Sie es der Antwort hinzufügen? Als Bearbeitung in einem anderen Teil
Ismael Miguel

Genau. Davon spreche ich! Mal sehen, ob Sie es noch weiter optimieren können
Ismael Miguel

2

Java: 395

Dies bildet ein Regex-Muster basierend auf den Buchstaben, die für jede Zahl zulässig sind, und setzt dann am Ende ein. * An, um mit den folgenden Zeichen übereinzustimmen.

Hier ist die Golfversion:

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;}

Und hier ist die ungolfed Version für die Lesbarkeit

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;
}

Ihr Code verstößt gegen Regel Nummer 7: "Variablen, Makros, globale Variablen, Konstanten, nicht standardmäßige Klassen und alle Sortierungen, die andere Werte innerhalb der Funktion übergeben, werden als ungültig betrachtet." und es verstößt irgendwie gegen Regel Nummer 3: "Sie können die Antworten anderer nicht verwenden oder erneut implementieren oder meine Implementierung kopieren.", aber auf Ihrem Code ist es irgendwie umstritten. Und es verstößt auch gegen die Regel 9: "Ihre Funktion wird benannt f".
Ismael Miguel

@IsmaelMiguel Ups. Regel 7 kann einfach durch Verschieben der Konstanten innerhalb der Funktion festgelegt werden. Ich habe es nur außerhalb der Funktion gezogen, um einen besseren Programmierstil zu erzielen. Regel 9 ist auch eine einfache Lösung. Ich gebe zu, dass ich Ihre Antwort nicht gelesen habe, also habe ich nicht absichtlich versucht, sie zu kopieren. Ich kann meine Antwort entfernen, wenn Sie denken, dass sie für den Wettbewerb zu nah ist.
Brian J

Ihre Antwort ist in Ordnung. Sie haben einen Fehler in Ihrem Code. Bei der letzten Konstante ( ([W-Zw-z)]) sollte es sein ([W-Zw-z]). Und beim Code-Golf müssen Sie sich keine Gedanken über Programmierstile und bewährte Methoden machen: Ihr Code muss einfach mit den erforderlichen Parametern arbeiten. Wenn Sie meine Antwort überprüfen, sehen Sie diese Zeile : $s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];. Dies ist ein schreckliches "Verbrechen" in PHP. Grundsätzlich zwinge ich PHP, nicht vorhandene Konstanten in Strings umzuwandeln. Das ist durchaus akzeptabel. Sie werden auch sehen, dass ich die Variable nicht einmal $tauf ein Array setze, bevor ich sie als solche verwende
Ismael Miguel

@IsmaelMiguel Guter Fang für den Regex-Fehler. Vielen Dank für den Hinweis. Ich werde versuchen, es morgen tatsächlich zu spielen. Vielleicht finden Sie einige Java-Beispiele auf dieser Site.
Brian J

Ich bin kein Java-Programmierer, aber ich erzähle Ihnen einige Dinge. Sie können codegolf.stackexchange.com/questions/6671/… überprüfen , um einige Tipps zu erhalten. Zu den allgemeinen Tipps gehören das Entfernen unbrauchbarer Leerzeichen (Zeilenumbrüche, Leerzeichen, Tabulatoren), ein Buchstaben lange Variablennamen und alles, um die Codegröße so weit wie möglich zu reduzieren.
Ismael Miguel

1

C # .NET 4.5 235

Das sollte funktionieren:

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;}

Willkommen bei PPCG. Ihr Code wird funktionieren, aber Sie müssen ihn noch viel weiter reduzieren. Durch Entfernen aller nutzlosen Leerzeichen (Leerzeichen, Tabulatoren, Zeilenumbrüche) konnte ich Ihren Code auf 167 Byte reduzieren. Dieser Code kann viel weiter reduziert werden, da bin ich mir sicher. Ich empfehle, codegolf.stackexchange.com/questions/173/… zu lesen , um Ihren Code noch weiter zu verkürzen. Um Ihnen ein wenig zu helfen, ist die Wortliste eine durch Zeilenumbrüche getrennte Zeichenfolge, und Sie scheinen anzunehmen, dass es bereits möglich ist, eine foreachdarin zu verwenden. Wenn Sie erwarten, dass dies bereits der Fall ist IEnumerable, geben Sie den außerhalb verwendeten Code an
Ismael Miguel

@IsmaelMiguel TY Ich werde es mir ansehen. Liste sind IEnumerable Es gibt keinen Code außerhalb dessen, was ich gepostet habe.
Chaossie

Wenn Sie sich die Spezifikation der Funktion ansehen, sehen Sie, dass der 2. Parameter ebenfalls eine Zeichenfolge ist. (Zitat: "Sie erhalten 1 Telefonnummer in einer Zeichenfolge und den Inhalt einer Textdatei mit einer Liste von Wörtern (nehmen Sie keinen bestimmten Zeilenumbruchstil an).") Und Sie haben 1 nutzloses Leerzeichen auf Ihrer Variable a.
Ismael Miguel

Ich habe die Verbesserungen bei Ihrer Frage bemerkt und Ihnen eine positive Bewertung gegeben. Sie können jedoch trotzdem ein Byte auf Ihrem avar speichern . Aber ich sehe wirklich spürbare Verbesserungen! Mach weiter so.
Ismael Miguel

1

Python 2 (155 Bytes)

Sollte auch in Python 3 mit den entsprechenden Ersetzungen funktionieren ( string-> bytes, bPräfix auf Zeichenfolgen usw.).

Ich war mir nicht sicher, ob der maketransAnruf außerhalb der Funktion als "fair" angesehen wird. Wenn nicht, beträgt die Funktion 134 Bytes, wobei sie nach innen verschoben wird.

EDIT: Ein Byte aus einem dummen Versehen gelöscht.

Mit vorbereiteten maketrans67 Bytes:

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)]

Mit maketransim Körper 134 Bytes:

from string import maketrans

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

Mit importund maketransim Körper, 155 Bytes:

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

Testanruf:

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

Das maketransist Teil des Funktionskörpers. Du solltest es bewegen. Ich weiß nicht, ob es überhaupt möglich ist, aber Sie können versuchen, das direkt zu verwenden import. Ich glaube, ich habe es irgendwo gesehen ... Aber dein Code ist wirklich nett!
Ismael Miguel

Wollen Sie den Import verschieben und in den Body aufrufen? Ja, ich denke, das ist auch möglich.
Criptych steht mit Monica

Ich habe darüber nachgedacht t=(from stirng import maketrans)([...]). Ich habe keine Ahnung, ob es überhaupt möglich ist. Aber vielleicht können Sie verwenden, from string import as x t=x([...])was ich nicht sicher bin, ob es auch möglich ist: /
Ismael Miguel

Die richtige Version ist die letzte. Aber die Antwort ist meiner Meinung nach akzeptabel. +1 für __import__('string').maketran.
Ismael Miguel

OK danke. Ich habe die ungültigen Antworten entfernt.
Criptych steht mit Monica

0

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

Nun, das ist eine ziemlich große Antwort, aber gut.

Ich hoffe, das bringt mehr Leute zur Antwort.

Diese Funktion erwartet, dass der Rohinhalt gelesen wird.

Hier ist der Code:

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;}

Dies funktioniert, indem überprüft wird, ob der Buchstabe in der Liste der zulässigen Buchstaben enthalten ist.

Beispiel: Die Eingabe 36würde prüfen, ob 1abcder erste Buchstabe des Wortes und 1defder zweite Buchstabe vorhanden sind.

Ich füge hinzu, 1damit nicht überprüft wird, ob sich der Buchstabe an der 1. Position befindet (was zurückkehren würde 0und was dazu führen würde false). if(!strpos(1..$s[$c],$v[$i]))oder if(!strpos($c.$s[$c],$v[$i]))wird den gleichen Effekt haben, aber der 1. verwirrt mehr und ich mag es.

Andernfalls wird das Wort entfernt.

Ohne verbleibende Wörter wird ein leeres Array zurückgegeben.

Um dies online zu testen, gehen Sie zu http://writecodeonline.com/php/ und erstellen Sie eine einfache Variable mit einem Wort für Zeile.

Ein überprüfbares Beispiel:

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));

Dies sollte Folgendes ausgeben:

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

Um an älteren PHP-Versionen zu arbeiten, ersetzen Sie $s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];durch$s=array(2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz);


Für den 20% Bonus:

Um den Code zu reduzieren, habe ich einfach hinzugefügt ||$t[$v[0]]++>4, wodurch überprüft wird, wie oft der erste Buchstabe verwendet wurde.

In PHP $tmuss nicht definiert werden, was dazu beiträgt, einen großen Teil von 37,2 Bytes zu reduzieren .

Verwenden Sie die folgende Variable als zweites Argument, um diesen Effekt zu sehen:

$lines=<<<WORDS
one
two
three
four
five
six
seven
eight
nine
ten
twelve
time
tutor
test
truth
WORDS;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.