Triangle with Recursion - c

I have an assignment from my uni where I have to print a triangle using recursion in C language. I have tried writing my code as follows but I am not able to find my mistake. Kindly can anyone point out where I have to edit.
int tri(int x, int org);
int dreick(int x) {
return tri(x,x);
}
int tri(int x,int org) {
if (x == 0) {
return 0;
}
else {
return (x - 1, org);
}
for (int i = 0; i < (org - x); i++) {
printf("");
}
for (int j = 0; j <= x; j++) {
printf("*");
}printf("\n");
}
int main() {
int a = dreick(5);
printf("%d",a);
}

Recursion works as follows: each step receives a parameter which specifies what work still needs to be done; if no work needs to be done, then it returns without doing anything; otherwise, it does one step of the work, and then invokes itself with a new value for the parameter which specifies the remaining work to be done.
In your case, the parameter specifying what work still needs to be done can be the row number.
Your triangle-printing code can print the top (single star at row 0) and the bottom (row of stars at row N) outside of recursion, so as to keep things simple. Use recursion to print each line of text from 1 to N-1.
On each step of the recursion you print a number of spaces, an asterisk, some more spaces, and then another asterisk. The number of spaces depends on the row number. (How deep down the triangle you are.) You are done when you reach N-1.

Related

Need Clarification on Recursive Function Methodology

Apologies in advance, I am very new to c and programming.
I'm currently working on understanding how recursive functions work and have a major mental block.
I was provided an example of a recursive function that creates a "pyramid" of sorts out of hash symbols (see below). I can't understand why the output is not flipped horizontally, with n hashes on top and 1 hash on bottom.
In trying to make sense of it, I created a table with the number of loops, n value, n - 1 value, and how man hashes I think it should print.
On loop 1, n starts out as 4 and the "for loop" should run 4 times since "i" goes through during 0, 1, 2, and 3.
Line break
On loop 2, n is now 3 and the "for loop" should run 3 times since "i" goes through during 0, 1, and 2.
And so on and so forth...
I created nested for loops that I thought would provide the same result: n (height) is 4 originally and works down to 0, i works upwards from 0 printing hashes but the result is the exact opposite.
#include <cs50.h>
#include <stdio.h>
void draw(int n);
int main(void)
{
// prompt user for height of pyramid
int height = get_int("Height ");
// call recursive 'draw' function
draw(height);
printf("\n");
// my nested loop function I made that I can't tell how is different from the recursive function
for (int n = height; n >= 0; n--)
{
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}
}
// recursive function example I was given that I cannot make sense of
void draw(int n)
{
if (n <= 0)
{
return;
}
draw(n - 1);
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}
Result below. Their result on top. Mine below it.
If someone could please help clarify what I'm missing I would greatly appreciate it.
Look to see when this recursion will emit its first out put
void draw(int n)
{
if (n <= 0)
{
return;
}
draw(n - 1);
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}
see that it keeps calling itself before the printf, it only stops doing that one n reaches 0, then it starts returning and calling the prints, but in reverse order of n.
ie it goes
draw(4)->draw(3)->draw(2)->draw(1)->draw(0)
printf loop *1
printf loop * 2
printf loop * 3
printf loop * 4
You have called the draw(n-1); before the for loop. Therefore the function recursively called like this.
First Draw(4); function calls from main function. Then calls Draw(4-1); -> Draw(3); Then again Draw(3-1); -> Draw(2); it doesn’t go to the line which has for loop until base condition. So, next again calls Draw(2-1); -> Draw(1);
After that Draw(1-1); -> Draw(0); since n=0 function will return.
Next go backwards now. Because you haven’t completed the Draw(n) function. You only did recursively calling it self. After finishing that you have printing part. Since you are now in Draw(1), you starts printing from 1. You came to Draw(1) from Draw(4). So now you have to go again back to Draw(4) from Draw(1). That’s why we go backwards.
Path explanation:
Now you are in Draw(1); so it prints #. Then finishes Draw(1); next Draw(2); so it prints ##. next Draw(3); so it prints ###.
next Draw(4); so it prints #### .
That’s how the recursion function works. Therefore the output is,
#
##
###
####
In your nested loop it starts from 4. Because you have used n=height. So your code should start from n=1 like below code.
for (int n = 1; n <= height ; n++)
{
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}

While loop won't break as intended in C

I'm trying to learn how to program in C and have stumbled into a problem that seems like it should have been a simple fix, but it's giving me more issues then I anticipated. I'm trying to created a number guessing game, where you get three chances to guess the number, but my issue is that the Do While loop wont break when the right answer is guessed. Here is the function:
void Win_Search(int lucky[],const int MAX, int user_entry, int i)
{
int j=0;
do {
j++;
printf("Please enter a number between 0 and 100\n");
scanf("%d",&user_entry);
for(i = 0; i < MAX; i++)
{
if(user_entry==lucky[i])
{
printf("winner\n");
}
}
} while(user_entry==lucky[i]||j<3);
}
Basically it's supposed to loop through the array lucky[i] and check to see if the user_entry equals any of the 20 numbers in the array. As of right now it loops through, recognizes if a winning number has been selected from the array, but doesn't break from the array.
when I change it to
}while(user_entry!=lucky[i]||j<3);
it completely ignores the counter and just loops forever.
I don't want to use break because everything I've read about it talks about it's poor programming practice. Is there another way to break, or have simply just made a mistake thats causing this issue.
Thanks in advance.
Consider for a second where your index variable "i" comes from. What happens to it after you've found a correct user entry? Where does the control flow go?
I would suggest having a look at the "break" keyword.
You wrote while (user_entry == lucky[i]..) which translates to as long as user_entry is equal to lucky[i] keep on looping. Which is clearly not what you intend to do.
Transform your condition to } while (user_entry != lucky[i] && j < 3); and you should be fine. This will translate in plain english to as long as user_entry is different of lucky[i] AND j is inferior to 3, keep looping.
But using this, you test on the value of lucky[i] even when i means nothing ( when i is equal to max, you don't want to test it, and this goes in the domain of undefined behavior).
But if you realy dont want to use break keyword, one solution is to use a flag. Set it to 1 before you start to loop, and change it to 0 when the good answer is found. Your code will become
void Win_Search(int lucky[],const int MAX, int user_entry, int i)
{
int j=0;
char flag = 1;
do {
j++;
printf("Please enter a number between 0 and 100\n");
scanf("%d",&user_entry);
for(i = 0; i < MAX; i++)
{
if(user_entry==lucky[i])
{
printf("winner\n");
flag = 0;
}
}
} while(flag&&j<3);
}
}while(user_entry!=lucky[i]||j<3);
That is bad logic - loop while the user's entry isn't the lucky number OR j is below three? Surely you actually want this:
}while(user_entry!=lucky[i]&&j<3);
This is only the solution to your second issue of it ignoring the counter - the main problem is solved in the other answers.
The only independent condition is that the user has more guesses left. try this while"
while(j <= 3);
The less than should be obvious, but the equals belongs there because you increment your j before the loop so it will be
j = 1 => first guess
j = 2 => second guess
j = 3 => third guess
After that the user should have no more guesses
You should find this doesn't work, that is because we want to exit the loop if the user guesses correctly. To do this, you can use a int as a bool (0-false, 1-yes).
void Win_Search(int lucky[],const int MAX, int user_entry, int i)
{
int j=0;
int exitCase = 0;
do {
j++;
printf("Please enter a number between 0 and 100\n");
scanf("%d",&user_entry);
for(i = 0; i < MAX; i++)
{
if(user_entry==lucky[i])
{
exitCase = 1;
printf("winner\n");
}
}
} while(exitCase == 0 || j <= 3);
}

function to perform bubble sort in C providing unstable results

I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.

Code help to determine if point is in Mandelbrot set (check my solution)

Here is my function that tests two points x and y if they're in the mandelbrot set or not after MAX_ITERATION 255. It should return 0 if not, 1 if it is.
int isMandelbrot (int x, int y) {
int i;
int j;
double Re[255];
double Im[255];
double a;
double b;
double dist;
double finaldist;
int check;
i=0;
Re[0]=0;
Im[0]=0;
j=-1;
a=0;
b=0;
while (i < MAX_ITERATION) {
a = Re[j];
b = Im[j];
Re[i]=((a*a)-(b*b))+x;
Im[i]=(2 * a * b) + y;
i++;
j++;
}
finaldist = sqrt(pow(Re[MAX_ITERATION],2)+pow(Im[MAX_ITERATION],2));
if (dist > 2) { //not in mandelbrot
check = 0;
} else if (dist <= 2) { //in mandelbrot set
check = 1;
}
return check;
}
Given that it's correct (can someone verify... or write a more efficient one?).
Here is my code to print it, however it does not work! (it keeps giving all points are in the set). What have I done wrong here?
int main(void) {
double col;
double row;
int checkSet;
row = -4;
col = -1;
while (row < 1.0 ) {
while (col < 1.0) {
checkSet = isMandelbrot(row, col);
if (checkSet == 1) {
printf("-");
} else if (checkSet == 0) {
printf("*");
}
col=col+0.5;
}
col=-1;
row=row+0.5;
printf("\n");
}
return 0;
}
There are some bugs in your code. For example, you do this:
a = Re[j];
b = Im[j];
But at the first iteration, j = -1, so you're getting the value at index -1 of the arrays. That is not what you wanted to do.
Also, why are Re and Im arrays - do you really need to keep track of all the intermediate results in the calculation?
Wikipedia contains pseudocode for the algorithm, you might want to check your own code against that.
Another bug: your function takes int arguments, so the values of your double inputs will be truncated (i.e. the fractional part will be discarded).
You should probably be checking for escape inside the while loop. That is to say, if ((a*a + b*b) > 4) at any time then that pixel has escaped, end of story. By continuing to iterate those pixels, as well as wasting CPU cycles you the values are growing without bound and seem to be exceeding what can be represented in a double - the result is NaN, so your finaldist computation is producing garbage.
I think you would benefit from more resolution in your main. Your code as you've put it here isn't computing enough pixels to really see much of the set.

Finding the largest palindrome of the product of two three digit numbers problem

So on Project Euler the Problem 4 states the following:
A palindromic number reads the same
both ways. The largest palindrome made
from the product of two 2-digit
numbers is 9009 = 91 99.
Find the largest palindrome made from
the product of two 3-digit numbers.
I have tried the following:
#include <stdio.h>
#include <stdlib.h>
int check(int result)
{
char b[7];
sprintf(b, "%d", result);
if (b[0] == b[5] && b[1] == b[4] && b[2] == b[3])
{
return 1;
}
else
{
return 0;
}
}
int main () {
int i;
int g;
int final;
for (i = 999; i > 99; i--)
{
for (g = 999; g > 99; g--)
{
if (check(g*i) == 1)
{
final = g*i;
goto here;
}
}
}
here:
printf("%d", final);
}
But, this does not work. Instead of the right answer, I get 580085, which I guess is a palindrome at least, but still not the right answer.
Let me explain my program starting from int main:
int i and int g are my multipliers. They are those two three digit numbers.
int final is the number that will store the largest palindrome.
I start two for loops going to down to get every number possibility.
I get out of the loop using a goto when the first palindrome is reached(probably should not but, it doesn't effect a small program like this too much).
The first palindrome should be the biggest one possible since I am counting down from the top.
Let me now explain my check:
First off since these are two three digit numbers multiplying together to determine the size a char would need to be to hold that value I went to a calculator and multiplied 999 * 999 and it ended up being 6 then I need to add one because I found out from one the questions I posted earlier that sprintf puts a \0 character at the end.
Ok, now that I have a char and all, I copied result (which i*g in int main) and put it in char b[7].
Then I just checked b to see if it equalled it self with by hard coding each slot I needed to check for.
Then I returned accordingly, 1 for true, and 2 for false.
This seems perfectly logical to me but, it does not work for some weird reason. Any hints?
This assumption is wrong:
The first palindrome should be the biggest one possible since I am counting down from the top.
You will check 999*100 = 99900 before 998*101 = 100798, so clearly you can´t count on that.
The problem is that the first palindrome that you find is not the bigger one for sure.
Just an example:
i = 900, g = 850 -> 765000
i = 880, g = 960 -> 844800
The first one is smaller, but since you iterate first on i, then on g it will be discovered first.
Ok, they are not palindrome but the concept is the same..
I think you are tackling this problem back to front. It would be more efficient to generate the palindromes from highest to lowest then check by factorizing them. First one that has two three digit factors is the answer.
e.g.
bool found = false;
for (int i = 998; i >= 100; i--)
{
char j[7];
sprintf(j,"%d",i);
j[3]= j[2];
j[4]= j[1];
j[5]= j[0];
int x =atoi(j);
int limit = sqrt((float) x);
for (int z = 999; z >= limit; z--)
{
if (x%z==0){
printf("%d",x);
found = true;
break;
}
}
if (found) break;
}
The first palindrome should be the biggest one possible since I am counting down from the top
The problem is that you might have found a palindrome for a large i and a small g. It's possible that there's a larger palindrome that's the product of j and k where:
i > j and
g < k
(I hope this makes sense).
Java Implementation:
public class Palindrome {
public static void main(String[] args)
{ int i, j;
int m = 1;
int k =11;
boolean flag = false;
while (true)
{;
if (flag) j = m + 1;
else j = m;
for (i = k; i > 0; i--)
{
j++;
int number, temp, remainder, sum = 0;
number = temp = (1000 - i) * (1000 - j);
while (number > 0)
{
remainder = number % 10;
number /= 10;
sum = sum * 10 + remainder;
}
if (sum == temp)
{
System.out.println("Max value:"+temp);
return;
}
}
if (flag)
m++;
k=k+11;
flag = !flag;
}
}
}
A word on performance. You have the possibility of duplicating many of the products because you are using a pretty simple nested loop approach. For instance, you start with 999*999 and then 999*998, etc. When the inner loop finishes, you will decrement the outer loop and start again with 998*999, which is the same as 999*998.
Really, what you want to do is start the inner loop with the same value as the current outer loop value. This will eliminate your duplicate operations. Something like this...
for (i = 999; i > 99; i--)
{
for (g = i; g > 99; g--)
{
...
However, as Emilio pointed out, your assumption that the first palindrome you find will be the answer is incorrect. You need to compute the biggest numbers first, obviously. So you should try them in this order; 999*999, 999*998, 998*998, 999*997, 998*997, etc...
Haven't tested it but I think you want something like this (pseudo code):
x = 999;
n = 0;
while (++n <= x)
{
j = x;
k = j - n;
while (j >= k)
{
y = j-- * k;
if (check(y))
stop looking
}
}
I found this article which might help you. It has improved brute force approach.
All the above provided answers are excellent, but still I could not restrict myself from writing the code. The code posted by #thyrgle is absolutely perfect. Only a slight correction which he needs to do is just check which product is the maximum.
The code can be as
int i,j,max=0,temp;
for(i=999;i>=100;i--){
for(j=i;j>=100;j--){
temp=i*j;
if(isPalin(temp) && temp>max){
max=temp;
}
}
}
cout<<max<<"\n";
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[6];
void convertToString(int xy){
int i,t=100000;
for(i=0;i<6;i++){
a[i]=xy/t;
xy = xy % t;
t=t/10;
}
}
int check(){
int i;
for(i=0;i<3;i++){
if(a[i]!=a[6-i]){
return 0;
}
}
return 1;
}
void main(){
int x,y,xy,status=0;
int i=0,j=0,p=0;
for(x=999;x>99;x--){
for(y=x;y>99;y--){
xy=x*y;
convertToString(xy);
status = check();
if(status==1){
if(xy>p){
p=xy;
i=x;
j=y;
}
}
}
}
printf("\nTwo numbers are %d & %d and their product is %d",i,j,p);
}
x,y=999,999
k=0
pal=[]
while (y>99):
while (x>=100):
m=x*y
n=x*y
while (n!=0):
k=k*10+(n%10)
n=int(n/10)
if(m==k):
if k not in pal:
pal.append(k)
x=x-1
k=0
else:
y,x=y-1,999
pal.sort()
print(pal)
it gives 906609 as the largest palindrome number

Resources