Calculating and Printing a tree [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I need to build a tree that looks like this:
So I take in 2 numbers from the user, a and b. a defines the number of rows, and b defines the starting root node value. So if i had a=5 and b=3, then we get:
I basically just print that out to the console. I am just really lost how on how to start. Could anyone give me a little push in the right direction?

This is Pascal's triangle, and the value at row n, column k is b * (n choose k) where n and k are both zero-indexed, and (n choose k) = n! / (k! * (n-k)!)
Once you've figured this out, then the solution to your problem amounts to writing a function int choose(int n, int k) and to laying out the square on the console.
The layout is the hardest part, but here's an approach:
First, you need to pick a width that you're going to print the number out in. Let's say it's W. Probably W = 3 will be good.
Second, you need to figure out how many spaces to print at the start of each line. Each row adds W + 1 width to the printed part, so you need to have (W + 1) / 2 less space before on each subsequent row, ending at 0 space at row (a - 1). That means (a - n - 1) * (W + 1) / 2 spaces beforehand on row n.
Third, you need to write a function int choose(int n, int k)
Finally, you just need to iterate through the rows, first printing the number of spaces determined by step 2, then printing the numbers computed using the function in step 3, making sure that they're printed using something like printf("%-*d ", W, b * choose(n, k)); to keep them aligned.

One way might be to "grow" the tree downwards... Given the number of rows you can figure out how many elements are in the tree and allocate an array of the appropriate size.
Then starting at the top, assuming rows numbered from 1, down_left(x) = x + row(x) where x is the array index and row(x) is the row number x belongs to. down_right(x) = down_left(x) + 1.
Start at the top and go down_left and down_right. Then for each element in the next row you just created do the same, except add to the row below to get the cumulative effect of the "parent" numbers.
e.g. if user asks for 3 rows and root value of 3.
You know you will need 6 array elements. Allocate 6 elements and zero them.
Row 1: Put 3 at array[0].
Row n: Create by looking at each element in the previous row, call it i. Then do array[down_left(i)] += i and array[down_right(i)] += i. This creates row n. Repeat.
That's the rough idea anyway, have a play and see where it gets you... :)

Related

how to make the backtracking algorithm properly? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have an exercise (please take a look at picture):
Problem
The problem:
You input any number (number is integer) then the program will find numbers in binary tree has 4 levels. The top is your number you input, and the pair of 2 numbers at lower level will be added together and 2 times the parent number above. And the numbers must be used only once.
Here my code, but it still doesn't work properly. Please figure out for me what is my mistake here.
#include <stdio.h>
#include <stdbool.h>
#define MAX 15
int data[MAX]; // binary tree with 4 levels
void init_Data(){
int i=0;
for(i=0; i<=MAX; i++){
data[i] = -1;
}
}
void BackTracking(int index){
int c1, c2; // c1 and c2 are a pair that is added and equal 2 times the parent number
for(c1=1; c1<data[index]; c1++){
c2 = 2*data[index] - c1;
if(!Search(c1) && !Search(c2)){ // checking c1 and c2 is used or not
data[2*index+1] = c1; // put c1 into data
data[2*index+2] = c2; // put c2 into data
if(index == MAX/2) // the stop condition
print_Data(); // print out
else
BackTracking(index+1);
}
}
}
bool Search(int number){
int i=0;
for(i=0; i<MAX; i++){
if(number == data[i])
return true;
}
return false;
}
int main(int argc, char const *argv[]) {
int n = 0;
init_Data();
printf("Enter your number: ");
scanf("%d\n", &n);
data[0] = n;
BackTracking(0);
return 0;
}
I've got working code for this exercise, but since it is an exercise, I'll just give some primers.
How do you solve the problem? One way to find a valid configuration (of Sudoku grids, of eight non-attacking queens on a chess board or of numbers in a tree) is backtracking: You prober various possible solutions and when you find that it is invalid, you revert to a previous partial solution that is still valid.
One way to implement backtracking is to use recursion, where each step in the solution (put a number in the Sudoku grid, placing a queen, assigning a pait of numbers in your problem) is one level of recursion. Backracking then means to return to previous levels in the recursion.
How do you represent the tree? Your picture shows a binary tree. You can represent such a tree as a linear array:
0
1 2
3 4 5 6
7 8 9 10 11 12 13 14 15
For a node with the array index i, you get:
parent(i) == (i - 1) / 2
left(i) == 2*i + 1
right(i) == 2*i + 2
You need the array to print the solution once you have found it.
How do you traverse the tree? There are many ways to traverse a tree. Here, you can use many ways as long as you have assigned a value to the parent node before visiting it.
In your case, the easiest way is to do a level-wise iteration that follows the linear array. You can use the fact that the two numbers you need to find for each parant node are adjacent. Start with index i = 1 and if you can find two valid numbers, advace to i + 2.
That way to iterate also provides a nice terminating condition: When you reach the fifth level, you have found a valid solution.
How do you find out whether a number has been used? The straightforward solution is to look at all numbers up to the current index. This method will become slow the deeper you go in your tree, though. (But that shouldn't be a concern for a tree of 4 levels.)
If you choose your numbers such that the smaller number if always to the right, you have a binary search tree. You can use that to find whether a number has been used in (O log n), that is you have to visit each level of the tree once instead of visiting each node once.
There are other ways to keep track of which numbers have been used like bit sets or hashes, but these have to be implemented in C.
Edit: You've got the basics of the code right, but:
The termination criterion should be checked for the next step, so index + 1 == MAX/2. Alternatively, you can check index before (and instead of) entering the loop. (I prefer the latter, because it puts the termination criterion at the top of the function, but the former is closer to your existing code.)
In Search, you check the whole range of elements. That's okay, because the unused elements are −1. There is one problem, though: You don't reset the used elements, so that the check is against values from solutions that you have backtracked from. You can reset these values to −1 before backtracking. A better approach might be to check only the values that you have already entered. (Not resetting the values means that you will find fewer solutions. The first value for which there are solutions is 8, but without resetting, it won't find a solution here.)
Currently, you print all solutions. (Well, all solutions for which the left bracnch has the smaller number.) Depending on the value, there will be a lot of solutions. If you just want to print one solution, you can stop backtracking short by returning early.
You should provide prototypes of the functions before you use them, so that the compiler can make sure you are passing the correct arguments.
Here's a corrected version:
void BackTracking(int index){
int c1, c2;
for(c1=1; c1<data[index]; c1++){
c2 = 2*data[index] - c1;
if(!Search(c1) && !Search(c2)){
data[2*index+1] = c1;
data[2*index+2] = c2;
if(index + 1 == MAX/2)
print_Data();
else
BackTracking(index+1);
data[2*index+1] = -1;
data[2*index+2] = -1;
}
}
}
I think you can solve it using dynamic programming, if you do not care about number of computations, then you can also use combination algorithms.
your input = 10
for first level there could be X possible pair of numbers {n1,n2} = 2*10
for each of the pairs above pick one and use recursion to check further
run(input,tree)
for n1 from 0 to input:
for n2 from n1+1 to input:
if n1+n2 = 2*input:
pairs.add(n,input-n)
//if no pairs staisfy our condition
if pairs ==null:
return false
//check each pair
foreach pair in pairs:
run(pair.numbers, tree)

Sudoku Checker Program C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm trying to complete a sudoku solution checker program in c. I'm still trying to understand the steps in building this program before I start coding it. I found this example online http://practicecprogram.blogspot.com/2014/10/c-program-to-find-out-if-solved-sudoku.html
There are a few questions I still don't understand.
1 For my program I am given a text file with the first number being a number that says how many sets of sudoku solutions it contains. I am almost understanding how to check just one solution but having to do it for N solutions and making the program work for multiple sudoku solutions confuses me. Especially in making my 2d arrays for the values. My ouput is supposed to only be Yes or No on a new line for however many N sets.
2 Is checking that all rows and columns have sums of 45 and that the values are >0, <10 enough to prove that the solution is valid? I'm assuming since every puzzle only has one solution I don't have to check each 3x3 grid to make it doesn't contain duplicates if each row and column sum to 45.
1) simple:
/// Read the number of puzzles;
...
for (i = 0; i < number_of_puzzless; i++) {
// Read Data for a puzzle
...
// Process puzzle data
...
// Print result
...
}
2) The sum or all cells in a row/column is equal to 45 and all numbers are in a range from 1 to 9. Is this enough to check only rows and columns to state that the whole puzzle is valid?
Yes it is. Even if you try to fool your checker and would give it a row that, say, has two sixes and two nines and no sevens and eights, this would break the checks on some columns.
Your problem statement is missing an input. The sample assumes that the solution for each game is typed in, but in #1 you state that the only input is the number of games to solve. There has to be a source of data for each game solution. Let's assume there is another file for each game. Your program needs to read in each game solution, verify the solution, and simply report pass or fail as the result. The sample code needs to be re-coded to accept a file-based input but it does not need to retain all solutions in memory at once.
Another rule for Sudoku is that each digit in a row or column may only appear once. Just calculating a total for each row or column won't catch duplicates.
1) Handle each puzzle one at a time. Read the puzzle into the array. Check it. Then read the next puzzle into the same array. If you only want a single yes/no for all the puzzles collectively you can print no and exit as soon as any check fails. If you make it to the end without any failed checks, then print yes. If you need to print whether individual puzzles passed, then answer before moving on to the next puzzle.
2)No! Absolutely not. One simple example is a sudoku filled with all 5s. This will give a 45 sum for every block, row, and column, but obviously is incorrect. It is also not sufficient to only check the presence of each digit along the rows and columns. For example consider one filled with 1 - 9 on the first row. Each successive row is a left rotate of the previous row. This would give all digits in each row and each column, but the blocks would be wrong e.g. block 0,0 would be 123,234,456.
One (maybe the best) way to check for each number is to set up an array of flags. Each index represents that number in the puzzle. Scan the line (or row or block) and set the flag for each number when you reach it. Then check to make sure all the flags are set. For checking a row:
int i,col;
int flags[9];
//zero the flags
for(i 0 1; i < 9; i++)
flags[i] = 0;
//check row
for(col = 0; col < 9; col++)
flags[data[row][col] - '1'] = 1;
//check flags
for(i 0 1; i < 9; i++)
if( 0 == flags[i] )
fail = true;

Random numbers from an array and delete in C [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am writing a very simple program, yet I can not seem to get it to work properly. I want to start with an array with numbers from 1-69 and then randomly select 5 numbers from this array without repeating. And I do not want to just shuffle the array and take the first 5 numbers. I want it to resemble more of a darwing numbers out of a hat with the probability being the way it should be.
For Example:
Array1[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
Array2[]
// I want it to randomly choose an element from Array1, remove it from Array1, and place it in Array2. Then repeat the process until I have 5 randomly pulled numbers from Array1 without repeating.
Any help is greatly appreciated! Thank You!
P.s. I am writing this project in C.
Pseudo-code:
Create 69-element array A[] with values [1 ... 69]. Length = 69;.
Randomly create an index index = rand()%Length;
Swap that indexed element A[index] with array element A[Length-1].
Decrement: Length--
Repeat steps 2-4 four more times.
The last five elements of A[] are the desired set - no repeats.
Note: code is not shuffling the complete array - which would be a waste of time.
You can't simply "remove" a cell in a C array; if you really want to do it that way, the best you can do is:
select the element with rank n (from array A) and do whatever you want with it
move elements n+1, n+2, etc. (from array A) one cell left (backward) with something like memcpy
remember the new size of the array A (because the allocated memory will remain the same during the whole process)
You absolutely need to just "try something", post your work, and ask questions about what you've tried. Especially if this is a homework assignment, we can't "do your work for you" :(
There are many ways you can approach this.
Some example options:
a) Fill the array with "legal" numbers, select five numbers from five random positions, then mark those positions "taken" (so they won't be selected again).
b) Randomly fill the array with legal numbers, and choose five at a time, starting with position "0". Increment current position by "five" each time.
c) Etc.
"I want it to resemble more of a darwing numbers out of a hat." That is exactly how you can implement this:
Create a hat array with all lottery ticket in it.
Pick a random ticket from the array, store it and remove the ticket from the hat.
Repeat until you have as many tickets as you need.
Deletions from arrays require the tail of the array being shifted, but you don't need that here: The order of the items in the hat isn't important, so you can move the last element to the gap the drawn ticket has left in the array and decrement the array length.
So:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
int hat[70]; // pool of numbers
size_t n = 70; // size of pool
size_t i;
// get pseudo-random-number generator underway
srand(time(NULL));
// fill pool with all numbers
for (i = 0; i < n; i++) hat[i] = i;
// pick five numbers and print them
for (i = 0; i < 5; i++) {
size_t pick = rand() % n;
printf("%d\n", hat[pick]);
hat[pick] = hat[--n];
}
return 0;
}
In your case, the number of drawn numbers is small in comparison to the pool, so you might actually look at things the other way: Instead of restricting the items that you draw, you could look at the items you have already drawn and draw a ticket until you get one that you haven't seen yet. But the method above is genneral.

Custom Function with array input printing wrong result in certain cases?

I needed to make a function that takes an array as input (and its dimensions X,Y or ROW,COL) and calculates the sum of all lines (storing each sum in a cell of the newarray.
For an input of NxN array seems to be working perfectly.
For an input of KxN array where K>N seems to be working perfectly.
int* linesum(int *ar,int X,int Y)
{
int i,j,lsum=0;
int *new=malloc(X*sizeof(int));
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
lsum+=*(ar+i*X+j);
}
*(new+i)=lsum;
lsum=0;
}
return new;
}
lsum+=*(ar+i*X+j);
should be
lsum += *(ar+i*Y+j);
or
lsum += *(ar+i+j*X);
The difference between these two is the chosen memory layout. i counts the current row, while j counts the current column. There are now two possible (simple) memory layouts for the matrix (assume X=3 and Y=4 as an example):
0 1 2 3
4 5 6 7
8 9 10 11
or
0 3 6 9
1 4 7 10
2 5 8 11
where numbers are the indexes of the linear array storing the matrix elements. In the first case you get the the next element of a given row by simply adding 1, but you need to jump 4 (the number of columns Y) to get to the next row.
In the second case you need to jump X=3 (the number of rows) to get to the next element in a given row, but if you want to get to the next row, you simply have to add 1.
These two layouts give you the two different pointer arithmetics shown above. You decided the layout when you initialized your array, which you haven't posted, so I cannot know which one is correct in your case.
Note that from a performance viewpoint (if your matrix is very large) the first case is better for your particular access pattern, because the array can be read element by element, while the second layout would require repeatedly jumping Y elements in memory.
You could also use double arrays / pointers to get around such pointer arithmetic. Also I guess it would be good to avoid new as a variable name, even if this is C. If somebody would try to compile your code with a C++ compiler it would throw errors, because new is a reserved keyword there.

maximum no of equal elements in the array after n transformation [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
You have an array containing n elements. At any move, you choose two indices i and j, i not equals j and increment value at one index and decrease value at other index. You can make this move any number of times. We need is the maximum number of elements which can have the same value (after any number of moves).
Example for 1,2,3,4 answer is 3 since we can have at most 3 elements equal after applying the moves any number of times. But i am searching for the algorithm to do that so needed help.
As stated, this doesn't take much of an algorithm. If you can do it as many times as you want, you should always be able to get a result with either N or N-1 elements equal (where N is the size of the input array).
Take the sum of the input. For example, in your case: sum(1,2,3,4) = 10.
If sum % N == 0, the answer is N. Any time before that, you'll have at least one element higher than sum/N and at least one lower. Increment the low, decrement the high.
Else the answer is N-1. The final set can have N-1 elements equal to (int)sum/N and the last element will be the remainder from the original sum. You can use that last element as a "spare" to increment/decrement whichever other elements you want.
Since you don't have to actually find the transformations, the end result is O(N). You just take the sum and mod it by N to check which answer to give. There's no use recursing or searching for "averaging pairs" unless you want to find the sequence of steps that lead to the answer..
This might be a very ineffective algorithm - but you could try some sort of dynamic programming.
def elems(array, previous_attempts = []):
# Get a list of all the possible arrays (after transforming the current array)
# and remove all of the arrays we have seen so far.
possible_arrays = possibilities(array) - previous_attempts
# If there are no more possible, return the number of elements the array
# has in common.
if possible_arrays is empty:
return num_in_common(array)
# Otherwise, for all the possibilities find the one that creates the maximum
# amount of elements in common.
max = 0
for a in possible_arrays:
# This is a recursive call that calculates the score for the possibility.
# It also keeps track of the current state so we don't revisit it.
score = elems(a, previous_attempts.append(array))
if score > max:
max = score
return max
You can count the number of occurrences of each value in the array (Lets call the array A of size N). Let the maximal number of occurrences of any value in A be max (may be several values), you are only interested in the values that appeared max times, as other values can't surpass max+1 appearances by the suggested method.
Extreme cases:
if max=N the answer is N
if max=N-1 the answer is N-1
In all the other cases, for each value V that appeared max times, you are trying to find two other values that have an average of V but don't equal V. if they exist, then the answer is max+2 (you can increment them so they both will be equal to V). if no such indexes i and j exist, the answer is max+1 (you can increment any two other values until one of them will be equal to V).
EDIT:
This answer assumes that you only choose i and j once and then increase/decrease them as much as you like (I guess I misinterpreted).

Resources