decimalPlaces) decimalPlaces = currentDecimalPlaces;
+ }
+ return decimalPlaces;
+ }
+
+ /**
+ * Reverses the digits of a positive integer a using arithmetic.
+ * @param a positive integer
+ * @return reverse digits
+ */
+ public static int digitReverse(int a){
+ if(a<0) throw new IllegalArgumentException();
+ int b = 0;
+ while(a != 0) {
+ b = (10 * b) + (a % 10);
+ a /= 10;
+ }
+ return b;
+ }
+
+ /**
+ * sum of decimal digits. 701=7+0+1=8
+ * @param number
+ * @return the digit sum
+ */
+ public static int digitSum(int number){
+ int sum = 0;
+ while(number > 0) {
+ sum = sum + (number % 10);
+ number /= 10;
+ }
+ return sum;
+ }
+
+ /**
+ * @param n
+ * @return n!
+ */
+ public static BigInteger factorial(int n) {
+ BigInteger ansBI = new BigInteger("1");
+ if(n == 0) return ansBI;
+ return new BigInteger(String.valueOf(n)).multiply(factorial(n-1));
+ }
+
+ /**
+ * assuming n ≥ 0
+ * @param n
+ * @return n!
+ */
+ public static long factorial(long n) {
+ if(n>20) throw new RuntimeException("cause overflow, only factorial till 20 can be calculated.");
+ if(n == 0) return 1;
+ return n * factorial(n-1);
+ }
+
+ /**
+ * @param x double value
+ * @return the digits after the decimal point
+ */
+ public static double frac(double x){
+ if(x > 0.0) return x - Math.floor(x);
+ else return x - Math.ceil(x);
+ }
+
+ /**
+ * Computes the greatest common divisor of p and q using Euclid's algorithm.
+ * @param p
+ * @param q
+ * @return greatest common divisor
+ */
+ public static int gcd(int p, int q) {
+ if(q == 0) return p;
+ else return gcd(q, p % q);
+ }
+
+ /**
+ * φ = (1+√5)/2 = 1.6180339887498948482...
+ * @return golden ratio
+ */
+ public static double golden() {
+ return (1.0 + Math.sqrt(5)) / 2.;
+ }
+
+ /**
+ * Computes an approximation to the golden ratio using the recursive
+ * formula f0 = 1, fn = 1 + 1 / fn-1 if n > 0.
+ *
+ * n = 5: 1.625
+ * n = 10: 1.6179775280898876
+ * n = 20: 1.618033985017358
+ * n = 30: 1.6180339887496482
+ * @param n
+ * @return golden ratio
+ */
+ public static double golden(int n) {
+ if(n == 0) return 1;
+ return 1.0 + 1.0 / golden(n-1);
+ }
+
+ /**
+ * Computes the number of primes less than or equal to a
+ * using the Sieve of Eratosthenes.
+ * @param a number
+ * @return the number of primes <= a
+ */
+ public static int primeSieve(int a){
+ int i, j;
+ // initially assume all integers are prime
+ boolean[] isPrime = new boolean[a + 1];
+ for(i=2; i<=a; i++)
+ isPrime[i] = true;
+ // mark non-primes <= N using Sieve of Eratosthenes
+ for(i=2; i*i<=a; i++) {
+ // if i is prime, then mark multiples of i as nonprime
+ // suffices to consider mutiples i, i+1, ..., N/i
+ if (isPrime[i])
+ for(j=i; i*j<=1; j++)
+ isPrime[i*j] = false;
+ }
+ // count primes
+ int primes = 0;
+ for(i=2; i<=a; i++)
+ if (isPrime[i]) primes++;
+ return primes;
+ }
+
+ public static boolean kroneckerDelta(int x, int y){
+ return (x == y);
+ }
+
+ /**
+ * @param a array
+ * @return maximum value in array, -∞ if no such value
+ */
+ public static int max(int... a){
+ int i;
+ int max = Integer.MIN_VALUE;
+ for(i=0; i max)
+ max = a[i];
+ return max;
+ }
+
+ /**
+ * @param a double array
+ * @return maximum value in double array, -∞ if no such value
+ */
+ public static int max(int[][] a){
+ int i, j;
+ int max = Integer.MIN_VALUE;
+ for(i=0; i max)
+ max = a[i][j];
+ return max;
+ }
+
+ /**
+ * @param a array
+ * @return maximum value in array, -∞ if no such value.
+ */
+ public static double max(double... a){
+ int i;
+ double max = Double.NEGATIVE_INFINITY;
+ for(i=0; i max)
+ max = a[i];
+ return max;
+ }
+
+ /**
+ * @param is first index
+ * @param ie last index
+ * @param a array
+ * @return maximum value in subarray a[is...ie], -∞ if no such value.
+ */
+ public static double max(int is, int ie, double... a) {
+ if(!inBounds(a, is, ie))
+ throw new RuntimeException("Subarray indices out of bounds");
+ int i;
+ double max = Double.NEGATIVE_INFINITY;
+ for(i=is; i<=ie; i++)
+ if(a[i] > max)
+ max = a[i];
+ return max;
+ }
+
+ /**
+ * @param a double array
+ * @return maximum value in double array, -∞ if no such value.
+ */
+ public static double max(double[][] a){
+ int i, j;
+ double max = Double.NEGATIVE_INFINITY;
+ for(i=0; i max)
+ max = a[i][j];
+ return max;
+ }
+
+ public static int maxOrderOfMagnitude(double[] a){
+ int i, log;
+ int maxlog = Integer.MIN_VALUE;
+ for(i=0; i maxlog)
+ maxlog = log;
+ }
+ return maxlog;
+ }
+
+ /**
+ * Sum of values of a data set divided by number of values.
+ * @param a data field
+ * @return average value in array, NaN if no such value
+ */
+ public static double mean(int... a) {
+ if(a.length == 0) return Double.NaN;
+ double sum = sum(a);
+ return sum / a.length;
+ }
+
+ /**
+ * Sum of values of a data set divided by number of values.
+ * @param a data field
+ * @return average value in array, NaN if no such value
+ */
+ public static double mean(double... a){
+ if(a.length == 0) return Double.NaN;
+ double sum = sum(a);
+ return sum / a.length;
+ }
+
+ /**
+ * Sum of values of a data set divided by number of values.
+ * @param is first index
+ * @param ie last index
+ * @param a data field
+ * @return average value in subarray a[is...ie], NaN if no such value.
+ */
+ public static double mean(int is, int ie, double... a) {
+ if(!inBounds(a, is, ie))
+ throw new RuntimeException("Subarray indices out of bounds");
+ int length = ie - is + 1;
+ if(length == 0) return Double.NaN;
+ double sum = sum(a, is, ie);
+ return sum / length;
+ }
+
+ /**
+ * Middle value separating the greater and lesser halves of a data set.
+ * @param a data filed
+ * @return the median value of a data field
+ */
+ public static double median(double... a){
+ Arrays.sort(a);
+ if((a.length+1)%2==0) return a[(a.length+1)/2-1];
+ else{
+ int pos = (int) (a.length+1)/2;
+ return (a[pos-1]+a[pos])/2;
+ }
+ }
+
+ /**
+ * @param a array
+ * @return minimum value in array, +∞ if no such value
+ */
+ public static int min(int... a){
+ int i;
+ int min = Integer.MAX_VALUE;
+ for(i=0; is...ie], +∞ if no such value
+ */
+ public static double min(int is, int ie, double... a) {
+ if(!inBounds(a, is, ie))
+ throw new RuntimeException("Subarray indices out of bounds");
+ int i;
+ double min = Double.POSITIVE_INFINITY;
+ for(i=is; i<=ie; i++)
+ if (a[i] < min)
+ min = a[i];
+ return min;
+ }
+
+ /**
+ * @param a double array
+ * @return minimum value in double array, +∞ if no such value
+ */
+ public static double min(double[][] a){
+ int i, j;
+ double min = Double.POSITIVE_INFINITY;
+ for(i=0; i max)
+ max = a[i];
+ }
+ return new double[]{min,max};
+ }
+
+ /**
+ * @param a array
+ * @return minimum and maximum value in array, +∞ for minimum or -∞ for maximum if no such value
+ */
+ public static double[] minmax(double[][] a){
+ int i, j;
+ double min = Double.POSITIVE_INFINITY;
+ double max = Double.NEGATIVE_INFINITY;
+ for(i=0; i max)
+ max = a[i][j];
+ }
+ return new double[]{min,max};
+ }
+
+ /**
+ * TODO:
+ * Most frequent value in a data set.
+ * @param a array
+ * @return the mode of a data field
+ */
+ public static double mode(double... a){
+// MATLAB:
+// X = sort(x);
+// indices = find(diff([X; realmax]) > 0); % indices where repeated values change
+// [modeL,i] = max (diff([0; indices])); % longest persistence length of repeated values
+// mode = X(indices(i));
+ return 0;
+ }
+
+ /**
+ * Modular exponentiation a^e mod m.
+ * Computes a^e mod m using repeated squaring.
+ * 17^5 mod 10 = 7.
+ * 43417^53535 mod 34310 = 12053.
+ * 345343417^542323535 mod 324244310 = 23504373.
+ * @param a base
+ * @param e exponent
+ * @param m modulus
+ * @return Modular exponentiation a^e mod m
+ */
+ public static int modExp(int a, int e, int m) {
+ if(e == 0) return 1;
+ long t = modExp(a, e/2, m); // use long for intermediate computations to eliminate overflow
+ long c = (t * t) % m;
+ if(e % 2 == 1)
+ c = (c * a) % m;
+ return (int) c;
+ }
+
+ public static double random(){ return java.lang.Math.random(); }
+
+ public static double[] randomSeq(int n){
+ int i;
+ double[] result = new double[n];
+ for(i=0; is...ie], NaN if no such value.
+ */
+ public static double stddev(double[] a, int is, int ie) {
+ return Math.sqrt(var(a, is, ie));
+ }
+
+ /**
+ * @param a array
+ * @return population standard deviation of array, NaN if no such value.
+ */
+ public static double stddevp(double[] a) {
+ return Math.sqrt(varp(a));
+ }
+
+ /**
+ * @param a array
+ * @param is first index
+ * @param ie last index
+ * @return population standard deviation of subarray a[is...ie], NaN if no such value.
+ */
+ public static double stddevp(double[] a, int is, int ie) {
+ return Math.sqrt(varp(a, is, ie));
+ }
+
+ /**
+ * @param a
+ * @return sum of all values in array.
+ */
+ public static int sum(int[] a) {
+ int i, sum = 0;
+ for(i=0; is...ie]
+ */
+ public static double sum(double[] a, int is, int ie) {
+ if(!inBounds(a, is, ie))
+ throw new RuntimeException("Subarray indices out of bounds");
+ int i;
+ double sum = 0.0;
+ for(i=is; i<=ie; i++)
+ sum += a[i];
+ return sum;
+ }
+
+ /**
+ * @param a
+ * @return sum of all values in array.
+ */
+ public static double sumAbs(double[] a) {
+ int i;
+ double sum = 0.0;
+ for(i=0; is...ie], NaN if no such value
+ */
+ public static double var(double[] a, int is, int ie) {
+ int length = ie - is + 1;
+ if(!inBounds(a, is, ie))
+ throw new RuntimeException("Subarray indices out of bounds");
+ if(length == 0) return Double.NaN;
+ int i;
+ double avg = mean(is, ie, a);
+ double sum = 0.0;
+ for(i=is; i<=ie; i++)
+ sum += (a[i] - avg) * (a[i] - avg);
+ return sum / (length - 1);
+ }
+
+ /**
+ * @param a array
+ * @return population variance of array, NaN if no such value
+ */
+ public static double varp(double[] a) {
+ int n = a.length;
+ if(n == 0) return Double.NaN;
+ int i;
+ double avg = mean(a);
+ double sum = 0.0;
+ for(i = 0; i < n; i++)
+ sum += (a[i] - avg) * (a[i] - avg);
+ return sum / n;
+ }
+
+ /**
+ * @param a array
+ * @param is first index
+ * @param ie last index
+ * @return population variance of subarray a[is...ie], NaN if no such value.
+ */
+ public static double varp(double[] a, int is, int ie) {
+ int length = ie - is + 1;
+ if(!inBounds(a, is, ie))
+ throw new RuntimeException("Subarray indices out of bounds");
+ if(length == 0) return Double.NaN;
+ double avg = mean(is, ie, a);
+ double sum = 0.0;
+ for (int i = is; i <= ie; i++) {
+ sum += (a[i] - avg) * (a[i] - avg);
+ }
+ return sum / length;
+ }
+
+ /**
+ * Bubble sort
+ * @param a array
+ */
+ public static void bubbleSort(double[] a){
+ int i;
+ double k;
+ for(i=0; i0; j--){
+ if(a[j-1] > a[j]){
+ k = a[j];
+ a[j] = a[j-1];
+ a[j-1] = k;
+ }
+ }
+ }
+ }
+
+ /**
+ * Merge sort
+ * @param a array
+ * @param l left index
+ * @param r right index
+ */
+ public static void mergeSort(double[] a, int l, int r) {
+ if (l < r){
+ int q = (l + r) / 2;
+ mergeSort(a, l, q);
+ mergeSort(a, q + 1, r);
+ merge(a, l, q, r);
+ }
+ }
+
+ // @see #mergeSort
+ private static void merge(double[] a, int l, int q, int r) {
+ double[] arr = new double[a.length];
+ int i, j, k;
+ for(i=l; i<=q; i++)
+ arr[i] = a[i];
+ for(j=q+1; j<=r; j++)
+ arr[r+q+1-j] = a[j];
+ i = l;
+ j = r;
+ for(k=l; k<=r; k++){
+ if(arr[i] <= arr[j]){
+ a[k] = arr[i];
+ i++;
+ } else {
+ a[k] = arr[j];
+ j--;
+ }
+ }
+ }
+
+ /**
+ * OETsort. Odd-Even-Transposition-Sort
+ * @param a array
+ */
+ public static void oetSort(double[] a){
+ int i, j;
+ double k;
+ for(i=0; ia[j+1]){
+ k = a[j];
+ a[j] = a[j+1];
+ a[j+1] = k;
+ }
+ }
+ }
+ }
+
+ /**
+ * quick sort.
+ * @param a array
+ */
+ public static void quickSort(double[] a){
+ quickSort(a, 0, a.length-1);
+ }
+
+ /**
+ * quick sort
+ * @param a array
+ * @param l left index
+ * @param r right index
+ */
+ public static void quickSort(double[] a, int l, int r){
+ int q;
+ if(l < r){
+ q = quickSortPartition(a, l, r);
+ quickSort(a, l, q);
+ quickSort(a, q + 1, r);
+ }
+ }
+
+ /**
+ * define partition index of quick sort algorithm.
+ * @param a array
+ * @param l left index
+ * @param r right index
+ * @return partitioned index
+ */
+ static int quickSortPartition(double[] a, int l, int r) {
+ int i, j;
+ double x = a[(l+r)/2];
+ i = l - 1;
+ j = r + 1;
+ do{ i++; } while(a[i] < x);
+ do{ j--; } while(a[j] > x);
+ if(ia[i+1]){
+ k = a[i];
+ a[i] = a[i+1];
+ a[i+1] = k;
+ switched = true;
+ }
+ }
+ } while (switched == true);
+ }
+
+ /**
+ * Select sort
+ * @param a array
+ */
+ public static void selectSort(double[] a){
+ int i, j, q;
+ double k;
+ for(i=a.length-1; i>=1; i--){
+ q = 0;
+ for(j=1; j<=i; j++)
+ if(a[j] > a[q])
+ q = j;
+ k = a[q];
+ a[q] = a[i];
+ a[i] = k;
+ }
+ }
+
+ /**
+ * Shaker sort
+ * @param a array
+ */
+ public static void shakerSort(double[] a){
+ int i = 0, l = a.length;
+ while(i < l) {
+ shaker1(a, i, l);
+ l--;
+ shaker2(a, i, l);
+ i++;
+ }
+ }
+
+ private static void shaker1(double[] a, int i, int l){
+ int j;
+ double k;
+ for(j=i; j a[j+1]){
+ k = a[j];
+ a[j] = a[j+1];
+ a[j+1] = k;
+ }
+ }
+ }
+
+ private static void shaker2(double[] a, int i, int l) {
+ int j;
+ double k;
+ for(j=l-1; j>=i; j--){ // decrement from upper index
+ if(a[j] > a[j+1]){
+ k = a[j];
+ a[j] = a[j+1];
+ a[j+1] = k;
+ }
+ }
+ }
+
+ /**
+ * complexity ~ O(N3/2)
+ * @param a array
+ */
+ public static void shellSort(double[] a){
+ int i, j, k, N = a.length;
+ double v;
+ for(k=1; k<=N/9; k=3*k+1) ;
+ for( ; k>0; k/=3)
+ for(i=k; i<=N; i++){
+ v = a[i-1];
+ j = i-1;
+ while(j>k-1 && a[j-k]>v){
+ a[j] = a[j-k];
+ j -= k;
+ }
+ a[j] = v;
+ }
+ }
+
+ /**
+ * Simple sort
+ * @param a array
+ */
+ public static void simpleSort(double[] a){
+ int i, j;
+ double k;
+ for(i=a.length-1; i>1; i--){
+ for(j=0; j<=i-1; j++){
+ if(a[j] >= a[i]){
+ k = a[i];
+ a[i] = a[j];
+ a[j] = k;
+ }
+ }
+ }
+ }
+
+ public static void print(double[] a){
+ System.out.print("[");
+ int i;
+ for(i=0; i1 +2*d2 + 3*d3 + ... + 10*d10
+ * is a multiple of 11.
+ * For example, 0-201-31452-5 is legal since
+ * 1*5 + 2*2 + 3*5 + 4*4 + 5*1 + 6*3 + 7*1 + 8*0 + 9*2 + 10*0 = 88
+ * and 88 is a multiple of 11.
+ * @param isbn number given the first 9 digits
+ * @return full isbn number, with check digit
+ * @see #isbnCheckDigit(String)
+ */
+ public static String isbn(String isbn){
+ System.out.println(isbn);
+ int checkDigit = isbnCheckDigit(isbn);
+ // return check digit, use X for 10
+ String result = "" + isbn;
+ if(checkDigit == 10) result += "X";
+ else result += checkDigit;
+ return result;
+ }
+
+ /**
+ * Determines if a VIN number is valid by computing its check digit.
+ * Do aggressive error checking.
+ *
+ * 1B4YEM9P4KP186543 : Invalid
+ * 1FA-CP45E-X-LF192944 : Valid
+ * 1FA-CP45E-6-LF192944 : Invalid
+ * QFA-CP45E-X-LF192944 :
+ * Exception in thread "main" java.lang.RuntimeException: Illegal character: Q
+ * 1FA-CP45E-G-LF192944 :
+ * Exception in thread "main" java.lang.RuntimeException: Illegal check digit: G
+ * 1FA-CP45E-X-LF19294 :
+ * Exception in thread "main" java.lang.RuntimeException: VIN number must be 17 characters
+ * @param s VIN number
+ * @return boolean true: valid, false: invalid
+ */
+ public static boolean vin(String s){
+ int[] values = { 1, 2, 3, 4, 5, 6, 7, 8, 0, 1,
+ 2, 3, 4, 5, 0, 7, 0, 9, 2, 3,
+ 4, 5, 6, 7, 8, 9 };
+ int[] weights = { 8, 7, 6, 5, 4, 3, 2, 10, 0, 9,
+ 8, 7, 6, 5, 4, 3, 2 };
+ s = s.replaceAll("-", "");
+ s = s.toUpperCase();
+ if(s.length() != 17)
+ throw new RuntimeException("VIN number must be 17 characters");
+ int sum = 0;
+ int i;
+ for(i=0; i<17; i++){
+ char c = s.charAt(i);
+ int value;
+ int weight = weights[i];
+ // letter
+ if(c >= 'A' && c <= 'Z') {
+ value = values[c - 'A'];
+ if(value == 0)
+ throw new RuntimeException("Illegal character: " + c);
+ }
+ // number
+ else if(c >= '0' && c <= '9') value = c - '0';
+ // illegal character
+ else throw new RuntimeException("Illegal character: " + c);
+ sum = sum + weight * value;
+ }
+ // check digit
+ sum = sum % 11;
+ char check = s.charAt(8);
+ if(check != 'X' && (check < '0' || check > '9'))
+ throw new RuntimeException("Illegal check digit: " + check);
+ if (sum == 10 && check == 'X') return true; // System.out.println("Valid");
+ else if(sum == check - '0') return true; // System.out.println("Valid");
+ else return false; // System.out.println("Invalid");
+ }
+
+ /**
+ * @param n oder of matrix
+ * @return Hadamard matrix of order N. Assumes N is a power of 2.
+ */
+ public static boolean[][] hadarmad(int n){
+ int i, j, k;
+ boolean[][] H = new boolean[n][n];
+ // initialize Hadamard matrix of order N
+ H[0][0] = true;
+ for(k=1; ks is greater than ie and 0 and
+ * if ie is lower than array.length
+ */
+ public static boolean inBounds(int[] a, int is, int ie){
+ return(is>0 && ies is greater than ie and 0 and
+ * if ie is lower than array.length
+ */
+ public static boolean inBounds(double[] a, int is, int ie){
+ return(is>0 && ie= 1582, corresponding to a year in the Gregorian calendar.
+ */
+ public static boolean isLeapYear(double year){
+ // divisible by 4 and not 100 unless divisible by 400
+ return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
+ }
+
+ /**
+ * @param i value
+ * @param j value
+ * @return true or false if i divides j or j divides i
+ */
+ public static boolean itDivides(double i, double j){
+ return (i % j == 0 || j % i == 0);
+ }
+
+ public static boolean isPrime(int number){
+ boolean isPrime = true;
+ if (number < 2) isPrime = false;
+
+ // try all possible factors i of N
+ // if if N has a factor, then it has one less than or equal to sqrt(N),
+ // so for efficiency we only need to check i <= sqrt(N) or equivalently i*i <= N
+ for(long i = 2; i*i <= number; i++) {
+
+ // if i divides evenly into N, N is not prime, so break out of loop
+ if(number % i == 0) {
+ isPrime = false;
+ break;
+ }
+ }
+ return isPrime;
+ }
+
+ /**
+ * Angle from radians to degrees
+ * @param angrad an angle, in radians
+ * @return degrees
+ */
+ public static double toDeg(double angrad){ return angrad*180/π; }
+
+ /**
+ * Angle from degrees to radians
+ * @param angdeg - an angle, in degrees
+ * @return radians
+ */
+ public static double toRad(double angdeg){ return angdeg*π/180; }
+
+ /**
+ * @param a number
+ * @return a in binary
+ * @see Integer#toBinaryString(int)
+ */
+ public static int toBinary(int a){
+ boolean isNegative = a<0;
+ if(isNegative) a *= -1;
+ // set v to the largest power of two that is <= a
+ int v = 1;
+ String result = "";
+ while(v <= a/2)
+ v = v * 2;
+ // check for presence of powers of 2 in a, from largest to smallest
+ while(v > 0){
+ if(a < v) // v is not present in n
+ result += "0";
+ else { // v is present in n, so remove v from n
+ result += "1";
+ a = a - v;
+ }
+ v = v / 2; // next smallest power of 2
+ }
+ return Integer.valueOf(result);
+ }
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ double[] numbers = new double[]{26.1, 25.6, 25.7, 25.2, 25.0};
+ System.out.println(Arrays.toString(numbers));
+ Arrays.sort(numbers);
+ System.out.println(Arrays.toString(numbers));
+ double[] numbers2 = new double[]{26.1, 25.6, 25.7, 25.2, 25.0, 24.7};
+
+ System.out.println(toBinary(16));
+
+ System.out.println(Arrays.toString(sample(6, 49)));
+
+ System.out.println("sqrt(5) = "+sqrt(5));
+ System.out.println("sqrt(5) = "+Math.sqrt(5));
+
+ System.out.println("hypo/sqrt(3^2+4^2) = "+hypot(3, 4)+" : "+(hypot(3, 4)==5.));
+
+ System.out.println("The full ISBN number of 020131452 is " + isbn("020131452"));
+
+ double mean;
+ mean = Maths.mean(numbers);
+ System.out.println(mean);
+
+ double median;
+ median = Maths.median(numbers);
+ System.out.println(median);
+ median = Maths.median(numbers2);
+ System.out.println(median);
+
+ System.out.println(decimalPlaces(10));
+ System.out.println(decimalPlaces(0.01));
+
+ System.out.println(factorial(20));
+ System.out.println(factorial(40));
+
+ double[] a = new double[]{0.1, 0.4, 0.3};
+ // Convert command-line arguments to array of doubles and call various methods.
+ if(args.length!=0) a = StdArrayIO.readDouble1D(); // Maths.java < 0.1 0.4 0.3
+ StdOut.printf(" min %7.3f\n", min(a));
+ StdOut.printf(" mean %7.3f\n", mean(a));
+ StdOut.printf(" max %7.3f\n", max(a));
+ StdOut.printf(" std dev %7.3f\n", stddev(a));
+
+ System.out.println("\nShellSort demo");
+ java.util.Random rg = new java.util.Random();
+ a = new double[30];
+ int i;
+ for(i=0; i