Finding the Smallest Value Out of Three Integers via a Ternary Operator
Due to the title being too descriptive, I'm left with not much to say in this post. So, here's the one-line implementation along with a test function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h> /** Returns the minimum of three values */ int min( int a, int b, int c ) { return ( a < b ? ( a < c ? a : c ) : ( b < c ? b : c ) ); } /** Test Function */ int main( ) { int a = 1, b = 2, c = 3; // Test all combinations of a, b, c printf( "{ %d, %d, %d } => min = %d\n", a, b, c, min( a, b, c ) ); printf( "{ %d, %d, %d } => min = %d\n", a, c, b, min( a, c, b ) ); printf( "{ %d, %d, %d } => min = %d\n", b, a, c, min( b, a, c ) ); printf( "{ %d, %d, %d } => min = %d\n", b, c, a, min( b, c, a ) ); printf( "{ %d, %d, %d } => min = %d\n", c, a, b, min( c, a, b ) ); printf( "{ %d, %d, %d } => min = %d\n", c, b, a, min( c, b, a ) ); return 0; } |
Whereas the output from the test function is as follows:
gdoko@mars:~$ ./min
{ 1, 2, 3 } => min = 1
{ 1, 3, 2 } => min = 1
{ 2, 1, 3 } => min = 1
{ 2, 3, 1 } => min = 1
{ 3, 1, 2 } => min = 1
{ 3, 2, 1 } => min = 1HTH
Calculating the Sum of All Proper Divisors in C
Hi there! Now that I have your attention, I'd like to tell you that I'm happy to share my very first post in Number Theory. I know, I know. It's elementary. However, I'm hoping to continue publishing similar posts as I study more; and this post is the very first one.
That said, this post is about a simple algorithm which calculates the sum of all proper divisors of a number. The meaning of a proper divisor here is that of a positive divisor of a number, excluding that number. So, if f(n) represents the function for calculating the sum of all proper divisors, we'll have the following for n = 10:
f( 10 ) = 1 + 2 + 5 = 8
With that in mind, the C implementation of the algorithm that carries the calculation of the sum of all proper divisors of a number, is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #include <stdio.h> #include <math.h> /** Get the sum of all proper divisors of a positive number */ long long sum_proper_divisors( int number ) { int i; long long sum = 0; if( number == 1 ) { return sum; } // Set sum to 1, as we start iteration from 2 sum = 1; // Iterate from 2 to sqrt( number ) int j = sqrt( number ); for( i = 2; i <= j; i++ ) { // If a number is a proper divisor, add it to the sum if( number % i == 0 ) { sum = sum + i; // If there's a multiple of a proper divisor, that is not equal to the // current proper divisor, then add it to the sum as well. if( i != number / i ) { sum = sum + ( number / i ); } } } return sum; } /** Test Function */ int main( ) { printf( "%d\t%lld\n", 1, sum_proper_divisors( 1 ) ); printf( "%d\t%lld\n", 20, sum_proper_divisors( 20 ) ); printf( "%d\t%lld\n", 25, sum_proper_divisors( 25 ) ); return 0; } |
Assuming the specified number is 20; then we'll get the following:
number = 20 => sqrt( 20 ) = 4 (integer flooring)
sum = 1; iterate from 2 to 4 (inclusive)
first iteration:
20 % 2 == 0 => sum = 3
20 / 2 == 10 => 2 != 10 => sum = 13
second iteration:
20 % 3 != 0
third iteration:
20 % 4 == 0 => sum = 17
20 / 4 == 5 => 5 != 4 => sum = 22Thus, the sum of all proper divisors for 20, is 22. On the other han, if specified the number as 25, then we'll get the following:
number = 25 => sqrt( 25 ) = 5
sum = 1; iterate from 2 to 5 (inclusive)
first iteration:
25 % 2 != 0
second iteration:
25 % 3 != 0
third iteration:
25 % 4 != 0
fourth iteration:
25 % 5 == 0 => sum = 6
25 / 5 == 5 => 5 == 5 (sum stays the same)Thus, the sum of all proper divisors for 25, is 6. On the other hand, the execution of the test function will yield the following results:
gdoko@mars:~$ ./sum_proper_divisors 1 0 20 22 25 6
HTH
Sorting 3-Numbers in Ascending Order in C
Recently, while tackling a programming challenge, I had to sort 3-numbers in ascending order (no; that wasn't the challenge, but one of the steps). However, I wanted to do this in a very lightweight and straightforward manner. So, the end result was a code containing 3-if conditions and a pointer manipulation function for swapping, as seen below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <stdio.h> /** Swaps two numbers via pointer manipulation */ void swap( int* a, int* b ) { int temp = *a; *a = *b; *b = temp; } /** Test Function */ int main( ) { int a, b, c; scanf( "%d %d %d", &a, &b, &c ); // Order numbers in ascending order if( b < a ) swap( &a, &b ); if( c < b ) swap( &b, &c ); if( b < a ) swap( &a, &b ); printf( "%d %d %d\n", a, b, c ); return 0; } |
As expected, the outcome of this endeavor worked as follows:
gdoko@mars:~$ ./min 1 2 3 1 2 3 gdoko@mars:~$ ./min 1 3 2 1 2 3 gdoko@mars:~$ ./min 3 1 2 1 2 3
HTH
Handling Big Numbers in C
Today I was looking at various C implementations for handling very large numbers. Although I've noticed that there were several libraries, such as The GNU Multiple Precision Arithmetic Library; I was more interested in a very lightweight, straightforward, single-file implementation. With that in mind, I finally came accross Professor's Skiena bignum.c implementation.
One of the first things I've noticed with this implementation is the missing string_to_bignum( char* s, bignum* n ) function. So, with some effort I went ahead and wrote that function. In addition, as I was studying the code, I also changed the formatting here and there, and added some additional comments for the sake of improved legibility. Thus, thinking that someone else might benefit from these tweaks as well, I'm going ahead with posting the complete [tweaked] source code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | /** * Copyright 2003 by Steven S. Skiena; all rights reserved. * * Permission is granted for use in non-commerical applications provided this * copyright notice remains intact and unchanged. * * This file contains the structure for representing big numbers. In addition, * this file contains functions for adding, subtracting, multiplying, and * dividing very large numbers. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXDIGITS 101 // Maximum Length Bignum #define PLUS 1 // Positive Sign Bit #define MINUS -1 // Negative Sign Bit /** Struct for big numbers */ typedef struct { char digits[ MAXDIGITS ]; // Represent the number int signbit; // 1 if positive, -1 if negative int lastdigit; // Index of high-order digit } bignum; /** Function headers declarations */ void print_bignum( bignum* n ); void string_to_bignum( char* s, bignum* n ); void int_to_bignum( int s, bignum* n ); void initialize_bignum( bignum* n ); void zero_justify( bignum* n ); void add_bignum( bignum* a, bignum* b, bignum* c ); void subtract_bignum( bignum* a, bignum* b, bignum* c ); void digit_shift( bignum* n, int d ); void multiply_bignum( bignum* a, bignum* b, bignum* c ); void divide_bignum(bignum *a, bignum *b, bignum *c); int max( int a, int b ); int compare_bignum( bignum* a, bignum* b ); /** Prints big number */ void print_bignum( bignum* n ) { int i; if( n->signbit == MINUS ) printf( "-" ); for( i = n->lastdigit; i >= 0; i-- ) { printf( "%c", '0' + n->digits[ i ] ); } printf("\n"); } /** Converts a string to a big number */ void string_to_bignum( char* s, bignum* n ) { int i, j; for( i = 0; i < MAXDIGITS; i++ ) { n->digits[ i ] = ( char ) 0; } n->lastdigit = -1; for( j = strlen( s ) - 1; j > 0; j-- ) { n->lastdigit++; n->digits[ n->lastdigit ] = s[ j ] - '0'; } // Check if the last character is a minus sign or a digit if( s[ 0 ] == '-' ) { n->signbit = MINUS; } else { n->lastdigit++; n->digits[ n->lastdigit ] = s[ 0 ] - '0'; n->signbit = PLUS; } } /** Converts an integer to a big number */ void int_to_bignum( int s, bignum* n ) { int i, t; n->signbit = s >= 0 ? PLUS : MINUS; for( i = 0; i < MAXDIGITS; i++ ) { n->digits[ i ] = ( char ) 0; } n->lastdigit = -1; t = abs( s ); while( t > 0 ) { n->lastdigit++; n->digits[ n->lastdigit ] = (t % 10); t = t / 10; } if( s == 0 ) { n->lastdigit = 0; } } /** Initializes a big number */ void initialize_bignum( bignum* n ) { int_to_bignum( 0, n ); } /** Returns the greatest of two integers */ int max( int a, int b ) { return a > b ? a : b; } /** Zero justifies a big number */ void zero_justify( bignum* n ) { while( ( n->lastdigit > 0 ) && ( n->digits[ n->lastdigit ] == 0 ) ) { n->lastdigit--; } if( ( n->lastdigit == 0 ) && ( n->digits[ 0 ] == 0 ) ) { n->signbit = PLUS; /* hack to avoid -0 */ } } /** Adds big numbers; i.e. c = a + b */ void add_bignum( bignum* a, bignum* b, bignum* c ) { int carry; /* carry digit */ int i; /* counter */ initialize_bignum( c ); if( a->signbit == b->signbit ) { c->signbit = a->signbit; } else { if( a->signbit == MINUS ) { a->signbit = PLUS; subtract_bignum( b, a, c ); a->signbit = MINUS; } else { b->signbit = PLUS; subtract_bignum( a, b, c ); b->signbit = MINUS; } return; } c->lastdigit = max( a->lastdigit, b->lastdigit ) + 1; carry = 0; for( i = 0; i <= ( c->lastdigit ); i++ ) { c->digits[ i ] = ( char ) ( carry + a->digits[ i ] + b->digits[ i ] ) % 10; carry = ( carry + a->digits[ i ] + b->digits[ i ] ) / 10; } zero_justify( c ); } /** Subtracts big numbers; i.e. c = a - b */ void subtract_bignum( bignum* a, bignum* b, bignum* c ) { int borrow; /* has anything been borrowed? */ int v; /* placeholder digit */ int i; /* counter */ initialize_bignum( c ); if( ( a->signbit == MINUS ) || ( b->signbit == MINUS ) ) { b->signbit = -1 * b->signbit; add_bignum( a, b, c ); b->signbit = -1 * b->signbit; return; } if( compare_bignum( a, b ) == PLUS ) { subtract_bignum( b, a, c ); c->signbit = MINUS; return; } c->lastdigit = max( a->lastdigit, b->lastdigit ); borrow = 0; for( i = 0; i <= ( c->lastdigit ); i++ ) { v = ( a->digits[ i ] - borrow - b->digits[ i ] ); if( a->digits[ i ] > 0) { borrow = 0; } if( v < 0 ) { v = v + 10; borrow = 1; } c->digits[ i ] = ( char ) v % 10; } zero_justify( c ); } /** Compares big numbers */ int compare_bignum( bignum* a, bignum* b ) { int i; /* counter */ if( ( a->signbit == MINUS ) && ( b->signbit == PLUS ) ) return( PLUS ); if( ( a->signbit == PLUS ) && ( b->signbit == MINUS ) ) return( MINUS ); if( b->lastdigit > a->lastdigit ) return( PLUS * a->signbit ); if( a->lastdigit > b->lastdigit ) return( MINUS * a->signbit ); for( i = a->lastdigit; i >= 0; i-- ) { if( a->digits[ i ] > b->digits[ i ] ) return( MINUS * a->signbit ); if( b->digits[ i ] > a->digits[ i ] ) return( PLUS * a->signbit ); } return( 0 ); } /** Multiplies a big number by 10^d */ void digit_shift( bignum* n, int d ) { int i; /* counter */ if( ( n->lastdigit == 0 ) && ( n->digits[ 0 ] == 0 ) ) return; for( i = n->lastdigit; i >= 0; i-- ) { n->digits[ i + d ] = n->digits[ i ]; } for( i = 0; i < d; i++ ) { n->digits[ i ] = 0; } n->lastdigit = n->lastdigit + d; } /** Multiplies big numbers; i.e. c = a * b */ void multiply_bignum( bignum* a, bignum* b, bignum* c ) { bignum row; /* represent shifted row */ bignum tmp; /* placeholder bignum */ int i, j; /* counters */ initialize_bignum( c ); row = *a; for( i = 0; i <= b->lastdigit; i++ ) { for( j = 1; j <= b->digits[ i ]; j++ ) { add_bignum( c, &row, &tmp ); *c = tmp; } digit_shift( &row, 1 ); } c->signbit = a->signbit * b->signbit; zero_justify( c ); } /** Divides big numbers; i.e. c = a / b */ void divide_bignum(bignum *a, bignum *b, bignum *c) { bignum row; /* represent shifted row */ bignum tmp; /* placeholder bignum */ int asign, bsign; /* temporary signs */ int i; /* counters */ initialize_bignum( c ); c->signbit = a->signbit * b->signbit; asign = a->signbit; bsign = b->signbit; a->signbit = PLUS; b->signbit = PLUS; initialize_bignum( &row ); initialize_bignum( &tmp ); c->lastdigit = a->lastdigit; for( i = a->lastdigit; i >= 0; i-- ) { digit_shift( &row, 1 ); row.digits[ 0 ] = a->digits[ i ]; c->digits[ i ] = 0; while( compare_bignum( &row, b ) != PLUS ) { c->digits[ i ]++; subtract_bignum( &row, b, &tmp ); row = tmp; } } zero_justify( c ); a->signbit = asign; b->signbit = bsign; } /** Test Function */ int main( ) { bignum n1, n2, n3, zero; // Instantiate string buffers for big numbers a and b char* a = calloc( MAXDIGITS, sizeof( char ) ); char* b = calloc( MAXDIGITS, sizeof( char ) ); // Get big numbers a and b as strings printf( "a = " ); fgets( a, MAXDIGITS, stdin ); printf( "b = " ); fgets( b, MAXDIGITS, stdin ); // Remove the newline character (if present) from string buffers char* nl; if( ( nl = strchr( a, '\n' ) ) != NULL ) *nl = '\0'; if( ( nl = strchr( b, '\n' ) ) != NULL ) *nl = '\0'; // Create a and b big number instances via the string buffers string_to_bignum( a, &n1 ); string_to_bignum( b, &n2 ); // Test addition add_bignum( &n1, &n2, &n3 ); printf( "a + b = " ); print_bignum( &n3 ); // Test comparison int comparison = compare_bignum( &n1, &n2 ); printf( "a %s b\n", comparison == 0 ? "==" : ( comparison < 0 ? ">" : "<" ) ); // Test subtraction subtract_bignum( &n1, &n2, &n3 ); printf( "a - b = " ); print_bignum( &n3 ); // Test multiplication multiply_bignum( &n1, &n2, &n3 ); printf( "a * b = " ); print_bignum( &n3 ); // Test division int_to_bignum( 0, &zero ); if( compare_bignum( &zero, &n2 ) == 0 ) { printf( "a / b = NaN\n" ); } else { divide_bignum( &n1, &n2, &n3 ); printf( "a / b = " ); print_bignum( &n3 ); } return 0; } |
Quicksort Implementation in C
Since I've started teaching various computer science courses last August, I've had a chance to dive deeper and deeper in the world of C programming. However, having to program in Java for a living, I'm far from being converted
That said, this is my second post only that bears the tag of C. What you'll find below is a C implementation of the Quicksort algorithm. This implementation has been adapted from my previous post: Quicksort Implementation in Java. To those of you who had a chance to delve in C, you'll notice that I don't make a lot of use of C-specific features. However, this was done on purpose as the goal of this implementation was to translate the code from Java to C with the least amount of modifications.
Needless to say, I hope you'll find both implementations beneficial, and do not hesitate to provide any feedback you might have.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #include <stdio.h> #define ARRAY_SIZE 9 /** Sorts the specified array recursively */ void sort( int array[ ], int left, int right ) { if( left < right ) { int pivot = partition( array, left, right ); sort( array, left, pivot - 1 ); sort( array, pivot + 1, right ); } } /** Swaps the values at the specified array indexes */ void swap( int array[ ], int a, int b ) { int temp = array[ a ]; array[ a ] = array[ b ]; array[ b ] = temp; } /** * Partitions the specified array based on the pivot element it * selects. Afterwards by relying on a comparison sort, it places * all the elements less than or equal to the pivot before it, * and the elements greater than the pivot, after it. Finally, the * pivot index is returned. */ int partition( int array[ ], int left, int right ) { // Select pivot element int pivot = array[ right ]; int j, i = left - 1; for( j = left; j < right; j++ ) { if( array[ j ] <= pivot ) { i++; swap( array, i, j ); } } // Move the pivot element in the middle of the array swap( array, i + 1, right ); // Return the pivot element index return i + 1; } /** Test Method */ int main( ) { // Initialize input array int input[ ] = { 3, 7, 8, 5, 2, 1, 9, 5, 4 }; // Sort the input array via quicksort sort( input, 0, ARRAY_SIZE - 1 ); // Output the sorted input array int i; for( i = 0; i < ARRAY_SIZE; i++ ) { printf( "%d%s", input[ i ], ( i < ARRAY_SIZE - 1 ) ? ", " : "\n" ); } return 0; } |
P.S. Happy Leap Day! -- February 28, 2012
Hi there! Welcome to my personal blog. My name is Genc (pronounced as Ghentz) and I'm a Software Engineer and Adjunct Professor of Computer Science living and working in Pittsburgh, Pennsylvania. In my blog you'll find posts on algorithms, data structures, programming, sci-fi and whatnot. I hope you find your visit helpful and enjoyable!