Chapter 12 Exercises: Sets and Enumerations


Part A: Enumeration Fundamentals

Exercise A1. Define an enumerated type TColor with the values Red, Orange, Yellow, Green, Blue, Indigo, and Violet. Write a program that declares a variable of type TColor, assigns it the value Green, and prints its ordinal value using Ord.

Exercise A2. Using the TColor type from A1, write a for loop that iterates through every color and prints both the ordinal value and the color name (you will need a ColorToStr helper function).

Exercise A3. Define an enumerated type TMonth with all twelve months (Jan through Dec). Write a function DaysInMonth(M: TMonth; LeapYear: Boolean): Integer that returns the correct number of days for each month. Use a case statement.

Exercise A4. Using the TMonth type from A3, write a function MonthToQuarter(M: TMonth): Integer that returns 1, 2, 3, or 4. Then write a function QuarterName(Q: Integer): string that returns 'Q1' through 'Q4'.

Exercise A5. Define an enumerated type TDirection with values North, East, South, West. Write a function TurnRight(D: TDirection): TDirection that returns the direction 90 degrees clockwise. Write a corresponding TurnLeft function. (Hint: Use Succ and Pred with wrap-around logic, or use a case statement.)


Part B: Subrange Types

Exercise B1. Define a subrange type THour = 0..23 and a subrange type TMinute = 0..59. Write a program that reads an hour and minute from the user, assigns them to variables of these types, and prints the time in HH:MM format. Compile with {$R+} and test what happens when you enter 25 for the hour.

Exercise B2. Define a subrange type TDiceRoll = 1..6. Write a program that simulates rolling two dice 1000 times and counts how many times each sum (2 through 12) appears. Use array[2..12] of Integer for the counts.

Exercise B3. Define an enumerated type TDay = (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday) and a subrange type TWeekday = Monday..Friday. Write a procedure ScheduleMeeting(Day: TWeekday; Hour: THour) that prints a message confirming the meeting. What happens if you try to call ScheduleMeeting(Saturday, 10) with range checking on?

Exercise B4. Define a subrange type TGrade = 0..100. Write a function LetterGrade(Score: TGrade): Char that returns 'A' for 90-100, 'B' for 80-89, 'C' for 70-79, 'D' for 60-69, and 'F' for 0-59.

Exercise B5. Create a type TAlphaChar = 'A'..'Z'. Write a function CaesarShift(Ch: TAlphaChar; Shift: Integer): TAlphaChar that applies a Caesar cipher shift, wrapping around from 'Z' to 'A'.


Part C: Set Operations

Exercise C1. Declare a set of Char variable called Vowels and initialize it with all vowels (both upper and lowercase). Write a program that reads a line of text and counts the number of vowels, consonants (alphabetic non-vowels), digits, and other characters using set membership tests.

Exercise C2. Define TDay and TDays = set of TDay. Create three set variables: Weekend, Weekdays, and MySchedule (pick any 3-4 days). Print which days are in your schedule but not on the weekend (set difference), and which scheduled days fall on the weekend (set intersection).

Exercise C3. Write a function IsValidEmail(const S: string): Boolean that performs a basic email validation using character sets. It should check that: (a) the string contains exactly one @, (b) there is at least one character before the @, (c) there is at least one . after the @, and (d) all characters are in a valid set (alphanumeric, ., _, -, @).

Exercise C4. Write a program that reads a string and determines which digits (0-9) appear in it. Display the set of digits found and the set of digits not found. For example, for input "abc123", found = {1, 2, 3}, not found = {0, 4, 5, 6, 7, 8, 9}.

Exercise C5. Define TPermission = (pRead, pWrite, pExecute, pDelete, pAdmin) and TPermissions = set of TPermission. Write a procedure DescribePermissions(P: TPermissions) that prints each permission in the set. Then write a program that creates permissions for three roles (Viewer, Editor, Admin) and displays them.


Part D: Applied Problems

Exercise D1. Password Strength Checker. Write a function PasswordStrength(const Password: string): Integer that returns a score from 0 to 5 based on which character classes are present (lowercase, uppercase, digits, special characters, length > 8). Use sets for character classification. Each criterion met adds 1 point.

Exercise D2. Card Game Setup. Define enumerations for TSuit = (Clubs, Diamonds, Hearts, Spades) and TRank = (Ace, Two, Three, ..., King). Define a record TCard with Suit: TSuit and Rank: TRank. Write a procedure that generates and displays a standard 52-card deck by iterating over both enumerations.

Exercise D3. Student Attendance Tracker. Define TDay and TDays. Create an array of 5 TDays variables representing five students' attendance for the week. Write procedures to: (a) display each student's attendance, (b) find days when all students were present (intersection of all sets), (c) find days when no students were present (complement logic).

Exercise D4. Simple Token Classifier. Write a program that reads a line of source code and classifies each character as belonging to one of these categories: letter, digit, operator (+, -, *, /, =, <, >), bracket ((, ), [, ], {, }), whitespace, or other. Use character sets for each category. Print the count for each category.

Exercise D5. Menu Option Manager. Define TMenuOption = (moNew, moOpen, moSave, moClose, moPrint, moUndo, moRedo, moQuit). Write a program that simulates a text editor: start with only [moNew, moOpen, moQuit] available; when the user selects "New" or "Open", add [moSave, moClose, moPrint, moUndo] to the available set; after an edit, add moRedo; selecting "Close" returns to the initial set. Display available options at each step.


Part E: Challenge Problems

Exercise E1. Sieve of Eratosthenes with Sets. Implement the Sieve of Eratosthenes to find all prime numbers up to 255 using set of Byte. Start with a set containing [2..255], then for each prime found, remove all its multiples from the set. Print the remaining elements (the primes).

Exercise E2. Scoped Enumerations. Rewrite the name collision example from Section 12.2 using Free Pascal's {$scopedenums on} directive. Define TTrafficLight and TPaint with overlapping value names. Write a program that uses both types, qualifying each value with its type name.

Exercise E3. Set-Based Spell Checker. Write a simple spell checker that uses set of Char to detect potentially misspelled words. A "suspicious" word is one that: (a) contains no vowels, (b) contains three consecutive consonants, or (c) contains characters outside ['a'..'z', 'A'..'Z', '''']. Read a text file and flag suspicious words.

Exercise E4. Finite State Machine. Define TState = (sStart, sIdentifier, sNumber, sOperator, sError) and use character sets to drive transitions. Build a simple lexer that reads a string character by character, uses sets to determine the character class, and transitions between states accordingly. Output each token found.

Exercise E5. Bit-Level Visualization. Write a program that takes a set of 0..7 and displays its internal bit representation as 8 binary digits. Then demonstrate that union corresponds to OR, intersection to AND, and difference to AND NOT by showing the bit patterns alongside the set operations.


Part M: Metacognitive Exercises

Exercise M1. Before reading Section 12.6, predict how you think Pascal stores a set of TDay internally. After reading the section, compare your prediction to the actual implementation. What surprised you? What did you get right?

Exercise M2. Think of a program you have written (in any language) that used magic numbers or string comparisons where an enumeration would have been better. Describe the specific bugs or maintenance problems that occurred (or could have occurred) and how enumerations would have prevented them.

Exercise M3. Pascal's sets are limited to 256 elements. Write a paragraph arguing that this is a feature, not a limitation. Then write a paragraph arguing that it is a limitation. Which argument do you find more convincing, and why?

Exercise M4. The in operator reads naturally in English: if Day in Weekend. Find three other places in your recent code where set membership tests would improve readability. Rewrite those code snippets using Pascal sets.

Exercise M5. Rank the three type features from this chapter (enumerations, subranges, sets) in order of how useful you think they will be in your own programming. Explain your ranking. Revisit this ranking after completing the case studies and see if your opinion has changed.