Panda
Panda

Reputation: 527

How to print an unequal row length matrix in spiral form?

I have a matrix like this:

{
  {4,5,6,7,8},
  {2,3,1,4},
  {1,2},
  {1,2,3,4,5}
  {5,6,7,8}
}

I want to print this in spiral way, so the output should be: 4 5 6 7 8 4 2 5 8 7 6 5 1 1 1 3 1 4 3 2

The code I currently have for spiral matrix is like this:

void spiral(int a[][]) { 
    int i, k = 0, l = 0, m = a.length, n = a[0].length; 

    while (k < m && l < n) { 
        for (i = l; i < n; ++i) { 
            System.out.print(a[k][i] + " "); 
        } 
        k++; 

        for (i = k; i < m; ++i) { 
            System.out.print(a[i][n - 1] + " "); 
        } 
        n--; 

        if (k < m) { 
            for (i = n - 1; i >= l; --i) { 
                System.out.print(a[m - 1][i] + " "); 
            } 
            m--; 
        }

        if (l < n) { 
            for (i = m - 1; i >= k; --i) { 
            System.out.print(a[i][l] + " "); 
        } 
        l++; 
    } 
} 

The problem is that I am not able to understand how to make it work for unequal array length rows. I would really appreciate any help and insight in this.

Upvotes: 0

Views: 151

Answers (1)

Ryan
Ryan

Reputation: 1760

Here's my solution to it. It can probably be more efficient, but it works:

public static void main(String [] args) throws ScriptException {
    Integer [][] input = new Integer[][] {
                                    {4,5,6,7,8},
                                    {2,3,1,4},
                                    {1,2},
                                    {1,2,3,4,5},
                                    {5,6,7,8}
                                };

   List<List<Integer>> list = listify(input);
   processSpiral(list);
}

private static <T> void processSpiral(List<List<T>> list) {
    if (!list.isEmpty()) {
        printTop(list);
        list.removeIf(l -> l.isEmpty());
        printLast(list);
        list.removeIf(l -> l.isEmpty());
        printBottom(list);
        list.removeIf(l -> l.isEmpty());
        printFirst(list);
        list.removeIf(l -> l.isEmpty());
        processSpiral(list);
    }
}

private static <T> void printFirst(List<List<T>> list) {
    if (!list.isEmpty()) {
        for (int i = list.size() -1; i >= 0; i --) {
            List<T> row = list.get(i);
            if (!row.isEmpty()) {
                System.out.print(String.format("%s ", row.get(0).toString()));
                row.remove(0);
            }
        }
    }
}

private static <T> void printBottom(List<List<T>> list) {
    if (!list.isEmpty()) {
        List<T> bottomRow = list.get(list.size() - 1);
        Collections.reverse(bottomRow);
        for (T i : bottomRow) {
            System.out.print(String.format("%s ", i.toString()));
        }
        list.remove(list.size() - 1);
    }
}
private static <T> void printLast(List<List<T>> list) {
    list.stream()
        .filter(l -> !l.isEmpty())
        .forEach(l -> {
            T i = l.get(l.size() - 1);
            System.out.print(String.format("%s ", i.toString()));
            l.remove(l.size() - 1);
        });
}
private static <T> void printTop(List<List<T>> list) {
    List<T> firstRow = list.get(0);
    list.remove(0);
    //print the first row
    for (T i : firstRow) {
        System.out.print(String.format("%s ", i.toString()));
    }
}

private static <T> List<List<T>> listify(T [][] input) {
    //convert to List of List for simplicity's sake
    List<List<T>> list = new ArrayList<>();
    for (T [] row : input) {
        //do not use Arrays.asList() as that creates an immutable List
        List<T> l = new ArrayList<>(row.length);
        for (T i : row) {
            l.add(i);
        }
        list.add(l);
    }

    return list;
}

Upvotes: 1

Related Questions