All pastes #963189 Raw Edit

Learn Binary

public c v1 · immutable
#963189 ·published 2008-03-30 09:32 UTC
rendered paste body
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/time.h>/* C doesn't even have TRUE and FALSE, isn't C silly? */#define FALSE 0#define TRUE 1/* It's macros are fun though. Although people cry when you use them. */#define unless( x ) if ( ! ( x ) )#define until( x ) while( ! ( x ) )inline int answer_is_binary_nibble( const char *answer ) {	char *ptr;	if ( strlen( answer ) > 4 ) {		return( FALSE );	}	ptr = ( char * )answer;	do {		if ( *ptr != '1' && *ptr != '0' ) {			return( FALSE );					}	} while( *( ++ptr ) );	return( TRUE );}inline int answer_is_exit( const char *answer ) {	return( !strcasecmp( answer, "exit" ) );}inline int answer_is_valid( const char *answer ) {	return (		answer_is_binary_nibble( answer ) ||		answer_is_exit( answer )	);}char *strchomp( char string[] ) {	char *ptr;	ptr = string + strlen( string ) - 1;	if ( *ptr == '\n' ) {		*ptr = '\0';	}	/* Perl also ditches \r but this isn't perl. */	return( string );}inline unsigned int convert_answer_to_number( const char *answer ) {	char *ptr;	int power;	unsigned int result;	unless ( answer_is_binary_nibble( answer ) ) {		fputs( "It's usually good practice to perform sanity checks everywhere.\n", stderr );		fputs( "If you don't and make a mistake your program can be insecure!\n", stderr );		fputs( "This should never happen so we exit the program here.!\n", stderr );		exit( 255 );	}	ptr = ( char * )answer;	/* Another use of understanding how binary works */	power = 1 << ( strlen( answer ) - 1 );	result = 0;	do {		if ( *ptr == '1' ) {		/* Here too */			result = result | power;		}		/* Here too */		power = power >> 1;	} while( *( ++ptr ) );	return( result );}int main( int argc, char *argv[] ) {	int stopped;	unsigned int number;	int valid_answer;	int right_answer;	unsigned int consecutive_right_answers;	unsigned int total_right_answers;	char answer[ 6 ];	unsigned int answer_as_a_number;	struct timeval now;		/* Pretend to be random */	gettimeofday( &now, NULL );	srand( now.tv_usec );		puts( "Puts there only are 10 kinds of people in the world:\nThose who grok binary, and those who do not.\n\nLearn binary by repetiton! Type exit to stop.\n" );	/* Some people say forever loops are bad form. Boohoo. */	consecutive_right_answers = 0;	total_right_answers = 0;	while ( TRUE ) {		/* Another use of understanding how binary works */		number = ( unsigned int ) rand() & 0xF;		printf( "Enter the following in binary: %X (%u).\n" , number, number );		right_answer = FALSE;		until( right_answer ) {			valid_answer = FALSE;			until( valid_answer ) {				fgets( answer, 6, stdin );				/* Some people do such silly things */				if ( feof( stdin ) || ferror( stderr ) ) {					exit( 254 );				}				/* This is a pearlism to ditch the linefeed */				strchomp( answer );				valid_answer = answer_is_valid( answer );				unless ( valid_answer ) {					puts( "Not a valid answer. Enter a binary number up to 1111 or \"exit\".\nDo not enter more than 4 characters.\n" );				}			}			if ( answer_is_exit( answer ) ) {				/* Exits forever loop */				return( 0 );			}					answer_as_a_number = convert_answer_to_number( answer );			right_answer = answer_as_a_number == number;			if ( right_answer ) {				printf( "Correct! You have %u total right answers. Your current streak is %u.\n", ++total_right_answers, ++consecutive_right_answers );							} else {				puts( "Haha! You fail! Try again!!!\n" );				consecutive_right_answers = 0;			}		}	}	return( FALSE );}