Code Analysis
This page is incomplete. It does not cover all important aspects of this subject. Please keep this in mind when reading the page and add relevant information if possible. |
Code Analysis | ||||
Inquiry & Lab Event | ||||
Forum Threads | ||||
There are no tests available for this event | ||||
There are no images available for this event | ||||
There are no question marathons for this event | ||||
This event was not held recently in Division B | ||||
This event was not held recently in Division C |
Code Analysis is a Division B and Division C event that was first run as a trial event at the 2018 Virginia state tournament and at the 2019 Wisconsin state tournament. It was also run at the 2019 Massachusetts state tournament as Python Code Analysis, using Python as the target language rather than Java. At the 2020 Washington state tournament, it replaced Ping Pong Parachute. Competitors are asked to determine the output or error that a given piece of code outputs without running the code. Each team is allowed one 8.5"x11" double-sided reference sheet, or two single-sided reference sheets of the same size.
Contents
The Event
Teams are not allowed to bring electronic devices into the testing room. All code given will be in Java, but problems focus on general programming concepts as opposed to specific qualities of Java. Problems may be written in a variety of ways, such as a series of statements, a method to be called with specific arguments, or a complete program with a main() method. All inputs and values will be specified, and no external inputs are allowed. All code given will also be properly indented.
While problems may be written in different ways, there are only two types of answers that will be requested. The competitor will determine the output of the code as created by System.out.print(), System.out.printIn(), and/or System.out.format() if a problem has an output. Space will be provided for the competitor to write their answer, and if the answer depends on spacing then a grid will be given so the answer is aligned properly. However, if the code has an error, then the competitor will be asked to describe the run-time error that occurs when the code is run. The error message or exception type does not need to be reproduced, but the competitor must describe what goes wrong and how to correct it.
Subjectivity in Test Writing
Test writers are free to craft the test according to their own coding philosophies. Based on an informal survey of a half dozen 2018/2019 tests:
- some embrace obfuscation, while others stick to clean ("honest") code.
- nearly all tests have at least one problem with recursion, although this recursion often ends up being simple single-branch nesting of no more than 3 levels.
- some tests emphasize mastery of printf and precise output formatting -- \n, whitespace, ASCII, etc. Other tests simply calculate numbers and print them, one per line.
- non-descriptive variable names and method names are very common -- i, x, n, foo, etc.
- some tests use nonsensical junk code with zero practical value. Other tests are full of real, usable code -- sorting, towers of hanoi, prime number calculations, etc.
Binary
Binary is the most basic form of data used by a computer. While most programs are not written in binary, it is important to have an understanding of how binary works. There are only two digits used in binary code - 0 and 1. Each number is known as a bit, and there are eight bits in a byte. Half a byte (4 bits) is also known as a nibble. Individual bits can be manipulated by bitwise operations, such as AND (&), OR (|), or XOR (^). Binary numbers are also known as bit strings, and when translated into decimal or hexadecimal numbers encode for specific data.
ASCII
Operators
Java can manipulate variables in a variety of ways using operators. An operator represents an action or a process, and return the result of that action being performed on one or more operands. The operand is the value which a given action is being performed on. Some operators appear much more frequently than others, but all have their own uses.
Arithmetic Operators
In most cases, arithmetic operators are the same as they are in algebra. However, Java has a couple of additional operators not typically found in math.
Operator | Description | Example |
---|---|---|
+ (Addition) | Adds values on either side of the operator. | 2 + 5 returns 7. |
− (Subtraction) | Subtracts the value on the right of the operator from the value on the left. | 2 - 5 returns -3. |
* (Multiplication) | Multiplies values on either side of the operator. | 2 * 5 returns 10. |
/ (Division) | Divides the value on the left side of the operator by the value on the right. | 10 / 5 returns 2. |
% (Modulus) | Divides the value on the left side of the operator by the value on the right and returns the remainder. | 10 % 3 returns 1. |
++ (Increment) | Increases the value of the operand by 1. | 5++ returns 6. |
−− (Decrement) | Decreases the value of the operand by 1. | 5-- returns 4. |
Relational Operators
Relational operators show the relationships between two values. All relational operators return a boolean, meaning that they are either true or false. Some of these are also found in algebra, just like the arithmetic operators.
Operator | Description | Example |
---|---|---|
== (Equal To) | Checks if the values on either side of the operator are equal to each other, and if they are then it returns true. | 2 == 5 returns false. |
!= (Not Equal To) | Checks if the values on either side of the operator are not equal to each other, and if they are not then it returns true. | 2 != 5 returns true. |
> (Greater Than) | Checks if the value of the left operand is greater than the right operand, and if it is it returns true. | 2 > 5 returns false. |
< (Less Than) | Checks if the value of the left operand is less than the right operand, and if it is it returns true. | 2 < 5 returns true. |
>= (Greater Than Or Equal To) | Checks if the value of the left operand is greater than or equal to the right operand, and if it is it returns true. | 2 >= 2 returns true. |
<= (Less Than Or Equal To) | Checks if the value of the left operand is less than or equal the right operand, and if it is it returns true. | 2 <= 5 returns true. |
Boolean Operators
Compares two boolean variables and returns a boolean.
Operator | Description | Example |
---|---|---|
| (OR) | Will return true if either boolean condition is true. Will return false if both conditions are false. | If bool1 is true and bool2 is false, then bool1 | bool2 is true. |
& (AND) | Will return true if both boolean conditions are true. Otherwise, it will return false. | If bool1 is true and bool2 is false, then bool1 & bool2 is false. |
^ (XOR) | Will return true if one, but not both, of the boolean conditions is true. Will return false if both conditions are true or false. | If bool1 is true and bool2 is true, then bool1 ^ bool2 is false. |
! (NOT) | Flips the boolean value. | If bool1 is false, then !bool1 is true. |
De Morgan’s Law
Given that A and B are both boolean variables, De Morgan’s Law states that
- [math]!(A \& B) == !A \| !B[/math]
and
- [math]!(A \| B) == !A \& !B[/math]
Short-Circuit Operators
Short circuit operators will not evaluate the second part of a boolean operation if it isn’t necessary. It is written in code as || for OR operations and && for AND operations.
An example, if the condition being evaluated is A || B and A is true, then regardless what B is, A || B will be true, so the computer doesn’t evaluate B. For the expression A && B and A was false, then the expression would return false regardless of what B is.
The reason why a short-circuit for XOR doesn’t exist is because if you evaluate A ^ B, if A is either true or false, the value B still needs to be evaluated to see whether the expression A ^ B returns true or false.
Bitwise Operators
NOTE: All bitwise evaluations are done in binary. They all return the primitive number type (int, long, byte, char) back.
Operator | Description | Example |
---|---|---|
| (OR) | Compares each binary digit and if either digit is a 1, then it gives back a 1. Otherwise it gives back a 0. | 7_{10} | 18_{10} = 111_{2} | 10010_{2} = 10111_{2} = 23_{10} |
& (AND) | Compares each binary digit and if both digits is a 1, then it gives back a 1. Otherwise it gives back a 0. | 7_{10} & 18_{10} = 111_{2} & 10010_{2} = 10_{2} = 2_{10} |
^ (XOR) | Compares each binary digit and if only one of the digits is a 1, then it gives back a 1. Otherwise it gives back a 0. | 7_{10} ^ 18_{10} = 111_{2} ^ 10010_{2} = 10101_{2} = 21_{10} |
~ (NOT/Complement) | For each digit, it sets each 1 to 0 and each 0 to 1. | ~18_{10} = ~10010_{2} = 1101_{2} = 13_{10} |
>> (Right Shift) | Shifts all the bits to the right. Preserves the sign, meaning it keeps the same number of binary digits. | 10>>1=5 since 1010_{2} shifted to the right 1 is 0101_{2} which is 5_{10}. |
>>> (Unsigned Right Shift) | Shifts all the bits to the right. This is the unsigned version of the signed right shift. It doesn't keep the same number of binary digits. | 10>>1=5 since 1010_{2} shifted to the right 1 is 101_{2} which is 5_{10}. |
<< (Left Shift) | Shifts all the bits to the left. | 10<<1=20 since 1010_{2} shifted to the left 1 is 10100_{2} which is 20_{10}. |
Logical Operators
These operators are used to compare primitive data types. The operator must compare the same data type otherwise the program will throw a compiler error.
Operator | Description | Example |
---|---|---|
== (Equals) | Returns true if both primitives are of the same value. Otherwise, it returns false. |
int x = 0; if (x == 0) { //if x is equal to 0... System.out.println("This statement will print since x == 0 is true"); } else { //otherwise System.out.println("This statement will not print"); } |
!= (Does not equal) | Returns true if both primitives are of different values. Otherwise, it returns false. |
int x = 10; if (x != 0) { // if x is not equal to 0... System.out.println("This statement will print since x != 0 is true"); } else { // otherwise... System.out.println("This statement will not print"); } |
> (Greater than) | Returns true if the primitive on the left side is larger than the primitive on the right side. Otherwise, it returns false. |
int x = 10; boolean isXGreaterThanZero = x > 0; // You can use logical operators and assign the return value to a boolean! if (isXGreaterThanZero) { // if x is greater than 0... System.out.println("This statement will print since x > 0 is true"); } else { // otherwise... System.out.println("This statement will not print"); } |
>= (Greater than or equal to) | Returns true if the primitive on the left side is larger than or equal to the primitive on the right side. Otherwise, it returns false. |
int x = 10; if (x >= 10) { // if x is greater than or equal to 10... System.out.println("This statement will print since x >= 10 is true"); } else { // otherwise... System.out.println("This statement will not print"); } |
< (Less than) | Returns true if the primitive on the left side is smaller than the primitive on the right side. Otherwise, it returns false. |
int x = -400; if (x < 2000) { // if x is less than 2000... System.out.println("This statement will print since x < 2000 is true"); } else { // otherwise... System.out.println("This statement will not print"); } |
<= (Less than or equal to) | Returns true if the primitive on the left side is smaller than or equal to the primitive on the right side. Otherwise, it returns false. |
int x = -300; if (x <= -24) { // if x is less than or equal to -300... System.out.println("This statement will print since x <= -24 is true"); } else { // otherwise... System.out.println("This statement will not print"); } |
Assignment Operators
Assignment operators allow data types to be assigned values.
Operator | Description | Example |
---|---|---|
= (Assignment) | It is used to set the value to a data type. Both primitives and Objects can use this operator. |
int x; // By default, Java sets uninitialized primitives to 0 x = 10; // x is now set to 10 System.out.println(x); // This will print 10 |
+= (Increment) | It is used to add some primitive value to itself. This is similar to doing x = x + y. This can only be used with PRIMITIVES. |
int x = 10; x += 20; System.out.println(x); // This will print 30 |
-= (Decrement) | It is used to subtract some primitive value to itself. This is similar to doing x = x - y. This can only be used with PRIMITIVES. |
int x = 10; x -= 20; System.out.println(x); // This will print -10 |
Miscellaneous Operators
Control Flow Statements
Conditional
If-Else
Switch
Loops
While
Do-While
For
For each
Data Types
Primitive
int
boolean
char
Object
String
Integer
Boolean
Arrays
Variables
Functions
Recursion
Types of Errors
Scoring
Each problem specifies its own worth. No one problem can be worth more than 20% of the total score possible.