Pangram in Cobol: Complete Solution & Deep Dive Guide
Mastering Cobol String Logic: A Deep Dive into the Pangram Problem
Discover how to solve the classic pangram detection problem using Cobol, a language that powers the world's most critical financial and governmental systems. This guide breaks down the logic, provides a complete code solution, and explores the nuances of string manipulation in a mainframe environment, turning a simple challenge into a masterclass in robust programming.
The Surprising Challenge of an Alphabet Sentence
Imagine being tasked with maintaining a piece of software written decades ago. The code is dense, the syntax is unfamiliar, and it's responsible for processing millions of transactions per second. This is the daily reality for a Cobol developer. While modern languages chase fleeting trends, Cobol remains the bedrock of global finance, insurance, and logistics, a silent giant processing over 95% of ATM swipes.
You might think a simple word puzzle—like checking if a sentence contains every letter of the alphabet—is trivial. But tackling this "pangram" problem in Cobol is a perfect microcosm of the skills required to thrive in this environment. It forces you to think algorithmically, to manage memory directly, and to master powerful but verbose data manipulation techniques. You're not just solving a puzzle; you're forging the disciplined mindset of a mainframe programmer.
This guide will walk you through every step of that journey. We will dissect the logic, build a solution from scratch, and reveal how this seemingly simple exercise from the kodikra.com exclusive curriculum unlocks a deeper understanding of Cobol's true power.
What Exactly is a Pangram?
A pangram is a sentence or phrase that contains every single letter of a given alphabet at least once. The most famous English pangram is "The quick brown fox jumps over the lazy dog." This sentence is a favorite for testing typewriters and computer keyboards because it conveniently uses all 26 letters.
For the purpose of this programming challenge, the core rules are simple:
- Completeness: The sentence must contain each of the 26 letters from 'a' to 'z'.
- Case-Insensitivity: It doesn't matter if a letter is uppercase (e.g., 'A') or lowercase (e.g., 'a'). Both count as the same letter.
- Non-Alphabetic Characters: Punctuation, numbers, and spaces should be ignored. They don't contribute to the pangram and don't disqualify it.
Understanding these constraints is the first step in designing an effective algorithm. Our program must be smart enough to normalize the input (handle casing) and filter out irrelevant characters.
Why Use Cobol for a Logic Puzzle?
Solving a pangram problem in a language like Python or JavaScript can be done in a few lines of code. So, why deliberately choose Cobol, a language known for its verbosity? The answer lies in the value of the process, not just the result.
Working with Cobol forces you to be explicit and deliberate. You manually define data structures, control memory layout with PIC clauses, and construct loops with precise control. This builds a foundational understanding of how computers actually process data, a skill often abstracted away by modern high-level languages.
Furthermore, string manipulation is a cornerstone of data processing in mainframe applications. Customer names, addresses, policy numbers, and transaction records are all strings. Mastering verbs like INSPECT, UNSTRING, and PERFORM VARYING to parse and validate this data is a non-negotiable skill for any serious Cobol programmer. The pangram challenge is a perfect, isolated environment to hone these exact skills.
How to Design the Pangram Detection Algorithm
Before writing a single line of Cobol, we must architect a clear, logical plan. The most efficient approach involves using a "flag" system to track which letters of the alphabet we have encountered.
The core strategy can be broken down into these steps:
- Initialization: Create a data structure to act as our tracker. A simple array or table with 26 slots, one for each letter of the alphabet, is perfect. We'll initialize all slots to a "not found" state (e.g., the flag 'N').
- Normalization: Take the input sentence and convert it entirely to one case, either lowercase or uppercase. This simplifies our logic immensely, as we no longer need to check for both 'a' and 'A', 'b' and 'B', and so on. Lowercase is the common convention.
- Iteration and Flagging: Loop through the normalized sentence, character by character. For each character, we ask two questions:
- Is this character a letter from 'a' to 'z'?
- If it is, which letter is it?
- Verification: After checking every character in the sentence, we loop through our 26-slot tracker. If we find even one flag that is still in the "not found" state, the sentence is not a pangram. If all 26 flags are "found", it is a pangram.
Algorithm Flow Diagram
Here is a visual representation of our primary algorithm, using a frequency map (our flag array) to track letters.
● Start
│
▼
┌──────────────────────────┐
│ Initialize 26 'N' flags │
│ (for a-z) │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Get input sentence & │
│ convert to lowercase │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Loop through each char │
│ in the sentence │
└────────────┬─────────────┘
│
╭──────────▼───────────╮
│ Is char 'a' thru 'z'?│
╰──────────┬───────────╯
│
Yes ──────┴────── No
│ │
▼ ▼
┌──────────────────┐ (Ignore &
│ Calculate index │ continue)
│ & set flag to 'Y'│
└──────────────────┘
│
└──────────────────┐
│
▼
┌──────────────────────────┐
│ End of sentence loop │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Check all 26 flags │
└────────────┬─────────────┘
│
╭──────────▼───────────╮
│ Are all flags 'Y'? │
╰──────────┬───────────╯
│
Yes ──────┴────── No
│ │
▼ ▼
┌──────────────┐ ┌───────────────┐
│ It's a │ │ Not a │
│ Pangram │ │ Pangram │
└──────────────┘ └───────────────┘
│ │
└────────┬─────────┘
▼
● End
The Complete Cobol Solution: Code and Walkthrough
Now, let's translate our algorithm into a working Cobol program. This solution is designed for clarity and follows best practices for structure and readability. It is written to be compatible with compilers like GnuCOBOL.
Full Source Code
IDENTIFICATION DIVISION.
PROGRAM-ID. IS-PANGRAM.
AUTHOR. Kodikra.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-INPUT-SENTENCE PIC X(100) VALUE
"The quick brown fox jumps over the lazy dog".
01 WS-NORMALIZED-SENTENCE PIC X(100).
01 WS-RESULT-FLAG PIC X(1) VALUE 'Y'.
88 IS-A-PANGRAM VALUE 'Y'.
88 NOT-A-PANGRAM VALUE 'N'.
01 WS-LOOP-VARS.
05 WS-I PIC 9(3) VALUE 0.
05 WS-SENTENCE-LEN PIC 9(3) VALUE 0.
05 WS-ALPHA-INDEX PIC 9(2) VALUE 0.
05 WS-CURRENT-CHAR PIC X(1).
* This table holds a flag for each letter of the alphabet.
* 'N' = Not Found, 'Y' = Found.
01 WS-ALPHABET-TABLE.
05 WS-LETTER-FLAGS OCCURS 26 TIMES.
10 WS-LETTER-FLAG PIC X(1).
PROCEDURE DIVISION.
MAIN-LOGIC.
*----------------------------------------------------------------*
* 1. INITIALIZE & PREPARE THE DATA
*----------------------------------------------------------------*
PERFORM INITIALIZE-ALPHABET-TABLE.
PERFORM NORMALIZE-INPUT-SENTENCE.
*----------------------------------------------------------------*
* 2. PROCESS THE SENTENCE AND MARK FOUND LETTERS
*----------------------------------------------------------------*
MOVE FUNCTION LENGTH(FUNCTION TRIM(WS-NORMALIZED-SENTENCE))
TO WS-SENTENCE-LEN.
PERFORM VARYING WS-I FROM 1 BY 1
UNTIL WS-I > WS-SENTENCE-LEN
MOVE WS-NORMALIZED-SENTENCE(WS-I:1) TO WS-CURRENT-CHAR
IF WS-CURRENT-CHAR >= 'a' AND WS-CURRENT-CHAR <= 'z'
COMPUTE WS-ALPHA-INDEX =
FUNCTION ORD(WS-CURRENT-CHAR) -
FUNCTION ORD('a') + 1
MOVE 'Y' TO WS-LETTER-FLAG(WS-ALPHA-INDEX)
END-IF
END-PERFORM.
*----------------------------------------------------------------*
* 3. VERIFY IF ALL LETTERS WERE FOUND
*----------------------------------------------------------------*
PERFORM VERIFY-PANGRAM-RESULT.
*----------------------------------------------------------------*
* 4. DISPLAY THE FINAL RESULT
*----------------------------------------------------------------*
IF IS-A-PANGRAM
DISPLAY "Sentence is a pangram: YES"
ELSE
DISPLAY "Sentence is a pangram: NO"
END-IF.
STOP RUN.
*================================================================*
* SUBROUTINES / PARAGRAPHS
*================================================================*
INITIALIZE-ALPHABET-TABLE.
* Sets all 26 letter flags to 'N' (Not Found).
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 26
MOVE 'N' TO WS-LETTER-FLAG(WS-I)
END-PERFORM.
NORMALIZE-INPUT-SENTENCE.
* Copies the input and converts it to lowercase.
MOVE WS-INPUT-SENTENCE TO WS-NORMALIZED-SENTENCE.
INSPECT WS-NORMALIZED-SENTENCE
CONVERTING 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
TO 'abcdefghijklmnopqrstuvwxyz'.
VERIFY-PANGRAM-RESULT.
* Checks the alphabet table. If any flag is still 'N',
* it's not a pangram.
MOVE 'Y' TO WS-RESULT-FLAG. *> Assume it's a pangram initially
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 26
IF WS-LETTER-FLAG(WS-I) = 'N'
MOVE 'N' TO WS-RESULT-FLAG
EXIT PERFORM *> No need to check further
END-IF
END-PERFORM.
Detailed Code Walkthrough
IDENTIFICATION DIVISION
This is the simplest division. PROGRAM-ID. IS-PANGRAM. gives our program a name. It's mandatory boilerplate for any Cobol program.
DATA DIVISION and WORKING-STORAGE SECTION
This is where we define all our variables. Cobol requires you to declare everything upfront.
WS-INPUT-SENTENCE: A variable of typePIC X(100), meaning it can hold up to 100 alphanumeric characters. We pre-populate it with a known pangram for testing.WS-NORMALIZED-SENTENCE: Another 100-character variable that will hold the lowercase version of our input.WS-RESULT-FLAG: A single-character flag. We use level-88 names (IS-A-PANGRAM,NOT-A-PANGRAM) to create condition-names. This makes ourIFstatements in thePROCEDURE DIVISIONmuch more readable (e.g.,IF IS-A-PANGRAMinstead ofIF WS-RESULT-FLAG = 'Y').WS-LOOP-VARS: A group item to keep our counters and temporary variables organized.PIC 9(3)defines a 3-digit numeric field.WS-ALPHABET-TABLE: This is the heart of our algorithm.OCCURS 26 TIMEScreates an array (called a table in Cobol) with 26 elements. Each element,WS-LETTER-FLAG, is a single character that will hold 'Y' or 'N'.
PROCEDURE DIVISION
This division contains the executable code, the logic of our program.
MAIN-LOGIC.
This is our main entry point. We use PERFORM to call other paragraphs (subroutines), which keeps the main logic clean and easy to follow.
PERFORM INITIALIZE-ALPHABET-TABLE.: We first call the subroutine to set up our tracker, ensuring all flags start at 'N'.PERFORM NORMALIZE-INPUT-SENTENCE.: Next, we prepare our input data by converting it to lowercase.MOVE FUNCTION LENGTH(...) TO WS-SENTENCE-LEN.: We calculate the length of the trimmed, normalized sentence. UsingFUNCTION TRIMremoves any trailing spaces, ensuring our loop doesn't run longer than necessary.PERFORM VARYING WS-I FROM 1 BY 1...: This is the main processing loop. It iterates from the first character (index 1 in Cobol) to the last.MOVE WS-NORMALIZED-SENTENCE(WS-I:1) TO WS-CURRENT-CHAR: This is called "reference modification." It extracts a substring of length 1 starting at positionWS-Iand places it intoWS-CURRENT-CHAR.IF WS-CURRENT-CHAR >= 'a' AND WS-CURRENT-CHAR <= 'z': We check if the character is a lowercase letter.COMPUTE WS-ALPHA-INDEX = ...: If it's a letter, we perform a clever calculation.FUNCTION ORDgives the numeric value of a character in the computer's character set (like ASCII or EBCDIC). By subtracting the value of 'a' and adding 1, we map 'a' to index 1, 'b' to 2, and so on.MOVE 'Y' TO WS-LETTER-FLAG(WS-ALPHA-INDEX): We use the calculated index to access the correct slot in our table and set its flag to 'Y'.
PERFORM VERIFY-PANGRAM-RESULT.: After the loop finishes, we call the verification routine.IF IS-A-PANGRAM...: Finally, we check our result flag using the readable level-88 name andDISPLAYthe outcome.STOP RUN.: This terminates the program.
Subroutines (Paragraphs)
INITIALIZE-ALPHABET-TABLE.: A simple loop that runs 26 times to set everyWS-LETTER-FLAGto 'N'.NORMALIZE-INPUT-SENTENCE.: This paragraph uses the powerfulINSPECTverb.INSPECT ... CONVERTINGacts like a search-and-replace, swapping every uppercase letter with its lowercase equivalent in one command.VERIFY-PANGRAM-RESULT.: We start by optimistically setting our main result flag to 'Y'. Then we loop through our 26 flags. The moment we find an 'N', we know it's not a pangram. We set the flag to 'N' and useEXIT PERFORMto break out of the loop immediately, as there's no need to check further. This is a small but important optimization.
Alternative Approaches and Considerations
The flag table method is highly efficient, but it's not the only way to solve the problem. Understanding alternatives helps deepen your problem-solving skills.
Alternative: Iterating the Alphabet
An alternative approach flips the logic: instead of iterating through the sentence, we can iterate through the alphabet and check if each letter exists within the sentence.
The algorithm would look like this:
- Normalize the input sentence to lowercase.
- Start a loop that goes from 'a' to 'z'.
- Inside the loop, for the current letter (e.g., 'a'), search the entire sentence to see if it's present. In Cobol, you could use
INSPECT ... TALLYINGfor this. - If the letter is not found in the sentence, you know immediately it's not a pangram. You can stop and return a "false" result.
- If the loop completes successfully (meaning every letter from 'a' to 'z' was found), then it is a pangram.
Alternative Algorithm Flow Diagram
● Start
│
▼
┌──────────────────────────┐
│ Get input sentence & │
│ convert to lowercase │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Loop through alphabet │
│ ('a' to 'z') │
└────────────┬─────────────┘
│
╭──────────▼───────────╮
│ Does sentence contain│
│ current letter? │
╰──────────┬───────────╯
│
No ──────┴────── Yes
│ │
▼ ▼
┌─────────────────┐ (Continue to
│ Not a Pangram. │ next letter)
│ Exit immediately.│
└─────────────────┘
│
└──────────────────┐
│
▼
┌──────────────────────────┐
│ End of alphabet loop │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ It's a Pangram │
└──────────────────────────┘
│
▼
● End
Pros and Cons of Each Method
Choosing the right algorithm often depends on the specific constraints and expected data. Here’s a comparison:
| Aspect | Flag Table Method (Our Solution) | Iterating Alphabet Method (Alternative) |
|---|---|---|
| Performance | Generally faster. It passes through the input sentence only once. The final check of 26 flags is constant and very fast. Complexity is O(N) where N is the length of the sentence. | Potentially slower. In the worst case (a true pangram), it scans the entire sentence 26 times. Complexity can be up to O(26 * N), which is significantly worse for long sentences. |
| Memory Usage | Requires a small, fixed amount of extra memory for the 26-byte flag table. This is negligible. | Requires minimal extra memory, only for loop counters. Slightly more memory-efficient. |
| Logic Complexity | The logic is slightly more complex due to the index calculation (FUNCTION ORD) and the need for two separate loops (processing and verification). |
The logic is arguably simpler and more direct to read: "For each letter, is it in the sentence?" This can be easier for beginners to conceptualize. |
| Early Exit | Can only exit early during the final verification step. It must always process the entire sentence first. | Can exit very early. If the sentence is `"bbb"`, it will fail on the very first check (for 'a') and terminate immediately. |
For most use cases, our primary solution using the flag table is superior due to its predictable and efficient O(N) performance.
Frequently Asked Questions (FAQ)
Is Cobol still a relevant language to learn?
Absolutely. While it's not used for web or mobile development, Cobol is the backbone of the global economy. Major banks, insurance companies, airlines, and government agencies rely on mainframe systems running billions of lines of Cobol code. There is a high demand for developers who can maintain and modernize these critical systems, often leading to stable and lucrative careers.
Why is case-insensitivity so important for this problem?
Case-insensitivity ensures the logic is robust. A user or data source might provide a sentence in all caps, title case, or a random mix. By normalizing the input to a single case (like lowercase), our core logic only has to check for 26 possibilities ('a' through 'z') instead of 52 ('a' through 'z' and 'A' through 'Z'). This dramatically simplifies the code and prevents errors.
What does PIC X(1) mean in the Cobol DATA DIVISION?
PIC stands for "Picture Clause" and it defines the type and size of a data item. X signifies an alphanumeric character (it can hold letters, numbers, or symbols). The number in parentheses, (1), specifies the length. So, PIC X(1) defines a variable that can hold exactly one alphanumeric character.
How does the INSPECT verb work in more detail?
The INSPECT verb is a powerful tool for string examination and manipulation. It has several forms: TALLYING (counts occurrences of characters), REPLACING (replaces characters or strings with others), and CONVERTING (as used in our solution), which performs a character-by-character translation based on two provided strings of equal length.
Can this pangram detection logic be used in other programming languages?
Yes, the core algorithm is language-agnostic. The "flag table" or "frequency map" approach is a standard and efficient way to solve this problem in any language. In Python, you might use a dictionary or a set; in Java, a boolean[] array or a HashMap. The implementation details change, but the fundamental logic of tracking occurrences remains the same.
What are some common pitfalls when handling strings in Cobol?
The most common issues stem from Cobol's fixed-length nature. If you move a shorter string into a longer variable, the remaining space is padded, which can cause issues with comparisons or length calculations if not handled with TRIM. Another pitfall is off-by-one errors in loops and reference modification, as Cobol strings are 1-indexed, unlike the 0-indexed arrays in many modern languages.
Where can I continue my Cobol learning journey?
This exercise is part of a structured learning path designed to build your skills progressively. To see how this module fits into the bigger picture, you can explore our Cobol 3 learning path. For a comprehensive overview of the language and more tutorials, be sure to discover the complete Cobol guide on our platform.
Conclusion: From Puzzle to Practical Skill
We've journeyed from a simple definition of a pangram to a robust, efficient, and well-structured Cobol program. In doing so, we've touched upon core concepts that are vital for any mainframe developer: explicit data definition, algorithmic thinking, string manipulation with verbs like INSPECT, and the power of structured programming with PERFORM.
The pangram problem, while academic, is a perfect proxy for real-world data validation tasks. Whether you're checking if a product ID contains valid characters, parsing a complex transaction string, or validating user input, the fundamental skills are the same. By mastering this challenge, you're not just learning Cobol; you're learning how to think with the precision and discipline required to manage the world's most critical codebases.
Disclaimer: The Cobol code provided in this article has been structured for clarity and is compatible with modern compilers like GnuCOBOL. Syntax and features may vary slightly between different mainframe environments and compiler versions. Always consult the documentation for your specific system.
Published by Kodikra — Your trusted Cobol learning resource.
Post a Comment