How can I do this again? in C - c

#define G 10
int main(){
int grid[G][G],c,x;
for(c=1;c<=5;c++){
for(x=1;x<=5;x++){
if(c+x<=5)
grid[c][x]=+1;
else if(c+x>=7)
grid[c][x]=-1;
else
grid[c][x]=0;
printf("%2d\t ",grid[c][x]);
}
printf("\n");
}
getch();
return 0;
}
its output is
Which is what I really wanted to do but now I need to make it look like
and now I don't have any idea on how to do it, it's hurting my head now

I would do it like this
for(c=0; c<5; c++) { /* arrays start at 0, not 1. */
for(x=0; x<5; x++) { /* arrays start at 0, not 1. */
if (c == x) { /* looking at your output, the 0's occur when c == x */
grid[c][x] = 0;
} else if (c > x) { /* the -1 when c > x */
grid[c][x] = -1;
} else { /* obviously c > x */
grid[c][x] = 1;
}
/* nothing else changed */
printf("%2d\t ",grid[c][x]);
}
printf("\n");
}

It's quite simple, you have three distinct cases:
if both c and x are equal, your grid shows zero
if x is greater than c, your grid shows 1
else (ie, when x is less than c), your grid shows -1
Basically, we've written the if-else structure you need in your loop to get the desired output:
if (c == x) grid[c][x] = 0;
else if (x > c) grid[c][x] = 1;
else grid[c][x] = -1;
Thus, the full code looks like this:
#include <stdio.h>
#define G 10
int main()
{
int grid[G][G],c,x;
for(c=0;c<5;++c)
{//zero indexed
for(x=0;x<5;++x)
{//perhaps change 5 with G, or another macro or some int
if(c == x) grid[c][x] = 0;
else if (c < x) grid[c][x] = 1;//1 is fine, the + is not required
else grid[c][x] = -1;
printf("%2d\t ",grid[c][x]);
}
printf("\n");
}
return 0;
}
Which as you can see on this codepad works just fine.
note:
As I said, the + in +1 is optional. I'd even advise against it. If I happen to come across a statement like some_int = +1; I might assume that it's a bug, and it was supposed to read some_int += 1;, which is a different thing all together.

The major diagonal of matrix is collection of elements that meet row==column condition. Plus we know that row and column elements above(right from) diagonal meet row<column, and below ones row>column condition. And here is how to make that matrix and while making we will show them :
#define G 5
int grid[G][G], row, column;
for (row =0; row < G; row++) {
for (column =0; column < G; column++) {
if (row<column)
grid[row][column] = 1;
else if (row>column)
grid[row][column] = -1;
else
grid[row][column] = 0;
printf("%2d\t ", grid[row][column]);
}
printf("\n");
}
And here is output:
0 1 1 1 1
-1 0 1 1 1
-1 -1 0 1 1
-1 -1 -1 0 1
-1 -1 -1 -1 0
And Here is what was your problem.
You chose minor (secondary) diagonal isntead of main
Your index handling done manually .Like you calculated conditions manually. It is not good
And here is how you should do for minor diagonal without calculating condition manually
#define G 5
int grid[G][G], row, column ;
for(row=0;row<G;row++){
for(column=0;column< G;column++){
if(row+column<G-1)
grid[row][column]=1;
else if(row+column>G-1)
grid[row][column]=-1;
else /*minor diagonal meet row==(G-1)-column //G-1 cause index begins from 0*/
grid[row][column]=0;
printf("%2d\t ",grid[row][column]);
}
printf("\n");
}

Now Swap the first and last columns of your matrix then second and second last. Thats it

#include <stdio.h>
#define G 10
int i,j;
int grid[G][G];
int main() {
for(i=0; i<G; i++) {
for(j=0; j<G; j++) {
if(i==j) grid[i][j]=0;
else if(i<j) grid[i][j]=1;
else if(i>j) grid[i][j]=-1;
printf("%2d\t", grid[i][j]);
}
printf("\n");
}
return 0;
}

you can modify your program as below :
1,for(c=1;c<=5;c++) -->for(c=5;c>=1;c--)
2, grid[c][x]=+1; --> grid[c][x]=-1;
3, grid[c][x]=1; --> grid[c][x]=+1;
#define G 10
int main(){
int grid[G][G],c,x;
for(c=5;c>=1;c--){
for(x=1;x<=5;x++){
if(c+x<=5)
grid[c][x]=-1;
else if(c+x>=7)
grid[c][x]= 1;
else
grid[c][x]=0;
printf("%2d\t ",grid[c][x]);
}
printf("\n");
}
getch();
return 0;
}

You need to create a 2D matrix, where the matrix is diagonally zero, upper triangle would be 1, and lower triangle would be -1.
So,
if **row == column** , then assign 0 to diagonal. (**grid[row][column] = 0**)
else if , **row < column**, then assign 1 to upper triangle. (*grid[row][column*] = 1)
else, **row > column**, then assign -1 to lower triangle. (*grid[row][column] = -1*)

Related

Is it possible to simplify this algorithm so that it only uses 1 loop and 2 variables?

Is it possible to get the same results as this code using only a and b?
I'm trying to calculate c from a and b to avoid using a third variable, but I can't find a solution.
#include <stdio.h>
#include <stdlib.h>
const int LENGTH = 20;
int main()
{
char arr[LENGTH];
for (int a = 0, b = 1, c = 0; c < LENGTH; c++) {
if (a < b) {
arr[c] = '*';
a++;
} else {
arr[c] = ' ';
a = 0;
b++;
}
}
printf(arr);
return EXIT_SUCCESS;
}
Code result : * ** *** **** *****
In the event that checking if a number is triangular by linking or writing some sort of sqrt() function is not a solution that you find acceptable:
Each group of **... in the final string has a ' ' at the end, so the shortest segment in the string is "* ", which is 2 chars long.
The c in your loop is the index of the char array that this iteration should write to, the a is the index inside the current group of '*'s, and b is length of the current group of '*'s less one (since we want to count the spaces). Directly before the if clause in your for loop, it can be said that c is the sum from 2 to b plus a.
In other words, if a=0, and b=1, then c=0, because the sum from 2 to 0 is 0, plus 0 is 0.
If a=3, and b=4, then c= (2+3+4) + 3 = 12.
This means that you could write your code like this:
#include <stdio.h>
const int LENGTH = 20;
int sumFromTwo(int in){ //Recursive function to calculate sigma(2:in)
if(in < 2)
return 0;
else
return in + sumFromTwo(in - 1);
}
int main()
{
char arr[LENGTH + 1]; //Extra byte for null-terminator
for (int a = 0, b = 1; sumFromTwo(b) + a < LENGTH ; ) {
if (a < b) {
arr[sumFromTwo(b) + a] = '*';
a++;
} else {
arr[sumFromTwo(b) + a] = ' ';
a = 0;
b++;
}
}
arr[LENGTH] = '\0'; //Always null-terminate your strings
printf(arr);
return EXIT_SUCCESS;
}
But using recursion to avoid using a variable that is almost certainly going to be optimized into a register anyway is not going to save your computer any resources, least of all RAM, so it is definitely cleaner to do it the way you did in your question (but please null-terminate your string before passing it to your choice of printf or puts).

Recursive Fibonacci in C

I'm trying to figure out why this code isn't working.
#include <stdio.h>
int main()
{
int num;
puts("what index of the Fibbonaci series do you want?");
scanf("%d", &num);
num = fib(num);
printf("%d", num);
return 0;
}
int fib(int num)
{
if (num == 0)
return 1;
else if (num == 1)
return 1;
else return (fib(num - 1)+fib(num-2));
}
P.S. I'm trying to keep it as simple as possible, and I was told that index's 0 and 1 are equal to 1.
Firstly, your function is not declared before main() and that is why your program does not run1.
Secondly, Fibonacci Sequence is defined as either:
1, 1, 2, 3, 5, 8,...
or
0, 1, 1, 2, 3, 5, 8,...
where the recursive relation describing it is : Fibn = Fibn-1 + Fibn-2
Which converted in C code would look like either something similar with what you got (first definition above), or a bit modified (using the second equally right definition):
int fib(int num)
{
if (num == 0) {
return 0;
} else if (num == 1) {
return 1;
} else {
return fib(num - 1) + fib(num - 2);
}
}
Note:
Both mine and your versions of the function are not very effective as they will make a lot of calls, most of them to calculate overlapping values, i.e. they will calculate a lot of overlapping subproblems. This could be fixed by using memoization.
Here is an example of an implementation, using the above notion of memoization:
// header needed for the container: map
#include <map>
int mem_fact (int i, std::map<int, int>& m) {
// if value with key == i does not exist in m: calculate it
if (m.find(i) == m.end()) {
// the recursive calls are made only if the value doesn't already exist
m[i] = mem_fact (i - 1, m) + mem_fact (i - 2, m);
}
// if value with key == i exists, return the corresponding value
return m[i];
}
int fast_factorial (int i) {
// key (Fibonacci index) - value (Fibbonaci number)
std::map<int, int> memo;
// initialize the first two Fibonacci numbers
memo.insert(std::pair<int,int>(0, 0));
memo.insert(std::pair<int,int>(1, 1));
return mem_fact(i, memo);
}
then in main,if you call both like so:
int slow_fib = fib(10);
int fast_fib = fast_factorial(10);
you will get the same result: slow_fib = fast_fib = 55, however fib() will have to make 177 calls and fast_factorial() only 19 calls.
1. error: 'fib' was not declared in this scope
fib(0) is 0, not 1. Whoever indicated/ordered that fib(0) is 1 is wrong.
Change
if (num == 0)
return 1;
to
if (num == 0)
return 0;
Best thing is to avoid recursive form as possible.
int fib(int index) -- first fibonacci number is at index 0
{
int a = 0;
int b = 1;
int c = 0;
for (int i = 0; i<index; ++i)
{
a = b;
b += c;
c = a;
}
return a; // <<-- value at index
}

Find number of paths in a 2d binary array (C)

I have been asked this question during an interview, and have been struggling to find an elegant solution (in C), Problem statement:
You are given a two-dimensional array with M rows and N columns.
You are initially positioned at (0,0) which is the top-left cell in
the array.
You are allowed to move either right or downwards.
The array is filled with 1′s and 0′s. A 1 indicates that you can move
through that cell, a 0 indicates that you cannot move through the
cell.
Write a function in C ‘numberOfPaths’ which takes in the above two dimensional array, return the number of valid paths from the top-left cell to the bottom-right cell (i.e. [0,0] to [M-1,N-1]).
Edit: forgot to mention that the requirement is for a recursive solution
help would be greatly appreciated!
Thanks
If you are looking for a recursive solution you can use DFS.
DFS (array, x, y)
{
if (array [x][y]==0 || x>M || y>N){
return;
}
if (x==M && y==N){
count++;
return;
}
DFS (array, x, y+1);
DFS (array, x+1, y);
}
The number of paths to a given point is just the number of paths to the point above, plus the number of paths to the point to the left. So, the pseudo-code would roughly be:
num_paths[0][0] = 1;
for (x = 0; x < M; ++x)
for (y = 0; y < N; ++y)
if (!allowed_through[x][y])
num_paths[x][y] = 0;
else
num_paths[x][y] = num_paths[x-1][y] + num_paths[x][y-1];
You need special cases for x=0 and y=0, but otherwise, I think that should do.
#include <stdio.h>
int count=0;
int maxrows = 10;
int maxcols = 10;
int M, N;
void DFS (int array[][10], int x, int y)
{
int r, c;
/* process element at input row and column */
if (array [x][y]==0 || x>M || y>N){
/* no path forward; return */
return;
}
if (x==M-1 && y==N-1){
/* found path; increment count */
count++;
return;
}
/* recurse: to matrix starting from same row, next column */
r = x;
c = y +1;
if (c < N-1) {
DFS (array, r,c);
} else {
/* if last column - check to see */
/* if rest of rows in last column allow for a path */
int tr = r;
while ( tr <= M-1) {
if (array[tr][c] == 1) {
tr++;
}
else {
return;
}
}
/* reached last node - path exists! */
count++;
}
/* recurse: to matrix starting from next row, same column */
r = x+1;
c = y;
if (r < M-1) {
DFS (array, r,c);
} else {
/* if last row - check to see */
/* if rest of columns in last row allow for a path */
int tc = c;
while ( tc <= N-1) {
if (array[r][tc] == 1) {
tc++;
} else {
return;
}
}
/* reached last node - path exists! */
count++;
}
}
int main () {
int i, j;
scanf("%d %d",&M,&N);
int a[10][10] = {};
int row, col;
for(i=0;i<M;i++)
for(j=0;j<N;j++)
scanf("%d", &a[i][j]);
if ((M > maxrows) || (N > maxcols)) {
printf("max of 10 rows and 10 cols allowed for input\n");
return (-1);
};
/* print input matrix */
for(row=0;row<M;row++) {
for(col=0;col<N;col++){
printf("%d ",a[row][col]);
}
printf(" EOR\n");
}
DFS(a,0,0);
printf("number of paths is %d\n", count);
return 0;
}
Try this function its a preliminary step before printing all the paths.
If the size of the vector Out is 0 then the # of paths are 0, but if size(Out) > 0 then the size of vector Nodes + 1 are the total number of paths from top left to bottom right.
#include <iostream>
#include <vector>
using namespace std;
typedef vector<pair<int,int> > vPii;
bool pathTL2BR( int Arr2D[][4], vPii &Out, vPii &Nodes,
int _x,int _y, int _M, int _N)
{
bool out1 = false;
bool out2 = false;
if( Arr2D[_x][_y] == 1 )
{
if( _y+1 < _N )
out1 = pathTL2BR( Arr2D, Out, Nodes, _x, _y+1, _M, _N);
if( _x+1 < _M )
out2 = pathTL2BR( Arr2D, Out, Nodes, _x+1, _y, _M, _N);
if( (out1 || out2) ||
( (_x == (_M-1)) && (_y == (_N-1)) ) )
{
if(out1 && out2)
Nodes.push_back( make_pair(_x,_y ) );
Out.push_back( make_pair(_x,_y ) );
return true;
}
else
return false;
}
else
return false;
}
// Driver program to test above function
int main()
{
int Arr2D[][4] = {
{1,1,1,1},
{0,1,0,1},
{0,1,0,1},
{0,1,0,1}
};
vPii Out;
vPii Nodes;
vector<vPii> Output;
pathTL2BR( Arr2D, Out, Nodes, 0, 0, 4, 4);
return 0;
}
This is a python solution, I have put explanations in the comments.
def find_num_paths(arr_2D, i, j):
# i,j is the start point and you have to travel all the way back to 0,0
if i == j and i == 0:
return 1 # you have reached the start point
if i < 0 or j < 0 or arr_2D[i][j] == 0: # out of range or no path from that point
return 0
if arr_2D[i][j] == 1:
return find_num_paths(arr_2D, i, j-1) + find_num_paths(arr_2D, i-1, j) + find_num_paths(arr_2D, i-1, j-1) # you could go one step above, to the left or diagonally up.

I would like to to generate random values in C

I would like to ask about random values in C.
My C program has coding as below.
int random_a( int current_s,int r[num_s][num_a])
{
int i;
for(i=0;i<4;i++)
{
if(r[current_s][i] > -1) break;
}
return i;
}
For example condition
r[current_s][0] and r[current_s][2] > -1
If I run my program, answer have only i = 0. But I would like to get random answer that is 0 and 2 (1 and 3 not included because r[current_s][1] and r[current_s][3] = -1).
As my plan, I would like to get a random value between 0 and 3 using (rand()%4); if (r[current_s][i] > -1) is correct I will return that value. But if (r[current_s][i] = -1) generate a random number again until r[current_s][i] > -1 then return value.
What should I do?
Assuming that current_s is the row number of your matrix which contains the values -1 or greater, you can use this code :
int random_a(int current_a, int r[num_s][num_a])
{
if (current_a>num_s) return 0; //checking condition as current_a changes below
int i;
for (i=0;i<4;i++)
{
if(r[current_s][i] > -1) return i;
else if (r[current_s][i] && i==3) return (random_a(current_a+1,r[num_s][num_a])
else i++;
}
}
here you can change current_a based on your need.

UVA's 3n+1 wrong answer although the test cases are correct . . .?

UVA problem 100 - The 3n + 1 problem
I have tried all the test cases and no problems are found.
The test cases I checked:
1 10 20
100 200 125
201 210 89
900 1000 174
1000 900 174
999999 999990 259
But why I get wrong answer all the time?
here is my code:
#include "stdio.h"
unsigned long int cycle = 0, final = 0;
unsigned long int calculate(unsigned long int n)
{
if (n == 1)
{
return cycle + 1;
}
else
{
if (n % 2 == 0)
{
n = n / 2;
cycle = cycle + 1;
calculate(n);
}
else
{
n = 3 * n;
n = n + 1;
cycle = cycle+1;
calculate(n);
}
}
}
int main()
{
unsigned long int i = 0, j = 0, loop = 0;
while(scanf("%ld %ld", &i, &j) != EOF)
{
if (i > j)
{
unsigned long int t = i;
i = j;
j = t;
}
for (loop = i; loop <= j; loop++)
{
cycle = 0;
cycle = calculate(loop);
if(cycle > final)
{
final = cycle;
}
}
printf("%ld %ld %ld\n", i, j, final);
final = 0;
}
return 0;
}
The clue is that you receive i, j but it does not say that i < j for all the cases, check for that condition in your code and remember to always print in order:
<i>[space]<j>[space]<count>
If the input is "out of order" you swap the numbers even in the output, when it is clearly stated you should keep the input order.
Don't see how you're test cases actually ever worked; your recursive cases never return anything.
Here's a one liner just for reference
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
Not quite sure how your code would work as you toast "cycle" right after calculating it because 'calculate' doesn't have explicit return values for many of its cases ( you should of had compiler warnings to that effect). if you didn't do cycle= of the cycle=calculate( then it might work?
and tying it all together :-
int three_n_plus_1(int n)
{
return n == 1 ? 1 : three_n_plus_1((n % 2 == 0) ? (n/2) : (3*n+1))+1;
}
int max_int(int a, int b) { return (a > b) ? a : b; }
int min_int(int a, int b) { return (a < b) ? a : b; }
int main(int argc, char* argv[])
{
int i,j;
while(scanf("%d %d",&i, &j) == 2)
{
int value, largest_cycle = 0, last = max_int(i,j);
for(value = min_int(i,j); value <= last; value++) largest_cycle = max_int(largest_cycle, three_n_plus_1(value));
printf("%d %d %d\r\n",i, j, largest_cycle);
}
}
Part 1
This is the hailstone sequence, right? You're trying to determine the length of the hailstone sequence starting from a given N. You know, you really should take out that ugly global variable. It's trivial to calculate it recursively:
long int hailstone_sequence_length(long int n)
{
if (n == 1) {
return 1;
} else if (n % 2 == 0) {
return hailstone_sequence_length(n / 2) + 1;
} else {
return hailstone_sequence_length(3*n + 1) + 1;
}
}
Notice how the cycle variable is gone. It is unnecessary, because each call just has to add 1 to the value computed by the recursive call. The recursion bottoms out at 1, and so we count that as 1. All other recursive steps add 1 to that, and so at the end we are left with the sequence length.
Careful: this approach requires a stack depth proportional to the input n.
I dropped the use of unsigned because it's an inappropriate type for doing most math. When you subtract 1 from (unsigned long) 0, you get a large positive number that is one less than a power of two. This is not a sane behavior in most situations (but exactly the right one in a few).
Now let's discuss where you went wrong. Your original code attempts to measure the hailstone sequence length by modifying a global counter called cycle. However, the main function expects calculate to return a value: you have cycle = calculate(...).
The problem is that two of your cases do not return anything! It is undefined behavior to extract a return value from a function that didn't return anything.
The (n == 1) case does return something but it also has a bug: it fails to increment cycle; it just returns cycle + 1, leaving cycle with the original value.
Part 2
Looking at the main. Let's reformat it a little bit.
int main()
{
unsigned long int i=0,j=0,loop=0;
Change these to long. By the way %ld in scanf expects long anyway, not unsigned long.
while (scanf("%ld %ld",&i,&j) != EOF)
Be careful with scanf: it has more return values than just EOF. Scanf will return EOF if it is not able to make a conversion. If it is able to scan one number, but not the second one, it will return 1. Basically a better test here is != 2. If scanf does not return two, something went wrong with the input.
{
if(i > j)
{
unsigned long int t=i;i=j;j=t;
}
for(loop=i;loop<=j;loop++)
{
cycle=0;
cycle=calculate(loop );
if(cycle>final)
{
final=cycle;
}
}
calculate is called hailstone_sequence_length now, and so this block can just have a local variable: { long len = hailstone_sequence_length(loop); if (len > final) final = len; }
Maybe final should be called max_length?
printf("%ld %ld %ld\n",i,j,final);
final=0;
final should be a local variable in this loop since it is separately used for each test case. Then you don't have to remember to set it to 0.
}
return 0;
}

Resources