#!/bin/bash
#
# @file:
#   gen_factoring.sh
#
# @description:
#   Generate the factoring device.
# This script emits Java code for factoring
# 32bit integers using a guessing approach
# where a number is selected and compared
# to n using gcd.  If the gcd is not
# one, the result is then used as a divisor
# of n.  This code generates 'm' test branches.
#
# @author:
#   Roger G. Doss
#

M=512;
COUNT=0;
OUTPUT="monte_carlo_m.java"
if [ -e $OUTPUT ]
then
    rm -f $OUTPUT
fi
#
# Output the preamble.
#
printf "\t/* Copyright (C) Roger G. Doss.  All rights reserved. */\n" >> $OUTPUT
printf "\t/* Code generated on $DATE */\n" >> $OUTPUT
printf "import java.math.BigInteger; \n" >> $OUTPUT
printf "import java.util.Random; \n" >> $OUTPUT
printf " \n" >> $OUTPUT
printf "public class monte_carlo_m { \n" >> $OUTPUT
printf " \n" >> $OUTPUT
printf "    public monte_carlo_m(BigInteger n) \n" >> $OUTPUT
printf "    { \n" >> $OUTPUT
printf "        // Attempt to factor 'n' by selecting \n" >> $OUTPUT
printf "        // at random, integer 'trial' and checking \n" >> $OUTPUT
printf "        // the gcd(n,trial).  If trial is not \n" >> $OUTPUT
printf "        // one, and the gcd is \n" >> $OUTPUT
printf "        // greater than one, we have a divisor. \n" >> $OUTPUT
printf "        BigInteger trial, d; \n" >> $OUTPUT
printf "        int m = $M; \n" >> $OUTPUT
printf "        Random r    = new Random(); \n" >> $OUTPUT
printf "        Random[] rand = new Random[m]; \n" >> $OUTPUT
printf "        for(int i = 0; i < m; i++) { \n" >> $OUTPUT
printf "            rand[i]= new Random(); \n" >> $OUTPUT
printf "            rand[i].setSeed(r.nextInt()); \n" >> $OUTPUT
printf "        } \n" >> $OUTPUT
printf "        int bitLength = n.bitLength(); \n" >> $OUTPUT
printf "        while(true) \n" >> $OUTPUT
printf "        {\n" >> $OUTPUT

while [ $M != 0 ]
do
printf "            trial = new BigInteger(bitLength,rand[$COUNT]); \n" >> $OUTPUT
printf "            if(!trial.equals(BigInteger.ONE) && !((d=n.gcd(trial)).equals(BigInteger.ONE))) { \n" >> $OUTPUT
printf "                System.out.println(\"p: \" + n.divide(d) + \" q: \" + d); \n" >> $OUTPUT
printf "                break; \n" >> $OUTPUT
printf "            } \n" >> $OUTPUT
((COUNT=$COUNT + 1));
((M=$M-1));
done
printf "        } \n" >> $OUTPUT
printf "    } \n" >> $OUTPUT
printf " \n" >> $OUTPUT
printf "    public static void main(String[] args) \n" >> $OUTPUT
printf "    { \n" >> $OUTPUT
printf "        monte_carlo_m _1 = new monte_carlo_m(new BigInteger(args[0].trim())); \n" >> $OUTPUT
printf "    } \n" >> $OUTPUT
printf "} \n" >> $OUTPUT
#
# EOF
#