Home | History | Annotate | Download | only in other
      1 /* factor.c - Factor integers
      2  *
      3  * Copyright 2014 Rob Landley <rob (at) landley.net>
      4  *
      5  * No standard, but it's in coreutils
      6 
      7 USE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN))
      8 
      9 config FACTOR
     10   bool "factor"
     11   default y
     12   help
     13     usage: factor NUMBER...
     14 
     15     Factor integers.
     16 */
     17 
     18 #include "toys.h"
     19 
     20 static void factor(char *s)
     21 {
     22   unsigned long l, ll;
     23 
     24   for (;;) {
     25     char *err = s;
     26 
     27     while(isspace(*s)) s++;
     28     if (!*s) return;
     29 
     30     l = strtoul(s, &s, 0);
     31     if (*s && !isspace(*s)) {
     32       error_msg("%s: not integer", err);
     33 
     34       return;
     35     }
     36 
     37     printf("%lu:", l);
     38 
     39     // Negative numbers have -1 as a factor
     40     if (l < 0) {
     41       printf(" -1");
     42       l *= -1;
     43     }
     44 
     45     // Nothing below 4 has factors
     46     if (l < 4) {
     47       printf(" %lu\n", l);
     48       continue;
     49     }
     50 
     51     // Special case factors of 2
     52     while (l && !(l&1)) {
     53       printf(" 2");
     54       l >>= 1;
     55     }
     56 
     57     // test odd numbers.
     58     for (ll=3; ;ll += 2) {
     59       long lll = ll*ll;
     60 
     61       if (lll>l || lll<ll) {
     62         if (l>1) printf(" %lu", l);
     63         break;
     64       }
     65       while (!(l%ll)) {
     66         printf(" %lu", ll);
     67         l /= ll;
     68       }
     69     }
     70     xputc('\n');
     71   }
     72 }
     73 
     74 void factor_main(void)
     75 {
     76   if (toys.optc) {
     77     char **ss;
     78 
     79     for (ss = toys.optargs; *ss; ss++) factor(*ss);
     80   } else for (;;) {
     81     char *s = 0;
     82     size_t len = 0;
     83 
     84     if (-1 == getline(&s, &len, stdin)) break;
     85     factor(s);
     86   }
     87 }
     88