[alt.sources] Useful prog for custom freewheels

jfh@rpp386.Dallas.TX.US (John F. Haugh II) (01/15/89)

In article <1680068@hpfelg.HP.COM> koren@hpfelg.HP.COM writes:
>After some furious scribbling on the back of napkins, I decided
>to write a little program to graphically display gear ratios.  I
>hacked out a little BASIC program which is included here.  (OK,
>OK, don't laugh.  I like C as much as the next guy, but this
>thing took me ~5 minutes in basic, and would have taken ~20 in
>C).

Okay, I didn't do the graphics, but I did SORT the gears by size
and output this nice little table.  The prompts are sent to stderr,
so you can redirect the output to a file and still see your prompts!

Sample output for my bike follows ...
-- gears.c --
#include <stdio.h>
#include <string.h>

struct	size {
	int	fgear,		/* which front gear was used */
		rgear;		/* which rear gear was used */
	double	length;		/* size of wheel in inches */
} sizes[100];

#define	SIZES(i,j)	((&sizes[i * nrear + j]))

compare (a, b)
struct	size	*a;
struct	size	*b;
{
	if (a->length > b->length)
		return (1);
	else if (a->length < b->length)
		return (-1);
	else
		return (0);
}

main ()
{
	char	buf[BUFSIZ];		/* read strings from keyboard */
	int	wheel;			/* size of wheel in inches */
	int	nfront,			/* number of front chainrings */
		front[10];		/* teeth on each ring */
	int	nrear,			/* number of rear sprockets */
		rear[10];		/* teeth on each sprocket */
	int	i, j;
	char	*cp;

	setbuf (stdout, NULL);		/* no buffering on output */

	fprintf (stderr, "Enter size of wheel in inches: ");

	if (gets (buf) == NULL || sscanf (buf, "%d", &wheel) != 1)
		exit (1);

	fprintf (stderr, "Enter front chainring sizes, separated by blanks: ");

	if (gets (buf) == NULL)		/* get the line full of chainrings */
		exit (1);

	for (cp = buf, nfront = 0;nfront < 10;) {
		i = atoi ((cp = strtok (cp, " \t")) == NULL ? "0":cp);
		cp = NULL;		/* for subsequent calls to strtok */
		if (i <= 0)		/* some bogus number or EOS */
			break;

		front[nfront++] = i;	/* save gear size */
	}

	fprintf (stderr, "Enter rear sprocket sizes, separated by blanks: ");

	if (gets (buf) == NULL)		/* get the line full of sprockets */
		exit (1);

	for (cp = buf, nrear = 0;nrear < 10;) {
		i = atoi ((cp = strtok (cp, " \t")) == NULL ? "0":cp);
		cp = NULL;		/* yup, same thing here ;-) */
		if (i <= 0)
			break;

		rear[nrear++] = i;
	}
	for (i = 0;i < nfront;i++) {
		for (j = 0;j < nrear;j++) {
			SIZES(i, j)->fgear = i;
			SIZES(i, j)->rgear = j;
			SIZES(i, j)->length =
				(double) front[i] / (double) rear[j] * wheel;
		}
	}
	qsort (sizes, nfront * nrear, sizeof (struct size), compare);

	printf ("\nNumber\tGear\tRatio\tSize in inches\n");
	for (i = 0;i < nfront * nrear;i++) {
		printf ("%2d\t", i + 1);
		printf ("%d/%d\t", sizes[i].fgear + 1, sizes[i].rgear + 1);
		printf ("%d/%d\t", front[sizes[i].fgear], rear[sizes[i].rgear]);
		printf ("%5.1f\n", sizes[i].length);
	}
}
-- sample run --
Enter size of wheel in inches: 27
Enter front chainring sizes, separated by blanks: 40 52
Enter rear sprocket sizes, separated by blanks: 14 16 18 21 24 28

Number	Gear	Ratio	Size in inches
 1	1/6	40/28	 38.6
 2	1/5	40/24	 45.0
 3	2/6	52/28	 50.1
 4	1/4	40/21	 51.4
 5	2/5	52/24	 58.5
 6	1/3	40/18	 60.0
 7	2/4	52/21	 66.9
 8	1/2	40/16	 67.5
 9	1/1	40/14	 77.1
10	2/3	52/18	 78.0
11	2/2	52/16	 87.8
12	2/1	52/14	100.3
-- 
John F. Haugh II                        +-Quote of the Week:-------------------
VoiceNet: (214) 250-3311   Data: -6272  |"UNIX doesn't have bugs,
InterNet: jfh@rpp386.Dallas.TX.US       |         UNIX is a bug."
UucpNet : <backbone>!killer!rpp386!jfh  +--------------------------------------