This is a 'filtering' problem where all solutions are created with brute force and only the proper solutions are output. The steps are:
The first thought on generating passwords might be to use nested loops. The problem, though, is that the number of nested loops is unknown. The easy way to address that issue is recursion: a function that knows how to add one more letter to the answer -- and which can then call itself for more letters. Of course, that function must know when to stop. A typical recursive function in this context looks like this:
function solve (needed_data, somecounter) { if (somecounter >= somelimit) { /* we are going no deeper in this call tree */ print, save, whatever is needed now that we're "done" return; } /* We are not done yet... do the next thing */ foreach choice (some number of choices) { augment_the_solution_a_bit; solve (needed_data_plus_choice, somecounter+1); } return; }So it remains only to write that recursive routing. My solution is below.
#include <stdio.h> int vowel[26]; char outstring[30]; int l; /* length of output */ int c; /* number of letters */ char letters[26]; /* automatically init'd to all 0's */ FILE *fout; main () { int i, j; FILE *fin = fopen ("passwd.in", "r"); fout = fopen ("passwd.out", "w"); fscanf(fin, "%d %d\n", &l, &c); for (i = 0; i < c; i++) fscanf(fin, "%c ", &letters[i]); letters[c] = '\0'; /* mark the vowels for counting later: */ vowel['a'] = vowel['e'] = vowel['i'] = vowel['o'] = vowel['u'] = 1; /* sort the letters so solutions are generated in alphabetical order */ for (i = 0; i < c -1; i++) for (j = i+1; j < c; j++) if (letters[i] > letters[j]) { int t = letters[i]; letters[i] = letters[j]; letters[j] = t; } makepasswd (0, 0); /* used 0 letters; start with first letter */ exit (0); } makepasswd (i, start) { int j, nvowels, ncons; if (i == l) { ncons = nvowels = 0; for (j = 0; j < l; j++) { /* count vowels/consonants */ if (vowel [outstring[j]]) nvowels++; else ncons++; } if (nvowels < 1) return; /* filter for vowel constraint */ if (ncons < 2) return; /* filter for constraint constraint */ fprintf (fout, "%s\n", outstring); return; } if (start >= c) return; /* too long now */ for (j = start; j < c; j++) { /* add a letter at 'start' */ outstring[i] = letters[j]; makepasswd (i+1, j+1); /* add another letter or finish */ } }