制作数学竞赛评分者


17

我喜欢参加由美国数学荣誉学会Mu Alpha Theta举办的数学竞赛。在比赛中,我接受了30个问题的多项选择题测试。每个问题有五个选择,标记为A到E。

我在测试中的得分是,每个正确答案为4分,空白为空则为零分,每个错误答案为负1分。

编写一个程序,根据上述评分系统对测试进行评分。输入应包含两个部分:答案键和响应。留空的问题将作为空格输入。第一个输入必须仅包含字母AE(或ae,由您选择),并且可以假定输入中没有空格。第二个输入只能包含空格和字母AE(或ae)。未执行30个问题的测试的输入必须Invalid test作为输出打印。

输出应为年级或Invalid test

奖金

如果您的程序在最终得分之后将正确打印数字,将空白打印为空白以及将错误的数字打印为(aR bB cW),则请减去20个字节。

样品输入

CABBDCABECDBACDBEAACADDBBBEDDA    //answer key
CABEDDABDC BACDBBAADE  CBBEDDA    //responses

样品输出

没有奖金

73

奖金

73 (20R 3B 7W)

适用标准规则。以字节为单位的最短代码获胜。


我们应该如何处理第一行中的空格?
lirtosiast,2015年

@ThomasKwa第一行中不应有空格。Invalid test
Arcturus

2
张贴答案后,您似乎更改了规则,其中至少有2条无效。请不要进行更改,以免在发布挑战后使答案无效。在发布之前,最好使用沙盒获取反馈。
Alex A.

我认为这将是更有趣的秘密的

区分大小写如何?另外,如果我的语言......不被空白怎么办?我可以在输入中指定空格应改为下划线吗?

Answers:


7

佩斯53 51

?&!-sJ.z+d<G5&FqR30lMJ+sm?qFd4_1CJ/eJd"Invalid test

在线尝试

检查是通过查看在所有空格和a-e都删除时整个输入是否包含任何字符,以及检查两个字符串是否都具有length来完成的30

得分计算是通过将两行压缩在一起,然后将每对映射到来完成的(letters are equal) ? 4 : -1。然后简单地将这些值相加,然后将第二行中的空格数加回到分数中。


1
没有错误。(当前的字节数少于Dennis的答案...)
Arcturus

7

认真地,86个字节

,`;l5╙¬=);' UΣS" ABCDE"=(**;l`Mi@)=YWé"Invalid test"0WX@Z```i@;(=5*(' =D+`(;l@)5╙¬=IMΣ

像输入 "CABBDCABECDBACDBEAACADDBBBEDDA", "CABEDDABDC BACDBBAADE CBBEDDA"

在线尝试(您必须手动输入输入内容,因为永久链接不喜欢引号)

现在就开始工作。不会,添加奖金将花费20多个字节。

我知道我忘记了某事... Invalid Test如果出现错误,则不会打印。我的希望超出了Dennis的期望。


可以?认真吗 然后我要
投票

4

JavaScript(ES6),134个字节

编辑:问题要求已更改。该答案来自程序需要确保每个答案字符为AE,每个响应字符为AE或空格且它们的长度均为30的情况,否则返回return Invalid test

(a,r)=>[...a].map((q,i)=>q>"E"|q<"A"?x=1:(c=r[l=i])==" "?0:c>"E"|c<"A"?x=1:c==q?s+=4:s--,s=x=0)&&x|l!=29|r.length!=30?"Invalid test":s

说明

(a,r)=>                   // a = answer string, r = responses string
  [...a].map((q,i)=>      // iterate over answers, q = answer, i = question number
    q>"E"|q<"A"?x=1:      // x = 1 if answer is invalid
    (c=r[l=i])==" "?0:    // c = question response, l = answer length, add 0 for space
    c>"E"|c<"A"?x=1:      // x = 1 if response is invalid
    c==q?s+=4:s--,        // add 4 if correct, subtract 1 if incorrect
    s=x=0                 // s = total score, x = is invalid
  )&&
    x|l!=29|r.length!=30? // check input lengths for validity
      "Invalid test":
      s                   // return the score

测试

<input type="text" id="answers" value="CABBDCABECDBACDBEAACADDBBBEDDA" /><br />
<input type="text" id="responses" value="CABEDDABDC BACDBBAADE  CBBEDDA" /><br />
<button onclick='result.innerHTML=(

(a,r)=>[...a].map((q,i)=>q>"E"|q<"A"?x=1:(c=r[l=i])==" "?0:c>"E"|c<"A"?x=1:c==q?s+=4:s--,s=x=0)&&x|l!=29|r.length!=30?"Invalid test":s

)(answers.value,responses.value)'>Go</button><pre id="result"></pre>



3

JavaScript(Firefox 31+),86字节

(x,y)=>(r=i=0,[for(l of y)x[i++]==l?r+=4:r-=l!=' '],i!=30|i-x.length?'Invalid test':r)

使用为ES7建议的数组理解。因此,目前支持仅限于Firefox。

有奖励,106字节(126-20)

(x,y)=>[r=w=i=0,[for(l of y)x[i++]==l?r++:w+=l!=' '],`${r*4-w} (${r}R ${i-r-w}B ${w}W)`,'Invalid test'][i!=30||i-x.length?3:2]

编辑:以前我的解决方案只检查答案或问题的长度,现在检查两者。


您可以f=在开始时省略,说这会生成lambda函数。
Conor O'Brien 2015年

1
@CᴏɴᴏʀO'Bʀɪᴇɴ谢谢,我总是忘了它来自测试-_-
George Reith,

如果没有奖金,这将大大缩短。86个字节:(x,y)=>(r=i=0,[for(l of y)x[i++]==l?r+=4:r-=l!=' '],i!=30|i-x.length?'Invalid test':r)
user81655 2015年

@ user81655是的,谢谢。。。我有点儿困惑了……模板字符串本身就是34个字节
George Reith 2015年

我有一个非常相似的答案,但是我没有复制这个答案(我的第一次尝试是先例,但由于未检查长度而删除了它)。就是说:尽管有3次投票,这还是无效的,因为不检查范围A ... E
edc65

2

Japt,71字节

JaptJa vaScri pt的缩写。口译员

Ul ¥30©Vl ¥30«(U+V k"[A-E ]+" ?U¬r@VgZ ¥Y?X+4:VgZ ¥S?X:X-1,0 :`InvÃ. È.

他们俩 . s分别是不可打印的Unicode字符U + 0017和U + 0099。

怎么运行的

Ul ==30&&Vl ==30&&!(U+V k"[A-E ]+" ?Uq r@VgZ ==Y?X+4:VgZ ==S?X:X-1,0 :"Invalid test
                    // Implicit: U = first input, V = second input
Ul ==30&&Vl ==30&&  // If both input lengths are 30, and
!(U+V k"[A-E ]+"?   // removing all ABCDE and spaces from (U+V) results in an empty string:
Uq r@            ,0 //  Reduce U with this function, starting with a value of 0:
VgZ ==Y?            //   If the matching char in V is equal to this char, 
X+4                 //    return previous value + 4.
:VgZ ==S?X          //   Else if the matching char in V is a space, return previous value.
:X-1                //   Else (if it's wrong), return previous value - 1.
:"Invalid test      // Else, return "Invalid test".
                    // Implicit: output last expression

我希望有一种较短的方法来确保两个长度都等于30。欢迎提出建议!


2

Haskell中,144个 138字节

a%b|map length[a,b]==[30,30]&&"ABCDE"!a&&"ABCDE "!b=show$sum$zipWith(?)a b|0<1="Invalid test"
l!s=all(`elem`l)
_?' '=0
x?y|x==y=4|0<1=0-1

如果没有验证,大约为50。

用法: "ABCDEABCDEABCDEABCDEABCDEABCDE" % "AAAAABBBBBCCCCCDDDDDEEEEEAAAAA"


1
!可以定义为all(`elem`l)s,节省6个字节。
Zgarb

1
......或pointfree: g=all.flip elem
nimi 2015年

2

C#,162个 154 148 134字节

string g(string k,string a)=>k.Length!=30||a.Length!=30?"Invalid Test!":Enumerable.Range(0,30).Sum(e=>a[e]==' '?0:k[e]==a[e]?4:-1)+"";

用法

g("CABBDCABECDBACDBEAACADDBBBEDDA", "CABEDDABDC BACDBBAADE  CBBEDDA")

测试

http://csharppad.com/gist/15f7c9c3c8cfce471ff2


您可以将其更改int s=0,i=0;for(;...为节省3个字节。
LegionMammal978

如果我第一次输入29个字符,第二次输入31个字符,这将行不通。它应该显示“ invalid test”,但实际上会尝试评分。
约翰

@ noisyass2:字符串x(字符串k,字符串a)=> k.Length!= 30 || a.Length!= 30?“无效测试!”:Enumerable.Range(0,30).Sum(e => a [e] ==''?0:k [e] == a [e]?4:-1)+“”; (134个字符),并考虑Johans的投入。
Stephan Schinkel,2015年

+1表示解决方案,但这符合条件吗?OP表示完整程序。
Yytsi 2015年

约翰很好抓住!@StephanSchinkel感谢您使用委托和Enum.range位的想法。我能够刮掉3个字符,将条件更改为30 ==(k.Length&a.Length)
noisyass2

2

Ruby,81个字符

->t,s{r=0;30.times{|i|r+=t[i]==s[i]?4:s[i]>' '?-1:0};t.size==30?r:'Invalid test'}

样品运行:

2.1.5 :001 > ->t,s{r=0;30.times{|i|r+=t[i]==s[i]?4:s[i]>' '?-1:0};t.size==30?r:'Invalid test'}['CABBDCABECDBACDBEAACADDBBBEDDA','CABEDDABDC BACDBBAADE  CBBEDDA']
 => 73 

2.1.5 :002 > ->t,s{r=0;30.times{|i|r+=t[i]==s[i]?4:s[i]>' '?-1:0};t.size==30?r:'Invalid test'}['CCCATCH','CABEDDABDC BACDBBAADE  CBBEDDA']
 => "Invalid test" 

2

Java 183 169字节

这是Java 8的一个不错的实践:

String f(String a,String r){return a.length()==30&r.length()==30?""+IntStream.range(0,30).map(i->a.charAt(i)==r.charAt(i)?4:r.charAt(i)!=' '?-1:0).sum():"Invalid test";}

我不是Java高尔夫球手,但是我认为您可以String.valueOf通过将int添加到空字符串(""+IntStream....)中来保存-我也相信Java允许非短路,因此您可以删除其中之一&并保存一个字节。
VisualMelon 2015年

@VisualMelon很棒的提示,谢谢。我很讨厌String.valueOf占用了多少字节!
RCB 2015年

2

脑干,354字节

+[--[>]<<+>-],----------[[<<<]>>->[>>>],----------]<<<[<<<]>>+[<-[-------<+>]<.+[---<+>]<.++++++++.[-<+++>]<-.+++++++++++.---.-----.-[---<+>]<-.---[-<++++>]<.+++[-<+++>]<.[---<+>]<----.+.>]>[[>,----------->+++++++[<---<<+++>>>-]<[<<+[>>+<<-]]>[>]<<<[>[>+>+<<-]>>[<<+>>-]>[>>>]>----<<<<[<<<]>>[-]]>[>-<-]>[>>[>>>]>-----<<<<[<<<]>[-]]>>]----[>+++<--]>--.<]

需要一个允许您从单元格0左移的解释器。输出是一个有符号字节。例如,字节0x49被打印用于示例输入,并且0xFF被打印以用于输入时使用相同的第一行,但第二行替换为“ C”和29个空格。

分数从0开始,随着第二行输入的读取,对它们进行了以下更改:

  • 输入正确:不执行任何操作
  • 输入错误:减5
  • 输入为空格:减4

最后,添加120。从功能上讲,它与假设完美得分并施加惩罚(而不是从0开始)相同。

有评论:

+[--[>]<<+>-]                          Get 29

,----------[[<<<]>>->[>>>],----------] Get first line of input; for each char sub one
                                       from the 29

<<<[<<<]>>+                            Add one to the cell that originally held 29

[                                      If the cell that originally held 29 is nonzero:

  Write "Invalid test"
  <-[-------<+>]<.+[---<+>]<.++++++++.[-<+++>]<-.+++++++++++.---.-----.-[---<+>]<-.---[-<++++>]<.+++[-<+++>]<.[---<+>]<----.+.

>]

>[                                     If the cell to the right is nonzero:

  This block is only ever entered if "Invalid test" isn't written!

  [                                      For all 30 characters of the first input:

    >,                                     Get char from second input to the right

    ----------                             Subtract 10 for consistency

    -                                      Subtract one more

    >+++++++[<---<<+++>>>-]                Subtract 21 (plus above lines = 32)

    <[                                     If it's nonzero:

      <<+[>>+<<-]                            Add 22 to the character

    ]

    >[>]<<<[                                 If the above block wasn't entered:

      >[>+>+<<-]>>[<<+>>-]                   Make a copy of the character from input 1

      >[>>>]>----                            Subtract 4 from the score

      <<<<[<<<]>>[-]                         Go to the cell just before first character

    ]

    >[>-<-]                                Subtract input 1 char from input 2 char

    >[                                     If the result is nonzero:

      >>[>>>]>-----                          Subtract 5 from the score

      <<<<[<<<]>[-]                          Go back to the result and set it to 0

    ]

    >>                                     Move on to next character

  ]

  ----[>+++<--]>--                       Add 120 to score (perfect score)

  .                                      Print score

  <                                      Go to an empty cell to kill loop

]

1

Python 3中,187 179 175 165 155 151

lambda a,b:(['Invalid test',sum([-1,4][i==j]for i,j in zip(a,b))+b.count(' ')][len(a)==len(b)==30and set(a)^set('ABCDE')==set(b)^set('ABCDE ')==set()])

1

JavaScript ES7、102

像往常一样,奖金是不值得的。

(k,h,t=i=0)=>[for(x of h)t+=k[i++]==x?4:1-x?0:-1]|/[^ A-E]/.test(k+h)|i-30|k.length-i?"Invalid test":t

检查第一个输入中的无效空格(因为这对我来说很有意义)112

(k,h,t=i=0)=>[for(x of h)(y=k[i++])>' '?t+=y==x?4:1-x?0:-1:k=h+h]|/[^ A-E]/.test(k+h)|i-30|k[i]?"Invalid test":t

gh,当我尝试验证时,它占用了我一半的代码:(k,r,s=0)=>/^[A-E]{30}$/.test(k)&&/^[ A-E]{30}$/.test(r)?Object.keys(k).map(i=>k[i]==r[i]?s+=4:s-=r[i]!=' ').pop():'Invalid Test'129字节。
尼尔

1

Python 2.7版,131,116,109,139

我尝试做一个“简短”的python解决方案...好了,这里的建议非常受欢迎

lambda c,d:d.count(' ')+sum([-1,4][a==b]for a,b in zip(c,d)if b!=' ')if not set('ABCDE ')^set(c+d)and len(c)==len(d)==30 else'Test Invalid'

添加更多字符使其更具可读性...

def m(c, d):
    if len(c)==len(d)==30:return d.count(' ')+sum((a==b)*4+(a!=b)*-1 for a,b in zip(c,d)if b!=' ')
    return'Test Invalid'

1

Prolog,165字节

一半以上的字节用于无效测试检查。

码:

p(X,X,4).
p(_,32,0).
p(_,_,-1).
A*B:-length(A,30),length(B,30),subset(A,`ABCDE`),subset(B,`ABCDE `),maplist(p,A,B,L),sum_list(L,S),write(S);write('Invalid Test').

解释:

p(X,X,4).                                       % If corresponding elements are equal, 4p
p(_,32,0).                                      % If answer is 'space', 0p
p(_,_,-1).                                      % Else, -1p
A*B:-length(A,30),length(B,30),                 % Check that input is of correct length
     subset(A,`ABCDE`),subset(B,`ABCDE `),      % Check that input has correct characters
     maplist(p,A,B,L),sum_list(L,S),write(S);   % Create a list of scores (L) and print sum
     write('Invalid Test').                     % If anything failed, write Invalid Test

例:

`CABBDCABECDBACDBEAACADDBBBEDDA`*`CABEDDABDC BACDBBAADE  CBBEDDA`.
73

在这里在线尝试


1

MATLAB,92 90字节

感谢Tom Carpenter帮助我将答案减少了2个字节!

function c(q,a),if nnz(q)~=30,t='Invalid test';else s=q-a;t=5*nnz(~s)-sum(s<9);end,disp(t)

功能可以通过指定的答卷被称为q,并提交答案。例如:

c('CABBDCABECDBACDBEAACADDBBBEDDA','CABEDDABDC BACDBBAADE  CBBEDDA')

答案只是打印到屏幕上。如果允许打印ans = 73,则可以节省8个字节


替换numel(q)为可以节省2个字节nnz(q)
汤姆·卡彭特

1

C#6.0-> (270-20 = 250) 246-20 = 226个字节

void m(string b,string c){if((b+c).Length==60){var a=new int[3];int s=0;for(int i=0;i<30;i++){if(b[i]==c[i]){a[0]++;s+=4;}else if(c[i]==' ')a[2]++;else{a[1]++;s--;}}Console.Write(s+$" ({a[0]} {a[2]} {a[1]})");}else Console.Write("Invalid test");}

可读和非公开的版本:

    void m(string b, string c)
    {
        if ((b+c).Length==60)
        {
            var a = new int[3];
            int s = 0;
            for (int i = 0; i < 30; i++)
            {
                if (b[i]==c[i])
                {
                    a[0]++;
                    s+=4;
                }
                else if (c[i] == ' ')a[2]++;
                else
                {
                    a[1]++;
                    s--;
                }
            }
            Console.Write(s+$" ({a[0]} {a[2]} {a[1]})");
        }
        else Console.Write("Invalid test");
    }

真的想获得奖金:D


干得好!在这里申请几个普通的招数,你可以声明i连同s外面的for循环。您可以var用来声明a,节省1个字节(hurrah!)。您不需要{}代码中的许多花括号,这始终是修剪字节的好方法,并且在比较char时总是值得看一下ASCII表(您可以c[i]==' '使用不等式将字节略去)。您还应该考虑向后计数字符串-在这种情况下,可以通过重新调整for循环来节省至少1个字节。
VisualMelon 2015年

不幸的是,您的提交目前不符合标准,因为它无法识别无效的输入。
VisualMelon 2015年

@VisualMelon啊,我好蠢。我在学校写了这篇论文,所以我忘了添加“无效测试”等内容。我将它们添加
进来

@VisualMelon是的,这是在课程结束时在学校提交并编写的,我将对其进行编辑。感谢您的把戏:)
Yytsi

0

Groovy 2.4.5,107字节

只是早期Java答案的简单翻译。

f={a,b->a.length()==30&b.length()==30?(0..29).collect{a[it]==b[it]?4:b[it]!=' '?-1:0}.sum():'Invalid test'}

0

C,273-20 = 253字节

#include<stdio.h>
#include<string.h>
int main(int c,char**v){char*p=v[1],*q=v[2],*s=" ABCDE",r[]={0,0,0};if(strspn(p,s+1)!=30||p[30]||strspn(q,s)!=30||q[30])puts("Invalid test");else{for(;*p;++q)++r[(*p++!=*q)+(*q==' ')];printf("%d (%dR %dB %dW)",4**r-r[1],*r,r[2],r[1]);}}

尽管已花了23个字节来打印,但我还是获得了奖金。:-(

说明

#include <stdio.h>
#include <string.h>
int main(int c,char**v)
{
    char *p=v[1], *q=v[2],      /* arguments */
        *s=" ABCDE",            /* valid chars */
        r[]={0,0,0};            /* results - right, wrong, blank */

    if (strspn(p,s+1) != 30     /* validity check - answer key begins with [A-E]{30} */
        || p[30]                /* and ends there */
        || strspn(q,s) != 30    /* same for answers, but allow space, too */
        || q[30])
    {
        puts("Invalid test");
    } else {
        for ( ;  *p;  ++q)      /* for each answer */
            ++r[(*p++!=*q)+(*q==' ')]; /* increment the appropriate counter */
        printf("%d (%dR %dB %dW)",4**r-r[1],*r,r[2],r[1]); /* print result */
    }
}

检查无效输入的代码是计算答案的代码的两倍-真正的挑战在于for循环即将结束。实际上,这是一个假定输入始终有效的版本,以163-20 = 143字节表示:

#include<stdio.h>
int main(int c,char**v){char*p=v[1],*q=v[2],r[]={0,0,0};for(;*p;++q)++r[(*p++!=*q)+(*q==' ')];printf("%d (%dR %dB %dW)",4**r-r[1],*r,r[2],r[1]);}

做出相同假设并仅打印分数的字节(133字节):

#include<stdio.h>
int main(int c,char**v){char*p=v[1],*q=v[2],r[]={4,-1,0};for(c=0;*p;++q)c+=r[(*p++!=*q)+(*q==' ')];printf("%d",c);}

0

SAS 9.4、291-20 = 271字节(附赠)或231字节(附赠)

有奖金:

data a;k='CABBDCABECDBACDBEAACADDBBBEDDA';r='CABEDDABDC BACDBBAADE  CBBEDDA';c=0;b=0;w=0;if length(k) ne 30 then put "Invalid test";do i=1 to 30;if substr(k,i,1)=substr(r,i,1) then c=c+1;else if substr(r,i,1) =' ' then b=b+1;else w=w+1;end;a=cat(c*4-w,' (',c,'R ',b,'B ',w,'W)');put a;run;

没有奖金:

data a;k='CABBDCABECDBACDBEAACADDBBBEDDA';r='CABEDDABDC BACDBBAADE  CBBEDDA';c=0;if length(k) ne 30 then put "Invalid test";do i=1 to 30;if substr(k,i,1)=substr(r,i,1) then c=c+4;else if substr(r,i,1)ne' ' then c=c-1;end;put c;run;

Sas实际上没有输入/输出,因此您需要用键替换k ='..',并用响应替换r ='..'。输出将输出到日志。

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.