I was doing a coding challenge for a website, the premise was:
In this challenge, write a program that takes in three arguments, a start temperature (in
Celsius), an end temperature (in Celsius) and a step size. Print out a table that goes from > the start temperature to the end temperature, in steps of the step size; you do not
actually need to print the final end temperature if the step size does not exactly match.
You should perform input validation: do not accept start temperatures less than a lower
limit (which your code should specify as a constant) or higher than an upper limit (which
your code should also specify). You should not allow a step size greater than the
difference in temperatures. (This exercise was based on a problem from C Programming
Language).
I got the same results as the solution did, but I’m curios as to why their solution is more efficient (I’d presume it is). Anyone able to explain it to me? Their solution is first followed by mine.
#include <stdio.h>
#define LOWER_LIMIT 0
#define HIGHER_LIMIT 50000
int main(void) {
double fahr, cel;
int limit_low = -1;
int limit_high = -1;
int step = -1;
int max_step_size = 0;
/* Read in lower, higher limit and step */
while(limit_low < (int) LOWER_LIMIT) {
printf("Please give in a lower limit, limit >= %d: ", (int) LOWER_LIMIT);
scanf("%d", &limit_low);
}
while((limit_high <= limit_low) || (limit_high > (int) HIGHER_LIMIT)) {
printf("Please give in a higher limit, %d < limit <= %d: ", limit_low, (int) HIGHER_LIMIT);
scanf("%d", &limit_high);
}
max_step_size = limit_high - limit_low;
while((step <= 0) || (step > max_step_size)) {
printf("Please give in a step, 0 < step >= %d: ", max_step_size);
scanf("%d", &step);
}
/* Initialise Celsius-Variable */
cel = limit_low;
/* Print the Table */
printf("\nCelsius\t\tFahrenheit");
printf("\n-------\t\t----------\n");
while(cel <= limit_high) {
fahr = (9.0 * cel) / 5.0 + 32.0;
printf("%f\t%f\n", cel, fahr);
cel += step;
}
printf("\n");
return 0;
}
My solution:
#include <stdio.h>
#include <stdlib.h>
#define LOW 0
#define HIGH 50000
int main(void)
{
int lower, higher, step, max_step;
float cel, fahren;
printf("\nPlease enter a lower limit, limit >= 0: ");
scanf("%d", &lower);
if (lower < LOW)
{
printf("\nERROR: Lower limit must be >= 0.");
exit(1);
}
printf("\nPlease enter a upper limit, limit <= 50000: ");
scanf("%d", &higher);
if (higher > HIGH)
{
printf("\nERROR: Upper limit must be <= 50,000.");
exit(1);
}
printf("\nPlease enter an increment amount, 0 < step <= 10: ");
scanf("%d", &step);
max_step = higher - lower;
if (step > max_step)
{
printf("\nERROR: Step size cannot exceed difference between higher and lower limit.");
exit(1);
}
printf("Celsuis \tFahrenheit\n");
printf("------- \t-----------\n\n");
cel = (float)lower;
while (cel < higher)
{
fahren = cel * 9/5 + 32;
printf("%f \t%f\n", cel, fahren);
cel = cel + step;
}
return 0;
}
Hmm, which is more efficient… before making that claim we need some metrics, what are we talking about here? Run time? Binary size?
Just a quick example… we can compile both solutions and run them with the “time” command and a worst case (0-50000 with a step of 1) to see what type of times we’re using:
“Their” solution size:
“Their” solution running time:
Your solution size:
Your solution running time:
So your solution takes longer and has a larger image size. Can we say now that “they” have a more efficient program? Not really, the
timeisn’t totally accurate on this scale (and with other things happening in the system) so we’d need a number of runs. Averaged over four* runs:So no, they are not really more “efficient” then you are.
There are some trivial things we can do to increase the “efficiency” here, but because the solutions are so similar, and the code is so trivial (a single stepping traversal) I’m not really sure if it matters all that much.
As far as “efficient” code size, you’ll note that your
.textsize is larger than the other solution. Your messages are more verbose and readable, so you take a hit on size. Is that more efficient? Perhaps if size is important, but personally I think readability is more important unless we’re talking an embedded solution.* – you need a lot more runs and a more sensitive timing mechanism, but this is just a quick example