ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/cnt.c
Revision: 1.3
Committed: Mon Apr 11 18:08:19 2022 UTC (2 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +97 -26 lines
Log Message:
feat(cnt): Added -s option to shuffle output

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 1.3 static const char RCSid[] = "$Id: cnt.c,v 1.2 2003/06/08 12:03:09 schorsch Exp $";
3 greg 1.1 #endif
4     /*
5     * cnt.c - simple counting program.
6     *
7     * 2/1/88
8 greg 1.3 *
9     * Added -s (shuffle) option April 2022
10 greg 1.1 */
11    
12     #include <stdio.h>
13 greg 1.3 #include <time.h>
14     #include "random.h"
15 greg 1.1
16 greg 1.3 #define MAXDIM 50
17 greg 1.1
18     char buf[256];
19    
20    
21 greg 1.3 /* Encode integer in string and return pointer to end */
22     static char *
23 schorsch 1.2 tack(
24 greg 1.3 char *b,
25     int i
26 schorsch 1.2 )
27 greg 1.1 {
28 greg 1.3 char *cp;
29 greg 1.1 char *res;
30    
31     *b++ = '\t';
32     cp = b;
33     if (i == 0)
34     *cp++ = '0';
35     else
36     do {
37     *cp++ = i%10 + '0';
38     i /= 10;
39     } while (i);
40     res = cp--;
41     #define c i
42     while (cp > b) { /* reverse string */
43     c = *cp;
44     *cp-- = *b;
45     *b++ = c;
46     }
47     #undef c
48     return(res);
49     }
50    
51    
52 greg 1.3 /* Loop over dimensions, spitting out buffer after each increment */
53 schorsch 1.2 static void
54     loop(
55     int *n,
56     char *b
57     )
58 greg 1.1 {
59     int i;
60    
61     if (n[0] == 0) {
62     *b = '\0';
63     puts(buf);
64     return;
65     }
66     for (i = 0; i < n[0]; i++)
67     loop(n+1, tack(b, i));
68     }
69 greg 1.3
70    
71     /* Shuffle all possible output strings and spit out randomly */
72     static void
73     shuffle(
74     int *n
75     )
76     {
77     int sub[MAXDIM];
78     int ndim;
79     int alen;
80     int *myshuf;
81     int i, j;
82    
83     alen = 1; /* allocate shuffle index array */
84     for (j = 0; n[j]; j++)
85     if ((alen *= n[j]) < 0)
86     exit(1);
87    
88     myshuf = (int *)malloc(alen*sizeof(int));
89     if (myshuf == NULL) {
90     fputs("Insufficient memory for shuffle\n", stderr);
91     exit(1);
92     }
93     for (i = alen; i--; ) /* initialize in any order */
94     myshuf[i] = i;
95     /* get unique starting point */
96     srandom((long)time(0));
97     /* perform Fisher-Yates shuffle */
98     for (i = 0; i < alen-1; i++) {
99     int ix = random()%(alen-i) + i;
100     int ndx = myshuf[i];
101     myshuf[i] = myshuf[ix];
102     myshuf[ix] = ndx;
103     }
104     /* put randomly indexed output */
105     for (i = alen; i--; ) {
106     int aval = myshuf[i];
107     for (j = 0; n[j+1]; j++) {
108     printf("\t%d", aval % n[j]);
109     aval /= n[j];
110     }
111     printf("\t%d\n", aval);
112     }
113     free(myshuf);
114     }
115    
116    
117     int
118     main(
119     int argc,
120     char *argv[]
121     )
122     {
123     char *prog = argv[0];
124     int doshuffle = 0;
125     int n[MAXDIM];
126     int a;
127    
128     argv++; argc--;
129     if (argc <= 0)
130     goto userr;
131     if (argv[0][0] == '-' && argv[0][1] == 's') {
132     doshuffle = 1;
133     argv++; argc--;
134     }
135     for (a = 0; a < argc; a++)
136     if ((n[a] = atoi(argv[a])) <= 1)
137     goto userr;
138     n[a] = 0;
139     if (!a)
140     goto userr;
141    
142     if (doshuffle)
143     shuffle(n);
144     else
145     loop(n, buf);
146    
147     return(0);
148     userr:
149     fputs("Usage: ", stderr);
150     fputs(prog, stderr);
151     fputs(" [-s] N0 [N1 ..]\n", stderr);
152     return(1);
153     }