10f66f451Sopenharmony_ci/* factor.c - Factor integers 20f66f451Sopenharmony_ci * 30f66f451Sopenharmony_ci * Copyright 2014 Rob Landley <rob@landley.net> 40f66f451Sopenharmony_ci * 50f66f451Sopenharmony_ci * No standard, but it's in coreutils 60f66f451Sopenharmony_ci 70f66f451Sopenharmony_ciUSE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN)) 80f66f451Sopenharmony_ci 90f66f451Sopenharmony_ciconfig FACTOR 100f66f451Sopenharmony_ci bool "factor" 110f66f451Sopenharmony_ci default y 120f66f451Sopenharmony_ci help 130f66f451Sopenharmony_ci usage: factor NUMBER... 140f66f451Sopenharmony_ci 150f66f451Sopenharmony_ci Factor integers. 160f66f451Sopenharmony_ci*/ 170f66f451Sopenharmony_ci 180f66f451Sopenharmony_ci#include "toys.h" 190f66f451Sopenharmony_ci 200f66f451Sopenharmony_cistatic void factor(char *s) 210f66f451Sopenharmony_ci{ 220f66f451Sopenharmony_ci unsigned long long l, ll; 230f66f451Sopenharmony_ci 240f66f451Sopenharmony_ci for (;;) { 250f66f451Sopenharmony_ci char *err = s; 260f66f451Sopenharmony_ci int dash = 0; 270f66f451Sopenharmony_ci 280f66f451Sopenharmony_ci while(isspace(*s)) s++; 290f66f451Sopenharmony_ci if (*s=='-') dash = *s++; 300f66f451Sopenharmony_ci if (!*s) return; 310f66f451Sopenharmony_ci 320f66f451Sopenharmony_ci errno = 0; 330f66f451Sopenharmony_ci l = strtoull(s, &s, 0); 340f66f451Sopenharmony_ci if (errno || (*s && !isspace(*s))) { 350f66f451Sopenharmony_ci error_msg("%s: not integer", err); 360f66f451Sopenharmony_ci while (*s && !isspace(*s)) s++; 370f66f451Sopenharmony_ci continue; 380f66f451Sopenharmony_ci } 390f66f451Sopenharmony_ci 400f66f451Sopenharmony_ci printf("-%llu:"+!dash, l); 410f66f451Sopenharmony_ci 420f66f451Sopenharmony_ci // Negative numbers have -1 as a factor 430f66f451Sopenharmony_ci if (dash) printf(" -1"); 440f66f451Sopenharmony_ci 450f66f451Sopenharmony_ci // Nothing below 4 has factors 460f66f451Sopenharmony_ci if (l < 4) { 470f66f451Sopenharmony_ci printf(" %llu\n", l); 480f66f451Sopenharmony_ci continue; 490f66f451Sopenharmony_ci } 500f66f451Sopenharmony_ci 510f66f451Sopenharmony_ci // Special case factors of 2 520f66f451Sopenharmony_ci while (l && !(l&1)) { 530f66f451Sopenharmony_ci printf(" 2"); 540f66f451Sopenharmony_ci l >>= 1; 550f66f451Sopenharmony_ci } 560f66f451Sopenharmony_ci 570f66f451Sopenharmony_ci // test odd numbers until square is > remainder or integer wrap. 580f66f451Sopenharmony_ci for (ll=3; ;ll += 2) { 590f66f451Sopenharmony_ci long lll = ll*ll; 600f66f451Sopenharmony_ci 610f66f451Sopenharmony_ci if (lll>l || lll<ll) { 620f66f451Sopenharmony_ci if (l>1) printf(" %llu", l); 630f66f451Sopenharmony_ci break; 640f66f451Sopenharmony_ci } 650f66f451Sopenharmony_ci while (!(l%ll)) { 660f66f451Sopenharmony_ci printf(" %llu", ll); 670f66f451Sopenharmony_ci l /= ll; 680f66f451Sopenharmony_ci } 690f66f451Sopenharmony_ci } 700f66f451Sopenharmony_ci xputc('\n'); 710f66f451Sopenharmony_ci } 720f66f451Sopenharmony_ci} 730f66f451Sopenharmony_ci 740f66f451Sopenharmony_civoid factor_main(void) 750f66f451Sopenharmony_ci{ 760f66f451Sopenharmony_ci if (toys.optc) { 770f66f451Sopenharmony_ci char **ss; 780f66f451Sopenharmony_ci 790f66f451Sopenharmony_ci for (ss = toys.optargs; *ss; ss++) factor(*ss); 800f66f451Sopenharmony_ci } else for (;;) { 810f66f451Sopenharmony_ci char *s = 0; 820f66f451Sopenharmony_ci size_t len = 0; 830f66f451Sopenharmony_ci 840f66f451Sopenharmony_ci if (-1 == getline(&s, &len, stdin)) break; 850f66f451Sopenharmony_ci factor(s); 860f66f451Sopenharmony_ci } 870f66f451Sopenharmony_ci} 88