Faire un classificateur de concours de mathématiques


17

J'aime participer à des concours de mathématiques organisés par Mu Alpha Theta, une société d'honneur des mathématiques aux États-Unis. Lors des compétitions, je fais un test à choix multiple de 30 questions. Il y a cinq choix par question, étiquetés de A à E.

Mon score à un test est de quatre points pour chaque bonne réponse, zéro point pour une question laissée en blanc et un point négatif pour chaque mauvaise réponse.

Écrivez un programme qui note un test selon le système de notation ci-dessus. L'entrée doit comporter deux éléments: une clé de réponse suivie de réponses. Les questions laissées en blanc doivent être saisies comme des espaces vides. La première entrée ne doit contenir que les lettres AE (ou ae, votre choix), et on peut supposer qu'il n'y a pas d'espace dans l'entrée. La deuxième entrée ne doit contenir que des espaces vides et les lettres AE (ou ae). Les entrées ne mettant pas en œuvre des tests de 30 questions doivent être impriméesInvalid test en sortie.

La sortie doit être le grade ou Invalid test.

Prime

Si votre programme imprime le nombre à droite, le nombre laissé vierge et le nombre incorrect après le score final (aR bB cW), décollez 20 octets.

Exemple d'entrée

CABBDCABECDBACDBEAACADDBBBEDDA    //answer key
CABEDDABDC BACDBBAADE  CBBEDDA    //responses

Exemple de sortie

Pas de bonus

73

Prime

73 (20R 3B 7W)

Des règles standard s'appliquent. Le code le plus court en octets gagne.


Que devons-nous faire avec les espaces en première ligne?
lirtosiast

@ThomasKwa Il ne devrait pas y avoir d'espaces sur la première ligne. Invalid test.
Arcturus

2
Il semble que vous ayez modifié les règles après la publication des réponses, ce qui a invalidé au moins 2 d'entre elles. Veuillez ne pas apporter de modifications qui pourraient invalider les réponses après la publication d'un défi. C'est une bonne idée d'utiliser le bac à sable pour obtenir des commentaires avant de publier.
Alex A.

Je pense que cela aurait été plus intéressant car sournois
cat

que diriez-vous de la casse? aussi, que faire si ma langue est ... déplaisante par les espaces? puis-je spécifier des espaces dans l'entrée doit être souligné à la place?
chat

Réponses:


7

Pyth, 53 51

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

Essayez-le en ligne

Les vérifications sont effectuées en voyant si la totalité de l'entrée contient des caractères lorsque tous les espaces a-esont supprimés et en vérifiant si les deux chaînes ont une longueur 30.

Le calcul du score se fait par les deux lignes zipping ensemble, puis en mettant en correspondance chaque couple de: (letters are equal) ? 4 : -1. Ensuite, additionnez simplement les valeurs et ajoutez le nombre d'espaces de la deuxième ligne au score.


1
Aucune erreur. (Actuellement moins d'octets que la réponse de Dennis ...)
Arcturus

7

Sérieusement , 86 octets

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

Prend l'entrée comme "CABBDCABECDBACDBEAACADDBBBEDDA", "CABEDDABDC BACDBBAADE CBBEDDA"

Essayez-le en ligne (vous devrez entrer manuellement l'entrée car les permaliens n'aiment pas les guillemets)

Travailler sur le bonus maintenant. Non, l'ajout du bonus coûterait plus de 20 octets.

Je savais que j'oubliais quelque chose ... Invalid Testn'était pas imprimé en cas d'erreur. Voilà mes espoirs de jouer à l'extérieur avec Dennis.


Le fait-il? Sérieusement? Ensuite, je dois le voter
edc65

4

JavaScript (ES6), 134 octets

Modifier: les exigences de la question ont changé. Cette réponse provient du moment où le programme devait s'assurer que chaque caractère de réponse est AE, chaque caractère de réponse est AE ou espace et qu'ils ont tous les deux une longueur de 30, sinon retour 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

Explication

(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

Tester

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

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

Utilise la compréhension de tableau qui est proposée pour ES7. Le support est donc limité à Firefox pour le moment.

Avec bonus, 106 octets (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]

Modifier: Auparavant, ma solution ne vérifiait que la réponse ou la longueur de la question, vérifie maintenant les deux.


Vous pouvez omettre le f=au début et dire que cela génère une fonction lambda.
Conor O'Brien

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Merci, j'oublie toujours que c'est sur leur test -_-
George Reith

Ce serait beaucoup plus court sans le bonus. 86 octets:(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

@ user81655 C'est vrai, merci ... je me suis un peu rattrapé ... la chaîne de modèle à elle seule fait 34 octets
George Reith

J'ai une réponse très similaire, mais je n'ai pas copié celle-ci (ma première tentative est un précédent, mais je l'ai supprimée car je ne vérifiais pas les longueurs). Cela dit: ce n'est pas valable malgré 3 votes positifs, comme ne vérifie pas la plage A ... E
edc65

2

Japt , 71 octets

Japt est une version abrégée de Ja vaScri pt . Interprète

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

Les deux .s à la fin doivent être les caractères Unicode non imprimables U + 0017 et U + 0099, respectivement.

Comment ça fonctionne

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

J'espère qu'il y a un moyen plus court de s'assurer que les deux longueurs sont égales à 30. Suggestions bienvenues!


2

Haskell, 144 138 octets

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

Serait environ 50 sans la validation. renifler .

Usage: "ABCDEABCDEABCDEABCDEABCDEABCDE" % "AAAAABBBBBCCCCCDDDDDEEEEEAAAAA"


1
!peut être défini comme une all(`elem`l)séconomie de 6 octets.
Zgarb

1
... ou aller Pointfree: g=all.flip elem.
nimi

2

C #, 162 154 148 134 octets

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)+"";

Usage

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

Tester

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


Vous pouvez le changer int s=0,i=0;for(;...pour enregistrer 3 octets.
LegionMammal978

Cela ne fonctionnera pas si j'entre 29 caractères pour la première entrée et 31 pour la seconde.
Johan

@ noisyass2: chaîne x (chaîne k, chaîne a) => k.Longueur! = 30 || a.Longueur! = 30? "Test invalide!": Enumerable.Range (0,30) .Sum (e => a [e] == ''? 0: k [e] == a [e]? 4: -1) + ""; (134 caractères) et tient compte de l'entrée de Johans.
Stephan Schinkel

+1 pour la solution, mais est-ce admissible? OP a déclaré le programme complet.
Yytsi

Johan belle prise! @StephanSchinkel merci pour l'idée d'utiliser le délégué et le bit Enum.range. J'ai pu raser 3 autres caractères en changeant la condition à 30 == (k.Length & a.Length)
noisyass2

2

Ruby, 81 caractères

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

Exemple d'exécution:

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 octets

C'était une bonne partie de la pratique de 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";}

Je ne suis pas un golfeur Java, mais je pense que vous pouvez enregistrer le String.valueOfen ajoutant simplement l'int à une chaîne vide ( ""+IntStream....) - Je crois également que Java permet le non-court-circuitage et, donc vous pouvez supprimer l'un des &et enregistrer un octet .
VisualMelon

@VisualMelon Grands conseils, merci. Cela m'ennuyait combien d'octets String.valueOf prenaient!
RCB

2

brainfuck, 354 octets

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

Nécessite un interpréteur qui vous permet d'aller à gauche de la cellule 0. La sortie est un octet signé. Par exemple, l'octet 0x49est imprimé pour l'exemple d'entrée et 0xFFest imprimé pour l'entrée avec la même première ligne mais la deuxième ligne remplacée par "C" et 29 espaces.

Le score commence à 0, et lorsque la deuxième ligne d'entrée est lue, ces modifications y sont apportées:

  • L'entrée est correcte: ne rien faire
  • L'entrée est incorrecte: soustrayez 5
  • L'entrée est un espace: soustraire 4

Enfin, 120 sont ajoutés. Fonctionnellement, cela revient à supposer un score parfait et à appliquer des pénalités, plutôt que de commencer à 0.

Avec commentaires:

+[--[>]<<+>-]                          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 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

Comme d'habitude, le bonus ne vaut pas la peine.

(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

Vérification des espaces non valides dans la première entrée (car cela a du sens pour moi) 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

Ugh, la validation a pris la moitié de mon code quand j'ai essayé: (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 octets.
Neil

1

Python 2.7, 131, 116, 109 , 139

J'ai essayé de faire une solution "courte" en python ... Et bien voilà, les suggestions sont plus que bienvenues

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'

L'ajout de quelques caractères supplémentaires le rend beaucoup plus lisible ...

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 octets

Plus de la moitié des octets sont destinés à la vérification des tests non valides.

Code:

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

Expliqué:

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

Exemple:

`CABBDCABECDBACDBEAACADDBBBEDDA`*`CABEDDABDC BACDBBAADE  CBBEDDA`.
73

Essayez-le en ligne ici


1

MATLAB, 92 90 octets

Merci à Tom Carpenter de m'avoir aidé à réduire ma réponse de 2 octets!

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)

La fonction peut être appelée en affectant la feuille de réponses à q et les réponses soumises à a . par exemple:

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

La réponse est simplement imprimée à l'écran. 8 octets pourraient être enregistrés s'il est autorisé à imprimer ans = 73


Vous pouvez économiser 2 octets en remplaçant numel(q)par nnz(q).
Tom Carpenter

1

C # 6.0 -> (270-20 = 250) 246-20 = 226 octets

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

Version lisible et non golfée:

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

Je voulais vraiment obtenir le bonus: D


Bon travail! Quelques astuces générales qui s'appliquent ici, vous pouvez déclarer ien sdehors de la boucle for. Vous pouvez utiliser varpour déclarer a, en économisant 1 octet (hourra!). Vous n'avez pas besoin de beaucoup d'accolades {}dans votre code, ce qui est toujours un bon moyen de couper les octets, et cela vaut toujours la peine de regarder une table ASCII lors de la comparaison des caractères (vous pouvez supprimer un octet c[i]==' 'en utilisant une inégalité). Vous devriez également envisager de compter à travers les chaînes en arrière - dans ce cas, vous pouvez enregistrer au moins 1 octet en redéfinissant quelque peu la boucle for.
VisualMelon

Malheureusement, votre soumission n'est actuellement pas complice des critères, car elle ne peut pas reconnaître les entrées invalides.
VisualMelon

@VisualMelon Ahh, je me sens tellement stupide. J'ai écrit cette soumission à l'école, j'ai donc oublié d'ajouter les choses «test invalide», etc. Je vais les ajouter :)
Yytsi

@VisualMelon Oui, cela a été soumis et écrit à l'école à la fin du cours, je vais le modifier. Merci pour les astuces :)
Yytsi

0

Groovy 2.4.5, 107 octets

Juste une simple traduction de la réponse Java précédente .

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 octets

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

J'ai pris le bonus, même si cela m'a coûté 23 octets juste pour l'imprimer. :-(

Explication

#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 */
    }
}

Il y a deux fois plus de code pour vérifier les entrées invalides que pour compter les réponses - la vraie chair du défi est dans la forboucle vers la fin. En fait, voici une version qui suppose que l'entrée est toujours valide, en 163-20 = 143 octets:

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

Et celui qui fait la même hypothèse et imprime uniquement le score, en 133 octets:

#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 octets (avec bonus) ou 231 octets (sans bonus)

Avec bonus:

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;

Sans bonus:

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 n'a pas vraiment d'entrée / sortie, vous devez donc remplacer le k = '..' par la clé, et r = '..' par la réponse. La sortie est imprimée dans le journal.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.