Pseudocode Pre release Material IGCSE - pseudocode

I have attempted a pre release task for an IGCSE pre release(https://bestexamhelp.com/exam/cambridge-igcse/computer-science-0478/2017/0478-s17-pm-22.php) here is attached the documentation for the pseudocode(http://alongside.us/pseudocode/0478_pseudocode_guide.pdf) and I have run the program in VS code using a pcse extension which can be found here(https://github.com/virchau13/pcse-ext). I have successfully managed to complete and produce task 1 however my second task will not run. I am unable to identify the error as the program simply doesn't run despite only outputting a single message. Any help would be greatly appreciated.
DECLARE SeniorCitizenNames: ARRAY[1:36] OF STRING
DECLARE individualCollectedAmount: ARRAY[1:36] OF REAL
DECLARE numSeniorCitizens: INTEGER
DECLARE Carers: INTEGER
DECLARE numPeople: INTEGER
DECLARE coachCost: INTEGER
DECLARE ticketCost: REAL
DECLARE mealCost: REAL
DECLARE totalCost: REAL
DECLARE costPerPerson: REAL
DECLARE totalAmountCollected: REAL
DECLARE hasMorePeople: BOOLEAN
DECLARE Carer1: STRING
DECLARE Carer2: STRING
DECLARE Carer3: STRING
OUTPUT "Enter Number of Senior Citizens:"
INPUT numSeniorCitizens // minimum 10 maximum 36
WHILE numSeniorCitizens < 10 OR numSeniorCitizens > 36 DO
OUTPUT "INVALID. The number of Senior Citizens must be between 10 and 36 inclusive.
Please enter another number:"
INPUT numSeniorCitizens // minimum 10 maximum 36
ENDWHILE
// Going to the trip
Carers <- 2
IF numSeniorCitizens > 24
THEN
Carers <- 3
ENDIF
numPeople <- numSeniorCitizens + Carers
IF numPeople >= 12 AND numPeople <= 16
THEN
coachCost <- 150
mealCost <- 14.00
ticketCost <- 21.00
ELSE
IF numPeople >= 17 AND numPeople <= 26
THEN
coachCost <- 190
mealCost <- 13.50
ticketCost <- 20.00
ELSE
IF numPeople >= 27 AND numPeople <= 39
THEN
coachCost <- 225
mealCost <- 13.00
ticketCost <- 19.00
ENDIF
ENDIF
ENDIF
totalCost <- coachCost + mealCost * numPeople + ticketCost * numPeople
costPerPerson <- totalCost / numSeniorCitizens
totalAmountCollected <- 0
FOR count <- 1 TO numSeniorCitizens
OUTPUT "Enter the names of the senior citizens and the amount they paid"
INPUT SeniorCitizenNames[count]
INPUT individualCollectedAmount[count]
totalAmountCollected <- totalAmountCollected + individualCollectedAmount[count]
NEXT
OUTPUT "Are there more senior citizens to be added?"
INPUT hasMorePeople
WHILE numSeniorCitizens < 36 AND hasMorePeople == TRUE DO
numSeniorCitizens <- numSeniorCitizens + 1
OUTPUT "Enter the names of the senior citizens and the amount they paid"
INPUT SeniorCitizenNames[numSeniorCitizens]
INPUT individualCollectedAmount[numSeniorCitizens]
totalAmountCollected <- totalAmountCollected +
individualCollectedAmount[numSeniorCitizens]
OUTPUT "Are there more senior citizens to be added?"
INPUT hasMorePeople
ENDWHILE
OUTPUT "the first carers name"
INPUT Carer1
OUTPUT "The second carers name is:"
INPUT Carer2
IF numSeniorCitizens > 24
THEN
Carers <- 3
OUTPUT "The third carers name is:"
INPUT Carer3
ENDIF
numPeople <- numSeniorCitizens + Carers
FOR count <- 1 TO numSeniorCitizens
OUTPUT SeniorCitizenNames[count]
NEXT
OUTPUT "The first and second Carers names are", Carer1, "and", Carer2
IF numSeniorCitizens > 24
THEN
OUTPUT "The third carers name is", Carer3
ENDIF
OUTPUT "The total cost of this trip is $", totalCost // The totoal cost
OUTPUT "The cost per person for this trip is $", costPerPerson // The cost per person
OUTPUT "THe total amount collected is $", totalAmountCollected // amount of money collected
by organiser

I do not know if the pseudocode below will resolve the issue(s), but I have slightly edited some of your original pseudocode:
DECLARE SeniorCitizenNames: ARRAY[1:36] OF STRING
DECLARE individualCollectedAmount: ARRAY[1:36] OF REAL
DECLARE numSeniorCitizens: INTEGER
DECLARE Carers: INTEGER
DECLARE numPeople: INTEGER
DECLARE coachCost: INTEGER
DECLARE ticketCost: REAL
DECLARE mealCost: REAL
DECLARE totalCost: REAL
DECLARE costPerPerson: REAL
DECLARE totalAmountCollected: REAL
DECLARE hasMorePeople: BOOLEAN
DECLARE Carer1: STRING
DECLARE Carer2: STRING
DECLARE Carer3: STRING
OUTPUT "Enter Number of Senior Citizens:"
numSeniorCitizens <- USERINPUT // minimum 10 maximum 36
WHILE numSeniorCitizens < 10 OR numSeniorCitizens > 36:
OUTPUT "INVALID. The number of Senior Citizens must be between 10 and 36 inclusive. Please enter another number:"
numSeniorCitizens <- USERINPUT // minimum 10 maximum 36
ENDWHILE
// Going to the trip
Carers <- 2
IF numSeniorCitizens > 24 THEN:
Carers <- 3
ENDIF
numPeople <- numSeniorCitizens + Carers
IF numPeople >= 12 AND numPeople <= 1 THEN:
coachCost <- 150
mealCost <- 14.00
ticketCost <- 21.00
ELIF numPeople >= 17 AND numPeople <= 26 THEN:
coachCost <- 190
mealCost <- 13.50
ticketCost <- 20.00
ELIF numPeople >= 27 AND numPeople <= 39 THEN:
coachCost <- 225
mealCost <- 13.00
ticketCost <- 19.00
ENDIF
ENDIF
ENDIF
totalCost <- coachCost + mealCost * numPeople + ticketCost * numPeople
costPerPerson <- totalCost / numSeniorCitizens
totalAmountCollected <- 0
FOR count <- 1 TO numSeniorCitizens:
OUTPUT "Enter the names of the senior citizens and the amount they paid"
SeniorCitizenNames[count] <- USERINPUT
individualCollectedAmount[count] <- USERINPUT
totalAmountCollected <- totalAmountCollected + individualCollectedAmount[count]
OUTPUT "Are there more senior citizens to be added?"
hasMorePeople <- USERINPUT
WHILE numSeniorCitizens < 36 AND hasMorePeople == TRUE:
numSeniorCitizens <- numSeniorCitizens + 1
OUTPUT "Enter the names of the senior citizens and the amount they paid"
SeniorCitizenNames[numSeniorCitizens] <- USERINPUT
individualCollectedAmount[numSeniorCitizens] <- USERINPUT
totalAmountCollected <- totalAmountCollected +
individualCollectedAmount[numSeniorCitizens]
OUTPUT "Are there more senior citizens to be added?"
hasMorePeople <- USERINPUT
ENDWHILE
OUTPUT "the first carers name"
Carer1 <- USERINPUT
OUTPUT "The second carers name is:"
Carer2 <- USERINPUT
IF numSeniorCitizens > 24 THEN:
Carers <- 3
OUTPUT "The third carers name is:"
Carer3 <- USERINPUT
ENDIF
numPeople <- numSeniorCitizens + Carers
FOR count <- 1 TO numSeniorCitizens:
OUTPUT SeniorCitizenNames[count]
OUTPUT "The first and second Carers names are", Carer1, "and", Carer2
IF numSeniorCitizens > 24 THEN:
OUTPUT "The third carers name is", Carer3
ENDIF
OUTPUT "The total cost of this trip is $", totalCost // The total cost
OUTPUT "The cost per person for this trip is $", costPerPerson // The cost per person
OUTPUT "THe total amount collected is $", totalAmountCollected // amount of money collected by organiser

Related

AMPL: Syntax for sets?

I'm spinning up on high level language for mixed integer linear programs (MILPs). The language is A Modeling Language for A Mathematical Programming Language (AMPL).
Chapter 4, page 65, Figure 4-7 shows the following syntax:
set PROD := bands coils plate ;
However, Chapter 5, page 74, shows the following syntax:
set PROD = {"bands", "coils", "plate"};
Can anyone please explain this difference in syntax?
I put the latter into a *.dat file, and AMPL complains expected ; ( : or symbol where the { is. Wondering if it is just a mistake in the manual.
Thanks.
The syntax in Chapter 4 --
set PROD := bands coils plate;
-- is used in data files, while the syntax in Chapter 5 --
set PROD = {"bands", "coils", "plate"};
-- is used in model files. It's a little weird (IMO) that the syntax for sets is different in model and data files, but it is. For another example of this difference, see this question and answer.
Complete working example code modified from AMPL manual
Added by the original poster of the question.
dietu.mod:
# dietu.mod
#----------
# set MINREQ; # nutrients with minimum requirements
# set MAXREQ; # nutrients with maximum requirements
set MINREQ = {"A", "B1", "B2", "C", "CAL"};
set MAXREQ = {"A", "NA", "CAL"};
set NUTR = MINREQ union MAXREQ; # nutrients
set FOOD; # foods
param cost {FOOD} > 0;
param f_min {FOOD} >= 0;
param f_max {j in FOOD} >= f_min[j];
param n_min {MINREQ} >= 0;
param n_max {MAXREQ} >= 0;
param amt {NUTR,FOOD} >= 0;
var Buy {j in FOOD} >= f_min[j], <= f_max[j];
minimize Total_Cost: sum {j in FOOD} cost[j] * Buy[j];
subject to Diet_Min {i in MINREQ}:
sum {j in FOOD} amt[i,j] * Buy[j] >= n_min[i];
subject to Diet_Max {i in MAXREQ}:
sum {j in FOOD} amt[i,j] * Buy[j] <= n_max[i];
The explicit definitions of setes MINREQ and MAXREQ and their members is taken from the *.dat file below (where their definitions have been commented out). Matlab users, observe above & beware that you need commas between members in a set.
dietu.dat:
# dietu.dat
#----------
data;
# set MINREQ := A B1 B2 C CAL ;
# set MAXREQ := A NA CAL ;
set FOOD := BEEF CHK FISH HAM MCH MTL SPG TUR ;
param: cost f_min f_max :=
BEEF 3.19 2 10
CHK 2.59 2 10
FISH 2.29 2 10
HAM 2.89 2 10
MCH 1.89 2 10
MTL 1.99 2 10
SPG 1.99 2 10
TUR 2.49 2 10 ;
param: n_min n_max :=
A 700 20000
C 700 .
B1 0 .
B2 0 .
NA . 50000
CAL 16000 24000 ;
param amt (tr): A C B1 B2 NA CAL :=
BEEF 60 20 10 15 938 295
CHK 8 0 20 20 2180 770
FISH 8 10 15 10 945 440
HAM 40 40 35 10 278 430
MCH 15 35 15 15 1182 315
MTL 70 30 15 15 896 400
SPG 25 50 25 15 1329 370
TUR 60 20 15 10 1397 450 ;
Solve the model using the following at the AMPL prompt:
reset data;
reset;
model dietu.mod;
data dietu.dat;
solve;

Ruby armstrong numbers in a range

puts "Enter range(starts at 1), ends at the number that you enter: "
range = gets.chomp.to_i
number = 1
while number <= range
temporary_number = number
sum_angstrom = 0
number += number
while(temporary_number != 0)
digit = temporary_number % 10
temporary_number /= 10
sum_angstrom = sum_angstrom + (digit ** 3)
end
if (sum_angstrom == number)
puts number
end
end
This time, I tried to make a program to show the armstrong numbers in a range that's taken from the user's input. The program just stops after I enter the number and press enter and i can't figure out why.
Keep in mind that i can't use for(each), that's why i'm using while so often.
First of all, change number += number to number += 1; otherwise you will only test the powers of 2.
Second, move the number += 1 line at the bottom of the while block it is in. Otherwise you will always test if sum_armstrong(n) == n+1.
This works:
puts "Enter range(starts at 1), ends at the number that you enter: "
range = gets.chomp.to_i
number = 1
while number <= range
temporary_number = number
sum_angstrom = 0
while(temporary_number != 0)
digit = temporary_number % 10
temporary_number /= 10
sum_angstrom = sum_angstrom + (digit ** 3)
end
if (sum_angstrom == number)
puts number
end
number += 1
end
Armstrong Number in Ruby one liner
n = 153
s = 0
n.to_s.split("").map{|e| s+=(e.to_i*e.to_i*e.to_i)}
puts (n==s ? "Armstrong number" : "Not Armstrong number")
You can iterate in a range to print the value based on your requirement.
Main logic lies in below line.
n.to_s.split("").map{|e| s+=(e.to_i*e.to_i*e.to_i)}
Improving my answer a little bit
n.digits.map{|e| s+=(e**3)}

Count number of 1 digits in 11 to the power of N

I came across an interesting problem:
How would you count the number of 1 digits in the representation of 11 to the power of N, 0<N<=1000.
Let d be the number of 1 digits
N=2 11^2 = 121 d=2
N=3 11^3 = 1331 d=2
Worst time complexity expected O(N^2)
The simple approach where you compute the number and count the number of 1 digits my getting the last digit and dividing by 10, does not work very well. 11^1000 is not even representable in any standard data type.
Powers of eleven can be stored as a string and calculated quite quickly that way, without a generalised arbitrary precision math package. All you need is multiply by ten and add.
For example, 111 is 11. To get the next power of 11 (112), you multiply by (10 + 1), which is effectively the number with a zero tacked the end, added to the number: 110 + 11 = 121.
Similarly, 113 can then be calculated as: 1210 + 121 = 1331.
And so on:
11^2 11^3 11^4 11^5 11^6
110 1210 13310 146410 1610510
+11 +121 +1331 +14641 +161051
--- ---- ----- ------ -------
121 1331 14641 161051 1771561
So that's how I'd approach, at least initially.
By way of example, here's a Python function to raise 11 to the n'th power, using the method described (I am aware that Python has support for arbitrary precision, keep in mind I'm just using it as a demonstration on how to do this an an algorithm, which is how the question was tagged):
def elevenToPowerOf(n):
# Anything to the zero is 1.
if n == 0: return "1"
# Otherwise, n <- n * 10 + n, once for each level of power.
num = "11"
while n > 1:
n = n - 1
# Make multiply by eleven easy.
ten = num + "0"
num = "0" + num
# Standard primary school algorithm for adding.
newnum = ""
carry = 0
for dgt in range(len(ten)-1,-1,-1):
res = int(ten[dgt]) + int(num[dgt]) + carry
carry = res // 10
res = res % 10
newnum = str(res) + newnum
if carry == 1:
newnum = "1" + newnum
# Prepare for next multiplication.
num = newnum
# There you go, 11^n as a string.
return num
And, for testing, a little program which works out those values for each power that you provide on the command line:
import sys
for idx in range(1,len(sys.argv)):
try:
power = int(sys.argv[idx])
except (e):
print("Invalid number [%s]" % (sys.argv[idx]))
sys.exit(1)
if power < 0:
print("Negative powers not allowed [%d]" % (power))
sys.exit(1)
number = elevenToPowerOf(power)
count = 0
for ch in number:
if ch == '1':
count += 1
print("11^%d is %s, has %d ones" % (power,number,count))
When you run that with:
time python3 prog.py 0 1 2 3 4 5 6 7 8 9 10 11 12 1000
you can see that it's both accurate (checked with bc) and fast (finished in about half a second):
11^0 is 1, has 1 ones
11^1 is 11, has 2 ones
11^2 is 121, has 2 ones
11^3 is 1331, has 2 ones
11^4 is 14641, has 2 ones
11^5 is 161051, has 3 ones
11^6 is 1771561, has 3 ones
11^7 is 19487171, has 3 ones
11^8 is 214358881, has 2 ones
11^9 is 2357947691, has 1 ones
11^10 is 25937424601, has 1 ones
11^11 is 285311670611, has 4 ones
11^12 is 3138428376721, has 2 ones
11^1000 is 2469932918005826334124088385085221477709733385238396234869182951830739390375433175367866116456946191973803561189036523363533798726571008961243792655536655282201820357872673322901148243453211756020067624545609411212063417307681204817377763465511222635167942816318177424600927358163388910854695041070577642045540560963004207926938348086979035423732739933235077042750354729095729602516751896320598857608367865475244863114521391548985943858154775884418927768284663678512441565517194156946312753546771163991252528017732162399536497445066348868438762510366191040118080751580689254476068034620047646422315123643119627205531371694188794408120267120500325775293645416335230014278578281272863450085145349124727476223298887655183167465713337723258182649072572861625150703747030550736347589416285606367521524529665763903537989935510874657420361426804068643262800901916285076966174176854351055183740078763891951775452021781225066361670593917001215032839838911476044840388663443684517735022039957481918726697789827894303408292584258328090724141496484460001, has 105 ones
real 0m0.609s
user 0m0.592s
sys 0m0.012s
That may not necessarily be O(n2) but it should be fast enough for your domain constraints.
Of course, given those constraints, you can make it O(1) by using a method I call pre-generation. Simply write a program to generate an array you can plug into your program which contains a suitable function. The following Python program does exactly that, for the powers of eleven from 1 to 100 inclusive:
def mulBy11(num):
# Same length to ease addition.
ten = num + '0'
num = '0' + num
# Standard primary school algorithm for adding.
result = ''
carry = 0
for idx in range(len(ten)-1, -1, -1):
digit = int(ten[idx]) + int(num[idx]) + carry
carry = digit // 10
digit = digit % 10
result = str(digit) + result
if carry == 1:
result = '1' + result
return result
num = '1'
print('int oneCountInPowerOf11(int n) {')
print(' static int numOnes[] = {-1', end='')
for power in range(1,101):
num = mulBy11(num)
count = sum(1 for ch in num if ch == '1')
print(',%d' % count, end='')
print('};')
print(' if ((n < 0) || (n > sizeof(numOnes) / sizeof(*numOnes)))')
print(' return -1;')
print(' return numOnes[n];')
print('}')
The code output by this script is:
int oneCountInPowerOf11(int n) {
static int numOnes[] = {-1,2,2,2,2,3,3,3,2,1,1,4,2,3,1,4,2,1,4,4,1,5,5,1,5,3,6,6,3,6,3,7,5,7,4,4,2,3,4,4,3,8,4,8,5,5,7,7,7,6,6,9,9,7,12,10,8,6,11,7,6,5,5,7,10,2,8,4,6,8,5,9,13,14,8,10,8,7,11,10,9,8,7,13,8,9,6,8,5,8,7,15,12,9,10,10,12,13,7,11,12};
if ((n < 0) || (n > sizeof(numOnes) / sizeof(*numOnes)))
return -1;
return numOnes[n];
}
which should be blindingly fast when plugged into a C program. On my system, the Python code itself (when you up the range to 1..1000) runs in about 0.6 seconds and the C code, when compiled, finds the number of ones in 111000 in 0.07 seconds.
Here's my concise solution.
def count1s(N):
# When 11^(N-1) = result, 11^(N) = (10+1) * result = 10*result + result
result = 1
for i in range(N):
result += 10*result
# Now count 1's
count = 0
for ch in str(result):
if ch == '1':
count += 1
return count
En c#:
private static void Main(string[] args)
{
var res = Elevento(1000);
var countOf1 = res.Select(x => int.Parse(x.ToString())).Count(s => s == 1);
Console.WriteLine(countOf1);
}
private static string Elevento(int n)
{
if (n == 0) return "1";
//Otherwise, n <- n * 10 + n, once for each level of power.
var num = "11";
while (n > 1)
{
n--;
// Make multiply by eleven easy.
var ten = num + "0";
num = "0" + num;
//Standard primary school algorithm for adding.
var newnum = "";
var carry = 0;
foreach (var dgt in Enumerable.Range(0, ten.Length).Reverse())
{
var res = int.Parse(ten[dgt].ToString()) + int.Parse(num[dgt].ToString()) + carry;
carry = res/10;
res = res%10;
newnum = res + newnum;
}
if (carry == 1)
newnum = "1" + newnum;
// Prepare for next multiplication.
num = newnum;
}
//There you go, 11^n as a string.
return num;
}

Tracing this algorithm, is my trace right?

For a classwork problem I am doing, I am supposed to trace (check for bugs) the following algorithm (in pseudocode):
num <- 2
count <- 1
while count < 5
{
count <- count * num
if count / 2 < 2
print "Hello"
else
while count < 7
{
count <- count + 1
}
print "The count is " + count + "."
}
When i traced this code, I got
num count output
2 1 Hello The count is 1.
My question is, was my trace right? It looks like there is something else I have to add.
When you are tracing the problem, you need to note down all value changes in the program.
In your program, we have 2 variables to trace: count and num. From the program, we can figure out 2 facts:
There is no assignment of num;
All output statements are related to count.
Therefore, we should focus on tracing the changes on count.
Notice that this block:
while count < 7
{
count <- count + 1
}
can be replaced with
if count < 7
{
count = 7
}
The workflow of the program can be depicted in English like below:
Check if count is smaller than 5, YES go to 2, NO program ends;
Double count;
If count / 2 is smaller than 2, YES go to 4, NO go to 5;
Print "Hello", go to 6;
If count is smaller than 7, set count to 7;
Print "The count is +count+.`", go to 1;
Now the task is to use 1 as initial value of count and walk through the work flow until the program terminates.
Let's do it together:
count equals to 1, so go to 2;
Now count equals to 2;
count / 2 equals to 1, which is smaller than 2, so go to 4;
Hello is printed, go to 6;
"The count is 2." is printed, go to 1;
count equals to 2, so go to 2;
Now count equals to 4;
count / 2 equals to 2, which is NOT smaller than 2, so go to 5;
count is set to 7;
"The count is 7." is printed, go to 1;
count equals to 7, so program terminates.
Therefore the output will be:
HelloThe count is 2.The count is 7.
Here is how you should walk through this.
num = 2
count = 1
while 1 < 5
{
2 = 1 * 2
if 2 /2 < 2 //since 1 < 2 print Hello
print "Hello"
else //This is skipped because the if was true
while count < 7
{
count <- count + 1
}
print "The count is " + count + "." //This prints "The Count is 2
}
Then you continue through the while loop with count = 2.
Start of second iteration.
while 2 < 5
{
4 = 2 * 2
count changes each time through the loop.

displayng number pyramid in O(n) execution

How do we print the following with O(n) execution
may be using a single for loop?
1
2 3
4 5 n
up to n rows
all I can do is using nested for loops
Nested for loop doesn't necessarily mean it's not O(n) any more. If what's inside the nested loop gets executed O(n) times, then the nested loop is perfectly fine:
cur_num <- 1
cur_step <- 1
while cur_num <= n
for i <- 1 to cur_step
print cur_num++
cur_step++
print '\n'
With a single for loop, it's doable, but slightly less pleasant
cur_num <- 1
cur_step <- 1
cur_step_consumed <- 0
for i <- 1 to n
print cur_num++
cur_step_consumed++
if cur_step_consumed == cur_step
cur_step_consumed <- 0
cur_step++
print '\n'
In C++:
size_t amount = 1;
size_t count = 0;
for(size_t i=1;i<=n;++i){
cout << i << " ";
++count;
if (count == amount){
cout << endl;
count = 0;
++amount;
}
}
output for n = 29:
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
29
The idea is to track the number of elements to print in the current row, and track the number of elements printed in the current row. When the number of elements we've printed for the current row is the same as the total number of elements to print for that row, reset the count and increment the number of elements to print for the next row. You can mess with the formatting to get prettier output, but this is the gist of how it can be done in O(n) time and O(1) space.

Resources