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\$
5
  • 2
    \$\begingroup\$ @DevelopingDeveloper Please try to avoid Cumbersome I/O formats. \$\endgroup\$ Dec 11, 2017 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\$ Dec 11, 2017 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\$ Dec 11, 2017 at 17:25
  • 2
    \$\begingroup\$ Welcome to PPCG. Nice first question in my humble opinion. \$\endgroup\$
    – ElPedro
    Dec 11, 2017 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\$ Dec 11, 2017 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
\$\endgroup\$
1
  • \$\begingroup\$ @nimi - good point, I missed that bit. Fixed. \$\endgroup\$ Dec 11, 2017 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!

\$\endgroup\$
2
  • \$\begingroup\$ 69-ord(i) don't works \$\endgroup\$
    – Rod
    Dec 11, 2017 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, 2017 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
\$\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!

\$\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)

\$\endgroup\$
4
  • 2
    \$\begingroup\$ -3 bytes if you use Tr \$\endgroup\$
    – user73398
    Dec 11, 2017 at 18:31
  • 3
    \$\begingroup\$ This fails for second test case.It returns 1.85 because you count F=-1 \$\endgroup\$
    – ZaMoC
    Dec 11, 2017 at 18:43
  • 2
    \$\begingroup\$ Here is a 41bytes fix: N[(5-(LetterNumber@#2/. 6->5)).#/Tr@#,3]& \$\endgroup\$
    – ZaMoC
    Dec 11, 2017 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\$ Dec 11, 2017 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

\$\endgroup\$
3
  • \$\begingroup\$ At what point does search become golfier than parseInt? \$\endgroup\$
    – Neil
    Dec 11, 2017 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, 2017 at 18:25
  • \$\begingroup\$ Huh, I hadn't even noticed that there's no E... \$\endgroup\$
    – Neil
    Dec 11, 2017 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!

\$\endgroup\$
2
  • \$\begingroup\$ I think you mean LETTERS[-5] \$\endgroup\$ Dec 12, 2017 at 9:49
  • \$\begingroup\$ @user2390246 yes, of course. that was silly of me. \$\endgroup\$
    – Giuseppe
    Dec 12, 2017 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*/
}
\$\endgroup\$
1
  • \$\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, 2017 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));
}
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Reduce length by using this? static float m(String l){return l.equals("F")?0:('E'-l.charAt(0));} \$\endgroup\$ Dec 12, 2017 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.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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