Skip to content

Instantly share code, notes, and snippets.

@Edward-H
Created February 28, 2017 22:22
Show Gist options
  • Save Edward-H/07e1b40802d37f9905362be8afd0502c to your computer and use it in GitHub Desktop.
Save Edward-H/07e1b40802d37f9905362be8afd0502c to your computer and use it in GitHub Desktop.
Daily programmer #304 Easy Challenge solution in COBOL
>>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