Adjusting the result of query which is using round function - oracle

Suppose I have a query as:
Select round(column 1 - column 2) delta from table;
Now I want delta as delta -1 if (column 1 - column 2) results in a number with decimal value equal or more than 0.5 (like 100.65). Because the delta will be rounded to next whole number (like 101). But I want just delta (means 100 and not 101).
If (column 1 - column 2) results in a number with decimal value less than 0.5 (like 100.35) then the delta is automatically right (like 100 after rounding).
So the problem is occurring for rounding of (column 1 - column 2) when (column 1 - column 2) has a value greater than 0.5.

Related

Calculate Sum in matrix of SSRS report by column value

The report is designed to display the hours actually worked and the hours an employee should have worked between two specified dates. For this I used a matrix.
The problem is in total row. The actually worked hours are counted correctly, and the hours that the employee should have worked are counted not by the sum of the column, but as a Cartesian product.
Can I sum "Base Work Hours" by the column value?
On the picture above the total "Base Work Hours" should be 400.
My report:
WorkHours calculated as
select
(DATEDIFF(DAY, #dtStartDate, #dtEndDate) + 1
- DATEDIFF(WEEK, #dtStartDate, #dtEndDate) * 2
- CASE WHEN DATEPART(WEEKDAY, #dtStartDate) in (1, 7) THEN 1 ELSE 0 END
- CASE WHEN DATEPART(WEEKDAY, #dtEndDate) in (1, 7) THEN 1 ELSE 0 END
)
* WorkHoursDay
FROM tblEmpl

Finding the optimal sum of a 2D array

The problem statement goes like this:
Given an N x M array of (nonnegative) integers, find the optimal value of each column in the array, taking into account free rows.
A free row is anything in the range of [prevOld, prevNew]
Free rows are given starting values of:
prevOld = 0
prevNew = 0
so at the first step, only row 0 is free. If an element lies in a free row, it incurs no penalty.
If an element is not in a free row, then the penalty incurred is 2 * distance to closest free row - (e.g if free rows are [1,3] and our element is in row 5 then the element loses 2*(5-3) value. But if the element was in row 2, then no pentalty is incurred since 1 <= 2 <= 3
Once an element has been selected, free rows are updated as such:
prevOld = prevNew
prevNew = row of selected element
So if we begin with [x,y] and choose element in row z, then for the next column, free rows are now [y,z]
We are asked to solve this using an dynamic programming algorithm.
I am having a hell of a time coming up with a recurrence relation for this problem. I originally tried an algorithm that chooses the maximum element in a column based on a "real" value given the free rows, but this doesn't take into account the fact that sometimes we want to choose a lower value in our current column for a higher value in the next column. Any point in the right direction would be greatly appreciated.
EDIT
Sample input/output (no input/output was given, so putting this together from instructions):
Input: 3 x 3 array
4 5 7
7 8 7
1 9 10
First column is 4 7 1 and our starting rows are prevOld = 0 and prevNew = 0, [0,0]
so the 0th row is the only free row, with that, the "real" values of the first column are: 4 5 -3
4 is row 0, so it is free therefore its value is not affected
7 is in row 1, which is 1 away from the closest free row 0, so it loses 2*1 value, so 7 has a "real" value of 5
1 is in row 2, which is 2 away from the closest row, so it loses 2*2 value, so 1 has a "real" value of -3
With these real values we would select 7 (row 1) as our choice. Now we update prevOld and prevNew
prevOld = prevNew
prevNew = 1 (because we selected row 1)
so now we have [0,1] as the free rows and we move onto the next column: 5 8 9
Skipping ahead: real values of this column are
5 (row 0 is free, no loss)
8 (row 1 is free, no loss)
7 (row 2 is 1 away from the closest free row, so it loses 2*1 value)
so we choose 8 (row 1) and update prevOld and prevNew again:
prevOld = prevNew
prevNew = 1 (selected row)
free rows are now [1,1] for the final column: 7 7 10
real values are: 5 7 8, so we choose 8 and were done
Output is: 1 1 2 (the rows we selected in each column), total: 21 (total of the "real" values we selected in the rows)

How to implement a cumulative product table?

Given the following problem:
There is a sequence of k integers, named s for which there can be 2 operations,
1) Sum[i,j] -
What is the value of s[i]+s[i+1]+...+s[j]?
2) Update[i,val] -
Change the value of s[i] to val.
I am sure most people here have heard of using a cumulative frequency table/fenwick tree to optimize the complexity.
Now, if I don't want to query the sum but instead I want to perform the following:
Product[i,j] -
What is the value of s[i] * s[i+1] * ... * s[j]?
The new problem seems trivial at first, at least for the first operation Product[i,j].
Assuming I am using a cummulative product table named f:
At first thought, when we call Update[i,val], we should divide the cummulative products at f[z] for z from i -> j by the old value of s[i] then multiply by the new value.
But we will face 2 issues if the old value of s[i] is 0:
Division by 0. But this is easily tackled by checking if the old value of s[i] is 0.
The product of any real number with 0 is 0. This result will cause all other values from f[i] to f[j] to be 0. So we are unable to successfully perform Update[i,val]. This problem is not so trivial as it affects other values besides f[i].
Does anyone have any ideas how I could implement a cummulative product table that supports the 2 operations mentioned above?
Maintain 2 tables:
A cumulative product table, in which all zero entries have been stored as ones instead (to avoid affecting other entries).
A cumulative sum storing the number of zero entries. Each entry s[i] is 1 if f[i] is 0 and 0 if non-zero.
To compute the cumulative product, first calculate the cumulative sum of zero entries in the given range. If non-zero (i.e. there is 1 or more zero in the range) then the cumulative product is zero. If zero then calculate the cumulative product as you describe.
It might be more accurate to store your factors as logarithms in some base and compute the cumulative product as a sum of log values. You'd just be computing 2 cumulative sums. In that case you would need to store zero entries in the product table as log values of 0 (i.e. values of 1).
Here's an example, using a simple cumulative sum (not Fenwick trees, but you could easily use them instead):
row f cum_f isZero cum_isZero log(f) cum_log(f)
-1 1 1 0 0 0 0
0 3 3 0 0 0.477 0.477
1 0 3 1 1 -inf 0.477
2 4 12 0 1 0.602 1.079
3 2 24 0 1 0.301 1.38
4 3 72 0 1 0.477 1.857
row is the index, f is the factor, cum_f is the cumulative product of f treating zeros as if they were ones, isZero is a flag to indicate if f is zero, cum_isZero is the cumulative sum of the isZero flags, log(f) is the log of f in base 10, cum_log(f) is the cumulative sum of log_f, treating -inf as zero.
To calculate the sum or product of a range from row i to row j (inclusive), subtract row[i-1] from row[j], using row -1 as a "virtual" row.
To calculate the cumulative product of f in rows 0-2, first find the cumulative sum of isZero: cum_isZero[2] - cum_isZero[-1] = 1 - 0 = 1. That's non-zero, so the cumulative product is 0
To calculate the cumulative product of f in rows 2-4, do as above: cum_isZero[4] - cum_isZero[1] = 0 - 0 = 0. That's zero, so we can calculate the product.
Using cum_f: cum_f[4] / cum_f[1] = 72 / 3 = 24 = 4 x 2 x 3
Using cum_log_f: cum_log(f)[4] - cum_log(f)[1] = 1.857 - 0.477 = 1.38
101.38 = approx 24

Nullify a 2D matrix with some set of operations

Given an N x M matrix having only positive integer values, we have to nullify the matrix
i.e make all entries 0.
We are given two operations
1) multiply each element of any one column at a time by 2.
2) Subtract 1 from all elements of any one row at a time
Find the minimum number of operations required to nullify the matrix.
i thought of doing something related to LCM but could not reach to a solution
Let's first solve for 1 row first and we can extend it to all rows. Let's take a random example:
6 11 5 13
The goal is to make all elements as 1. First we make 5 (smallest element) as 1. For this we need to subtract 4 (i.e subtract 1 four times). The resultant array is:
2 7 1 9
Now we multiply 1 with 2 and subtract all row elements by 1:
1 6 1 8
Next, we multiply 2 1's by 2 and subtract all row elements by 1:
1 5 1 7
Continuing in this manner, we get to 1 1 1 1. Now we subtract 1 to get 0 0 0 0.
Next, we get to other rows and do the same like above. The row we nullified above are all zeroes so multiplication by 2 when manipulating other rows doesn't change the already nullified rows.
The question of finding the minimum number of operations would also depend on the row sequence we select. I think that would be to select a row whose maximum is minimum (among other rows) first. I need to verify this.

Matrix with equal sum of rows and columns

I have NxM matrix with integer elements, greater or equal than 0.
From any cell I can transfer 1 to another one (-1 to the source cell, +1 to the destination).
Using this operation, I have to make sums for all rows and columns equal. The question is how to find the minimal amount of such operations to achieve my task. During the processing cells may be negative.
For example, for
1 1 2 2
1 0 1 1
0 0 1 1
1 1 1 2
The answer is 3.
P.s.: I've tried to solve it on my own, but came only to brute-force solution.
First, find the expected sum per row and per column 1.
rowSum = totalSum / numRows
colSum = totalSum / numCols
Then, iterate through the rows and the columns and compute the following values:
rowDelta = 0
for each row r
if sum(r) > rowSum
rowDelta += sum(r) - rowSum
colDelta = 0
for each col c
if sum(c) > colSum
colDelta += sum(c) - colSum
The number of the minimum moves to equilibrate all the rows and columns is:
minMoves = max(rowDelta, colDelta)
This works because you have to transfer from rows that exceed rowSum into rows that don't exceed it, and from columns that exceed colSum into columns that don't exceed it.
If initially rowDelta was lower than colDelta, then you will attain a stage where you equilibrated all the rows, but the columns are still not equilibrated. At this case, you will continue transferring from cells to other cells in the same row. The same applies if initially colDelta was lower than rowDelta, and that's why we selected the maximum between them as the expected result.
1 If totalSum is not a multiple of numRows or numCols, then the problem has no solution.
Let us consider the one dimensional case: you have an array of numbers and you are allowed a single operation: take 1 from the value of one of the elements of the array and add it to other element. The goal is to make all elements equal with minimal operations. Here the solution is simple: you choose random "too big number" and add one to random "too small" number. Let me now describe how this relates to the problem at hand.
You can easily calculate the sum that is needed for every column and every row. This is the total sum of all elements in the matrix divided by the number of columns or rows respectively. From then on you can calculate which rows and columns need to be reduced and which - increased. see here:
1 1 2 2 -2
1 0 1 1 +1
0 0 1 1 +2
1 1 1 2 -1
+1+2-1-2
Expected sum of a row: 4
Expected sum of a column: 4
So now we generate two arrays: the array of displacements in the rows: -2,+1,+2,-1 and the number of displacements in the columns: +1,+2,-1,-2. For this two arrays we solve the simpler task described above. It is obvious that we can not solve the initial problem in fewer steps than the ones required for the simpler task (otherwise the balance in the columns or rows will not be 0).
However I will prove that the initial task can be solved in exactly as many steps as is the maximum of steps needed to solve the task for the columns and rows:
Every step in the simpler task generates two indices i and j: the index from which to subtract and the index to which to add. Lets assume in a step in the column task we have indices ci and cj and in the row task we have indices ri and rj. Then we assign a correspondence of this in the initial task: take 1 from (ci, ri) and add one to (cj, rj). At certain point we will reach a situation in which there might be still more steps in, say, the columns task and no more in the rows task. So we get ci and cj, but what do we do for ri and rj? We just choose ri=rj so that we do not screw up the row calculations.
In this solution I am making use of the fact I am allow to obtain negative numbers in the matrix.
Now lets demonstrate:
Solution for columns:
4->1;3->2;4->2
Solution for rows:
1->3;1->3;2->4
Total solution:
(4,1)->(1,3);(3,1)->(2,3);(4,2)->(2,4)
Supose thar r1 is the index of a row with maximal sum, while r2 is the row with minimal sum. c1 column with maximal sum and c2 column with minimal.
You need to repeat the following operation:
if Matrix[r1][c1] == Matrix[r2][c2] we're done!
Otherwise, Matrix[r1][c1] -= 1 and Matrix[r2][c2] += 1

Resources