Need help with logic (C) - c

I need to swap first n elements from two non repeating sequences(arrays), where n is a random integer.
Seq1: 1 4 5 6 9 8 2 3 7
Seq2: 3 9 1 2 8 7 4 5 6
If n = 4
Seq1: 3 9 1 2 | 9 8 2 3 7
Seq2: 1 4 5 6 | 8 7 4 5 6
Now i need to repair the sequence by replacing the repeated numbers after '|'.
How to do this?
This is my effort..
for(left1 = 0; left1<pivot; left1++)
{
for(right1 = pivot; right1 < no_jobs; right1++)
{
if(S1->sequence[left1] == S1->sequence[right1])
{
for(left2 = 0; left2<pivot; left2++)
{
for(right2 = pivot; right2<no_jobs; right2++)
{
if(S2->sequence[left2] == S2->sequence[right2])
{
swap_temp = S1->sequence[right1];
S1->sequence[right1] = S2->sequence[right2];
S2->sequence[right2] = swap_temp;
break;
}
}
}
}
}
}

Swapping the first n elements is straightforward using a single for loop.
for(int i = 0; i < n; i++){
int tmp = array1[i];
array1[i] = array2[i];
array2[i] = tmp;
}
Now you need to find what has changed in the arrays. You can do this by comparing the parts you swapped.
int m1 = 0, m2 = 0;
int missing_array1[n];
int missing_array2[n];
for(int i = 0; i < n; i++){
bool found = false;
for(int j = 0; j < n; j++){
if(array1[i] == array2[j]){
found = true;
break;
}
}
if(!found){
missing_array2[m2++] = array1[i];
}
}
for(int i = 0; i < n; i++){
bool found = false;
for(int j = 0; j < n; j++){
if(array2[i] == array1[j]){
found = true;
break;
}
}
if(!found){
missing_array1[m1++] = array2[i];
}
}
missing_array2 now contains the numbers that are missing from array2. These are all the numbers that will be duplicated in array1. The same goes for missing_array1. Next you need to scan both arrays and replace the duplicates with the missing numbers.
while(m1 >= 0){
int z = 0;
while(missing_array1[m1] != array2[n + z]){
z++;
}
array2[n + z] = missing_array2[m1--];
}
while(m2 >= 0){
int z = 0;
while(missing_array2[m2] != array1[n + z]){
z++;
}
array1[n + z] = missing_array1[m2--];
}
In summary, you compare the parts you swapped to find the values that will be missing from each array. These value are also the values that will be duplicated in the opposite array. Then you scan each of the arrays and replace the duplicate values with one of the missing values (I assume you don't care which of the missing values, as long as all the values are unique.

If the swapped portions of the sequences contain the same values, then there would be no repeats - performing the swap would just shuffle the first n elements. So the values you need to repair are the values which occur in one of the swapped sequences
Firstly, I'd create a histogram of the n swapped elements, with those from sequence 1 counting as bit 0, and those from sequence 2 as bit 1. If any members of the histogram are non-zero, then they occur in one or the other sequence only.
If there are values requiring repair, then you can construct a look-up table of the values which require rewriting. This should map i to i unless i is one of the asymmetric values in the histogram, in which case it needs to map to the another asymmetric value.
Seq1: 1 4 5 6 9 8 2 3 7
Seq2: 3 9 1 2 8 7 4 5 6
If n = 4
Seq1: 3 9 1 2 | 9 8 2 3 7
Seq2: 1 4 5 6 | 8 7 4 5 6
histogram
value 1 2 3 4 5 6 7 8 9
count 3 1 1 2 2 2 0 0 1
mapping for sequence 1 ( while histogram [S1[i]] & 1, replace[S1[i]] with S2[i] )
value 1 2 3 4 5 6 7 8 9
replace 1 6 5 4 5 6 7 8 4
apply mapping to sequence 1 for i > n
Seq1: 3 9 1 2 | 9 8 2 3 7
replace - - - - | 4 8 6 5 7
result 3 9 1 2 | 4 8 6 5 7
mapping for sequence 2 ( while histogram [S2[i]] & 2, replace[S2[i]] with S1[i] )
value 1 2 3 4 5 6 7 8 9
replace 1 2 3 9 3 2 7 8 9
apply mapping to sequence 1 for i > n
Seq2: 1 4 5 6 | 8 7 4 5 6
replace - - - - | 8 7 9 3 2
result 1 4 5 6 | 8 7 9 3 2
Alternatively, replace with the next value with the other bit set in the histogram (the iterated replace will also need to check for replacing a value with itself); I'm assuming it doesn't really matter what value is used as the replacement as long as the values in the result are unique.

Related

How to create a Sudoku grid with the following pattern in C without arrays?

I have to create a Sudoku grid with the following pattern in C:
1 2 3 4
3 4 1 2
2 3 4 1
4 1 2 3
The first number in the top left corner (here: 1) must be an editable variable for a start value. There is another variable to create the grid with by the square size, in this example the square size is 2 and the 1 2 3 4 are in one square. 3 4 1 2 are in another square and so on...
If the start value is e.g. 3, the grid looks like this:
3 4 1 2
1 2 3 4
4 1 2 3
2 3 4 1
I noticed that there is a pattern: If the row number is odd, the new start value of the next row is the second last one. If the row number is even, the new start value of the next row is the last one. I tried to do it in C, but the even rows are cloning themselves. Note that arrays and pointers are not allowed here, only loops and other control-structures.
I tried the following approach, but the even rows are cloning themselves:
#include <stdio.h>
const int intSquareSize = 2;
const int intFieldLength = intSquareSize * intSquareSize;
int intStartValue = 3;
int main() {
int a = 0;
int b = 0;
int m = 0;
for (int intRowCounter = 1; intRowCounter <= intFieldLength; intRowCounter++) {
m = intFieldLength - 1;
for (int intColumnCounter = 1; intColumnCounter <= intFieldLength; intColumnCounter++) {
a = intStartValue + (intColumnCounter - 1);
b = a;
if (a > intFieldLength) {
a = intFieldLength - m;
m--;
}
if (intRowCounter % 2 == 0 && intColumnCounter == intFieldLength) {
intStartValue = a;
} else if (intRowCounter % 2 == 1 && intColumnCounter == (intFieldLength - 1)) {
intStartValue = b;
}
printf("%d\t", a);
}
printf("\n");
}
return 0;
}
What did I wrong and how can I fix it?
If the row number is odd, the new start value of the next row is the second last one. If the row number is even, the new start value of the next row is the last one.
I don't think it is helpful to think in terms of odd and even. The involved numbers are just symbols, and one could even replace them with distinct colors (for example). Odd/even is not a significant thing here, and it would certainly not play the same role in other board sizes.
The pattern I see is this:
In the first intSquareSize rows, the values shift horizontally (compared to the previous row) by intSquareSize. For example with intSquareSize=3 the first three rows could be:
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9 1 2 3 4 5 6 7 8
Notice the shift of 3 positions to the left at each next row.
Then the pattern for the next chunks of intSquareSize rows would be the same, but with one shift. So the complete 9x9 sudoku would look like this:
3 4 5 6 7 8 9 1 2
6 7 8 9 1 2 3 4 5
9 1 2 3 4 5 6 7 8
4 5 6 7 8 9 1 2 3
7 8 9 1 2 3 4 5 6
1 2 3 4 5 6 7 8 9
5 6 7 8 9 1 2 3 4
8 9 1 2 3 4 5 6 7
2 3 4 5 6 7 8 9 1
This is just one possible pattern you could follow. There could be others. But the following code will apply the above logic. Note I used your variables, but I prefer to use 0-based logic, so loop variables start at 0, and the value of a is also 0-based. Only at the time of printing 1 is added to that value, so it becomes 1-based:
int a = intStartValue - 1; // Move from 1-based to 0-based
for (int intBlockCounter = 0; intBlockCounter < intSquareSize; intBlockCounter++) {
for (int intRowCounter = 0; intRowCounter < intSquareSize; intRowCounter++) {
for (int intColumnCounter = 0; intColumnCounter < intFieldLength; intColumnCounter++) {
printf("%d\t", (a + 1)); // back to 1-based
a = (a + 1) % intFieldLength;
}
printf("\n");
a = (a + intSquareSize) % intFieldLength; // Shift within a block
}
a = (a + 1) % intFieldLength; // Shift between blocks
}

Equalize to zero a different element of a matrix for each row without loop

I have an IxS matrix called numerateur and I would like to set one element per row to zero. However, the column to which this element belongs changes for each row. I can do it with a loop but would like to use a more efficient method.
You can find my loop below:
choice is an Ix1 vector containing, for each row, the column number of the element I want to set to zero in numerateur.
for i = 1:I
rank1 = choice(i);
numerateur(i,rank1) = 0;
end
You need to convert the column indices to linear indices:
ind = (1:size(numerateur,1)) + (choice(:).'-1)*size(numerateur,1);
numerateur(ind) = 0;
Example:
>> numerateur = randi(9,5,7)
numerateur =
8 7 8 3 2 8 4
7 8 6 3 6 1 3
8 9 5 5 5 9 5
4 4 2 7 4 9 9
1 6 7 3 8 7 9
>> choice = [2; 3; 6; 5; 1];
>> ind = (1:size(numerateur,1)) + (choice(:).'-1)*size(numerateur,1);
>> numerateur(ind) = 0;
>> numerateur
numerateur =
8 0 8 3 2 8 4
7 8 0 3 6 1 3
8 9 5 5 5 0 5
4 4 2 7 0 9 9
0 6 7 3 8 7 9
Use implicit expansion to find logical indices:
numerateur(choice == 1:size(numerator,2)) = 0;
Alternatively you can use sparse matrix to generate logical indices:
numerateur(sparse(1:I,choice,true,I,S)) = 0;

How do we make arrays in awk?

{
k = 0
x = 0
fracon = (10/2)+1
{
for (j = 1; j <= 1100 ; j++)
{
if (j <= fracon)
scal[j]= j-x
else
k= k + 1
scal[j]= j - (2*k)
{
if (scal[j] == 1)
fracon= fracon+11
{
if (j % 11 == 0)
x=x+11
k=k+0.5
}
}
}
}
}
That's all. I used the above code to generate the following array. It works in Matlab, but it does not work in awk.
array= [1 2 3 4 5 6 5 4 3 2 1 1 2 3 4 5 6]
here is another way of generating the same sequence
$ awk 'BEGIN{for(i=0;i<=20;i++) {k=i%11+1; printf "%s ", (k<7?k:12-k)}; print ""}'
1 2 3 4 5 6 5 4 3 2 1 1 2 3 4 5 6 5 4 3 2
not sure what you want is just repeated on a 11 element cycle or not; difficult to say based on limited sample.
or without awk
$ yes $({ seq 6; seq 5 -1 1; } | paste -sd' ') | head -100 | paste -sd' '
1 2 3 4 5 6 5 4 3 2 1 1 2 3 4 5 6 5 4 3 2 1 ...
with square brackets
$ awk 'BEGIN{printf "[";
for(i=0;i<=1100;i++) {k=i%11+1; printf "%s ", (k<7?k:12-k)};
printf "]\n"}'
[1 2 3 4 5 6 5 4 3 2 1 1 2 3 4 5 6 ... 5 4 3 2 1 ]
Stuffing these values into a large array is not optimal, you can write a function to return the indexed value easily
$ awk 'function k(i,_i) {_i=i%11+1; return _i<7?_i:12-_i}
BEGIN{for(i=0;i<=25;i++) print k(i)}'
in the real code, you'll use k(i) instead of printing. Note the array index starts from 0.
N.B. the _i is a local variable in the awk function; you don't need to use in the call syntax.

Improper Initialization of 2D Array in C

I am trying to construct a 2D array for an assignment. I've used a nested for loop to construct the 2D array using scanf():
int width;
int height;
scanf("%d %d",&width,&height);
int array[width][height];
for (int i=0;i<height;i++){
for (int j=0;j<width;j++){
scanf("%d",&array[i][j]);
}
}
However when I print the array, I can see that it has been constructed in a strange way, where all the numbers of the first line past a certain point are the first few numbers from the second line (instead of what they should be). The next lines after work fine.
Example:
Input:
6 2
1 3 5 7 9 1
2 4 6 8 0 2
3 4 2 0 1 3
The created array looks like this:
1 3 2 4 6 8 (<-- these last 4 numbers are the first 4 numbers of the second line)
2 4 6 8 0 2 (correct)
3 4 2 0 1 3 (correct)
Any ideas? Thanks a lot.
Your declaration of array
int array[width][height];
is wrong. The outer loop goes from 0 to height - 1, but array[i] can only go
from 0 to width - 1. The same applies for the inner loop. You swapped width
and height in the declaration of the array, it should be
int array[height][width];
Also note that for the matrix
1 3 5 7 9 1
2 4 6 8 0 2
3 4 2 0 1 3
the width is 6 and the height is 3, so the correct input should be
6 3
1 3 5 7 9 1
2 4 6 8 0 2
3 4 2 0 1 3
I compiled and run this code:
#include <stdio.h>
int main(void)
{
int width;
int height;
scanf("%d %d",&width,&height);
int array[height][width];
for (int i=0;i<height;i++){
for (int j=0;j<width;j++){
scanf("%d",&array[i][j]);
}
}
printf("----------------\n");
for (int i=0;i<height;i++){
for (int j=0;j<width;j++){
printf("%d ", array[i][j]);
}
printf("\n");
}
}
And the output is:
$ ./b
6 3
1 3 5 7 9 1
2 4 6 8 0 2
3 4 2 0 1 3
----------------
1 3 5 7 9 1
2 4 6 8 0 2
3 4 2 0 1 3
as you can see, now it's reading correctly. See https://ideone.com/OJjj0Y

Running weighted quick union

So I have to take an ID array
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
And perform weighted quick union on it. I have to perform the operations 9-0, 3-4, 5-8, 7-2, 2-1, 5-7, 0-3, and 4-2. Here's what I did to the array for these operations:
9-0
0 1 2 3 4 5 6 7 8 9
9 1 2 3 4 5 6 7 8 9
3-4
0 1 2 3 4 5 6 7 8 9
9 1 2 3 3 5 6 7 8 9
5-8
0 1 2 3 4 5 6 7 8 9
9 1 2 3 3 5 6 7 5 9
7-2
0 1 2 3 4 5 6 7 8 9
9 1 7 3 3 5 6 7 5 9
2-1
0 1 2 3 4 5 6 7 8 9
9 7 7 3 3 5 6 7 5 9
5-7
0 1 2 3 4 5 6 7 8 9
9 7 7 3 3 7 6 7 5 9
0-3
0 1 2 3 4 5 6 7 8 9
9 7 7 3 3 7 6 7 5 3
4-2
0 1 2 3 4 5 6 7 8 9
9 7 7 3 3 7 6 3 5 9
The problem is that the ID array operations are different depending on if you're using quick find or quick union or weighted quick union. So would this be right for weighted quick union? Here's the code I'm using for weighted quick union:
public class WeightedQuickUnionUF
{
private int[] id; // parent link (site indexed)
private int[] sz; // size of component for roots (site indexed)
private int count; // number of components
public WeightedQuickUnionUF(int N)
{
count = N;
id = new int[N];
for (int i = 0; i < N; i++) id[i] = i;
sz = new int[N];
for (int i = 0; i < N; i++) sz[i] = 1;
}
public int count()
{ return count; }
public boolean connected(int p, int q)
{ return find(p) == find(q); }
private int find(int p)
{ // Follow links to find a root.
while (p != id[p]) p = id[p];
return p;
}
public void union(int p, int q)
{
int i = find(p);
int j = find(q);
if (i == j) return;
// Make smaller root point to larger one.
if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i]; }
else { id[j] = i; sz[i] += sz[j]; }
count--;
}
}
The code for weighted quick union shows you how it works but basically it's a type of Union-find where you connect two trees together. With weighted quick union you always connected the smaller tree to the larger one. The ID array is a representation of a tree where there's numbers on the top row and bottom row. If the number on top matches the bottom then that number is a root in the forest but for example if the top number is a 9 and the bottom number is 0 then it means 9 is a child of 0. The ID array starts out with 9 single node trees and operations like 9-0 connects two trees together.

Resources