]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - games/factor/factor.c
unfinished sblive driver, playback/mixer only for now - not enabled in
[FreeBSD/FreeBSD.git] / games / factor / factor.c
1 /*
2  * Copyright (c) 1989, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Landon Curt Noll.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by the University of
19  *      California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #ifndef lint
38 static const char copyright[] =
39 "@(#) Copyright (c) 1989, 1993\n\
40         The Regents of the University of California.  All rights reserved.\n";
41 #endif /* not lint */
42
43 #ifndef lint
44 #if 0
45 static char sccsid[] = "@(#)factor.c    8.4 (Berkeley) 5/4/95";
46 #endif
47 static const char rcsid[] =
48  "$FreeBSD$";
49 #endif /* not lint */
50
51 /*
52  * factor - factor a number into primes
53  *
54  * By: Landon Curt Noll   chongo@toad.com,   ...!{sun,tolsoft}!hoptoad!chongo
55  *
56  *   chongo <for a good prime call: 391581 * 2^216193 - 1> /\oo/\
57  *
58  * usage:
59  *      factor [number] ...
60  *
61  * The form of the output is:
62  *
63  *      number: factor1 factor1 factor2 factor3 factor3 factor3 ...
64  *
65  * where factor1 < factor2 < factor3 < ...
66  *
67  * If no args are given, the list of numbers are read from stdin.
68  */
69
70 #include <err.h>
71 #include <ctype.h>
72 #include <errno.h>
73 #include <limits.h>
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <unistd.h>
77
78 #include "primes.h"
79
80 /*
81  * prime[i] is the (i-1)th prime.
82  *
83  * We are able to sieve 2^32-1 because this byte table yields all primes
84  * up to 65537 and 65537^2 > 2^32-1.
85  */
86 extern ubig prime[];
87 extern ubig *pr_limit;          /* largest prime in the prime array */
88
89 int     hflag;
90
91 void    pr_fact __P((ubig));    /* print factors of a value */
92 void    usage __P((void));
93
94 int
95 main(argc, argv)
96         int argc;
97         char *argv[];
98 {
99         ubig val;
100         int ch;
101         char *p, buf[100];              /* > max number of digits. */
102
103         while ((ch = getopt(argc, argv, "h")) != -1)
104                 switch (ch) {
105                 case 'h':
106                         hflag++;
107                         break;
108                 case '?':
109                 default:
110                         usage();
111                 }
112         argc -= optind;
113         argv += optind;
114
115         /* No args supplied, read numbers from stdin. */
116         if (argc == 0)
117                 for (;;) {
118                         if (fgets(buf, sizeof(buf), stdin) == NULL) {
119                                 if (ferror(stdin))
120                                         err(1, "stdin");
121                                 exit (0);
122                         }
123                         for (p = buf; isblank(*p); ++p);
124                         if (*p == '\n' || *p == '\0')
125                                 continue;
126                         if (*p == '-')
127                                 errx(1, "negative numbers aren't permitted.");
128                         errno = 0;
129                         val = strtoul(buf, &p, 0);
130                         if (errno)
131                                 err(1, "%s", buf);
132                         if (*p != '\n')
133                                 errx(1, "%s: illegal numeric format.", buf);
134                         pr_fact(val);
135                 }
136         /* Factor the arguments. */
137         else
138                 for (; *argv != NULL; ++argv) {
139                         if (argv[0][0] == '-')
140                                 errx(1, "negative numbers aren't permitted.");
141                         errno = 0;
142                         val = strtoul(argv[0], &p, 0);
143                         if (errno)
144                                 err(1, "%s", argv[0]);
145                         if (*p != '\0')
146                                 errx(1, "%s: illegal numeric format.", argv[0]);
147                         pr_fact(val);
148                 }
149         exit(0);
150 }
151
152 /*
153  * pr_fact - print the factors of a number
154  *
155  * If the number is 0 or 1, then print the number and return.
156  * If the number is < 0, print -1, negate the number and continue
157  * processing.
158  *
159  * Print the factors of the number, from the lowest to the highest.
160  * A factor will be printed numtiple times if it divides the value
161  * multiple times.
162  *
163  * Factors are printed with leading tabs.
164  */
165 void
166 pr_fact(val)
167         ubig val;               /* Factor this value. */
168 {
169         ubig *fact;             /* The factor found. */
170
171         /* Firewall - catch 0 and 1. */
172         if (val == 0)           /* Historical practice; 0 just exits. */
173                 exit(0);
174         if (val == 1) {
175                 (void)printf("1: 1\n");
176                 return;
177         }
178
179         /* Factor value. */
180         (void)printf(hflag ? "0x%lx:" : "%lu:", val);
181         for (fact = &prime[0]; val > 1; ++fact) {
182                 /* Look for the smallest factor. */
183                 do {
184                         if (val % (long)*fact == 0)
185                                 break;
186                 } while (++fact <= pr_limit);
187
188                 /* Watch for primes larger than the table. */
189                 if (fact > pr_limit) {
190                         (void)printf(hflag ? " 0x%lx" : " %lu", val);
191                         break;
192                 }
193
194                 /* Divide factor out until none are left. */
195                 do {
196                         (void)printf(hflag ? " 0x%lx" : " %lu", *fact);
197                         val /= *fact;
198                 } while ((val % *fact) == 0);
199
200                 /* Let the user know we're doing something. */
201                 (void)fflush(stdout);
202         }
203         (void)putchar('\n');
204 }
205
206 void
207 usage()
208 {
209         (void)fprintf(stderr, "usage: factor -h [value ...]\n");
210         exit (0);
211 }