Evaluate dice rolling notation strings

前端 未结 14 1454
甜味超标
甜味超标 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:11

    Clojure, 854 characters as is, 412 shrunk

    Just run "(roll-dice "input-string")".

    (defn roll-dice
      [string]
      (let [parts (. (. (. string replace "-" "+-") replaceAll "\\s" "") split "\\+")
            dice-func (fn [d-notation]
                        (let [bits (. d-notation split "d")]
                          (if (= 1 (count bits))
                            (Integer/parseInt (first bits))  ; Just a number, like 12
                            (if (zero? (count (first bits)))
                              (inc (rand-int (Integer/parseInt (second bits))))  ; Just d100 or some such
                              (if (. (first bits) contains "*")
                                (* (Integer/parseInt (. (first bits) replace "*" ""))
                                    (inc (rand-int (Integer/parseInt (second bits)))))
                                (reduce +
                                  (map #(+ 1 %)
                                        (map rand-int
                                            (repeat
                                              (Integer/parseInt (first bits))
                                              (Integer/parseInt (second bits)))))))))))]      
        (reduce + (map dice-func parts))))
    

    To shrink, I made variables 1 letter, moved the (first bits)/(second bits) into variables, made dice-func an anonymous function, made a wrapper for Integer.parseInt called 'i', and stripped out comments and extra whitespace.

    This should work on anything valid, with or without whitespace. Just don't go asking it for "15dROBERT", it will throw an exception.

    They way it works is by splitting up the string into dice (that's the 3rd line, the let). So "5d6+2*d4-17" becomes "5d6","2*d4","-17".

    Each of those is then processed by the function dice-func, and the results are added up (this is the map/reduce on the last line)

    Dice-func takes a little dice string (such a "5d6") and splits it on the "d". If there is only one part left, it was a simple number (6, -17, etc).

    If the first part contains a *, we multiply that number by a random interger, 1 to (number after d), inclusive.

    If the first part doesn't contain a *, we take first number random rolls (just like previous line) and add them up (this is the map/reduce in the middle).

    This was fun little challenge.

提交回复
热议问题