Costruire un test di velocità di battitura / misurazione del CPM


11

Le regole

È tempo di costruire un test di velocità di battitura nella tua lingua preferita!

1 . Fornisci un file con un dizionario a scelta (ogni 'parola' al suo interno deve essere delimitata da nuova riga). Inseriscilo via stdino fornisci il nome come argomento della riga di comando.

un'
capace
di
sopra
assenza
...

2 . Scegli 10 parole casuali dal file (non devono essere consentiti duplicati) e stampale nel modo seguente:

-> diretto
-> terra
-> successivo
-> cinque
...

3 . Inizia a misurare il tempo trascorso da ora in poi!

4 . Consenti all'utente di digitare tutte e dieci le parole il più velocemente possibile (terminato con un ritorno a capo). Stampa OKquando hai una corrispondenza, stampa WRONGquando si verifica un errore di battitura (o la parola è già stata digitata correttamente in questa corsa).

5 . Ferma gli orologi! Ora stampare il CPM (lettere accentate al minuto) di riferimento, che è calcolato come segue: (sum of the characters of the chosen words / time spent typing (seconds)) * 60. Arrotondare al numero intero più vicino e riprodurre il seguente output (campione):

-> Hai totalizzato 344 CPM!

Una corsa di esempio

-> sistemati
-> lato
-> aperto
-> ministro
-> rischio
-> colore
-> nave
-> stesso
-> dimensioni
-> spada
Risolvere
ok
lato
ok
Aperto
ok
# ...................... alcune linee tratteggiate ......................
parola
SBAGLIATO
spada
ok
-> Hai totalizzato 298 CPM!

Il vincitore

Questo è code colf, la voce più breve (nel conteggio dei caratteri del codice sorgente) vince, buon divertimento!


4
Penso che il vincitore dovrebbe essere in parte segnato dalla persona con il CPM più alto;)
mellamokb

Con quale precisione dobbiamo misurare il tempo? La risoluzione di un secondo è OK?
Ilmari Karonen,

@Ilmari Karonen: una risoluzione di un secondo andrebbe bene per questo specifico concorso.
ChristopheD,

Risposte:


5

K, 146

Presuppone un file di dizionario chiamato 'd' nella directory di lavoro corrente.

{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!";}

Molto bello e breve, la prima voce Kche ho visto (qui su codegolf.se) ...
ChristopheD,

Grazie, tutte le mie risposte qui sono in Q o (sempre più) in K.
tmartin

Non capisco perché abbia ottenuto un solo voto (il mio)!
ChristopheD,

11

Bash - 217 212 199 196 caratteri

Non vincerò ma è stato divertente

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!

Meno di 200 caratteri ora!

Prende il file dell'elenco di parole come argomento. Ora accetta l'elenco di parole sull'input standard. Incollalo nel terminale e premi ^ D

Suggerimento implementato da manatwork


1
Non vincerò ma è stato divertente - penso lo stesso quando invio le mie soluzioni C # :)
Cristian Lupascu,

1
È possibile utilizzare la $SECONDSvariabile shell per semplificare il calcolo del tempo trascorso.
arte

Puoi rimuovere altri 2 caratteri: 1) :nell'espansione del parametro valore predefinito; 2) $di fronte SECONDSalla valutazione aritmetica. In realtà c'è un altro personaggio in più, la nuova riga in corrispondenza del file.
arte

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)

Abbastanza semplice, sono sicuro che ci sono miglioramenti da apportare. Prende il nome file del dizionario come argomento della riga di comando.

EDIT : alcune piccole modifiche, principalmente attorno a mantenere le nuove righe dal dizionario. Di conseguenza, il file avrà bisogno di una nuova riga finale per funzionare correttamente.


4

C, 305 309 347 caratteri

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

Grazie a @ugoren per i suggerimenti di miglioramento. L'uso di una "undicesima parola" per scartare le voci del dizionario in arrivo è stata una grande vittoria rispetto al mio precedente approccio strcpy-if-scelto.

Ecco la fonte non golfata:

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

Alcuni miglioramenti: 1. K & R dichiarazione: main(n,v)char**v;{.... 2. stdinpuò essere char *. fgets(buf,len,stdin)= gets(buf)(non importa il sovraccarico del buffer). 3. Cosa c'è che non va rand()%i? RAND_MAXnon è necessario. 4. Perché long?
ugoren,

1
Inoltre: 1) t=time(0)-> time(&t). 2) n*60/(time(0)-t)ha parentesi che devono andare - *60può essere spostato n+=60*printf, quindi n/=time(0)-t. 3) Sostituire bcon un ulteriore elemento in w, sostituire strcpycon read direttamente in w.
ugoren,

Sostituzione fgets()con gets()necessità di codice aggiuntivo per gestire le nuove righe nel dizionario; questo finì per essere più breve. rand()%inon è sufficiente; il calcolo effettivo è (double)i*rand()/RAND_MAX. Spostare *60in printf significa anche cambiare -4in in -240modo che alla fine si verifichi una perdita. I tuoi altri punti sono validi, però (credo). Oh, ed longè perché time_t è tradizionalmente un lungo. Solo perché stiamo giocando a golf non significa che non possiamo essere portatili.
breadbox

Ho perso 4-> 240... Portabilità e golf non vanno bene insieme. Ma definire i,t;(implicitamente int) va bene fino a MAX_INTpochi secondi (se non lo usi time(&t)). Con rand(), tutto ciò che serve è una 10/ipossibilità, e lo rand()%i<10fa.
ugoren,

La tua selezione casuale è alquanto imperfetta (non è necessaria l'equità assoluta). L'undicesima riga dovrebbe avere una possibilità del 10/11 di essere selezionata, ma lo fai rand()%10>10, il che le dà il 100%. rand()%(i+1)>9è meglio (ma invece se %(i+1)farlo i++>9?. Anche spostarsi *stdindi essere il primo e salvare uno spazio.
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!");}

Versione corrente qui: http://ideone.com/Nt6Id


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

Questo è in Python 2.x, in 3.x Posso radere altri 4 caratteri usando la funzione di stampa.

Newline incluse


2
"Domanda: le newline contano?" Di solito andiamo dai "caratteri necessari". Nel caso di Python, sì, è necessario contare le nuove righe, poiché rimuoverle impedirà al programma di funzionare.
Joey Adams,

1
Penso che tu possa cambiare z=lambda x:in def z(x):.
Joey Adams,

@JoeyAdams: avrei potuto solo non averne restituito nessuno, ma ho bisogno di tornare len(x)e ci def z(x):returnsono altri 5 caratteri: /
Joel Cornett,

Penso che puoi vincere alcuni personaggi eseguendo il piping nell'input (consentito nella domanda) e usando input()invece disys.argv[1].read()
ChristopheD,

@JoelCornett: Whoops, hai ragione.
Joey Adams,

2

PHP 187 byte

Newline sono stati aggiunti per chiarezza:

<?$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!

Accetta il nome file del dizionario come argomento della riga di comando. Il file del dizionario deve terminare con una nuova riga.


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!")
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.