Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building a training set of tags for cobol #104

Closed
ErikSchierboom opened this issue Oct 31, 2023 · 21 comments
Closed

Building a training set of tags for cobol #104

ErikSchierboom opened this issue Oct 31, 2023 · 21 comments

Comments

@ErikSchierboom
Copy link
Member

Hello lovely maintainers 👋

We've recently added "tags" to student's solutions. These express the constructs, paradigms and techniques that a solution uses. We are going to be using these tags for lots of things including filtering, pointing a student to alternative approaches, and much more.

In order to do this, we've built out a full AST-based tagger in C#, which has allowed us to do things like detect recursion or bit shifting. We've set things up so other tracks can do the same for their languages, but its a lot of work, and we've determined that actually it may be unnecessary. Instead we think that we can use machine learning to achieve tagging with good enough results. We've fine-tuned a model that can determine the correct tags for C# from the examples with a high success rate. It's also doing reasonably well in an untrained state for other languages. We think that with only a few examples per language, we can potentially get some quite good results, and that we can then refine things further as we go.

I released a new video on the Insiders page that talks through this in more detail.

We're going to be adding a fully-fledged UI in the coming weeks that allow maintainers and mentors to tag solutions and create training sets for the neural networks, but to start with, we're hoping you would be willing to manually tag 20 solutions for this track. In this post we'll add 20 comments, each with a student's solution, and the tags our model has generated. Your mission (should you choose to accept it) is to edit the tags on each issue, removing any incorrect ones, and add any that are missing. In order to build one model that performs well across languages, it's best if you stick as closely as possible to the C# tags as you can. Those are listed here. If you want to add extra tags, that's totally fine, but please don't arbitrarily reword existing tags, even if you don't like what Erik's chosen, as it'll just make it less likely that your language gets the correct tags assigned by the neural network.


To summarise - there are two paths forward for this issue:

  1. You're up for helping: Add a comment saying you're up for helping. Update the tags some time in the next few days. Add a comment when you're done. We'll then add them to our training set and move forward.
  2. You not up for helping: No problem! Just please add a comment letting us know :)

If you tell us you're not able/wanting to help or there's no comment added, we'll automatically crowd-source this in a week or so.

Finally, if you have questions or want to discuss things, it would be best done on the forum, so the knowledge can be shared across all maintainers in all tracks.

Thanks for your help! 💙


Note: Meta discussion on the forum

@ErikSchierboom
Copy link
Member Author

Exercise: hello-world

Code

      *Sample COBOL program
       IDENTIFICATION DIVISION.
       PROGRAM-ID. hello-world.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-RESULT PIC X(14).
       PROCEDURE DIVISION.
       HELLO-WORLD.
        MOVE "Hello, World!" TO WS-RESULT.

Tags:

construct:assignment
construct:comment
construct:data-definition
construct:divide
construct:hello-world
construct:identification-division
construct:move
construct:number
construct:procedure
construct:program-id
construct:section
construct:variable
construct:working-storage
paradigm:imperative
paradigm:procedural

@ErikSchierboom
Copy link
Member Author

Exercise: yacht

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. YACHT.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-RESULT PIC 99 VALUE 0.
       01 WS-CATEGORY PIC X(15).
       01 WS-DICE. 
         10 WS-DICE1 PIC 9.
         10 WS-DICE2 PIC 9.
         10 WS-DICE3 PIC 9.
         10 WS-DICE4 PIC 9.
         10 WS-DICE5 PIC 9.
          PROCEDURE DIVISION.
          YACHT.
       EVALUATE (WS-CATEGORY)
       WHEN 'ones'
          MOVE 0 TO WS-RESULT
          IF WS-DICE1 = 1
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE1
          END-IF
          IF WS-DICE2 = 1
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE2
          END-IF
          IF WS-DICE3 = 1
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE3
          END-IF
          IF WS-DICE4 = 1
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE4
          END-IF
          IF WS-DICE5 = 1
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE5
          END-IF
       WHEN 'twos'
          MOVE 0 TO WS-RESULT
          IF WS-DICE1 = 2
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE1
          END-IF
          IF WS-DICE2 = 2
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE2
          END-IF
          IF WS-DICE3 = 2
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE3
          END-IF
          IF WS-DICE4 = 2
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE4
          END-IF
          IF WS-DICE5 = 2
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE5
          END-IF
       WHEN 'threes'
          MOVE 0 TO WS-RESULT
          IF WS-DICE1 = 3
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE1
          END-IF
          IF WS-DICE2 = 3
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE2
          END-IF
          IF WS-DICE3 = 3
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE3
          END-IF
          IF WS-DICE4 = 3
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE4
          END-IF
          IF WS-DICE5 = 3
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE5
          END-IF
       WHEN 'fours'
          MOVE 0 TO WS-RESULT
          IF WS-DICE1 = 4
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE1
          END-IF
          IF WS-DICE2 = 4
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE2
          END-IF
          IF WS-DICE3 = 4
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE3
          END-IF
          IF WS-DICE4 = 4
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE4
          END-IF
          IF WS-DICE5 = 4
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE5
          END-IF
       WHEN 'fives'
          MOVE 0 TO WS-RESULT
          IF WS-DICE1 = 5
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE1
          END-IF
          IF WS-DICE2 = 5
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE2
          END-IF
          IF WS-DICE3 = 5
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE3
          END-IF
          IF WS-DICE4 = 5
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE4
          END-IF
          IF WS-DICE5 = 5
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE5
          END-IF
       WHEN 'sixes'
          MOVE 0 TO WS-RESULT
          IF WS-DICE1 = 6
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE1
          END-IF
          IF WS-DICE2 = 6
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE2
          END-IF
          IF WS-DICE3 = 6
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE3
          END-IF
          IF WS-DICE4 = 6
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE4
          END-IF
          IF WS-DICE5 = 6
             COMPUTE WS-RESULT = WS-RESULT + WS-DICE5
          END-IF
       WHEN 'full house'
          IF (WS-DICE1 = WS-DICE2 AND WS-DICE3 = WS-DICE4 AND 
              WS-DICE4 = WS-DICE5 AND WS-DICE1 <> WS-DICE5) OR         
             (WS-DICE1 = WS-DICE3 AND WS-DICE2 = WS-DICE4 AND 
              WS-DICE4 = WS-DICE5 AND WS-DICE1 <> WS-DICE5) OR
             (WS-DICE1 = WS-DICE4 AND WS-DICE3 = WS-DICE2 AND 
              WS-DICE2 = WS-DICE5 AND WS-DICE1 <> WS-DICE5) OR
             (WS-DICE1 = WS-DICE5 AND WS-DICE3 = WS-DICE4 AND 
              WS-DICE4 = WS-DICE2 AND WS-DICE1 <> WS-DICE4) OR
             (WS-DICE2 = WS-DICE3 AND WS-DICE1 = WS-DICE4 AND 
              WS-DICE4 = WS-DICE5 AND WS-DICE2 <> WS-DICE5) OR
             (WS-DICE2 = WS-DICE4 AND WS-DICE1 = WS-DICE3 AND 
              WS-DICE3 = WS-DICE5 AND WS-DICE2 <> WS-DICE5) OR
             (WS-DICE2 = WS-DICE5 AND WS-DICE1 = WS-DICE4 AND 
              WS-DICE4 = WS-DICE3 AND WS-DICE2 <> WS-DICE4) OR
             (WS-DICE3 = WS-DICE4 AND WS-DICE1 = WS-DICE2 AND 
              WS-DICE2 = WS-DICE5 AND WS-DICE3 <> WS-DICE5) OR
             (WS-DICE3 = WS-DICE5 AND WS-DICE1 = WS-DICE2 AND 
              WS-DICE2 = WS-DICE4 AND WS-DICE3 <> WS-DICE4) OR
             (WS-DICE4 = WS-DICE5 AND WS-DICE1 = WS-DICE2 AND 
              WS-DICE2 = WS-DICE3 AND WS-DICE4 <> WS-DICE3) 
             COMPUTE WS-RESULT = WS-DICE1 + WS-DICE2 + WS-DICE3 +       
                                 WS-DICE4 + WS-DICE5                    
          ELSE                                                          
             MOVE 0 TO WS-RESULT                                        
          END-IF                                                        
       WHEN 'four of a kind'
          IF WS-DICE1 = WS-DICE2
             IF WS-DICE1 = WS-DICE3
                IF WS-DICE1 = WS-DICE4
                   COMPUTE WS-RESULT = WS-DICE1 * 4   
                ELSE
                   IF WS-DICE1 = WS-DICE5
                      COMPUTE WS-RESULT = WS-DICE1 * 4
                   ELSE
                      MOVE 0 TO WS-RESULT
                   END-IF
                END-IF
             ELSE
                IF WS-DICE1 = WS-DICE4 AND WS-DICE1 = WS-DICE5
                   COMPUTE WS-RESULT = WS-DICE1 * 4
                ELSE
                   MOVE 0 TO WS-RESULT
                END-IF
             END-IF
          ELSE
             IF WS-DICE1 = WS-DICE3 AND WS-DICE1 = WS-DICE4 AND
                WS-DICE1 = WS-DICE5
                COMPUTE WS-RESULT = WS-DICE1 * 4
             ELSE
                IF WS-DICE2 = WS-DICE3 AND WS-DICE2 = WS-DICE4 AND
                   WS-DICE2 = WS-DICE5
                   COMPUTE WS-RESULT = WS-DICE1 * 4
                 ELSE
                    MOVE 0 TO WS-RESULT
                 END-IF
             END-IF
          END-IF
       WHEN 'little straight'
          IF WS-DICE1 = 1 OR WS-DICE2 = 1 OR WS-DICE3 = 1 OR 
             WS-DICE4 = 1 OR WS-DICE5 = 1
             IF WS-DICE1 = 2 OR WS-DICE2 = 2 OR WS-DICE3 = 2 OR 
                WS-DICE4 = 2 OR WS-DICE5 = 2
                IF WS-DICE1 = 3 OR WS-DICE2 = 3 OR WS-DICE3 = 3 OR 
                   WS-DICE4 = 3 OR WS-DICE5 = 3
                   IF WS-DICE1 = 4 OR WS-DICE2 = 4 OR WS-DICE3 = 4 OR 
                      WS-DICE4 = 4 OR WS-DICE5 = 4
                      IF WS-DICE1 = 5 OR WS-DICE2 = 5 OR WS-DICE3 = 5 OR 
                         WS-DICE4 = 5 OR WS-DICE5 = 5
                         MOVE 30 TO WS-RESULT
                      ELSE
                         MOVE 0 TO WS-RESULT
                      END-IF
                   ELSE
                      MOVE 0 TO WS-RESULT
                   END-IF
                ELSE
                   MOVE 0 TO WS-RESULT
                END-IF
             ELSE
                MOVE 0 TO WS-RESULT
             END-IF
          ELSE
             MOVE 0 TO WS-RESULT
          END-IF
       WHEN 'big straight'
          IF WS-DICE1 = 2 OR WS-DICE2 = 2 OR WS-DICE3 = 2 OR 
             WS-DICE4 = 2 OR WS-DICE5 = 2
             IF WS-DICE1 = 3 OR WS-DICE2 = 3 OR WS-DICE3 = 3 OR 
                WS-DICE4 = 3 OR WS-DICE5 = 3
                IF WS-DICE1 = 4 OR WS-DICE2 = 4 OR WS-DICE3 = 4 OR 
                   WS-DICE4 = 4 OR WS-DICE5 = 4
                   IF WS-DICE1 = 5 OR WS-DICE2 = 5 OR WS-DICE3 = 5 OR 
                      WS-DICE4 = 5 OR WS-DICE5 = 5
                      IF WS-DICE1 = 6 OR WS-DICE2 = 6 OR WS-DICE3 = 6 OR 
                         WS-DICE4 = 6 OR WS-DICE5 = 6
                         MOVE 30 TO WS-RESULT
                      ELSE
                         MOVE 0 TO WS-RESULT
                      END-IF
                   ELSE
                      MOVE 0 TO WS-RESULT
                   END-IF
                ELSE
                   MOVE 0 TO WS-RESULT
                END-IF
             ELSE
                MOVE 0 TO WS-RESULT
             END-IF
          ELSE
             MOVE 0 TO WS-RESULT
          END-IF
       WHEN 'choice'
          COMPUTE WS-RESULT = WS-DICE1 + WS-DICE2 + WS-DICE3 +
                              WS-DICE4 + WS-DICE5
       WHEN 'yacht'
          IF WS-DICE1 = WS-DICE2 AND WS-DICE1 = WS-DICE3 AND 
             WS-DICE1 = WS-DICE4 AND WS-DICE1 = WS-DICE5
             MOVE 50 TO WS-RESULT
          ELSE 
             MOVE 0 TO WS-RESULT
          END-IF
       WHEN OTHER
          MOVE 99 TO WS-RESULT
       END-EVALUATE.
        YACHT-EXIT.

Tags:

construct:add
construct:and
construct:assignment
construct:boolean
construct:char
construct:compute
construct:divide
construct:end
construct:end-evaluate
construct:end-if
construct:evaluate
construct:if
construct:int
construct:integral-number
construct:logical-and
construct:logical-or
construct:multiply
construct:number
construct:or
construct:procedure
construct:section
construct:string
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural
technique:boolean-logic
technique:math

@ErikSchierboom
Copy link
Member Author

Exercise: yacht

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. YACHT.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
           01 WS-RESULT PIC 99 VALUE 0.
           01 WS-CATEGORY PIC X(15).
           01 WS-DICE PIC 9(5).
           01 WS-COUNT  PIC 9.
           01 WS-CHECK PIC 9.
           01 WS-TEST   PIC 9.
           01 WS-TEST2 PIC 9.
           01 WS-LTL PIC 9(5) VALUE 12345.
           01 WS-BIG PIC 9(5) VALUE 23456.
           01 WS-TABLE-A.
               05 WS-A PIC 9 OCCURS 5 TIMES INDEXED BY I.
           01 WS-TABLE-B.
               05 WS-B PIC 9 OCCURS 5 TIMES INDEXED BY J.
           01 WS-TABLE-LB.
               05 WS-L PIC 9 OCCURS 5 TIMES INDEXED BY L.
       PROCEDURE DIVISION.
           YACHT.
               IF WS-CATEGORY EQUALS 'yacht' THEN PERFORM YACHT-TEST.
               IF WS-CATEGORY EQUALS 'four of a kind' THEN
                   PERFORM FOUR-KIND.
               IF WS-CATEGORY EQUALS 'full house' THEN
                   PERFORM FULL-HOUSE.
               IF WS-CATEGORY EQUALS 'little straight' THEN
                   MOVE WS-LTL TO WS-TABLE-LB.
                   PERFORM STRAIGHT.
               IF WS-CATEGORY EQUALS 'big straight' THEN
                   MOVE WS-BIG TO WS-TABLE-LB.
                   PERFORM STRAIGHT.
               IF WS-CATEGORY EQUALS 'choice' THEN PERFORM CHOICE.
               IF WS-CATEGORY EQUALS 'ones' THEN MOVE 1 TO WS-TEST.
               IF WS-CATEGORY EQUALS 'twos' THEN MOVE 2 TO WS-TEST.
               IF WS-CATEGORY EQUALS 'threes' THEN MOVE 3 TO WS-TEST.
               IF WS-CATEGORY EQUALS 'fours' THEN MOVE 4 TO WS-TEST.
               IF WS-CATEGORY EQUALS 'fives' THEN MOVE 5 TO WS-TEST.
               IF WS-CATEGORY EQUALS 'sixes' THEN MOVE 6 TO WS-TEST.

               DISPLAY WS-RESULT.
           STOP RUN.

           YACHT-TEST.
               MOVE WS-DICE TO WS-TABLE-A.
               MOVE WS-A(1) TO WS-TEST.
               PERFORM VARYING I FROM 1 BY 1 UNTIL I > 5
                   IF WS-A(I) NOT EQUAL WS-TEST THEN
                       MOVE 0 TO WS-RESULT
                       EXIT PARAGRAPH
               END-PERFORM.
               MOVE 50 TO WS-RESULT.

           FOUR-KIND.
               MOVE WS-DICE TO WS-TABLE-A.
               MOVE WS-DICE TO WS-TABLE-B.
               PERFORM VARYING I FROM 1 BY 1 UNTIL I > 5
                   MOVE WS-A(I) TO WS-TEST
                   DISPLAY 'Test: ' WS-TEST
                   MOVE 0 TO WS-COUNT
                   PERFORM VARYING J FROM 1 BY 1 UNTIL J > 5
                       DISPLAY 'B-TABLE: ' WS-B(J)
                       IF WS-B(J) EQUALS WS-TEST THEN
                           ADD 1 TO WS-COUNT
                           DISPLAY 'COUNT: ' WS-COUNT
                   END-PERFORM
                   IF WS-COUNT EQUALS 4 THEN
                     MULTIPLY WS-TEST BY 4 GIVING WS-RESULT
                     EXIT PARAGRAPH
               END-PERFORM.
               
           FULL-HOUSE.
             MOVE WS-DICE TO WS-TABLE-A.
             MOVE WS-DICE TO WS-TABLE-B.
             MOVE WS-A(1) TO WS-TEST.
             DISPLAY 'TEST1: ' WS-TEST
             PERFORM VARYING I FROM 1 BY 1 UNTIL I > 5
               IF WS-A(I) EQUALS WS-TEST THEN
                   DISPLAY 'MATCHING: ' WS-A(I)
                   ADD 1 TO WS-COUNT
               ELSE
                   DISPLAY 'NOT MATCHING: ' WS-A(I)
                   MOVE WS-A(I) TO WS-TEST2
               END-IF
             END-PERFORM.
             DISPLAY 'FIRST COUNT: ' WS-COUNT
             IF WS-COUNT EQUALS 3 OR WS-COUNT EQUALS 2 THEN
                 SUBTRACT WS-COUNT FROM 5 GIVING WS-CHECK
                 MOVE 0 TO WS-COUNT
                 DISPLAY 'CHECK: ' WS-CHECK
                 PERFORM VARYING J FROM 1 BY 1 UNTIL J > 5
                   ADD WS-B(J) TO WS-RESULT
                   IF WS-B(J) EQUALS WS-TEST2 THEN
                       DISPLAY 'MATCHING SECOND: ' WS-B(J)
                       ADD 1 TO WS-COUNT  
                 END-PERFORM.
                 DISPLAY 'SECOND COUNT: ' WS-COUNT
                 DISPLAY 'CURRENT RESULT: ' WS-RESULT
                 IF WS-COUNT NOT EQUAL WS-CHECK THEN
                     DISPLAY 'WAS NOT EQUAL TO CHECK'
                     MOVE 0 TO WS-RESULT.

           STRAIGHT.
               MOVE WS-DICE TO WS-TABLE-A.
               PERFORM VARYING L FROM 1 BY 1 UNTIL L > 5
                   PERFORM VARYING I FROM 1 BY 1 Until I > 5
                       IF WS-A(I) EQUALS WS-L(L) THEN
                           ADD 1 TO WS-COUNT
                   END-PERFORM
               END-PERFORM.
               IF WS-COUNT EQUALS 5 THEN MOVE 30 TO WS-RESULT.

           CHOICE.
               MOVE WS-DICE TO WS-TABLE-A.
               PERFORM VARYING I FROM 1 BY 1 UNTIL I > 5
                   ADD WS-A(I) TO WS-RESULT
               END-PERFORM.

           PAIR-SCORES.
               MOVE WS-DICE TO WS-TABLE-A.
               PERFORM VARYING I FROM 1 BY 1 UNTIL I > 5
                   IF WS-A(I) EQUALS WS-TEST THEN
                       ADD 1 TO WS-COUNT
               END-PERFORM.
               MULTIPLY WS-TEST BY WS-COUNT GIVING WS-RESULT.

Tags:

construct:add
construct:boolean
construct:by
construct:char
construct:display
construct:divide
construct:else
construct:exit
construct:if
construct:indexed
construct:move
construct:multiply
construct:nested
construct:number
construct:or
construct:parameter
construct:perform
construct:pic
construct:run
construct:section
construct:stop
construct:string
construct:subtract
construct:then
construct:until
construct:value
construct:variable
construct:visibility
paradigm:imperative
paradigm:procedural
technique:boolean-logic
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: pangram

Code

      * ----------------------------------------------------------------------
      * exercism.io
      * COBOL Track Exercise: pangram
      * Contributed: Anthony J. Borla ([email protected])
      * ----------------------------------------------------------------------
       IDENTIFICATION DIVISION.
       PROGRAM-ID. PANGRAM.
       DATA DIVISION.
      *
       WORKING-STORAGE SECTION.
       01 WS-SENTENCE             PIC X(60) VALUE SPACES.
       01 WS-RESULT               PIC 9(01).
      *
       01 WS-CONSTANTS.
          05 WS-OPERATION-STATUS.
             10 WS-IS-PANGRAM     PIC 9(01) VALUE 1.
             10 WS-NOT-PANGRAM    PIC 9(01) VALUE ZEROES.
      *
       01 WS-SCRATCHPAD.
          05 WS-SENTENCE-LENGTH   PIC 9(02).
          05 WS-IDX               PIC 9(02).
      *
       01 WS-COUNT-TABLE-LENGTH   PIC 9(02) VALUE 26.
       01 WS-COUNT-TABLE.
          05 WS-COUNT             PIC 9(02)
                                  OCCURS 26 TIMES.
      *
       PROCEDURE DIVISION.
      *
       PANGRAM.
           COMPUTE WS-SENTENCE-LENGTH =
             FUNCTION LENGTH(FUNCTION TRIM(WS-SENTENCE))
      *
           IF WS-SENTENCE-LENGTH < 1 THEN
             MOVE WS-NOT-PANGRAM TO WS-RESULT
             EXIT PARAGRAPH
           END-IF
      *
           MOVE WS-IS-PANGRAM TO WS-RESULT
      *
           MOVE ZEROES TO WS-COUNT-TABLE
      *
           INSPECT FUNCTION UPPER-CASE(WS-SENTENCE)
             TALLYING WS-COUNT(1) FOR ALL 'A'
                      WS-COUNT(2) FOR ALL 'B'
                      WS-COUNT(3) FOR ALL 'C'
                      WS-COUNT(4) FOR ALL 'D'
                      WS-COUNT(5) FOR ALL 'E'
                      WS-COUNT(6) FOR ALL 'F'
                      WS-COUNT(7) FOR ALL 'G'
                      WS-COUNT(8) FOR ALL 'H'
                      WS-COUNT(9) FOR ALL 'I'
                      WS-COUNT(10) FOR ALL 'J'
                      WS-COUNT(11) FOR ALL 'K'
                      WS-COUNT(12) FOR ALL 'L'
                      WS-COUNT(13) FOR ALL 'M'
                      WS-COUNT(14) FOR ALL 'N'
                      WS-COUNT(15) FOR ALL 'O'
                      WS-COUNT(16) FOR ALL 'P'
                      WS-COUNT(17) FOR ALL 'Q'
                      WS-COUNT(18) FOR ALL 'R'
                      WS-COUNT(19) FOR ALL 'S'
                      WS-COUNT(20) FOR ALL 'T'
                      WS-COUNT(21) FOR ALL 'U'
                      WS-COUNT(22) FOR ALL 'V'
                      WS-COUNT(23) FOR ALL 'W'
                      WS-COUNT(24) FOR ALL 'X'
                      WS-COUNT(25) FOR ALL 'Y'
                      WS-COUNT(26) FOR ALL 'Z'
      *
           MOVE 1 TO WS-IDX
      *
           PERFORM WS-COUNT-TABLE-LENGTH TIMES
             IF WS-COUNT(WS-IDX) = 0 THEN
               MOVE WS-NOT-PANGRAM TO WS-RESULT
               EXIT PARAGRAPH
             END-IF
             ADD 1 TO WS-IDX
           END-PERFORM.
      *

Tags:

construct:assignment
construct:comment
construct:compute
construct:data-definition
construct:divide
construct:end-perform
construct:exit
construct:if
construct:implicit-conversion
construct:inspect
construct:integral-number
construct:invocation
construct:length
construct:move
construct:number
construct:occurs
construct:parameter
construct:perform
construct:pic
construct:program-id
construct:section
construct:string
construct:then
construct:times
construct:using
construct:value
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: pangram

Code

        IDENTIFICATION DIVISION.
        PROGRAM-ID. PANGRAM.
        ENVIRONMENT DIVISION.
        DATA DIVISION.
        WORKING-STORAGE SECTION.
        01 WS-SENTENCE PIC X(60).
        01 WS-RESULT PIC 9.

        01 WS-CHARS      PIC X(26) VALUE 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
        01 REDEFINES WS-CHARS.
           05 WS-CHAR    PIC X OCCURS 26 TIMES.
        01 WS-COUNT      PIC 9(3).
        01 WS-IX         PIC 99.
      
        PROCEDURE DIVISION.
        PANGRAM.
         MOVE FUNCTION UPPER-CASE(WS-SENTENCE) TO WS-SENTENCE.
         PERFORM VARYING WS-IX FROM 1 BY 1 UNTIL WS-IX > 26
            MOVE 0 TO WS-COUNT
            INSPECT WS-SENTENCE TALLYING WS-COUNT 
               FOR ALL WS-CHAR(WS-IX)
            IF WS-COUNT > 0
               MOVE ' ' TO WS-CHAR(WS-IX)
         END-PERFORM.
         IF WS-CHARS EQUAL SPACES
            MOVE 0 TO WS-RESULT
         ELSE
            MOVE 1 TO WS-RESULT
         END-IF
         GOBACK.

Tags:

construct:assignment
construct:char
construct:divide
construct:else
construct:environment
construct:go
construct:if
construct:implicit-conversion
construct:indexed
construct:inspect
construct:integral-number
construct:invocation
construct:move
construct:number
construct:occurs
construct:paradigm
construct:procedure
construct:section
construct:string
construct:subtract
construct:until-loop
construct:value
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural

@ErikSchierboom
Copy link
Member Author

Exercise: difference-of-squares

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. difference-of-squares.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-DIFFERENCE-OF-SQUARES PIC 9(8).
       01 WS-SUM-OF-SQUARES PIC 9(8).
       01 WS-SQUARE-OF-SUM PIC 9(8).
       01 WS-NUMERATOR PIC 9(8).
       01 WS-NUMBER PIC 9(8).
       01 WS-SUM PIC 9(8).

       PROCEDURE DIVISION.
       
       SQUARE-OF-SUM.
       COMPUTE WS-SUM = WS-NUMBER * (WS-NUMBER + 1) / 2.
       COMPUTE WS-SQUARE-OF-SUM = WS-SUM * WS-SUM.
       
       SUM-OF-SQUARES.
       COMPUTE WS-NUMERATOR = 
           WS-NUMBER * (WS-NUMBER + 1) * (2 * WS-NUMBER + 1).
       COMPUTE WS-SUM-OF-SQUARES = WS-NUMERATOR / 6.
       
       DIFFERENCE-OF-SQUARES.
       COMPUTE WS-DIFFERENCE-OF-SQUARES = 
           WS-SQUARE-OF-SUM - WS-SUM-OF-SQUARES.
       
       SHOW-RESULTS.
       DISPLAY WS-SQUARE-OF-SUM.
       DISPLAY WS-SUM-OF-SQUARES.
       DISPLAY WS-DIFFERENCE-OF-SQUARES.
       

Tags:

construct:add
construct:char
construct:compute
construct:divide
construct:display
construct:identifier
construct:integer
construct:integral-number
construct:multiply
construct:number
construct:paragraph
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural

@ErikSchierboom
Copy link
Member Author

Exercise: difference-of-squares

Code

      * ----------------------------------------------------------------------
      * exercism.io
      * COBOL Track Exercise: difference-of-squares
      * Contributed: Anthony J. Borla ([email protected])
      * ----------------------------------------------------------------------
       IDENTIFICATION DIVISION.
       PROGRAM-ID. DIFFERENCE-OF-SQUARES.
       DATA DIVISION.
      *
       WORKING-STORAGE SECTION.
       01 WS-NUMBER                 PIC 9(08) VALUE ZEROES.
       01 WS-SQUARE-OF-SUM          PIC 9(08) VALUE ZEROES.
       01 WS-SUM-OF-SQUARES         PIC 9(08) VALUE ZEROES.
       01 WS-DIFFERENCE-OF-SQUARES  PIC 9(08) VALUE ZEROES.
      *
       01 WS-SCRATCHPAD.
          05 WS-NTH-VALUE           PIC 9(03) VALUE ZEROES.
          05 WS-SUM                 PIC 9(06) VALUE ZEROES.
          05 WS-SQUARE              PIC 9(06) VALUE ZEROES.
      *
       PROCEDURE DIVISION.
      *
       DIFFERENCE-OF-SQUARES.
           COMPUTE WS-DIFFERENCE-OF-SQUARES =
             WS-SQUARE-OF-SUM - WS-SUM-OF-SQUARES.
      *
      *
       SQUARE-OF-SUM.
           MOVE ZEROES TO WS-SUM
           MOVE 1 TO WS-NTH-VALUE
      *
           PERFORM WS-NUMBER TIMES
             ADD WS-NTH-VALUE TO WS-SUM
             ADD 1 TO WS-NTH-VALUE
           END-PERFORM
      *
           COMPUTE WS-SQUARE-OF-SUM = WS-SUM ** 2.
      *
      *
       SUM-OF-SQUARES.
           MOVE ZEROES TO WS-SUM-OF-SQUARES
           MOVE 1 TO WS-NTH-VALUE
      *
           PERFORM WS-NUMBER TIMES
             COMPUTE WS-SQUARE = WS-NTH-VALUE ** 2
             ADD WS-SQUARE TO WS-SUM-OF-SQUARES
             ADD 1 TO WS-NTH-VALUE
           END-PERFORM.
      *

Tags:

paradigm:imperative
paradigm:procedural
technique:math
uses:COBOL
uses:IBM Z/Architecture

@ErikSchierboom
Copy link
Member Author

Exercise: collatz-conjecture

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. collatz-conjecture.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-NUMBER     PIC S9(8).
       01 WS-STEPS      PIC 9(4).
       01 WS-ERROR      PIC X(35).
       01 N             PIC S9(8).
       01 WS-REMAINDER  PIC 9.
       
       PROCEDURE DIVISION.
       COLLATZ-CONJECTURE.
         IF WS-NUMBER IS LESS THAN 1 THEN
            MOVE 0 TO WS-STEPS
            MOVE "Only positive integers are allowed" TO WS-ERROR
         ELSE
            IF WS-NUMBER = 1 THEN 
               MOVE 0 TO WS-STEPS
            ELSE
               MOVE 0 TO WS-STEPS
               PERFORM UNTIL WS-NUMBER EQUAL 1
                  ADD 1 TO WS-STEPS GIVING WS-STEPS
                  DIVIDE WS-NUMBER BY 2 GIVING N REMAINDER WS-REMAINDER
                  IF WS-REMAINDER = 0 THEN
                     COMPUTE WS-NUMBER = WS-NUMBER / 2
                  ELSE
                     COMPUTE WS-NUMBER = 3 * WS-NUMBER + 1
                  END-IF
               END-PERFORM
            END-IF
         END-IF         
      
         DISPLAY WS-STEPS.
         DISPLAY WS-ERROR.

Tags:

construct:add
construct:assignment
construct:char
construct:compute
construct:divide
construct:else
construct:if
construct:int
construct:integral-number
construct:move
construct:multiply
construct:number
construct:perform
construct:section
construct:string
construct:then
construct:until
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural

@ErikSchierboom
Copy link
Member Author

Exercise: bob

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. BOB.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-HEYBOB                PIC X(60).
       01 WS-RESULT                PIC X(40).
       01 ws-char                  pic X.
       PROCEDURE DIVISION.
       BOB.
           move FUNCTION REVERSE(function trim(WS-HEYBOB))(1:1)
               to ws-char
           evaluate true
               when WS-HEYBOB = spaces
                   move "Fine. Be that way!" to WS-RESULT
               when WS-HEYBOB equal function upper-case(WS-HEYBOB)
                   move "Whoa, chill out!" to WS-RESULT
               when WS-char = '?'
                   move "Shure." to WS-RESULT
               when other
                   move "Whatever." to WS-RESULT

           end-evaluate
       display WS-HEYBOB
       display WS-RESULT
       goback.
      
      

Tags:

construct:assignment
construct:char
construct:comment
construct:display
construct:divide
construct:end
construct:end-evaluate
construct:function
construct:identifier
construct:implicit-conversion
construct:invocation
construct:length
construct:move
construct:number
construct:parameter
construct:pic
construct:procedure
construct:section
construct:string
construct:to
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:functional
paradigm:reflective
technique:divide-and-conquer
technique:higher-order-functions

@ErikSchierboom
Copy link
Member Author

Exercise: bob

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. BOB.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-HEYBOB                PIC X(60).
       01 UPCASE                   PIC X(60).
       01 PUNCTUATION              PIC X.
       01 LEN                      PIC 9(2).
       01 COUNTER                  PIC 9(2).
       01 WS-RESULT                PIC X(40).
       01 A                        PIC X.
      *     88 NUMBERS VALUE "0" THROUGH "9".
       01 ONLY-NUMS                PIC 9 VALUE 1.
       

       PROCEDURE DIVISION.
       BOB.
           MOVE FUNCTION UPPER-CASE(WS-HEYBOB) TO UPCASE.
           MOVE FUNCTION TRIM(WS-HEYBOB) TO WS-HEYBOB.
           MOVE FUNCTION LENGTH(WS-HEYBOB) TO LEN.
           SUBTRACT 1 FROM LEN.
           MOVE WS-HEYBOB(LEN:1) TO PUNCTUATION.
           ADD 1 TO LEN.
           PERFORM IS-ONLY-NUMS.
           PERFORM REST.
       REST.
           EVALUATE TRUE
              WHEN LEN = 0 
                 MOVE "Fine. Be that way!" TO WS-RESULT
              WHEN PUNCTUATION = '?'
                 IF WS-HEYBOB = UPCASE 
                   MOVE "Calm down, I know what I'm doing!" TO WS-RESULT
                 ELSE
                   MOVE "Sure." TO WS-RESULT
                 END-IF
              WHEN ONLY-NUMS = 1
                 MOVE "Whatever." TO WS-RESULT
              WHEN WS-HEYBOB = UPCASE 
                 MOVE "Whoa, chill out!" TO WS-RESULT
              WHEN OTHER
                 MOVE "Whatever." TO WS-RESULT
           END-EVALUATE.
           GOBACK.
       IS-ONLY-NUMS.
           PERFORM VARYING COUNTER FROM 1 BY 1 UNTIL COUNTER = LEN 
              MOVE WS-HEYBOB(COUNTER:1) TO A
              IF A=0 OR A=1 OR A=2 OR A=3 OR A=4 OR A=5 OR A=6 OR A=7
                 OR A=8 OR A=9
                 COMPUTE ONLY-NUMS = ONLY-NUMS * 1
              ELSE
                 COMPUTE ONLY-NUMS = ONLY-NUMS * 0
              END-IF
           END-PERFORM.

Tags:

construct:assignment
construct:boolean
construct:char
construct:comment
construct:compute
construct:data-definition
construct:divide
construct:evaluate
construct:if
construct:implicit-conversion
construct:indexed
construct:integral-number
construct:invocation
construct:length
construct:logical-or
construct:move
construct:multiply
construct:nested
construct:number
construct:paragraph
construct:perform
construct:procedure
construct:section
construct:string
construct:subtract
construct:until
construct:variable
construct:visibility
paradigm:imperative
paradigm:procedural
technique:boolean-logic
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: two-fer

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. two-fer.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-NAME PIC X(16) VALUES 'you'.
       01 WS-RESULT PIC X(64).
       PROCEDURE DIVISION.
       TWO-FER.
         STRING 'One for ' DELIMITED BY SIZE
           WS-NAME DELIMITED BY SPACE
           ', one for me.' DELIMITED BY SIZE
           INTO WS-RESULT.

Tags:

construct:string
construct:assignment
construct:data-definition
construct:divide
construct:identification-division
construct:implicit-conversion
construct:into
construct:numeric-overflow
construct:paradigm
construct:procedure
construct:section
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:declarative

@ErikSchierboom
Copy link
Member Author

Exercise: raindrops

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. raindrops.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-NUMBER PIC 9(4).
       01 WS-RESULT PIC X(20). 


       PROCEDURE DIVISION.
       RAINDROPS.

           IF FUNCTION MOD(WS-NUMBER, 3) = 0
              STRING WS-RESULT DELIMITED BY SPACE
              'Pling' DELIMITED BY SIZE INTO WS-RESULT
           END-IF

           IF FUNCTION MOD(WS-NUMBER, 5) = 0
           STRING WS-RESULT DELIMITED BY SPACE
              'Plang' DELIMITED BY SIZE INTO WS-RESULT
           END-IF

           IF FUNCTION MOD(WS-NUMBER, 7) = 0
           STRING WS-RESULT DELIMITED BY SPACE
              'Plong' DELIMITED BY SIZE INTO WS-RESULT
           END-IF

           IF WS-RESULT = SPACES
              MOVE WS-NUMBER TO WS-RESULT
           END-IF

           EXIT
           .

       

Tags:

construct:assignment
construct:divide
construct:if
construct:integral-number
construct:into
construct:method
construct:number
construct:parameter
construct:procedure
construct:string
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural
technique:basic-arithmetic

@ErikSchierboom
Copy link
Member Author

Exercise: luhn

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. luhn.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       REPOSITORY. FUNCTION ALL INTRINSIC.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-CARD-NUMBER PIC X(32).
       01 WS-CARD-DIGITS.
          02 WS-DIGIT OCCURS 32 PIC 9.
       01 WS-CHECKSUM PIC 9.
       01 WS-VALID PIC X(5).
          88 LUHN-VALID VALUE 'VALID'.
          88 LUHN-FALSE VALUE 'FALSE'.
       01 N PIC 99.
       01 I PIC S99.
       01 WS-VALUE PIC 99.
       01 DOUBLING PIC X(10) VALUE '246813579'.
       
       PROCEDURE DIVISION.
       LUHN.
          SET LUHN-VALID TO TRUE
          MOVE ZEROS TO N
          MOVE ZEROS TO WS-CHECKSUM
          MOVE ZEROS TO WS-CARD-DIGITS
          PERFORM VARYING I FROM 1 BY 1
            UNTIL (I > 32) OR LUHN-FALSE
             EVALUATE WS-CARD-NUMBER(I:1)
                WHEN '0' THRU '9'
                     ADD 1 TO N
                     MOVE WS-CARD-NUMBER(I:1) TO WS-DIGIT(N)
                WHEN SPACES
                     CONTINUE
                WHEN OTHER
                     SET LUHN-FALSE TO TRUE
             END-EVALUATE
          END-PERFORM

          IF (N < 2)
             SET LUHN-FALSE TO TRUE
          END-IF
      
          IF (LUHN-VALID)
             ADD -1 TO N
             DISPLAY WS-CARD-DIGITS
             PERFORM VARYING I FROM N BY -2
               UNTIL (I < 1)
                IF (WS-DIGIT(I) NOT = 0)
                   MOVE DOUBLING(WS-DIGIT(I):1) TO WS-DIGIT(I)
                END-IF
             END-PERFORM
      
             ADD 1 TO N
             PERFORM VARYING I FROM 1 BY 1
               UNTIL (I > N)
                ADD WS-DIGIT(I) TO WS-CHECKSUM
             END-PERFORM

             IF WS-CHECKSUM NOT = 0
                SET LUHN-FALSE TO TRUE
             END-IF
          END-IF.

Tags:

construct:add
construct:boolean
construct:by-numeric-value
construct:char
construct:comment
construct:divide
construct:evaluate
construct:if
construct:implicit-conversion
construct:indexed
construct:int
construct:integral-number
construct:invocation
construct:move
construct:multiply
construct:number
construct:occurs
construct:or
construct:perform
construct:section
construct:set
construct:string
construct:subtract
construct:until
construct:value
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: roman-numerals

Code

000001 IDENTIFICATION DIVISION.
       PROGRAM-ID. ROMAN-NUMERALS.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-NUMBER PIC 9999.
       01 WS-RESULT PIC X(20) VALUE SPACES.
       01 WS-DIGIT    PIC 9.
       01 WS-PLACE    PIC 9999.
       01 WS-COUNTER  PIC 9.
       01 MAIN-CHAR   PIC X.
       01 MID-CHAR    PIC X.
       01 NEXT-CHAR   PIC X.
       01 WS-NEW-SPOT PIC 99.
      
       PROCEDURE DIVISION.
       ROMAN-NUMERALS.
           DISPLAY "I=1, V=5, X=10, L=50, C=100, D=500, M=1000"
      * II = 2, III = 3, VI = 6, AND LXX = 70, BUT IV = 4 AND XC = 90
      
           MOVE 1 TO WS-NEW-SPOT
           PERFORM VARYING WS-COUNTER FROM 1 BY 1 UNTIL WS-COUNTER > 4
              MOVE WS-NUMBER(WS-COUNTER:1) TO WS-DIGIT
              EVALUATE WS-COUNTER
                 WHEN 1 MOVE 1000 TO WS-PLACE
                 WHEN 2 MOVE  100 TO WS-PLACE
                 WHEN 3 MOVE   10 TO WS-PLACE 
                 WHEN 4 MOVE    1 TO WS-PLACE 
              END-EVALUATE 
      *       DISPLAY WS-PLACE "'S PLACE: " WS-DIGIT
              PERFORM CHARACTER-PLACEMENT
           END-PERFORM

           DISPLAY "ORIGINAL INPUT: " WS-NUMBER
           DISPLAY "ROMAN NUMERAL: " WS-RESULT

           STOP RUN.
      
      * FUNCTION TO PLACE THE CHARACTERS
       CHARACTER-PLACEMENT.
      * CHECK BY PLACE
      * IF 1'S PLACE < 0, PUT NOTHING
      * IF 1'S PLACE 1-3, I = 1, II = 2, III = 3
      * IF 1'S PLACE = 4, PUT IT AS 1 LESS THAN 5, OR IV
      * IF 1'S PLACE = 6-8, THEN 6 = VI, 7 = VII, 8 = VIII
      * IF 1'S PLACE = 9, THEN PUT IT AS 1 LESS THAN 10, OR IX
      * SAME CONCEPT FOR ALL OTHER PLACES
           EVALUATE WS-PLACE 
              WHEN 1000   MOVE "M" TO MAIN-CHAR
              WHEN  100   MOVE "C" TO MAIN-CHAR
                          MOVE "D" TO MID-CHAR
                          MOVE "M" TO NEXT-CHAR
              WHEN   10   MOVE "X" TO MAIN-CHAR
                          MOVE "L" TO MID-CHAR
                          MOVE "C" TO NEXT-CHAR
              WHEN    1   MOVE "I" TO MAIN-CHAR
                          MOVE "V" TO MID-CHAR
                          MOVE "X" TO NEXT-CHAR
           END-EVALUATE 

           IF WS-DIGIT < 4 THEN 
      * IF 0, 1, 2, OR 3: PLACE THE MAIN CHARACTER THAT MANY TIMES
              PERFORM WS-DIGIT TIMES
                 ADD 1 TO WS-NEW-SPOT GIVING WS-NEW-SPOT
                 MOVE MAIN-CHAR TO WS-RESULT(WS-NEW-SPOT:1)
              END-PERFORM
           ELSE IF WS-DIGIT = 4 THEN 
      * IF 4: PLACE THE MAIN CHARACTER THEN THE MID CHARACTER
              ADD 1 TO WS-NEW-SPOT GIVING WS-NEW-SPOT 
              MOVE MAIN-CHAR TO WS-RESULT(WS-NEW-SPOT:1)
              ADD 1 TO WS-NEW-SPOT GIVING WS-NEW-SPOT 
              MOVE MID-CHAR TO WS-RESULT(WS-NEW-SPOT:1)
           ELSE IF WS-DIGIT = 5 THEN
      * IF 5: PLACE THE MID CHARACTER
              ADD 1 TO WS-NEW-SPOT GIVING WS-NEW-SPOT 
              MOVE MID-CHAR TO WS-RESULT(WS-NEW-SPOT:1)
           ELSE IF WS-DIGIT < 9 THEN 
      * IF 6, 7, OR 8: PLACE THE MID CHARACTER, THEN MAIN CHARACTERS AFTER IT
              ADD 1 TO WS-NEW-SPOT GIVING WS-NEW-SPOT 
              MOVE MID-CHAR TO WS-RESULT(WS-NEW-SPOT:1)
              PERFORM VARYING WS-COUNTER FROM 6 BY 1 UNTIL 
                 WS-COUNTER > WS-DIGIT 
                    ADD 1 TO WS-NEW-SPOT GIVING WS-NEW-SPOT 
                    MOVE MAIN-CHAR TO WS-RESULT(WS-NEW-SPOT:1)
              END-PERFORM
           ELSE IF WS-DIGIT = 9 THEN
      * IF 9: PLACE THE MAIN CHARACTER THEN THE NEXT CHARACTER
              ADD 1 TO WS-NEW-SPOT GIVING WS-NEW-SPOT 
              MOVE MAIN-CHAR TO WS-RESULT(WS-NEW-SPOT:1)
              ADD 1 TO WS-NEW-SPOT GIVING WS-NEW-SPOT 
              MOVE NEXT-CHAR TO WS-RESULT(WS-NEW-SPOT:1)
           END-IF.

Tags:

construct:assignment
construct:char
construct:comment
construct:evaluate
construct:if
construct:indexed
construct:int
construct:integral-number
construct:invocation
construct:label
construct:move
construct:number
construct:paragraph
construct:perform
construct:procedure
construct:run
construct:section
construct:stop
construct:string
construct:subtract
construct:then
construct:times
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:procedural
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: roman-numerals

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. ROMAN-NUMERALS.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-NUMBER PIC 9999.
       01 WS-RESULT PIC X(20).
       01 CONTADOR PIC 99.
       01 TEMP PIC 9.
       01 COUNTYEAR PIC 9.
       01 ROMANNUMERALS.
         05 RO-PLUS PIC X.
         05 RO-FIVE PIC X.
         05 RO-NEUTRAL PIC X.
         05 THEOTHERS PIC X(7).

       PROCEDURE DIVISION.

       ROMAN-NUMERALS.
       INITIALIZE WS-RESULT COUNTYEAR.
       MOVE "  MDCLXVI" TO ROMANNUMERALS.
       MOVE 1 TO CONTADOR.

       IF WS-NUMBER(1:1) < 4 THEN
         PERFORM VARYING COUNTYEAR FROM 1 BY 1 UNTIL COUNTYEAR > 4
          MOVE WS-NUMBER(COUNTYEAR:1) TO TEMP
          PERFORM THEROMANALGORITHM
          MOVE ROMANNUMERALS(3:7) TO ROMANNUMERALS
         END-PERFORM           
       END-IF.
       ROMAN-NUMERALS-END.

       THEROMANALGORITHM.
         IF TEMP = 9 THEN
           MOVE RO-NEUTRAL TO WS-RESULT(CONTADOR:1)
           ADD 1 TO CONTADOR
           MOVE RO-PLUS TO WS-RESULT(CONTADOR:1)
           ADD 1 TO CONTADOR
           MOVE 0 TO TEMP
         ELSE
           IF TEMP > 4 THEN
             MOVE RO-FIVE TO WS-RESULT(CONTADOR:1)
             ADD 1 TO CONTADOR
             COMPUTE TEMP = TEMP - 5
             PERFORM UNTIL TEMP = 0
               MOVE RO-NEUTRAL TO WS-RESULT(CONTADOR:1)
               ADD 1 TO CONTADOR
               COMPUTE TEMP = TEMP - 1
             END-PERFORM
           ELSE
             IF TEMP = 4 THEN
               MOVE RO-NEUTRAL TO WS-RESULT(CONTADOR:1)
               ADD 1 TO CONTADOR
               MOVE RO-FIVE TO WS-RESULT(CONTADOR:1)
               ADD 1 TO CONTADOR
               MOVE 0 TO TEMP
             ELSE
               PERFORM UNTIL TEMP = 0
               MOVE RO-NEUTRAL TO WS-RESULT(CONTADOR:1)
               ADD 1 TO CONTADOR
               COMPUTE TEMP = TEMP - 1
               END-PERFORM
             END-IF
           END-IF
         END-IF.

Tags:

construct:assignment
construct:add
construct:boolean
construct:char
construct:comment
construct:compute
construct:divide
construct:end
construct:end-perform
construct:environment
construct:if
construct:indexed
construct:initialize
construct:int
construct:integral-number
construct:invocation
construct:move
construct:number
construct:parameter
construct:perform
construct:procedure
construct:section
construct:string
construct:subtract
construct:then
construct:until
construct:variable
construct:visibility
paradigm:imperative
paradigm:declarative
technique:control-flow

@ErikSchierboom
Copy link
Member Author

Exercise: triangle

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. TRIANGLE.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
      *Incoming
       01 WS-SIDES PIC X(20).
       01 TABLE-SIDES.
          03 WS-SIDE OCCURS 3 PIC 9V9.
       01 WS-PROPERTY PIC X(11).
      *Outgoing
       01 WS-RESULT PIC 9.
       PROCEDURE DIVISION.
       TRIANGLE.
          MOVE ZEROS TO WS-RESULT
          UNSTRING WS-SIDES DELIMITED BY ',' 
              INTO WS-SIDE(1), WS-SIDE(2), WS-SIDE(3)
      
          IF (WS-SIDE(2) + WS-SIDE(3) > WS-SIDE(1)) AND
             (WS-SIDE(1) + WS-SIDE(3) > WS-SIDE(2)) AND
             (WS-SIDE(1) + WS-SIDE(2) > WS-SIDE(3))
             EVALUATE WS-PROPERTY
                WHEN 'equilateral'
                     IF (WS-SIDE(1) = WS-SIDE(2)) AND
                        (WS-SIDE(1) = WS-SIDE(3))
                        MOVE 1 TO WS-RESULT
                     END-IF
                WHEN 'isosceles'
                     IF (WS-SIDE(1) = WS-SIDE(2)) OR
                        (WS-SIDE(1) = WS-SIDE(3)) OR
                        (WS-SIDE(2) = WS-SIDE(3))
                        MOVE 1 TO WS-RESULT
                     END-IF
                WHEN 'scalene'
                     IF (WS-SIDE(1) NOT = WS-SIDE(2)) AND
                        (WS-SIDE(1) NOT = WS-SIDE(3)) AND
                        (WS-SIDE(2) NOT = WS-SIDE(3))
                        MOVE 1 TO WS-RESULT
                     END-IF
             END-EVALUATE
          END-IF.
          
          
       

Tags:

paradigm:imperative
paradigm:procedural
technique:boolean-logic

@ErikSchierboom
Copy link
Member Author

Exercise: queen-attack

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. QUEEN-ATTACK.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
      *Inputs
       01 WS-QUEEN PIC X(9).
       01 WS-WHITE_QUEEN PIC X(9).
       01 WS-BLACK_QUEEN PIC X(9).
       01 WS-PROPERTY PIC X(11).
      *Outputs
       01 WS-RESULT PIC 9.
       01 ws-local.
          03 ws-row    pic s9.
          03 ws-col    pic s9.
          03 ws-wr     pic 9.
          03 ws-wc     pic 9.
          03 ws-br     pic 9.
          03 ws-bc     pic 9.      
          03 ws-d1     pic 9.
          03 ws-d2     pic 9.
      
       PROCEDURE DIVISION.
       QUEEN-ATTACK.
           move 1 to ws-result
           evaluate true
            when WS-PROPERTY = "create"
               unstring WS-QUEEN delimited by "," into ws-row, ws-col
               if ws-col < 0 or ws-row < 0 or
                  ws-col > 7 or ws-row > 7 
                   move 0 to ws-result
            when WS-PROPERTY = "canAttack"
               unstring WS-WHITE_QUEEN delimited by "," 
                   into ws-wr, ws-wc
               unstring WS-BLACK_QUEEN delimited by "," 
                   into ws-br, ws-bc
               subtract ws-wr from ws-br giving ws-d1
               subtract ws-wc from ws-bc giving ws-d2
               if ws-wr <> ws-br and ws-wc <> ws-bc
                   if ws-d1 <> ws-d2
                       move 0 to ws-result
           end-evaluate
           display ws-result
       .
       QUEEN-ATTACK-EXIT.
       goback
       .
      

Tags:

construct:and
construct:assignment
construct:boolean
construct:comment
construct:evaluate
construct:if
construct:integral-number
construct:invocation
construct:logical-operators
construct:move
construct:number
construct:or
construct:procedure
construct:string
construct:subtract
construct:unstring
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:logical
paradigm:procedural
technique:boolean-logic

@ErikSchierboom
Copy link
Member Author

Exercise: scrabble-score

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SCRABBLE-SCORE.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 I PIC 99.
       01 C PIC X.
       01 WS-ORD PIC 99.
       01 WS-SCORE-VALUES PIC X(27) VALUE '97789686925979970999966260'.
       01 WS-SCORE PIC 99.

      *Inputs
       01 WS-WORD   PIC X(60).
      *Outputs
       01 WS-RESULT PIC 99.
       PROCEDURE DIVISION.
       SCRABBLE-SCORE.
          MOVE FUNCTION UPPER-CASE(WS-WORD) TO WS-WORD
          MOVE ZEROS TO WS-RESULT
          PERFORM VARYING I FROM 1 BY 1
            UNTIL (WS-WORD(I:1) = SPACE)
             MOVE WS-WORD(I:1) TO C
             COMPUTE WS-ORD = FUNCTION ORD(C) - 65
             MOVE WS-SCORE-VALUES(WS-ORD:1) TO WS-SCORE
             COMPUTE WS-SCORE = 10 - WS-SCORE
             ADD WS-SCORE TO WS-RESULT
          END-PERFORM.

Tags:

construct:assignment
construct:char
construct:comment
construct:compute
construct:data-description
construct:divide
construct:environment
construct:header
construct:implicit-conversion
construct:indexed
construct:int
construct:integral-number
construct:move
construct:number
construct:paragraph
construct:perform
construct:pic
construct:section
construct:string
construct:subtract
construct:tag
construct:to
construct:until
construct:using
construct:value
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:reflective
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: scrabble-score

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SCRABBLE-SCORE.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
      *Inputs
       01 WS-WORD   PIC X(60).
      *Outputs
       01 WS-RESULT PIC 99.
       01 ws-ix        pic 9(02).
       01 ws-points.
          05 ws-point pic 9 occurs 60 times.      
       PROCEDURE DIVISION.
       SCRABBLE-SCORE.
           move function lower-case(ws-word) to ws-points.
           inspect ws-points converting 'aeioulnrst' to '1111111111'
           inspect ws-points converting 'dg' to '22'
           inspect ws-points converting 'bcmp' to '3333'
           inspect ws-points converting 'fhvwy' to '44444'
           inspect ws-points converting 'k' to '5'
           inspect ws-points converting 'jx' to '88'
           inspect ws-points converting 'qz' to '00'
           perform varying ws-ix from 1 by 1 until ws-ix > 60
               if ws-point(ws-ix) is numeric
                   if ws-point(ws-ix) equal 0
                       add 10 to WS-RESULT
                   else
                       add ws-point(ws-ix) to WS-RESULT
                   end-if
               end-if
           end-perform
           display ws-points.
           display WS-RESULT.
           goback.      

Tags:

construct:add
construct:char
construct:class
construct:comment
construct:convert
construct:data-definition
construct:display
construct:divide
construct:end
construct:end-perform
construct:environment
construct:if
construct:inspect
construct:int
construct:integral-number
construct:invocation
construct:method
construct:move
construct:number
construct:occurs
construct:parameter
construct:perform
construct:pic
construct:procedure
construct:section
construct:string
construct:to
construct:until
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: allergies

Code

       IDENTIFICATION DIVISION.
       PROGRAM-ID. allergies.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-SCORE       PIC 999.
       01 WS-ITEM        PIC X(12).
       01 WS-RESULT      PIC A.
       01 WS-RESULT-LIST PIC X(108).
       01 WS-AUX-LIST PIC X(108).
       01 WS-ITEM-AUX    PIC X(12).
       01 WS-VALOR       PIC 9(03).
       01 WS-DIVISIBLE   PIC 9.
       PROCEDURE DIVISION.
       ALLERGIC-TO.
      * Code this paragraph
           PERFORM INICI-VALORES
           IF WS-SCORE > 0
              MOVE WS-SCORE TO WS-VALOR
              PERFORM CALCULAR-ALERG
           END-IF
           CONTINUE.
       LIST-ALLERGENS.
      * Code this paragraph
           PERFORM INICI-VALORES
           IF WS-SCORE > 0
              MOVE WS-SCORE TO WS-VALOR
              PERFORM CALCULAR-ALERG
           END-IF
           .
       CALCULAR-ALERG.
           IF WS-VALOR = 257
              MOVE "eggs" TO WS-AUX-LIST
              MOVE "Y"    TO WS-RESULT
              MOVE 0      TO WS-VALOR
           END-IF
           IF WS-VALOR > 127
              COMPUTE WS-DIVISIBLE = WS-VALOR / 128
              COMPUTE WS-VALOR = WS-VALOR - (128 * WS-DIVISIBLE)
              MOVE "cats" TO WS-ITEM-AUX
              PERFORM ARMA-CADENA
              IF WS-ITEM = 'cats'
                 MOVE 'Y' TO WS-RESULT
              END-IF
           END-IF
           IF ((WS-VALOR > 63) AND (WS-VALOR < 128))
              COMPUTE WS-VALOR = WS-VALOR - 64
              MOVE "pollen" TO WS-ITEM-AUX
              PERFORM ARMA-CADENA
              IF WS-ITEM = 'pollen'
                 MOVE 'Y' TO WS-RESULT
              END-IF
           END-IF
           IF ((WS-VALOR > 31) AND (WS-VALOR < 64))
              COMPUTE WS-VALOR = WS-VALOR - 32
              MOVE "chocolate" TO WS-ITEM-AUX
              PERFORM ARMA-CADENA
              IF WS-ITEM = 'chocolate'
                 MOVE 'Y' TO WS-RESULT
              END-IF
           END-IF
           IF ((WS-VALOR > 15) AND (WS-VALOR < 32))
              COMPUTE WS-VALOR = WS-VALOR - 16
              MOVE "tomatoes" TO WS-ITEM-AUX
              PERFORM ARMA-CADENA
              IF WS-ITEM = 'tomatoes'
                 MOVE 'Y' TO WS-RESULT
              END-IF
           END-IF
           IF ((WS-VALOR > 7)  AND (WS-VALOR < 16))
              COMPUTE WS-VALOR = WS-VALOR - 8
              MOVE "strawberries" TO WS-ITEM-AUX
              PERFORM ARMA-CADENA
              IF WS-ITEM = 'strawberries'
                 MOVE 'Y' TO WS-RESULT
              END-IF
           END-IF
           IF ((WS-VALOR > 3)  AND (WS-VALOR < 8))
              COMPUTE WS-VALOR = WS-VALOR - 4
              MOVE "shellfish" TO WS-ITEM-AUX
              PERFORM ARMA-CADENA
              IF WS-ITEM = 'shellfish'
                 MOVE 'Y' TO WS-RESULT
              END-IF
           END-IF
           IF ((WS-VALOR > 1)  AND (WS-VALOR < 4))
              COMPUTE WS-VALOR = WS-VALOR - 2
              MOVE "peanuts" TO WS-ITEM-AUX
              PERFORM ARMA-CADENA
              IF WS-ITEM = 'peanuts'
                 MOVE 'Y' TO WS-RESULT
              END-IF
           END-IF
           IF (WS-VALOR > 0)
              COMPUTE WS-VALOR = WS-VALOR - 1
              MOVE "eggs" TO WS-ITEM-AUX
              PERFORM ARMA-CADENA
              IF WS-ITEM = 'eggs'
                 MOVE 'Y' TO WS-RESULT
              END-IF
           END-IF
           MOVE WS-AUX-LIST TO WS-RESULT-LIST
           CONTINUE 
           .
       INICI-VALORES.
           INITIALIZE WS-VALOR
                      WS-RESULT-LIST
                      WS-DIVISIBLE
                      WS-AUX-LIST
           MOVE 'N' TO WS-RESULT
           .
       ARMA-CADENA.
           IF WS-AUX-LIST = SPACES
              MOVE WS-ITEM-AUX TO WS-RESULT-LIST
           ELSE
              STRING WS-ITEM-AUX ',' WS-AUX-LIST
                     DELIMITED BY ''
                     INTO WS-RESULT-LIST
           END-IF
           MOVE WS-RESULT-LIST TO WS-AUX-LIST
           MOVE SPACES TO WS-RESULT-LIST
           .

Tags:

construct:assignment
construct:comment
construct:compute
construct:continue
construct:divide
construct:if
construct:initialize
construct:integral-number
construct:logical-and
construct:move
construct:multiply
construct:number
construct:paragraph
construct:perform
construct:string
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:logical
technique:boolean-logic
uses:Multiplication

@ErikSchierboom
Copy link
Member Author

This is an automated comment

Hello 👋 Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant