Erstellen Sie einen Tippgeschwindigkeitstest / CPM-Messung

11

Die Regeln

Es ist Zeit, einen Tippgeschwindigkeitstest in der Sprache Ihrer Wahl zu erstellen!

1 . Sie stellen einer Datei ein Wörterbuch Ihrer Wahl zur Verfügung (jedes 'Wort' muss durch Zeilenumbrüche getrennt sein). Pipe es in via stdinoder gib seinen Namen als Kommandozeilenargument an.

ein
fähig
Über
über
Abwesenheit
...

2 . Wählen Sie 10 zufällige Wörter aus der Datei aus (es dürfen keine Duplikate zulässig sein) und drucken Sie sie folgendermaßen aus:

-> direkt
-> Boden
-> weiter
-> fünf
...

3 . Messen Sie ab sofort die aufgewendete Zeit!

4 . Lassen Sie den Benutzer alle zehn Wörter so schnell wie möglich eingeben (endete mit einem Wagenrücklauf). Drucken OKSie, wenn Sie eine Übereinstimmung haben, drucken Sie, WRONGwenn ein Tippfehler vorliegt (oder das Wort wurde in diesem Lauf bereits erfolgreich eingegeben).

5 . Stoppen Sie die Uhren! Drucken Sie nun den CPM- Benchmark (Zeichen pro Minute) aus, der wie folgt berechnet wird : (sum of the characters of the chosen words / time spent typing (seconds)) * 60. Runden Sie auf die nächste Ganzzahl und reproduzieren Sie die folgende (Beispiel-) Ausgabe:

-> Sie haben 344 CPM erzielt!

Ein Probelauf

-> erledigen
-> Seite
-> öffnen
-> Minister
-> Risiko
-> Farbe
-> Schiff
-> gleich
-> Größe
-> Schwert
sich niederlassen
in Ordnung
Seite
in Ordnung
öffnen
in Ordnung
# ...................... einige Zeilen wurden abgeschnitten ......................
Wort
FALSCH
Schwert
in Ordnung
-> Sie haben 298 CPM erzielt!

Der Gewinner

Dies ist Code Colf, der kürzeste Eintrag (in der Anzahl der Quellcode-Zeichen) gewinnt, viel Spaß!

ChristopheD
quelle
4
Ich denke, der Gewinner sollte teilweise von der Person mit dem höchsten CPM erzielt werden;)
mellamokb
Wie genau müssen wir die Zeit messen? Ist eine Auflösung von einer Sekunde in Ordnung?
Ilmari Karonen
@Ilmari Karonen: Eine Auflösung von einer Sekunde wäre für diesen speziellen Wettbewerb in Ordnung.
ChristopheD

Antworten:

5

K, 146

Nimmt eine Wörterbuchdatei mit dem Namen 'd' im aktuellen Arbeitsverzeichnis an.

{b:+/#:'a:10?_0:`:d;-1"-> ",/:a;s:.z.t;while[#a;$[(,/0:0)~*a;[a:1_a;-1"OK"];-1"WRONG"]];-1"--> You have scored ",($(60000*b)%"i"$.z.t-s)," CPM!";}
tmartin
quelle
Sehr schön und kurz, erster Eintrag in KIch habe gesehen (hier auf codegolf.se) ...
ChristopheD
Vielen Dank, alle meine Antworten hier sind in Q oder (zunehmend) in K.
tmartin
Ich verstehe nicht ganz, warum dies nur eine einzige Gegenstimme bekam (meine)!
ChristopheD
11

Bash - 217 212 199 196 Zeichen

Ich werde nicht gewinnen, aber es hat Spaß gemacht

declare -A W
for w in `shuf -n10`;do C+=$w;echo -\> $w;W[$w]=OK;done
SECONDS=0
for((;${#W[*]};));do read r;echo ${W[$r]-WRONG};unset W[$r];done
echo --\> You have scored $((60*${#C}/SECONDS)) CPM!

Jetzt unter 200 Zeichen!

Nimmt die Wortlistendatei als Argument. Nimmt jetzt die Wortliste für die Standardeingabe. Fügen Sie es in das Terminal ein und drücken Sie ^ D.

Vorschlag von Manatwork implementiert

Geoff Reedy
quelle
1
Ich werde nicht gewinnen, aber es hat Spaß gemacht - ich denke das gleiche, wenn ich meine C # -Lösungen
poste
1
Sie können die $SECONDSShell-Variable verwenden, um die Berechnung der verstrichenen Zeit zu vereinfachen.
Manatwork
Sie können 2 weitere Zeichen entfernen: 1) die :in der Standardwertparametererweiterung; 2) die $vor SECONDSin der arithmetischen Auswertung. Tatsächlich gibt es ein weiteres zusätzliches Zeichen, den Zeilenumbruch am und der Datei.
Manatwork
4

Ruby (189 178 171 168)

$><<t=['',d=[*$<.lines].sample(10)]*'-> '
s=Time.now
puts d.delete($stdin.gets)?:OK:'WRONG'while d[0]
puts'--> You have scored %i CPM!'%((t.size-40)/(Time.now-s)*60)

Ziemlich einfach, ich bin sicher, dass Verbesserungen vorgenommen werden müssen. Nimmt den Dateinamen des Wörterbuchs als Befehlszeilenargument.

BEARBEITEN : Ein paar kleinere Änderungen, hauptsächlich um die Zeilenumbrüche aus dem Wörterbuch beizubehalten. Infolgedessen benötigt die Datei einen nachgestellten Zeilenumbruch, um ordnungsgemäß zu funktionieren.

Paul Prestidge
quelle
4

C 305 309 347 Zeichen

char*stdin,w[11][99];long i,t;main(int n,char**v){v=fopen(v[1],"r");
for(srand(time(&t));fgets(w[i++>9?(n=rand()%i)>10?0:n:i],99,v););
for(i=n=0;i<10;n+=printf("-> %s",w[++i])-4);
for(;i;puts(!strcmp(*w,w[11-i])?--i,"OK":"WRONG"))fgets(*w,99,stdin);
printf("--> You have scored %ld CPM!\n",n*60/(time(0)-t));}

Vielen Dank an @ugoren für die Verbesserungshinweise. Die Verwendung eines "11. Wortes" zum Verwerfen eingehender Wörterbucheinträge war ein großer Gewinn gegenüber meinem vorherigen strcpy-if-selected-Ansatz.

Hier ist die Quelle ohne Wolf:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

static char words[11][99];
static long i, t;

int main(int argc, char *argv[])
{
    FILE *fp;
    int n;

    fp = fopen(argv[1], "r");
    srand(time(0));
    for (i = 0 ; fgets(words[0], sizeof words[0], fp) ; ++i) {
        n = i < 10 ? i : rand() % i;
        if (n < 10)
            strcpy(words[n + 1], words[0]);
    }
    fclose(fp);

    n = 0;
    for (i = 1 ; i <= 10 ; ++i)
        n += printf("-> %s", words[i]) - 4;
    t = time(0);
    i = 1;
    while (i <= 10 && fgets(words[0], sizeof words[0], stdin)) {
        if (strcmp(words[0], words[i])) {
            puts("WRONG");
        } else {
            puts("OK");
            ++i;
        }
    }
    if (i > 9)
        printf("-> You have scored %ld CPM!\n", n * 60 / (time(0) - t));

    return argc - argc;
}
Brot-Box
quelle
Einige Verbesserungen: 1. K & R-Erklärung : main(n,v)char**v;{.... 2. stdinkann sein char *. fgets(buf,len,stdin)= gets(buf)(egal die Pufferüberläufe). 3. Was ist los mit rand()%i? RAND_MAXwird nicht benötigt. 4. Warum long?
Ugoren
1
Auch: 1) t=time(0)-> time(&t). 2) n*60/(time(0)-t)hat Klammern, die gehen müssen - *60kann dann verschoben n+=60*printfwerden n/=time(0)-t. 3) Durch bein zusätzliches Element wersetzen, durch strcpydirekt einlesen ersetzen w.
Ugoren
Das Ersetzen fgets()durch gets()erfordert zusätzlichen Code, um die Zeilenumbrüche im Wörterbuch zu verarbeiten. diese endete kürzer. rand()%iist nicht ausreichend; Die eigentliche Berechnung ist (double)i*rand()/RAND_MAX. Wenn Sie das *60zum printf verschieben, müssen Sie auch das -4to ändern , -240damit letztendlich ein Verlust entsteht. Ihre anderen Punkte sind jedoch gültig (glaube ich). Oh, und das longliegt daran, dass time_t traditionell lang ist. Nur weil wir Golf spielen, heißt das nicht, dass wir nicht tragbar sein können.
Brotkasten
Ich habe vermisst 4-> 240... Portabilität und Golf passen nicht gut zusammen. Das Definieren i,t;(implizit int) ist jedoch bis zu MAX_INTSekunden in Ordnung (wenn Sie es nicht verwenden time(&t)). Mit rand(), alles was Sie brauchen eine 10/iChance, und rand()%i<10es tut.
Ugoren
Ihre zufällige Auswahl ist etwas fehlerhaft (nicht, dass absolute Fairness erforderlich ist). Die 11. Zeile sollte eine 10/11-Chance haben, ausgewählt zu werden, aber Sie tun dies rand()%10>10, was 100% ergibt. rand()%(i+1)>9ist besser (aber stattdessen, wenn %(i+1)ja i++>9?. Bewegen Sie *stdinsich auch als Erster und sparen Sie Platz.
ugoren
2

C # 401

void T(){
Action<string>C=Console.WriteLine;Func<string>R=Console.ReadLine;
var w=new List<string>();
for(var l=R();l!="";l=R())w.Add(l);
var s=w.OrderBy(_=>Guid.NewGuid()).Take(10).ToList();
s.ForEach(x=>C("=> "+x));
var t=s.Select(x=>x.Length).Sum();
var c=Stopwatch.StartNew();
while(s.Any()){C(s.Remove(R())?"OK":"WRONG");}
c.Stop();
C("--> You have scored "+c.Elapsed.TotalSeconds*60/t+" CPM!");}

Laufende Version hier: http://ideone.com/Nt6Id

Cristian Lupascu
quelle
2

Python ( 256 235)

import time as t,random as r
def p(x):print x
c=r.sample(input().split("\n"),10)
z=lambda x:p(("WRONG","OK")[raw_input()==x])or len(x)
p("--> "+"\n--> ".join(c))
_=t.time()
p("--> You have scored %d CPM!"%(sum(map(z,c))/(t.time()-_)*60))

Dies ist in Python 2.x, in 3.x kann ich 4 weitere Zeichen mit der Druckfunktion rasieren.

Zeilenumbrüche enthalten

Joel Cornett
quelle
2
"Frage: Zählen Zeilenumbrüche?" Wir gehen normalerweise nach "notwendigen Zeichen". Im Fall von Python müssen die Zeilenumbrüche gezählt werden, da das Programm durch Entfernen entfernt wird.
Joey Adams
1
Ich denke , man kann sich ändern z=lambda x:zu def z(x):.
Joey Adams
@ JoeyAdams: Ich könnte, wenn ich nur keine zurückgeben müsste, aber ich muss zurückkehren len(x)und def z(x):returnist 5 weitere Charaktere: /
Joel Cornett
Ich denke, Sie können einige Charaktere gewinnen, indem Sie die Eingabe (in der Frage erlaubt) input()sys.argv[1].read()
ChristopheD
@ JoelCornett: Hoppla, du hast recht.
Joey Adams
2

PHP 187 Bytes

Aus Gründen der Übersichtlichkeit wurden neue Zeilen hinzugefügt:

<?$s=file($argv[1]);
for(shuffle($s);$i++<10;$l+=strlen($$i))echo~ÒÁß,$$i=$s[$i];
for($t=time();$j++<10;)echo$$j==fgets(STDIN)?OK:WRONG,~õ?>
--> You have scored <?=0|$l/(time()-$t)*60?> CPM!

Akzeptiert den Dateinamen des Wörterbuchs als Befehlszeilenargument. Die Wörterbuchdatei muss mit einem Zeilenumbruch enden.

primo
quelle
2

Scala ( 319 306 304 302)

var s=util.Random.shuffle(io.Source.fromFile(args(0)).getLines.toSet)take 10
def?(a:Any)=println(a)
var l=(0/:s){_+_.size}
s map{"-> "+_}map?
def n=System.nanoTime
val t=n
while(s.size!=0){val m=readLine
if(s contains m)?("OK")else?("WRONG");s-=m}
?("--> You have scored "+l*60000000000L/(n-t)+" CPM!")
Prinz John Wesley
quelle