สร้างการทดสอบความเร็วในการพิมพ์ / การวัด CPM


11

กฎระเบียบ

ได้เวลาสร้างการทดสอบความเร็วการพิมพ์ในภาษาที่คุณเลือกแล้ว!

1 . คุณให้ไฟล์พจนานุกรมที่มีตัวเลือก (คำว่า 'ทุกคำในนั้นต้องเป็นตัวคั่นบรรทัดใหม่) ไพพ์ในผ่านstdinหรือให้ชื่อเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

a
สามารถ
เกี่ยวกับ
ข้างบน
ขาด
...

2 . เลือก 10 คำสุ่มจากไฟล์ (ไม่อนุญาตให้ซ้ำกัน) และพิมพ์ออกมาในลักษณะดังต่อไปนี้:

-> โดยตรง
-> พื้น
-> ถัดไป
-> ห้า
...

3 . เริ่มการวัดเวลาที่ใช้นับจากนี้ไป!

4 . ให้ผู้ใช้พิมพ์คำทั้งสิบคำให้เร็วที่สุดเท่าที่จะทำได้ (จบลงด้วยการคืนรถ) พิมพ์OKเมื่อคุณมีคู่ที่ตรงกันพิมพ์WRONGเมื่อเรามีข้อผิดพลาดในการพิมพ์ (หรือคำที่ถูกพิมพ์เรียบร้อยแล้วในการวิ่งครั้งนี้)

5 . หยุดเวลา! ตอนนี้พิมพ์CPM (caracters ต่อนาที) (sum of the characters of the chosen words / time spent typing (seconds)) * 60มาตรฐานซึ่งคำนวณดังนี้ ปัดเศษเป็นจำนวนเต็มที่ใกล้ที่สุดและสร้างผลลัพธ์ (ตัวอย่าง) ต่อไปนี้:

-> คุณได้คะแนน 344 CPM!

ตัวอย่างการเรียกใช้

-> ชำระบัญชี
-> ด้านข้าง
-> เปิด
-> รัฐมนตรี
-> ความเสี่ยง
-> สี
-> เรือ
-> เดียวกัน
-> ขนาด
-> ดาบ
ชำระ
ตกลง
ด้าน
ตกลง
เปิด
ตกลง
# ...................... บางบรรทัดคัดลอก ......................
คำ
ไม่ถูกต้อง
ดาบ
ตกลง
-> คุณได้คะแนน 298 CPM!

ผู้ชนะ

นี่คือ code colf ซึ่งเป็นรายการที่สั้นที่สุด (ในการนับจำนวนตัวอักษรของซอร์สโค้ด) ขอให้สนุก!


4
ฉันคิดว่าผู้ชนะควรได้คะแนนจากผู้ที่มี CPM สูงสุดบางส่วน;)
mellamokb

เราต้องการวัดเวลาอย่างแม่นยำเพียงใด? ความละเอียดหนึ่งวินาทีตกลงหรือไม่
Ilmari Karonen

@Ilmari Karonen: ความละเอียดหนึ่งวินาทีจะดีสำหรับการประกวดนี้โดยเฉพาะ
ChristopheD

คำตอบ:


5

K, 146

ถือว่าไฟล์พจนานุกรมชื่อ 'd' ในไดเรกทอรีทำงานปัจจุบัน

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

ดีและสั้นมากรายการแรกในKฉันได้เห็น (ที่นี่ใน codegolf.se) ...
ChristopheD

ขอบคุณคำตอบทั้งหมดของฉันที่นี่อยู่ใน Q หรือ (มากขึ้น) ใน K.
tmartin

ฉันไม่เข้าใจเลยว่าทำไมสิ่งนี้มี upvote เดียว (ของฉัน)!
ChristopheD

11

Bash - 217 212 199 196 ตัวอักษร

ไม่ใช่ว่าจะชนะ แต่มันก็สนุก

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!

ต่ำกว่า 200 ตัวอักษรตอนนี้!

นำไฟล์ wordlist มาเป็นอาร์กิวเมนต์ ตอนนี้รับรายการคำศัพท์จากอินพุตมาตรฐาน วางในเทอร์มินัลแล้วกด ^ D

ดำเนินการตามข้อเสนอแนะจากการจัดการ


1
ไม่ gonna ชนะ แต่มันก็สนุก - ฉันคิดว่าเหมือนกันเมื่อผมโพสต์ของฉัน C # โซลูชั่น :)
Cristian Lupascu

1
คุณสามารถใช้$SECONDSตัวแปรเชลล์เพื่อทำให้การคำนวณเวลาที่ผ่านไปง่ายขึ้น
จัดการ

คุณสามารถลบอักขระได้อีก 2 ตัว: 1) :ในการขยายพารามิเตอร์ค่าเริ่มต้น; 2) $ด้านหน้าของSECONDSการประเมินผลเลขคณิต อันที่จริงมีอักขระพิเศษอีกบรรทัดขึ้นบรรทัดใหม่ที่และของไฟล์
จัดการ

4

ทับทิม (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)

ค่อนข้างธรรมดาฉันแน่ใจว่ามีการปรับปรุงที่จะต้องทำ ใช้ชื่อไฟล์ของพจนานุกรมเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

แก้ไข : ปรับแต่งเล็กน้อยไม่กี่ส่วนใหญ่รอบการรักษาบรรทัดใหม่จากพจนานุกรม ดังนั้นไฟล์จะต้องขึ้นบรรทัดใหม่เพื่อให้ทำงานได้อย่างถูกต้อง


4

C, 305 309 347ตัวอักษร

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

ขอบคุณ @ugoren สำหรับคำแนะนำในการปรับปรุง การใช้ "คำที่ 11" เพื่อยกเลิกรายการพจนานุกรมขาเข้าเป็นชัยชนะครั้งใหญ่ของวิธี strcpy-if-selected ก่อนหน้าของฉัน

นี่คือแหล่ง Ungolfed:

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

การปรับปรุงบางอย่าง 1. K & R main(n,v)char**v;{...ประกาศ: 2. สามารถstdin = (ไม่ต้องสนใจบัฟเฟอร์มากไปกว่านี้) 3. มีอะไรผิดปกติกับ? ไม่จำเป็น 4. ทำไม? char *fgets(buf,len,stdin)gets(buf)rand()%iRAND_MAXlong
ugoren

1
นอกจากนี้: 1) ->t=time(0) time(&t)2) n*60/(time(0)-t)มีวงเล็บว่าต้องไป - *60สามารถเคลื่อนย้ายไปแล้วn+=60*printf n/=time(0)-t3) แทนที่bด้วยองค์ประกอบพิเศษในการwแทนที่ด้วยการอ่านโดยตรงในstrcpy w
ugoren

การแทนที่fgets()ด้วยgets()ความต้องการโค้ดพิเศษเพื่อจัดการกับบรรทัดใหม่ในพจนานุกรม แผลนี้สั้นลง rand()%iไม่เพียงพอ (double)i*rand()/RAND_MAXการคำนวณที่เกิดขึ้นจริง การย้าย*60ไปยัง printf ยังหมายถึงการเปลี่ยน-4ไปยัง-240ท้ายที่สุดทำให้เกิดการสูญเสีย ประเด็นอื่น ๆ ของคุณนั้นถูกต้อง (ฉันเชื่อ) โอ้และlongเป็นเพราะ time_t มีความยาวแบบดั้งเดิม เพียงเพราะเราเล่นกอล์ฟไม่ได้หมายความว่าเราไม่สามารถพกพาได้
breadbox

ฉันพลาด4-> 240... การพกพาและกอล์ฟไม่ไปด้วยกันได้ดี แต่การกำหนดi,t;(โดยนัย int) ก็โอเคไม่เกินMAX_INTวินาที (ถ้าคุณไม่ได้ใช้time(&t)) ด้วยrand()สิ่งที่คุณต้องการคือ10/iโอกาสและrand()%i<10ทำ
ugoren

การเลือกแบบสุ่มของคุณค่อนข้างมีข้อบกพร่อง (ไม่ใช่ความยุติธรรมที่สมบูรณ์แบบ) บรรทัดที่ 11 ควรมีโอกาส 10/11 ในการเลือก แต่คุณทำrand()%10>10ซึ่งให้ 100% rand()%(i+1)>9ดีกว่า (แต่ถ้าเป็น%(i+1)เช่นi++>9?นั้น*stdinให้ย้ายไปเป็นอันดับแรกและประหยัดพื้นที่
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!");}

ใช้เวอร์ชั่นที่นี่: 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))

นี่คือ python 2.x ใน 3.x ฉันสามารถโกนอักขระได้อีก 4 ตัวโดยใช้ฟังก์ชั่นการพิมพ์

ขึ้นบรรทัดใหม่


2
"คำถาม: การขึ้นบรรทัดใหม่นับหรือไม่" เรามักจะไปด้วย "ตัวละครที่จำเป็น" ในกรณีของ Python จะต้องนับบรรทัดใหม่เนื่องจากการลบบรรทัดเหล่านั้นจะทำให้โปรแกรมไม่ทำงาน
Joey Adams

1
ฉันคิดว่าคุณสามารถเปลี่ยนไปz=lambda x: def z(x):
Joey Adams

@ JoeyAdams: ฉันสามารถทำได้ถ้าเพียงต้องการที่จะกลับไม่มี แต่ฉันต้องการที่จะกลับมาlen(x)และdef z(x):returnเป็น charaters อีก 5: /
Joel Cornett

ฉันคิดว่าคุณสามารถชนะตัวละครบางตัวโดยการใส่ท่อในอินพุต (อนุญาตในคำถาม) และใช้input()แทนsys.argv[1].read()
ChristopheD

@JoelCornett: โอ้โหคุณพูดถูก
Joey Adams

2

PHP 187 ไบต์

เพิ่มบรรทัดใหม่เพื่อความชัดเจน:

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

ยอมรับชื่อไฟล์พจนานุกรมเป็นอาร์กิวเมนต์บรรทัดคำสั่ง ไฟล์พจนานุกรมจะต้องลงท้ายด้วยการขึ้นบรรทัดใหม่


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.