Messing with the high school computer teacher



  • I'm taking the AP Java course at my high school, but have been programming for a long time previously.  Anyways, we read the chapter on boolean logic in conjunction with if statements.

    One of the programs assigned was to create a program which would take a number grade as input and print out the letter grade (96 -> A+, 65 -> D, 81 -> B-, etc.).

    I decided to mess with the computer teacher a little, and write the entire program without using an if statement.  The result is the following in valid java:

    import TerminalIO.*;
    public class YipFlou
    {

        public static void main(String[] args)
        {
            Boolean yipFlou = false;
            KeyboardReader keyboardReader = new KeyboardReader();
            int x = keyboardReader.readInt("X:? ");
            char z = ' ';
            yipFlou = (x >= 100 && (0==(x=99) || 'X'==(z = '+')) || (x < 60) && (0==(x = 40)) || (x < 60) || (((x%10 < 2) && ('X'==(z = '-'))) || (x%10 >= 6 && 'X'==(z = '+'))));
            char y = (char)((int)'E' - ((x - 50)/10));
            System.out.println(y + "" + z);
        }
    }


    I wrote the above code (of course using better variable names, and slightly more spread out, eventually refactoring to the above "most evil" edition.

    Note: TerminalIO is a helper package used by our book, and we just read from stdin to the variable "x" using it.

     

    I sent it to my computer teacher, to see if he could figure out what it does without compiling it.  He couldn't, but if that code arrived in front of me, I'm not sure I could either.
     



  • hurray for the ternary operator!

     

    public class asdf {
        public static void main(String[] args) {
            while (true) {
                Scanner in = new Scanner(System.in);
                System.out.println("Please enter a grade\n");
                int grade = in.nextInt();
                char append = ' ';
                int tens = grade / 10;
                int ones = grade % 10;
                char letter = (char) ((int) 'E' - ((tens >= 10) ? 4 : ((tens < 6) ? -1 : (tens - 5))));
                append = (tens >= 10) ? '+' : (tens <= 5) ? ' ' : (ones >= 6) ? '+' : (ones <= 2) ? '-' : ' ';
                System.out.print(letter + "" + append + "\n");
            }
        }
    }
     



  • I figured that on the scale of evilness, the ternary ranked too close to the if statement in terms of not being evil



  • yes, short circuit evaluation is much more evil.   I was just trying to make it pretty readable.



  • "if p then q" is logically equivalent to "q or not p".  The comma (sequencing operator) is nice too:

    if (p) {x = 5; y = strlen(z)} else {x = 7;}

    !p || (x = 5, y = strlen(z)); p || (x = 7);

     

     

     



  • Code like this makes me wonder why you didn't just right the whole thing as a binary expression. I'd need to see the table of values to be sure, but I would have thought it would be possible to write the entire thing without a single '||' or '&&' appearing.



  • Unless I was teaching Obfuscation 101, I'd have failed you. Properly written code is both correct and readable.



  • I can do it without any Ifs, Ands, Ors, or ternary operators - just pure math (and the odd string function).  I present the following in VB.Net ('cause I don't know any Java):

    <FONT size=2><FONT size=2>

    <FONT color=#0000ff>Dim</FONT><FONT size=2> Grade </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Integer</FONT><FONT size=2>
    </FONT>Console.Write(</FONT><FONT color=#a31515 size=2>"Enter Grade: "</FONT><FONT size=2>) : </FONT><FONT size=2>Grade = Console.ReadLine
    </FONT>Console.WriteLine( Chr(Math.Truncate((100 - Grade) / 15) + 65) & </FONT><FONT color=#0000ff size=2>CInt</FONT><FONT size=2>(Math.Truncate(3 - (((100 - Grade) </FONT><FONT color=#0000ff size=2>Mod</FONT><FONT size=2> 15) / 5)) - 1).ToString(</FONT><FONT color=#a31515 size=2>"+;-;"</FONT><FONT size=2>) )</FONT>

    <FONT size=2>For the Non-VB among you, Chr() is a function that takes an ASCII code (such as 65) and returns the associated character (such as "A").

    </FONT>


  • Stupid edit timeouts.  The last bit should be:

    <FONT size=2>

    .ToString(</FONT><FONT color=#a31515 size=2>"+;-; "</FONT><FONT size=2>))

    </FONT>


  • @Albatross said:

    I can do it without any Ifs, Ands, Ors, or ternary operators - just pure math (and the odd string function).  I present the following in VB.Net ('cause I don't know any Java):

    <font size="2"><font size="2">
    </font></font>

    <font size="2"><font size="2"><font color="#0000ff">Dim</font><font size="2"> Grade </font><font color="#0000ff" size="2">As</font><font size="2"> </font><font color="#0000ff" size="2">Integer</font><font size="2">
    </font>Console.Write(</font><font color="#a31515" size="2">"Enter Grade: "</font><font size="2">) : </font><font size="2">Grade = Console.ReadLine
    </font>Console.WriteLine( Chr(Math.Truncate((100 - Grade) / 15) + 65) & </font><font color="#0000ff" size="2">CInt</font><font size="2">(Math.Truncate(3 - (((100 - Grade) </font><font color="#0000ff" size="2">Mod</font><font size="2"> 15) / 5)) - 1).ToString(</font><font color="#a31515" size="2">"+;-;"</font><font size="2">) )</font>

    <font size="2">For the Non-VB among you, Chr() is a function that takes an ASCII code (such as 65) and returns the associated character (such as "A").</font>

    grade  = 1000000 



  • @tster said:

    @Albatross said:

    I can do it without any Ifs, Ands, Ors, or ternary operators - just pure math (and the odd string function).  I present the following in VB.Net ('cause I don't know any Java):

    <FONT size=2><FONT size=2></FONT></FONT>

    <FONT size=2><FONT size=2><FONT color=#0000ff>Dim</FONT><FONT size=2> Grade </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Integer</FONT><FONT size=2>
    </FONT>Console.Write(</FONT><FONT color=#a31515 size=2>"Enter Grade: "</FONT><FONT size=2>) : </FONT><FONT size=2>Grade = Console.ReadLine
    </FONT>Console.WriteLine( Chr(Math.Truncate((100 - Grade) / 15) + 65) & </FONT><FONT color=#0000ff size=2>CInt</FONT><FONT size=2>(Math.Truncate(3 - (((100 - Grade) </FONT><FONT color=#0000ff size=2>Mod</FONT><FONT size=2> 15) / 5)) - 1).ToString(</FONT><FONT color=#a31515 size=2>"+;-;"</FONT><FONT size=2>) )</FONT>

    <FONT size=2>For the Non-VB among you, Chr() is a function that takes an ASCII code (such as 65) and returns the associated character (such as "A").</FONT>

    grade  = 1000000 

    Hehe!

    I had to write the first programming example to get into a C++ class at my college. The object was to draw a triangle, like this:

    cout << "       *     ";

    cout << "     *  *    "; //etc

    He was not looking for this:

    #include <iostream>
    #include <string>
    #include "stdafx.h"
    using namespace std;

    void DrawTriangle(int w); //declaring function

    void DrawTriangle(int w)  // actual function
    {
        int wide = w;    // width in characters
        int i = 0;
        int j = 0;
        string starz = ""; //holds the string to be output to console

        for (i=1; i<((wide+1)/2); ++i)  //draws the single star on top
        {
                starz += " ";       
        }
        starz += "*";
        cout << starz << endl;
       
        for (i = 1; i<(((wide + 1)/2)-1); ++i) // draws the legs of the triangle
        {                                      
            starz = "";
            for (j = 0; j < (((wide-1)/2)-i); ++j) //draws left star
            {
                starz = starz + " ";
            }
            starz = starz + "*";
            for (j = 0; j < 2*i-1; ++j) // draws right star
            {
                starz = starz + " ";
            }
            starz = starz + "*";
            cout << starz << endl;
        }
        starz = "";
        for (i=0; i < wide; ++i) //draws the base of the triangle
        {
            starz += "*";
        }
        cout << starz << endl;

    }


    int _tmain(int argc, _TCHAR* argv[]) //i have no idea why it uses _tmain. VS2003...
    {
        int width = 0;
        bool errr = true;
        while (errr)                //make sure the user enters an odd number
        {
            cout << "Enter base width(must be an odd number): ";
            cin >> width;
            if ((width%2) == 0)
            {
                cout << "An odd number is one that is not divisible by 2!" << endl << endl;
                errr = true;
            }       
            else
            {
                errr = false;
            }
        }   
        cout << "calling the DrawTriangle function..." << endl << endl << endl;
        DrawTriangle(width);
        cout << endl << endl << endl << "returned from the DrawTriangle function." << endl;

        return 0;
    }

    Mind you, this was the first C++ app i had ever written.



  • I remember a "Fox Trot" comic strip in which Jason's teacher assigned the following problem:  Farmer Jones has a rectangular field 100 feet wide and 200 feet long.  What is the area of the field in square feet?

    Jason uses calculus to find the area under the curve "y = 200" for the interval 0 <= x <= 100.

    That's the first page of what he hands in.  The next 99 pages are a proof that his method yielded the correct result.

     



  • Found a nice way! 

    #include <stdio.h>
    /**
     * Computes the grade of a student according to the following table:
     * 0-59  : F
     * 60-63 : D-
     * 64-66 : D
     * 67-69 : D+
     * 70-73 : C-
     * 74-76 : C
     * 77-79 : C+
     * 80-83 : B-
     * 84-86 : B
     * 87-89 : B+
     * 90-94 : A-
     * 95-100: A
     * Usage: grades [INT_SCORE]
     */

    static const unsigned int A_LEN = 7;
    static const unsigned int D_LEN = 5;

    void usage(const char *progname) {
        printf("usage: %s [INT_SCORE]\n",progname);
    }

    int main(int argc, const char** argv)
    {       
        //No grade supplied? Usage and quit
        if (argc < 2) {
            usage(argv[0]);
            return 1;
        }
       
        unsigned int grade, h[A_LEN], dec[D_LEN], imod;
        char modc, gradec;

        //Parse grade
        grade = atoi(argv[1]);
        if (grade == 0) {
            printf("Either you supplied 0 or something invalid, can't really tell since atoi() sucks...\nGonna stick with 0.\n");
        }

        //Initialize inputs by bytifying int score (waste of memory) 
        for (int i=0; i<A_LEN; i++) {
            h[i] = ((grade >> (A_LEN-i-1))&1);
        }
        //Compute transformation to grade space ;)
        dec[0] =
            (!h[0]&&!h[1]) ||
            (!h[0]&&!h[2]) ||
            (!h[0]&&!h[3]) ||
            (!h[0]&&!h[4]);
        dec[1] =
            (h[1]&&h[2]&&h[3]&&h[4]) ||
            (h[0]&&!h[1]&&!h[2])     ||
            (h[0]&&h[1]&&h[2])       ||
            (h[0]&&h[1]&&h[3])       ||
            (h[0]&&!h[2]&&h[3]);
        dec[2] =
            (!h[1]&&!h[3]&&!h[4]) ||
            (!h[1]&&!h[3]&&!h[5]) ||
            (h[1]&&h[4]&&h[5])    ||
            (h[1]&&h[4]&&h[6])    ||
            (h[2]&&!h[4]&&!h[5])  ||
            (h[1]&&h[3])          ||
            (h[2]&&!h[3])         ||
            !h[0];
        dec[3] =
            (!h[1]&&h[2]&&h[3]&&h[4]&&h[5]&&h[6]) ||
            (!h[2]&&h[3]&&h[4]&&!h[5]&&!h[6])     ||
            (!h[2]&&!h[3]&&!h[4]&&!h[5])          ||
            (!h[2]&&!h[3]&&!h[4]&&!h[6])          ||
            (!h[2]&&h[3]&&!h[4]&&h[5])            ||
            (!h[2]&&!h[4]&&h[5]&&!h[6])           ||
            (h[2]&&!h[3]&&h[4]&&!h[5])            ||
            (h[2]&&!h[3]&&h[4]&&!h[6])            ||
            (!h[0]&&!h[1])                        ||
            (!h[0]&&!h[2])                        ||
            (!h[0]&&!h[3])                        ||
            (!h[0]&&!h[4])                        ||
            (h[0]&&h[1])                          ||
            (h[1]&&!h[2])                         ||
            (h[1]&&!h[3])                         ||
            (h[1]&&!h[4]);
        dec[4] =
            (h[0]&&!h[2]&&!h[3]&&h[4]&&h[5])   ||
            (h[0]&&!h[2]&&h[3]&&!h[4]&&!h[5])  ||
            (h[0]&&h[2]&&h[3]&&h[4]&&!h[5])    ||
            (h[0]&&h[2]&&h[3]&&h[4]&&!h[6])    ||
            (h[0]&&h[2]&&h[3]&&h[5]&&!h[6])    ||
            (h[0]&&h[1]&&h[4]&&h[5])           ||
            (h[0]&&h[1]&&h[4]&&h[6])           ||
            (h[0]&&h[2]&&!h[3]&&!h[4])         ||
            (h[0]&&h[2]&&!h[4]&&h[5])          ||
            (h[1]&&h[2]&&h[3]&&h[4])           ||
            (h[0]&&h[1]&&h[2])                 ||
            (h[0]&&h[1]&&h[3]);
        //Compute integer modcode
        imod = (dec[3] << 1) + dec[4];
        //Convert to char
        modc = (char) (imod+43+(imod%2)+(imod/2*-13));
        //Compute grade
        gradec = (char) ((dec[0] << 2) + (dec[1] << 1) + dec[2] + 65);
        //Print the result
        printf("You've got the grade: %c%c",gradec,modc);
        return 0;
    }


     

     


     



  • If we're trying to avoid if's there's something like this in C#:

     

    <FONT size=2>

    </FONT><FONT color=#0000ff size=2>public</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>string</FONT><FONT size=2> GetGrade(</FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2> score)
    {
        </FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2>[] gradeMaximumsArray = { 59, 63, 66, 69, 73, 76, 79, 83, 86, 89, 94, 100 };
        </FONT><FONT color=#0000ff size=2>string</FONT><FONT size=2>[] grades = { </FONT><FONT color=#800000 size=2>"F"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"D-"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"D"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"D+"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"C-"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"C"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"C+"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"B-"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"B"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"B+"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"A-"</FONT><FONT size=2>, </FONT><FONT color=#800000 size=2>"A"</FONT><FONT size=2> };

    </FONT><FONT color=#008080 size=2>    List</FONT><FONT size=2><</FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2>> gradeList = </FONT><FONT color=#0000ff size=2>new</FONT><FONT size=2> </FONT><FONT color=#008080 size=2>List</FONT><FONT size=2><</FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2>>(gradeMaximumsArray);

    </FONT><FONT color=#0000ff size=2>    int</FONT><FONT size=2> i = gradeList.FindIndex(</FONT><FONT color=#0000ff size=2>delegate</FONT><FONT size=2>(</FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2> test)
                                              {
                                                   </FONT><FONT color=#0000ff size=2>return</FONT><FONT size=2> score < test;
                                              });

    </FONT><FONT color=#0000ff size=2>    if</FONT><FONT size=2> (i == -1)
    </FONT><FONT color=#0000ff size=2>        throw</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>new</FONT><FONT size=2> </FONT><FONT color=#008080 size=2>ArgumentException</FONT><FONT size=2>(</FONT><FONT color=#008080 size=2>String</FONT><FONT size=2>.Format(</FONT><FONT color=#800000 size=2>"Supplied a score higher than {0}"</FONT><FONT size=2>, gradeBreakpoints[gradeBreakpoints.Length - 1]));

    </FONT><FONT color=#0000ff size=2>    return</FONT><FONT size=2> grades[i];
    }</FONT>

    <FONT size=2>(Well, ok, I guess I used one there at the end)</FONT>

    <FONT size=2>-cw

    </FONT>

Log in to reply