// Task 2: Word Stickers // // C translation #include #include #include #include #include #include #include "args.h" // // bool ismissing = lettermissing( letter, sticker[], nstickers ); // Return true iff letter is missing from all sticker[nstickers]. // Return false otherwise. // bool lettermissing( char letter, char **sticker, int nstickers ) { for( int i=0; i0 ) putchar( ',' ); printf( "%s", stickers[used[i]] ); } putchar( '\n' ); } int minstickers=1000000; int minstickers_used[1024]; // // findall( word, used ); // Given a word, and a numbered list of stickers already used in // used[0..] (ended by a -1 sentinel), // find all combinations of stickers[nstickers] that contain all letters // in word, and track and store the best (minimum) number of stickers // in minstickers, along with the sticker numbers themselves in // minstickers_used[]. // How? the key insight is that each sticker can be used (or not) // whenever it contains any letters in common with the word. So try // both possibilities recursively. // void findall( char *word, int *used ) { // count how many stickers we've currently used int nused; for( nused=0; used[nused] != -1; nused++ ); if( *word == '\0' ) { if( debug ) { printf( "debug: found solution, used = " ); print_stickers( nused, used ); } if( nused < minstickers ) { minstickers = nused; memcpy( minstickers_used, used, nused*sizeof(int) ); if( debug ) { printf( "debug: found new best solution, min stickers = %d, used = ", minstickers ); print_stickers( minstickers, minstickers_used ); } } return; } for( int sn=0; sn\n", newword ); } findall( newword, used ); free( newword ); // now try without the sticker used[--nused] = -1; } } int main( int argc, char **argv ) { int argno = process_flag_n_m_args( "word-stickers", argc, argv, 2, 1000, "word stickerwordlist" ); // lower case all arguments for( int i=argno; i0 ) putchar( ',' ); printf( "%s", stickers[i] ); } putchar( '\n' ); } char missingletters[512]; findmissing( word, stickers, nstickers, missingletters ); if( *missingletters != '\0' ) { printf( "0\n" ); if( debug ) { printf( "No solutions, because letters %s " "are missing from all stickers\n", missingletters ); } exit(0); } char incommon[52]; lettersincommon( word, stickers[0], incommon ); if( debug ) { printf( "debug: letters in common between %s and %s are %s\n", word, stickers[0], incommon ); } minstickers=1000000; minstickers_used[0] = -1; int stickers_used[1024]; stickers_used[0] = -1; findall( word, stickers_used ); printf( "%d\n", minstickers ); if( debug ) { printf( "debug: stickers used: " ); print_stickers( minstickers, minstickers_used ); } return 0; }