Archive for the 'Java' Category

Quiz: Count the ways to find a word by walking on a grid (5)

Thursday, April 3rd, 2008
/*
 * Author : David Tran
 * Date   : 2008-04-03
 * Quiz   : CountPaths
 */

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Quiz4 {
    
    public static void main(String[] args) throws Exception {
        new Quiz4().solve();
    }

    public void solve() {
        long start = System.currentTimeMillis();
        loadProblem();
        BigInteger solutions = BigInteger.ZERO;
        for (int index : starts) {
            solutions = solutions.add(findSolution(index / cols, index % cols, 0));
        }
        System.out.println("Total Solution = " + solutions);
        System.out.println("Total time (msec) to solve = " + (System.currentTimeMillis() - start));
    }
    
    public Quiz4() throws Exception {
        rows = 50;
        cols = 50;
        cellLength = 1;
        goal = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; // 50x"A"
        gridData = new String[rows][cols];  // 50×50x"A"
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                gridData[i][j] = "A";
            }
        }
    }
    
    private int rows;
    private int cols;
    private int lastNumber;
    private List<Integer> starts;
    private Map<Integer, BigInteger>[][] grid;

    private int cellLength;
    private String goal;
    private String[][] gridData;
    
    
    @SuppressWarnings("unchecked")
    private void loadProblem() {
        // split goal string to build up dictionary
        Map<String, List<Integer>> dictionary = new HashMap<String, List<Integer>>();
        for (int nb = 0, position = 0, length = goal.length(); position < length; nb++, position += cellLength) {
            String substring = goal.substring(position, position + cellLength);
            if (dictionary.containsKey(substring)) {
                dictionary.get(substring).add(nb);
            } else {
                List<Integer> values = new ArrayList<Integer>();
                values.add(nb);
                dictionary.put(substring, values);
            }
        }
        if (dictionary.size() <= 0) {
            throw new IllegalArgumentException("No input data ?!");
        }
        
        lastNumber = (goal.length() / cellLength) - 1;
        starts = new ArrayList<Integer>();
        grid = (Map<Integer, BigInteger> [][]) new Map[rows][cols];
        
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                String key = gridData[i][j];
                if (dictionary.containsKey(key)) {
                    Map<Integer, BigInteger> map = new HashMap<Integer, BigInteger>();
                    for (int nb : dictionary.get(key)) {
                        map.put(nb, null);
                        if (nb == 0) {
                            starts.add(i * cols + j);
                        }
                    }
                    grid[i][j] = map;
                }
            }
        }
    }
    
    private BigInteger findSolution(int i, int j, int nb) {
        if (nb == lastNumber) {
            return BigInteger.ONE;
        } else {
            BigInteger solutions = grid[i][j].get(nb);
            if (solutions == null) {
                solutions = BigInteger.ZERO;
                for (int index : findNeighbors(i, j, nb)) {
                    solutions = solutions.add(findSolution(index / cols, index % cols, nb + 1));
                }
                grid[i][j].put(nb, solutions);
            }
            return solutions;
        }
    }
    
    private List<Integer> findNeighbors(int i, int j, int nb) {
        int nextNb = nb + 1;
        List<Integer> neighbors = new ArrayList<Integer>();
        addNeighbor(i - 1, j - 1, nextNb, neighbors);
        addNeighbor(i - 1, j    , nextNb, neighbors);
        addNeighbor(i - 1, j + 1, nextNb, neighbors);
        addNeighbor(i    , j - 1, nextNb, neighbors);
        addNeighbor(i    , j + 1, nextNb, neighbors);
        addNeighbor(i + 1, j - 1, nextNb, neighbors);
        addNeighbor(i + 1, j    , nextNb, neighbors);
        addNeighbor(i + 1, j + 1, nextNb, neighbors);
        return neighbors;
    }
    
    private void addNeighbor(int i, int j, int nb, List<Integer> list) {
        if (i >= 0 && i < rows && j >= 0 && j < cols && 
                grid[i][j] != null && grid[i][j].containsKey(nb)) {
            list.add(i * cols + j);
        }
    }
}

Result on my machine:


A:>java Quiz4
Total Solution = 303835410591851117616135618108340196903254429200
Total time (msec) to solve = 562

Quiz: Count the ways to find a word by walking on a grid (3)

Monday, March 31st, 2008


/*
 * Author : David Tran
 * Date   : 2008-03-31
 * Quiz   : see  http://davidtran.doublegifts.com/blog/?p=140
 * Note   : Revise previous version, improve it to use less memory and much faster.
 *          Instead of caching neighbors, this time it caches the solutions number. 
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Quiz2 {
    
    public static void main(String[] args) {
        new Quiz2().solve();
    }

    public void solve() {
        loadProblem();
        int solutions = 0;
        for (int index : starts) {
            solutions += findSolution(index / cols, index % cols, 0);
        }
        System.out.println("Total Solution = " + solutions);
    }
    
    private int rows;
    private int cols;
    private int lastNumber;
    private List<Integer> starts;
    private Map<Integer, Integer>[][] grid;  // key=position in goal;value=number solutions
    
    @SuppressWarnings("unchecked")
    private void loadProblem() {
        // to simplify, we hard-coded the problem data for now.
        // and skip all preconditions checking:
        // *   0 < rows, cols, goal’s length, cell’s length <= 50
        // *   all cell have the exact cellLength length
        // *   goal’s length modulo cell’s length == 0
        
        rows = 3;
        cols = 3;
        int cellLength = 2;
        String[][] gridData = {
            {"AA", "BB", "CZ"},
            {"FF", "EE", "DD"},
            {"GX", "AA", "IY"},
        };
        String goal = "AAEEAA";

        // split goal string to build up dictionary
        Map<String, List<Integer>> dictionary = new HashMap<String, List<Integer>>();
        for (int nb = 0, position = 0, length = goal.length(); position < length; nb++, position += cellLength) {
            String substring = goal.substring(position, position + cellLength);
            if (dictionary.containsKey(substring)) {
                dictionary.get(substring).add(nb);
            } else {
                List<Integer> values = new ArrayList<Integer>();
                values.add(nb);
                dictionary.put(substring, values);
            }
        }
        if (dictionary.size() <= 0) {
            throw new IllegalArgumentException("No input data ?!");
        }
        
        lastNumber = (goal.length() / cellLength) - 1;
        starts = new ArrayList<Integer>();
        grid = (Map<Integer, Integer> [][]) new Map[rows][cols];
        
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                String key = gridData[i][j];
                if (dictionary.containsKey(key)) {
                    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
                    for (int nb : dictionary.get(key)) {
                        map.put(nb, null);
                        if (nb == 0) {
                            starts.add(i * cols + j);
                        }
                    }
                    grid[i][j] = map;
                }
            }
        }
    }
    
    private int findSolution(int i, int j, int nb) {
        int solutions = 0;
        if (nb == lastNumber) {
            solutions = 1;
        } else {
            if (grid[i][j].get(nb) != null) {
                solutions = grid[i][j].get(nb);
            } else {
                for (int index : findNeighbors(i, j, nb)) {
                    solutions += findSolution(index / cols, index % cols, nb + 1);
                }
                grid[i][j].put(nb, solutions);
            }
        }
        return solutions;
    }
    
    private List<Integer> findNeighbors(int i, int j, int nb) {
        int nextNb = nb + 1;
        List<Integer> neighbors = new ArrayList<Integer>();
        addNeighbor(i - 1, j - 1, nextNb, neighbors);
        addNeighbor(i - 1, j    , nextNb, neighbors);
        addNeighbor(i - 1, j + 1, nextNb, neighbors);
        addNeighbor(i    , j - 1, nextNb, neighbors);
        addNeighbor(i    , j + 1, nextNb, neighbors);
        addNeighbor(i + 1, j - 1, nextNb, neighbors);
        addNeighbor(i + 1, j    , nextNb, neighbors);
        addNeighbor(i + 1, j + 1, nextNb, neighbors);
        return neighbors;
    }
    
    private void addNeighbor(int i, int j, int nb, List<Integer> list) {
        if (i >= 0 && i < rows && j >= 0 && j < cols && 
                grid[i][j] != null && grid[i][j].containsKey(nb)) {
            list.add(i * cols + j);
        }
    }
}

Quiz: Count the ways to find a word by walking on a grid (2)

Saturday, March 29th, 2008


/*
 * Author : David Tran
 * Date   : 2008-03-29
 * Quiz   : see  http://davidtran.doublegifts.com/blog/?p=139
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

public class Quiz {
    
    public static void main(String[] args) {
        new Quiz().solve();
    }

    public void solve() {
        loadProblem();
        for (int index : starts) {
            findSolution(index / cols, index % cols, 0);
        }
        System.out.println("Total Solution = " + solutions);
    }
    
    private int rows;
    private int cols;
    private int lastNumber;
    private int solutions;
    private List<Integer> starts;
    private Map<Integer, List<Integer>>[][] grid;
    
    @SuppressWarnings("unchecked")
    private void loadProblem() {
        // to simplify, we hard-coded the problem data for now.
        // and skip all preconditions checking:
        // *   0 < rows, cols, goal’s length, cell’s length <= 50
        // *   all cell have the exact cellLength length
        // *   goal’s length modulo cell’s length == 0
        
        rows = 3;
        cols = 3;
        int cellLength = 2;
        String[][] gridData = {
            {"AA", "BB", "CZ"},
            {"FF", "EE", "DD"},
            {"GX", "AA", "IY"},
        };
        String goal = "AAEEAA";

        /* - - - - - - - - - - - - 
        int cellLength = 1;
        String[][] gridData = {
            {"A", "B", "C"},
            {"D", "E", "F"},
            {"G", "A", "I"},
        };
        String goal = "AEA";
         - - - - - - - - - - - - */
        
        // split goal string to build up dictionary
        Map<String, List<Integer>> dictionary = new HashMap<String, List<Integer>>();
        for (int nb = 0, position = 0, length = goal.length(); position < length; nb++, position += cellLength) {
            String substring = goal.substring(position, position + cellLength);
            if (dictionary.containsKey(substring)) {
                dictionary.get(substring).add(nb);
            } else {
                List<Integer> values = new ArrayList<Integer>();
                values.add(nb);
                dictionary.put(substring, values);
            }
        }
        if (dictionary.size() <= 0) {
            throw new IllegalArgumentException("No input data ?!");
        }
        
        lastNumber = (goal.length() / cellLength) - 1;
        starts = new ArrayList<Integer>();
        grid = (Map<Integer, List<Integer>> [][]) new Map[rows][cols];
        
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                String key = gridData[i][j];
                if (dictionary.containsKey(key)) {
                    Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
                    for (int nb : dictionary.get(key)) {
                        map.put(nb, null);
                        if (nb == 0) {
                            starts.add(i * cols + j);
                        }
                    }
                    grid[i][j] = map;
                }
            }
        }
    }
   
    private Stack<String> stack = new Stack<String>();
    private void findSolution(int i, int j, int nb) {
        stack.push("(" + i + "," + j + ") ");
        if (nb == lastNumber) {
            solutions++;
            System.out.println(stack);
        } else {
            if (grid[i][j].get(nb) == null) {
                findNeighbors(i, j, nb);
            }
            for (int index : grid[i][j].get(nb)) {
                findSolution(index / cols, index % cols, nb + 1);
            }
        }
        stack.pop();
    }
    
    private void findNeighbors(int i, int j, int nb) {
        int nextNb = nb + 1;
        List<Integer> neighbors = new ArrayList<Integer>();
        addNeighbor(i - 1, j - 1, nextNb, neighbors);
        addNeighbor(i - 1, j    , nextNb, neighbors);
        addNeighbor(i - 1, j + 1, nextNb, neighbors);
        addNeighbor(i    , j - 1, nextNb, neighbors);
        addNeighbor(i    , j + 1, nextNb, neighbors);
        addNeighbor(i + 1, j - 1, nextNb, neighbors);
        addNeighbor(i + 1, j    , nextNb, neighbors);
        addNeighbor(i + 1, j + 1, nextNb, neighbors);
        grid[i][j].put(nb, neighbors);
    }
    
    private void addNeighbor(int i, int j, int nb, List<Integer> list) {
        if (i >= 0 && i < rows && j >= 0 && j < cols && 
                grid[i][j] != null && grid[i][j].containsKey(nb)) {
            list.add(i * cols + j);
        }
    }
}

Regexp and Prime numbers

Tuesday, April 24th, 2007

There is one-liner script that will tell you if a given number is prime.
It checks for primality with a regexp.

Original perl code:
Abigail’s code:

perl -wle 'print "Prime" if (1 x shift) !~ /^1?$|^(11+?)\1+$/'

Full explanation:
http://montreal.pm.org/tech/neil_kandalgaonkar.shtml

Ruby version:

ruby -wle 'puts "Prime" unless ("1" * ARGV[0].to_i) =~ /^1$|^(11+?)\1+$/' [number]

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/244371
http://snippets.dzone.com/posts/show/3691

Python version:
http://jtauber.com/blog/2007/03/18/python_primality_regex



I couldn’t resist porting it to Java, so here is my Java version (It is not one-liner, but maybe one statement?) :

public class PrimeTester {
  public static void main(String[] args) {
    System.out.println(String.format("%0" + args[0] + "d", 0).matches("^0$|^(00+?)\\1+$") ? "Not prime" : "Prime");
  }
}

public class PrimeTester {

  public static boolean isPrime(int number) {
    return !String.format("%0" + number + "d", 0).matches("^0$|^(00+?)\\1+$");
  }

  public static void main(String[] args) {
    System.out.println(isPrime(Integer.parseInt(args[0])) ? "Prime" : "Not prime");
  }
}