Computation
Computations are typically done through functions.
So far, we have only shown one function which is the main function int main(void)
.
As a good practice (and is actually enforced in a strict ANSI C standard), a function body has two parts:
- Declarations: This part contains all the variables to be used by the function. It tells the compiler what type of memory cells are needed.
- Executables: This part contains the instructions on how to process the memory cells.
Main Function | |
---|---|
1 2 3 4 5 |
|
Assignment Statements
Syntax
<lvalue> = <expr>
NOTE:
=
means assign the result of evaluating the<expr>
into the location described by the<lvalue>
.<lvalue>
must be assignable.- The value being assigned is then returned as the result of the evaluation1.
The sequence of evaluation of an assignment is as follows:
- Evaluate
<lvalue>
into an assignable location. - Evaluate
<expr>
into a value. - Assign the value from (2) into the location from (1).
This sequence of operations allows us to evaluate an assignment that does not make sense mathematically: sum = sum + item
.
Mathematically, there is no such number that is equal to itself plus another number unless the other number is 0
.
As an assignment, the evaluation can be summarised in the diagram below.
Side Effect
One of the "note" on assignment is that
The value being assigned is then returned as the result of the evaluation.
This leads to the concept of cascaded assignment such as: a = b = c = 3 + 6;
.
In this case, the assignment proceed fro, right to left.
The code is functionally equivalent to: a = (b = (c = 3 + 6));
.
More explicitly, it is:
1 2 3 |
|
However, there is a more sinister part of this: a = 5 + (b = 3);
.
In this case, we first assign the value 3
to b
and then the entire expression is evaluated into 3
.
Next, we evaluate a = 5 + 3
as the result, which will assign the value 8
to a
.
This return value often called the "side effect" of an assignment. It is useful to assign the same initial value to multiple variables. However, you should avoid writing convoluted codes such as the sinister example above.
Invalid Assignments
In an assignment, the <lvalue>
must be an assignable location such as variable.
If you try to run the code below, you will encounter a compilation error lvalue required as left operand of assignment
.
1 2 |
|
Arithmetic Operations
The arithmetic operations in C can be summarised as the table below:
Arithmetic Operations
Code | Behaviour |
---|---|
x + y |
Add y to x |
x - y |
Subtract y from x |
x * y |
Multiply x and y |
x / y |
Divide x by y ; if both x and y are int , then truncate, otherwise operate as double |
x % y |
The remainder after x is divided by y |
x++ |
Return the value of x ; then increment x by 1 |
x-- |
Return the value of x ; then decrement x by 1 |
++x |
Increment x by 1 ; then return the value of x |
--x |
Decrement x by 1 ; then return the value of x |
Increment/Decrement
Note the order of the increment/decrement and return of value.
If the variable x
has a value of 3
, then after:
y = x++;
\(\rightarrow\)y
has a value of3
andx
has a value of4
.y = x--;
\(\rightarrow\)y
has a value of3
andx
has a value of2
.y = ++x;
\(\rightarrow\)y
has a value of4
andx
has a value of4
.y = --x;
\(\rightarrow\)y
has a value of2
andx
has a value of2
.
When multiple operations are used in a single expression, the order of evaluation follows the operator precedence.
Operator Precedence
Precedence | Kinds | Operators | Associativity | Examples |
---|---|---|---|---|
1 | Postfix Unary | ++ , -- |
Left to right | x-- , x++ |
2 | Prefix Unary | + , - , ++ , -- , & , * , (type) , ! |
Right to left | x = +4; , x = -23; , --x; |
3 | Multiplicative Binary | * , / , % |
Left to right | x * y , z % 2; |
4 | Additive Binary | + , - |
Left to right | x + y , z - 2; |
5 | Relational | <= , >= , < , > |
Left to right | x < y , z >= 2; |
6 | Equality | == , != |
Left to right | x != y , z == 2; |
7 | Conjunction | && |
Left to right | x == y && x == 1 |
8 | Disjunction | || |
Left to right | x == y || x == 1 |
9 | Assignment | = , += , -= , *= , /= , %= |
Right to left | x += y , z = 2; |
The operators with the lower precedence are evaluated first. Since there can be multiple operators with the same precedence, the associativity is used to resolve the order.
Parentheses
If you are not sure about the precedence, parentheses can be used to force a certain ordering. As a good practice, you should write parentheses whenever you are in doubt.
One way to easily evaluate any expression is to put parentheses around the operands based on the precedence above.
For instance, given the expression 5 - 6 * 7 + 4 / 5
, we repeatedly put parentheses using the precedence table from lowest precedence to largest precedence.
If there are operators on the same precedence level, we resolve by associativity.
Precedence Resolution and Evaluation
Precedence Resolution | |
---|---|
1 2 3 4 5 |
|
Evaluation | |
---|---|
1 2 3 4 5 |
|
Evaluation Order
"Left-most innermost"
To show the arithmetic operation in action, we will use the program ArithOps.c
below:
Arithmetic Operations
ArithOps.c | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Division and Remainder
When we perform operations with different numeric types (i.e., combinations of int
and either float
or double
), the result follow the most general type.
Since technically all whole numbers can be represented as real numbers by adding .0
at the end, float
and double
are considered more general than int
.
In the case of division where both operands are int
, we also expect the result to be int
.
This resulting int
is obtained by simply truncating the values after the decimal point.
Such division operation is called integer division.
Not to be confused with Python's floor division.
Division Operation
z |
x |
y |
z = x/y |
---|---|---|---|
int |
10 |
4 |
z = 2 |
int |
10 |
4.0 |
z = 2 |
int |
10.0 |
4 |
z = 2 |
int |
10.0 |
4.0 |
z = 2 |
double |
10 |
4 |
z = 2.0 |
double |
10 |
4.0 |
z = 2.5 |
double |
10.0 |
4 |
z = 2.5 |
double |
10.0 |
4.0 |
z = 2.5 |
x |
y |
C: x/y |
C: x/y |
Python: x//y |
Python: x%y |
---|---|---|---|---|---|
10 |
4 |
2 |
2 |
2 |
2 |
10 |
-4 |
-2 |
2 |
-3 |
-2 |
-10 |
4 |
-2 |
-2 |
-3 |
2 |
-10 |
-4 |
2 |
-2 |
2 |
-2 |
Note: Python //
division is a floor division.
The result is the integer smaller than or equal to the result.
Type casting may also affect the division operation. But since type cast operation has a very high precedence, we have to be careful with the order of operation.
Type Cast
TypeCast.c | |
---|---|
1 2 3 4 5 6 7 8 |
|
Selection
C provides two control structures that allow you to select a group of statements to be executed or skipped when certain conditions are met.
The conditions are expressions that are evaluated to Boolean values (i.e., either true
or false
2).
They are usually composed of expressions combined with relational operators and logical operators.
Boolean
You may have noticed that both true
and false
are not part of reserved keywords.
This is because they are indeed not.
To actually use these keywords, you will need to include the Boolean library using #include <stdbool.h>
.
The type of Boolean values in C is called bool
.
If you do not wish to include the Boolean library, you may use the following macro expansion:
Boolean | |
---|---|
1 2 3 |
|
As the Boolean macro expansion above shows, true
is equal to 1
and false
is equal to 0
.
However, any non-zero values are treated as true.
But note, non-zero values except 1 is not equal to true
.
This will be made clear below.
Arithmetic Operations
Relational | Interpretation |
---|---|
< |
Less than |
<= |
Less than or equal to |
> |
Greater than |
>= |
Greater than or equal to |
== |
Equal to |
!= |
Not equal to |
Comparison with JavaScript and Python
Unlike JavaScript, there is no such thing as "strict" equality (i.e., ===
) or inequality (i.e., !==
).
Also, if you are coming from Python, you might find that 1 <= x <= 5
has a wildly different meaning than in Python.
In C, relational operators are treated like any other operators so the expression above is equivalent to (1 <= x) <= 5
.
In which case, you either get true <= 5
or false <= 5
depending on the value of x
.
Logical operators are used to combine two or more Boolean expressions. They can be used to form complex logical statements such as:
- If temperature is greater than 40C or blood pressure is greater than 200, then go to A&E immediately.
- If all the three subject scores (English, Maths and Science) are greater than 85 and mother tongue score is at least 80, recommend taking Higher Mother Tongue.
We usually summarise the logical operators using their truth table.
Truth Table
X |
Y |
X && Y |
X || Y |
!X |
---|---|---|---|---|
true |
true |
true |
true |
false |
true |
false |
false |
true |
false |
false |
true |
false |
true |
true |
false |
false |
false |
false |
true |
X |
X && Y |
X || Y |
!X |
---|---|---|---|
true |
Y |
true |
false |
false |
false |
Y |
true |
Short-Circuit
The main difference between short-circuit truth table and the basic truth table is whether the variable/expression represented by Y
is going to be evaluated or not.
In the case of &&
, Y
is only evaluated when X
is true
and in the case of ||
, Y
is evaluated only when X
is false
.
This allows for a "safe" execution especially in the case where the evaluation of Y
may result in an error.
Consider the case of finding an inverse of a number (i.e., 1/x).
x cannot be 0 because we cannot divide by zero.
We can safeguard this using short-circuit evaluation:
Short-Circuit
Safe Inverse | |
---|---|
1 2 3 |
|
It is important to note that the result of relational and logical operators are always Boolean.
In other words, it will always be either true
or false
.
Non-Zero
We mentioned that any non-zero values are treated as true but only 1 is equal to true
.
What do we mean by that?
We will illustrate this with examples instead.
The first example below shows how we can evaluate a logical operation above using non-zero values.
Non-Zero as True
NonZeroTrue.c | |
---|---|
1 2 |
|
To evaluate both lines, we first find the corresponding Boolean values:
5
:true
0
:false
-1
:true
We then convert the expressions using the Boolean:
- Line 1:
true && false
⇝false
- Line 2:
true || false
⇝true
As we print this as integer %d
, we convert the Boolean back to integer:
false
:0
true
:1
The second example below shows how these non-zero values --although treated as true-- are not equal to true
unless the value is 1.
While we did not mention false
, it should be clear that is will be equal to 0.
True is One
TrueIsOne.c | |
---|---|
1 2 3 4 5 |
|
The main part here is line 2 and line 5.
At line 5, we show that -1 is treated as true because otherwise the output will not be true
or 1
.
However, we cannot equate -1 with true
using -1 == true
.
This will instead produce false
.
Quick Quiz
What are the values of x
, y
and z
?
1 2 3 4 5 |
|
x
istrue
but there is a warning from the compiler. This warning is because&&
has higher precedence than||
so the warning is for programmers who may not know this precedence.y
istrue
false
and it is always good to add parentheses for readability. Note, it should befalse
, the previous version of this is wrong as it puttrue
instead. The run on ReplIt should be taken as a base answer in case of discrepancy.z
istrue
.
Selection Statement
If-Statement
If-Statement
If | |
---|---|
1 2 3 |
|
If-Else | |
---|---|
1 2 3 4 5 |
|
Unlike Python, there is no elif
.
The magic here is that the curly bracket is optional if there is only one statement within the block.
Since an if
is technically a single statement, there is no need for curly bracket between else
and if
.
Else-If | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
This flowchart uses the code from "Elif" tab.
Absolute Value
The absolute value of a number n, written as |n|, is the magnitude of the number. In other words, it is how far the number is from 0 in the number line. This value is always positive. For instance, the magnitude of 5, denoted by |5|, is simply 5. On the other hand, the magnitude of -10, denoted by |-10| is simply 10.
Write a C program to read a single integer input and print the absolute value of the number.
The idea is to check if the number is negative. If it is, we then convert it to a positive value by multiplying it with -1.
Answer | |
---|---|
1 2 3 4 5 6 |
|
Switch-Case
Switch-Case
Switch | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
- Variable or expression in
variable_or_expression
must be of discrete type (_usuallychar
orint
). value1
,value2
,value3
, ... need not be in any particular order.- There can be 0 or more
case
. - There can be 0 or 1
default
. - If there is
default
, it must be after all thecase
.
This flowchart uses the code from "Syntax" tab.
Chess
With the rise in popularity the Netflix series Queen's Gambit, you decide to write a program that can partially read a chess notation. In this case, you are simply going to read a single character and print the corresponding chess piece according to the following table. The symbol is provided simply to show you what the piece looks like.
Character | Piece | Symbol |
---|---|---|
'K' |
King | ♚ |
'Q' |
Queen | ♛ |
'R' |
Rook | ♜ |
'B' |
Bishop | ♝ |
'N' |
Knight | ♞ |
How do you read a single character?
The placeholder is %c
.
Also, don't forget the break;
to avoid spill over to the next case.
Answer | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Repetition
Repetition Statement
C provides three control structures that allow you to select a group of statements to be executed repeatedly.
While-Loop
While-Loop
While-Loop | |
---|---|
1 2 3 |
|
This flowchart uses the code from "Syntax" tab.
Sum to 10
Consider a code to sum a number from 1 to 10.
Sum1To10_While.c | |
---|---|
1 2 3 4 5 |
|
Do-While-Loop
Do-While-Loop
Do-While-Loop | |
---|---|
1 2 3 |
|
This flowchart uses the code from "Syntax" tab.
Sum to 10
Consider a code to sum a number from 1 to 10.
Sum1To10_DoWhile.c | |
---|---|
1 2 3 4 5 |
|
While vs Do-While vs For
Do while loop always perform the body
at least once.
So the difference might be subtle and only on the corner cases.
This is best illustrated by the image on the left.
Additionally, as you may have guessed, a for-loop can be converted to a while-loop simply by
- moving
init
to before the for-loop, and - moving
update
to afterbody
inside the loop
Although you are mostly correct, the behaviour can differ in a subtle way when we take into account break
and continue
.
For-Loop
For-Loop
For-Loop | |
---|---|
1 2 3 |
|
This flowchart uses the code from "Syntax" tab.
Sum to 10
Consider a code to sum a number from 1 to 10.
Sum1To10_For.c | |
---|---|
1 2 3 4 |
|
Break and Continue
There are two statements that can be used within a repetition structures:
break
: This statement exits the nearest loop. In other words, it jumps out of the nearest loop3.continue
: This statement continues to the end of the loop body. In other words, it jumps to just after the last line of the body of the nearest loop but before going back to the top.
Break, Continue, For
As you will see in the examples below, there is a difference in the behaviour of continue
between for-loop and while-loop (or do-while-loop).
The difference is subtle and it involves the update
component of the for-loop.
When a continue
is executed, we do jump to the end of the loop body.
However, the update
is performed after the loop body.
As such, the update
is still going to be executed and not skipped when using continue
.
On the other hand, if we do a rewriting as follows:
1 2 3 |
|
1 2 3 4 5 |
|
If there is a continue
in the body
, the for-loop version will still execute the update
but the while-loop version will not execute the update
.
Break
BreakInLoop.c | |
---|---|
1 2 3 4 5 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
BreakInLoop.c | |
---|---|
1 2 3 4 5 6 7 |
|
BreakInLoop.c | |
---|---|
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 |
|
BreakInLoop.c | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
BreakInLoop.c | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Continue
ContinueInLoop.c | |
---|---|
1 2 3 4 5 |
|
1 2 3 4 5 6 7 8 9 10 11 |
|
ContinueInLoop.c | |
---|---|
1 2 3 4 5 6 7 |
|
ContinueInLoop.c | |
---|---|
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 7 8 9 10 |
|
ContinueInLoop.c | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
ContinueInLoop.c | |
---|---|
1 2 3 4 5 6 7 8 9 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Exercises
Arithmetic
Celcius to Fahrenheit
We can convert a temperature given in Celcius to Fahrenheit using the following formula:
T°F = T°C × 9 ÷ 5 + 32
The operation precedence is the normal precedence. Write a program to read the temperature given in Celcius as integer and print the corresponding temperature in Fahrenheit printed to two decimal places.
Sample Run 1
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Sample Run 2
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Sample Run 3
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Did you ensure that you are not doing integer division? How would you prevent doing integer division?
There are many ways, the two common ways are:
(double) x/y
x*1.0/y
Note that x/y*1.0
does NOT work because we perform x/y
first which already gives us integer before changing it to double.
How do you print 2 decimal places?
The placeholder is %.2f
.
Answer | |
---|---|
1 2 3 4 5 |
|
Note at line 4 (highlighted above), we multiply by 9.0
to ensure that we are not performing integer division.
Fahrenheit to Celcius
We can convert a temperature given in Fahrenheit to Celcius using the following formula:
T°C = (T°F - 32) × 5 ÷ 9
The operation precedence is the normal precedence. Write a program to read the temperature given in Fahrenheit as integer and print the corresponding temperature in Celcius printed to two decimal places.
Sample Run 1
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Sample Run 2
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Sample Run 3
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Did you ensure that you are not doing integer division? How would you prevent doing integer division?
There are many ways, the two common ways are:
(double) x/y
x*1.0/y
Note that x/y*1.0
does NOT work because we perform x/y
first which already gives us integer before changing it to double.
How do you print 2 decimal places?
The placeholder is %.2f
.
Did you ensure the correct order of operation?
The subtraction should be performed before multiplication.
So, you need parentheses (x - 32) * y
.
Without the parentheses (i.e., x - 32 * y
), you will be performing multiplication before subtraction.
Answer | |
---|---|
1 2 3 4 5 |
|
We put parentheses around the subtraction to ensure that it is performed first.
Selection Statement
Leap Year
According to NASA
What is a Leap Year?
It takes approximately 365.25 days for Earth to orbit the Sun — a solar year. We usually round the days in a calendar year to 365. To make up for the missing partial day, we add one day to our calendar approximately every four years. That is a leap year.
A leap year can be checked by doing arithmetic operation on the year as follows:
- If the year is divisible by 4, then it is a leap year.
- EXCEPT:
- If the year is also divisible by 100, then it is common year.
- EXCEPT:
- If the year is also divisible by 400, then it is a common year.
- Otherwise it is a common year.
Write a C program to read a single integer input and print "Common Year" if the year is a common year and print "Leap Year" if the year is a leap year.
Sample Run 1
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Divisible by 4 and it is a leap year.
Sample Run 2
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Although it is divisible by 4, it is also divisible by 100. So it is a common year.
Sample Run 3
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Although it is divisible by 4 and divisible by 100, it is also divisible by 400. So it is a leap year.
How do you check if a number x
is divisible by another number y
?
x % y == 0
Which check is the most relevant to check for leap year?
Checking divisibility by 400 first because this number will definitely be disivible by 100 and 4. If so, then definitely a leap year.
Then the second most relevant is divisibility by 100 because such number will also be divisible by 4 (since 4 × 25 = 100). If so, then definitely a common year assuming we have ruled out divisibility by 400.
Lastly, we simply check divisibility by 4 to determine the remaining possibilities.
Answer | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 |
|
BMI
According to the CDC, the formula for computing the BMI is as follows:
BMI Formula
weight ÷ (height)2
The weight is given in kg and the height is given in m. Once you have computed the BMI, we can check the categories:
- Underweight if the BMI is less than 18.5.
- Normal if the BMI is greater than or equal to 18.5 but less than 25.0.
- Overweight if the BMI is greater than or equal to 25.0 but less than 30.0.
- Obese if the BMI is greater than or equal to 30.0.
Write a program that accepts two inputs: weight in kg and height in m. Both inputs are real numbers and given in a single line. The program should output the category.
Sample Run 1
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
The BMI is 20.8.
Sample Run 2
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
The BMI is 26.1.
Sample Run 3
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
The BMI is 31.2.
How do you perform squaring?
Simply height * height
.
But you need to do this first before dividing weight
by this.
Alternatively, divide twice:
weight / height / height
.
Answer | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Repetition Statement
3n+1
This problem is also called the Collatz Conjecture. We start with a simple computation given an input n:
- If n is even, the next value of n is n ÷ 2.
- If n is odd, the next value of n is 3 × n + 1.
The conjecture states that starting from any positive n (i.e., n ≥ 1), the value of n will eventually reach 1. This has been checked for very large numbers but has never been proven. What we want to know is how many steps until we reach 1.
Write a program that reads a single integer and print the number of steps until the number reaches 1. You are guaranteed that the input will be at least 1.
Sample Run 1
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
3 ⇒ 10 ⇒ 5 ⇒ 16 ⇒ 8 ⇒ 4 ⇒ 2 ⇒ 1
Sample Run 2
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Sample Run 3
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
Already 1.
What kind of loop do you need?
While-loop. Unfortunately, because the input will be at least 1, using do-while-loop will perform the operation at least once which we should not do at all. You can also do for-loop by ignoring initialisation and update.
Answer | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 |
|
Average
Now for something slightly different. This problem is more of an input problem. The task is rather simple, we want to find the average of some numbers. The question is, how many numbers?
Well, that is also depend on the input. The input will consists of two parts:
- The first line is a single integer n ≥ 1.
- The next n lines are all real numbers.
- You have to find the average of these numbers.
- Print the average up to 2 decimal places.
Notice how we have not learnt about array yet. So, you cannot use them. Can you write a program to do this?
Sample Run 1
Input | |
---|---|
1 2 3 4 5 6 |
|
Output | |
---|---|
1 |
|
(1.1 + 1.2 + 1.3 + 1.4 + 1.5) ÷ 2 = 1.3
Without array, how do we store all these numbers?
We do not have to. The average is simply the total divided by how many numbers we have. So, we simply have to calculate the total as we read the number.
You are guaranteed that there will be at least two lines in the input.
Answer | |
---|---|
1 2 3 4 5 6 7 8 |
|
Harder Average
Now this is similar to the average problem. But to make this harder, we do not know how many numbers are there! Instead, we will read the number until we encounter any negative number. We then compute the average excluding this negative number.
You are guaranteed that there will be at least two lines on the input. Additionally, the input will not be zero.
Sample Run 1
Input | |
---|---|
1 2 3 4 5 6 |
|
Output | |
---|---|
1 |
|
(1.1 + 1.2 + 1.3 + 1.4 + 1.5) ÷ 2 = 1.3
How do we even read all these numbers?
Similar to before, we accumulate all values into the total. But we will not stop the iteration until we have read a negative number.
What kind of loop do you need?
Do-while-loop. This is the simplest because we have to read at least one number.
Answer | |
---|---|
1 2 3 4 5 6 7 8 9 10 |
|
Break and Continue
Efficient Prime Number
A prime number is a number that is divisible only by 1 and itself. Write a program to read in a number and print "prime" if the number is a prime number and print "composite" if the number is not a prime number. Can you do it efficiently?
Sample Run 1
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
9 = 3 × 3
Sample Run 2
Input | |
---|---|
1 |
|
Output | |
---|---|
1 |
|
When can you stop? How to stop?
We can simply stop when we have found a counter-example.
In this case, when we find that the number is a composite number.
We stop by using break;
.
How many checks do you need?
It may seem like you need to check n-2 times (from 2 to n-1). But you simply have to check √n times. The proof for this is left as an exercise as this is not the main topic for this exercise.
Answer | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Challenges
We will not give the answers for these challenges.
Normalised Average
Instead of a standard average, we will be computing the normalised average. Consider a sequence of numbers X1, X2, ..., Xn. We denote two important values:
- Xmax = max(X1, X2, ..., Xn)
- Xmin = min(X1, X2, ..., Xn)
For each number Xi, we scale this number by:
X'i = (Xi - Xmin) ÷ (Xmax - Xmin)
What we are computing is then the average of X'1, X'2, ..., X'n. The input is similar to the harder average problem. In other words, you do not know how many numbers are there. So, you cannot use array. Can you solve this?
For simplicity, you may assume that the number (except the negative one) will be between 1 and 1000 (inclusive).
Sample Run 1
Input | |
---|---|
1 2 3 4 5 6 |
|
Output | |
---|---|
1 |
|
Sample Run 2
Input | |
---|---|
1 2 3 4 5 6 |
|
Output | |
---|---|
1 |
|
Sample Run 2
Input | |
---|---|
1 2 3 4 5 6 |
|
Output | |
---|---|
1 |
|
-
Depending on the source you read, this return value of an assignment is either the main effect or the side effect. In most literature, a side effect is the effect on the memory due to the functional abstraction. As a function, we are only interested in the mapping between the input and the output. Any other behaviours (e.g., changes in memory), are considered side effect. ↩
-
If you are from Python, note that the first letter is in lowercase and not uppercase. ↩
-
Nearest is in terms of nesting. We either exit to the end or continue back to top of the inner-most loop that contains the
break
/continue
. ↩