建立打字速度测试/测量每千次展示费用


11

规则

现在是时候以您选择的语言构建打字速度测试了!

1。您为文件提供了一个选择字典(文件中的每个“单词”都必须以换行符分隔)。通过管道输入,stdin或提供其名称作为命令行参数。

一种
能够
关于
以上
缺席
...

2。从文件中选择10个随机单词(不允许重复),并按以下方式打印出来:

->直接
->地面
->下一个
->五个
...

3。从现在开始开始计算时间!

4。让用户尽快键入所有十个单词(以回车结束)。打印OK,当你有一个匹配,打印WRONG的时候我们有一个打字错误(或单词已经成功地在此运行类型)。

5。停止计时!现在,打印CPM(每分钟上网人数)基准,该基准的计算方法如下:(sum of the characters of the chosen words / time spent typing (seconds)) * 60。四舍五入到最接近的整数并重现以下(样本)输出:

->您的得分为344 CPM!

样品运行

->解决
->侧
->打开
->部长
->风险
->颜色
->船
->相同
->大小
->剑
解决
好
侧
好
打开
好
#...............................某些线被剥夺...............................
字
错误
剑
好
->您已获得298 CPM!

赢家

这是代码colf,最短的条目(在源代码字符数中)获胜,玩得开心!


4
我认为获胜者应该部分由最高CPM的人评分;)
mellamokb

我们需要多精确地测量时间?一秒钟的分辨率可以吗?
Ilmari Karonen'5

@Ilmari Karonen:一秒钟的分辨率对于此特定比赛是可以的。
ChristopheD

Answers:


5

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

我不太明白为什么只有一个投票(我的)!
ChristopheD

11

击- 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个字符!

将单词列表文件作为参数 现在将标准输入上的单词列表作为参数。将其粘贴到终端中,然后按^ D

实施建议的建议


1
不会赢,但是很有趣 -我发布C#解决方案时也是如此:)
Cristian Lupascu 2012年

1
您可以使用$SECONDSshell变量来简化经过时间的计算。
manatwork,2012年

您可以再删除2个字符:1):在默认值参数中展开;2)$SECONDS算术运算中的前面。实际上,还有一个额外的字符,文件的and处的换行符。
manatwork'5

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-chosen方法的一大胜利。

这是非公开来源:

#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可以char *fgets(buf,len,stdin)= gets(buf)(不必担心缓冲区溢出)。3.怎么了rand()%iRAND_MAX不需要。4.为什么long
ugoren

1
另外:1)t=time(0)-> time(&t)。2)n*60/(time(0)-t)具有括号必须去- *60可以移动到n+=60*printf,然后n/=time(0)-t。3)替换b为中的额外元素w,替换strcpy为直接读入w
ugoren

替换fgets()gets()需要额外的代码来处理字典中的换行符;这个伤口变短了。rand()%i还不够 实际计算为(double)i*rand()/RAND_MAX。将*60print 移到printf还意味着将-4to 更改为to,-240以便最终解决。但是,您的其他观点是有效的(我相信)。哦,long是因为time_t传统上很长。仅仅因为我们打高尔夫球并不意味着我们不能随身携带。
面包箱

我很想念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 2012年

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

蟒蛇(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,是的,需要计算换行符,因为删除换行符会使程序无法运行。
乔伊·亚当斯

1
我认为您可以更改z=lambda x:def z(x):
乔伊·亚当斯

@JoeyAdams:我可以只返回任何一个,但我需要返回,len(x)并且def z(x):return还有5个角色:/
Joel Cornett 2012年

我想你可以通过输入(允许在问题)管道和使用赢得一些字符input(),而不是sys.argv[1].read()
ChristopheD

@JoelCornett:糟糕,您是对的。
乔伊·亚当斯

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!

接受字典文件名作为命令行参数。词典文件必须以换行符结尾。


2

阶(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!")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.