Ganzzahlige Marke in Note

30

Wandeln Sie eine positive ganze Zahl (0 und höher, kein Maximum) in eine Note um, indem Sie die folgenden Regeln beachten:

A = 100+  
B = 90 - 99  
C = 80 - 89  
D = 70 - 79  
E = 60 - 69  
F = 59 and less.

Das fühlte sich ein wenig langweilig an, also machen Sie die Note a + wenn es 7,8 oder 9 ist und a, -wenn es 0,1 oder 2 ist. Ignorieren Sie dies für die F- und A-Fälle.

Ein Beispiel:

Eingang:

65

Ausgabe:

E

Testfälle:

0  -> F
20 -> F
65 -> E
72 -> D-
75 -> D
80 -> C-
99 -> B+
102 -> A
864 -> A

Keine nachgestellten Leerzeichen. Eine neue Zeile nach der Ausgabe ist in Ordnung, aber konsistent. Funktionen und volle Programme sind beide in Ordnung.

Dies ist Codegolf, also gewinnt der kürzeste Code. Dies wurde inspiriert durch eine Frage an Ubuntu: Wie schreibe ich ein Shell-Skript, um numerischen Bereichen Buchstabenstufen zuzuweisen? . Die Antworten sind in Bash und Python, also leicht verwöhnt.


Bestenliste:

Hier ist ein Stack-Snippet, um sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache zu generieren.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Tim
quelle
1
Wäre da nicht ein A+und A-? Ich verstehe nicht, warum wir sie ignorieren.
ASCIIThenANSI
1
@ASCIIThenANSI macht es interessanter, Ausnahmen zu haben, und es gibt kein Maximum für das A, also nein+
Tim
1
Diese Klassifikationstafel hat einen Fehler: Die Fischversion ist älter und meine Antwort liegt davor.
Ismael Miguel
@IsmaelMiguel Es wurde geschrieben, als der früheste Beitrag noch nicht der Standardbindungsbrecher war (daher werden überhaupt keine Bindungen bestellt). Ich werde versuchen, es irgendwann zu beheben (wahrscheinlich nicht für diese Herausforderung, aber zumindest die Quelle auf Meta).
Martin Ender
@ MartinBüttner Ich habe gerade darauf hingewiesen.
Ismael Miguel

Antworten:

21

Python 2, 72 70 62 Bytes

lambda n:"FA"[n>59:1+n/100]or chr(75-n/10)+"+-"[(n+3)%10/3::2]

Dies ist eine anonyme Funktion, die eine Ganzzahl annimmt und die Note als Zeichenfolge zurückgibt.

(thanks to @MartinBüttner, @grc and @TheNumberOne for tips)

Sp3000
quelle
4
"EDCB"[n/10-6] -> chr(75-n/10)
grc
What a clever way to select a character that might be empty!
xnor
11

CJam, 34 33 32 bytes

riAmd)4/"- +"=S-\Ae<5e>_~'L+o5%<

Okay, I've tried multiple approaches now and am unable to get this below 33, so here goes the explanation:

ri                                 e# Read the input and convert to integer
  Amd                              e# Take divmod of the input with 10. This leaves the
                                   e# number/10 and number%10 on stack
     )4/                           e# Increment the mod by 1 and integer divide by 4.
        "- +"=S-                   e# This converts 0,1,2 to 0 and 7,8,9 to 2. Pick - or +
                                   e# respectively and remove space in case of 3,4,5 and 6
                \Ae<5e>            e# To the divisor by 10 scope it to range of [5,10]
                       _~          e# Take a copy and do number * -1 - 1
                         'L+       e# Add it to char L. This gets us the required grade
                            o      e# Output the grade. This removes it from stack
                             5%    e# We now have scoped divisor on stack. Do mod with 5
                               <   e# Both 5 and 10 will return 0, in which case, we don't
                                   e# want the + or -. So we do a substr(0, 0).
                                   e# 5 represents F and 10, A. For others, it will do
                                   e# substr(0,X) where X > 0. Since the string is only
                                   e# 1 char long, it doesn't affect at all.

UPDATE: 1 byte saved thanks to a pointer by Dennis

Try it online here

Optimizer
quelle
What does the s do?
Dennis
@Dennis converts char +/-/space to string for the last <
Optimizer
That shouldn't be necessary. Character String - pushes a string.
Dennis
@Dennis Ah, you are right. I think for some previous version, the usage was different.
Optimizer
8

Retina, 43 + 15 = 58 bytes

...+
A
.[012]
$&-
.[789]
$&+
^9.
B
^8.
C
^7.
D
6.
E
\d.*
F

Retina is a regex language created by Martin Büttner, where the odd-numbered files are the regex to match with, and the even-numbered files are what to replace it with. Each line is a separate file, so I've added 15 bytes for each additional file.

Explanation

It starts by making anything with 3 or more digits an A. It adds a - if it is two-digit number ending with 0, 1, or 2, and + if it ends with 7, 8, or 9. The numbers are then mapped to their grade (e.g. a number starting with 9 is given a B). Any number left over is automatically an F. Unfortunately, ;` must be prepended to all but to the last regex to suppress intermediate output. Update: version 0.5.0 has intermediate output off by default, allowing me to save a few bytes.

NinjaBearMonkey
quelle
Are you sure it doesn't output + and - for the F case?
Tim
1
@Tim It shouldn't, because \d.* matches and replaces the whole string, + included.
NinjaBearMonkey
Ahh okay - I can see that now! :)
Tim
8

C, 99 bytes

I'm new here, I hope I'm following the rules.

char b[3];char*f(n){b[1]=0;n<60?*b=70:n>99?*b=65:(*b=75-n/10,b[1]=n%10<3?45:n%10>6?43:0);return b;}

This function takes the mark as a parameter and returns the grade as a NULL-terminated string.

Explanation

Added whitespace:

char b[3];

char *f(n) {
    b[1] = 0;
    n<60 ? *b = 70 :
    n>99 ? *b = 65 :
    (
        *b = 75 - n / 10,
        b[1] = n % 10 < 3 ? 45 : n % 10 > 6 ? 43 : 0
    );

    return b;
}

Global variables are automatically initialized to zero, so b is filled with NULLs. Since only the first two characters are ever touched, we only have to worry about putting a NULL in b[1] if the grade has only one character. This NULL is inserted at the very beginning of the function. The n parameter is implicitly int. If the grade is less than 60, then it's set to 'F', if it's bigger than 99 it's set to 'A'. In the other cases, the base grade is given by 'E' - (n - 60) / 10, which simplifies to 75 - n / 10. n % 10 gets the units digit of the mark. If it's less than 3 then a - is appended, if it's bigger than 6 a + is appended, otherwise b[1] is nulled (which it already was).

Test cases

#include <stdio.h>

char b[3];char*f(n){b[1]=0;n<60?*b=70:n>99?*b=65:(*b=75-n/10,b[1]=n%10<3?45:n%10>6?43:0);return b;}

int main() {
    printf("  0 -> %s\n", f(0));
    printf(" 20 -> %s\n", f(20));
    printf(" 65 -> %s\n", f(65));
    printf(" 72 -> %s\n", f(72));
    printf(" 75 -> %s\n", f(75));
    printf(" 80 -> %s\n", f(80));
    printf(" 99 -> %s\n", f(99));
    printf("102 -> %s\n", f(102));
    printf("864 -> %s\n", f(864));

    return 0;
}

Output:
  0 -> F
 20 -> F
 65 -> E
 72 -> D-
 75 -> D
 80 -> C-
 99 -> B+
102 -> A
864 -> A
Andrea Biondo
quelle
Perfect :) Nothing wrong there.
Tim
difference between ur code and mine is one word "printf" that should save more than 3 byts in case ignored :)
Abr001am
7

Pyth, 33 bytes

+C-75K@S[/QTT5)1<-@"- +"/heQ4d%K5

Try it online: Demonstration or Test Suite

Explanation:

                                     implicit: Q = input
        [/QTT5)                      create the list [Q/10, 10, 5]
       S                             sort
      @        1                     take the element in the middle
     K                               store in K (this results in a number between 5 and 10)
  -75K                               75 - K
 C                                   char with ASCII-value ...
                  @"- +"/heQ4        "- +"[(Q%10 + 1) / 4]
                 -           d       remove spaces
                <             %K5    slice [:K%5]
+                                    add these two chars and print
Jakube
quelle
7

><> (Fish), 78 71 bytes

iii0)?/:0({:'6'(@@+?/'{'01.
;$-o:'4'(?\'7'(?;'+'o
 ;o'A'\   \'-'o;o'F'\

Method:

  • We read the codepoints of first 3 characters x,y,z from the input. If a character is not present the value of its variable's will be -1 implicitly. (ord(c) will mark the codepoint of the character c)
  • If z > 0 (3 digit input) print A and exit.
  • If x < ord('6') or y < 0 (input < 60) print F and exit.
  • Print the character with codepoint 123 - x.
  • If y < ord('4') print-` and exit.
  • If y > ord('6') print+` and exit.
  • Exit.
randomra
quelle
7

C, 67 65

Surprisingly, this is quite close to the python solution.

f(i){printf(i<60?"F":i>99?"A":"%c%s",75-i/10,"-\0+"+(i%10+1)/4);}

But in order for this program, to come to such great shortness, sacrifices had to be made:

  • If an F or an A is printed printf doesn't even look at the other arguments passed. This is a quite nasty hack.

  • If (i%10+1)/4 evaluates to 1 (no + or - should be appended to the grade), the %s formatter receives a pointer to a \0 byte, so nothing is printed. Also quite funny, because I didn't know that you could take the address of an indexed string literal. (e.g. &"string"[i]) (edit: "string"+i is even shorter! Thanks @nutki)

Here the output of the program for the numbers 57 to 102. I made it a hexdump, so we can be sure no weird \0 bytes have been printed.

% seq 44 115 | xargs -n1 ./grade | xxd
0000000: 4646 4646 4646 4646 4646 4646 4646 4646  FFFFFFFFFFFFFFFF
0000010: 452d 452d 452d 4545 4545 452b 452b 452b  E-E-E-EEEEE+E+E+
0000020: 442d 442d 442d 4444 4444 442b 442b 442b  D-D-D-DDDDD+D+D+
0000030: 432d 432d 432d 4343 4343 432b 432b 432b  C-C-C-CCCCC+C+C+
0000040: 422d 422d 422d 4242 4242 422b 422b 422b  B-B-B-BBBBB+B+B+
0000050: 4141 4141 4141 4141 4141 4141 4141 4141  AAAAAAAAAAAAAAAA

The main method used:

main(c,v)char**v;{f(atoi(v[1]));}
MarcDefiant
quelle
1
&"string"[i] is unnecessary as it is equivalent to shorter "string"+i with which you can save 2 bytes.
nutki
i must be objective and upovote this :) congrats , u beated all C records
Abr001am
6

CJam, 41 39 37 34 bytes

This is way too long, but I don't think I'll be golfing it further for now.

qiAmd'K@Ae<5e>:X-X5%g@)4/"- +"=*S-

Test it here. Or run all test cases here.

Three bytes saved by Optimizer.

Explanation

(Slightly outdated)

qi                                    e# Read input and convert to integer.
  'K1$                                e# Push the character K, then copy the input.
      A/                              e# Divide by 10.
        Ae<5e>                        e# Clamp the result to the range 5..10.";
              -                       e# Subtract from K to get the grade.
               _'Am                   e# Duplicate get difference to A.
                   5%g                e# Check that its neither 0 (A) nor 5 (F).
                      @               e# Pull up the other copy of the input.
                       A%)4/          e# ((i % 10) + 1) / 4
                            "- +"=    e# Use that to select -, space, or +.
                                  *   e# Multiply it with the earlier boolean so that
                                      e# it vanishes for A and F.
                                   S- e# Remove the space if there is one.
Martin Ender
quelle
6

GNU sed, 73 + 1 = 74 bytes

The + 1 is for the -r parameter.

s/^[1-5]?.$/F/
s/.{3,}/A/
s/[7-9]$/+/
s/[3-6]$//
s/[0-2]$/-/
y/9876/BCDE/
Digital Trauma
quelle
5

Python 2, 94 88 84 69 bytes

lambda g:g>99and'A'or[chr(75-g/10)+'-+'[g%10>2:1-(g%10>6)],'F'][g<60]
TheNumberOne
quelle
5

JavaScript (ES6), 66 bytes

Straight.

F=n=>n<60?'F':n>99?'A':'EDCB'[n/10-6|0]+(n%10>6?'+':n%10<3?'-':'')

// TEST (in Firefox)

for(i=0;i<111;i++)document.write(i+'='+F(i)+' ')

edc65
quelle
4

R, 107 105 99 bytes

Not a very good effort I'm afraid, but I will try and golf it more later.

cat(LETTERS[11-(r=min(max(scan(),59),100))%/%10],if(r>59&r<100)c('-','','+')[(r%%10+1)/4+1],sep='')

Edit Dropped a couple of ifs. Fixed the case and an incorrect result for 100. Now to get rid of the ifelses. Got rid of ifelses.

MickyT
quelle
I think you want LETTERS rather than letters.
Alex A.
3

Perl, 66 62 bytes

This can probably be golfed more. Also a different way might be better.

$_=$_>99?A:$_<60?F:s/\d$/$&>6?"+":$&<3?"-":""/re;y/9876/BCDE/

+1 for -p

Run with:

echo 72 | perl -pE'$_=$_>99?A:$_<60?F:s/\d$/$&>6?"+":$&<3?"-":""/re;y/9876/BCDE/'
hmatt1
quelle
Why not use -p and drop the say?
ThisSuitIsBlackNot
@ThisSuitIsBlackNot thanks! Updated
hmatt1
2

Javascript (ES6), 78 79 bytes

This really isn't the smartest option, but I did what I could.

F=n=>'FEDCBA'[n[2]?5:n<60?0:n[0]-5]+(n[2]||n<60?'':'-+\n'[n[1]<3?0:n[1]>6?1:2])

Simply pass the grade as a string, and it will return it's grade letter.

The string part in very important.

You can check a testcase here:

console._RELAY_TO_DOC=true;

//non-es6 version:

function F(n){return 'FEDCBA'[n[2]?5:n<60?0:n[0]-5]+(n[2]||n<60?'':'-+\n'[n[1]<3?0:n[1]>6?1:2])}



var testcases=[0,20,65,72,75,77,80,90,99,100,102,180,1000],
    results={};

for(var i in testcases)
{
  results[testcases[i]]=F(testcases[i]+'');
}

console.log(results);
<script src="http://ismael-miguel.github.io/console-log-to-document/files/console.log.min.js"></script>

If the aditional space after the letter isn't allowed, I will happily remove it. It wasn't! This increased my code by 1 byte, but nothing (too) serious.

Ismael Miguel
quelle
1
@Tim Fixed it. I hope it is enough. Quoting yourself: "One newline after output is fine, but keep it consistent.". I think that is consistent enough.
Ismael Miguel
2

C#, 143 127 112 88 bytes

string g(int n){return n>=100?"A":n<=59?"F":(char)(75-n/10)+(n%10>6?"+":n%10<3?"-":"");}

I tried to be clever by doing ASCII number mods, but it seems I wasn't alone!

Thanks to Tim for advice on lists instead of ifs.

Thanks to DarcyThomas for pointing out I could use nested ternary operators.

Transmission
quelle
1
Can you not cut down on the ifs using lists?
Tim
I'm not sure what you mean by using lists, could you explain a little?
Transmission
In python I can do this: [item1,item2][condition]. If the condition is True it gives the 2nd item, if False the first.
Tim
Good idea! Added that.
Transmission
I think you could use ternary if statements e.g., return <condition> ? <true result> : <false result> Note you can also nest them so return <condition> ? <true result> : <condition> ? <2nd true result> : < 2nd false result>
DarcyThomas
1

Haskell, 78 bytes

The first line feels wasteful, costing 14 bytes, but I couldn't find a shorter version without it.

(#)=replicate
a="A":a
f=(!!)$60#"F"++[g:s|g<-"EDCB",s<-3#"-"++4#""++3#"+"]++a

Explanation

The operator # is a shorthand for creating n copies of its second argument. List a is an infinite list of Strings "A". Function f indexes into a list of all grades for n=0,1,... The list comprehension builds the "middle part" of this list (grades E to B); g is a single Char that is prepended to the String s (which may be empty).

Usage

ghci> map f [0,20,65,72,75,80,99,102,864]
["F","F","E","D-","D","C-","B+","A","A"]
user40671
quelle
1

C, 102 bytes

int f(int h){int b,c;printf("%c%c",b?65:!c?70:75-h/10,!(b=h>99)*(c=h>59)*(((h%10<3)*45+(h%10>6)*43)));

}

Usage

#include <stdio.h>
int f(int );
int main(){
    int c;
    scanf("%d",&c);
    f(c);
}
Abr001am
quelle
You are missing the + and - part.
Optimizer
ah ok .... miss that
Abr001am
too long :( ....
Abr001am
1

dc, 52

[Anq]sa[Fnq]sf[q]sn16o?A~rd9<ad6>f20r-n1+4/d1=n45r-P

Output

$ for i in {0,20,65,72,75,80,99,102,864}; do printf "{%s -> %s} " $i $(dc -e '[Anq]sa[Fnq]sf[q]sn16o?A~rd9<ad6>f20r-n1+4/d1=n45r-P' <<< $i); done
{0 -> F} {20 -> F} {65 -> E} {72 -> D-} {75 -> D} {80 -> C-} {99 -> B+} {102 -> A} {864 -> A} $ 
$ 
Digital Trauma
quelle
1

TI-Basic, 79 74 76 Bytes

Input N
If N>99
105->N
sub("FFFFFFEDCBA",1+int(N.1),1
If Ans!="F
Ans+sub("---    +++",1+fPart(N.1),1
Ans
Timtech
quelle
That does not work for numbers less than 10.
lirtosiast
Nice catch, Tom, it was missing 1+
Timtech
This also has (invisible) trailing spaces whenever there is no + or -.
lirtosiast
1

TI-BASIC, 69 68 66 bytes

.1Ans
sub("F?E-E+D-D+C-C+B-B+A",1+2max(0,min(9,int(2Ans)-11)),int(e^(Ans<10 and Ans≥6 and iPart(2.2-5fPart(Ans

TI-BASIC is not good for string manipulation.

Input on the calculator homescreen, in the form of [number]:[program name].

Formatted:

.1Ans
sub(                      //Syntax for the substring command is sub(string, index, length)

    "F?E-E+D-D+C-C+B-B+A"                  //String that encodes possible grades

    ,1+2max(0,min(9,            ))         //Starts at "F" if input <60, "A" if >=100
                   int(2Ans)-11           //(Input-55)/5, so starts at "E" from 60 to 64,
                                          //second E from 65-69, D from 70 to 74, &c.

    ,int(e^(                                   //length 1 if false, 2 (includes +/-) if true
            Ans<10 and Ans≥6 and               //grade between 60 and 100        
                                 iPart(               //1 if abs. val. of below >= 0.2
                                       2.2-5fPart(Ans  //2.2-.5(last digit)    

This can probably be golfed further.

lirtosiast
quelle
0

C#, 82 bytes

Func<int,string>g=s=>s>99?"A":s<60?"F":(char)(75-s/10)+(s%10<3?"-":s%10>6?"+":"");

Here's a fiddle with some test-cases.

Blorgbeard
quelle
0

JavaScript (ES6), 86 83 bytes

What's really eating up characters is the String.fromCharCode and the +/- condition... I strongly suspect there's a clever way to shorten at least one of them.

f=n=>n>99?'A':n<60?'F':String.fromCharCode(75.9-n/10|0)+(n%10<3?'-':n%10>6?'+':'');
vvye
quelle
If you want short code, String.fromCharCode is almost always useless. Use string indexing (see the other javascript answers)
edc65
Anyway, ~~(.1*-n+75.9) --> 75.9-n/10|0
edc65
@edc65 Thanks for the golfing advice! I'll keep string indexing in mind for the next occasion.
vvye
0

PHP5.5, 73 bytes

Once again, not the shortest one.

But it works!

<?=($n=$_GET[n])<59?F:($n>99?A:'BCDE'[$n[0]-6].'+-'[$n[1]<3?1:2*$n[1]<5])

I've classified it under PHP5.5 instead of just PHP since this uses syntax that is only valid for PHP5.5 and PHP5.6.

You can read about string and array dereferencing in the manual:
http://php.net/manual/en/migration55.new-features.php

Ismael Miguel
quelle
0

Perl, 52

#!perl -p
$_=$_>99?A:$_<60?F:"$_"^"s";y/JK7890-6/BC+++\-\--/d
nutki
quelle
0

Ruby, 58 Bytes

Couldn't believe that there are no Ruby ones here. On reflection it's fairly similar to some that are here already but anyway:

->x{x<60?'F':x>99?'A':(75-x/10).chr+'+-'[(x+3)%10/3].to_s}

Try it here

RichieAHB
quelle
0

Excel, 100 bytes

=IF(A1<60,"F",IF(A1>99,"A",MID("EDCB",INT(A1/10)-5,1)&IF(MOD(A1,10)<3,"-",IF(MOD(A1,10)>6,"+",""))))
Wernisch
quelle