7.9 Writing and Amending Algorithms

Question Bank · 7 Questions

Objectives: Students should be able to —

  • 1 Write, amend and correct errors in flowcharts.
  • 2 Write, amend and correct errors in programs.
  • 3 Write, amend and correct errors in pseudocode.
  • 4 Describe the stages of designing and constructing an algorithm.
  • 5 Use 1D and 2D arrays, nested loops, CASE and REPEAT-UNTIL in algorithms.
  • 6 Use procedures (SUB) and functions with parameters and return values.
  • 7 Apply pre-defined functions: LEN(X), LENGTH(X), ROUND(X, n), UPPER(X), LOWER(X), SUBSTRING(X, start, len).
  • 8 Use meaningful names and comments to make code readable.
  • 9 Use test data (normal, abnormal, boundary) and trace tables to validate algorithms.

Stages of Designing and Constructing an Algorithm

Method: The ten sequential stages of designing and constructing an algorithm are —

  1. Analyse the problem and make sure that you understood it properly.
  2. Determine what would be the — Inputs, Processes and Outputs.
  3. Break down the problem into sub-problems if it is complex.
  4. Write down all the steps needed to solve the problem sequentially from start to end.
  5. Determine what variables and constants need to be declared and initialised to set up the program.
  6. Determine the sequential statements and compound statements (like selection and looping) need to be used.
  7. Construct your algorithm using either flowchart or pseudocode designing tools.
  8. Making sure that it can be easily read and understood by others. Use meaningful names for variables and constants.
  9. Use several sets of test data (normal, abnormal and boundary) and trace tables to find any errors in your algorithm.
  10. Debug the errors if found, and test your algorithm until it works perfectly to produce the desired output.

Algorithms using Arrays, Nested Loops and CASE

(a) Pseudocode algorithm — uses a nested FOR loop (outer: 4 subjects; inner: 600 students), CASE OF to switch subject name and a REPEAT-UNTIL range-check validation:

// Initialisation of variables for overall counters OverallHighest ← 0 OverallLowest ← 100 OverallTotal ← 0 FOR Test = 1 TO 4 // Outer loop for 4 subject tests // Initialisation of variables for subject counters SubjectHighest ← 0 SubjectLowest ← 100 SubjectTotal ← 0 CASE OF Test 1 : SubjectName ← "Maths" 2 : SubjectName ← "Science" 3 : SubjectName ← "English" 4 : SubjectName ← "IT" ENDCASE FOR NoStd = 1 TO 600 // Inner loop 600 times for each subject // Range check validation of marks between 0 and 100 REPEAT OUTPUT "Enter Student-", NoStd, "'s mark for ", SubjectName INPUT Mark UNTIL Mark >= 0 AND Mark <= 100 // Identifying and storing subject-wise and overall highest and lowest IF Mark > SubjectHighest THEN SubjectHighest ← Mark IF Mark > OverallHighest THEN OverallHighest ← Mark IF Mark < SubjectLowest THEN SubjectLowest ← Mark IF Mark < OverallLowest THEN OverallLowest ← Mark // Calculating and storing subject-wise and overall running total SubjectTotal ← SubjectTotal + Mark OverallTotal ← OverallTotal + Mark NEXT NoStd // Calculate and output subject-wise average, highest and lowest mark SubjectAverage ← SubjectTotal / 600 OUTPUT SubjectName OUTPUT "Average mark is ", SubjectAverage OUTPUT "Highest mark is ", SubjectHighest OUTPUT "Lowest mark is ", SubjectLowest NEXT Test // Calculate and output overall average, highest and lowest mark OverallAverage ← OverallTotal / 2400 OUTPUT "Overall Average mark is ", OverallAverage OUTPUT "Overall Highest mark is ", OverallHighest OUTPUT "Overall Lowest mark is ", OverallLowest

(b) Explain how you would test your algorithm:

For the algorithm to be tested by dry running, I would reduce the number of students to 5 and the number of subjects to 2.

Method: This reduces the total iterations from 4 × 600 = 2400 down to 2 × 5 = 10, making it practical to fill in a trace table by hand. Test data should include:

  • Normal data — marks within range (e.g., 55, 78, 92).
  • Boundary data — marks at 0 and 100 (the limits of the range check).
  • Abnormal data — marks outside range (e.g., -5, 105) to verify the REPEAT-UNTIL rejects them.

(a) Pseudocode algorithm to declare arrays and variables, and input the names and marks using nested FOR loops:

// Declaring 1D and 2D array DECLARE StudentName : ARRAY[1:100] OF STRING DECLARE StudentMark : ARRAY[1:100, 1:10] OF INTEGER // Declaring variables DECLARE ClassSize : INTEGER DECLARE SubjectNo : INTEGER // Input number of students and subjects OUTPUT "Enter the number of students : " INPUT ClassSize OUTPUT "Enter the number of subjects : " INPUT SubjectNo // Outer loop to repeat for each student FOR NoStd = 1 TO ClassSize OUTPUT "Enter the name of the student : " INPUT StudentName[NoStd] // Inner loop to repeat for each subject FOR NoSub = 1 TO SubjectNo OUTPUT "Enter the mark for subject-", NoSub, " : " INPUT StudentMark[NoStd, NoSub] NEXT NoSub NEXT NoStd

(b) Grading program — uses CONSTANT thresholds, nested FOR loop for totals, ROUND() pre-defined function and nested IF for grade selection:

The grade boundaries are —

Average mark Grade awarded
Average >= 70Distinction
Average >= 55 AND < 70Merit
Average >= 40 AND < 55Pass
Average < 40Fail
// Initialise constants for different average marks CONSTANT Distinction = 70 CONSTANT Merit = 55 CONSTANT Pass = 40 // Initialise variables to count the number of students with different grades NoDistinction = 0 NoMerit = 0 NoPass = 0 NoFail = 0 // Outer loop to repeat for each student of class FOR NoStd = 1 TO ClassSize StdTotal = 0 // Initialise variable to calculate total mark of each student // Inner loop to repeat for each subject FOR NoSub = 1 TO SubjectNo // Calculate total mark of each student StdTotal = StdTotal + StudentMark[NoStd, NoSub] NEXT NoSub // Calculate and round the average mark to its nearest whole number AverageMark = ROUND(StdTotal / SubjectNo, 0) // Check and store the grade awarded IF AverageMark >= Distinction THEN GradeAwarded = "Distinction" NoDistinction = NoDistinction + 1 ELSE IF AverageMark >= Merit THEN GradeAwarded = "Merit" NoMerit = NoMerit + 1 ELSE IF AverageMark >= Pass THEN GradeAwarded = "Pass" NoPass = NoPass + 1 ELSE GradeAwarded = "Fail" NoFail = NoFail + 1 ENDIF ENDIF ENDIF // Output the student's name, total mark, average and grade awarded OUTPUT StudentName[NoStd], " has score total mark ", StdTotal OUTPUT "Average mark ", AverageMark OUTPUT "He is awarded with grade ", GradeAwarded NEXT NoStd // Output the overall number of students awarded with different grade OUTPUT "Number of Distinctions = ", NoDistinction OUTPUT "Number of Merits = ", NoMerit OUTPUT "Number of Passes = ", NoPass OUTPUT "Number of Fails = ", NoFail

Password Algorithms — Validation, Procedures and Functions

Method: The algorithm uses a REPEAT-UNTIL loop controlled by a flag variable PassCheck and an attempt counter. It performs a length check using LEN() and a double-entry verification by comparing Password with Password2.

// Initialise a counter to try for 3 attempts Attempt ← 0 // Loop or repeat until correct password or attempt is 3 REPEAT // Tag a variable as TRUE PassCheck ← TRUE OUTPUT "Please enter your password : " INPUT Password IF LEN(Password) < 8 THEN // Tag as FALSE, if password is less than 8 characters. PassCheck ← FALSE ELSE OUTPUT "Please re-enter your password : " INPUT Password2 IF Password2 <> Password THEN // Tag as FALSE, if both password doesn't match. PassCheck ← FALSE ENDIF ENDIF Attempt ← Attempt + 1 UNTIL PassCheck OR Attempt = 3 IF PassCheck THEN // Output success if password is valid. OUTPUT "Password successful" ELSE OUTPUT "Password failed" ENDIF

Method: The main program uses a REPEAT-UNTIL loop that stops when Option = 4. It CALLs the DashBoard SUB procedure to display the menu, then uses CASE OF to dispatch each option. Option 2 and 3 CALL the PassChecker FUNCTION with parameters and use its return value.

// Initialisation of variables by storing some password Password ← "Johny4U" // Loop or repeat until option-4 to Quit REPEAT // Calling procedure to display the available options CALL DashBoard // Ask to input the option of their choice OUTPUT "Input the option between 1 and 4 : " INPUT Option CASE Option OF 1 : OUTPUT "Enter your new password : " INPUT NewPass Password = NewPass OUTPUT "New password is added successfully." 2 : OUTPUT "Enter the password to check : " INPUT CheckPass // Call the function to check both password matches // by assigning parameter to pass and get return value OUTPUT "Your password is ", PassChecker(CheckPass, Password) 3 : OUTPUT "Enter your old password : " INPUT OldPass // Call the function to verify and authenticate IF PassChecker(OldPass, Password) = "correct" THEN OUTPUT "Enter your new password : " INPUT NewPass OUTPUT "Your password is changed successfully." ELSE OUTPUT "Your old password is wrong." ENDIF 4 : OUTPUT "Thanks for using the program." OTHERWISE : OUTPUT "Invalid, re-enter the option." ENDCASE UNTIL Option = 4 // Procedure or sub-routine to display the available options. SUB DashBoard OUTPUT "Choose the option from the list below -" OUTPUT "1. Enter a new password." OUTPUT "2. Check the password." OUTPUT "3. Change the password." OUTPUT "4. Quit." END SUB // Function to check if input password matches with the current password FUNCTION PassChecker(PassToCheck, CurrentPwd : STRING) RETURNS STRING IF CurrentPwd = PassToCheck THEN RETURN "correct" ELSE RETURN "wrong" ENDIF END FUNCTION

Method: The main loop REPEATs until PassValidation() returns "Valid password.". The function uses LENGTH(), UPPER(), LOWER() and SUBSTRING() pre-defined functions, and four counters (NoSpace, NoUpCase, NoLowCase, NoDigit) to verify each rule.

// Loop or repeat until the password is valid REPEAT OUTPUT "Enter the password : " INPUT Password // Call the function to check and output if the password is valid or not. OUTPUT PassValidation(Password) UNTIL PassValidation(Password) = "Valid password." // Function to check if the password meet all the set criteria // and return the message whether it is valid or not with reason. FUNCTION PassValidation(Pwd : STRING) RETURNS STRING // Initialisation of all needed counters NoSpace ← 0 NoUpCase ← 0 NoLowCase ← 0 NoDigit ← 0 Digits = "0123456789" // Check if the length of password is within the range or not IF (LENGTH(Pwd) >= 10 AND LENGTH(Pwd) <= 20) THEN // Loop for each character of password FOR Count = 1 TO LENGTH(Pwd) // Check if the password contains white space and if not then, then - IF (SUBSTRING(Pwd, Count, 1) <> " ") THEN // Check if they are alphabetic letters IF (LOWER(SUBSTRING(Pwd, Count, 1)) <> UPPER(SUBSTRING(Pwd, Count, 1))) THEN // Check and count for Upper and Lower-case letter IF (SUBSTRING(Pwd, Count, 1) = UPPER(SUBSTRING(Pwd, Count, 1))) THEN NoUpCase = NoUpCase + 1 ELSE NoLowCase = NoLowCase + 1 ENDIF ELSE // If not alphabets, then check if it contains numeric digits FOR D = 1 TO LENGTH(Digits) IF SUBSTRING(Pwd, Count, 1) = SUBSTRING(Digits, D, 1) THEN NoDigit = NoDigit + 1 NEXT D ENDIF ELSE // If white space then Count NoSpace = NoSpace + 1 ENDIF NEXT Count // Return whether password is valid or not with appropriate reason IF (NoSpace = 0 AND NoUpCase > 0 AND NoLowCase > 0 AND NoDigit > 0) THEN RETURN "Valid password." IF NoSpace > 0 THEN RETURN "Invalid password, blank space is not allowed." IF NoUpCase = 0 THEN RETURN "Invalid password, it should contain atleast one upper case letter." IF NoLowCase = 0 THEN RETURN "Invalid password, it should contain atleast one lower case letter." IF NoDigit = 0 THEN RETURN "Invalid password, it should contain atleast one digit between 0 and 9." ELSE // Return if password is less than 10 or greater than 20 characters RETURN "Invalid password, it should be between 10 and 20 character in length." ENDIF END FUNCTION

Game Algorithm — Noughts & Crosses with 2D Array

Method: The 3×3 grid is stored in Game[1:3, 1:3]. The main FOR Count = 1 TO 9 loop allows up to 9 moves. Each move validates the chosen cell is empty and the symbol is X/O and is different from the previous one. The SUB DisplayBoard procedure prints the grid and the FUNCTION Result checks all four winning lines (rows, columns, two diagonals) using EXIT FOR to short-circuit.

Part 1 — Main program (declare & initialise array, accept moves, call procedure/function):

// Declare and Initialise the Array with empty space. DECLARE Game : ARRAY[1:3, 1:3] OF STRING FOR Row = 1 TO 3 FOR Col = 1 TO 3 Game[Row, Col] = "" NEXT Col NEXT Row // Create loop to repeat input 9-times for 3x3 different cells. FOR Count = 1 TO 9 // Input the location of move and accept only if it is empty. REPEAT INPUT "Enter the row : ", XAxis INPUT "Enter the column : ", YAxis IF (Game[XAxis, YAxis] = "X" OR Game[XAxis, YAxis] = "O") THEN OUTPUT "Invalid, this place is not empty" ENDIF UNTIL NOT(Game[XAxis, YAxis] = "X" OR Game[XAxis, YAxis] = "O") // Input in turn and accept only "X" or "O". // Ensure that each of the player uses different symbol. REPEAT OUTPUT "Put nought or cross in row-", XAxis, ", Col-", YAxis INPUT Symbol // Storing input in upper case letter Play = UPPER(Symbol) IF NOT(Play = "X" OR Play = "O") THEN OUTPUT "Invalid - try again 'X' or 'O' only" // After play-1, check whether current symbol matches with previous one. IF (Count > 1 AND Play = SymbolTag) THEN OUTPUT "Invalid, please put another symbol" UNTIL (Play = "X" OR Play = "O") AND (Play <> SymbolTag) // Storing the input in ARRAY after validation Game[XAxis, YAxis] = Play // Store the input in temporary variable to match with the next entry SymbolTag = Play // Call the Procedure to output the current status of the board CALL DisplayBoard // Call the Function to check and output the winner. IF Result(Play) = "won" THEN OUTPUT "Player with ", Play, "-mark ", Result(Play), " the game." // Stop the game if function returns "won", by exiting the loop EXIT FOR ENDIF NEXT Count

Part 2 — SUB DisplayBoard procedure (prints the 3×3 grid):

// Procedure to output the current status of the game board SUB DisplayBoard FOR Row = 1 TO 3 FOR Col = 1 TO 3 // Semi-colon ; symbol allows to output in same line. OUTPUT Game[Row, Col], ""; NEXT Col // PRINT breaks the line and allows to continue on next PRINT NEXT Row END SUB

Part 3 — FUNCTION Result (checks rows, columns and both diagonals for a winning line):

// Function to check who 'won' the game and // return the result back. FUNCTION Result(ParameterMark : STRING) RETURNS STRING // Check for same mark in straight row FOR Row = 1 TO 3 FOR Col = 1 TO 3 IF Game[Row, Col] = ParameterMark THEN InRow = "True" ELSE InRow = "False" ENDIF // Exit the inner-loop if the symbols are not same and check the next row. IF InRow = "False" THEN EXIT FOR NEXT Col // Exit the outer-loop altogether, if the symbols are same in the row. IF InRow = "True" THEN EXIT FOR NEXT Row // Check for same mark in straight column FOR Col = 1 TO 3 FOR Row = 1 TO 3 IF Game[Row, Col] = ParameterMark THEN InColumn = "True" ELSE InColumn = "False" ENDIF // Exit the inner-loop if the symbols are not same and check the next column. IF InColumn = "False" THEN EXIT FOR NEXT Row // Exit the outer-loop altogether, if the symbols are same in the column. IF InColumn = "True" THEN EXIT FOR NEXT Col // Check for same mark in diagonal-1 (left to right) FOR D1 = 1 TO 3 IF Game[D1, D1] = ParameterMark THEN InD1 = "True" ELSE InD1 = "False" ENDIF IF InD1 = "False" THEN EXIT FOR NEXT D1 // Check for same mark in diagonal-2 (right to left) D2Col = 3 FOR D2 = 1 TO 3 IF Game[D2, D2Col] = ParameterMark THEN InD2 = "True" ELSE InD2 = "False" ENDIF D2Col = D2Col - 1 IF InD2 = "False" THEN EXIT FOR NEXT D2 IF (InRow = "True" OR InColumn = "True" OR InD1 = "True" OR InD2 = "True") THEN // Returns the parameter value "won". RETURN "won" ENDIF END FUNCTION
Note: The function checks four possible winning patterns — 3 rows, 3 columns, diagonal-1 (top-left to bottom-right: [1,1] [2,2] [3,3]) and diagonal-2 (top-right to bottom-left: [1,3] [2,2] [3,1]). The EXIT FOR statement is used to break out of the inner loop early once a mismatch is found, and to break out of the outer loop early once a winning line is confirmed — this is an efficiency optimisation.

Revision: Statements and Key Computing Terms

Statement Key Term
A step-by-step set of instructions used to solve a problem.Algorithm
A diagrammatic representation of an algorithm using shapes (oval, rectangle, diamond, parallelogram).Flowchart
A text-based, half-formal representation of an algorithm using keywords like INPUT, OUTPUT, FOR, WHILE.Pseudocode
Instructions executed one after another, in order.Sequence
A construct that chooses between paths based on a condition (IF/THEN/ELSE, CASE OF).Selection
A construct that repeats a block of code (FOR/NEXT, WHILE/ENDWHILE, REPEAT/UNTIL).Iteration (Looping)
A named storage location whose value can change during program execution.Variable
A named storage location whose value is fixed throughout the program (e.g., CONSTANT Pass = 40).Constant
A collection of variables of the same type accessed using a single identifier and an index.Array
An array with one index, storing a single list of values (e.g., StudentName[1:100]).1D Array
An array with two indexes, storing rows and columns of values (e.g., Game[1:3, 1:3]).2D Array
A keyword used to define the size and data type of an array or variable.DECLARE
The operator used to store a value in a variable (e.g., Attempt ← 0).Assignment operator
A loop that runs a fixed number of times using a counter (FOR ... NEXT).FOR-NEXT loop
A loop that tests the condition at the start and may not execute at all (WHILE ... ENDWHILE).WHILE loop
A loop that tests the condition at the end and always executes at least once (REPEAT ... UNTIL).REPEAT-UNTIL loop
A multi-way selection construct that runs one branch out of many (CASE OF ... ENDCASE).CASE statement
A sub-routine that performs a task but does not return a value, called with CALL.Procedure (SUB)
A sub-routine that performs a task and returns a single value using RETURN.Function
A value passed into a procedure or function when it is called.Parameter
A variable used to control how many times a loop runs (e.g., Count, NoStd).Counter variable
A variable used to keep a running total (e.g., StdTotal = StdTotal + Mark).Accumulator
A Boolean variable used to remember the state of a check (e.g., PassCheck ← TRUE).Flag / Tag variable
A statement that jumps out of a loop before its natural end (e.g., EXIT FOR).EXIT statement
A pre-defined function that returns the number of characters in a string.LEN(X) / LENGTH(X)
A pre-defined function that returns a substring of length len starting at position start.SUBSTRING(X, start, len)
A pre-defined function that returns the string converted to upper-case / lower-case.UPPER(X) / LOWER(X)
A pre-defined function that rounds a number to n decimal places.ROUND(X, n)
A validation check that ensures input is within a given range (e.g., Mark >= 0 AND Mark <= 100).Range check
A validation check that ensures a string has the correct number of characters.Length check
A verification technique where the user types the same data twice and the two inputs are compared.Double-entry verification
Test data that should be accepted by the program (typical values).Normal data
Test data that should be rejected by the program (wrong type or out of range).Abnormal data
Test data at the edges of acceptability (the lowest and highest valid values).Boundary / Extreme data
A technique of running an algorithm by hand, recording the values of all variables at each step.Dry run / Trace table
Text in a program that is ignored by the computer but explains the code to humans (e.g., // ...).Comment
The process of finding and fixing errors in an algorithm or program.Debugging