1. (25 points) Write a program that takes the the values of a two-card blackjack hand as input, and prints out the point total of the hand. The value of the cards '2' through '10' is equal to their face value, the cards 'K', 'Q', 'J' are worth 10 points and the ace ('A') is worth 11 points unless it comes with another ace, then it's worth 1 point. The program should be able to catch incorrect input.

Sample runs:

```   Enter cards: A K
The score is 21

Enter cards: A A
The score is 2

Enter cards: 10 7
The score is 17

Enter cards: 12 7
*** Incorrect input 2
```

### Hints, hints, hints:

• The cards can take symbolic values, therefore they must be read as characters.
• The 10 is two characters long, so you must read an extra character.
• To handle the aces, you can set the value to 11 if the first card is an ace and if you get an ace for the second card and the score is 11, you know that you have to aces.

```   PROGRAM BlackJack;

{ Read a two-card blackjack hand and give score }

VAR card : char;
score, entry : integer;
error : boolean;

BEGIN
{ Initialize score }

score := 0;
error := FALSE;
entry := 1;

write('Enter cards: ');

WHILE (NOT error) AND (entry < 3) DO
BEGIN
CASE card OF

{ 2 through 9 are worth their face value }

'2'..'9'                : score := score + ord(card) - ord('0');

{ Jack, queen and king worht 10 points each }

'J','j','Q','q','K','k': score := score + 10;

{ The only time we allow a '1' is as first character of '10' }

'1':
IF entry = 1 THEN
BEGIN
IF card = '0' THEN
score := score + 10
ELSE
error := TRUE;
END
ELSE
error := TRUE;

{ The ace is worth 11 unless the previous card was an ace, in which }
{ case the current score would be 11 and the total score will be 2 }

'A','a'                :
IF entry = 1 THEN
score := 11
ELSE
IF score = 11 THEN
score := 2
ELSE
score := score + 11;

ELSE
error := TRUE

END; { case }

IF error THEN
writeln('*** Invalid input ', card)
ELSE
BEGIN

{ Advance to the next entry }

entry := entry + 1;

{ Read away empty space between cards }

END;

END; { While }

IF NOT error THEN
writeln('The score is ', score);
END.
```

2. (25 points) The integer 36 has a peculiar property: it is a perfect square and it is also the sum of the integers from 1 to 8. The next such number is 1225, which is 35^2 as well as the sum of 1 through 49. Write a program that finds the next umber that is a perfect square, and is also the sum of the series 1...n. The program should output the number and the limits of the summation.

Sample run:

```   41616 is equal to the square of 204 and the sum from 1 to 288.
```

### Notes:

• The function sqrt will return the square root of the argument.
• The function trunc will return the integer part of a real number.
• A number is a perfect square iff it is equal to the square of its integer square root; i.e., if X is an integer, then X is a perfect square iff X = trunc(sqrt(X)) * trunc(sqr(X)).
• Since you already know that 1225 is equal to the sum of 1 through 49, you should take this as your starting point; i.e, see if the sum of 1 through 50 is a perfect square, etc.

```   PROGRAM SumSquare;

VAR sum : longint;
upLimit : integer;

BEGIN

{ We alread know that 1225 (1...49) works, let's go from there }

upLimit := 50;
sum := 1275;

WHILE (trunc(sqrt(sum)) * trunc(sqrt(sum)) <> sum) DO
BEGIN
upLimit := upLimit + 1;
sum := sum + upLimit;
END;

write(sum, ' is equal to the square of ', intSqr);
writeln(' and the sum from 1 to ', upLimit);

END.
```

3. (20 points) Write a procedure that takes three integers and returns them in sorted order.

Extra credit: use a simplified bubble sort algorithm.

Extra, extra credit: write a helper procedure ConditionalSwap to help you with the bubble sort.

Version 1

```   PROCEDURE Sort(VAR first, second, third : integer);

VAR temp : integer;

BEGIN
IF first < second THEN
BEGIN
IF first < third THEN        { first is smallest, compare other two }
BEGIN
IF third < second THEN
BEGIN                     { new order: first, third, second }
temp := second;
second := third;
third := temp
END
END
ELSE                         { third is smallest, second is largest }
BEGIN                        { new order: third, first, second }
temp := first;
first := third;
third := second;
second := temp;
END
END
ELSE                            { second is smaller than first }
BEGIN
IF second < third THEN       { second is smallest, compare other two }
BEGIN
IF third < first THEN
BEGIN                     { new order: second, third, first }
temp := first;
first := second;
second := third;
third := temp
END
ELSE
BEGIN                     { new order: second, first, third }
temp := first;
first := second;
second := temp
END
END
ELSE                         { third is smallest, first is largest }
BEGIN                        { new order: third, second, first }
temp := first;
first := third;
third := temp;
END;
END;
END;
```

Version 2, with Bubble Sort

```   PROCEDURE Sort(VAR first, second, third : integer);

VAR temp : integer;

BEGIN

IF first > second THEN
BEGIN
temp := second;
second := first;
first := temp;
END;

IF second > third THEN
BEGIN
temp := third;
third := second;
second := temp;
END;

IF first > second THEN
BEGIN
temp := second;
second := first;
first := temp;
END;
END;
```

Version 2, with Bubble Sort and Conditional Swap

```   PROCEDURE ConditionalSwap(VAR first, second : integer);

VAR temp : integer;

BEGIN
IF first > second THEN
BEGIN
temp := second;
second := first;
first := temp;
END;
END;

PROCEDURE Sort(VAR first, second, third : integer);

BEGIN
ConditionalSwap(first, second);
ConditionalSwap(second, third);
ConditionalSwap(first, second);
END;
```

4. (15 points) What's the output of the following procedure ?

```   PROCEDURE Quiz;
VAR counter : integer;
BEGIN
FOR counter := 1 TO 9 DO
CASE counter MOD 5 OF
0  : write('often');
1  : write('what');
2,4: write('is');
3  : write('not');
END; { CASE }
writeln;
END; { Quiz }
```

```   whatisnotisoftenwhatisnotis
```

5. (15 Points)
 i) Write the following as a boolean expression. A < 27, B <> 6, D not in ['A','B'] : (A < 27) AND (B <> 6) AND NOT(D in ['A', 'B']) ii) Write the following as a boolean expression. 0 < A <= 100, B is lowercase letter. : (0 < A) AND (A <= 100) AND (B in ['a'..'z']) iii) Evaluate the following: NOT NOT NOT (3 >= 2 AND 2 <= 1) : TRUE iv) Evaluate the following: (3491203 MOD 253) IN [0..252]) : TRUE v) Evaluate the following: (TRUE AND NOT FALSE) OR (NOT TRUE AND TRUE) : TRUE