Created
February 28, 2017 22:22
-
-
Save Edward-H/07e1b40802d37f9905362be8afd0502c to your computer and use it in GitHub Desktop.
Daily programmer #304 Easy Challenge solution in COBOL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
>>SOURCE FREE | |
IDENTIFICATION DIVISION. | |
FUNCTION-ID. get-month-num. | |
DATA DIVISION. | |
WORKING-STORAGE SECTION. | |
01 month-name-table-area VALUE "JANFEBMARAPRMAYJUNJULAUGSEPOCT"- | |
"NOVDEC". | |
03 month-name-table PIC X(3) OCCURS 12 TIMES. | |
LINKAGE SECTION. | |
01 month-name PIC X(3). | |
01 month-num PIC 99. | |
PROCEDURE DIVISION USING month-name RETURNING month-num. | |
PERFORM VARYING month-num FROM 1 BY 1 | |
UNTIL month-name-table (month-num) = month-name | |
CONTINUE | |
END-PERFORM | |
. | |
END FUNCTION get-month-num. | |
IDENTIFICATION DIVISION. | |
PROGRAM-ID. little-accountant. | |
ENVIRONMENT DIVISION. | |
CONFIGURATION SECTION. | |
REPOSITORY. | |
FUNCTION get-month-num | |
. | |
INPUT-OUTPUT SECTION. | |
FILE-CONTROL. | |
SELECT journal ASSIGN "journal.txt" | |
LINE SEQUENTIAL. | |
SELECT chart ASSIGN "chart.txt" | |
LINE SEQUENTIAL. | |
DATA DIVISION. | |
FILE SECTION. | |
FD journal. | |
01 journal-entry PIC X(100). | |
FD chart. | |
01 chart-entry PIC X(100). | |
WORKING-STORAGE SECTION. | |
01 account-debit PIC 9(8) VALUE ZERO. | |
01 account-credit PIC 9(8) VALUE ZERO. | |
01 account-balance PIC S9(8) VALUE ZERO. | |
01 num-chart-entries PIC 9(4). | |
01 chart-entries-area. | |
03 chart-entries OCCURS 1 TO 20 TIMES | |
DEPENDING ON num-chart-entries | |
INDEXED BY chart-idx. | |
05 account-num PIC 9(4). | |
05 account-name PIC X(20). | |
01 first-account PIC 9(4). | |
01 first-account-str PIC X(4). | |
01 first-period PIC X(6). | |
01 first-period-month PIC 99. | |
01 first-period-month-name PIC X(3). | |
01 first-period-year PIC 9999. | |
01 first-period-year-digits PIC 99. | |
01 formatted-balance PIC -(15)9. | |
01 formatted-credit PIC -(15)9. | |
01 formatted-debit PIC -(15)9. | |
01 input-str PIC X(80). | |
01 num-journal-entries PIC 9(4). | |
01 journal-entries-area. | |
03 journal-entries OCCURS 1 TO 1000 TIMES | |
DEPENDING ON num-journal-entries | |
ASCENDING KEY year, month | |
INDEXED BY journal-idx. | |
05 account-num PIC 9(4). | |
05 credit PIC 9(8). | |
05 debit PIC 9(8). | |
05 month PIC 99. | |
05 year PIC 9(4). | |
01 last-account PIC 9(4). | |
01 last-account-str PIC X(4). | |
01 last-period PIC X(6). | |
01 last-period-month PIC 99. | |
01 last-period-month-name PIC X(3). | |
01 last-period-year PIC 9(4). | |
01 last-period-year-digits PIC 99. | |
01 last-two-year-digits PIC 99. | |
01 month-name PIC X(3). | |
01 output-format PIC X(4). | |
88 text-output VALUE "TEXT". | |
88 csv-output VALUE "CSV". | |
01 selected-debit PIC 9(8) VALUE ZERO. | |
01 selected-credit PIC 9(8) VALUE ZERO. | |
01 selected-balance PIC S9(8) VALUE ZERO. | |
01 total-credit PIC 9(8) VALUE ZERO. | |
01 total-debit PIC 9(8) VALUE ZERO. | |
PROCEDURE DIVISION. | |
PERFORM load-journal | |
PERFORM load-chart | |
PERFORM accept-user-input | |
PERFORM produce-report | |
GOBACK | |
. | |
load-journal SECTION. | |
OPEN INPUT journal | |
*> Skip headings line. | |
READ journal | |
PERFORM VARYING num-journal-entries FROM 1 BY 1 UNTIL 1 <> 1 | |
READ journal | |
AT END | |
EXIT PERFORM | |
END-READ | |
UNSTRING journal-entry DELIMITED BY ";" OR "-" | |
INTO account-num OF journal-entries (num-journal-entries), | |
month-name, last-two-year-digits, debit (num-journal-entries), | |
credit (num-journal-entries) | |
MOVE FUNCTION get-month-num(month-name) TO month (num-journal-entries) | |
MOVE FUNCTION YEAR-TO-YYYY(last-two-year-digits) | |
TO year(num-journal-entries) | |
ADD debit (num-journal-entries) TO total-debit | |
ADD credit (num-journal-entries) TO total-credit | |
END-PERFORM | |
CLOSE journal | |
IF total-debit <> total-credit | |
DISPLAY "ERROR: Books are unbalanced." | |
DISPLAY "Debit: " total-debit | |
DISPLAY "Credit: " total-credit | |
STOP RUN WITH ERROR STATUS | |
END-IF | |
SET num-journal-entries DOWN BY 1 | |
SORT journal-entries ASCENDING year, month | |
. | |
load-chart SECTION. | |
OPEN INPUT chart | |
*> Skip headers line. | |
READ chart | |
PERFORM VARYING num-chart-entries FROM 1 BY 1 UNTIL 1 <> 1 | |
READ chart | |
AT END | |
EXIT PERFORM | |
END-READ | |
UNSTRING chart-entry DELIMITED BY ";" | |
INTO account-num OF chart-entries (num-chart-entries), | |
account-name (num-chart-entries) | |
END-PERFORM | |
SET num-chart-entries DOWN BY 1 | |
SORT chart-entries ASCENDING account-num OF chart-entries | |
CLOSE chart | |
. | |
accept-user-input SECTION. | |
ACCEPT input-str | |
UNSTRING input-str DELIMITED BY SPACES INTO first-account-str, | |
last-account-str, first-period, last-period, output-format | |
IF first-account-str = "*" | |
MOVE account-num OF chart-entries (1) TO first-account | |
ELSE | |
*> Turn a partial account number into a complete one, e.g. 12 -> 1200. | |
INSPECT first-account-str REPLACING ALL SPACE BY "0" | |
MOVE first-account-str TO first-account | |
END-IF | |
IF last-account-str = "*" | |
MOVE account-num OF chart-entries (num-chart-entries) TO last-account | |
ELSE | |
INSPECT last-account-str REPLACING ALL SPACE BY "0" | |
MOVE last-account-str TO last-account | |
END-IF | |
IF first-period = "*" | |
MOVE month (1) TO first-period-month | |
MOVE year (1) TO first-period-year | |
ELSE | |
UNSTRING first-period DELIMITED BY "-" INTO first-period-month-name, | |
first-period-year-digits | |
MOVE FUNCTION get-month-num(first-period-month-name) TO first-period-month | |
MOVE FUNCTION YEAR-TO-YYYY(first-period-year-digits) TO first-period-year | |
END-IF | |
IF last-period = "*" | |
MOVE month (num-journal-entries) TO last-period-month | |
MOVE year (num-journal-entries) TO last-period-year | |
ELSE | |
UNSTRING last-period DELIMITED BY "-" INTO last-period-month-name, | |
last-period-year-digits | |
MOVE FUNCTION get-month-num(last-period-month-name) TO last-period-month | |
MOVE FUNCTION YEAR-TO-YYYY(last-period-year-digits) TO last-period-year | |
END-IF | |
. | |
produce-report SECTION. | |
PERFORM output-report-headers | |
PERFORM output-balances | |
. | |
output-report-headers SECTION. | |
DISPLAY "Total debit: " FUNCTION TRIM(total-debit) | |
" Total credit: " FUNCTION TRIM(total-credit) | |
DISPLAY "Balance from account " first-account " to " last-account | |
" from period " first-period-month-name "-" first-period-year-digits | |
" to " last-period-month-name "-" last-period-year-digits | |
DISPLAY SPACE | |
DISPLAY "Balance:" | |
IF text-output | |
PERFORM output-table-header | |
ELSE | |
PERFORM output-csv-header | |
END-IF | |
. | |
output-balances SECTION. | |
*> Find first account to report on. | |
SET chart-idx TO 1 | |
SEARCH chart-entries | |
AT END | |
EXIT SECTION | |
WHEN account-num OF chart-entries (chart-idx) >= first-account | |
CONTINUE | |
END-SEARCH | |
*> Output balance for each account in ascending order. | |
PERFORM VARYING chart-idx FROM chart-idx BY 1 | |
UNTIL chart-idx > num-chart-entries | |
OR account-num OF chart-entries (chart-idx) > last-account | |
*> Find final debit and credit of account | |
SET journal-idx TO 1 | |
INITIALIZE account-debit, account-credit, account-balance | |
PERFORM UNTIL EXIT | |
SEARCH journal-entries | |
AT END | |
EXIT PERFORM | |
WHEN account-num OF journal-entries (journal-idx) | |
= account-num OF chart-entries (chart-idx) | |
ADD debit (journal-idx) TO account-debit, selected-debit | |
ADD credit (journal-idx) TO account-credit, selected-credit | |
END-SEARCH | |
SET journal-idx UP BY 1 | |
END-PERFORM | |
SUBTRACT account-credit FROM account-debit GIVING account-balance | |
ADD account-balance TO selected-balance | |
MOVE account-debit TO formatted-debit | |
MOVE account-credit TO formatted-credit | |
MOVE account-balance TO formatted-balance | |
IF text-output | |
PERFORM output-table-line | |
ELSE | |
PERFORM output-csv-line | |
END-IF | |
END-PERFORM | |
MOVE selected-debit TO formatted-debit | |
MOVE selected-credit TO formatted-credit | |
MOVE selected-balance TO formatted-balance | |
IF text-output | |
PERFORM output-table-footer | |
ELSE | |
PERFORM output-csv-footer | |
END-IF | |
. | |
output-table-header SECTION. | |
DISPLAY "ACCOUNT |DESCRIPTION | DEBIT| CREDIT| BALANCE|" | |
DISPLAY "-------------------------------------------------------------------------------------" | |
. | |
output-csv-header SECTION. | |
DISPLAY "ACCOUNT;DESCRIPTION;DEBIT;CREDIT;BALANCE;" | |
. | |
output-table-line SECTION. | |
DISPLAY account-num OF chart-entries (chart-idx) " |" | |
account-name OF chart-entries (chart-idx) (1:16) "|" | |
formatted-debit "|" formatted-credit "|" formatted-balance "|" | |
. | |
output-csv-line SECTION. | |
DISPLAY account-num OF chart-entries (chart-idx) ";" | |
FUNCTION TRIM(account-name OF chart-entries (chart-idx)) ";" | |
FUNCTION TRIM(formatted-debit) ";" FUNCTION TRIM(formatted-credit) ";" | |
FUNCTION TRIM(formatted-balance) ";" | |
. | |
output-table-footer SECTION. | |
DISPLAY "TOTAL | |" formatted-debit "|" | |
formatted-credit "|" formatted-balance "|" | |
. | |
output-csv-footer SECTION. | |
DISPLAY "TOTAL;;" FUNCTION TRIM(formatted-debit) ";" | |
FUNCTION TRIM(formatted-credit) ";" FUNCTION TRIM(formatted-balance) ";" | |
. | |
END PROGRAM little-accountant. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment