DEV Community

Discussion on: Daily Coding Puzzles - Oct 29th - Nov 2nd

Collapse
 
chubbard profile image
Charlie Hubbard • Edited

A groovy version that will do it out to billions. For example:

import static WordMath.*
words {
   oneBillionTwoMillionThreeThousandFiveHundredSixtyFour( plus( one() ) )
}

The only unfortunate thing is in order to support methodMissing it has to be done on instance methods so the words closure hides that fact

class WordMath {

    Map<String,Integer> NAMES_TO_VALUE = [
        "one": 1,
        "two": 2,
        "three": 3,
        "four": 4,
        "five": 5,
        "six": 6,
        "seven": 7,
        "eight": 8,
        "nine": 9,
        "ten": 10,
        "eleven": 11,
        "twelve": 12,
        "thirteen": 13,
        "fourteen": 14,
        "fifteen": 15,
        "sixteen": 16,
        "seventeen": 17,
        "eighteen": 18,
        "nineteen": 19,
        "twenty": 20,
        "thirty": 30,
        "fourty": 40,
        "fifty": 50,
        "sixty": 60,
        "seventy": 70,
        "eighty": 80,
        "ninety": 90,
        "hundred": 100,
        "thousand": 1_000,
        "million": 1_000_000,
        "billion": 1_000_000_000
    ]

    static Integer words(Closure c) {
        c.delegate = new WordMath()
        c()
    }

    def plus( Integer v ) {
        return { v2 -> v2 + v }
    }

    def minus( Integer v ) {
        return { v2 -> v2 - v }
    }

    def times( Integer v ) {
        return { v2 -> v2 * v }
    }

    def dividedBy( Integer v ) {
        return { v2 -> v2 / v }
    }

    def methodMissing( String name, args ) {
        Integer value = parseValue( name )
        if( args.size() > 0 ) {
            args[0]( value )
        } else {
            return value
        }
    }

    Integer parseValue(String name) {
        Integer value = 0
        Integer buffer = 0
        name.replaceAll(/([A-Z])/, ' $1').toLowerCase().split(" ").each { String  number ->
            Integer v = NAMES_TO_VALUE[ number ]
            if( v ) {
                if( v < 100 ) {
                    buffer += v
                } else {
                    buffer *= v
                    if( v > 999 ) {
                        value += buffer
                        buffer = 0
                    }
                }
            } else {
                println("Unknown number ${number}!")
            }
        }
        return value + buffer
    }
}