/**
 * 根据表达式计算字母数
 * 说明:
 *   给定一个描述字母数量的表达式,计算表达式里的每个字母实际数量
 *   表达式格式:
 *     字母紧跟表示次数的数字,如 A2B3
 *     括号可将表达式局部分组后跟上数字,(A2)2B
 *     数字为1时可缺省,如 AB3。
 * 示例:
 *   countOfLetters('A2B3'); // { A: 2, B: 3 }
 *   countOfLetters('A(A3B)2'); // { A: 7, B: 2 }
 *   countOfLetters('C4(A(A3B)2)2'); // { A: 14, B: 4, C: 4 }
 */

function countOfLetters(letters) {
  /** 代码实现 */
 
  const lettersArr = letters.split('')
  const result = {}
  let length = lettersArr.length
  let arr = []
  let status = 0
  let innerObj = {}

  const isLetter = (s) => !/[^A-Za-z]/.test(s)
  const isNumber = (s) => !/[^0-9]/.test(s)
  const isLeft = (s) => s === '('
  const isRight = (s) => s === ')'
  
  const objAdding = (code,number) => {
    result[code] =(result[code] || 0) + number
  }
  const innerObjAdding = (code,number) => {
    innerObj[code] =(innerObj[code] || 0) + number
  }
  while(length--){
    const code = lettersArr[length]
    if(status === 0){
      if(isLetter(code)){
        objAdding(code,1)
        arr = []
        status = 0
        continue;
      }
      if(isNumber(code)){
        arr.unshift(code)
        status = 1
        continue;
      }
      if(isRight(code)){
        arr.unshift(code)
        status = 2
        continue;
      }
    }
    if(status === 1){
      if(isLetter(code)){
        objAdding(code,+arr.join(''))
        arr = []
        status = 0
        continue;
      }
      if(isNumber(code)){
        arr.unshift(code)
        status = 1
        continue;
      }
      if(isRight(code)){
        arr.unshift(code)
        status = 2
        continue;
      }
    }
    if(status === 2){
      if(isLeft(code)){
        const index = arr.findIndex(item => item === ')')
        const str = arr.slice(0,index).join('')
        const obj = countOfLetters(str)
        arr = arr.slice(index + 1)
        let s
        for(let i = 0;i < arr.length;i++){
          if(!isNumber(arr[i])){
            break;
          } else {
            s = i+1
          }
        }
        const pointerNumber =  +arr.slice(0,s).join('') || 1
        arr = arr.slice(s)
        const keys = Object.keys(obj)
        keys.map(key => {
          innerObjAdding(key,obj[key])
        })
        const innerKeys = Object.keys(innerObj)
        innerKeys.map(key => {
          innerObj[key] = innerObj[key]*pointerNumber
        })
        if(arr.length === 0){
          const keys = Object.keys(innerObj)
          keys.map(key => {
            objAdding(key,innerObj[key])
          })
          innerObj = {}
          status = 0
        }
        continue;
      }
      arr.unshift(code)
    }
  }
  return result
}

console.log(countOfLetters('A2B3'))
console.log(countOfLetters('A(A3B)2'))
console.log(countOfLetters('C4(A(A3B)2)2'))```

// TODO 思路不对,应该可以生成一颗树!!!