coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: factor -- print factorization in exponential form


From: L A Walsh
Subject: Re: factor -- print factorization in exponential form
Date: Mon, 20 Nov 2017 13:22:17 -0800
User-agent: Thunderbird

Eduardo � wrote:
On Sat, Nov 11, 2017 at 12:49:36AM +0100, Emanuel Landeholm wrote:
List,

I'm working with large composite numbers and would like to have the option
of printing the factorization in exponential form. I have attached a patch
for printing factorizations in this form:

    $ src/factor
    68000
    68000: 2^5 5^3 17

[Note: I'm not a coreutils developer, I just lurk here :-) ]

Hey!

I couldn't help but notice that this could be done with a simple AWK script and 
a pipe...
----
   Can also do it in bash-script (attached).

   Takes input as:

   1: output of factor on command line:
      > pfactor $(factor 100)
      2**2 5**2

   2: list of numbers on command line:
      > pfactor 100 200 500
      2**2 5**2
      2**3 5**2
      2**2 5**3

   3: list of numbers on input:
      > echo '100
      200
      500' |pfactor
      2**2 5**2
      2**3 5**2
      2**2 5**3
    or
      > echo -e '100\n200\n300'|pfactor
      2**2 5**2
      2**3 5**2
      2**2 3 5**2


In all cases, it uses the output of factor.  (Already had pfactor,
but added ability to read from input, 1 number/line).

Obviously, it could be improved on 400 different ways as well
as written 400 different ways  in at least 100+ different
languages... ;-)


#!/bin/bash -u
# gvim=:SetNumberAndWidth

#include stdalias || {
#       printf >&2 "Can't include source files.  Need include?"
#       exit 1
#}
shopt -s expand_aliases
alias my=declare  int='my -i'

# take line from 'factor', like:  585728: 2 2 2 2 2 2 2 2 2 2 2 2 11 13
# and convert to 585728: 2**12 11 13

pfactor () {
        if [[ ! $1 =~ :$ ]]; then 
                printf >&2 "Error in factor output: $*\n"
                exit 1
        fi
        shift

        pterm () {
                ((count)) || return 0
                my multi=""
                ((count>1)) && printf -v multi "**%d" "$count"
                printf "%d%s " "$last" "$multi"
        }

        my -ai facs=($@)
        int last=0 count=0 i=0
        for ((i=0; i < ${#facs[@]}; ++i)); do
                int this=${facs[i]}
                if (($this!=$last)); then
                        pterm
                        last=this
                        count=1
                elif ((this==last)); then
                        count+=1
                fi
        done
        pterm
        printf "\n"
        unset -f pterm
}

_pf_looks_like_factOut_() {
        if (($#>1)) && [[ $1 =~ ^[0-9]+:$ ]] ; then
                shift
                while (($#)); do
                        [[ !  $1 =~ ^[0-9]+$ ]] && return 1
                        shift
                done
                return 0
        fi
        return 1
}

_pf_isnum_() {
        [[ $1 =~ ^[0-9]+$ ]]
}

_pf_caller_() {
        if (($#)); then 
                if _pf_looks_like_factOut_ "$@"; then
                        pfactor "$@"
                        return 0
                else
                        while (($#)) && _pf_isnum_ "$1"; do
                                pfactor $(factor "$1") || return 1
                                shift
                        done
                        return 0
                fi
        fi
        return 1
}

int results=0
#set -x

if (($#)); then 
        _pf_caller_ "$@" && exit 0
elif [[ ! -t 0 ]]; then
        while read -t 0.1 inp; do
                if [[ $inp ]] ; then
                        set $inp
                        _pf_caller_ "$@" && results+=1
                fi
        done
fi
if ((results<1)); then
        printf >&2 "Need output line from 'factor'\n"
        exit 1
fi

#set +x

reply via email to

[Prev in Thread] Current Thread [Next in Thread]