Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Wednesday, March 18, 2015

100th Comic

Today I've published 100 comics since starting my Amphibian.com webcomics on August 1, 2014. I feel like that's a major accomplishment. At least it's a large number. Not large like the national debt of the United States or Apple's market capitalization or anything, but pretty big.

A long time ago in a galaxy far, far away (okay maybe like 22 years ago in Port Royal, Pennsylvania) I did a comic about a frog that ran weekly in a local newspaper. At one comic per week, it took me nearly 2 years to reach 100. I guess it's really not that impressive, since Garfield reached 100 comics published in under 17 weeks.

But you know what I don't like about the number 100? It's not prime. 101 is though. If you ever want to calculate a list of prime numbers, you can use the Sieve of Eratosthenes. It is a very efficient algorithm for finding "smaller" primes (the primes that normal people would want, if normal people want primes at all). I implemented it once in Java.

public class SieveOfEratosthenes {

    /**
     * Uses the Sieve of Eratosthenes to calculate an array of prime
     * numbers up to a given maximum number.
     * 
     * @param max the highest number to consider for primeness
     * @return an array containing prime numbers
     */
    private static int[] getPrimes(int max) {

        if (max < 2) {
            return new int[0];
        }

        int size = ( max % 2 == 0 ? max/2 : (max/2)+1 );
        int[] nums = new int[size];
        nums[0] = 2; // 2 is the first prime and only even prime
        // we'll fill the rest of the array with the odds,
        // since we know that all the evens will just be removed anyway
        int n = 3; 
        for (int i = 1; i < nums.length; i++) {
            nums[i] = n;
            n = n + 2;
        }

        // we can stop when we get past the square root of max
        int sqRoot = (int) Math.sqrt(max);
        int idx = 0;
        int f = nums[idx];
        while (f <= sqRoot) {

            if (f != -1) {

                // "remove" all numbers that are multiples of f.
                // basically that just means set them to -1 and 
                // ignore them in the future.
                for (int j = idx+1; j < nums.length; j++) {
                    int num = nums[j];
                    if (num != -1) {
                        if (num % f == 0) {
                            nums[j] = -1;
                        }
                    }
                }

            }

            f = nums[idx++];

        }
  
        // clean up the list (remove the -1's)
        int marker = 0;
        int index = 0;
        int lastPrimeIndex = 0;
        while (index < nums.length) {
            if (nums[index] != -1) {
                lastPrimeIndex = marker;
                marker++;
            } else {
                for (int k = marker; k < nums.length; k++) {
                    if (nums[k] != -1) {
                        nums[index] = nums[k];
                        nums[k] = -1;
                        if (index > lastPrimeIndex) {
                            lastPrimeIndex = index;
                        }
                        marker = k+1;
                        break;
                    }
                }
            }
            index++;
        }

        int[] ret = new int[lastPrimeIndex+1];
        System.arraycopy(nums, 0, ret, 0, lastPrimeIndex+1);

        return ret;

    }

    public static void main(String[] args) {

        if (args.length < 1) {
            System.out.println("no arguments given");
            System.exit(1);
        } else {

            int largest = 0;
            try {
                largest = Integer.parseInt(args[0]);
            } catch (NumberFormatException nfe) {
                System.out.println(args[0] + " is not an integer");
                System.exit(1);
            }

            int[] primes = getPrimes(largest);

            // print out the list
            for (int i = 0; i < primes.length; i++) {
                if (i > 0) {
                    System.out.print(',');
                }
                System.out.print(primes[i]);
            }

        }

    }

}

Give that class a command-line argument of an integer and it will return you a list of prime numbers up to and including that number. I'll warn you though, very large numbers will take a while to calculate.

Today's comic includes multiple references to the number 100, which is a fine number to use as input to the sieve.

Amphibian.com comic for 18 March 2015

Monday, March 9, 2015

Plants Don't Do Math

There's no evidence that plants have any kind of higher-order cognitive abilities. They can't really perform calculations. So why do so many of them exhibit Fibonacci's sequence in their leaf arrangements, florets, etc.? Old Fib's sequence also provides us with a good way to estimate the Golden Ratio, which is an irrational number. And the Golden Spiral that is made using the Golden Ratio also appears in sunflower seed arrangements, as well as the shells of marine animals.

What's going on?

It turns out that these arrangements in nature seem to be the best ways to maximize space. The Golden Spiral is the best way to pack the most seeds into the head of the sunflower, for example.

Golden Spirals in a sunflower
To estimate the Golden Ratio using the Fibonacci Sequence, just take any two of the adjacent numbers and divide the larger by the smaller. It works better with the larger numbers. Take 6765 divided by 4181 (the 21st and 20th numbers), for example. That equals 1.618034, which is a pretty close estimate. Humans love the Golden Ratio - it seems to touch on something deep within our brains. It shows up all the time in architecture and art - sometimes not intentionally.

Fish scales, however, seem to be arranged randomly. So fish aren't that cool. I thought that I read years ago how fish scales are arranged in a way related to Fibonacci's Sequence, which is why this subject is tied to today's comic (which includes the trout again). However, a search on the subject turned up no evidence and I have to conclude that either my memory is faulty or my information was bad. Probably my memory.

But since we're here, if you'd like to calculate the first n Fibonacci numbers or the nth number in the sequence, you can use a recursive function. I wrote this one a while back in Java. It takes a number n as a command-line argument and prints out, one per line, the first n numbers in the sequence.

public class Fibonacci {

    /**
     * Calculate the (n+1)th number in the Fibonacci Sequence.
     * For example, 0 will give you the first number (0), 1 the
     * second number (1), 2 the third number (1), and so on.
     * 
     * @param n the sequence number
     * @return the value of that position in the sequence
     */
    private static int fib(int n) {

        if (n == 0) {
            return 0;
        } else if (n == 1) {
            return 1;
        } else {
            return fib(n-1) + fib(n-2);
        }

    }

    public static void main(String[] args) {

        if (args.length < 1) {
            System.out.println("no arguments given");
            System.exit(1);
        } else {

            int f = 0;
            try {
                f = Integer.parseInt(args[0]);
            } catch (NumberFormatException nfe) {
                System.out.println(args[0] + " is not an integer");
                System.exit(1);
            }

            for(int i = 0; i < f; i++) {
                System.out.println(fib(i));
            }

        }
    }
}

The function is really simple, since the method of calculation is so simple. The first number in the sequence is 0 and the second number is 1. So there are two cases to end the recursion. For all others, the function just calls itself for the previous 2 numbers and adds them together. I love recursion. And frogs.

Amphibian.com comic for 9 March 2015

Friday, September 26, 2014

Why Do I Write Code in [insert language here]?

Starting this past Wednesday and continuing today (it will go on into next week if you must know), the frogs in my comic have hired some pythons to write software because they heard it was trendy. For the record, the Python programming language was named after Monty Python, not a snake, but that makes little difference when you are trying to select a language for a new project.

So the question is, do you pick a language to code in because it is practical or because it is popular?

And how do you even measure a programming language's popularity?

It turns out there are several groups that try to measure language popularity utilizing different methods. Take a look at the following...
So by most measures, Java and C remain very popular. It's important to see this in real objective data, because sometimes our understanding of programming language popularity becomes skewed by media attention. Often, languages that people talk about very much are used very little in production systems.

I found that all very interesting, but when I am starting a project (or re-starting, or upgrading) I try to pick the most appropriate language for the job. If there is more than one viable language for my system requirements, I pick the one that is most familiar to the team (which may be just myself). In other words, I tend to take a very practical approach to language selection.

Sometimes there is little choice. If you want to create an iOS application, your options are very constrained. This kind of specialization in certain product spaces is nothing new. When I was writing BBS Door Games in 1995, nearly all development was done in Pascal. I don't know why, I didn't really question those types of things back then. Of course, I only knew of 3 programming languages at the time...

Other times there is too much choice. If you want to build a web application, your options are nearly limitless. Personally, I have written REST web service applications in Java for a WebLogic application server and in JavaScript for Node.js. The JavaScript ones tend to be easier to write, but that doesn't mean that it's always the better choice. Knowing your particular requirements and the properties of a number of languages are the keys to making the right decision.

The take away from this is that if you want to be an extremely effective software engineer, you should be familiar with many languages and not be afraid to learn new ones. If you pick a bad one for a project, at least it's a learning experience. Don't make the same mistake again, even if it means learning something completely new.

Amphibian.com comic for September 26, 2014