Printing every unlock pattern in a 2d phone keypad in C - c

I want to write a function that prints all possible patterns like in the examples below. In every case, we must start in the top left of a 3x3 array. It's similar to the patterns to unlock mobile phones, except the line can't go diagonally and must pass through every box.
1--->2--->3 1--->2--->3
| |
v v
8<---7 4 or 6<---5<---4
| ^ | |
v | v v
9 6<---5 7--->8--->9
I started by writing a code where [0][0] was assigned 1 then randomise the rest of the digits in the 2d array until 1[0] or 0 was equal to 2, and so forth. But I feel like this is making the problem even more difficult to solve.
Then tried to use recursion to call the makePattern function again and again until the array is changed; however, it changes all values in the array to 2 because of these lines of code:
int value = 2;
array[x][y] = value;
However, I don't how to loop this value so that it increases as the function is called again.
#include <stdio.h>
#include <stdlib.h>
#define ROW 3
#define COLUMN 3
int makePattern(int array[ROW][COLUMN], int x, int y);
int main(void) {
int x, y;
int count = 2;
int i, j;
int array[ROW][COLUMN] = {
{'1', '0', '0'},
{'0', '0', '0'},
{'0', '0', '0'},
};
makePattern(array, 0, 0);
for (i = 0; i < ROW; i++) {
for (j = 0; j < COLUMN; j++) {
printf("%d", array[i][j]);
}
printf("\n");
}
return 0;
}
int makePattern(int array[ROW][COLUMN], int x, int y) {
int value = 2;
array[x][y] = value;
for (value = 2; value < 9; value++) {
if (x + 1 < ROW && array[x+1][y] == '0') {
makePattern(array, x + 1, y);
}
if (x - 1 >= 0 && array[x - 1][y] == '0') {
makePattern(array, x - 1, y);
}
if (y + 1 < COLUMN && array[x][y + 1] == '0') {
makePattern(array, x, y + 1);
}
if (y - 1 >= 0 && array[x][y - 1] == '0') {
makePattern(array, x, y - 1);
}
value++;
}
}

You're on the right track here in that you're using a 3x3 matrix to keep track of state (visited nodes and to store the path taken), x/y coordinates to represent the current location and spawning four recurse calls to handle the possible move directions (with bounds checks).
However, I'm not sure the loop running to 9 is going to work--this will spawn 36 recursive calls per frame. This might be workable in some implementations, but I think the easiest approach is to treat each frame as exploring one possible direction given an x/y coordinate pair, then backtracking (undoing the move) after all directions have been explored recursively from that square. Whenever we hit the last step, we know we've explored all of the squares and it's time to print the current solution path.
Here's code which achieves this and basically hardcodes the dimensions. An exercise would be to generalize the code to matrices of any size and return the path to separate printing from the traversal logic. I also opted to move state out of the main function.
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
static void print_unlock_patterns_r(int pad[3][3], int x, int y, int step) {
static int const directions[][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
pad[y][x] = 1 + step;
for (int i = 0; i < 4; i++) {
int xp = x + directions[i][0];
int yp = y + directions[i][1];
if (xp >= 0 && xp < 3 && yp >= 0 && yp < 3 && !pad[yp][xp]) {
print_unlock_patterns_r(pad, xp, yp, step + 1);
}
}
if (step == 8) {
for (int i = 0; i < 3; i++, puts("")) {
for (int j = 0; j < 3; printf("%d", pad[i][j++]));
}
puts("");
}
pad[y][x] = 0;
}
void print_unlock_patterns() {
int pad[3][3];
memset(pad, 0, sizeof(pad));
print_unlock_patterns_r(pad, 0, 0, 0);
}
int main(void) {
print_unlock_patterns();
return 0;
}
Output:
123
894
765
123
874
965
123
654
789
129
438
567
145
236
987
189
276
345
187
296
345
167
258
349

Related

Must print a numerical sequence 15, 12, 24, 21, 42, 39, 78, 75, 150, 147

As I see it the numerical sequence consists of 2 separate sequences. This is the code that I have so far. I am not sure if you must use a while or a for loop. I am fairly new at coding so if someone please could help me.
if the entered value is 10 it must give the first 10 terms of the sequence, and if I enter 5 it must give me the first 5 terms of the sequence.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int a, n = 1, t, y = 1; // First Numerical Sequence
int b, m = 2, s, x = 2; // Second Numerical Sequence
int d, r, z; // Extra
printf("Enter A Tn : ");
scanf(" %d", &z);
printf("\n");
while (n <= z) {
a = 15;
r = pow(2, n - y);
d = (9 * (r - 1)) / (2 - 1);
t = a + d;
printf("%d\n", t);
n += 2;
y++;
}
while (m <= z) {
b = 12;
r = pow(2, m - x);
d = (9 * (r - 1)) / (2 - 1);
s = b + d;
printf("%d\n", s);
m += 2;
x++;
}
printf("\n");
return 0;
}
This will get the job done.
#include <stdio.h>
int main(){
int val,ic; //iteration count, will print ic*2 number
scanf("%d %d",&val,&ic);
for(int i = 0;i<ic;i++){
printf("%d ",val);
val-=3;
printf("%d ",val);
val*=2;
}
printf("\n");
}
How to compile & run:
C:\Users\stike\Desktop>rem assume you saved it in a.c
C:\Users\stike\Desktop>gcc -o a a.c
C:\Users\stike\Desktop>a
15
5
15 12 24 21 42 39 78 75 150 147
If you want to print the same sequence starting from 15 and o till a certain number which the user inputs, you can follow the following code.
Hope you understood the sequence pattern when a number is given it is printed and reduce the number by 3, then it is printed and then twice the number and printed, and again reduce by 3, likewise, it flows on.
#include <stdio.h>
int main() {
int endNum;
int beginNum = 15;
printf("Enter the end: ");//(lineA) here we initialize the variables with beginNum as 15
scanf("%d", &endNum); //(Line B) let the user to input endNum of the sequence,in the example it is 147
while ((beginNum-3) <= endNum) { // checks the condition
printf("%d ", beginNum);
if(beginNum==endNum) return 0; //check whether you print the end number.
beginNum -= 3; // reduce by 3
printf("%d ", beginNum);
beginNum *= 2; // multiply by 2
}
return 0;
}
if you don't need to user input a endNum just initialize the value 147 to variable endNum.
And delete the lines A and B.
Here's another approach using static variables
#include <stdio.h>
int next(void) {
static int last, n = 0;
if (n++ == 0) return last = 15; // 1st element of sequence
if (n % 2) return last = last * 2; // odd elements
return last = last - 3; // even elements
}
int main(void) {
for (int k = 0; k < 10; k++) {
printf("%d ", next());
}
puts("");
return 0;
}

maze generation algorithm in c with DFS

recently i read this topic about generating mazes in c . see here https://www.algosome.com/articles/maze-generation-depth-first.html
and i want to write it in c . here is my code and it's not working right .
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int check[5][5];
int v[5][5];
int border(int x , int y ){
if(x> -1 && x< 6 && y > -1 && y<6)
return 1;
else
return 0 ;
}
int wall[6][6][6][6];
void dfs ( int x , int y){
srand(time(NULL));
int s = 1/*rand() % 4 ;*/ ;
if(s=1 ){
if(border(x ,y-1)&& check[x][y-1]==0){
check[x][y]=1;
wall[x][y][x+1][y]=1;
dfs(x , y-1);
}
else
return ;
}
else if(s=2){
if(border(x+1 ,y)&&check[x+1][y]==0){
check[x][y]=1;
wall[x+1][y][x+1][y+1]=1;
dfs(x+1 , y);
}
else return ;
}
else if(s=3){
if(border(x ,y+1)&&check[x][y+1]==0){
check[x][y]=1;
wall[x][y+1][x+1][y+1]=1;
dfs(x , y+1);
}
else return ;
}
else if(s=0){
if(border(x-1 ,y)&&check[x-1][y]==0){
check[x][y]=1;
wall[x][y][x][y+1]=1;
dfs(x-1 , y);
}
else return ;
}
return ;
}
int main(){
dfs( 4, 4);
for(int i =0 ; i < 6 ; i++)
for (int j =0 ; j < 6 ; j++)
for ( int h =0 ; h <6 ; h++)
for (int k =0 ; k < 6 ; k ++)
printf("%d \n" , wall[i][j][h][k]);
return 0 ;
}
i invert my table to graph , and i want to show me the coordinates of my walls .
what's the problem ?
You have several errors – programming errors and logic errors – in your code:
When you distiguish between the directions the s=1 and so on should be s == 1. You want a comparison, not an assignment. (Your code is legal C, so there is no error.)
You call srand at the beginning of dfs, which you call recursively. This will make your single (commented) rand call always create the same random number. You should seed the pseudo random number generator only once at the beginning of main.
You can store the paths the way you do, but it is wasteful. There are only four possible paths from each cell, so you don't need an array that allows to create a path between (0,0) and (3,4), for example.
Your code would benefit from using constants or enumerated values instead of the hard-coded 5's and 6's. This will allow you to change the dimensions later easily.
But your principal error is in how you implement the algorithm. You pick one of the for directions at random, then test whether that direction leads to a valid unvisited cell. If so, you recurse. If not, you stop. This will create a single unbranched path through the cells. Note that if you start in a corner cell, you have already a 50% chance of stopping the recursion short.
But you want something else: You want a maze with many branches that leads to every cell in the maze. Therefore, when the first recursion returns, you must try to branch to other cells. The algorithm goes like this:
Make a list of all possible exits.
If there are possible exits:
Pick one exit, create a path to that exit and recurse.
Update the list of possible exits.
Note that you cannot re-use the old list of exits, because the recursion may have rendered some possible exits invalid by visiting the destination cells.
Below is code that creates a maze with the described algorithm. I've used two distinct arrays to describe horizontal and vertical paths:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
enum {
W = 36, // width of maze
H = 25 // height of maze
};
enum {
North,
East,
South,
West,
NDir
};
char visited[H][W];
char horz[H][W - 1]; // horizontal E-W paths in the maze
char vert[H - 1][W]; // veritcal N-S paths in the maze
/*
* Fill dir with directions to unvisited cells, return count
*/
int adjacent(int dir[], int x, int y)
{
int ndir = 0;
if (y > 0 && visited[y - 1][x] == 0) dir[ndir++] = North;
if (x < W - 1 && visited[y][x + 1] == 0) dir[ndir++] = East;
if (y < H - 1 && visited[y + 1][x] == 0) dir[ndir++] = South;
if (x > 0 && visited[y][x - 1] == 0) dir[ndir++] = West;
return ndir;
}
/*
* Traverse cells depth first and create paths as you go
*/
void dfs(int x, int y)
{
int dir[NDir];
int ndir;
visited[y][x] = 1;
ndir = adjacent(dir, x, y);
while (ndir) {
int pick = rand() % ndir;
switch (dir[pick]) {
case North: vert[y - 1][x] = 1; dfs(x, y - 1); break;
case East: horz[y][x] = 1; dfs(x + 1, y); break;
case South: vert[y][x] = 1; dfs(x, y + 1); break;
case West: horz[y][x - 1] = 1; dfs(x - 1, y); break;
}
ndir = adjacent(dir, x, y);
}
}
/*
* Print a map of the maze
*/
void map(void)
{
int i, j;
for (i = 0; i < W; i++) {
putchar('_');
putchar('_');
}
putchar('\n');
for (j = 0; j < H; j++) {
putchar('|');
for (i = 0; i < W; i++) {
putchar(j < H - 1 && vert[j][i] ? ' ' : '_');
putchar(i < W - 1 && horz[j][i] ? '_' : '|');
}
putchar('\n');
}
}
int main()
{
srand(time(NULL));
dfs(0, 0);
map();
return 0;
}
You can test it here. If you replace the while in dsf with a simple if, you get more or less what you implemented. Note that this creates only a single, usually short path.

Efficiency of Cryptarithmetic Algorithm solver decomposition

The problem is the following: Given "ABC+DEF=GHI" format string, where A,B,C etc. represent unique digits, find the expression that gives maximum GHI. Ex: Input string is AAB+AAB=AAB, then there's no solution. If it is instead AAA + BBB = AAA, a solution is 999 + 000 = 999. Another example string: ABC + CBA = GGG, a result is => 543 + 345 = 888.
I have ruled out impossible cases easily. The algorithm I have in mind is a bruteforce, that simply tries maximizing the rhs first. However my problem was doing this fast, and also watching out for the unique digits. What's an efficient way to solve this problem?
Notes: I wish to solve this in a singlethreaded approach, and my current problem is detecting if a unique digit is used in "assign_value" function. Perhaps a better method to assign values is there?
EDIT: As per smci's suggestion, here's what I want to achieve, in the very end: ABRA + CADABRA + ABRA + CADABRA == HOUDINI ; 7457 + 1797457 + 7457 + 1797457 == 3609828 -- A system that can handle not only strings of the form I provided in the beginning (3 digit number + 3 digit number = 3 digit number) but also those. However it doesn't hurt to start simple and go with the solution of format I gave :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_EXPRESSION_SIZE 11 + 1
#define MAX_VARIABLES 9
int variables_read[MAX_VARIABLES] = { 0 };
struct variable {
int coefficient;
int* ptr;
int side;
int canhavezero;
unsigned value_max;
};
typedef struct variable Variable;
struct equation {
Variable* variables[9]; // max
unsigned distinct_on_rhs;
unsigned var_count;
};
typedef struct equation Equation;
int int_pow(int n, int k) {
int res = 1;
for(int i = 0; i < k; ++i)
res *= n;
return res;
}
void AddVariable(Equation* E, Variable* V) {
E->variables[E->var_count++] = V;
}
int IsImpossible(char* expression) {
// if all letters are same or end letters are same, no solution
if(
(expression[0] == expression[4] && expression[0] == expression[8]) ||
(!strncmp(expression, expression + 4, 3) && !strncmp(expression, expression + 8, 3))
)
return 1;
return 0;
}
int assign_value(Equation* E, int pos, int* values) {
if(!E->variables[pos]->value_count) {
if(pos < 0)
return 2;
// if no possible values left, reset this, but take one value count from the closest variable
E->variables[pos - 1]->value_count--;
E->variables[pos]->value_count = E->variables[pos]->value_max;
return 0;
}
int i;
for(i = 9; i >= 0 && values[i] == -1; --i)
printf("Assigning %d to %c\n", E->variables[pos]->value_set[E->variables[pos]->value_count - 1], 'A' + (E->variables[pos]->ptr - E->variables[0]->ptr));
*(E->variables[pos]->ptr) = values[i];
values[i] = -1; // we have unique numbers
return 0;
}
int isSolved(Equation E) {
int sum = 0, coeff = 0;
printf("Trying...\n");
for(int i = 0; i < E.var_count; ++i) {
coeff = E.variables[i]->coefficient * (*E.variables[i]->ptr);
printf("%d ", *E.variables[i]->ptr);
if(E.variables[i]->side)
coeff *= -1;
sum += coeff;
}
printf("\nSum was %d\n", sum);
return !sum;
}
char* evaluate(char* expression) {
char* res;
// check for impossible cases first
if(IsImpossible(expression)) {
res = (char *) malloc(sizeof(char) * strlen("No Solution!"));
strcpy(res, "No Solution!");
return res;
}
res = (char *) malloc(sizeof(char) * MAX_EXPRESSION_SIZE);
// now try to find solutions, first describe the given characters as equations
Equation E;
E.var_count = 0;
E.distinct_on_rhs = 0;
int side_mode = 0, powcounter = 0;
int a = -1, b = -1, c = -1, d = -1, e = -1, f = -1, g = -1, h = -1, i = -1;
int* max_variables[MAX_VARIABLES] = { &a, &b, &c, &d, &e, &f, &g, &h, &i };
for(int j = 0; j < MAX_EXPRESSION_SIZE - 1; ++j) {
if(expression[j] == '+')
continue;
if(expression[j] == '=') {
side_mode = 1;
continue;
}
Variable* V = (Variable *) malloc(sizeof(Variable));
// we know we always get 3 digit numbers but we can easily change if we need to
V->coefficient = int_pow(10, 2 - (powcounter % 3));
V->ptr = max_variables[expression[j] - 'A'];
V->side = side_mode;
E.distinct_on_rhs += side_mode && !variables_read[expression[j] - 'A'];
if(!(powcounter % 3)) { // beginning of a number
V->value_count = 9;
V->value_max = 9;
V->canhavezero = 0;
}
else {
V->value_count = 10;
V->value_max = 10;
V->canhavezero = 1;
}
AddVariable(&E, V);
variables_read[expression[j] - 'A'] = 1;
++powcounter;
}
for(int j = 0; j < E.var_count; ++j)
printf("%d %c %d\n", E.variables[j]->coefficient, 'A' + (E.variables[j]->ptr - max_variables[0]), E.variables[j]->side);
// we got a representaion of the equation, now try to solve it
int solved = 0;
// O(9^N), where N is number of distinct variables.
// An optimization we can do is, we first assign possible max values to rhs number, then go down. We need max number.
printf("Distincts: %d\n", E.distinct_on_rhs);
do {
// try to assign values to all variables and try if it solves the equation
// but first try to assign rhs as max as possible
int values[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int temp = E.var_count - E.distinct_on_rhs;
while(temp < E.var_count) {
solved = assign_value(&E, temp, values);
++temp;
}
for(int j = E.var_count - 1 - E.distinct_on_rhs; j >= 0; --j)
solved = assign_value(&E, j, values);
if(solved) // can return no solution
break;
printf("Solving...\n");
solved = isSolved(E);
system("PAUSE");
} while(!solved);
if(solved == 2) {
res = (char *) malloc(sizeof(char) * strlen("No Solution!"));
strcpy(res, "No Solution!");
}
else {
}
return res;
}
int main() {
char expression[MAX_EXPRESSION_SIZE] = { 0 };
do {
printf("Enter the formula: ");
scanf("%s", expression);
char* res = evaluate(expression);
printf("%s\n", res);
free(res);
} while(expression[0] != '-');
return 0;
}
I would start with the result. There are not that many different cases:
AAA
AAB, ABA, BAA
ABC
All other cases can be reduced to these by renaming the variables. ABC + CBA = GGG would become DBC + CBD = AAA.
Then you have
10 possible solutions for the one-variable case AAA
90 (10*9) for the two variable cases
720 (10*9*8) for the three variable case
assuming that zero is allowed anywhere. If not, you can filter out those that are not allowed.
This sets the variables for the right side of the equation. Each variable that appears only on the left, adds possible solutions. B adds a factor of 9, C a factor of 8, D 7 and so forth.
The most "efficient" solution would take all knowledge of the task and simple print the result. So the question is how much of the conditions can be coded and where and what flexibility is needed.
An alternative is to view the generation of test cases and evaluation of them separately.
A simple recursion function can generate the 10! (362880) test cases of unique digits.
unsigned long long count = 0;
unsigned long long sol = 0;
void evaluate(int object[]) {
count++;
int ABC = object[0] * 100 + object[1] * 10 + object[2];
int DEF = object[3] * 100 + object[4] * 10 + object[5];
int GHI = object[6] * 100 + object[7] * 10 + object[8];
if (ABC + DEF == GHI) {
printf("%4llu %03d + %03d = %03d\n", ++sol, ABC,DEF,GHI);
}
}
void form_combos(int pool[], size_t pool_count, int object[],
size_t object_count, size_t object_count_max) {
if (object_count >= object_count_max) {
evaluate(object);
return;
}
assert(pool_count > 0);
int *pool_end = pool + pool_count - 1;
for (size_t p = 0; p < pool_count; p++) {
int sample = pool[p]; // take one out
pool[p] = *pool_end; // replace it with the end
object[object_count] = sample;
form_combos(pool, pool_count - 1, object, object_count + 1,
object_count_max);
pool[p] = sample; // restore pool item
}
}
int main() {
int pool[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
size_t pool_size = sizeof pool / sizeof pool[0];
#define object_count 9
int object[object_count];
form_combos(pool, pool_size, object, 0, object_count);
printf("Evaluate() iterations %llu\n", count);
}
Output
1 091 + 762 = 853
2 091 + 763 = 854
3 091 + 735 = 826
...
1726 874 + 061 = 935
1727 875 + 046 = 921
1728 876 + 045 = 921
Evaluate() iterations 3628800
What is nice about this approach is that if the task was now find
ABC*ABC + DEF*DEF == GHI*GHI
Changing only 2 lines of code:
if (ABC*ABC + DEF*DEF == GHI*GHI) {
printf("%4llu sqr(%03d) + sqr(%03d) = sqr(%03d)\n", ++sol, ABC,DEF,GHI);
}
results in
1 sqr(534) + sqr(712) = sqr(890)
2 sqr(546) + sqr(728) = sqr(910)
3 sqr(712) + sqr(534) = sqr(890)
4 sqr(728) + sqr(546) = sqr(910)
Evaluate() iterations 3628800
Ok, so for a trivial solution (a base to build a generalization on, so far it only works on the format <3 digit number> + <3 digit number> = <3 digit number>) inspired from #chux and #alain's suggestions is the following code. It truly runs on O(10^N) where N is the distinct number of digits present, or variables if you'd like to call them that. I'll see if I can generalize this even further.
Note that this is for the initial problem of finding the largest rhs. Take that into account as well.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_DIGITS 10
#define MAX_VARIABLES 9
#define MAX_EXPRESSION_SIZE 11
int IsImpossible(char* expression) {
// if all letters are same or end letters are same, no solution
if(
(expression[0] == expression[4] && expression[0] == expression[8]) ||
(!strncmp(expression, expression + 4, 3) && !strncmp(expression, expression + 8, 3))
)
return 1;
return 0;
}
int ArePointersAssigned(int*** pointers) {
for(int i = 0; i < MAX_VARIABLES; ++i) {
if(**pointers[i] == -1)
return 0;
}
return 1;
}
int evaluate(int*** pointers) {
int ABC = *(*pointers[0]) * 100 + *(*pointers[1]) * 10 + *(*pointers[2]);
int DEF = *(*pointers[3]) * 100 + *(*pointers[4]) * 10 + *(*pointers[5]);
int GHI = *(*pointers[6]) * 100 + *(*pointers[7]) * 10 + *(*pointers[8]);
if (ABC + DEF == GHI) { // since we use dfs, if this is a solution simply return it
//printf("%d + %d = %d\n", ABC, DEF, GHI);
return 1;
}
return 0;
}
// use the solved pointer to escape recursion early
// check_end checks if we reached 6 for the 2nd time, if it's first time we ignore (because it's start state)
void form_combos(int pool[], int pool_count, int object_count, int*** pointers, int* solved) {
if(object_count == MAX_DIGITS - 1)
object_count = 0;
if(*solved) // if a branch solved this, escape recursion
return;
if (ArePointersAssigned(pointers)) { // that means we got a full equation set
*solved = evaluate(pointers);
if(*solved)
return;
}
int *pool_end = pool + pool_count - 1;
for (int p = pool_count - 1; p >= 0 && !*solved; p--) {
int sample = pool[p]; // take one out
pool[p] = *pool_end; // replace it with the end
int temp = **pointers[object_count];
if(**pointers[object_count] == -1)
**pointers[object_count] = sample;
form_combos(pool, pool_count - 1, object_count + 1, pointers, solved);
pool[p] = sample; // restore pool item
if(!*solved)
**pointers[object_count] = temp;
}
}
int main() {
char expression[MAX_EXPRESSION_SIZE] = { 0 };
printf("Enter the formula: ");
scanf("%s", expression);
while(expression[0] != '-') {
if(IsImpossible(expression))
printf("No solution!\n");
else {
int digits[MAX_DIGITS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int object[MAX_VARIABLES] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 }; // stack for dfs
int *A = &object[0], *B = &object[1], *C = &object[2],
*D = &object[3], *E = &object[4], *F = &object[5],
*G = &object[6], *H = &object[7], *I = &object[8];
// set same pointers
int** pointers[MAX_VARIABLES] = { &A, &B, &C, &D, &E, &F, &G, &H, &I };
// analyze the equation
int var = 0;
for(int p = 0; p < MAX_EXPRESSION_SIZE; ++p) {
if(expression[p] >= 'A' && expression[p] <= 'I') {
*pointers[var++] = &object[expression[p] - 'A']; // link same pointers
}
}
int solved = 0, check_end = 0;
form_combos(digits, MAX_DIGITS, MAX_DIGITS - 4, pointers, &solved);
if(!solved) // it can be unsolvable still
printf("No solution!\n");
else
printf("%d%d%d + %d%d%d = %d%d%d\n", *A, *B, *C, *D, *E, *F, *G, *H, *I);
}
printf("Enter the formula: ");
scanf("%s", expression);
}
return 0;
}

Need help finding the complexity of this algorithm

Hi I need help finding the complexity of this algorithm.
Could you please answer the complexity line by line not just the final result?
The algorithm is the following one:
int algorithm(int x)
{
int y = 1;
while (y <= x-1)
{
int z = y*2;
while (z <= x)
{
int w = 1;
while (w <= z)
{
w++;
}
z++;
}
y++;
}
}
Any help would be appreciated!
Thanks
int algorithm(int x)
{
int y = 1;
while (y <= x-1) // <<< loop 1
{
int z = y*2;
while (z <= x) // <<< loop 2
int w = 1;
while (w <= z) // <<< loop 3
{
w++;
}
z++;
}
y++;
}
}
Let's break it down.
Loop 1: you go around (x-1) times: we call this O(x). Easy.
Loop 2: We start Z with 2*y, so 2, 4, 6, ... From there we go until x. Let's add them up:
sum((x-2) + (x-4) + (x-6) + ... + (x - x)) =
x * x / 2 - 2 * (1+2+3+...+x/2) =
x * x / 2 - 2 * (x/2)*(x/2+1) / 2 ~
x * x / 2 - x * x / 4 =
x * x / 4
= O(x^2)
Now the innermost loop: it goes from w = 1 to w = z; so it loops z times. And we know that
z = 2, 4, 6, ... x
So the innermost loop adds something of the order of x (x/2... same thing).
Combining the O(x) of loop 3 with the O(x^2) of loop 2 (which included the effect of the first loop) we conclude the "algorithm" is of order x^3. To verify, we can modify your code:
#include <stdio.h>
int algorithm(int x)
{
int c = 0;
int y = 1;
while (y <= x-1)
{
int z = y*2;
while (z <= x)
{
int w = 1;
while (w <= z)
{
c++; // count complexity
w++;
}
z++;
}
y++;
}
return c;
}
int main(void) {
int ii;
for(ii = 200; ii <= 400; ii+=10) {
printf("%d %d\n", ii, algorithm(ii));
}
}
The output is:
200 1338350
210 1549030
220 1780735
230 2034465
240 2311220
250 2612000
260 2937805
270 3289635
280 3668490
290 4075370
300 4511275
310 4977205
320 5474160
330 6003140
340 6565145
350 7161175
360 7792230
370 8459310
380 9163415
390 9905545
400 10686700
Plotting this on a lin-log plot, you get a pretty straight line.
When you take the ratio of algorithm(400) / algorithm(300), you get 2.369. And when you take (400/300)^3, the answer is 2.370. I think that is close enough to be convincing.
Following the formal steps below (I hope you're comfortable with Sigma Notation), you'll be able to obtain the exact order of growth of your algorithm:

custom string alignment using printf in C

I'm trying to get the following output from the given array
Apples 200 Grapes 900 Bananas Out of stock
Grapefruits 2 Blueberries 100 Orangess Coming soon
Pears 10000
Here's what I came up so far (feels like I'm overdoing it), however, I'm still missing something when padding the columns. I'm open to any suggestions on how to approach this.
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
char *fruits[][2] = {
{"Apples", "200"},
{"Grapes", "900"},
{"Bananas", "Out of stock"},
{"Grapefruits", "2"},
{"Blueberries", "100"},
{"Oranges", "Coming soon"},
{"Pears", "10000"},
};
int get_max (int j, int y) {
int n = ARRAY_SIZE(fruits), width = 0, i;
for (i = 0; i < n; i++) {
if (i % j == 0 && strlen(fruits[i][y]) > width) {
width = strlen(fruits[i][y]);
}
}
return width;
}
int main(void) {
int n = ARRAY_SIZE(fruits), i, j;
for (i = 0, j = 1; i < n; i++) {
if (i > 0 && i % 3 == 0) {
printf("\n"); j++;
}
printf("%-*s ", get_max(j, 0), fruits[i][0]);
printf("%-*s ", get_max(j, 1), fruits[i][1]);
}
printf("\n");
return 0;
}
Current output:
Apples 200 Grapes 900 Bananas Out of stock
Grapefruits 2 Blueberries 100 Oranges Coming soon
Pears 10000
You are computing widths wrong. In essence, you want to be able to compute the width of a particular column. Thus, in your get_max function, you should be able to specify a column. We can then pick out the elements from the list based on whether their index mod 3 is equal to the column. This can be accomplished as such:
int get_max (int column, int y) {
...
if (i % 3 == column /* <- change */ && strlen(fruits[i][y]) > width) {
...
}
Then in your main loop, you want to choose the widths of the columns based on what column you are currently in. You can do that by taking the index mod 3:
for (i = 0, j = 1; i < n; i++) {
...
printf("%-*s ", get_max(i % 3 /* change */, 0), fruits[i][0]);
printf("%-*s ", get_max(i % 3 /* change */, 1), fruits[i][1]);
}
This should work as you expect.
I dint try understanding your logic but i think you can space the data using tab with "\t":
printf("%s \t %d","banana", 200);

Resources