why time limit exceeded in uva 100 problem - c

I don't know what is the matter.. it works great when I run on my pc but when I submit in uva OJ it says time limit exceeded please help
Here is my solution:
#include <stdio.h>
int main()
{
long int i,j,c,t,k,u,r;
scanf("%d %d",&i,&j);
printf("%d %d",i,j);
r = 0;
if(i>j){
t = i;
i = j;
j = t;
}
for(k = i; k<=j;k++){
c = 1;
u = k;
while(u>1){
if(u%2 == 0)
u = u/2;
else
u = 3*u+1;
c++;
if(c>=r)
r = c;
}
}
printf (" %d",r);
return 0;
}

The following code, on my ubuntu Linux 14.04 takes about 1 second to run, when invoked via:
./untitled > outfile.txt
so perhaps this could be useful.
Note: this will have to be modified significantly for the euler problem
Note: the problem says "UNDER" 1 million, but this code starts at 1 million rather than starting at 999999
// Longest Collatz sequence
// Problem 14
/*
* criteria
* The following iterative sequence is defined for the set of positive integers:
* n → n/2 (n is even)
* n → 3n + 1 (n is odd)
*
* example:
* Using the rule above and starting with 13, we generate the following sequence:
* 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
* It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms.
* Although it has not been proved yet (Collatz Problem),
* it is thought that all starting numbers finish at 1.
*
* the question:
* Which starting number, under one million, produces the longest chain?
*
* Note:
* Once the chain starts the terms are allowed to go above one million.
*/
#include <stdio.h>
// prototypes
void fastWrite( size_t a );
int main( void )
{
#define MAX_START_VALUE (1000000)
size_t LongestChain = 0;
size_t LongestStartValue = 0;
for( size_t i=MAX_START_VALUE; i; i--)
{
size_t chainLength = 0;
size_t result = i;
// for debug
char buffer[] = "current start value:";
for( size_t j=0; buffer[j]; j++) putchar_unlocked( buffer[j] );
putchar_unlocked( ' ');
fastWrite( i );
// end debug
while( result != 1 )
{
chainLength++;
if( result&1 )
{ // then odd
result = 3*result +1;
}
else
{ // else even
result >>= 1;
}
// for debug
//./fastWrite( result );
// end debug
}
chainLength++;
// for debug
char buffer2[] = "chain length: ";
for( size_t k=0; buffer2[k]; k++) putchar_unlocked( buffer2[k] );
fastWrite( chainLength );
putchar_unlocked( '\n' );
// end debug
if ( chainLength > LongestChain )
{
LongestChain = chainLength;
LongestStartValue = i;
}
}
fastWrite( LongestStartValue );
putchar_unlocked('\n');
//putchar_unlocked('\n');
} // end function: main
inline void fastWrite(size_t a)
{
char snum[20];
//printf( "%s, %lu\n", __func__, a );
int i=0;
do
{
// 48 is numeric character 0
snum[i++] = (char)((a%10)+(size_t)48);
a=a/10;
}while(a>0);
i=i-1; // correction for overincrement from prior 'while' loop
while(i>=0)
{
putchar_unlocked(snum[i--]);
}
putchar_unlocked('\n');
} // end function: fastWrite

Just to be helpful with the time taken:
the following are good ways to speed up the I/O
#include <stdio.h>
void fastRead( size_t *a );
void fastWrite( size_t a );
inline void fastRead(size_t *a)
{
int c=0;
// note: 32 is space character
while (c<33) c=getchar_unlocked();
// initialize result value
*a=0;
// punctuation parens, etc are show stoppers
while (c>47 && c<58)
{
*a = (*a)*10 + (size_t)(c-48);
c=getchar_unlocked();
}
//printf( "%s, value: %lu\n", __func__, *a );
} // end function: fastRead
inline void fastWrite(size_t a)
{
char snum[20];
//printf( "%s, %lu\n", __func__, a );
int i=0;
do
{
// 48 is numeric character 0
snum[i++] = (char)((a%10)+(size_t)48);
a=a/10;
}while(a>0);
i=i-1; // correction for overincrement from prior 'while' loop
while(i>=0)
{
putchar_unlocked(snum[i--]);
}
putchar_unlocked('\n');
} // end function: fastWrite
and output characters via:
putchar_unlocked( char );
and always have a final, at end of each test case, the following line:
putchar_unlocked( '\n' );
to input a string of characters, call the following in a loop until a space or newline is encountered
char = getchar_unlocked()
and a final hint: most such problems are easily solved using size_t numeric values, which allows values to 4gig or more. (same as a unsigned long int)
For the current problem. as soon as a chain is calculated, save the chain, perhaps in an array, so you do not have to calculate it again.
Your could pre-calculate the first 'x' chains, say the first 10 for instance, to help with shortening the execution time.

Related

How does a recursive code determine if palindrome work?

I have a problem question and a snippet code below. The snippet is filled already because I found out the solution but I do not understand why it is like that. Could you help me explain how the codes work?
Problem: Ten tiles each have strings of in between 1 and 4 letters on them (hardcoded in the code below). The goal of this problem is to complete the code below so it counts the number of different orders in which all of the tiles can be placed such that the string they form creates a palindrome (a word that reads the same forwards and backwards). All of main, as well as the function eval which determines if a particular ordering of the tiles forms a palindrome. You may call this function in the function go. Complete the recursive function (named go) to complete the solution.
Snippet code:
#include <stdio.h>
#include <string.h>
#define N 10
#define MAXLEN 5
int go(int perm[], int used[], int k, char tiles[N][MAXLEN]);
int eval(int perm[], char tiles[N][MAXLEN]);
char MYTILES[N][MAXLEN] = {
"at", "ta", "g", "cc", "ccac", "ca", "cc", "gag", "cga", "gc"
};
int
main(void)
{
int perm[N];
int used[N];
for (int i = 0; i < N; i++)
used[i] = 0;
int res = go(perm, used, 0, MYTILES);
printf("Number of tile orderings that create palindromes is %d\n", res);
return 0;
}
int
go(int perm[], int used[], int k, char tiles[N][MAXLEN])
{
if (k == N)
return eval(perm, tiles);
int res = 0;
for (int i = 0; i < N; i++) {
if (used[i])
continue;
used[i] = 1;
perm[k] = i;
res += go(perm, used, k + 1, tiles);
used[i] = 0;
}
return res;
}
int
eval(int perm[], char tiles[N][MAXLEN])
{
char tmp[N * MAXLEN];
int idx = 0;
for (int i = 0; i < N; i++) {
int len = strlen(tiles[perm[i]]);
for (int j = 0; j < len; j++)
tmp[idx++] = tiles[perm[i]][j];
}
tmp[idx] = '\0';
for (int i = 0; i < idx / 2; i++)
if (tmp[i] != tmp[idx - 1 - i])
return 0;
return 1;
}
Thank you. I appreciate all help!!
To understand this code, add the following line to the start of eval():
for( int j = 0; j < N; j++ ) printf( "%d ", perm[j] ); putchar('\n');
The for() loop in go() causes a recursion that is 10 levels deep, ultimately generating 10! (~3.6 million) permutations of the 10 indices from 0 to 9. In sequence, each of those permutations is used to concatenate the 'tokens' (the short ACTG variations) into a single string that is then tested for being palindromic by `eval()'
This is called a "brute force" search through the possibility space.
Below I've revised the code to be slightly more compact, adding two "printf debugging" lines (marked "/**/") that report what the program is doing. You'll need some patience if you wish to watch millions of permutations of 0 to 9 scroll by, or simply comment out that line and recompile. I also shuffled things around and made the two interesting arrays global instead of "whacking the stack" by passing them up/down the recursion. Less code is better. This program is "single purpose". The clarity gained justifies using global variables in this instance, imho.
More interesting is the additional puts() line that reports the palindromic sequences.
#include <stdio.h>
#include <string.h>
#define N 10
#define MAXLEN 5
char MYTILES[N][MAXLEN] = { "AT","TA","G","CC","CCAC","CA","CC","GAG","CGA","GC" };
int perm[N], used[N] = { 0 };
int go( int k ) {
if (k == N) {
// At extent of recursion here.
/**/ for( int j = 0; j < k; j++ ) printf( "%d ", perm[j] ); putchar('\n');
// Make a string in this sequence
char tmp[N*MAXLEN] = {0};
for( int i = 0; i < N; i++ )
strcat( tmp, MYTILES[ perm[ i ] ] );
// Test string for being palidromic
for( int l = 0, r = strlen( tmp ) - 1; l <= r; l++, r-- )
if( tmp[l] != tmp[r] )
return 0; // Not palidrome
/**/ puts( tmp );
return 1; // Is palidrome
}
// recursively generate permutations here
int res = 0;
for( int i = 0; i < N; i++ )
if( !used[i] ) {
used[i] = 1;
perm[k] = i;
res += go( k+1 );
used[i] = 0;
}
return res;
}
int main( void ) {
printf( "Palindromic tile orderings: %d\n", go( 0 ) );
return 0;
}
An immediate 'speed-up' would be to test that the first letter of the 0th string to be permuted matches the last letter of the 9th string... Don't bother concatenating if a palindrome is impossible from the get-go. Other optimisations are left as an exercise for the reader...
BTW: It's okay to make a copy of code and add your own print statements so that the program reports what it is doing when... Or, you could single-step through a debugger...
UPDATE
Having added a preliminary generation of a 10x10 matrix to 'gate' the workload of generating strings to be checked as palindromic, with the 10 OP supplied strings, it turns out that 72% of those operations were doomed to fail from the start. Of the 3.6 million "brute force" attempts, a quick reference to this pre-generated matrix prevented about 2.6 million of them.
It's worthwhile trying to make code efficient.
UPDATE #2:
Bothered that there was still a lot of 'fat' in the execution after trying to improve on the "brute force" in a simple way, I've redone some of the code.
Using a few extra global variables (the state of processing), the following now does some "preparation" in main(), then enters the recursion. In this version, once the string being assembled from fragments is over half complete (in length), it is checked from the "middle out" if it qualifies as being palindromic. If so, each appended fragment causes a re-test. If the string would never become a palindrome, the recursion 'backs-up' and tries another 'flavour' of permutation. This trims the possibility space immensely (and really speeds up the execution.)
char *Tiles[] = { "AT","TA","G","CC","CCAC","CA","CC","GAG","CGA","GC" };
const int nTiles = sizeof Tiles/sizeof Tiles[0];
int used[ nTiles ];
char buildBuf[ 1024 ], *cntrL, *cntrR; // A big buffer and 2 pointers.
int fullLen;
int cntTested, goCalls; // some counters to report iterations
uint32_t factorial( uint32_t n ) { // calc n! (max 12! to fit uint32_t)
uint32_t f = 1;
while( n ) f *= n--;
return f;
}
int hope() { // center outward testing for palindromic characteristics
int i;
for( i = 0; cntrL[ 0 - i ] == cntrR[ 0 + i ]; i++ ) ; // looping
return cntrR[ 0 + i ] == '\0';
}
int go( int k ) {
goCalls++;
if( k == nTiles ) { // at full extent of recursion here
// test string being palindromic (from ends toward middle for fun)
cntTested++;
for( int l = 0, r = fullLen - 1; l <= r; l++, r-- )
if( buildBuf[l] != buildBuf[r] )
return 0; // Not palindrome
/**/ puts( buildBuf );
return 1; // Is palindrome
}
// recursively generate permutations here
// instead of building from sequence of indices
// this builds the (global) sequence string right here
int res = 0;
char *at = buildBuf + strlen( buildBuf );
for( int i = 0; i < nTiles; i++ )
if( !used[i] ) {
strcpy( at, Tiles[ i ] );
// keep recursing until > half assembled and hope persists
if( at < cntrL || hope() ) {
used[i] = 1;
res += go( k+1 ); // go 'deeper' in the recursion
used[i] = 0;
}
}
return res;
}
int main( void ) {
for( int i = 0; i < nTiles; i++ )
fullLen += strlen( Tiles[i] );
if( fullLen % 2 == 0 ) // even count
cntrR = (cntrL = buildBuf + fullLen/2 - 1) + 1; // 24 ==> 0-11 & 12->23
else
cntrR = cntrL = buildBuf + fullLen/2; // 25 ==> 0-12 & 12->24
printf( "Palindromic tile orderings: %d\n", go( 0 ) );
printf( "Potential: %d\n", factorial( nTiles ) );
printf( "Calls to go(): %d\n", goCalls );
printf( "Actual: %d\n", cntTested );
return 0;
}
ATCCACGAGCCGCCGAGCACCTA
ATCCACGAGCCGCCGAGCACCTA
ATCCACGCCGAGAGCCGCACCTA
ATCCACGCCGAGAGCCGCACCTA
ATCACCGAGCCGCCGAGCCACTA
ATCACCGCCGAGAGCCGCCACTA
ATCACCGAGCCGCCGAGCCACTA
ATCACCGCCGAGAGCCGCCACTA
TACCACGAGCCGCCGAGCACCAT
TACCACGAGCCGCCGAGCACCAT
TACCACGCCGAGAGCCGCACCAT
TACCACGCCGAGAGCCGCACCAT
TACACCGAGCCGCCGAGCCACAT
TACACCGCCGAGAGCCGCCACAT
TACACCGAGCCGCCGAGCCACAT
TACACCGCCGAGAGCCGCCACAT
CCACATGAGCCGCCGAGTACACC
CCACATGAGCCGCCGAGTACACC
CCACATGCCGAGAGCCGTACACC
CCACATGCCGAGAGCCGTACACC
CCACTAGAGCCGCCGAGATCACC
CCACTAGAGCCGCCGAGATCACC
CCACTAGCCGAGAGCCGATCACC
CCACTAGCCGAGAGCCGATCACC
CACCATGAGCCGCCGAGTACCAC
CACCATGCCGAGAGCCGTACCAC
CACCTAGAGCCGCCGAGATCCAC
CACCTAGCCGAGAGCCGATCCAC
CACCATGAGCCGCCGAGTACCAC
CACCATGCCGAGAGCCGTACCAC
CACCTAGAGCCGCCGAGATCCAC
CACCTAGCCGAGAGCCGATCCAC
Palindromic tile orderings: 32
Potential: 3628800
Calls to go(): 96712
Actual: 32
UPDATE #3 (having fun)
When there's too much code, and an inefficient algorithm, it's easy to get lost and struggle to work out what is happening.
Below produces exactly the same results as above, but shaves a few more operations from the execution. In short, go() is called recursively until at least 1/2 of the candidate string has been built-up. At that point, hope() is asked to evaluate the string "from the middle, out." As long as the conditions of being palindromic (from the centre, outward) are being met, that evaluation is repeated as the string grows (via recursion) toward its fullest extent. It is the "bailing-out early" that makes this version far more efficient than the OP version.
One further 'refinement' is that the bottom of the recursion is found without an extra call to \0. Once one has the concepts of recursion and permutation, this should all be straight forward...
char *Tiles[] = { "AT", "TA", "G", "CC", "CCAC", "CA", "CC", "GAG", "CGA", "GC" };
const int nTiles = sizeof Tiles/sizeof Tiles[0];
int used[ nTiles ];
char out[ 1024 ], *cntrL, *cntrR;
int hope() { // center outward testing for palidromic characteristics
char *pL = cntrL, *pR = cntrR;
while( *pL == *pR ) pL--, pR++;
return *pR == '\0';
}
int go( int k ) {
int res = 0;
char *at = out + strlen( out );
for( size_t i = 0; i < nTiles; i++ )
if( !used[i] ) {
strcpy( at, Tiles[ i ] );
if( at >= cntrL && !hope() ) // abandon this string?
continue;
if( k+1 == nTiles ) { // At extent of recursion here.
puts( out );
return 1;
}
used[i] = 1, res += go( k+1 ), used[i] = 0;
}
return res;
}
int main( void ) {
int need = 0;
for( size_t i = 0; i < nTiles; i++ )
need += strlen( Tiles[ i ] );
cntrL = cntrR = out + need/2; // odd eg: 25 ==> 0-12 & 12->24
cntrL -= (need % 2 == 0 ); // but, if even eg: 24 ==> 0-11 & 12->23
printf( "Palindromic tile orderings: %d\n", go( 0 ) );
return 0;
}

How to printf vertically?

This is my code. My point is to take string input and count how many of each letter occurs
#include <stdio.h>
#include <ctype.h>
int main()
{
int c1;
int a=0, b=0, c=0, d=0, e=0, f=0, g=0, h=0, i=0, j=0, k=0, l=0, m=0, n=0, o=0, p=0, q=0, r=0, s=0, t=0, u=0, v=0, w=0, x=0 , y=0, z=0;
while (( c1=getchar()) != EOF)
if (isalpha(tolower(c1)) != 0) {
if (tolower(c1) == 97) { // Character = 'a'
a += 1;
}
else if (tolower(c1) == 98) { // Character = 'b'
b += 1;
}
else if (tolower(c1) == 99) { // Character = 'c'
c += 1;
}
.
.
.
}
return 0;
}
Next I want to printf result in vertical. Could you give me some hints. For example,
input: ABC---Ddhhh
output:
*
* *
**** *
abcdefghijklmnopqrstuvwxyz
While it may be a struggle learning, it's important to spend time learning and not simply copy/pasting lines of code to have a big program. The best code is the briefest code that achieves the objective.
As others have said, the contiguous alphabet should cause you to use a contiguous array of counters, not individual variables. (One typo and your results will be wrong.) Nesting isalpha(tolower(c)) is not needed. And, you've shown how you might count, but not shown code that would output the desired results.
This is for you to study, learn and grow as a coder.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// Try to write functions; blocks of code that do what you want in compartments
void countAndGraph( char *str ) {
int max = 0, cnt[26] = { 0 }; // initialises 'max' and 26 counters
for( char *p = str; *p; p++ ) // as long as there is a character
if( isalpha( *p ) ) { // if it is alphabetic
int i = tolower( *p ) - 'a'; // convert ASCII character to value 0-25
if( ++cnt[ i ] > max ) // increment the right counter and test against max
max = cnt[ i ]; // 'max' - the ceiling - keeps getting higher
}
for( ; max; max-- ) { // lower the ceiling
for( int i = 0; i < 26; i++ ) // for 26 alphabetic characters
putchar( " *"[cnt[i]>=max] ); // output ' ' or '*' if count at/above ceiling
putchar( '\n' ); // newline
}
puts( "abcdefghijklmnopqrstuvwxyz" ); // reference alphabet string
puts( str ); // the string that's been analysed
puts( "" );
}
int main() {
char *tst[] = { // three test strings to demonstrate
"The quick brown fox jumps over the lazy dogs",
"Sally sells seashells by the sea shore",
"I wish I was what I was when I wished I was what I am now",
};
const size_t nTst = sizeof tst/sizeof tst[0];
for( size_t i = 0; i < nTst; i++ ) // count and graph each of the strings
countAndGraph( tst[i] );
return 0;
}
*
* *
* * * ****
**************************
abcdefghijklmnopqrstuvwxyz
The quick brown fox jumps over the lazy dogs
*
*
* * *
* * *
* * *
* * * * *
* * * * * *
** * * * * *** *
abcdefghijklmnopqrstuvwxyz
Sally sells seashells by the sea shore
*
* *
* *
* * *
* ** * *
* ** * *
* ** * *
* * ** * ** *
* ** ** *** ** *
abcdefghijklmnopqrstuvwxyz
I wish I was what I was when I wished I was what I am now
Now that you have this code, an exercise would be to print the bar graph in ascending/descending order. Don't stop with this one version; push it to a new educational experience.
*
*
*
*
**
***
****
*********
*************
**************
****************
*****************
******************
fzcxqpjkuvywnbmdgrloshiate
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe:
All mimsy were the borogoves,
And the mome raths outgrabe.
Any time you have more than one or two variables that do the same thing, it is time to use a data structure; in this case, an array. You will want something like
int counts[26];
instead of twenty six different variables, and only have one statement instead of 26 different if clauses. Then you can say
counts[lower(c1) - 97]
instead of a, b... z (after checking that lower(c1) is one of the letters).
The way to print the output is based on these insights:
The number of lines above the alphabet is the highest number in counts (let's call it maxcount). It would be 3 in your example.
For each line, there is a * if that letter's count is at least maxcount - line (i.e. in 0th line, there is a * if there is at least 3 - 0 counts of that character), otherwise there's a space.
I think you can just print one at a time.
#include <stdio.h>
#include <ctype.h>
int main()
{
int c1;
int a=0, b=0, c=0, d=0, e=0, f=0, g=0, h=0, i=0, j=0, k=0, l=0, m=0, n=0, o=0, p=0, q=0, r=0, s=0, t=0, u=0, v=0, w=0, x=0 , y=0, z=0;
// I might do an array here, so you can loop through later.
int letters[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
while (( c1=getchar()) != EOF) {
if (isalpha(tolower(c1)) != 0) {
if (tolower(c1) == 97) { // Character = 'a'
a += 1;
letters[0]++;
}
else if (tolower(c1) == 98) { // Character = 'b'
b += 1;
letters[1]++;
}
else if (tolower(c1) == 99) { // Character = 'c'
c += 1;
letters[2]++;
}
.
.
.
}
}
int ii;
for (ii = 0; ii < 26; ii++) {
printf("%d\n", letters[ii]);
}
return 0;
}

for loop, how to print integers/string two by two

This drives me crazy because it seems so easy, but I cannot figure it out.
I have a for-loop and it prints out words what I have entered. This version of for-loop prints it out this way:
"car - wheel - bike - handlebar",
instead I want to print it this way:
"car - wheel
bike - handlebar"
for(int i=0;i<numberOfWords;i++)
printf("%s - ",words[i]);
printf("\n");
EDIT: It prints out from an array. I have a function that takes in words and stores in an array. Then I want to pair two words side by side.
for(int i=0;i<numberOfWords;i++) }
printf("%s",words[i]);
if(i%2) printf("\n");
else printf(" - ");
}
printf("\n");
Explanation. Prints every word. And if i is odd (so after printing words[1] and words[3]) print a newline. Otherwise, print a - since another word will be printed on that line.
If the total number of words might not be even (of multiple of whatever number of words per line you want, since this code can be adapted for other than 2), then a specific code should be written for the last word. For example, adding
if(i==numberOfWords-1) break after the first printf, so that last loop iteration does not print any separator - nor newline.
As other answers have pointed out, some test of 'parity' of the loop counter will select between outputting a "spacer" or a "newline" after each word is printed. Some of those methods are arcane, and some of those methods will not properly handle the case of an odd number of words.
If you are going to make the effort to code this algorithm, it should be as capable as possible. The following works for "pairs", but it seems more lyrical to show it working for "triplets" of sequential words in an array. (Omitting checks for negative numbers and empty strings. Those are not a few of my favourite things.)
#include <stdio.h>
#include <string.h>
void out( char *w[], size_t n, size_t per ) {
// output sequential words (array elements) several per line.
for( size_t r = 0; r < n; r += per ) {
char *prfx = ""; // prefix separator for words...
for( size_t c = r; c < r+per && c < n; c++ ) {
printf( "%s%s", prfx, w[c] );
prfx = " - "; // subsequent words prefixed by this string
}
putchar( '\n' );
}
putchar( '\n' );
}
int approved( char *w ) { // suppress adding some words to the array
char *stop[] = { "and", "up", "are", "of" }; // "stopwords"
for( int i = 0; i < sizeof stop/sizeof stop[0]; i++ )
if( strcmp( w, stop[i] ) == 0 ) return 0;
return 1;
}
int main() {
char meat[] =
"Raindrops on roses and whiskers on kittens "
"Bright copper kettles and warm woolen mittens "
"Brown paper packages tied up with strings "
"These are a few of my favourite things";
char *words[100]; // sufficient
size_t nWords = 0;
// Break apart the meat into individual (approved) words
for( char *p = meat; (p = strtok( p, " \n") ) != NULL; p = NULL )
if( approved( p ) )
words[ nWords++ ] = p;
// out( words, nWords, 2 ); // now, output pairs
out( words, nWords, 3 ); // or output triplets
// out( words, nWords, 4 ); // or output quadruplets
return 0;
}
Raindrops - on - roses
whiskers - on - kittens
Bright - copper - kettles
warm - woolen - mittens
Brown - paper - packages
tied - with - strings
These - a - few
my - favourite - things
Slow day... Instead of multiple calls to strcmp() to approve (or not) certain words, there's this: (presumes that any word is <= 30 characters long.)
int approved( char *w ) {
char *stop = " and up a of ", buf[1+30+1=1], *p = buf+1;
while( (*p = *w) != '\0' ) p++, w++;
buf[0] = p[0] = ' '; p[1] = '\0';
return strstr( stop, buf ) == NULL;
}
It seems you mean the following
for ( int i = 0; i < numberOfWords; i++ )
{
if ( i % 2 == 0 )
{
printf( "\"%s - ", words[i] );
}
else
{
printf( "%s\"\n", words[i] );
}
}
The output will be
"car - wheel"
"bike - handlebar"
If you have an even number of words:
for (int i = 0; i < numberOfWords; i++)
printf("%s%s", words[i], i % 2 ? "\n" : " - ");
If you have an even or odd number of words:
int i = 0;
while (i < numberOfWords)
{
printf("%s", words[i]);
printf(i++ % 2 || i == numberOfWords ? "\n" : " - ");
}
My minimum working example uses command line parameters (argc, argv) to provide the test case array of strings, but the main difference to the other examples I have seen here is that this iterates over that array in steps of two.
It prints all pairs of words, and then catches and handles the single leftover array item in case the array contains an odd number of items.
int main(const int argc, const char *const argv[]) {
for (int i=0; i<argc; i+=2) {
if ((i+1)<argc) {
printf("word pair: %s - %s\n", argv[i], argv[i+1]);
} else {
printf("leftover word: %s\n", argv[i]);
}
}
return 0;
}

K & R section 1.10 example program skipping 'printf()' line

I'm learning C through K & R. I have reached to section 1.10 External Variables and Scope.
In that section they have written and explained program regarding external variable and their scope. I typed that code myself and tried to execute it. It does not show any run time or compile time error. However, it does not print any output also, which should be longest line from given input. I did debug the program and I found that program is skipping 'printf()' statement. I tried both on sublime text 2 + gcc and Turbo c++ v4.5, but still I don't get an output. I'm using Windows xpsp 3.
Here is my code :
#include<stdio.h>
/* program to pring longest line using external variables */
#define MAXSIZE 1000
int max;
char line[ MAXSIZE ];
char longest[ MAXSIZE ];
int getline( void );
void copy( void );
main()
{
int len;
extern int max;
extern char longest[];
max = 0;
while( ( len = getline() ) > 0 )
{
if( len > max )
{
len = max;
copy();
}
}
if( max > 0)
printf("\n%s\n", longest); /* This line is skipped */
return 0;
}
int getline( void ) /* Check if there is line */
{
int c, i;
extern char line[];
for( i = 0; i < MAXSIZE -1 && ( c = getchar()) != EOF && c != '\n'; ++i )
line[ i ] = c;
if( c == '\n' )
{
line[ i ] = c;
++i;
}
line[ i ] = '\0';
return i;
}
void copy( void ) /* copy current line to longest if it is long */
{
int i = 0;
extern char line[];
extern char longest[];
while( ( longest[ i ] = line[ i ] ) != '\0' )
++i;
}
So my questions are :
Why is this happening?
What should I do so that program won't skip 'printf()' and will print an output?
Please help. Thank you.
The intent of this code is to start max at zero then, for every line longer than the current max, copy the line and update max to the longer value:
max = 0;
while( ( len = getline() ) > 0 )
{
if( len > max )
{
len = max;
copy();
}
}
However, the line that's supposed to update max is assigning in the wrong direction. It sets len to be the current value of max and never updates max at all. This is something that would have been obvious with a bit of "Debugging 101", placing the following line after the call to copy():
printf ("New long line, len = %d, str = '%s'\n", max, longest);
That fact that you would never have seen the length changing would have (hopefully) narrowed down the problem pretty fast. The line in question should instead be:
max = len;

How would I use recursion to generate all possibilities?

Lets say if the input is 4 then the output should be all possible 4 letter words with letters a to f. All the way from aaaa to ffff. How would I do this through the use of recursion?
My apologies for not including my attempt at the problem in my initial question. And some for you are wondering why I am using recursion instead of using a simpler method (such as a for loop for example) and the reason for this is that my prof wants us to use a for loop to solve this problem.
Here is my attempt at doing this:
void allPossiblilities(int n)
{
char*result;
if(Done(result))/*since the last possibility will be all f I am using that as my base case*/
{
printf("%s",result);
return;
}
/*This is where the recursive part should go but I am totally lost as to what it should be*/
}
bool Done(result)/*This function just returns true if all the array's index are f*/
{
int i;
bool a=true;
for(i=0;i<=n-1;i++)
if(result[i]!='f')
a=false;
}
return a;
}
I will give you a hint, to make you think:
How many possibilities are for 4 digits and 10 possible numbers (0-9) base^digits = 10^4 = 10000 possible outputs 0000-9999, in your case they will base = 6 (A-F) and exp = 4 (4 positions) 6^4 = 1296 combinations.
How are recursive functions made?
They have 2 steps:
Basic Step: it's the criteria or the condition when the function doesn't call itself ( the final condition).
Recursive Step: It's the criteria or the condition when the function calls itself, and the result of it should be nearer to the Basic Step.
Example the famous factorial function, the basic step is the return of 1, and the recursive step is the second one.
PD: I am trying to make you analyze the problem and get the solution by yourself, and giving you some tools.
The code:
#include <stdio.h>
#include <stdlib.h>
void recurs( int * s );
void print( int * s );
int main( void )
{
int a[] = { 0, 0, 0, 0 };
print( a );
recurs( a );
}
void recurs( int * s )
{
int i;
/*Basic Case*/
if( s[ 3 ] == 5 && s[ 2 ] == 5 && s[ 1 ] == 5 && s[ 0 ] == 5 ){
print( s );
printf( "\nAccomplisshed!\n" );
}
else{
s[ 0 ] += 1;
for( i = 0; i < 3; i++ ){
if( s[ i ] == 6 ){
s[ i ] = 0;
s[ i + 1 ] += 1;
}
}
print( s );
recurs( s );
}
}
/* This only prints. */
void print( int * s )
{
int i;
printf( " " );
for( i = 3; i >= 0; i-- ){
printf( "%c", ( s[ i ] + 65 ) );
}
}
Part of the output:
int inc(char *c,char begin, char end){
if(c[0]==0) return 0;
if(c[0] == end){ // This make the algorithm to stop at char 'f'
c[0]=begin; // but you can put any other char
return inc(c+sizeof(char));
}
c[0]++;
return 1;
}
int all(int a, int n,char begin, char end){
int i,j;
char *c = malloc((n+1)*sizeof(char));
for(i=a;i<=n;i++){
for(j=0;j<i;j++) c[j]=begin;
c[i]=0;
do {
printf("%s\n",c);
} while(inc(c,begin,end));
}
free(c);
}
int main(void){
all(4,4,'a','f'); // Generates from 4 letters words starting in aaaa to ffff
}
If you call all(1,4,'a','f') it will generate a,b,c,d...ffff
If you call all(4,4,'a','z') it will generate from aaaa to zzzz
Just for the hell of using hex notation to generate a-f characters:
#include <stdio.h>
int v(unsigned char* i, unsigned short n) {
return !n || (*i>=0xa0 && (*i&0xf)>=10 && v(i+1,n-1));
}
void f(unsigned short i) {
if(i) f(i-1);
if(v((char*)&i,2)) printf("%x\n",i);
}
int main(){ f((1<<16)-1);}

Resources