13
\$\begingroup\$

GPA Calculator

(GPA = Grade Point Average)

You are a stressed out college student during finals week. Instead of studying for your exams coming up, you decide it is best to determine what GPA you will have at the end of the semester. This way you have data to back up your decision of staying up all night to get that A in Calculus instead of a B to remain on the Dean's list!

Being a computer science major you want to find the coolest way to determine this GPA. Of course the coolest way is with the shortest code! This is , so shortest code in bytes wins!

Details

  • The college that you go to uses a basic GPA scaled along with credit hours.
  • A letter grade of A is a 4.0, B is 3.0, C is 2.0, D is 1.0, and F is 0.0
  • Your GPA is a weighted GPA, so an A in a 4 credit hour class counts 4 times as much as an A in a 1 credit hour class (See examples below for more weight explanantion)
  • Credit Hours range from 1-4
  • Your program will need to have a list of two command line inputs, Grade and Credit Hour. You can determine the best way to input these into your program through the command line. You do not need to worry about too many inputs, but ensure your code can handle a 19 credit hour semester.

    • i.e. Input: A 1 B 4 C 2…
  • Your program must output the GPA, using 3 digits (i.e. X.XX)

  • Your GPA needs to be rounded to two decimal places. Round in whichever way you like (floor, ceil, base, etc…)

Input Examples(Choose whichever one works best for your design)

  • A1B3C2F3B4
  • A1 B3 C2 F3 B4
  • A 1 B 3 C 2 F 3 B 4
  • A,1,B,3,C,2,F,3,B,4
  • A1,B3,C2,F3,B4

Or any of the above combinations where you use the format of listing all grades, then their credit hours:

  • i.e. A B A A 3 4 1 1

Examples

Input - A 3 B 4 A 1 A 1
Output - 3.56
Explanation: (4.0 * 3 + 3.0 * 4 + 4.0 * 1 + 4.0 * 1)/(3+4+1+1) = 3.555556 rounded off to 3.56 

Input - A 4 F 2 C 3 D 4
Output - 2.00
Explanation: (4.0 * 4 + 0.0 * 2 + 2.0 * 3 + 1.0 * 4)/(4+2+3+4) = 2 rounded off to 2.00
\$\endgroup\$
  • 2
    \$\begingroup\$ @DevelopingDeveloper Please try to avoid Cumbersome I/O formats. \$\endgroup\$ – JungHwan Min Dec 11 '17 at 17:19
  • 1
    \$\begingroup\$ @JungHwanMin Please let me know which I/O option you wanted that I didn't specify? I gave about 6 different flexible options, but it needs to be specified to actually fit into this scenario. \$\endgroup\$ – DevelopingDeveloper Dec 11 '17 at 17:23
  • 3
    \$\begingroup\$ @DevelopingDeveloper Your GPA needs to be rounded to two decimal places: to achieve this, people need to add additional code that has nothing to do with GPA calculation. \$\endgroup\$ – JungHwan Min Dec 11 '17 at 17:25
  • 2
    \$\begingroup\$ Welcome to PPCG. Nice first question in my humble opinion. \$\endgroup\$ – ElPedro Dec 11 '17 at 20:58
  • 5
    \$\begingroup\$ Despite this being a fairly interesting question, I downvoted, because, as I said before, forcing rounding and outputting with trailing 0s makes this a multipart challenge; answers are having to unnecessarily add bytes, simply to conform to the output specs, which make a challenge boring and worse overall IMO. \$\endgroup\$ – caird coinheringaahing Dec 11 '17 at 23:23

10 Answers 10

5
\$\begingroup\$

Jelly,  15  21 bytes (12 with no rounding)

+6 bytes for the strict formatting (almost certainly possible in less but it's bed time)

Oạ69.Ḟ×S×ȷ2÷⁹S¤RLDż”.

A full program taking the grades and the respective credit hours which prints the calculated GPA (Note: the rounding method is to floor, as allowed in the OP).

Try it online!

With no rounding for 12 bytes:

Oạ69.Ḟ×S÷⁹S¤

How?

Oạ69.Ḟ×S×ȷ2÷⁹S¤RLDż”. - Link: list of characters, grades; list of number, creditHours
                      -                                   e.g. "AFBDC", [5, 2, 4, 1, 2]
O                     - cast to ordinals (vectorises)          [65,70,66,68,67]
  69.                 - literal 69.5
 ạ                    - absolute difference (vectorises)       [4.5,0.5,3.5,1.5,2.5]
     Ḟ                - floor (vectorises)                     [4,0,3,1,2]
      ×               - multiply by creditHours (vectorises)   [20,0,12,1,4]
       S              - sum                                    37
         ȷ2           - literal 100
        ×             - multiply                               3700
              ¤       - nilad followed by link(s) as a nilad:
            ⁹         -   chain's right argument, creditHours  [5, 2, 4, 1, 2]
             S        -   sum                                  14
           ÷          - division                               264.2857142857143
               R      - range                                  [1,2,3,...,264]
                L     - length                                 264
                 D    - digits                                 [2,6,4]
                   ”. - literal '.'
                  ż   - zip together                           [[2,'.'],6,4]
                      - implicit print (smashing)              2.64
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ @nimi - good point, I missed that bit. Fixed. \$\endgroup\$ – Jonathan Allan Dec 11 '17 at 23:12
4
\$\begingroup\$

Python 3, 66 bytes

-5 bytes thanks to Rod.

lambda g,c:'%.2f'%sum('FDCBA'.find(i)*j/sum(c)for i,j in zip(g,c))

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 69-ord(i) don't works \$\endgroup\$ – Rod Dec 11 '17 at 17:24
  • 1
    \$\begingroup\$ You have an extra (), also you can move the /sum(c) to save 3 bytes reaching 66 bytes \$\endgroup\$ – Rod Dec 11 '17 at 17:28
4
\$\begingroup\$

Perl 5, 57 53 + 2 (-an) = 59 55 bytes

$c+=$F[1];$\+=$F[1]*=!/F/&&69-ord}{printf'%.2f',$\/$c

Try it online!

Edit: swapped the input around to save 4 bytes

Input format: line separated, credits followed by grade:

grade credits

Example:

A 3
B 4
A 1
A 1
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Python 2, 69 bytes

lambda x:'%.2f'%sum('FDCBA'.find(a)*b*1./sum(zip(*x)[1])for a,b in x)

Try it online!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 39 bytes

N[(5-LetterNumber@#2/.-1->0).#/Tr@#,3]&

Takes a list of credit hours, and then a string of grades.

Does not work on TIO because TIO uses Mathematica kernel (which doesn't want to print arbitrary precision numbers)

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ -3 bytes if you use Tr \$\endgroup\$ – user73398 Dec 11 '17 at 18:31
  • 3
    \$\begingroup\$ This fails for second test case.It returns 1.85 because you count F=-1 \$\endgroup\$ – J42161217 Dec 11 '17 at 18:43
  • 2
    \$\begingroup\$ Here is a 41bytes fix: N[(5-(LetterNumber@#2/. 6->5)).#/Tr@#,3]& \$\endgroup\$ – J42161217 Dec 11 '17 at 19:07
  • \$\begingroup\$ @Jenny_mathy nice catch. I have no idea how I missed that... The extra parenthesis could be golfed down by moving the /., though. \$\endgroup\$ – JungHwan Min Dec 11 '17 at 21:53
2
\$\begingroup\$

JavaScript (ES6), 72 bytes

Input format: A1B3C2F3B4

f=([c,d,...s],a=b=0)=>c?f(s,a+~'DCBA'.search(c,b-=d)*d):(a/b).toFixed(2)

Test cases

f=([c,d,...s],a=b=0)=>c?f(s,a+~'DCBA'.search(c,b-=d)*d):(a/b).toFixed(2)

console.log(f('A3B4A1A1')) // 3.56
console.log(f('A4F2C3D4')) // 2.00

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ At what point does search become golfier than parseInt? \$\endgroup\$ – Neil Dec 11 '17 at 17:55
  • \$\begingroup\$ @Neil parseInt would probably become golfier with just a few more supported grades. One problem is the gap between F=0 and D=1, though. \$\endgroup\$ – Arnauld Dec 11 '17 at 18:25
  • \$\begingroup\$ Huh, I hadn't even noticed that there's no E... \$\endgroup\$ – Neil Dec 11 '17 at 19:22
2
\$\begingroup\$

R, 64 bytes

function(G,H)sprintf("%.2f",(5-match(G,LETTERS[-5]))%*%H/sum(H))

Try it online!

thanks to user2390246 for fixing a bug!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I think you mean LETTERS[-5] \$\endgroup\$ – user2390246 Dec 12 '17 at 9:49
  • \$\begingroup\$ @user2390246 yes, of course. that was silly of me. \$\endgroup\$ – Giuseppe Dec 12 '17 at 13:25
2
\$\begingroup\$

Java, 211 bytes

Input format: A1B3C2F3B4

Golfed

interface A{static void main(String[] a){int p=0,t=0,h=0,s=0;for(int c:a[0].toCharArray())if(p++%2==0)t=c=='A'?4:c=='B'?3:c=='C'?2:c=='D'?1:0;else{s+=(c-=48)*t;h+=c;}System.out.print(Math.ceil(100d*s/h)/100);}}

Unglofed

static void main(String[] a) {
    int p=0, //position in string
    t=0, //temp var, used to store the grade between iterations
    h=0, //credit sum
    s=0; //sum of weighted grade

    for(int c:a[0].toCharArray())
        if(p++%2==0)
            //map c to grade value, assign to temp variable t
            t=c=='A'?4:c=='B'?3:c=='C'?2:c=='D'?1:0;
        else{
            //map c to credit value, add temp variable (grade from previous char) * value of this char (credit) to sum
            s+=(c-=48)*t;
            //also, add credit to credit sum
            h+=c;
        }
    System.out.print(Math.ceil(100d*s/h)/100); //grade sum / credit hours sum, to 2dp*/
}

Other version

My gut frealing told me that using a different input format (ABCF1324) would make the code shorter. It seems like it didn't. The version below is 234 bytes long.

Golfed

interface A{static void main(String[] b){char[] a=b[0].toCharArray();int l=a.length/2,h=0,s=0,g,c,i;for(i=0;i<l;i++){g=a[i];g=g=='A'?4:g=='B'?3:g=='C'?2:g=='D'?1:0;c=a[i+l]-48;s+=g*c;h+=c;}System.out.print(Math.ceil(100d*s/h)/100);}}a

Ungolfed

static void main(String[] b) {
    char[] a=b[0].toCharArray(); //char array
    int l=a.length/2, //first grade char
    h=0, //credit sum
    s=0, //sum of weighted grade
    g,c, //avoid declaration in for loop. grade and credit being iterated
    i; //avoid declaration in for loop
    for(i=0;i<l;i++) {
        g=a[i];//get char representing grade from array
        g=g=='A'?4:g=='B'?3:g=='C'?2:g=='D'?1:0; //convert to grade
        c=a[i+l]-48;//get char representing grade from array and convert to credit (48 is value of '0')
        s+=g*c; //add weighted grade to sum
        h+=c; //add credit to sum
    }
    System.out.print(Math.ceil(100d*s/h)/100); //grade sum / credit hours sum, to 2dp*/
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Hello and welcome! You are not required to answer with full programs, so you can chip off a lot of bytes like that. \$\endgroup\$ – Nissa Dec 12 '17 at 14:50
2
\$\begingroup\$

Java 1.8, 287 249 Bytes

-38 bytes thanks to Bumptious

Golfed

static String N(String[]j){float g=0;float b=0;for(int i=0;i<j.length;i+=2){g=((m(j[i])*Float.parseFloat(j[i+1])+g));b+=Double.parseDouble(j[i+1]);}return String.format("%.2f",g/b);}static float m(String l){return l.equals("F")?0:('E'-l.charAt(0));}

Ungolfed

interface C {
static void main(String[] z) throws Exception {
    String[] j = {"A", "4", "B", "3", "C", "2", "D", "1", "F", "1"};
    System.out.println(N(j));
}

static String N(String[] j) {
    float g = 0;
    float b = 0;
    for (int i = 0; i < j.length; i += 2) {
        g = ((m(j[i]) * Float.parseFloat(j[i + 1]) + g));
        b += Double.parseDouble(j[i + 1]);
    }
    return String.format("%.2f", g / b);
}

static float m(String l) {
    return l.equals("F") ? 0 : ('E' - l.charAt(0));
}
}
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Reduce length by using this? static float m(String l){return l.equals("F")?0:('E'-l.charAt(0));} \$\endgroup\$ – Bumptious Q Bangwhistle Dec 12 '17 at 10:04
1
\$\begingroup\$

Julia 0.6, 46 43 42 bytes

g%h=round(max.(69-Int.(g),0)⋅h/sum(h),2)

Try it online!

Explanation

Input format: g: vector of grades; h: vector of credit hours

  • g%h: Redefine % operator.
  • 69-Int.(g): Convert 'F','D','C','B','A' to -1,1,2,3,4 respectively for each element of g.
  • max.( ,0): Clamp range to 0:4 (element-wise).
  • The rest is simple vector math.
  • Rounding costs 9 bytes.
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.