短縮しようとおもいましたが、断念。。以下メインのみ。
for(i=4;--i;)h+=!(u[i]*=u[i]==(a[i]=c?a[i]:48+rand()%10));
for(i=16;--i;)b+=!i*(u[i/4]==a[i%4]);

乱数のシードにcかuを使うのはどうでしょ?