Sunday, October 18, 2015

Hanoi towers in Java

Here is the code:

package sample;

import java.util.ArrayList;

/**
 * Created by IDEA on 31/07/15.
 */
public class Hanoi {
    final ArrayList<Integer> tower1;
    final ArrayList<Integer> tower2;
    final ArrayList<Integer> tower3;
    final ArrayList<ArrayList<Integer>> towers;

    public Hanoi(int n) {
        tower1 = new ArrayList<>();
        tower2 = new ArrayList<>();
        tower3 = new ArrayList<>();
        towers = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            tower1.add(i, new Integer(n - i));
        }
        towers.add(tower1);
        towers.add(tower2);
        towers.add(tower3);
    }

    public Hanoi() {
        this(3);
    }

    public ArrayList<ArrayList<ArrayList<Integer>>> moveDisks(ArrayList<ArrayList<Integer>> towers, int source, int target, int aux) throws Exception {
        ArrayList<ArrayList<ArrayList<Integer>>> res = new ArrayList<>();
        ArrayList<ArrayList<Integer>> towersCopy1 = deepCopy(towers);
        ArrayList<ArrayList<Integer>> towersCopy2 = deepCopy(towers);
        if (towersCopy2.get(source).size() == 1) {
            // The base case: source (1st) tower has only one disk
            towersCopy2.get(target).add(towersCopy2.get(source).get(0));
            towersCopy2.get(source).remove(0);
            res.add(towersCopy2);
            return res;
        } else {
            Integer baseDisk = towersCopy2.get(source).get(0);
            towersCopy2.get(source).remove(0);
            // Step 1: move all disks from source tower to auxiliary tower (except the base disk)
            ArrayList<ArrayList<ArrayList<Integer>>> subRes1 = moveDisks(towersCopy2, source, aux, target);
            for(ArrayList<ArrayList<Integer>> ts: subRes1) {
                ts.get(source).add(0, baseDisk);
            }
            res.addAll(subRes1);
            // Step 2: move the base disk to target tower
            ArrayList<ArrayList<ArrayList<Integer>>> subRes2 = moveDisks(res.get(res.size() - 1), source, target, aux);
            res.addAll(subRes2);
            // Step 3: move the other disks to target tower (from the auxiliary tower)
            ArrayList<ArrayList<ArrayList<Integer>>> subRes3 = moveDisks(res.get(res.size() - 1), aux, target, source);
            res.addAll(subRes3);
            return res;
        }
    }

    public ArrayList<ArrayList<ArrayList<Integer>>> moveDisks() throws Exception {
        return moveDisks(towers, 0, 1, 2);
    }

    public ArrayList<ArrayList<Integer>> deepCopy(ArrayList<ArrayList<Integer>> a) {
        ArrayList<ArrayList<Integer>> a1 = new ArrayList<>();
        for (ArrayList<Integer> i : a) {
            a1.add(new ArrayList<>(i));
        }
        return a1;
    }

    public void printTowersList(ArrayList<ArrayList<ArrayList<Integer>>> tsl) {
        for(ArrayList<ArrayList<Integer>> ts: tsl) {
            System.out.println("\n\n=====================");
            for(ArrayList<Integer> t: ts) {
                System.out.print("| ");
                for(Integer i: t) {
                    System.out.print(i + " ");
                }
                System.out.println();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Hanoi hanoi = new Hanoi();
        ArrayList<ArrayList<ArrayList<Integer>>> hanoiRes = hanoi.moveDisks();
        hanoi.printTowersList(hanoiRes);
    }
}

0 comments: