Evaluate dice rolling notation strings

前端 未结 14 1640
甜味超标
甜味超标 2021-01-30 14:55

Rules

Write a function that accepts string as a parameter, returning evaluated value of expression in dice notation, including addition and multiplication.

To

14条回答
  •  甜味超标
    2021-01-30 15:27

    Ruby, 166 characters, no eval

    In my opinion quite elegant ;).

    def g s,o=%w{\+ \* d}
    o[a=0]?s[/#{p=o.pop}/]?g(s.sub(/(\d+)?\s*(#{p})\s*(\d+)/i){c=$3.to_i
    o[1]?($1||1).to_i.times{a+=rand c}+a:$1.to_i.send($2,c)},o<

    Deobfuscated version + comments:

    def evaluate(string, opers = ["\\+","\\*","d"])
      if opers.empty?
        string
      else
        if string.scan(opers.last[/.$/]).empty? # check if string contains last element of opers array
    
          # Proceed to next operator from opers array.
    
          opers.pop
          evaluate(string, opers)
    
        else # string contains that character...
    
          # This is hard to deobfuscate. It substitutes subexpression with highest priority with
          # its value (e.g. chooses random value for XdY, or counts value of N+M or N*M), and
          # calls recursively evaluate with substituted string.
    
          evaluate(string.sub(/(\d+)?\s*(#{opers.last})\s*(\d+)/i) { a,c=0,$3.to_i; ($2 == 'd') ? ($1||1).to_i.times{a+=rand c}+a : $1.to_i.send($2,c) }, opers)
    
        end
      end
    end
    

提交回复
热议问题