Generate all 10-digit phone numbers - backtracking - c

I need to generate all 10-digit telephone numbers which start with 0721 and have 3 distinct even digits (not counting the first 4). I know I should be using backtracking and I think I got the math behind this: out of the 6 remaining digits, we should have combinations of 5 taken as 3 (0, 2, 4, 6, 8) * combinations with repetitions of 5 taken as 3 (1, 3, 5, 7, 9). I'm just not sure how to write this in code as my valid function.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#define N 6 // because we already know the first 4 digits
int v[N], even[5] = {0, 2, 4, 6, 8}, odd[5] = {1, 3, 5, 7, 9};
void display()
{
FILE *fout = fopen("telephone_numbers.txt", "w");
if(!fout)
{
fprintf(stderr, "Error opening the file.\n");
exit(EXIT_FAILURE);
}
fprintf(fout, "0721 ");
for(int i = 0; i < N; i++)
{
fprintf(fout, "%d", v[i]);
}
fputc(';', fout);
}
bool valid(int step, int v[])
{
int i;
for(i = 1; i < step; i++)
{
if( // how do I implement the math here?
}
}
bool solution(step)
{
if(step == N)
return true;
return false;
}
void back(int step)
{
for(int i = 0; i < N; i++)
{
if(valid(step))
{
if(solution(step))
{
display();
}
else back(step + 1);
}
}
}
int main(int argc, char **argv)
{
back(1);
return 0;
}

Related

How to solve this C bitwise university problem?

Problem
Given a sequence of N integer values (N > 1). Using at most one conditional operator(or conditional operator), the program must determine whether its is true that sequence is increasing. Loops on a program can only be used to enumerate elements of a sequence.
Example
int arr[] = {10, 9, 8, 7, 6, 5}; // Decreasing sequence
int arr2[] = {1, 2, 3, 4, 5, 6}; // Increasing sequence
My solution
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*
Returns num1 if num1 < num2 otherwise num2
*/
static int CompareNums(int num1, int num2)
{
return (int)(((num1 + num2) - sqrt((num1 - num2) * (num1 - num2))) / 2);
}
static _Bool IsIncreasing(int arr[], size_t N)
{
int min = arr[0];
int res = 0;
for (size_t i = 0; i < N - 1; i++)
{
min = CompareNums(arr[i + 1], min);
/*If min equals to current processed num => it is decreasing sequence*/
res = min ^ arr[i + 1];
}
return res;
}
int main(void)
{
int arr[] = {10, 9, 8, 7, 6, 5};
int arr2[] = {1, 2, 3, 4, 5, 6};
int res = IsIncreasing(arr2, 6);
if (res == 0)
{
printf("Decreasing\n");
}
else
{
printf("Increasing\n");
}
return 0;
}
It has a problem, it's work fine with sequence from example, but doesn't work with sequence like this
//It is a complex sequence, but idk how to make my code detect this sequences.
int arr[] = {10, 11, 6, 12, 13}
Restrictions
//You can't use if inside for loop
for(int i = 0; i < N; i++)
{
//can't do this
if(bool)
{
}
//and this also
int a = a > b ? a : b
}
//And also this
while(a > b)
{
}
You need to calculate is it increasing sequence or not inside function than check for it for display right string
static _Bool IsIncreasing(int arr[], size_t N)
{
}
int main(void)
{
int res = IsIncreasing(arr, N);
if(res)
{
printf("Increasing");
}
else
{
printf("Decreasing");
}
}
So, I'm don't know how to write clean function which will calculate increasing/decreasing sequences, including errors sequences. I wan't any support or ideas or maybe ready solution how to do this.

Problem searching for a value in a matrix

I wanted to make a function that checks if a value exists in a matrix or not by giving (the matrice + the value I want to check + the line) as parameters and I'm getting an error on the transtype from an integer to a pointer. Please I need a help as soon as possible, thank you:)
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
bool Search(int *Mat[4][4], int val, int numLigne) {
int i;
for (i = 0; i <= 4; ++i) {
if (Mat[numLigne][i] == val)
return 1;
else
return 0;
}
}
int main() {
int Mat[4][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
int p;
p = Search(Mat[4][4], 5, 1);
printf("The number is: %d", p);
return 0;
}
Plenty problems
int *Mat[4][4] it is the array of pointers to int. Not the pointer to array. You want int Mat[4][4] here
Search(Mat[4][4], you do not pass the pointer to the function only the integer value which is taken outside the array bounds. 2 UBs in one call. You want Search(Mat, here
for( i=0; i<=4; ++i ) it is wrong as indexes in your array are from 0 to 3, and you integrate to 4. You want for( i=0; i<4; ++i )
This code
for( i=0; i<=4; ++i )
{
if(Mat[numLigne][i] == val )
return 1;
else
return 0;
}
is equivalent to:
if(Mat[numLigne][0] == val )
return 1;
else
return 0;
You will stop on the index 0 as you return on both conditions.
I think you need to read the pointer and array chapters of your favourite C book. You need to read about iterations, ifs and functions.
There are multiple problems in your code:
the prototype for Search should be bool Search(int Mat[4][4], int value, int row); or simply bool Search(int Mat[][4], int value, int row);. as posted you declare Mat to be a matrix of pointers to int.
the loop for (i = 0; i <= 4; ++i) should stop when i == 4, hence the test should be i < 4.
if the value if not found in the first column, you immediately return 0 without testing the other columns.
passing the matrix to the function is written Search(Mat, 5, 1). As posted, you attempt to pass the value of a matrix element outside the matrix.
Search returns a boolean indicating if the row contains the value, but the column number is not returned. It would be better to return the column number and return -1 if the value is not found.
Here is a modified version:
#include <stdio.h>
int Search(int Mat[4][4], int val, int row) {
for (int i = 0; i < 4; ++i) {
if (Mat[row][i] == val)
return i;
}
return -1; // not found
}
int main() {
int Mat[4][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
int col = Search(Mat, 5, 1);
if (col >= 0)
printf("The value %d is at position Mat[%d][%d]\n", 5, 1, col);
else
printf("The value %d is not present in row %d of Mat\n", 5, 1);
return 0;
}

Find count of missing elements in an unsorted array of integers

How can I find how many elements are missing from an array of integers in C, if some of the numbers are duplicated?
Assume the array is int array = {1, 2, 1, 5, 4} and there should be numbers up to 6. Then, the program/function should output/return 2, as there are 2 elements missing (3, 6).
Note: 0 is not counted as a missing number, nor can it be present in an array.
This way?
int countMissing(int *x, int arrLen, int bound)
{
int * y = malloc ((bound + 1) * sizeof(int));
int i = 0;
int missing = 0;
memset(y,0,sizeof(int)*(bound+1));
for(i = 0; i<arrLen; i++)
{
if(x[i]<=bound)
{
y[x[i]] = 1;
}else
{
// error handling e.g.
return -1;
}
}
for(i = 1; i<=bound; i++)
{
if(y[i]==0) missing++;
}
free(y);
return missing;
}
Usage:
int main(void)
{
int array [] = {1, 2, 1, 5, 4};
printf("%d", countMissing(array, 5, 10));
return 0;
}
Output: 6.

Longest increasing sequence in an array in C

I want to make a program that returns me the longest increasing sequence in an array.
For example:
Input: 1, 2, 3, 2, 6, 2
Output: 1, 2, 3
Input: 4, 3, 1, 2, 4, 6, 4, 1, 5, 3, 7
Output: 1, 2, 4, 6
I managed to put together a code, but this only returns me the first sequence of consecutive, increasing numbers:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int j = 0;
int cou = 0;
int max = 0;
// c = final array; will contain the longest consecutive, increasing sequence of numbers
int c[10];
int n = 0;
int a[] = {1, 3, 5, 1, 5, 7, 8, 9, 10, 11, 12};
for (int i = 0; i < (sizeof(a)/sizeof(int)); ++i) {
if (a[i+1] > a[i])
++cou;
if (cou > max) {
max = cou;
c[j] = a[i];
c[j+1] = a[i+1];
j++;
}
if (j > n) //finding the size of my final array
n = j;
else {
cou = 0;
j = 0;
}
}
for (j = 0; j <= n; ++j)
printf("%d ",c[j]);
return 0;
}
So basically, I want the longest sequence of increasing, consecutive numbers.
Been busting my brains on this one for quite a while now, and still haven't managed to crack it open. Any help is welcome.
You need to iterate through array, finding sequences, and comparing their length. So, you need to remember previous length of sequence to compare. And you can't copy result to output array on the fly (if you need output array at all), because you can't predict length of next sequence. I'll better show you an example.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int previous_len=0, start=0, c[10], len=0; //c = final array; will contain the longest consecutive, increasing sequence of numbers
int a[] = {1, 3, 5, 1, 5, 7, 8, 9, 10, 11, 12};
for (int i = 0; i < (sizeof(a)/sizeof(int)); ++i) {
if(a[i+1] > a[i]) {
len++;
if (len > previous_len) {
previous_len=len;
start=i+1-len;
}
} else {
previous_len=len;
len=0;
}
}
for(int i = 0; i <= previous_len; ++i) {
c[i]=a[start+i]; //here you can copy data to output array, if you need it
printf("%d ",c[i]); //you can output a[start+i] instead
}
return 0;
}
It seems to mee that you miss some curly braces:
if(a[i+1] > a[i])
{
++cou;
if (cou>max)
{max = cou;
c[j]=a[i];
c[j+1] = a[i+1];
j++;}
if (j > n) //finding the size of my final array
n=j;
}
else
{cou = 0;
j=0;}
I suggest breaking this down into smaller pieces.
Start with a function:
int sequenceLength(int[] array, int arrayLen, int position)
... which returns the length of the sequence beginning at position. Test it and make sure
it works. You shouldn't need help to write that.
Once you have that, you can write something like:
int longestSequence(int[] array, int arrayLen) {
int longest = 0;
int longestLen = 0;
for(int i=0; i<arrayLen; i++) {
int seqLen = sequenceLength(array, arrayLen, i);
if(seqLen > longestLen) {
longest = i;
longestLen = seqLen;
}
}
return longest;
}
Again, test this and make sure it works for all circumstances.
Finally you need a function:
printSequence(int[] array, int arrayLen, int position)
... which prints the sequence beginning at that position. Again you should be able to tackle this on your own.
Put all those together:
printSequence(array,arrayLen(longestSequence(array,arrayLen)));
It's always easiest to break a challenge like this into smaller pieces to solve it.
There may be more efficient solutions that avoid backtracking, but guessing at your level, I don't think you need to go there.
(Note: although the code here may compile, consider it as pseudocode)
you used a array to store the longest sequence, that made your code go wrong in printing.
And you dint use braces for if() statement that resulted in wrong sequence.
you can make the following changes to make the code work,
int main()
{int j=0, cou=0, max=0, c[10], n=0; //c = final array; will contain the longest consecutive, increasing sequence of numbers
int a[] = {1, 3, 5, 1, 5, 7, 8, 9, 10, 11, 12};
int i,k,z;
for ( k=0,i = 0; i < (sizeof(a)/sizeof(int)); ++i)
{if(a[i+1] > a[i])
{ ++cou;
if (cou>max)
{max = cou;
z=k;
}
}
else
{
k=i+1;
cou = 0;
j=0;}
}
for( j = z; j <(sizeof(a)/sizeof(int)) ; ++j)
if(a[j]<a[j+1])
printf("%d ",a[j]);
else
break;
printf("%d",a[j]);
return 0;
}

Linux C LibPCRE output unique results

I have the following code that matches a REGEX in a string that contains multiple duplicates, what I want to do is to print out only unique matches, what can I do? Add to an array than make it unique and only then print out the results? Thanks!
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pcre.h>
int main() {
pcre *myregexp;
const char *error;
int erroroffset;
int offsetcount;
int offsets[(0+1)*3]; // (max_capturing_groups+1)*3
const char *result;
char *subject = "9,5,3,2,5,6,3,2,5,6,3,2,2,2,5,0,5,5,6,6,1,";
myregexp = pcre_compile("\\d,", PCRE_MULTILINE|PCRE_DOTALL|PCRE_NEWLINE_ANYCRLF, &error, &erroroffset, NULL);
if (myregexp != NULL) {
offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), 0, 0, offsets, (0+1)*3);
while (offsetcount > 0) {
if (pcre_get_substring(subject, offsets, offsetcount, 0, &result) >= 0) {
printf("%s\n", result);
}
offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), offsets[1], 0, offsets, (0+1)*3);
}
} else {
printf("Syntax error in REGEX at erroroffset\n");
}
}
This outputs:
bash$ ./regex
9,
5,
3,
2,
5,
6,
3,
2,
5,
6,
3,
2,
2,
2,
5,
0,
5,
5,
6,
6,
1,
and I need:
bash$ ./regex
0,
1,
2,
3,
5,
6,
9,
Yes, add to an array and deduplicate from there.
You can not search unique values with regex. You can search replace with regex and deduplicate some things like double new lines, multiple spaces and so on, but this doesn't work when the deduplication needs to occur using random seeking.
Here is an example of how to deduplicate: a -> b
#include <stdio.h>
#include <string.h>
main()
{
char *a[5];
int a_len = 5;
a[0] = "a";
a[1] = "b";
a[2] = "b";
a[3] = "a";
a[4] = "c";
char *b[a_len];
int b_len = 0;
int already_exists;
int i, j;
for (i = 0; i < a_len; i++)
{
already_exists = 0;
for ( j = 0; j < b_len; j++)
{
if (!strcmp(a[i], b[j]))
{
already_exists = 1;
break;
}
}
if (!already_exists)
{
b[b_len] = a[i];
b_len++;
}
}
for (i = 0; i < b_len; i++)
{
printf("%s", b[i]);
}
}
For these small arrays this is probably the fastest algorithm. For better performance on bigger arrays I would suggest deduplication on a sorted array.

Resources