Subset using Backtracking - c

The following question I was asked to solve using backtracking:
It's supposed to return the length of the longest subset of differences that replaces a sign.
For example:
for this given series [11,6,7,8,9] it returns 3.
because it includes this subset [11,8,9] and [11,6,8] .
*In this series a:[11,8,9] a[1]-a[0]<0 and a[2]-a[1]>0 .In other words the sign of the difference between each neighbor changes. *
I pretty much finished the coding but have no idea how to return the max length using backtracking.
Any note/help will be highly appreciated.
/* this function checks if we can add another number to the sequence
and still the differences between the numbers replace a sign.It's enough
to check the last two*/
int check_rec(int series[],int arr[],int n)
{ int count=0,c=n;
int temp1=0,temp2=0;
while(c>=0 && count!=2)
{
if (arr[c]==1 && count==0)
{ temp1=series[c];
count++;
}
if (arr[c]==1 && count==1 )
{ temp1=series[c];
count++;
}
c--;
}
if(count<2) return 1;
if(temp1>temp2 && series[n+1] < temp1) return 1;
if(temp1<temp2 && series[n+1]> temp1) return 1;
return 0;
}
int count_ones(int arr[],int n)
{ int c;
for(int i=0;i<n;i++)
{
if(arr[i])
c++;
}
return c;
}
// 1 in the array helper indicates that the index has been chosen.
void max_crazy(int series[], int n,int helper[],int length,int max[])
{
if(n==0)
{
int x=count_ones(helper,n);
if(x>max[0])
max[0]=x;
}
for(int i=0;i<2;i++)
{
if(n!=length && i==1 && !check_rec(series,helper,length-n))
continue;
helper[0]=i;
max_crazy(series,n-1,helper+1,length,max);
}
}

you can send a pointer that saves the max in the recursive function , and every time you reach the if(n==0) you have to check if the count_ones bigger than max then max=count_ones

Related

Program that computes the nth element of a number series given by a formula

Write a method/function with name cpSeries that computes the nth element in a series of numbers, given by the formula: a(n) = (a(n-1))2+a(n-2) when: n>1 and assuming that: a(1)=1, a(0)=0 Note that indexing of the series starts from 0.
I have already written the above code but it runs for an infinite time and I don't know how to fix it in order to compute the nth element.
Any ideas? I have to use only functions to solve this problem.
# include <stdio.h>
int cpSeries(int n)
{
int Nthterm = 0;
int i;
if (n==0) {
cpSeries(0) == 0;
}
else if (n==1) {
cpSeries(1) == 1;
}
for (i=0; i<=n; i++){
Nthterm = cpSeries((n-1))*cpSeries((n-1)) + cpSeries((n-2));
return Nthterm;
}
}
int main()
{
int n=6;
printf("The Nth term of the series is: %d",cpSeries(n));
}
If the provided equation gives you the nth element, I don't see the need for a loop.
Also, in the if conditions, you are calling the function again, but what you should do is return the value you need.
int cpSeries(int n){
int Nthterm;
if (n==0){
Nthterm = 0;
}
else if (n==1){
Nthterm = 1;
}
else {
Nthterm = cpSeries((n-1))*cpSeries((n-1)) + cpSeries((n-2));
}
return Nthterm;
}
Your final conditions just call the function another time instead of returning 0 or 1.
instead of
if (n==0) {
cpSeries(0) == 0;
}
else if (n==1) {
cpSeries(1) == 1;
}
use
if (n==0) {
return 0;
}
else if (n==1) {
return 1;
}
C is not a declarative language where you can specify the return value y of a function f given an argument x by writing something like f(x) = y, but you have to use a return statement.
Change cpSeries(0) == 0; to
return 0;
to avoid the infinite recursion (and the same for n == 1).

Understanding returning values functions C

I'm trying to understand how the return value of a function works, through the following program that has been given to me,
It goes like this :
Write a function that given an array of character v and its dim, return the capital letter that more often is followed by its next letter in the alphabetical order.
And the example goes like : if I have the string "B T M N M P S T M N" the function will return M (because two times is followed by N).
I thought the following thing to create the function:
I'm gonna consider the character inserted into the array like integer thank to the ASCII code so I'm gonna create an int function that returns an integer but I'm going to print like a char; that what I was hoping to do,
And I think I did, because with the string BTMNMPSTMN the function prints M, but for example with the string 'ABDPE' the function returns P; that's not what I wanted, because should return 'A'.
I think I'm misunderstanding something in my code or into the returning value of the functions.
Any help would be appreciated,
The code goes like this:
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int trovato;
for(int j=0;j<DIM-1;j++) {
if (a[j]- a[j+1]==-1) {
trovato=a[j];
}
}
return trovato;
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("%c",maxvolte(v,dim));
return 0;
}
P.S
I was unable to insert the value of the array using in a for scanf("%c,&v[i]) or getchar() because the program stops almost immediately due to the intepretation of '\n' a character, so I tried with strings, the result was achieved but I'd like to understand or at least have an example on how to store an array of character properly.
Any help or tip would be appreciated.
There are a few things, I think you did not get it right.
First you need to consider that there are multiple pairs of characters satisfying a[j] - a[j+1] == -1
.
Second you assume any input will generate a valid answer. That could be no such pair at all, for example, ACE as input.
Here is my fix based on your code and it does not address the second issue but you can take it as a starting point.
#include <stdio.h>
#include <assert.h>
int maxvolte(char a[],int DIM) {
int count[26] = {0};
for(int j=0;j<DIM-1;j++) {
if (a[j] - a[j+1]==-1) {
int index = a[j] - 'A'; // assume all input are valid, namely only A..Z letters are allowed
++count[index];
}
}
int max = -1;
int index = -1;
for (int i = 0; i < 26; ++i) {
if (count[i] > max) {
max = count[i];
index = i;
}
}
assert (max != -1);
return index + 'A';
}
int main()
{
int dim;
scanf("%d",&dim);
char v[dim];
scanf("%s",v);
printf("answer is %c\n",maxvolte(v,dim));
return 0;
}
#include <stdio.h>
int maxvolte(char a[],int DIM) {
int hold;
int freq;
int max =0 ;
int result;
int i,j;
for(int j=0; j<DIM; j++) {
hold = a[j];
freq = 0;
if(a[j]-a[j+1] == -1) {
freq++;
}
for(i=j+1; i<DIM-1; i++) { //search another couple
if(hold==a[i]) {
if(a[i]-a[i+1] == -1) {
freq++;
}
}
}
if(freq>max) {
result = hold;
max=freq;
}
}
return result;
}
int main()
{
char v[] = "ABDPE";
int dim = sizeof(v) / sizeof(v[0]);
printf("\nresult : %c", maxvolte(v,dim));
return 0;
}

CS50x pset3 (Why doesn't my program pass Check50?)

I completed my Problem Set 3 helpers.c program and it works perfectly up to a total of 10 of haystack but stops working when I press Control-D with less than 10 in haystack. Instead the program skips a line and I can freely write like in a not pad. Since, it can not pass 3 or 4 in haystacks, my program can't pass Check50. Does anybody have a solution to this problem?
In case you need my code, here it is:
bool search(int value, int values[], int n)
{
if(value < 0)
{
return false;
}
for(int i = 0; i < n; i++)
{
if (value == values[i])
{
return true;
}
}
return false;
}
/**
* Sorts array of n values.
*/
void sort(int values[], int n)
{
bool tf;
do
{
tf = false;
for(int i=0; i < n-1; i++)
{
if(values[i] > values[i+1])
{
int temp = values[i];
values[i] = values[i+1];
values[i+1] = temp;
tf = true;
}
}
}
while(tf == false);
return;
}
Your sorting algorithm is flawed. It just takes one round of the whole array and arranges it partially in order but not fully.
You can use bubble sort (refer to https://en.wikipedia.org/wiki/Bubble_sort or the lecture of cs50) of which I cannot provide code as it is against the honour code of the course.

Search of an element on a unsorted array recursively

This is an exercise that I took from an exam. It asks to write a function that receives an unsorted array v[] and a number X and the function will return 1 if X is present in v[] or 0 if X is not present in v[]. The function must be recursive and must work in this manner:
1. Compares X with the element in the middle of v[];
2. The function calls itself (recursion!!) on upper half and on the lower half of v[];
So I've written this function:
int occ(int *p,int dim,int X){
int pivot,a,b;
pivot=(dim)/2;
if(dim==0) //end of array
return 0;
if(*(p+pivot)==X) //verify if the element in the middle is X
return 1;
a=occ(p,pivot,X); //call on lower half
b=occ(p+pivot,dim-pivot,X); //call on upper half
if(a+b>=1) //if X is found return 1 else 0
return 1;
else{
return 0;
}
}
I tried to simulated it on a sheet of paper and it seems to be correct (Even though I'm not sure) then I've written it on ideone and it can't run the program!
Here is the link: https://ideone.com/ZwwpAW
Is my code actually wrong (probably!) or is it a problem related to ideone. Can someone help me? Thank you in advance!!!
The problem is with b=occ(p+pivot,dim-pivot,X); when pivot is 0. i.e. when dim is 1.
the next function call becomes occ(p,1,X); This again leads to the call occ(p,1,X); in a continuous loop.
It can be fixed by adding a condition to the call, as shown in the code below.
int occ(int *p,int dim,int X){
int pivot,a=0,b=0;
pivot=(dim)/2;
if(dim==0){
return 0;
}
if(*(p+pivot)==X)
return 1;
if (pivot != 0)
{
a=occ(p,pivot,X);
b=occ(p+pivot,dim-pivot,X);
}
if(a+b>=1)
return 1;
else{
return 0;
}
}
The implemetation is causing a stack overflow, as the recursion does not terminate if the input contains only one element. This can be fixed as follows.
int occ(int *p, int dim, int X)
{
int pivot, a, b;
pivot = (dim) / 2;
if (dim == 0)
{
return 0;
}
if (*(p + pivot) == X)
{
return 1;
}
if (dim == 1)
{
if (*(p + pivot) == X)
{
return 1;
}
else
{
return 0;
}
}
a = occ(p, pivot, X);
b = occ(p + pivot, dim - pivot, X);
if (a + b >= 1)
{
return 1;
}
else
{
return 0;
}
}
It's enought to change only this one line in the source code to avoid the endless loop with occ(p,1,X):
//if(dim==0) //end of array
if (pivot == 0)
return 0;

Modified N-Queens in C

I'm trying to modify an N-Queen puzzle solver to an N-Empress solver (Where the pieces can move like both rook and knight)
The code places (or at least tries to place) the chancellors in a way that they do not threaten each other. And backtracks to print all of the possible solutions. However, I can't get it to output the correct amount of solutions. The current ones it outputs is correct, but it doesn't output all of them. Not sure what condition I'm missing.
#include<stdio.h>
#include<math.h>
/*
N=4:8 Solutions
N=5:20 Solutions
N=8:2766 Solutions
*/
int board[20],count;
int main()
{
int n,i,j,numPuzzle;
void queen(int row,int n);
printf("Enter Number of Queens:");
scanf("%d", &n);
queen(1,n);
return 0;
}
//function for printing the solution
void print(int n)
{
int i,j;
printf("\n\nSolution %d:\n\n",++count);
for(i=1;i<=n;++i)
printf("\t%d",i);
for(i=1;i<=n;++i)
{
printf("\n\n%d",i);
for(j=1;j<=n;++j) //for nxn board
{
if(board[i]==j)
printf("\tQ"); //queen at i,j position
else
printf("\t-"); //empty slot
}
}
}
/*funtion to check conflicts
If no conflict for desired postion returns 1 otherwise returns 0*/
int place(int row,int column)
{
int i;
for(i=1;i<=row-1;++i)
{
//checking column and digonal conflicts
//printf("\nboard[i]=%d column=%d\n",board[i],column);
if(board[i]==column)
{
return 0;
}
if( (abs(board[i]-(column+3))==abs(i-row)) )
{
return 0;
}
if( (abs(board[i]-(column-3))==abs(i-row)) )
{
return 0;
}
if( (abs(board[i]+(column-3))==abs(i-row)) )
{
return 0;
}
if( (abs(board[i]+(column+3))==abs(i-row)) )
{
return 0;
}
}
return 1; //no conflicts
}
//function to check for proper positioning of queen
void queen(int row,int n)
{
int column;
for(column=1;column<=n;++column)
{
if(place(row,column))
{
board[row]=column; //no conflicts so place queen
if(row==n) //dead end
print(n); //printing the board configuration
else //try queen with next position
queen(row+1,n);
}
}
}
The place method is doesn't seem to be covering all cases. In knight move, the difference in columns and difference in rows sum up to 3.
int place(int row,int column)
{
int i;
for(i=1;i<=row-1;++i)
{
//checking column and digonal conflicts
//printf("\nboard[i]=%d column=%d\n",board[i],column);
if(board[i]==column)
{
return 0;
}
if(abs(board[i]-column)+abs(row-i)==3 )
{
return 0;
}
}
return 1; //no conflicts
}
The check against the Knight attack involves testing four tiles in relation to the current one. (There are eight possible Knight moves, but you only have to look in the rows that you have already placed Chancellors in, of course.)
in place, you probe the tile column and row, so you should check
board[row - 1] != column ± 2 (only if row -1 is on the board)
board[row - 2] != column ± 1 (only if row - 2 is on the board)
While you need to check all rows for attacking Rooks, the check for the Knight move is done only once. So:
int place(int row, int column)
{
int i;
if (row > 1 && abs(column - board[row - 1]) == 2) return 0;
if (row > 2 && abs(column - board[row - 2]) == 1) return 0;
for (i = 1; i < row; ++i) {
if (board[i] == column) return 0;
}
return 1;
}

Resources