Related
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
. . 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0
Recognition starts at 17 and goes backwards to 0.
What can be seen is the most simple pattern.
Pattern starts with at least three 0s or three 1s but could be more of each but not mixed!
First pattern is then followed by at least five 0s or five 1s depending on what came in the first pattern. Since pattern one contains three 0, there must be at least five 1s and vice versa
Then we want to see the first pattern again. At least three 0s or three 1s, again, depending wheather there were 1s or 0s before
Finally we want to see the second pattern again, which means at least five 0s or five 1s, again, depending on which pattern was seen before
I tried using for loops and counters but did not manage to work it out. What is struggling me is the fact, that the pattern is not of fixed size as there can be more than three or five 0s and 1s in succession.
Is anybody able to provide some pseudo code how to implement this or even some MQL5 code?
The following Swift code is everything else than optimal. It should just give you hints how you could implement it.
A function to match a single pattern:
func matchPattern(numbers: [Int], startIndex: Int, number: Int) -> Int {
var actualIndex = startIndex
while numbers[actualIndex] == number && actualIndex > 0 {
actualIndex = actualIndex - 1
}
return startIndex - actualIndex
}
A function to match the 4 patterns:
func match(binNrs: [Int]) -> Bool {
let firstPatternNr = binNrs[17]
let secondPatternNr = firstPatternNr == 0 ? 1 : 0
let pattern1Length = matchPattern(numbers: binNrs,
startIndex: 17,
number: firstPatternNr)
if pattern1Length < 3 { return false }
let pattern2Length = matchPattern(numbers: binNrs,
startIndex: 17 - pattern1Length,
number: secondPatternNr)
if pattern2Length < 5 { return false }
let pattern3Length = matchPattern(numbers: binNrs,
startIndex: 17 - pattern1Length - pattern2Length,
number: firstPatternNr)
if pattern3Length < 3 { return false }
let pattern4Length = matchPattern(numbers: binNrs,
startIndex: 17 - pattern1Length - pattern2Length - pattern3Length,
number: secondPatternNr)
return pattern4Length >= 5
}
Some test patterns with results:
let match1 = match(binNrs: [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0]) // true
let match2 = match(binNrs: [1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0]) // false (4th sequence < 5)
let match3 = match(binNrs: [0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0]) // false (1st sequence < 3)
let match4 = match(binNrs: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1]) // false (2nd sequence < 5)
Given the following fields:
Y INT, --Year.
M INT, --Month.
D INT, --Day.
T FLOAT --Hours (H), minutes (m), seconds (s) and milliseconds (x) (in the form HHmmss.xxx).
Is there a way to attempt to convert these values into a DATETIME2 without having to first convert them to a string-based data type? If the attempt fails (e.g. due to an overflowing day value (e.g. 35th of January 2019)), I would like NULL to be returned.
If I use DATETIME2FROMPARTS it will simply fail if passed any invalid component.
I am trying to avoid converting these into a string as the only reason I am trying this compromised solution is because the performance of my other solution which actually handles overflow and underflow, is incredibly slow against a large database (doesn't complete in 5 hours!) so I'm trying to try something simpler to see if it improves the performance of adding this as a computed persisted column.
Here is the bespoke solution I ended up writing for this. There is unfortunately repeated logic since I'm using this in a persisted computed column and thus cannot use variables or scalar functions (for parameters to be used as variables).
DECLARE #Y INT = 2000, #M INT = 2, #D INT = 29, #T FLOAT = 135559.999
SELECT IIF
(
--If the Year is out-of-bounds.
#Y <= 0 OR #Y > 9999
--Or the Month is out-of-bounds.
OR #M <= 0 OR #M > 12
--Or the Day is out-of-bounds (Accounts for leap years).
OR #D <= 0 OR #D > DAY(EOMONTH(DATETIME2FROMPARTS(#Y, #M, 1, 0, 0, 0, 0, 3)))
--Or the Time is less than 0
OR #T < 0
--Or the Hour is out-of-bounds.
OR ROUND(#T / 10000, 0, 1) >= 24
--Or the Minute is out-of-bounds.
OR ROUND(#T / 100, 0, 1) - ROUND(#T / 10000, 0, 1) * 100 >= 60
--Or the Second is out-of-bounds.
OR ROUND(#T, 0, 1) - ROUND(#T / 100, 0, 1) * 100 >= 60,
--NULL is returned
NULL,
--Otherwise, the Date Time components are parsable into a DATETIME2.
DATETIME2FROMPARTS
(
--Year
#Y,
--Month
#M,
--Day
#D,
--Hour
ROUND(#T / 10000, 0, 1),
--Minute
ROUND(#T / 100, 0, 1) - ROUND(#T / 10000, 0, 1) * 100,
--Second
ROUND(#T, 0, 1) - ROUND(#T / 100, 0, 1) * 100,
--Millisecond (multiplied by 1000 to use the first 3 decimal places).
(#T - ROUND(#T, 0, 1)) * 1000,
--Precision (3 is specified since only 3 decimal places become part of the integer for the fraction parameter above).
3
)
)
If you need millisecond precision different to 3 decimal places, where your millisecond precision is x, change 3 to x and * 1000 on the line above to * POWER(10, x).
I need to compare two images and create rectangles of the difference. I can build a difference matrix like this:
0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1
0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 1 1 1 0
0 0 0 0 1 1 0 0
where 1 is diff pixel. I need to find the way to create rectangles for areas of image diff. In my example, I have three areas to highlight.
# # #
# 1 #
# # #
# # # #
# 1 1 1
# # # #
# # # # #
# 1 0 0 #
# 0 1 0 #
# 1 1 1 #
# 1 1 0 #
So I'm looking for an algorithm to do that in a convenient way.
I'm assuming that the problem is as follows. Given a 0/1-matrix, cover the regions containing 1s with disjoint rectnagles (i.e. the rectangles must no intersect). In particular, non-rectangular shapes---for example, an L-shaped domino---are disallowed.
Here's an idea for an algorithm:
start at the origin, at index (0,0), and expand out until the expanded region contains a single rectangle of 1s that you cannot enlarge by moving to adjacent cells in either direction.
add that rectangle to the collection, and remove the processed region;
recurse on the remaining cells.
The running time should be linear in the number of cells; however, depending on whether there are additional specifications on the type of the output, you may need to change the first step.
I like the problem a lot. Notice that many different solutions may exist for a problem instance. A natural variation would be to require a cover comprised of as few rectangles as possible (i.e. a minimal cover); in this case, too, there may exist many different solutions. (The counting version of the problem looks interesting from the complexity-theoretic viewpoint.)
You could do a two-step algorithm: First, you find 8-connected components in your image, then you calculate the bounding box for each of the component.
This approach may lead to overlapping rectangles (imagine two nearby "L"-shapes), which you could solve by either merging the overlapping rectangles or by zeroing out non-connected components from each rectangle (so that you can sum all the rectangles and reconstruct the difference image appropriately).
If you go with the second choice, you can get the rectangles in Matlab as follows:
%# each element of the struct array rectangles contains a field
%# .Image, which is the rectangle, and
%# .BoundingBox, which is the coordinates of the rectangle.
rectangles = regionprops(differenceImage,'Image','BoundingBox');
Below is some JS demonstration code to find the rectangles, starting each time at the next remaining non-empty cell and exploring all paths in a recursive way. Cells are cleared as they are visited.
This is pretty close to what the the 'fill' tool is doing in MS Paint and the like. More precisely, this is a flood fill algorithm, as mentioned by j-random-hacker in the comments.
This code will find the inner bounds of the rectangles. It'd need to be slightly updated if you want the outer bounds instead.
var W = 8, H = 8;
var matrix = [
// 0 1 2 3 4 5 6 7
[ 0, 0, 0, 0, 0, 0, 0, 0 ], // 0
[ 0, 0, 0, 0, 0, 1, 1, 1 ], // 1
[ 0, 0, 0, 1, 0, 0, 0, 0 ], // 2
[ 0, 0, 0, 0, 0, 0, 0, 0 ], // 3
[ 0, 0, 0, 0, 1, 0, 0, 0 ], // 4
[ 0, 0, 0, 0, 0, 1, 0, 0 ], // 5
[ 0, 0, 0, 0, 1, 1, 1, 0 ], // 6
[ 0, 0, 0, 0, 1, 1, 0, 0 ] // 7
];
var dir = [
[ -1, -1 ], [ 0, -1 ], [ 1, -1 ], [ 1, 0 ], [ 1, 1 ], [ 0, 1 ], [ -1, 1 ], [ -1, 0 ]
];
var x, y, rect;
for(y = 0; y < H; y++) {
for(x = 0; x < W; x++) {
if(diffAt(x, y)) {
rect = { x0:x, y0:y, x1:x, y1:y };
recurse(x, y, rect);
console.log(
'Found rectangle: ' +
'(' + rect.x0 + ',' + rect.y0 + ') -> ' +
'(' + rect.x1 + ',' + rect.y1 + ')'
);
}
}
}
function recurse(x, y, rect) {
rect.x0 = Math.min(rect.x0, x);
rect.y0 = Math.min(rect.y0, y);
rect.x1 = Math.max(rect.x1, x);
rect.y1 = Math.max(rect.y1, y);
matrix[y][x] = 0;
for(var d = 0; d < 8; d++) {
if(diffAt(x + dir[d][0], y + dir[d][1])) {
recurse(x + dir[d][0], y + dir[d][1], rect);
}
}
}
function diffAt(x, y) {
return x < 0 || x >= W || y < 0 || y >= H ? 0 : matrix[y][x];
}
i wanted to know which algorithm should i apply here. Would a DFS do?
Given a 2–d matrix. Find the total number of connected sets in that matrix.
Connected set can be defined as group of cell(s) which has 1 mentioned on it and have at least one other cell in that set with which they share the neighbor relationship. A cell with 1 in it and no surrounding neighbor having 1 in it can be considered as a set with one cell in it. Neighbors can be defined as all the cells adjacent to the given cell in 8 possible directions (i.e. N, W, E, S, NE, NW, SE, SW direction). A cell is not a neighbor of itself.
For example:
1 0 0 1
0 0 1 0
0 0 1 0
1 0 0 1
number of connected sets is 3
0 0 1 0 0 1 0 0
1 0 0 0 0 0 0 1
0 0 1 0 0 1 0 1
0 1 0 0 0 1 0 0
1 0 0 0 0 0 0 0
0 0 1 1 0 1 1 0
1 0 1 1 0 1 1 0
0 0 0 0 0 0 0 0
number of connected set is 9.
I don't think you will need to think of it as a general graph problem and apply any algorithm such as BFS or DFS.
You will need to do three scans of the matrix.
scan 1:
start from the top
give every number each 1 with 1..n, in you example the first row would after that step would look like
1 0 0 2
go to the next line and for every 1 in the row check if the neighbor to your left is non-0
if non-0 take on the value to the left
if 0 check for non-0 neighbors in the previous line and take on the value of the left most one
if all of those are 0 that simply add 1 to the maximum number given so far
repeat 2 until last line has been processed
and your example should look like follows
1 0 0 2
0 0 2 0
0 0 2 0
3 0 0 2
scan 2:
start from the bottom
check if each neighbor has the same number as the left most neighbor as well as the same number as the neighbor in the row below it
basically if you have a matrix like this
1 0 2
1 0 2
0 1 0
to check ensure that a set has really the same number
scan 3:
count the number of unique non-0 entries in the matrix
Connected-component labeling algorithm is intended to mark out connected groups of elements (both for 4-connectivity and for 8-connectivity)
Pythonic Implementation, More understandable code:
# sea is 2 D array of 0 and 1s we have to find 1's group surrounded by 0's
def dfs(sea, i, j, b, h, visited):
surround = ((-1, -1), (0, -1), (1, -1),
(-1, 0), (1, 0),
(-1, 1), (0, 1), (1, 1)
)
if can_visit(sea, i, j, b, h, visited):
for s in surround:
visited[(i, j)] = 1
dfs(sea, i + s[0], j + s[1], b, h, visited)
def can_visit(sea, i, j, b, h, visited):
if i >= 0 and j >= 0 and i < b and j < h:
if (i, j) not in visited and sea[i][j] == 1:
return True
def find_island(sea):
visited = {}
h = len(sea)
count = 0
for i, row in enumerate(sea):
b = len(row)
for j, item in enumerate(row):
if can_visit(sea, i, j, b, h, visited):
count += 1
dfs(sea, i, j, b, h, visited)
return count
sea = [[1, 1, 0, 0, 0],
[0, 1, 0, 0, 1],
[1, 0, 0, 1, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1]
]
print find_island(sea)
You want to use a disjoint set datastructure and algorithm. This will pick a unique representative for each connected component, which you can count at the end.
To efficiently evaluate which elements are neighbors, you can scan the matrix line by line, maintaining a list of segments (of consecutive 1's) from the previous line, while determining which segments on the current line are adjacent to them.
There are 3 connected sets. All 1 which are neighbors of each other are considered as one single set. All 1 at a[1,4], a[2,3], a[3,3] and a[4,4] form one set and one at a[1,1] form one set and one at a[4,1] forms one set.
Scan the matrix for 1s. When you find one, call a recursive function that marks off its connected component if it is not already identified as being in one. Use recursion to find connected components. Have a quick lookup somewhere that tells you whether a given node has already been identified as being in a connected component to avoid identifying connected components 2x, and to avoid infinite loops while traversing a connected component.
If you want do it just by your matrix (without extra memory), do it as follow:
Set scanner position as [0,0]
Set a counter to zero.
Scan matrix from current scanner position row by row (and cell by cell) and find one 1 and set scanner position to next element after this 1, if there isn't any 1 go to step 6.
Set related one to counter+2 and recursively find all of its 1 neighbors and also set them to count + 2.
count = count + 1
Go to step 2.
output count.
PS: It's clear if the scanner position is greater than matrix size your algorithm will finishes (I didn't wrote this to prevent confusion).
This isn't nearly as hard as it looks. In fact, this feels very strongly like something a professor would assign for an assignment in first year Computer Science. So if this is homework, you should tag it as such.
However, the solution is fairly easy.
for (int y = 0; y < arr.height(); y++)
{
for (int x = 0; x < arr.width(); x++)
{
if (arr[x][y] == 1)
{
if (CheckIfConnected(x, y, arr))
{
connectedPositionsX.Add(x);
connectedPositionsY.Add(y);
}
}
}
}
Where connectedPositions would be a linked list or whatever you want to store sets with.
arr is a 2D array containing a matrix of the type you specified above.
CheckIfConnected can be implemented fairly simply as well.
bool CheckIfConnected(int x, int y, int[][]arr)
{
if (arr.width() >= 2) || (arr.height() >= 2)
{
if ((x < arr.width()) && (x >= 0) && (y < arr.height()) && (y >= 0))
{
if ((x-1) >= 0) //West
{
if (arr[x-1][y] == 1)
{
adjCount[x-1][y] += 1;
return true;
}
}
if (((x-1) >= 0) && ((y-1) >= 0)) //Northwest
{
if (arr[x-1][y-1] == 1)
{
adjCount[x-1][y-1] += 1;
return true;
}
}
if ((y-1) >= 0) //North
{
if (arr[x][y-1] == 1)
{
adjCount[x][y-1] += 1;
return true;
}
}
if (((x+1) < arr.width()) && ((y-1) >= 0)) //Northeast
{
if (arr[x+1][y-1] == 1)
{
adjCount[x+1][y-1] += 1;
return true;
}
}
if ((x+1) < arr.width()) //East
{
if (arr[x+1][y] == 1)
{
adjCount[x+1][y] += 1;
return true;
}
}
//I'll let you implement Southeast to Southwest on your own,
//the pattern is clear now.
}
}
return false;
}
From there, you know how many times you found a pairing on each position in the grid. This helps you keep track of your connections.
The counts in the 2D array adjCount keeps track of this for you.
You could also go through and modify Dijkstra's Algorithm to do it recursively for you. Since you mentioned DFS (Depth First Search) I'm assuming your professor or teacher wants you to go about solving it that way.
In that case:
Here is Dijkstra's Algorithm in Pseudo Code:
http://en.wikipedia.org/wiki/Dijkstra's_algorithm
Hope that helps! Cheers!
Just keep searching in East, SouthEast, South and SouthWest direction at one go recursively for each node having value as 1.
If the call to visit function is a fresh call and not from recursion increase the connected components.
import java.util.Scanner;
public class Solution {
public static void visit(int[][] ar, boolean[][] v,int i, int j){
int size = ar.length;
if(ar[i][j] == 1){
v[i][j] = true;
if(j>0 && i<size-1){
visit(ar,v,i+1,j-1); // SouthWest
}
if(i<size-1){
visit(ar,v,i+1,j); // South
if(j < size-1)
visit(ar,v,i+1,j+1); // SouthEast
}
if(j<size-1)
visit(ar,v,i,j+1); // East
}
}
public static void main(String[] args) {
int[][] ar;
int count = 0;
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ar = new int[n][n];
boolean[][] v = new boolean[n][n];
for(int i=0; i<n ; i++) {
for(int j=0; j<n; j++){
ar[i][j] = sc.nextInt();
v[i][j] = false;
}
}
for(int i=0; i<n ; i++) {
for(int j=0; j<n; j++){
if(ar[i][j] == 1 && !v[i][j]){
count++;
visit(ar,v,i,j);
}
}
}
System.out.println(count);
}
}
I have a class to help you find the total number of connected components in your 2D array. My class not only gives you the total number, but also gives you the clusters and visualize them for you. You can comment out the parts that you don't need. Please see this class in (java): https://github.com/m-vahidalizadeh/foundations/blob/master/src/algorithms/ConnectedComponetns.java
If you use python, there is a function in scipy to find this number.
from scipy.ndimage import label
data = [[0, 0, 1, 0, 0, 1, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 1, 0, 1],
[0, 1, 0, 0, 0, 1, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 1, 1, 0],
[1, 0, 1, 1, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0]]
connection_structure = [[1,1,1],
[1,0,1],
[1,1,1]]
_, N = label(data, connection_structure)
print(N)
>>> 9
Let's say I want to check if a number n = 123 has duplicate digits. I tried:
#include <iostream>
using namespace std;
int main() {
int n = 123;
int d1 = n % 10;
int d2 = ( n / 10 ) % 10;
int d3 = ( n / 100 ) % 10;
if( d1 != d2 && d1 != d3 && d2 != d3 ) {
cout << n << " does not have duplicate digits.\n";
}
}
Is there any faster solution to this problem?
Update
Sorry for being unclear. The code above was written in C++ only for description purpose. I have to solve this problem in TI-89, with a number of 9 digits. And since the limitation of memory and speed, I'm looking for a fastest way possible.
TI-89 only has several condition keyword:
If
If ... Then
when(
For ... EndFor
While ... EndWhile
Loop ... EndLoop
Custom ... EndCustom
Thanks,
Chan
Not necessarily faster but you should measure anyway, just in case - my optimisation mantra is "measure, don't guess".
But I believe it's clearer in intent (and simple enough to be translated to a simpler calculator language. It's also able to handle arbitrarily sized integers.
int hasDupes (unsigned int n) {
// Flag to indicate digit has been used, all zero to start.
int used[10] = {0};
// More than 10 digits must have duplicates, return true quickly.
if (n > 9999999999) return 1;
// Process each digit in number.
while (n != 0) {
// If duplicate, return true as soon as found.
if (used[n%10]) return 1;
// Otherwise, mark used, go to next digit.
used[n%10] = 1;
n /= 10;
}
// No duplicates after checking all digits, return false.
return 0;
}
If you have a limited range of possibilities, you can use the time-honoured approach of sacrificing space for time. For example, let's say you're talking about numbers between 0 and 999 inclusive (the : : markers simply indicate data I've removed to keep the size of the answer manageable):
const int *hasDupes = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 9
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, // 10 - 19
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 20 - 29
: :
0, 0, 1, 0, 0, 1, 0, 0, 0, 0, // 520 - 529
: :
0, 1, 0, 0, 0, 0, 0, 0, 1, 0, // 810 - 819
: :
0, 0, 0, 0, 0, 0, 0, 1, 0, 1, // 970 - 979
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, // 980 - 989
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 990 - 999
};
and just do a table lookup of hasDupes[n]. The table itself could be generated (once) programmatically and then just inserted into your code for usage.
However, based on your edit where you state you need to handle nine-digit numbers, a billion-element array is probably not going to be possible on your calculator. I would therefore opt for the first solution.
template<class T, int radix = 10>
bool has_duplicate_digits(T n) {
int digits_mask = 0;
while (digits_mask |= (1 << (n % radix)), n /= radix)
if (digits_mask & (1 << (n % radix)))
return true;
return false;
}
Something like that should work as long as n is nonnegative and int has at least radix bits.
digits_mask is a bitset (bit 0 represents the occurrence of a 0 digit, bit 1 represents the occurrence of a 1 digit, etc.).
The bitmap is populated with the least significant digit of n, and the rest of the digits are shifted down. If there are more digits, and the new least significant digit is marked as having occurred previously, return true, otherwise repeat.
When there are no more digits, return false.
1 << x returns 1, 2, 4, 8, etc.: masks to use to test/set bits in the bitset.
a |= z is shorthand for a = a | z, which sets bits by the union of a from z.
a & z is the intersection of the bits in a and z, and is zero (false) if none are set and non-zero (true) if any are set.
I did a crash course in TI-89 basic to answer :)
Let's see if this works (I haven't an emulator, so can't check).
Test()
Prgm
{0,0,0,0,0,0,0,0,0,0}->A
Title "Request"
Request "Enter a number",B
EndDlog
Expr(B)->B
While B > 1
MOD(10,B)->C
if A[C+1] = 1 goto K
1->A[C+1]
B-C->B
EndWhile
Title "Done"
Text "Numbers non repeating"
Enddlog
goto J
Lbl K
Title "Done"
Text "Numbers repeating"
Enddlog
Lbl J
EndPrgm