Triangle Challenge Question


#1

[code]#include <stdio.h>

// Declare global variable
float triangle;

// How to figure out the math
float remainingAngle(float angleA, float angleB)
{
float geometry = 180 - angleA - angleB;

return geometry; // Something has to be returned for function to work

}

int main(int argc, const char * argv[])

{
float angleA = 30.0;
float angleB = 60.0;
float angleC = remainingAngle(angleA, angleB);
printf(“The third angle is %.2f\n”, angleC);

return 0;

}[/code]

I used the preceding code to accomplish the challenge. It took me a while to figure out the function had to return a value for it to properly communicate its’ work. I also figured I didn’t need to declare angleC and could use other names for the variables.

My question is, what’s the optimal way to code this problem? I’m aware there are ‘more than one way to skin a cat’, but I’d like some opinions.

BTW, I’m an older guy, thinking about retiring in a few years. I’m not that old, and am thinking about coding as a second career. I’m a professional firefighter now, so this is as far from what I presently do as one can possibly get.

Thanks for any input I receive, and yes, I have thick skin.


#2

Your solution is already optimal.

Here are three variations:

float remainingAngle (float angleA, float angleB)
{
    float thirdAngle = 180 - angleA - angleB;
        
    return thirdAngle;
}
float remainingAngle (float angleA, float angleB)
{
    return 180 - angleA - angleB;
}
//  main.m

#include <stdio.h>

// a type name for our angles
typedef float angle_type;

// declare the signatures (or prototypes) of our functions...

// return the result directly
angle_type remainingAngle (angle_type, angle_type);

// return the result through an argument
void thirdAngle (angle_type *result, angle_type, angle_type);

int main (int argc, const char * argv[])
{
    angle_type angleA = 30.0;
    angle_type angleB = 60.0;
    angle_type angleC = remainingAngle (angleA, angleB);
    printf ("The third angle is %.2f\n", angleC);
    
    thirdAngle (&angleC, angleA, angleB);
    printf ("The third angle is again %.2f\n", angleC);

    return 0;
}

// define our functions...

// return the result directly
angle_type remainingAngle (angle_type A, angle_type B)
{
    angle_type thirdAngle = 180 - A - B;
    
    return thirdAngle;
}

// return the result through an argument
void thirdAngle (angle_type *result, angle_type A, angle_type B)
{
    *result = 180 - A - B;
}

You can also define and use a macro to achieve the same affect for this simple problem:

//  main.m

#include <stdio.h>

// Macro to calculate the third angle of a triangle
#define remainingAngle(A, B) (180 - (A + B))

int main (int argc, const char * argv[])
{
    float angleA = 30.0;
    float angleB = 60.0;
    float angleC = remainingAngle (angleA, angleB);
    printf ("The third angle is %.2f\n", angleC);
    
    return 0;
}

A macro that takes arguments resembles a function at the point of invocation.

PS: I still remember the loud banging on the door of my room by a firefighter who woke me up, asking me to get out, 3 AM in the morning. When I got out, I saw that one wing of the dormitory was being engulfed by fire. (1980, Beaver College, Glenside, Philadelphia.)
I didn’t get to thank him, but please accept my “thank you” on his behalf.


#3

Thanks Ibex. I’m happy you had a good experience with fire, many don’t.

I liked your 2nd and last(macro) examples. Very concise, and got the job done without all the BS I used.

A couple of questions for you, if you don’t mind. I declared a global variable in my code. Would that only be necessary if I wanted to access that information from another part of the program later, rather than rewrite the function?

Secondly, will I learn to think in a streamlined fashion using BNR teachings, or is that an individual trait that can’t be taught, or learned?

Thank you again for taking the time to help me with your input.


#4

Yes, global variables can be used to communicate information to the outside world, and to access that information from the outside world without invoking a function.

But they can lead to code that’s hard to understand and hard to maintain if due care is not taken; it is better to avoid using them whenever possible (always possible if speed is not a performance requirement.)

Here are two versions of the same program that converts angles in degrees to angles in radians.

[radian: a unit of angle, equal to an angle at the center of a circle whose arc is equal in length to the radius.]

Using three global variables:

//  main.m

#include <math.h> // for M_PI

// format strings
const char *DEGREES = "%9.5f degrees";
const char *RADIANS = "%9.5f radians\n";

// a type name for our angles
typedef float angle_type;

angle_type _angleInRadian;

// convert the given angle to radians and put the result in the global variable
void radiansFromDegrees (angle_type degrees)
{
    _angleInRadian = (M_PI/180.0)*degrees;
}

// access the angle in radians in the global variable and print
void printRadians ()
{
    printf (RADIANS, _angleInRadian);
}

int main (int argc, const char * argv[])
{
    for (angle_type v = 0; v <= 360; v += 15)
    {
        radiansFromDegrees (v);
        printf (DEGREES, v);
        printRadians ();
    }
    return 0;
}

There are three global variables here: DEGREES, RADIANS, and _angleInRadian. The third global variable is used to store/access the results of the computation that does the angle conversion; the first two variables are read-only global variables that specify the format strings used by printf.

Using two global variables:

// main.m

#include <math.h> // for M_PI

// format strings
const char *DEGREES = "%9.5f degrees";
const char *RADIANS = "%9.5f radians\n";

// a type name for our angles
typedef float angle_type;

// convert and return the result
angle_type radiansFromDegrees (angle_type degrees)
{
    return (M_PI/180.0)*degrees;
}

// print the given angle in radians
void printRadians (angle_type radians)
{
    printf (RADIANS, radians);
}

int main (int argc, const char * argv[])
{
    for (angle_type v = 0; v <= 360; v += 15)
    {
        printf (DEGREES, v);
        printRadians (radiansFromDegrees (v));
    }
    return 0;
}

This version no longer uses a global variable to store/access the results of the computation that does the angle conversion, but it still uses the global variables that specify the format strings.

Learning to be a good programmer is akin to learning to be a good piano player - it requires a lot of determination, a lot of practice, and a desire to explore, to make mistakes and to learn from those mistakes. (Although some people are better at this than others.) BNR books are excellent starting points to build upon. Also if you have the financial resources, they have the courses at the ranch, which you might consider attending once you feel that you have learned how to crawl. Last but not least, learning some computer science will help enormously.


#5

Thanks for the love, Ibex.

When you speak of computer science helping a lot, is that just to further the foundational understanding of computers/compilers/etc in general? I’m separating the military in 60 days, and, although I have a finance degree and own a company, I’d REALLY love to go back to school for stuff like this. I’ve been dabbling with coding for about 14 months now, and love it. It’s “hard knowledge”, meaning it’s a lot of trial-and-error based, and I love that.


#6

Yes, especially compilers, algorithms, and the theory of computation.

All the best and have fun!


#7

Your global variable isn’t doing anything at the moment. If you comment that line out, it still works.

So my confusion is, why doesn’t Xcode warn that it’s an unused variable? Does it treat globals differently to locals in this regard?


#8

@coda50

I did “reprogramming” it in german, to get a better grip and voila:
when I named the return variable “ergebnis” - what would be result, it hit me…

#import <Foundation/Foundation.h>
double berechneDrittenWinkel (double winkelA, double winkelB){
// here …
double ergebnis = 180 -winkelA-winkelB;
return ergebnis;
}

int main(int argc, const char * argv[])
{

@autoreleasepool {
    
    // insert code here...
    double winkelA = 40.0;
    double winkelB = 50.0;
    double winkelC = berechneDrittenWinkel(winkelA, winkelB);
    NSLog(@"Der dritte Winkel ist %.2f groß", winkelC);
    
    
}
return 0;

}

BTW , I am 48 and have the same idea and a strong will… :laughing: