Bankers algorithm in cobol - multidimensional-array

The issue I am getting is that line COLUMNS that i define in the working storage
section and when it is used within the 200-BANKER-FILL section is giving me a
syntax error in which COLUMNS is unexpected. the actual error is
'error: syntax error, unexpected COLUMNS'
I cannot seem to understand how the declaration of COLUMNS within the working storage section would be considered unexpected, any help would be great
IDENTIFICATION DIVISION.
PROGRAM-ID.BankerAlgoritm.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT BANKER-FILE-IN ASSIGN TO 's1.txt'
ORGANIZATION IS LINE SEQUENTIAL.
*> FUNCTION NUMVAL (STRING)
DATA DIVISION.
FILE SECTION.
FD BANKER-FILE-IN.
01 BANKER-LINE PIC X(9).
WORKING-STORAGE SECTION.
01 ARE-THERE-MORE-RECORDS PIC X(3) VALUE 'YES'.
88 NO-MORE-RECORDS VALUE 'NO '.
01 ROWS PIC 9.
01 COLUMNS PIC 9.
01 BANKER-TABLE-ASSIGN.
05 ASSIGN-ROW OCCURS 5 TIMES INDEXED BY X.
10 ASSIGN-COLUMN OCCURS 4 TIMES INDEXED BY Y.
20 ASSIGN-RESOURCE PIC 9.
01 BANKER-TABLE-MAX.
05 MAX-ROW OCCURS 5 TIMES INDEXED BY X.
10 MAX-COLUMN OCCURS 4 TIMES INDEXED BY Y.
20 MAX-RESOURCE PIC 9.
01 BANKER-TABLE-AVAL.
05 AVAL-COLUMN OCCURS 4 TIMES INDEXED BY Y.
10 AVAL-RESOURCE PIC 9.
01 BANKER-TABLE-REQUEST.
05 REQUEST-COLUMN OCCURS 4 TIMES INDEXED BY Y.
10 REQUEST-RESOURCE PIC 9.
01 BANKER-REQUEST-LINE.
05 REQUEST-LINE PIC 9.
05 SPACER PIC X.
05 REQUEST-ONE PIC 9.
05 PIC X.
05 REQUEST-TWO PIC 9.
05 PIC X.
05 REQUEST-THREE PIC 9.
05 PIC X.
05 REQUEST-FOUR PIC 9.
01 MATRIX.
05 ONE PIC 9.
05 PIC X.
05 TWO PIC 9.
05 PIC X.
05 THREE PIC 9.
05 PIC X.
05 FOUR PIC 9.
01 HOLDING-VAL-SINGLE PIC 9.
01 LINE-COUNT PIC 99 VALUE 0.
01 SAFE-STATE PIC XXXXX VALUE 'FALSE'.
PROCEDURE DIVISION.
*>****************************************
*> Controls direction of program logic *
*> and reads the first record. *
*>****************************************
100-MAIN-MODULE.
PERFORM UNTIL NO-MORE-RECORDS
READ BANKER-FILE-IN
AT END
MOVE 'NO ' TO ARE-THERE-MORE-RECORDS
NOT AT END
PERFORM 200-BANKER-FILL
END-READ
END-PERFORM
*> PERFORM 300-FILL-NEED
*> PERFORM 400-SAFE-STATE
*>IF SAFE-STATE = 'TRUE'
*> PERFORM 500-REQUEST
*> PERFORM 600-END-OF-JOB-RTN
STOP RUN.
200-BANKER-FILL.
ADD 1 TO LINE-COUNT
IF LINE-COUNT IS EQUAL TO 1
MOVE BANKER-LINE TO ROWS
END-IF
IF LINE-COUNT IS EQUAL TO 3
MOVE BANKER-LINE TO COLUMNS
END-IF
IF LINE-COUNT >= 5 AND <= 10
*>FILL ASSIGNED MATRIX
MOVE BANKER-LINE TO MATRIX
MOVE ONE TO ASSIGN-COLUMN(LINE-COUNT - 4, 1)
MOVE TWO TO ASSIGN-COLUMN(LINE-COUNT - 4, 2)
MOVE THREE TO ASSIGN-COLUMN(LINE-COUNT - 4, 3)
MOVE FOUR TO ASSIGN-COLUMN(LINE-COUNT - 4, 4)
END-IF
IF LINE-COUNT >= 12 AND <= 17
*>FILL IN MAX MATRIX
MOVE BANKER-LINE TO MATRIX
MOVE ONE TO MAX-COLUMN(LINE-COUNT - 11, 1)
MOVE TWO TO MAX-COLUMN(LINE-COUNT - 11, 2)
MOVE THREE TO MAX-COLUMN(LINE-COUNT - 11, 3)
MOVE FOUR TO MAX-COLUMN(LINE-COUNT - 11, 4)
END-IF
IF LINE-COUNT = 19
*> FILL IN AVAILIBLE MATRIX
MOVE BANKER-LINE TO MATRIX
MOVE ONE TO AVAL-COLUMN(1)
MOVE TWO TO AVAL-COLUMN(2)
MOVE THREE TO AVAL-COLUMN(3)
MOVE FOUR TO AVAL-COLUMN(4)
END-IF
IF LINE-COUNT = 21
*> FILL IN REQUEST
MOVE BANKER-LINE TO BANKER-REQUEST-LINE
END-IF.
*>*************************************************
*> Performed from 100-MAIN-MODULE. Closes files *
*>*************************************************
600-END-OF-JOB-RTN.
CLOSE BANKER-FILE-IN.
the next part is the input file
5
4
0 0 1 2
1 0 0 0
1 3 5 4
0 6 3 2
0 0 1 4
0 0 1 2
1 7 5 0
2 3 5 6
0 6 5 2
0 6 5 6
1 5 2 0
1:0 4 2 0

COLUMN is a reserved word in COBOL.
Here is a list of reserved words for future reference.

Related

How to derive a formula?

I have two 5x5 diamond grids,
Grid1: Y values are,
0
1 1
2 2 2
3 3 3 3
4 4 4 4 4
5 5 5 5
6 6 6
7 7
8
Grid2: X values are,
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3
0 1 2
0 1
0
I need to derive a formula to get Grid3 values related to X, Y, and gridSize. expecting the below values in Grid3 (index values),
00
01 02
03 04 05
06 07 08 09
10 11 12 13 14
15 16 17 18
19 20 21
22 23
24
What could be the formula which can be used to get Grid3 values?
To create a function getindex(x,y,size) returning the index, the first thing to notice is that because the index values increase from left to right first, the following identity always holds: getindex(x+1,y,size) = getindex(x,y,size)+1.
So we have
getindex(x,y,size): return x+[something involving only y and size]
Let's look at the index values for x=0. They start off as 0,1,3,6,10... for y=0,1,2.... These are the triangular numbers 0, 1, 1+2, 1+2+3, 1+2+3+4... and there's a closed-form solution y*(y+1)/2.
So our function, for the top half of the grid, looks like:
getindex(x,y,size): return x+y*(y+1)/2
When are we in the bottom half? When y>size. What do we do then? Count triangular numbers backwards from the bottom line. There are a total of (size*2-1) lines, so to flip the y coordinate we can replace y by (size*2-1)-y. Note that when y equals size we're in both the top and bottom half as far as this calculation is concerned.
Our function so far:
getindex(x,y,size): return x+((y<size) ? y*(y+1)/2 : size*size-(size*2-1-y)*(size*2-1-y+1)/2)
We should probably check for values that aren't actually in the grid. When are values not in the grid? When x or y is less than zero (off the top or left), or x>y (off the right in the top half), or x>=(size*2-1)-y (off the right in the bottom half) or y>size*2-1 (off the bottom).
So here we go:
function getindex(x,y,size):
if (x<0) return "off to the left"
if (y<0) return "off to the top"
if (x>y) return "off to the right (top half)"
if (x>=(size*2-1-y)) return "off to the right (bottom half)"
if (y>size*2-1) return "off the bottom"
return x+((y<size) ? y*(y+1)/2 : size*size-(size*2-1-y)*(size*2-1-y+1)/2)
Test it:
size = 5
counts = []
for (y in 0..10):
for (x in 0..10):
index = getindex (x, y, size)
print x, y, index
if index is OK:
counts[index]++
Now check that each grid value was produced precisely once:
assert (keys(counts) == size*size)
for i in (0..size*size-1):
assert (counts[i] == 1)
Writing a function to go in the reverse direction is left as an exercise :)

hex convert to datetime

Need some help to determine how is this date/time being encoded
Here are some examples (known date only):
2B5F0200 -> 31/10/2021
2B9F0200 -> 31/12/2021
2C3F0200 -> 31/01/2022
I don't understand how this datetime format works.
First, since the last two bytes are the same in all cases, let's focus on the first two bytes. Look at them in binary:
0x2B5F: 0b_0010_1011_0101_1111
0x2B9F: 0b_0010_1011_1001_1111
0x2C3F: 0b_0010_1100_0011_1111
Next, consider the binary representation for the numbers in the dates. In some date formats, months are 0-based (January is 0), in others they're 1-based, so include both.
21: 0b_1_0101
22: 0b_1_0110
10: 0b_1010, 0b_1001
12: 0b_1010, 0b_1001
01: 0b_0001, 0b_0000
31: 0b_1_1111
By inspection, each of these binary numerals appears in the appropriate date. 31 is the last 5 bits. The next 4 bits are 10, 12 and 1. 21 and 22 show up in the first 7 bits (for 100 years, you'll need at least 7 bits).
21 10 31
0x2B5F: 0b_0010101_1010_11111
21 12 31
0x2B9F: 0b_0010101_1100_11111
22 1 31
0x2C3F: 0b_0010110_0001_11111
The format is thus a packed bit-field:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-------------+-------+---------+
| year (YY) | month | day |
+-------------+-------+---------+
Or, as bit masks:
year: 0xFE00
month: 0x01E0
day: 0x001F

SSRS Expression Count values in one column where values in first column equal each other

I have searched for an answer with no luck. I've tried Lookup and CountDistinct.
In the table below I need to count the number of distinct Records that have both an A and B in box 1. I'd like to do this in an expression as I want to use the same dataset to pull up other combinations of results. Please note I have multiple datasets in this report. There's a reason for this insanity. I greatly appreciate any help.
Record Box File
01 1 A
01 1 B
01 2 B
01 2 B
02 1 A
02 1 B
02 2 B
03 1 B
03 1 B
Try to adjust your table a little bit to have the File column in the detailed row, then add a parent group by Box. In your detailed row, use the count expression on File.

How do I repeat only a part of a vector?

I have a vector of: 0,24,12,12,12,96,12,12,12,12,12,12.
I want to repeat only a part of it from 96 to the last element (12). The first part (0, 24, 12, 12, 12) I want to keep constant.
Could you please help ?
The answer depends on whether number 96 is always located at the 6th position inside your vector. If so, please refer to the first comment underneath your question. If the position is variable, however, you could implement a simple query that identifies the position of 96 inside your vector, and then repeat the part of the vector starting from there as often as you wish (2 times in the below-mentioned code).
x <- c(0,24,12,12,12,96,12,12,12,12,12,12)
# Identify index of 96
id <- which(x == 96)
# Repeat part of vector starting from `id` 2 times
c(x[1:(id-1)], rep(x[id:length(x)], 2))
# # Which results in
# [1] 0 24 12 12 12 96 12 12 12 12 12 12 96 12 12 12 12 12 12

Using a sqlite index for both a WHERE and an ORDER BY

I have a table that looks like this:
CREATE TABLE foo (type integer, priority integer);
'type' is one of a small number of values.
I want to do a query to select a sample rows of some type ordered by priority:
SELECT * FROM foo WHERE type = 0 ORDER BY priority DESC LIMIT 100;
I'm trying to create an index to make this fast. But it seems like sqlite doesn't allow me to handle both of the following cases:
Most items in foo have type = 0. In that case we should use the index to find the highest priority items and then check which ones have type = 0.
Most items in foo have type != 0. In that case we should use an index on type to find items of type = 0 and then sort them.
I can get sqlite to use either of these, but I can't figure out if it's possible to have a single index/query that's efficient for both cases. It seems like an index on (type, priority) would work, but it looks like sqlite is only using it for the first lookup and not the ORDER BY.
A single index on both columns allows to use an execution plan that is efficient in both cases:
> CREATE INDEX t_p ON foo(type, priority);
> EXPLAIN QUERY PLAN SELECT * FROM foo WHERE type = 0 ORDER BY priority DESC LIMIT 100;
0|0|0|SEARCH TABLE foo USING COVERING INDEX t_p (type=?)
> .explain on
> EXPLAIN SELECT * FROM foo WHERE type = 0 ORDER BY priority DESC LIMIT 100;
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Trace 0 0 0 00
1 Noop 0 0 0 00
2 Integer 100 1 0 00
3 Goto 0 15 0 00
4 OpenRead 2 3 0 k(3,B,B,B) 00
5 Integer 0 2 0 00
6 SeekLe 2 13 2 1 00
7 IdxLT 2 13 2 1 00
8 Column 2 0 4 00
9 Column 2 1 5 00
10 ResultRow 4 2 0 00
11 IfZero 1 13 -1 00
12 Prev 2 7 0 00
13 Close 2 0 0 00
14 Halt 0 0 0 00
15 Transaction 0 0 0 00
16 VerifyCookie 0 2 0 00
17 TableLock 0 2 0 foo 00
18 Goto 0 4 0 00
First, SQLite opens the index and quickly searches the last record where the type column is less than or equal to zero (6 SeekLe).
Then it returns results from the index, going backwards (12 Prev), until it encounters an index entry where the type column is less than zero (7 IdxLT).
This is a single scan through the index that never needs to skip over an unwanted entry.

Resources