Hatena::Groupcprogramming

C Study Diary

2008-12-11

c4ex2atof.cpp

16:44

Extend atof to handle scientific notation of the form 123.45e-6 where a floating-point number may be followed by e or E and an optionally signed exponent.

Question: if set ratio to float, the result is not accurate. Won't double*float be converted to double?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 10

double atof(char* s){
	
	double number=0.0, ratio=1.0, ten=10.0;
	int i=0, non_num=0, point=-1, sign=1, psign=1, e=0, exp=0, digit=0;

	while(s[i]!='\0'){
		switch(s[i]){
			case ' ': non_num++; break;
			case '.': point=i; break;
			case '-': if(e) psign=-1; else {sign=-1; non_num++;} break;
			case '+': if(e) psign=1; else {sign=1; non_num++;} break;
			case 'e': e=1; break;
			case 'E': e=1; break;
			default: if(e) exp=exp*10+(s[i]-'0'); else { number=number*ten+(s[i]-'0'); digit++; }
		}
		i++;
	}
	/* negtive exp sign or exp =0 => ratio=0.1 ; positive exp sign => ratio = 10.0  */
	if(psign<0 || exp==0) ratio = 1/ten;
	else ratio = ten;
	
	/* if point appears */
	if(point!=-1){
		for(i=0;i<abs(psign*exp-(digit-(point-non_num)));i++)
			number = number * ratio; 
	}
	/* no point */	
	else {
		for(i=0;i<exp;i++)
			number = number * ratio; 
	}

	return number*sign;
	
}

int main(){
	
	char s1[]="-123e5";
	char s2[]="123.12E-5";	
	char s3[]="   123.E";
	char s4[]="   -.12312235";
	char s[MAX];
	printf("input a float number, eg, 123.11e+5\n");
	scanf("%s",&s);
	printf("%s->%.10g\n",s,atof(s));
	printf("Preset test numbers:\n");
	printf("%s->%.10g\n",s1,atof(s1));
	printf("%s->%.10g\n",s2,atof(s2));
	printf("%s->%.10g\n",s3,atof(s3));
	printf("%s->%.10g\n",s4,atof(s4)); 	
}	

Run:

$ ./c4ex2atof.exe
input a float number, eg, 123.11e+5
0e10
0e10->0
Preset test numbers:
-123e5->-12300000
123.12E-5->0.0012312
   123.E->123
   -.12312235->-0.12312235

zero_count.cpp

12:07

To count zeros in a certain range, say 1-100000.

Question: How to deal with number larger than 10^9? Is it a good idea to use double instead?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* direct count */
int zero_count(unsigned long s, unsigned long n)
{	
	int count=0;
	unsigned long i, t;

	for(i=s;i<=n;i++)
	{
		t=i;
		do{
			if(t%10==0) count++;
			
		}while((t=t/10)>0);			

	}
	return count;
}

/* f(n), count from 1 to n, not as flexible as the first function */
int zero_count_speedy(unsigned long n){

	int	count = 0, subcount=0;
	unsigned long begin, end;
	
	if(n==10) {
		count=1;
		return count;
	}else{	
	/* f(n) = f(n/10) + zero_num[(n/10+1)~2*n/10]*9+1 , eg, f(1000) = f(100) + zero_num[101-200]*9+1 */
		begin=n/10+1;
		end=2*n/10;
		subcount=zero_count(begin,end);
		count+=zero_count_speedy(n/10)+subcount*9+1;

	}
	return count;

}


int main(){
	unsigned long n, s;
	int count;
	clock_t sclock,eclock;
	
	printf("input range(<10^10):(eg, 1-1000)\n");
	scanf("%lu-%lu",&s,&n);
	printf("count zero in %lu-%lu\n",s,n);

	sclock=clock();
	count=zero_count(s,n);
	eclock=clock();
	printf("Total number of zeros within %d-%d: %d\nTime used: %fseconds\n", s, n, count, (double)(eclock-sclock)/CLOCKS_PER_SEC);	

	sclock=clock();
	count=zero_count_speedy(n);
	eclock=clock();
	printf("Total number of zeros within 1-%d: %d\nTime used: %fseconds\n", n, count, (double)(eclock-sclock)/CLOCKS_PER_SEC);	

	return 0;
	
}

Run:

$ ./zero_count.exe
input range(<10^10):(eg, 1-1000)
1-1000
count zero in 1-1000
Total number of zeros within 1-1000: 192
Time used: 0.000000seconds
Total number of zeros within 1-1000: 192
Time used: 0.000000seconds

$ ./zero_count.exe
input range(<10^10):(eg, 1-1000)
1-1000000000
count zero in 1-1000000000
Total number of zeros within 1-1000000000: 788888898
Time used: 68.297000seconds
Total number of zeros within 1-1000000000: 788888898
Time used: 7.438000seconds

lymanlyman2008/12/11 18:21for larger int, you can try unsigned long long int(search int64 or so, this might be different among platforms), which is 64 bit. for science calculate (to say, no precision limitation), c is not a good choice unless introduce external lib (if exists)

annancyannancy2008/12/11 18:34Thank you!!

2008-12-10

c4ex1_sttrindex.cpp

15:36

Write the function strrindex(s,t) , which returns the position of the rightmost occurrence of t in s , or -1 if there is none.

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
 
int strrindex(char* s, char* t){
  
	int i=0, j, k, pos=-1;
	while(s[i]!='\0'){
		j=0;
		/* when s[i] ==t[0] */
		if(s[i]==t[j]){
				k=i;
				/* compare the following */
				while(t[j]!='\0' && s[k]!='\0' && s[++k]==t[++j]){
				}
				if(t[j]=='\0') pos = k-strlen(t);
		}
		i++;
	}
	return pos;
  
}


int main(void){

	char s1[]="Write the function strrindex(s,t) , which returns the position of the  rightmost occurrence of t in s , or -1 if there is none. ";
	char s2[]="the";
	int pos;
	pos=strrindex(s1,s2);
	printf("Search string t: %s\nIn sentence s: %s\n",s2,s1);
	printf("The rightmost occurence of t in s is at pos%d",pos);
	
	return 0;
}

Run:

$ ./c4ex1_sttrindex.exe
Search string t: the
In sentence s: Write the function strrindex(s,t) , which returns the position of the  rightmost occurrence of t in s , o
r -1 if there is none.
The rightmost occurence of t in s is at pos113

c3ex6_itoa_w.cpp

13:19

In a two's complement number representation, our version of itoa does not handle the largest negative number, that is, the value of n equal to -(2 to the power (wordsize - 1)) . Explain why not. Modify it to print that value correctly regardless of the machine on which it runs.

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <limits.h> 

#define MAX 20
 
void reverse(char s[]){
	
	int i, j;
	char c;
	
	for(i=0,j=strlen(s)-1;i<j;i++, j--){
		c=s[i];
		s[i]=s[j];
		s[j]=c;
	}	

}
 
void itoa(int n, char s[], int w){
 
	int i=0, sign;
	
	sign=n;
	
	do{
		s[i++]=abs(n%10)+'0';	 
	}while((abs(n/=10))>0);		 
	
	if(sign<0) s[i++] ='-';
	while(i<w) {
		s[i++]=' ';
	} 
	s[i]='\0';
	reverse(s);
}


int main(void){

	int a;
	char b[MAX];
	for(a=9;a<10000;a=a*10){
		itoa(a,b,8);
		printf("itoa(%d)=%s\n",a,b);
	}
	return 0;
}

Run:

$ ./c3ex6_itoa_new.exe
itoa(9)=       9
itoa(90)=      90
itoa(900)=     900
itoa(9000)=    9000

c3ex4_itob.cpp

12:16

Write the function itob(n,s,b) that converts the integer n into a base b character representation in the string s . In particular, itob(n,s,16) formats n as a hexadecimal integer in s .

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <limits.h> 

#define MAX 50
 
void reverse(char s[]){
	
	int i, j;
	char c;
	
	for(i=0,j=strlen(s)-1;i<j;i++, j--){
		c=s[i];
		s[i]=s[j];
		s[j]=c;
	}	

}
 
int itob(int n, char s[], int b){
 
	int i=0, sign;
	char digit[37]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	if( b<=1 || b>36) {
		printf("Base %d is not supported. \n",b);
		return -1;
	}	
	sign=n;	
	do{						/* b is the base to convert */
		s[i++]=digit[abs(n%b)];			/* convert to right digit  */
	}while((abs(n/=b))>0);				/* use abs() to get the absolute value */
	
	if(sign<0) s[i++] ='-';
	s[i]='\0';
	reverse(s);
	return 0;
}


int main(void){

	int a, n;
	char buff[MAX];
	for(a=INT_MIN;a<INT_MIN+2;a++){
		for(n=0;n<=36;n+=2){
			if(itob(a,buff,n)!=-1) printf("itob(%d,s,%d)=%s\n",a,n,buff);
		}	
	}
	return 0;
}

Run:

$ ./c3ex5_itob.exe
Base 0 is not supported.
itob(-2147483648,s,2)=-10000000000000000000000000000000
itob(-2147483648,s,4)=-2000000000000000
itob(-2147483648,s,6)=-553032005532
itob(-2147483648,s,8)=-20000000000
itob(-2147483648,s,10)=-2147483648
itob(-2147483648,s,12)=-4BB2308A8
itob(-2147483648,s,14)=-1652CA932
itob(-2147483648,s,16)=-80000000
itob(-2147483648,s,18)=-3928G3H2
itob(-2147483648,s,20)=-1DB1F928
itob(-2147483648,s,22)=-IKF5BF2
itob(-2147483648,s,24)=-B5GGE58
itob(-2147483648,s,26)=-6OJ8IOO
itob(-2147483648,s,28)=-4CLM98G
itob(-2147483648,s,30)=-2SB6CS8
itob(-2147483648,s,32)=-2000000
itob(-2147483648,s,34)=-1D8XQRQ
itob(-2147483648,s,36)=-ZIK0ZK
Base 0 is not supported.
itob(-2147483647,s,2)=-1111111111111111111111111111111
itob(-2147483647,s,4)=-1333333333333333
itob(-2147483647,s,6)=-553032005531
itob(-2147483647,s,8)=-17777777777
itob(-2147483647,s,10)=-2147483647
itob(-2147483647,s,12)=-4BB2308A7
itob(-2147483647,s,14)=-1652CA931
itob(-2147483647,s,16)=-7FFFFFFF
itob(-2147483647,s,18)=-3928G3H1
itob(-2147483647,s,20)=-1DB1F927
itob(-2147483647,s,22)=-IKF5BF1
itob(-2147483647,s,24)=-B5GGE57
itob(-2147483647,s,26)=-6OJ8ION
itob(-2147483647,s,28)=-4CLM98F
itob(-2147483647,s,30)=-2SB6CS7
itob(-2147483647,s,32)=-1VVVVVV
itob(-2147483647,s,34)=-1D8XQRP
itob(-2147483647,s,36)=-ZIK0ZJ

c3ex4_itoa.cpp

12:16

In a two's complement number representation, our version of itoa does not handle the largest negative number, that is, the value of n equal to -(2 to the power (wordsize - 1)) . Explain why not. Modify it to print that value correctly regardless of the machine on which it runs.


#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <limits.h> 

#define MAX 20
 
void reverse(char s[]){
	
	int i, j;
	char c;
	
	for(i=0,j=strlen(s)-1;i<j;i++, j--){
		c=s[i];
		s[i]=s[j];
		s[j]=c;
	}	

}
 
void itoa(int n, char s[]){
 
	int i=0, sign;
	
	sign=n;
	
	do{
		s[i++]=abs(n%10)+'0';		/* digit + '0' -> char,  char - '0' -> digit */
	}while((abs(n/=10))>0);			/* use abs() to get the absolute value */
	
	if(sign<0) s[i++] ='-';
	s[i]='\0';
	reverse(s);
}


int main(void){

	int a = INT_MIN;
	char b[MAX];
	itoa(a,b);
	printf("itoa(%d)=%s\n",a,b);

	return 0;
}

Run:

$ ./c3ex4_itoa.exe
itoa(-2147483648)=-2147483648

2008-12-09

c3ex3_expand.cpp

13:10

Write a function expand(s1,s2) that expands shorthand notations like a-z in the string s1 into the equivalent complete list abc...xyz in s2 . Allow for letters of either case and digits, and be prepared to handle cases like a-b-c and a-z0-9 and -a-z . Arrange that a leading or trailing - is taken literally.


#include <stdio.h>
#include <string.h> 

#define MAX 500
 
void expand(char* s1, char* s2){
 
	int i=0, j=0, t, schar, echar;
	while(s1[i]!='\0'){
		
		if(s1[i]=='-'){
			if(i!=0 && s1[i+1]!='\0'){
				schar=s1[i-1];
 				echar=s1[i+1];
				/* if the range is not reasonable */
				if((schar<echar) && ((schar>='0' && schar <='9'&& echar>='0' && echar<='9') || (schar>='a' && schar <='z' && echar>='a' && echar<='z') ||(schar>='A' && schar <='Z' && echar>='A' && echar<='Z'))){
					for(t=schar+1;t<echar;t++,j++){
						s2[j]=t;
					}
					i++;						
				}
				else {
					printf("Wrong range: %c to %c\n",schar,echar);
					s2[j++]=s1[i++];
				}	

			}	
			else s2[j++]=s1[i++];
		}
		else s2[j++]=s1[i++];	
	
	}
	s2[j] = '\0';
}


int main(void){

	char s1[]="-z-z-0-9-S-A-G-s-y-1-9";
	char s2[MAX];
	
	expand(s1,s2);
	printf("[source]\n%s\n[target]\n%s\n",s1,s2);
	printf("end");

	return 0;
}

Run:

$ ./c3ex3_expand.exe
Wrong range: z to z
Wrong range: z to 0
Wrong range: 9 to S
Wrong range: S to A
Wrong range: G to s
Wrong range: y to 1
[source]
-z-z-0-9-S-A-G-s-y-1-9
[target]
-z-z-0123456789-S-ABCDEFG-stuvwxy-123456789
end

c3ex2_escape.cpp

13:10

Write a function escape(s,t) that converts characters like newline and tab into visible escape sequences like \n and \t as it copies the string s to t . Use a switch . Write a function for the other direction as well, converting escape sequences into the real characters.


#include <stdio.h>
#include <string.h> 

#define MAX 500
 
void escape(char* s, char* t){
	
	int i=0,j=0;
	
	while(s[i]!='\0'){
	
		switch(s[i]){
			case '\n': t[j]='\\'; t[++j]='n'; break;
			case '\t': t[j]='\\'; t[++j]='t'; break;
			case '\v': t[j]='\\'; t[++j]='v'; break;
			case '\a': t[j]='\\'; t[++j]='a'; break;
			case '\r': t[j]='\\'; t[++j]='r'; break;
			case '\b': t[j]='\\'; t[++j]='b'; break;	
			case '\"': t[j]='\\'; t[++j]='"'; break;				
			default: t[j]=s[i];
		}		
		j++;
		i++;
	}
	t[j]='\0';
}
 
void rollback_escape(char* s, char* t){
	
	int i=0,j=0;
	
	while(s[i]!='\0'){
	
		if(s[i]=='\\') {
			switch(s[i+1]){
				case 'n': t[j]='\n'; i++; break;
				case 't': t[j]='\t'; i++; break;
				case 'v': t[j]='\v'; i++; break;
				case 'a': t[j]='\a'; i++; break;
				case 'r': t[j]='\r'; i++; break;			
				case 'b': t[j]='\b'; i++; break;			
				case '"': t[j]='\"'; i++; break;					
				default: t[j]=s[i];
			}
		}
		else t[j]=s[i];

		j++;
		i++;
	}
	t[j]='\0';
}

int main(void){

	char s[]="Jingle bell\rJingle bell\tJingle all the way\a\n\\\"Merry Christmas!\"\\'Hey \bHey'\n";
	char b1[MAX],b2[MAX];
	
	escape(s,b1);
	printf("Call escape(s,t)...\n[source]\n%s\n[target]\n%s\n",s,b1);
	printf("\n");
	rollback_escape(b1,b2);
	printf("Call rollback_escape(s,t)...\n[source]\n%s\n[target]\n%s\n",b1,b2);
	printf("end");

	return 0;
}

Run:

$ ./c3ex2_escape.exe
Call escape...
[source]
Jingle bell     Jingle all the way
\"Merry Christmas!"\'HeyHey'

[target]
Jingle bell\rJingle bell\tJingle all the way\a\n\\"Merry Christmas!\"\'Hey \bHey'\n

Call rollback_escape...
[source]
Jingle bell\rJingle bell\tJingle all the way\a\n\\"Merry Christmas!\"\'Hey \bHey'\n
[target]
Jingle bell     Jingle all the way
\"Merry Christmas!"\'HeyHey'

end

2008-12-08

c2ex10_upper2lower.cpp

14:32

Rewrite the function lower, which converts upper case letters to lower case, with a conditional expression instead of if-else .

Q: data type could be 'char' or 'int', any concern on using them?

#include <stdio.h>
#include <string.h>   

int lower(int x){
	
	int d;
	
	d = x<='Z'&& x>='A' ? x+'a'-'A' : x; 
 
	return d;
}

int main(void)
{
	char* test="AbCDEFgHIJKlMNoPQRSTUVWXYZ";
	int c,i;
	for(i=0;i<strlen(test);i++){
		c= test[i];
		printf("%c to lowercase: %c \n", c,lower(c));
	}	
 
	return 0;
}

Run:

$ ./c2ex10_upper2lower.exe
A to lowercase: a
b to lowercase: b
C to lowercase: c
D to lowercase: d
E to lowercase: e
F to lowercase: f
g to lowercase: g
H to lowercase: h
I to lowercase: i
J to lowercase: j
K to lowercase: k
l to lowercase: l
M to lowercase: m
N to lowercase: n
o to lowercase: o
P to lowercase: p
Q to lowercase: q
R to lowercase: r
S to lowercase: s
T to lowercase: t
U to lowercase: u
V to lowercase: v
W to lowercase: w
X to lowercase: x
Y to lowercase: y
Z to lowercase: z

c2ex9_bitcount.cpp

13:52

In a two's complement number system, x &= (x-1) deletes the rightmost 1-bit in x . Explain why. Use this observation to write a faster version of bitcount.

#include <stdio.h>
#include <stdlib.h>   

unsigned bitcount(unsigned x){
	
	int i, t=0;
	for(;x!=0;x&=x-1){
		t++;
	}
	
	return t;
	
}

int main(void)
{
	unsigned n;
	int c;

	printf("input unsigned integer n\n");
	scanf("%u",&n);
	printf("bitcount(%u)= ",n);
	c = bitcount(n);
	printf("%d",c);
 
	return 0;
}
Run:
$ ./c2ex9_bitcount.exe
input unsigned integer n
123
bitcount(123)= 6

$ ./c2ex9_bitcount.exe
input unsigned integer n
123445
bitcount(123445)= 9

えぬえぬ2008/12/08 21:11"x &= (x-1)" :O beautiful

2008-12-05

c3ex1_binsearch.cpp

17:32

Our binary search makes two tests inside the loop, when one would suffice (at the price of more tests outside). Write a version with only one test inside the loop and measure the difference in run-time.


#include <stdio.h>
#include <string.h>   
#include <time.h>

#define MAX 100000

int binsearch_new(int x, int v[], int n){
	
	int low, high, mid;
	
	low =0; 
	high = n-1;
	mid = (low+high)/2;	
	while(x!=v[mid] && low<high ){
		if(x < v[mid]){
			high=mid-1;
		}
		else{
			low=mid+1;
		}	
		mid = (low+high)/2;	
	}	
	if(x==v[mid]) return mid;
	else return -1;
}

int binsearch(int x, int v[], int n) {
    int low, mid, high;
    
    low = 0;
    high = n - 1;
    while ( low <= high ) {
        mid = (low+high) / 2;
        if ( x < v[mid] )
            high = mid - 1;
        else if ( x > v[mid] )
            low = mid + 1;
        else
            return mid;
    }
    return -1;
}


int main(void)
{
	int test[MAX];
	int c = -1, p, i;  // set c = -1 to run the binsearch function for longer time 
	clock_t sclock, eclock;
	
	for(i=0;i<MAX;i++){
		test[i]=i;		
	}
	
	for(i=0,sclock=clock();i<MAX;i++)	p=binsearch(c,test,MAX);
	eclock=clock();
	if(p!=-1) printf("%d is found at pos%d \n", c, p);
	printf("[binsearch] end clock: %d, start clock: %d, time used: %f seconds\n", eclock, sclock, double(eclock-sclock)/CLOCKS_PER_SEC);
	
	for(i=0,sclock=clock();i<MAX;i++)	p=binsearch_new(c,test,MAX);
	eclock=clock();
	if(p!=-1) printf("%d is found at pos%d \n", c, p);
	printf("[binsearch_new] end clock: %d, start clock: %d, time used: %f seconds\n", eclock, sclock, double(eclock-sclock)/CLOCKS_PER_SEC);

	return 0;
}

Run:

$ ./c3ex1_binsearch.exe
[binsearch] end clock: 62, start clock: 46, time used: 0.016000 seconds
[binsearch_new] end clock: 77, start clock: 62, time used: 0.015000 seconds

c2ex8_rightrot.cpp

19:29

Write a function rightrot(x,n) that returns the value of the integer x rotated to the right by n bit positions.


#include <stdio.h>
#include <stdlib.h>   

unsigned rightrot(unsigned x, int n){
	
	int i, t;
	for(i=0;i<n;i++){
		t=x&1;
		if(t>0) {
			x= (x>>1) | (~(~0U>>1));
		}	
		else {
			x= x>>1 ;
		}	
	}
	
	return x;
	
}

int main(void)
{
	unsigned c;
	unsigned k;
	int n;

	printf("input unsigned integer c n\n");
	scanf("%u %d",&c,&n);
	printf("rightrot(%u,%d)= ",c,n);
	k = rightrot(c, n);
	printf("%u",k);
 
	return 0;
}

Run:

$ ./c2ex8_rightrot.exe
input unsigned integer c n
123 4
rightrot(123,4)= 2952790023

c2ex7_invert.cpp

16:27

Write a function invert(x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the others unchanged.


#include <stdio.h>

unsigned invert(unsigned x,int p, int n){
	
	return ((x & (~(~0<<(p+1-n)) | (~0<<(p+1)))) | (~x & ~(~(~0<<(p+1-n)) | (~0<<(p+1)))));
	
}

int main(void)
{
	unsigned c;
	unsigned k;
	int p;
	int n;

	printf("input unsigned integer c p n\n");
	scanf("%u %d %d",&c,&p,&n);
	printf("invert(%u,%d,%d)= ",c,p,n);
	k = invert(c, p, n);
	printf("%d",k);

	return 0;
}

Run:

$ ./c2ex7_invert.exe
input unsigned integer c p n
23 2 1
invert(23,2,1)= 19

$ ./c2ex7_invert.exe
input unsigned integer c p n
1234 10 6
invert(1234,10,6)= 818

sendmoremoney.cpp

16:27

を満たすそれぞれ異なる 0 以上 9以下の数 S, E, N, D, M, O, R, Y を求めよ。(ただし S, M は 0 でない)

   S E N D
+  M O R E
---------
M O N E Y
#include <stdio.h>
#include <stdlib.h>

int a[8]={};
//	sendmory
//	01234567
int roll();		/* two ways to calculte */
int rolln(int);

int judge();

int main(){

	rolln(0);
	roll();

}

int judge(){

/*
	send=[0,1,2,3]
	more=[4,5,6,1]
	money=[4,5,2,1,7]
*/
	int i;
		if(a[0]*1000+a[1]*100+a[2]*10+a[3]+a[4]*1000+a[5]*100+a[6]*10+a[1]==a[4]*10000+a[5]*1000+a[2]*100+a[1]*10+a[7]){
			printf("    %d%d%d%d\n",a[0],a[1],a[2],a[3]);
			printf("+   %d%d%d%d\n",a[4],a[5],a[6],a[1]);
			printf("   %d%d%d%d%d\n",a[4],a[5],a[2],a[1],a[7]);
			printf("s e n d m o r y\n");
			for(i=0;i<8;i++)	printf("%d ",a[i]);
                        printf("\n");

			return 0;
		}
		else {
			return -1;
		}
		
}

int rolln(int id){
	
	int flag, i, n;
	
	if(id>7){
		return -1;
	}

	for(i=0;i<10;i++){
		if(i==0&&(id==0||id==4)) continue; 
	/* check if number i is avaiable */
		n=0;
		while(n<id){
			if(a[n]==i) {
				flag=1;
				break;	
			}	
			n++;			
		}
	/* number is used then, next i */	
		if(flag==1)	{
			flag=0;
			continue;
		}
	/* ok to assign */		
		else {
			a[id]=i;
			if(id<7){
				rolln(id+1);
			}	
			else {
				judge();
			}
		}	
	}
	return 0;
}


int roll(){

	int id;
	int i,j,k,l,m,n,o,p;
	
	for(i=0;i<10;i++){
		if(i!=0) {
			a[0]=i; 
		}	
		else continue;
		for(j=0;j<10;j++){
			if(j!=i) {
				a[1]=j;
			}	
			else continue;
			for(k=0;k<10;k++){
				if(k!=j&&k!=i){
					a[2]=k;
				}	
				else continue;
				for(l=0;l<10;l++){
					if(l!=k&&l!=j&&l!=i){
						a[3]=l;	
					}	
					else continue;
					for(m=0;m<10;m++){
						if(m!=0&&m!=l&&m!=k&&m!=j&&m!=i){
							a[4]=m;
						}
						else continue;						
						for(n=0;n<10;n++){
							if(n!=m&&n!=l&&n!=k&&n!=j&&n!=i){
								a[5]=n;
							}
							else continue;	
							for(o=0;o<10;o++){
								if(o!=n&&o!=m&&o!=l&&o!=k&&o!=j&&o!=i) {
									a[6]=o;					
								}	
								else continue;	
								for(p=0;p<10;p++){
									if(p!=o&&p!=n&&p!=m&&p!=l&&p!=k&&p!=j&&p!=i){
											a[7]=p;	
											judge();											
									}	
									else continue;									
								}
								
							}								
						}						
						
					}					
				}
			}
		}
	}	
}

Run:

$ ./sendmoremoney.exe
    9567
+   1085
   10652
s e n d m o r y
9 5 6 7 1 0 8 2  
    9567
+   1085
   10652
s e n d m o r y
9 5 6 7 1 0 8 2