Check overlapping series in C# - overlapping

I am making an application where the user adds start and end to define a range
The condition is that the range should not overlap:
How to check whether a number range is not overlapping e.g.
Range 1 Start 5 End 15
Range 2 Start 1 End 4
Range 3 Start 16 End 20
Range 4 Start 2 End 4
So the Range 4 makes the set invalid, how do I check this in C#.
Further the user can add the range in any order as in the example above, the entire series should be non overlapping.
Thanks for the help suggestion.
Regards,
Sakshi
Answer:
I made the solution is it correct:
If start and end is the range which needs to be validated then
start >startRange and start less than endRange
end>startRange and end less than endRange
The above 2 condition validates that the series is overlapping.
Where startRange and endRange is the start and end for all existing ranges.

The OP suggests two checks to validate that a new range does not overlap with an existing range. However, these two checks do not cover all the possibilities. For instance, if the existing range is (4,10) and the new range is (2,12), it will not be flagged, because it starts prior to the start of the existing range, and ends afterwards.
Instead, I'd recommend the following approach:
if (newRangeStart <= existingRangeEnd && newRangeEnd >= existingRangeStart) {
// we have an overlap
}
Essentially, there are four possibilities of overlapping ranges:
A range which starts before the existing range and ends within the existing range
A range which starts within the existing range and ends afterward
A range which starts within the existing range and ends within the existing range
A range which starts before the existing range and ends after the existing range
Cases (1) and (2) include partial overlap, while cases (3) and (4) include complete overlap (either the existing range completely encloses the new range [case 3] or the new range completely encloses the existing range [case 4]).
The OP's code catches cases 1, 2 and 3, but not case 4. The code here catches all 4 possibilities of an overlapping range.

Ranges need to have multiple checks:
You can have many variations of overlap, so you'll need to do several tests.
|-----------| |--------------|
|------------------------|
|-------------|
|--------------------------------|
First Check:
Start of Range 1 >= Start of Range 2 and Start of Range 1 <= End of Range 2
Second Check:
Start of Range 2 >= Start of Range 1 and Start of Range 2 <= End of Range 1
Third Check:
End of Range 1 >= Start of Range 2 and End of Range 1 <= End of Range 2
Fourth Check:
End of Range 2 >= Start of Range 1 and End of Range 2 <= End of Range 1
These checks assume that End >= Start on both ranges. If not, you'll need to swap the start and end for the tests.
public static bool DoRangesOverlap(int p_start1, int p_end1, int p_start2, int p_end2)
{
if ((p_start1 >= p_start2 && p_start1 <= p_end2) || (p_start2 >= p_start1 && p_start2 <= p_end1) || (p_end1 >= p_start2 && p_end1 <= p_end2) || (p_end2 >= p_start1 && p_end2 <= p_end1))
{
return true;
}
return false;
}

Related

Effectively using 2D VBA Array variable and fetch whenever required

I am trying to develop a mechanism where I can store all the values in 2D array for below table.
Below is the code that I have developed, just to store values.
Sub temp()
Dim QtyArray(4, 11) As Integer, rw As Integer, col As Integer
For rw = 0 To 4
For col = 0 To 11
QtyArray(rw, col) = Cells(rw + 2, col + 3).Value
MsgBox QtyArray(rw, col)
Next col
Next rw
End Sub
I want to apply logic as per below:
First identify columns where COUNTA is 1 (highlighted in red) and move 1 qty of stock from that store to another store where COUNTA > 2, priority would be in order from store A to L. For example, first store with COUNTA=1 is store D, and it has qty 2. So I want to move these 2 qty to store E (not store C because it has already 1 qty, also H has 2 qty.)
If the COUNTA of any store's qty is zero, nothing to be done.
I want to fetch separate report as per below format, showing how the stock is being moved across store as per logic rule 1.
Output:
Explained in previous section.

Extracting unique values from row in Excel

I need to summarize unique values from a row into a column that's in the same row. My goal is in the second row of the attached image where T:Z contains the data and AA:AC contains the summary (I typed the values in for the demo). The first row is what is currently occurring where I tried using a nested if function for values greater than zero, but I also tried using an index match function to no avail. The issue is I either receive duplicates in AA:AC or not all values are included.
Currently using Excel 2016
So if I understand you correctly, you are going to have a sheet of rows of data. You want to look in the columns T:Z and then generate a list of unique values (non-zero) in the columns AA:AC. I assume that you know you will never have more than 3 unique values, but I can't be sure that this wasn't just an omission.
Either way, the below code should work:
Sub Find_Uniques()
Dim X As Integer, Y As Integer, Z As Integer
Dim Temp_Strings() As String
For X = 1 to 10000 'This assumes you don't have more than 10,000 rows of data
ReDim Temp_Strings(1 to 5) As String
For Y = 20 to 26
If Range(Cells(X,Y).Address).Value <> "" And Range(Cells(X,Y).Address).Value <> 0 Then
For Z = 1 to 5
If Temp_Strings(Z) = "" Then
Temp_Strings(Z) = Range(Cells(X,Y).Address).Value
Exit For
End If
If Temp_Strings(Z) = Range(Cells(X,Y).Address).Value Then Exit For
Next Z
End If
Next Y
For Z = 1 to 5
If Temp_Strings(Z) <> "" Then Range(Cells(X,Z+26).Address)).Value = Temp_String(Z)
Next Z
Next X
End Sub
Thank you all for your help. Instead of extracting the data from the row, I wrote a macro that changed the zeros to blanks, deleted the blank cells, and shifted them to the left. After that it was easy to cut the range and paste it into the old data set to be analyzed.
Sub clean_data()
Sheets("Reason data").Range("H:Z").Replace 0, ""
Call delete_blanks
End Sub
Sub delete_blanks()
Sheets("Reason data").Range("H:Z").SpecialCells(xlCellTypeBlanks).Delete (xlToLeft)
Call move_data
End Sub
Sub move_data()
'Copies reason data and pastes it into data worksheet
Sheets("Reason data").Range("A3:K3", Sheets("Reason data").Range("A3:F3").End(xlDown)).Cut _
Sheets("Data").Range("A1").End(xlDown).Offset(1)
End Sub

excel within range of cells, is there a date entered

Having some columns with either empty or a date in it, I need to get a true or false for a date present.
A B C D E F
1 Name oDate eDate xDate EndDate Status
2 Lars 01-11-2015 ? <= TRUE
3 Erik ? <= FALSE
4 Niels 09-01-2015 10-02-2015 ? <= TRUE
5 Jens 02-02-2016 10-02-2015 ? <= TRUE
Tried with
=IF(COUNTIFS($AP2:$AP2;ISNUMBER($AP2);$AQ2:$AQ2;ISNUMBER($AQ2);$AR2:$AR2;ISNUMBER($AR2);$AS2:$AS2;ISNUMBER($AS2);$AT2:$AT2;ISNUMBER($AT2);$AU2:$AU2;ISNUMBER($AU2)) >= 1;"TRUE";"FALSE")
but that just checks if fields not empty.
Anyone?
To Excel dates are just numbers formatted to suit (subject to being in the range 0 - 2958465) so say 23 September 1904 is just the same as dozen gross (1,728) without added context such as formatting. Provided the formatting is as you show it can be detected to use to differentiate say 11/02/2015 from 42,046:
=OR(CELL("format",B2)="D1",CELL("format",C2)="D1",CELL("format",D2)="D1",CELL("format",B2)="D1")
However since detecting the format of cells rather than content, a blank cell formatted as a date will count even without, in that case 00/01/1990 being displayed. (So you might also want a further check, such as that the sum of B:E cells is also greater than 0, or that each is a positive number and not text.)

How to apply the formula on a summary field

I am developing an inventory system and I have developed the following function to convert between cartons and pieces.
Public Function convertQTY(ByVal units_case As Integer, ByVal quantity As QTY) As QTY
While quantity.pieces < 0 And quantity.cartons > 0
If quantity.pieces < 0 And quantity.cartons > 0 Then
quantity.pieces = units_case + quantity.pieces
quantity.cartons -= 1
End If
End While
If quantity.pieces >= units_case Then
quantity.cartons = quantity.cartons + (quantity.pieces \ units_case)
quantity.pieces = quantity.pieces Mod units_case
End If
Return quantity
End Function
For example if units/pieces per carton is 144 then the above code converts the pieces into cartons if the number exceeds 144 and if the pieces are less than 0 then the above code subtracts 1 from carton and adds units per carton into the number of pieces. So that the pieces never exceed total number of pieces in a carton and they are never shown to be less than 0.
I want the same effect in summary field in my crystal report. For showing sum of cartons and pieces at the end of each group. How can i achieve this?
By creating formulas for the number of cartons and remaining pieces, like so:
Number Of Cartons:
Sum ({MyTable.Pieces})\144
Remaining Pieces:
Sum ({MyTable.Pieces}) mod 144

Array formula not working in Excel

I have the following table in Excel (blank spaces are empty):
A B C D
1 1
2 3
3 4
4 -2
5 4
6 9
7 8
8
9
10
I would like to return the minimum of column A from A1 to A1000000, using the QUARTILE function, while excluding all negative values. The reason I want it from A1 to A1000000 and not A1 to A7 is because I want to update the table (adding new rows starting from A8) and have the formula also automatically update. The reason I want the QUARTILE and not MIN function is because I will be extending it to calculate other statistics like 1st and 3rd quartile.
This function works correctly and returns 1 (pressing ctrl+shift+enter):
QUARTILE(IF(A1:A7 > -1, A1:A7), 0)
However, when I tried the following, it returned 0 when it should still return 1 (pressing ctrl+shift+enter):
QUARTILE(IF(A1:A1000000 > -1, A1:A1000000), 0)
I also tried the following and it returned 0 (pressing ctrl+shift+enter):
QUARTILE(IF(AND(NOT(ISBLANK(A1:A1000000)), A1:A1000000 > -1), A1:A1000000), 0)
Anybody have a solution to my problem?
Create a dynamic named range, called for example, rng, defined by =OFFSET($A$1,0,0,COUNT($A1:$A10000),1)
Then modify your array formula to refer to rng, via =QUARTILE(IF(rng >-1,rng), 0)
Actually what you have works. Try doing:
=QUARTILE(IF(A:A > 0,A:A ),0)
The reason you are returning 0 is that a blank cell is considered to be of the value 0 when this formula is ran. For example, erase one of the values in the A1:A7 range and your original formula will return 0. Also, I would run the formula on the entire A column if possible (for readability, etc.)
Or do you need to return a "0" if that number is in the list?

Resources