package leetcode;

import java.util.ArrayList;
import java.util.List;

/**
 * https://leetcode.com/problems/mini-parser/
 */
public class Problem385 {
    public static class NestedInteger {
        private Integer value;
        private final List<NestedInteger> nested = new ArrayList<>();

        // Constructor initializes an empty nested list.
        public NestedInteger() {
        }

        // Constructor initializes a single integer.
        public NestedInteger(int value) {
            this.value = value;
        }

        // @return true if this NestedInteger holds a single integer, rather than a nested list.
        public boolean isInteger() {
            return value != null;
        }

        // @return the single integer that this NestedInteger holds, if it holds a single integer
        // Return null if this NestedInteger holds a nested list
        public Integer getInteger() {
            return isInteger() ? value : null;
        }

        // Set this NestedInteger to hold a single integer.
        public void setInteger(int value) {
            this.value = value;
        }

        // Set this NestedInteger to hold a nested list and adds a nested integer to it.
        public void add(NestedInteger ni) {
            nested.add(ni);
        }

        // @return the nested list that this NestedInteger holds, if it holds a nested list
        // Return null if this NestedInteger holds a single integer
        public List<NestedInteger> getList() {
            return isInteger() ? null : nested;
        }

        @Override
        public String toString() {
            return isInteger() ? Integer.toString(value) : nested.toString();
        }
    }

    private static class Token {
        private final String string;
        private int idx;

        public Token(String s) {
            this.string = s;
        }

        private boolean end() {
            return idx == string.length();
        }

        public char peek() {
            return string.charAt(idx);
        }

        public char next() {
            return string.charAt(idx++);
        }
    }

    public NestedInteger deserialize(String s) {
        return deserialize(new Token(s));
    }

    private static NestedInteger deserialize(Token token) {
        NestedInteger ni = new NestedInteger();
        while (!token.end()) {
            char c = token.peek();
            if (isNumber(c)) {
                Integer number = parseNumber(token);
                ni.add(new NestedInteger(number));
            } else if (c == '[') {
                token.next();
                ni.add(deserialize(token));
            } else if (c == ',') {
                token.next();
            } else if (c == ']') {
                token.next();
                break;
            }
        }
        return ni;
    }

    private static boolean isNumber(char c) {
        return c == '-' || (c >= '0' && c <= '9');
    }

    private static Integer parseNumber(Token token) {
        StringBuilder sb = new StringBuilder();
        while (!token.end() && isNumber(token.peek())) {
            sb.append(token.next());
        }
        return Integer.valueOf(sb.toString());
    }

    public static void main(String[] args) {
        Problem385 prob = new Problem385();

        System.out.println(prob.deserialize("324").getList());
        System.out.println(prob.deserialize("[123,324]").getList());
        System.out.println(prob.deserialize("[123,[456,[789]]]").getList());
        System.out.println(prob.deserialize("[123,345,[67,8,[9,10]],11]").getList());
    }
}

@@ -1705,404 +1705,182 @@
    p
-rivate static class Token %7B%0A        private final String string;%0A        private int idx;%0A%0A        public Token(String s) %7B%0A            this.string = s;%0A        %7D%0A%0A        private boolean end() %7B%0A            return idx == string.length();%0A        %7D%0A%0A        public char peek() %7B%0A            return string.charAt(idx);%0A        %7D%0A%0A        public char next() %7B%0A            return string.charAt(idx++
+ublic NestedInteger deserialize(String s) %7B%0A        Token token = new Token(s);%0A        char c = token.peek();%0A        if (isNumber(c)) %7B%0A            return parseNumber(token
 );%0A 
@@ -1896,59 +1896,25 @@
     
-%7D%0A%0A
     
-public NestedInteger deserialize(String s) %7B
+token.next();
 %0A   
@@ -1937,28 +1937,21 @@
 rialize(
-new T
+t
 oken
-(s)
 );%0A    %7D
@@ -2177,92 +2177,32 @@
     
-Integer number = parseNumber(token);%0A                ni.add(new NestedInteger(number
+ni.add(parseNumber(token
 ));%0A
@@ -2505,32 +2505,453 @@
 turn ni;%0A    %7D%0A%0A
+    private static class Token %7B%0A        private final String string;%0A        private int idx;%0A%0A        public Token(String s) %7B%0A            this.string = s;%0A        %7D%0A%0A        private boolean end() %7B%0A            return idx == string.length();%0A        %7D%0A%0A        public char peek() %7B%0A            return string.charAt(idx);%0A        %7D%0A%0A        public char next() %7B%0A            return string.charAt(idx++);%0A        %7D%0A    %7D%0A%0A
     private stat
@@ -3057,16 +3057,22 @@
  static 
+Nested
 Integer 
@@ -3265,16 +3265,34 @@
  return 
+new NestedInteger(
 Integer.
@@ -3317,399 +3317,8 @@
 g())
-;%0A    %7D%0A%0A    public static void main(String%5B%5D args) %7B%0A        Problem385 prob = new Problem385();%0A%0A        System.out.println(prob.deserialize(%22324%22).getList());%0A        System.out.println(prob.deserialize(%22%5B123,324%5D%22).getList());%0A        System.out.println(prob.deserialize(%22%5B123,%5B456,%5B789%5D%5D%5D%22).getList());%0A        System.out.println(prob.deserialize(%22%5B123,345,%5B67,8,%5B9,10%5D%5D,11%5D%22).getList()
 );%0A 

Solve problem 385