Given a list of prime ordered pairs, combine two lines with like terms to create an ordered triplet - c

Using C, I have generated a list of prime numbers to 10 million and from that list created another list consisting of ordered pairs [x,y] such that the difference of x and y is six.
However, when I try to write a code that generates an output of [x,y,z] triples, or [w,x,y,z] quadruple up to 10 million, my computer simply isn't powerful enough to finish the job in a reasonable amount of time.
My idea is to write a code that opens the text file of ordered pairs, recognizes a repeat number on two separate lines and combines those lines like so:
[5, 11]
[11, 17]
[17, 23]
[23, 29]
would turn into [5, 11, 17, 23, 29]
How can I do this in C?
edit: Here's my code to generate progressions of 5 numbers that differ by 6:
#include <stdio.h>
main()
{
freopen("test.txt", "w+", stdout);
FILE *twinPrimes;
twinPrimes = fopen("primes.txt", "r");
//read file into array
int numberArray[664579];
int i;
int j;
int k;
int l;
int m;
for (i = 0; i < 664579; i++)
{
fscanf(twinPrimes, "%d", &numberArray[i]);
}
for(i = 0; i < 664579; i++) {
for(j = i+1; j < i+6; j++) {
for(k = j+1; k < j+6; k++) {
for(l = k+1; l < k+6; l++) {
for(m = l+1; m < l+6; m++) {
if(abs(numberArray[i] - numberArray[j]) == 6) {
if(abs(numberArray[j] - numberArray[k]) == 6) {
if(abs(numberArray[k] - numberArray[l]) == 6) {
if(abs(numberArray[l] - numberArray[m]) == 6) {
printf("[%d, %d, %d, %d, %d]\n", numberArray[i], numberArray[j], numberArray[k], numberArray[l], numberArray[m]);} } } } } } }
}
}
}
However, the problem i'm still having is that I can't generate larger progressions without it slowing down my computer or taking extremely long to finish processing.
I have a text file, however, with a list of ordered pairs of primes that differ by 6. I think a MUCH more efficient code can be made by telling it to take the union of the two lines with a common element as shown above. However, I have no clue where to start with this code. Any help is appreciated.

Related

A question regarding making ordered pairs from every element in an array

I was curious about how I could possibly iterate through an array, and keep track of every single possible ordered pair.
To create a problem to illustrate this; lets say I have a function that takes in an input array, the length of that array and a "target" which is the product of 2 values, and outputs an array consisting of the indices of the input array that you need to multiply in order to get the "target".
int* multipairs(int* inputarray, int arraysize, int target){
/code
}
For example:
Given an array, arr = [2, 5, 1, 9, 1, 0, 10, 2], and target = 50
It should return output = [1,6].
In my mind, I would iterate through the arrays as follow;
(0,1) -> (0,2) -> (0,3) -> (0,4)....
In the second pass I would do:
(1,2) -> (1,3) -> (1,4)...
.
.
.
and so on
I have the idea of what I want to do, but I am unfamiliar with C programming, and have no idea how to make a proper for loop. Please help me figure this out.
Your description of the algorithm is complete - as you say, the first item in the pair is iterating over all the array indices. For each of those, you want to iterate over all the pairs that follow that in the array.
for (int i = 0, i < arraysize; i++)
{
for (int j = i + 1; j < arraysize; j++)
{
// operate on pair array[i] and array[j]
}
}
You can use nested for-loops to solve your problem.
int* multipairs(int* inputarray, int arraysize, int target){
int i, j, k = -1;
/*
Maximum number of such pairs can be arraysize*(arraysize-1)/2
Since, for each pair we store two indices (0-indexed),
maximum size of output array will be arraysize*(arraysize-1)
*/
int maxsize = arraysize*(arraysize-1);
int *output = (int*)malloc(sizeof(int)*maxsize);
for (i = 0, i < arraysize; i++){
for (j = i + 1; j < arraysize; j++){
if(inputarray[i] * inputarray[j] == target){
output[++k] = i;
output[++k] = j;
}
}
}
return output;
}

How to see if numbers have same digits in array?

I'm a bit stuck on one of my problems not because I don't know, but because I can't use more complex operations.(functions and multiple arrays)
So I need to make a program in C that ask for an input of an array(max 100 elements) and then program needs to sort that matrix by numbers with same digits.
So I made everything that I know, I tested my program with sorting algorithm from minimum to maximum values and it works, only thing that I can't understand is how should I test if the number have same digits inside the loop? (I can't use functions.)
So I know the method of finding if the number have the same digits but I don't know how to compare them. Here is an example of what I need.
This is what I have for now this sorts numbers from min to max.
#include <stdio.h>
int main() {
int matrix[100];
int i,j;
int temp,min;
int elements_number=0;
printf("Enter the values of matrix-max 100 elements-type -1 to end: ");
for(i=0;i<100;i++){
scanf("%d",&matrix[i]);
elements_number++;
if(matrix[i]==-1){
elements_number--;
break;
}
}
for (i=0; i<elements_number; i++) {
min=i;
for (j=i+1; j<elements_number; j++) {
if (matrix[j] < matrix[min])
min = j;
}
temp = matrix[i];
matrix[i] = matrix[min];
matrix[min] = temp;
}
for(i=0;i<elements_number;i++){
if(i!=elements_number-1){
printf("%d,",matrix[i]); }
else printf("%d.",matrix[i]);
}
return 0;
}
I need this output for these numbers:
INPUT :
1 22 43 444 51 16 7 8888 90 11 -1
OUTPUT:
1,22,444,7,8888,11,43,51,16,90.
Integers with 1 digit count as "numbers with same number of digits" like 7 and 1 in this example.
Hope that you can help.
After processing the array, the single-digit numbers should all be in the left part of the array, the other numbers in the right part. Within each part, the original order of the elements should be preserved. This is called a stable partition. It is different from sorting, because the elements are only classified into two groups. Sorting means that there is a clear relationship between any two elements in the array.
This can be done by "filtering" the array for single-digit numbers and storing the other numbers that were filtered out in a temporary second array. Then append the contents of that second array to the (now shorter) first array.
Here's how that could work:
#include <stdlib.h>
#include <stdio.h>
void print(const int *arr, int n)
{
for (int i = 0; i < 10; i++) {
if (i) printf(", ");
printf("%d", arr[i]);
}
puts(".");
}
int is_rep_digit(int n)
{
int q = n % 10;
n /= 10;
while (n) {
if (n % 10 != q) return 0;
n /= 10;
}
return 1;
}
int main()
{
int arr[10] = {1, 22, 43, 444, 51, 16, 7, 8888, 90, 11};
int aux[10]; // auxliary array for numbers with several digits
int i, j, k;
print(arr, 10);
j = 0; // number of single-digit numbers
k = 0; // number of other numbers
for (i = 0; i < 10; i++) {
if (is_rep_digit(arr[i])) {
arr[j++] = arr[i]; // pick single-digit number
} else {
aux[k++] = arr[i]; // copy other numbers to aux
}
}
k = 0;
while (j < 10) { // copy aux to end of array
arr[j++] = aux[k++];
}
print(arr, 10);
return 0;
}
Edit: I've just seen your requirement that you can't use functions. You could use Barmar's suggestion to test divisibility by 1, 11, 111 and so on. The tricky part is to find the correct divisor, however.
Anyway, the point I wanted to make here is that you don't need a full sorting algorithm here.

Decades Bucket Fill C Program

You are given the birth years of fifteen random people who were born in the twentieth century (1900 - 1999). You are given the data as the following array, which is to be the only argument used in your BucketSort function:
birthYears[] = {84, 51, 92, 72, 17, 62, 1, 16, 10, 28, 99, 71, 45, 18, 61};
Your function will have return type void and will work in the following manner:
• Create a 10x 10 array, which will represent the decades, and call it decade. Thus, decade[0][1] -> decade[0][9] will represent the 00’s, decade[1][0] -> decade[1][9] will represent the 10’s, and so on up to decade[9][0] -> decade[9][9] which will represent the 90’s.
• Initialize your array so that it contains only -1’s.
• Now go through the array birthYears and put each element in its appropriate bucket, and in its appropriate index (WATCH THE INDICES) in your decade array.
• Finally, trawl through decades, removing the elements one at a time and put back into the array birthYears. They should already be in the correct order.
This is what I have so far:
void Bucket_Sort(birthYears[]){
int i,j;
int decades[10][10];
for(i=0; i<15; i++)
}
//Actual Bucket Sort Function
void Bucket_Sort(int array[], int n){
int i, j;
int count[n];
for (i = 0; i < n; i++)
count[i] = 0;
for (i = 0; i < n; i++)
(count[array[i]])++;
for (i = 0, j = 0; i < n; i++)
for(; count[i] > 0; (count[i])--)
array[j++] = i;
}
I'm not sure how to proceed.
If I understand your assignment right, then I'd distribute the birthYear-values in a 10x10-array and then write them back (ordered now) into the birthYear-array. Note that Bucket Sort actually would require to sort each decade, but your assignment made it little bit simpler; Concerning the data, it seems as if each birth day occurs only once. Given that, the code could look as follows:
void Bucket_Sort(int array[], int n) {
// init decades array
int decades[10][10];
for(int dec=0;dec<10;dec++) {
for(int year=0;year<10;year++) {
decades[dec][year]=-1;
}
}
// distribute array values to decades array
for(int i=0; i<n; i++) {
int val = array[i];
int dec = val/10;
int year = val%10;
decades[dec][year]=val;
}
// write back
int target = 0;
for(int i=0; i<100; i++) {
int dec = i/10;
int year = i%10;
int val = decades[dec][year];
if (val>=0) {
array[target++] = val;
}
}
}

A way to go over the diagonals of an array of size [6][7]

I'm building in C language, a game called 4-in-a-row or Connect Four, for a fast review of the game you can see here:
http://en.wikipedia.org/wiki/Connect_Four
so, I have a 2 dimensional array of size [6][7], and I want to check in diagonal if there are 4 tokens which are "*" or "o" that are defined as a chars which are in a a row. I'm trying to write a function that after each play, it sums up all the possible diagonals and see if the sum is 4 for example, or if we want to check in pairs, if we get three similar pairs then there are 4 equal tokens in a row, so in this case the sum is 3, and so on..
for all I know, there are 12 different different diagonals (every 6 on different direction), how do u suggest me to write this function while being the most effective? and also including all the possibilities with less that 16 lines of code.
any kind of help would be appreciated!
here is an example of what I did:
int CheckDiagonal_1(char matrix[Rows][Columns])
{
int s_count = 0;
int o_count = 0;
for(int i = 0; i < 4; i++)
{
for(int j = 5; j >= 3; j--)
{
for(int k = 0; k <= 3; k++)
{
if(matrix[j-k][i+k]== matrix[j-k-1][i+k+1]) count ++;
if(count==4) return count;
}
count = 0;
}
}
return 0;
}
Diagonals are sequences where
i == j + c for i from (0,height) and c (-width, height)
or i == -j + c.
So if goal to write code that fits into small number of lines - just write loops that go over i {0-6} and check for indexes to fit in range. Something like
for (int c= -7; c < 7; c++)
{
int starsOnDiag = 0;
for(int i = 0; i < 7; i++)
{
starsOnDiag += !indexesInRange(i, j) ? 0 :
cell[i, i+c] == '*' ? 1 : 0;
}
... // other diagonal and check for other symbol
}

Algorithm for finding saddle-points in a 2-dimensional array

I'm looking for an algorithm to find the positions of all saddle points in an NxN matrix.
Searching through other answers on StackOverflow, as well as other sites in general, I've only found solutions regarding saddle points that operate in one direction. That is, I want to find a saddle point that can be a maximum in its row and minimum in its column, or a minimum in its row and maximum in its column.
For example, given:
array = {
{ 10, 15, 20, 15, 10 }
{ 5, 10, 15, 10, 5 }
{ 0, 5, 10, 5, 0 }
{ 5, 10, 15, 10, 5 }
{ 10, 15, 20, 15, 10 } },
the saddle points are the 10's in the corners and the 10 in the middle.
I can find them naively fairly easily, but I wanted something more efficient. I've been told it can be done in O(n^2).
I thought perhaps I could fix the x-coordinate and iterate through the y-coordinate to find all maximums and minimums, then reverse the process by fixing the y-coordinate and iterating through the x-coordinate, but I can't quite visualize it well enough to implement the idea.
Any help would be greatly appreciated.
Notice that in the naive implementation O(n3), you are recalculating the maximum value and minimum value for every element of a row/column you go through.
To eliminate this inefficiency, the idea is to loop through every row and column, and mark all positions with the maximum and minimum value in a separate N x N array. Each element of this separate array contains 2 pieces of boolean information: isMax and isMin (which can be encoded as bit if you want to). If all elements in a row/column are the same (i.e. maximum value = minimum value), then you might not want to mark any element.
For each row/column, this can be done in O(n) time. Use an n-element array to record the indices where the current maximum (minimum) value, and clear the array if there is a bigger (smaller) value than the current maximum (minimum). After you have finished looping through, use the information from the maximum (minimum) indices array to mark the corresponding isMax (isMin) field in the N x N array.
Since there are n rows and n columns, the complexity of this step is O(n2)
Then the rest is to loop through the N x N array which you have marked to search for any position with both isMax and isMin set.
O(n^2)
#include <stdio.h>
#define N 8
#define M 10
int arr[N][M] =
{ {1,2,0,3,9,4,5,3,6,7},
{2,4,3,5,9,0,2,3,4,1},
{5,3,4,7,6,1,9,0,4,2},
{6,9,7,8,6,7,7,4,5,6},
{8,3,1,9,2,0,6,2,8,2},
{2,7,3,0,3,6,3,1,5,3},
{8,2,5,9,7,7,8,3,7,3},
{1,7,4,8,5,8,5,0,0,6} };
int FindSaddlePoints(int arr[N][M])
{
int l_result = 0;
int l_row[M], l_column[N], i, j, index;
//find the min
for (i = 0; i < N; i++)
{
index = 0;
for (j = 1; j < M; j++)
{
if (arr[i][j] < arr[i][index])
{
index = j;
}
}
l_column[i] = index;
}
for (j = 0; j < M; j++)
{
index = 0;
//find the max
for (i = 1; i < N; i++)
{
if (arr[i][j] > arr[index][j])
{
index = i;
}
}
l_row[j] = index;
}
for (i = 0; i < N; i++)
{
for (j = 0; j < M; j++)
{
if (l_row[j] == i && l_column[i] == j && i != N && j != M)
{
//printf("found in row = %d column = %d", i, j);
l_result++;
}
}
}
return l_result;
}
void main()
{
int number = FindSaddlePoints(arr);
printf("%d", number);
}

Resources