Buat CPM tes / pengukuran kecepatan mengetik

11

Aturan

Saatnya untuk membangun tes kecepatan mengetik dalam bahasa pilihan Anda!

1 . Anda menyediakan file dengan kamus pilihan (setiap 'kata' di dalamnya harus dibatasi baris baru). Pipa itu melalui stdinatau berikan namanya sebagai argumen baris perintah.

Sebuah
sanggup
tentang
atas
ketiadaan
...

2 . Pilih 10 kata acak dari file (tidak ada duplikat harus diizinkan) dan cetak dengan cara berikut:

-> langsung
-> tanah
-> selanjutnya
-> lima
...

3 . Mulailah mengukur waktu yang dihabiskan mulai sekarang!

4 . Biarkan pengguna mengetik semua dari sepuluh kata secepat mungkin (berakhir dengan carriage return). Cetak OKketika Anda memiliki kecocokan, cetak WRONGketika kami memiliki kesalahan pengetikan (atau kata itu sudah berhasil diketik dalam proses ini).

5 . Hentikan jamnya! Sekarang mencetak CPM (caracters per menit) benchmark, yang dihitung sebagai berikut: (sum of the characters of the chosen words / time spent typing (seconds)) * 60. Membulatkan ke bilangan bulat terdekat dan mereproduksi output (sampel) berikut:

-> Anda telah mencetak 344 CPM!

Contoh dijalankan

-> puas
-> samping
-> buka
-> menteri
-> risiko
-> warna
-> kapal
-> sama
-> ukuran
-> pedang
menetap
baik
sisi
baik
Buka
baik
# ...................... beberapa baris terpotong ......................
kata
SALAH
pedang
baik
-> Anda telah mencetak 298 CPM!

Pemenang

Ini adalah kode colf, entri terpendek (dalam jumlah karakter kode sumber) menang, bersenang-senang!

ChristopheD
sumber
4
Saya pikir pemenang sebagian harus dinilai oleh orang dengan CPM tertinggi;)
mellamokb
Seberapa tepatnya kita perlu mengukur waktu? Apakah resolusi satu detik tidak apa-apa?
Ilmari Karonen
@Ilmari Karonen: resolusi satu detik akan baik untuk kontes khusus ini.
ChristopheD

Jawaban:

5

K, 146

Mengasumsikan file kamus yang disebut 'd' di direktori kerja saat ini.

{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
sumber
Sangat bagus dan pendek, entri pertama yang Kpernah saya lihat (di sini di codegolf.se) ...
ChristopheD
Terima kasih, semua jawaban saya di sini ada di Q atau (semakin) di K.
tmartin
Saya tidak mengerti mengapa ini hanya mendapat satu upvote (milik saya)!
ChristopheD
11

Bash - 217 212 199 196 karakter

Tidak akan menang tapi itu menyenangkan

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!

Di bawah 200 karakter sekarang!

Mengambil file daftar kata sebagai argumen Sekarang mengambil daftar kata pada input standar. Rekatkan di terminal dan tekan ^ D

Saran yang diterapkan dari manatwork

Geoff Reedy
sumber
1
Tidak akan menang tetapi itu menyenangkan - Saya pikir hal yang sama ketika saya memposting solusi C # saya :)
Cristian Lupascu
1
Anda bisa menggunakan $SECONDSvariabel shell untuk menyederhanakan menghitung waktu yang telah berlalu.
manatwork
Anda dapat menghapus 2 karakter lagi: 1) :dalam perluasan parameter nilai default; 2) $di depan SECONDSdalam evaluasi aritmatika. Sebenarnya ada karakter tambahan lain, baris baru di dan file.
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)

Cukup mendasar, saya yakin ada perbaikan yang harus dilakukan. Mengambil nama file kamus sebagai argumen baris perintah.

EDIT : Beberapa perubahan kecil, terutama seputar mempertahankan baris baru dari kamus. Akibatnya, file tersebut akan memerlukan baris baru tambahan agar berfungsi dengan benar.

Paul Prestidge
sumber
4

C, 305 309 347 karakter

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

Terima kasih kepada @ugoren untuk petunjuk perbaikannya. Menggunakan "kata ke-11" untuk membuang entri kamus yang masuk adalah kemenangan besar atas pendekatan strcpy-jika-dipilih saya sebelumnya.

Inilah sumber yang tidak diserang:

#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;
}
kotak roti
sumber
Beberapa perbaikan: 1. K & R deklarasi: main(n,v)char**v;{.... 2. stdinbisa char *. fgets(buf,len,stdin)= gets(buf)(apalagi buffer overruns). 3. Ada apa dengan itu rand()%i? RAND_MAXtidak dibutuhkan. 4. Mengapa long?
ugoren
1
Juga: 1) t=time(0)-> time(&t). 2) n*60/(time(0)-t)memiliki tanda kurung yang harus - *60dapat dipindahkan ke n+=60*printf, lalu n/=time(0)-t. 3) Ganti bdengan elemen tambahan w, ganti strcpydengan baca langsung ke w.
ugoren
Mengganti fgets()dengan gets()membutuhkan kode tambahan untuk berurusan dengan baris baru dalam kamus; akhirnya ini menjadi lebih pendek. rand()%itidak cukup; perhitungan sebenarnya adalah (double)i*rand()/RAND_MAX. Memindahkan *60ke printf juga berarti mengubah -4ke -240sehingga akhirnya berakhir kerugian. Poin Anda yang lain adalah yang valid, meskipun (saya percaya). Oh, dan longkarena time_t secara tradisional panjang. Hanya karena kita bermain golf bukan berarti kita tidak bisa portabel.
kotak roti
Saya melewatkan 4-> 240... Portabilitas dan golf tidak cocok bersama. Tetapi mendefinisikan i,t;(int implisit) tidak apa-apa hingga MAX_INTdetik (jika Anda tidak menggunakan time(&t)). Dengan rand(), yang Anda butuhkan adalah 10/ikesempatan, dan rand()%i<10melakukannya.
ugoren
Pilihan acak Anda agak cacat (bukan berarti keadilan mutlak diperlukan). Baris 11 harus memiliki kesempatan 10/11 untuk dipilih, tetapi Anda melakukannya rand()%10>10, yang memberikannya 100%. rand()%(i+1)>9lebih baik (tetapi sebaliknya jika %(i+1)dilakukan i++>9?. Juga pindah *stdinmenjadi yang pertama dan hemat tempat.
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!");}

Versi yang sedang berjalan di sini: http://ideone.com/Nt6Id

Cristian Lupascu
sumber
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))

Ini dalam python 2.x, dalam 3.x saya bisa mencukur 4 karakter lagi dengan menggunakan fungsi cetak.

Termasuk baris baru

Joel Cornett
sumber
2
"Pertanyaan: Apakah baris baru masuk hitungan?" Kami biasanya menggunakan "karakter yang diperlukan". Dalam kasus Python, ya, baris baru perlu dihitung, karena menghapusnya akan membuat program tidak berfungsi.
Joey Adams
1
Saya pikir Anda bisa berubah z=lambda x:menjadi def z(x):.
Joey Adams
@ JoeyAdams: Saya bisa jika hanya perlu mengembalikan tidak ada, tapi saya perlu kembali len(x)dan def z(x):return5 lagi charaters: /
Joel Cornett
Saya pikir Anda dapat memenangkan beberapa karakter dengan memasukkan input (diizinkan dalam pertanyaan) dan menggunakan input()bukannyasys.argv[1].read()
ChristopheD
@ JoelCornett: Ups, kau benar.
Joey Adams
2

PHP 187 byte

Baris baru telah ditambahkan untuk kejelasan:

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

Menerima nama file kamus sebagai argumen baris perintah. File kamus harus diakhiri dengan baris baru.

primo
sumber
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!")
Pangeran John Wesley
sumber