Solving coin problems

From Rosetta Code
This task has been flagged for clarification due to it being believed to be too difficult to implement in a reasonable amount of effort in more than one (usually very specialised) language. It may need to be divided into multiple tasks or modified substantially so that multiple implementations are practical, and that may cause code on this page in its current state to be flagged incorrect afterwards. See this page's Talk page for discussion.
Solving coin problems is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

In 1964, Daniel G. Bobrow created the STUDENT AI program in order to solve the types of word problems found in high school algebra books. You can read Bobrow's 1964 Ph.D. thesis, Natural Language Input for a Computer Problem Solving System. The program consists of 3 main pieces:

  1. A pattern matcher that reads the english input,
  2. rules to translate english into equations, and
  3. an algebraic equation solver.

In chapter 7 of his book, Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp, Peter Norvig lays out the STUDENT program and then challenges his readers as follows:

"Exercise 7.8 [d] Find a mathematically oriented domain that is sufficiently limited so that STUDENT can solve problems in it. The chemistry of solutions (calculating pH concentrations) might be an example. Write the necessary *student-rules*, and test the resulting program." (PAIP, p. 236)

There are several types of word problems commonly encountered in high school algebra, for example coin problems, age problems, distance problems, mixture problems, finance problems, lever problems, and work problems.

For this task, let's focus specifically on coin problems. Example: "If a person has three times as many quarters as dimes and the total amount of money is $5.95, find the number of quarters and dimes." (Bluman, Allan G. Math word problems demystified. 2005. The McGraw-Hill Companies Inc. p. 112, problem 1.)

Coin problems can all pretty much be schematized as follows:

  1. There are types of valuable things:
  2. There are instances of the th type of valuable thing.
  3. The value of the th type of thing is
  4. The total number of things is:
  5. The total value of all the things is:

A typical coin problem wants us to find the , given some of the other information from the schema.

The task is to write an AI program, inspired by Bobrow's STUDENT program and Norvig's challenge in PAIP, capable of solving the kinds of coin problems found in high school algebra.

The program should take coin problems written in plain english and output the solutions. The solutions needn't be output in English.

Go

This relatively simple program can only solve problems with 2 types of coins (or other objects) or 3 types of coins (but not other objects) without the need for an equation solver. However, it is able to solve all 28 problems of these types which were originally listed in the Perl entry before it was restricted to the subset of those problems (24) involving coins and bills.

package main

import (
    "fmt"
    "math"
    "regexp"
    "sort"
    "strconv"
    "strings"
)

type kind struct {
    name   string
    value  float64
    number int
}

// variable1 = constant1 * variable2 + constant2
type relation struct {
    variable1 string
    variable2 string
    constant1 float64
    constant2 float64
}

var nums = map[string]string{
    "one-half": "0 times", "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", "forty": "40",
    "fifty": "50", "sixty": "60", "seventy": "70", "eighty": "80", "ninety": "90",
    "hundred": "100"}

var nums2 = map[string]string{
    "twenty-": "2", "thirty-": "3", "forty-": "4",
    "fifty-": "5", "sixty-": "6", "seventy-": "7", "eighty-": "8", "ninety-": "9"}

var coins = map[string]float64{
    "pennies": 0.01, "nickels": 0.05, "dimes": 0.10, "quarters": 0.25, "half-dollars": 0.50,
    "one-dollar": 1.00, "two-dollar": 2.00, "five-dollar": 5.00, "ten-dollar": 10.00}

var bills = map[string]string{
    "$1": "one-dollar", "$2": "two-dollar", "$5": "five-dollar", "$10": "ten-dollar"}

var (
    rx1 = regexp.MustCompile(`\$\d+(\.\d+)?|\d+¢`)
    rx2 = regexp.MustCompile(`\b(pennies|nickels|dimes|quarters|half-dollar|one-dollar|two-dollar|five-dollar|ten-dollar)\b`)
    rx3 = regexp.MustCompile(`\s(\d+)\s`)
    rx4 = regexp.MustCompile(`(\d+) times as many ([-\w]+) as (s?he (does|has) )?([-\w]+)`)
    rx5 = regexp.MustCompile(`(\d+) more ([-\w]+) than (s?he (does|has) )?([-\w]+)`)
    rx6 = regexp.MustCompile(`(\d+) less ([-\w]+) than (s?he (does|has) )?([-\w]+)`)
    rx7 = regexp.MustCompile(`(\d+) dollars`)
)

func spaced(s string) string {
    return fmt.Sprintf(" %s ", s)
}

// Gets a sorted slice of monetary values.
func getValues(q string) []float64 {
    ss := rx1.FindAllString(q, -1)
    if ss == nil {
        return nil
    }
    var res []float64
    for _, s := range ss {
        if len(s) == 0 {
            continue
        }
        if s[0] == '$' {
            s = s[1:]
        } else {
            s = "." + s[:len(s)-2] // '¢' is 2 bytes
        }
        f, _ := strconv.ParseFloat(s, 64)
        res = append(res, f)
    }
    sort.Float64s(res)
    return res
}

// Gets a sorted slice of non-monetary integers.
func getNumbers(q string) []int {
    ns := rx3.FindAllString(q, -1)
    if ns == nil {
        return nil
    }
    var res []int
    for _, n := range ns {
        i, _ := strconv.Atoi(strings.TrimSpace(n))
        res = append(res, i)
    }
    sort.Ints(res)
    return res
}

// Gets the 'kinds' for the problem.
func getKinds(a []string) (int, []kind) {
    num, _ := strconv.Atoi(a[1])
    kinds := []kind{{a[2], 0, 0}, {a[5], 0, 0}}
    areCoins := false
    for i := range kinds {
        if v, ok := coins[kinds[i].name]; ok {
            kinds[i].value = v
            areCoins = true
        }
    }
    if !areCoins {
        return 0, nil
    }
    return num, kinds
}

// Checks if the problem involves 3 coins and
// also returns their names and the names of the coin which occurs most.
func hasThreeCoins(q string) ([]string, []string, bool) {
    q = strings.ReplaceAll(q, ".", "")
    q = strings.ReplaceAll(q, ",", "")
    words := strings.Split(q, " ")
    coinMap := make(map[string]int)
    for _, word := range words {
        if _, ok := coins[word]; ok {
            coinMap[word]++
        }
    }
    if len(coinMap) != 3 {
        return nil, []string{}, false
    }
    maxNum := 0
    var maxNames []string
    var names []string
    for k, v := range coinMap {
        names = append(names, k)
        if v > maxNum {
            maxNum = v
            maxNames = maxNames[:0]
            maxNames = append(maxNames, k)
        } else if v == maxNum {
            maxNames = append(maxNames, k)
        }
    }
    return names, maxNames, true
}

// Processes a problem which involves 3 coins.
func threeCoins(p, q string, names, maxNames []string) {
    var relations []relation
    am := rx4.FindAllStringSubmatch(q, -1)
    for i := 0; i < len(am); i++ {
        mult, kinds := getKinds(am[i])
        relations = append(relations, relation{kinds[0].name, kinds[1].name, float64(mult), 0})
    }
    mt := rx5.FindAllStringSubmatch(q, -1)
    for i := 0; i < len(mt); i++ {
        plus, kinds := getKinds(mt[i])
        relations = append(relations, relation{kinds[0].name, kinds[1].name, 1, float64(plus)})
    }
    lt := rx6.FindAllStringSubmatch(q, -1)
    for i := 0; i < len(lt); i++ {
        minus, kinds := getKinds(lt[i])
        relations = append(relations, relation{kinds[0].name, kinds[1].name, 1, -float64(minus)})
    }
    le := len(relations)
    if le > 2 {
        errorMsg(p)
        return
    }
    if le == 0 { // numbers of each coin must be the same
        sum := 0.0
        for _, name := range names {
            sum += coins[name]
        }
        res := getValues(q)
        tv := res[len(res)-1]
        n := int(tv/sum + 0.5)
        var kinds []kind
        for _, name := range names {
            kinds = append(kinds, kind{name, 0, n})
        }
        printAnswers(p, kinds)
    } else {
        res := getValues(q)
        totalValue := res[len(res)-1]
        for _, maxName := range maxNames {
            for i := 0; i < le; i++ {
                if relations[i].constant1 == 0 {
                    relations[i].constant1 = 0.5 // deals with 'one-half' cases
                }
                if le == 2 && maxName == relations[i].variable1 {
                    v := relations[i].variable2
                    relations[i].variable1, relations[i].variable2 = v, maxName
                    relations[i].constant1 = 1 / relations[i].constant1
                    relations[i].constant2 = -relations[i].constant2
                }
            }
            tv := totalValue
            var v1, v2, v3 string
            var n1, n2, n3 int
            if le == 2 {
                tmc := coins[relations[0].variable1]*relations[0].constant1 +
                    coins[relations[1].variable1]*relations[1].constant1 + coins[maxName]
                tv -= coins[relations[0].variable1]*relations[0].constant2 +
                    coins[relations[1].variable1]*relations[1].constant2
                v1, v2, v3 = maxName, relations[0].variable1, relations[1].variable1
                n1 = int(tv/tmc + 0.5)
                n2 = int(relations[0].constant1*float64(n1) + relations[0].constant2 + 0.5)
                n3 = int(relations[1].constant1*float64(n1) + relations[1].constant2 + 0.5)
            } else {
                res2 := getNumbers(q)
                tn := float64(res2[len(res2)-1])
                v1, v2 = relations[0].variable1, relations[0].variable2
                for _, name := range names {
                    if name != v1 && name != v2 {
                        v3 = name
                        break
                    }
                }
                mult1, mult2, mult3 := coins[v1], coins[v2], coins[v3]
                n2 = int(((tn-relations[0].constant2)*mult3-tv+relations[0].constant2*mult1)/
                    ((relations[0].constant1+1)*mult3-relations[0].constant1*mult1-mult2) + 0.5)
                n1 = int(float64(n2)*relations[0].constant1 + relations[0].constant2 + 0.5)
                n3 = int(tn) - n1 - n2
            }
            calcValue := float64(n1)*coins[v1] + float64(n2)*coins[v2] + float64(n3)*coins[v3]
            if math.Abs(totalValue-calcValue) <= 1e-14 {
                kinds := []kind{kind{v1, 0, n1}, kind{v2, 0, n2}, kind{v3, 0, n3}}
                printAnswers(p, kinds)
                return
            }
        }
        errorMsg(p)
    }
    return
}

func printAnswers(p string, kinds []kind) {
    fmt.Println(p)
    fmt.Print("ANSWER:")
    for i, kind := range kinds {
        if i > 0 {
            fmt.Print(",")
        }
        fmt.Printf(" %d %s", kind.number, kind.name)
    }
    fmt.Println("\n")
}

func errorMsg(p string) {
    fmt.Println(p)
    fmt.Println("*** CAN'T SOLVE THIS ONE ***\n")
}

func main() {
    ps := []string{
        "If a person has three times as many quarters as dimes and the total amount of money is $5.95, find the number of quarters and dimes.",
        "A pile of 18 coins consists of pennies and nickels. If the total amount of the coins is 38¢, find the number of pennies and nickels.",
        "A small child has 6 more quarters than nickels. If the total amount of coins is $3.00, find the number of nickels and quarters the child has.",
        "A child's bank contains 32 coins consisting of nickels and quarters. If the total amount of money is $3.80, find the number of nickels and quarters in the bank.",
        "A person has twice as many dimes as she has pennies and three more nickels than pennies. If the total amount of the coins is $1.97, find the numbers of each type of coin the person has.",
        "In a bank, there are three times as many quarters as half dollars and 6 more dimes than half dollars. If the total amount of the money in the bank is $4.65, find the number of each type of coin in the bank.",
        "A person bought 12 stamps consisting of 37¢ stamps and 23¢ stamps. If the cost of the stamps is $3.74, find the number of each type of the stamps purchased.",
        "A dairy store sold a total of 80 ice cream sandwiches and ice cream bars. If the sandwiches cost $0.69 each and the bars cost $0.75 each and the store made $58.08, find the number of each sold.",
        "An office supply store sells college-ruled notebook paper for $1.59 a ream and wide-ruled notebook paper for $2.29 a ream. If a student purchased 9 reams of notebook paper and paid $15.71, how many reams of each type of paper did the student purchase?",
        "A clerk is given $75 in bills to put in a cash drawer at the start of a workday. There are twice as many $1 bills as $5 bills and one less $10 bill than $5 bills. How many of each type of bill are there?",
        "A person has 8 coins consisting of quarters and dimes. If the total amount of this change is $1.25, how many of each kind of coin are there?",
        "A person has 3 times as many dimes as he has nickels and 5 more pennies than nickels. If the total amount of these coins is $1.13, how many of each kind of coin does he have?",
        "A person bought ten greeting cards consisting of birthday cards costing $1.50 each and anniversary cards costing $2.00 each. If the total cost of the cards was $17.00, find the number of each kind of card the person bought.",
        "A person has 9 more dimes than nickels. If the total amount of money is $1.20, find the number of dimes the person has.",
        "A person has 20 bills consisting of $1 bills and $2 bills. If the total amount of money the person has is $35, find the number of $2 bills the person has.",
        "A bank contains 8 more pennies than nickels and 3 more dimes than nickels. If the total amount of money in the bank is $3.10, find the number of dimes in the bank.",
        "Your uncle walks in, jingling the coins in his pocket. He grins at you and tells you that you can have all the coins if you can figure out how many of each kind of coin he is carrying. You're not too interested until he tells you that he's been collecting those gold-tone one-dollar coins. The twenty-six coins in his pocket are all dollars and quarters, and they add up to seventeen dollars in value. How many of each coin does he have?",
        "A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30. If there are three times as many nickels as quarters, and one-half as many dimes as nickels, how many coins of each kind are there?",
        "A wallet contains the same number of pennies, nickels, and dimes. The coins total $1.44. How many of each type of coin does the wallet contain?",
        "Suppose Ken has 25 coins in nickels and dimes only and has a total of $1.65. How many of each coin does he have?",
        "Terry has 2 more quarters than dimes and has a total of $6.80. The number of quarters and dimes is 38. How many quarters and dimes does Terry have?",
        "In my wallet, I have one-dollar bills, five-dollar bills, and ten-dollar bills. The total amount in my wallet is $43. I have four times as many one-dollar bills as ten-dollar bills. All together, there are 13 bills in my wallet. How many of each bill do I have?",
        "Marsha has three times as many one-dollar bills as she does five dollar bills. She has a total of $32. How many of each bill does she have?",
        "A vending machine has $41.25 in it. There are 255 coins total and the machine only accepts nickels, dimes and quarters. There are twice as many dimes as nickels. How many of each coin are in the machine?",
        "Michael had 27 coins in all, valuing $4.50. If he had only quarters and dimes, how many coins of each kind did he have?",
        "Lucille had $13.25 in nickels and quarters. If she had 165 coins in all, how many of each type of coin did she have?",
        "Ben has $45.25 in quarters and dimes. If he has 29 less quarters than dimes, how many of each type of coin does he have?",
        "A person has 12 coins consisting of dimes and pennies. If the total amount of money is $0.30, how many of each coin are there?",
    }
    for _, p := range ps {
        q := strings.ToLower(p)
        q = strings.ReplaceAll(q, "twice", "two times")
        for _, d := range []string{"half", "one", "two", "five", "ten"} {
            q = strings.ReplaceAll(q, d+" dollar", d+"-dollar")
        }
        for k, v := range nums {
            q = strings.ReplaceAll(q, spaced(k), spaced(v))
        }
        for k, v := range nums2 {
            q = strings.ReplaceAll(q, k, v)
        }
        for k, v := range nums {
            q = strings.ReplaceAll(q, k+" ", v+" ")
        }
        for k, v := range bills {
            q = strings.ReplaceAll(q, k+" ", v+" ")
        }
        q = strings.ReplaceAll(q, " bills", "")
        q = strings.ReplaceAll(q, " bill", "")
        // check if there are 3 coins involved
        if names, maxNames, ok := hasThreeCoins(q); ok {
            threeCoins(p, q, names, maxNames)
            continue
        }
        am := rx4.FindAllStringSubmatch(q, -1)
        if len(am) == 1 {
            mult, kinds := getKinds(am[0])
            if kinds == nil {
                errorMsg(p)
                continue
            }
            res := getValues(q)
            tv := res[len(res)-1]
            fmult := float64(mult)
            kinds[1].number = int(tv/(fmult*kinds[0].value+kinds[1].value) + 0.5)
            kinds[0].number = kinds[1].number * mult
            printAnswers(p, kinds)
            continue
        }
        mt := rx5.FindAllStringSubmatch(q, -1)
        if len(mt) == 1 {
            plus, kinds := getKinds(mt[0])
            if kinds == nil {
                errorMsg(p)
                continue
            }
            res := getValues(q)
            tv := res[len(res)-1]
            fplus := float64(plus)
            kinds[1].number = int((tv-fplus*kinds[0].value)/(kinds[0].value+kinds[1].value) + 0.5)
            kinds[0].number = kinds[1].number + plus
            printAnswers(p, kinds)
            continue
        }
        lt := rx6.FindAllStringSubmatch(q, -1)
        if len(lt) == 1 {
            minus, kinds := getKinds(lt[0])
            if kinds == nil {
                errorMsg(p)
                continue
            }
            res := getValues(q)
            tv := res[len(res)-1]
            fminus := float64(minus)
            kinds[1].number = int((tv+fminus*kinds[0].value)/(kinds[0].value+kinds[1].value) + 0.5)
            kinds[0].number = kinds[1].number - minus
            printAnswers(p, kinds)
            continue
        }
        res := getValues(q)
        var tv float64
        if len(res) > 0 {
            tv = res[len(res)-1]
        } else {
            res3 := rx7.FindAllStringSubmatch(q, -1)
            i, _ := strconv.Atoi(res3[0][1])
            tv = float64(i)
        }
        res2 := getNumbers(q)
        tn := res2[len(res2)-1]
        coinNames := rx2.FindAllString(q, -1)
        sort.Strings(coinNames)
        var kinds []kind
        if len(coinNames) > 0 {
            kinds = append(kinds, kind{coinNames[0], coins[coinNames[0]], 0})
            for i := 1; i < len(coinNames); i++ {
                if coinNames[i] != coinNames[i-1] {
                    kinds = append(kinds, kind{coinNames[i], coins[coinNames[i]], 0})
                }
            }
            if len(kinds) != 2 {
                errorMsg(p)
                continue
            }
        } else if len(res) >= 3 {
            kinds = append(kinds, kind{fmt.Sprintf("$%.2f item", res[0]), res[0], 0})
            for i := 1; i < len(res)-1; i++ {
                if res[i] != res[i-1] {
                    kinds = append(kinds, kind{fmt.Sprintf("$%.2f item", res[i]), res[i], 0})
                }
            }
            if len(kinds) != 2 {
                errorMsg(p)
                continue
            }
        } else {
            errorMsg(p)
            continue
        }
        ftn := float64(tn)
        kinds[0].number = int((tv-ftn*kinds[1].value)/(kinds[0].value-kinds[1].value) + 0.5)
        kinds[1].number = tn - kinds[0].number
        printAnswers(p, kinds)
    }
}
Output:
If a person has three times as many quarters as dimes and the total amount of money is $5.95, find the number of quarters and dimes.
ANSWER: 21 quarters, 7 dimes

A pile of 18 coins consists of pennies and nickels. If the total amount of the coins is 38¢, find the number of pennies and nickels.
ANSWER: 5 nickels, 13 pennies

A small child has 6 more quarters than nickels. If the total amount of coins is $3.00, find the number of nickels and quarters the child has.
ANSWER: 11 quarters, 5 nickels

A child's bank contains 32 coins consisting of nickels and quarters. If the total amount of money is $3.80, find the number of nickels and quarters in the bank.
ANSWER: 21 nickels, 11 quarters

A person has twice as many dimes as she has pennies and three more nickels than pennies. If the total amount of the coins is $1.97, find the numbers of each type of coin the person has.
ANSWER: 7 pennies, 14 dimes, 10 nickels

In a bank, there are three times as many quarters as half dollars and 6 more dimes than half dollars. If the total amount of the money in the bank is $4.65, find the number of each type of coin in the bank.
ANSWER: 3 half-dollars, 9 quarters, 9 dimes

A person bought 12 stamps consisting of 37¢ stamps and 23¢ stamps. If the cost of the stamps is $3.74, find the number of each type of the stamps purchased.
ANSWER: 5 $0.23 item, 7 $0.37 item

A dairy store sold a total of 80 ice cream sandwiches and ice cream bars. If the sandwiches cost $0.69 each and the bars cost $0.75 each and the store made $58.08, find the number of each sold.
ANSWER: 32 $0.69 item, 48 $0.75 item

An office supply store sells college-ruled notebook paper for $1.59 a ream and wide-ruled notebook paper for $2.29 a ream. If a student purchased 9 reams of notebook paper and paid $15.71, how many reams of each type of paper did the student purchase?
ANSWER: 7 $1.59 item, 2 $2.29 item

A clerk is given $75 in bills to put in a cash drawer at the start of a workday. There are twice as many $1 bills as $5 bills and one less $10 bill than $5 bills. How many of each type of bill are there?
ANSWER: 5 five-dollar, 10 one-dollar, 4 ten-dollar

A person has 8 coins consisting of quarters and dimes. If the total amount of this change is $1.25, how many of each kind of coin are there?
ANSWER: 5 dimes, 3 quarters

A person has 3 times as many dimes as he has nickels and 5 more pennies than nickels. If the total amount of these coins is $1.13, how many of each kind of coin does he have?
ANSWER: 3 nickels, 9 dimes, 8 pennies

A person bought ten greeting cards consisting of birthday cards costing $1.50 each and anniversary cards costing $2.00 each. If the total cost of the cards was $17.00, find the number of each kind of card the person bought.
ANSWER: 6 $1.50 item, 4 $2.00 item

A person has 9 more dimes than nickels. If the total amount of money is $1.20, find the number of dimes the person has.
ANSWER: 11 dimes, 2 nickels

A person has 20 bills consisting of $1 bills and $2 bills. If the total amount of money the person has is $35, find the number of $2 bills the person has.
ANSWER: 5 one-dollar, 15 two-dollar

A bank contains 8 more pennies than nickels and 3 more dimes than nickels. If the total amount of money in the bank is $3.10, find the number of dimes in the bank.
ANSWER: 17 nickels, 25 pennies, 20 dimes

Your uncle walks in, jingling the coins in his pocket. He grins at you and tells you that you can have all the coins if you can figure out how many of each kind of coin he is carrying. You're not too interested until he tells you that he's been collecting those gold-tone one-dollar coins. The twenty-six coins in his pocket are all dollars and quarters, and they add up to seventeen dollars in value. How many of each coin does he have?
ANSWER: 14 one-dollar, 12 quarters

A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30. If there are three times as many nickels as quarters, and one-half as many dimes as nickels, how many coins of each kind are there?
ANSWER: 18 nickels, 6 quarters, 9 dimes

A wallet contains the same number of pennies, nickels, and dimes. The coins total $1.44. How many of each type of coin does the wallet contain?
ANSWER: 9 pennies, 9 nickels, 9 dimes

Suppose Ken has 25 coins in nickels and dimes only and has a total of $1.65. How many of each coin does he have?
ANSWER: 8 dimes, 17 nickels

Terry has 2 more quarters than dimes and has a total of $6.80. The number of quarters and dimes is 38. How many quarters and dimes does Terry have?
ANSWER: 20 quarters, 18 dimes

In my wallet, I have one-dollar bills, five-dollar bills, and ten-dollar bills. The total amount in my wallet is $43. I have four times as many one-dollar bills as ten-dollar bills. All together, there are 13 bills in my wallet. How many of each bill do I have?
ANSWER: 8 one-dollar, 2 ten-dollar, 3 five-dollar

Marsha has three times as many one-dollar bills as she does five dollar bills. She has a total of $32. How many of each bill does she have?
ANSWER: 12 one-dollar, 4 five-dollar

A vending machine has $41.25 in it. There are 255 coins total and the machine only accepts nickels, dimes and quarters. There are twice as many dimes as nickels. How many of each coin are in the machine?
ANSWER: 90 dimes, 45 nickels, 120 quarters

Michael had 27 coins in all, valuing $4.50. If he had only quarters and dimes, how many coins of each kind did he have?
ANSWER: 15 dimes, 12 quarters

Lucille had $13.25 in nickels and quarters. If she had 165 coins in all, how many of each type of coin did she have?
ANSWER: 140 nickels, 25 quarters

Ben has $45.25 in quarters and dimes. If he has 29 less quarters than dimes, how many of each type of coin does he have?
ANSWER: 121 quarters, 150 dimes

A person has 12 coins consisting of dimes and pennies. If the total amount of money is $0.30, how many of each coin are there?
ANSWER: 2 dimes, 10 pennies

Julia

Uses the JuMP optimization library as a solver. The examples are from the Go code, and a few regex are from the Perl code.

using JuMP, GLPK

const nums = Dict(
    "zero"        => 0,   "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,
)

function coinproblemsolver(text, maxitems=4, verbose=false)
    coin_problem = Model(GLPK.Optimizer)
    for line in strip.(split(text, r"\n\n"))

        # save original version
        oldline = deepcopy(line)

        # ignore short or commented lines
        length(line) < 5 && continue
        line[1] == '#' && continue

        # create the data structures and registration function
        monies = Dict(
            "dollar_coin" => 100, "half_dollar" => 50, "quarter" => 25, "dime" => 10,
            "nickel" => 5, "penny" => 1,
        )
        foreach(d -> (monies["_" * "$d" * "_bill"] = 100 * d), [1, 2, 5, 10, 20, 50, 100, 500, 1000])

        itemnames = String[]
        itemvalues = Int[]

        function register_variables(vars)
            indices = Int[]
            for cap in vars
                idx = findfirst(x -> cap == x, itemnames)
                if !(idx isa Nothing)
                    push!(indices, idx)
                else
                    push!(itemnames, cap)
                    push!(indices, length(itemnames))
                    push!(itemvalues, get(monies, cap, 0))
                end
            end
            return indices
        end


        # set up the optimizer / problem solver
        @variables(coin_problem, begin x[1:maxitems] >= 0 end)


        # Simplify sentence and standardize quantities

        # convert hyphens to spaces, lowercase, newlines to spaces
        line = replace(replace(lowercase(line), "-" => " "), "\n" => " ")

        # fractions/multipliers to parsable forms
        line = replace(line, r"half.dollars?" => "half_dollar")
        line = replace(line, r"\bone\s+half\b" => "0.5")
        line = replace(line, r"\btwice\b" => "two times")

        # convert spelled out number to integer text per nums dictionary
        for p in nums
            line = replace(line, Regex("\\b" * p[1] * "\\b") => string(p[2]))
        end

        # remove plurals of coinage
        line = replace(line, r"(quarter|dime|nickel|dollar|coin|bill)s" => s"\1")
        line = replace(line, "pennies" => "penny")

        # change numerals to quantites and monies
        line = replace(line, r"dollar coin|all dollar" => "dollar_coin")
        line = replace(line, r"\$(\d+) bill" => s"_\1_bill")
        line = replace(line, r"(\d+) dollar bill" => s"_\1_bill")
        line = replace(line, r"((?:\d+\s+)+\d+)" => (s) -> mapreduce(x -> parse(Int, x), +, split(s))) # 20 6 -> 26

        # remove most unparsed words
        line = replace(line, r"\b(the|a|to|of|i|is|that|it|on|you|this|for|but|with|are|have|be|at|or|was|so|if|out|not|he|she|they|has|do|did|does)\b" => "")
        # simplify spacing
        line = replace(line, r"\s+" => " ")

        # Add variables and constraints to the problem
        for m in eachmatch(r"([\d\.]+) (?:times )?as many (\w+) as (\w+)", line)
            indices = register_variables([m[2], m[3]])
            @constraints(coin_problem, begin x[indices[1]] == x[indices[2]] * parse(Float64, m[1]) end)
        end
        for m in eachmatch(r"(\d+) more (\w+) than (\w+)", line)
            indices = register_variables([m[2], m[3]])
            @constraints(coin_problem, begin x[indices[1]] == x[indices[2]] + parse(Int, m[1]) end)
        end
        for m in eachmatch(r"(\d+) less (\w+) than (\w+)", line)
            indices = register_variables([m[2], m[3]])
            @constraints(coin_problem, begin x[indices[1]] == x[indices[2]] - parse(Int, m[1]) end)
        end
        if (m = match(r"same number (\w+), (\w+),? and (\w+)", line)) != nothing
            indices = register_variables(m.captures)
            @constraints(coin_problem, begin
                x[indices[1]] == x[indices[2]]
                x[indices[2]] == x[indices[3]]
            end)
        end
        if (m = match(r"(\d+) (?:\w+ )?(\w+),? consist\D+\$([\d\.]+)\D+\$([\d\.]+)", line)) != nothing
            n1, n2 = Int(round(100 * parse(Float64, m[3]))), Int(round(100 * parse(Float64, m[4])))
            s1, s2 = m[2] * "_costing_" * string(n1), m[2] * "_costing_" * string(n2)
            monies[s1], monies[s2] = n1, n2
            indices = register_variables([s1, s2])
            @constraints(coin_problem, begin sum(x) == parse(Int, m[1]) end)
        end
        if (m = match(r"(\d+) (?:\w+ )?(\w+),? consist\D+([\d\.]+)¢\D+([\d\.]+)¢", line)) != nothing
            n1, n2 = parse(Int, m[3]), parse(Int, m[4])
            s1, s2 = m[2] * "_costing_" * string(n1), m[2] * "_costing_" * string(n2)
            monies[s1], monies[s2] = n1, n2
            indices = register_variables([s1, s2])
            @constraints(coin_problem, begin sum(x) == parse(Int, m[1]) end)
        end
        if (m = match(r"(\d+) (?:coin|bill),? consist(?:s|ing) (\w+) and (\w+)", line)) != nothing
            indices = register_variables([m[2], m[3]])
            @constraints(coin_problem, begin sum(x) == parse(Int, m[1]) end)
        end
        if (m = match(r"(\d+) (?:coin)[^\d\.,]+pocket (\w+) and (\w+)", line)) != nothing
            indices = register_variables([m[2], m[3]])
            @constraints(coin_problem, begin sum(x) == parse(Int, m[1]) end)
        end
        if (m = match(r"(\d+) (?:coin|bill),? consist(?:s|ing) (\w+), (\w+), and (\w+)", line)) != nothing
            indices = register_variables([m[2], m[3], m[4]])
            @constraints(coin_problem, begin sum(x) == parse(Int, m[1]) end)
        end
        if (m = match(r"\$([\d\.]+) ream\D+\$([\d\.]+)\D+(\d+) reams", line)) != nothing
            n1, n2 = Int(round(100 * parse(Float64, m[1]))), Int(round(100 * parse(Float64, m[2])))
            s1, s2 = "ream_costing_" * string(n1), "ream_costing_" * string(n2)
            monies[s1], monies[s2] = n1, n2
            indices = register_variables([s1, s2])
            @constraints(coin_problem, begin sum(x) == parse(Int, m[3]) end)
        end
        if (m = match(r"(?:in my wallet,?|only accepts) (\w+), (\w+),? and (\w+)", line)) != nothing
            indices = register_variables([m.captures[1], m.captures[2], m.captures[3]])
        end
        if (m = match(r"(\d+) coin in (\w+) and (\w+) only", line)) != nothing
            indices = register_variables([m.captures[2], m.captures[3]])
            @constraints(coin_problem, begin sum(x) == parse(Int, m[1]) end)
        end
        if (m = match(r"(\d+) coin (?:total|in all)", line)) != nothing
            @constraints(coin_problem, begin sum(x) == parse(Int, m[1]) end)
        end
        if (m = match(r"(?:had only|in) (\w+) and (\w+)[,\.\?]", line)) != nothing
            indices = register_variables([m.captures[1], m.captures[2]])
        end
        if (m = match(r"(?:sold total|all together,? there) (\d+)", line)) != nothing
            @constraints(coin_problem, begin sum(x) == parse(Int, m[1]) end)
        end
        for m in eachmatch(r"cost \$([\d\.]+) each", line)
            s = "item_costing_" * m.captures[1]
            monies[s] = Int(round(100 * parse(Float64, m.captures[1])))
            register_variables([s])
        end

        # find a total
        m = match(r"add up \$?([\d\.]+)", line)
        if m isa Nothing
            m = match(r"(?:cost stamps|total cost|paid|value|valuing|store made)[^\$]+\$([\d\.]+)", line)
        end
        if m isa Nothing
            m = match(r"(?:total|value of|store made|given)[^\$]+\$([\d\.]+)", line)
        end
        if m isa Nothing
            m = match(r"\$([\d\.]+) (?:coin )?in", line)
        end
        if !(m isa Nothing)
            m1 = m.captures[1][end] == '.' ? m.captures[1][1:end-1] : m.captures[1]
            @constraints(coin_problem, begin
                sum([itemvalues[i] * x[i] for i in 1:length(itemnames)]) == Int(round(100 * parse(Float64, m1)))
            end)
        else
            m = match(r"total (?:amount coin )([\d\.]+)¢", line)
            if !(m isa Nothing)
                @constraints(coin_problem, begin
                    sum([itemvalues[i] * x[i] for i in 1:length(itemnames)]) == parse(Int, m[1])
                end)
            else
                error("Missing or unparsed total funds constraint")
            end
        end


        # set unused x components to 0
        for i in length(itemnames)+1:maxitems
            @constraints(coin_problem, begin x[i] == 0 end)
        end

        # solve
        optimize!(coin_problem)
        verbose && println(line)
        verbose && println(coin_problem)
        print(oldline, "\nAnswer:   ")
        for i in eachindex(itemnames)
            print(rpad(itemnames[i] * "(s)", 10), ": ", rpad(Int(round(JuMP.value(x[i]))), 10))
        end
        println("\n")
        JuMP.empty!(coin_problem)
    end
end

const DATA =  raw"""
If a person has three times as many quarters as dimes and the total amount of money is $5.95,
find the number of quarters and dimes.

A pile of 18 coins consists of pennies and nickels. If the total amount of the coins is 38¢,
find the number of pennies and nickels.

A small child has 6 more quarters than nickels. If the total amount of coins is $3.00,
find the number of nickels and quarters the child has.

A child's bank contains 32 coins consisting of nickels and quarters. If the total amount of
money is $3.80, find the number of nickels and quarters in the bank.

A person has twice as many dimes as she has pennies and three more nickels than pennies. If
the total amount of the coins is $1.97, find the numbers of each type of coin the person has.

In a bank, there are three times as many quarters as half dollars and 6 more dimes than
half dollars. If the total amount of the money in the bank is $4.65, find the number of
each type of coin in the bank.

A person bought 12 stamps consisting of 37¢ stamps and 23¢ stamps. If the cost of the stamps
is $3.74, find the number of each type of the stamps purchased.

A dairy store sold a total of 80 ice cream sandwiches and ice cream bars. If the sandwiches
cost $0.69 each and the bars cost $0.75 each and the store made $58.08, find the number
of each sold.

An office supply store sells college-ruled notebook paper for $1.59 a ream and wide-ruled
notebook paper for $2.29 a ream. If a student purchased 9 reams of notebook paper and
paid $15.71, how many reams of each type of paper did the student purchase?

A clerk is given $75 in bills to put in a cash drawer at the start of a workday. There are
twice as many $1 bills as $5 bills and one less $10 bill than $5 bills. How many of each
type of bill are there?

A person has 8 coins consisting of quarters and dimes. If the total amount of this change
is $1.25, how many of each kind of coin are there?

A person has 3 times as many dimes as he has nickels and 5 more pennies than nickels. If the
total amount of these coins is $1.13, how many of each kind of coin does he have?

A person bought ten greeting cards consisting of birthday cards costing $1.50 each and
anniversary cards costing $2.00 each. If the total cost of the cards was $17.00, find the
number of each kind of card the person bought.

A person has 9 more dimes than nickels. If the total amount of money is $1.20, find the
number of dimes the person has.

A person has 20 bills consisting of $1 bills and $2 bills. If the total amount of money
the person has is $35, find the number of $2 bills the person has.

A bank contains 8 more pennies than nickels and 3 more dimes than nickels. If the total
amount of money in the bank is $3.10, find the number of dimes in the bank.

Your uncle walks in, jingling the coins in his pocket. He grins at you and tells you that you
can have all the coins if you can figure out how many of each kind of coin he is carrying.
You're not too interested until he tells you that he's been collecting those gold-tone
one-dollar coins. The twenty-six coins in his pocket are all dollars and quarters, and they
add up to seventeen dollars in value. How many of each coin does he have?

A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30.
If there are three times as many nickels as quarters, and one-half as many dimes as nickels,
how many coins of each kind are there?

A wallet contains the same number of pennies, nickels, and dimes. The coins total $1.44. How
many of each type of coin does the wallet contain?

Suppose Ken has 25 coins in nickels and dimes only and has a total of $1.65. How many of
each coin does he have?

Terry has 2 more quarters than dimes and has a total of $6.80. The number of quarters and dimes
is 38. How many quarters and dimes does Terry have?

In my wallet, I have one-dollar bills, five-dollar bills, and ten-dollar bills. The total
amount in my wallet is $43. I have four times as many one-dollar bills as ten-dollar bills.
All together, there are 13 bills in my wallet. How many of each bill do I have?

Marsha has three times as many one-dollar bills as she does five dollar bills. She has a
total of $32. How many of each bill does she have?

A vending machine has $41.25 in it. There are 255 coins total and the machine only accepts
nickels, dimes and quarters. There are twice as many dimes as nickels. How many of each coin
are in the machine?

Michael had 27 coins in all, valuing $4.50. If he had only quarters and dimes, how many coins
of each kind did he have?

Lucille had $13.25 in nickels and quarters. If she had 165 coins in all, how many of each
type of coin did she have?

Ben has $45.25 in quarters and dimes. If he has 29 less quarters than dimes, how many of each
type of coin does he have?

A person has 12 coins consisting of dimes and pennies. If the total amount of money is $0.30,
how many of each coin are there?
"""

coinproblemsolver(DATA)
Output:
If a person has three times as many quarters as dimes and the total amount of money is $5.95, 
find the number of quarters and dimes.
Answer:   quarter(s): 21        dime(s)   : 7

A pile of 18 coins consists of pennies and nickels. If the total amount of the coins is 38¢, 
find the number of pennies and nickels.
Answer:   penny(s)  : 13        nickel(s) : 5

A small child has 6 more quarters than nickels. If the total amount of coins is $3.00, 
find the number of nickels and quarters the child has.
Answer:   quarter(s): 11        nickel(s) : 5

A child's bank contains 32 coins consisting of nickels and quarters. If the total amount of 
money is $3.80, find the number of nickels and quarters in the bank.
Answer:   nickel(s) : 21        quarter(s): 11

A person has twice as many dimes as she has pennies and three more nickels than pennies. If
the total amount of the coins is $1.97, find the numbers of each type of coin the person has.
Answer:   dime(s)   : 14        penny(s)  : 7         nickel(s) : 10

In a bank, there are three times as many quarters as half dollars and 6 more dimes than
half dollars. If the total amount of the money in the bank is $4.65, find the number of
each type of coin in the bank.
Answer:   quarter(s): 9         half_dollar(s): 3         dime(s)   : 9

A person bought 12 stamps consisting of 37¢ stamps and 23¢ stamps. If the cost of the stamps 
is $3.74, find the number of each type of the stamps purchased.
Answer:   stamps_costing_37(s): 7         stamps_costing_23(s): 5

A dairy store sold a total of 80 ice cream sandwiches and ice cream bars. If the sandwiches
cost $0.69 each and the bars cost $0.75 each and the store made $58.08, find the number
of each sold.
Answer:   item_costing_0.69(s): 32        item_costing_0.75(s): 48

An office supply store sells college-ruled notebook paper for $1.59 a ream and wide-ruled
notebook paper for $2.29 a ream. If a student purchased 9 reams of notebook paper and
paid $15.71, how many reams of each type of paper did the student purchase?
Answer:   ream_costing_159(s): 7         ream_costing_229(s): 2

A clerk is given $75 in bills to put in a cash drawer at the start of a workday. There are 
twice as many $1 bills as $5 bills and one less $10 bill than $5 bills. How many of each
type of bill are there?
Answer:   _1_bill(s): 10        _5_bill(s): 5         _10_bill(s): 4

A person has 8 coins consisting of quarters and dimes. If the total amount of this change
is $1.25, how many of each kind of coin are there?
Answer:   quarter(s): 3         dime(s)   : 5

A person has 3 times as many dimes as he has nickels and 5 more pennies than nickels. If the
total amount of these coins is $1.13, how many of each kind of coin does he have?
Answer:   dime(s)   : 9         nickel(s) : 3         penny(s)  : 8

A person bought ten greeting cards consisting of birthday cards costing $1.50 each and
anniversary cards costing $2.00 each. If the total cost of the cards was $17.00, find the
number of each kind of card the person bought.
Answer:   cards_costing_150(s): 6         cards_costing_200(s): 4

A person has 9 more dimes than nickels. If the total amount of money is $1.20, find the
number of dimes the person has.
Answer:   dime(s)   : 11        nickel(s) : 2

A person has 20 bills consisting of $1 bills and $2 bills. If the total amount of money
the person has is $35, find the number of $2 bills the person has.
Answer:   _1_bill(s): 5         _2_bill(s): 15

A bank contains 8 more pennies than nickels and 3 more dimes than nickels. If the total
amount of money in the bank is $3.10, find the number of dimes in the bank.
Answer:   penny(s)  : 25        nickel(s) : 17        dime(s)   : 20

Your uncle walks in, jingling the coins in his pocket. He grins at you and tells you that you 
can have all the coins if you can figure out how many of each kind of coin he is carrying.
You're not too interested until he tells you that he's been collecting those gold-tone
one-dollar coins. The twenty-six coins in his pocket are all dollars and quarters, and they
add up to seventeen dollars in value. How many of each coin does he have?
Answer:   dollar_coin(s): 14        quarter(s): 12

A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30.
If there are three times as many nickels as quarters, and one-half as many dimes as nickels,
how many coins of each kind are there?
Answer:   nickel(s) : 18        quarter(s): 6         dime(s)   : 9

A wallet contains the same number of pennies, nickels, and dimes. The coins total $1.44. How 
many of each type of coin does the wallet contain?
Answer:   penny(s)  : 9         nickel(s) : 9         dime(s)   : 9

Suppose Ken has 25 coins in nickels and dimes only and has a total of $1.65. How many of
each coin does he have?
Answer:   nickel(s) : 17        dime(s)   : 8

Terry has 2 more quarters than dimes and has a total of $6.80. The number of quarters and dimes
is 38. How many quarters and dimes does Terry have?
Answer:   quarter(s): 20        dime(s)   : 18

In my wallet, I have one-dollar bills, five-dollar bills, and ten-dollar bills. The total
amount in my wallet is $43. I have four times as many one-dollar bills as ten-dollar bills.
All together, there are 13 bills in my wallet. How many of each bill do I have?
Answer:   _1_bill(s): 8         _10_bill(s): 2         _5_bill(s): 3

Marsha has three times as many one-dollar bills as she does five dollar bills. She has a
total of $32. How many of each bill does she have?
Answer:   _1_bill(s): 12        _5_bill(s): 4

A vending machine has $41.25 in it. There are 255 coins total and the machine only accepts
nickels, dimes and quarters. There are twice as many dimes as nickels. How many of each coin
are in the machine?
Answer:   dime(s)   : 90        nickel(s) : 45        quarter(s): 120       

Michael had 27 coins in all, valuing $4.50. If he had only quarters and dimes, how many coins
of each kind did he have?
Answer:   quarter(s): 12        dime(s)   : 15

Lucille had $13.25 in nickels and quarters. If she had 165 coins in all, how many of each
type of coin did she have?
Answer:   nickel(s) : 140       quarter(s): 25

Ben has $45.25 in quarters and dimes. If he has 29 less quarters than dimes, how many of each
type of coin does he have?
Answer:   quarter(s): 121       dime(s)   : 150

A person has 12 coins consisting of dimes and pennies. If the total amount of money is $0.30,
how many of each coin are there?
Answer:   dime(s)   : 2         penny(s)  : 10

Perl

Coin-type 'word problems' are analyzed into their constituent algebraic relationships, in a format suitable for processing by MAXIMA, a free computer algebra system. NB: MAXIMA must be locally installed for this task to function.

use strict;
use warnings;

use List::Util qw(sum uniq);
use File::Temp qw(tempfile);

my %nums = (
        zero        => 0,   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,
);

my $decimal = qr/(?:[1-9][0-9]*\.?[0-9]*)|(?:0?\.[0-9]+)/;

while (<DATA>) {
    chomp;
    next if /^\s*$/ or /^\s*#.*$/; # skip blank and comment lines 

    my($count, $total) = (0, 0);
    our @words = our @eqns = our @vars = our @types = ();

    sub add_type {
        my($type,$value) = @_;
        push @vars, "v_$type: $value";
        push @types, $type;
    }

    # Step 1: standardize language

    s/-/ /g;                       # convert hyphens to spaces
    $_ = lc($_);                   # convert to lower case

    # tokenize sentence boundaries, punctuation, symbols
    s/([\.\?\!]) / $1\n/g;
    s/([\.\?\!])$/ $1\n/g;
    s/\$(.)/\$ $1/g;               # prefix
    s/(.)([\;\:\%',¢])/$1 $2/g;    # suffix

    # fractions/multipliers
    s/half.dollars?/half_dollar/g;
    s/\b(one )?half\b/0.5/g;
    s/\btwice\b/two times/g;

    # convert English number-names to numbers
    foreach my $key (keys %nums) { s/\b$key\b/$nums{$key}/eg }

    # remove plurals
    s/(quarter|dime|nickel|dollar|coin|bill)s/$1/g;
    s/pennies/penny/g;

    # misc
    s/dollar coin/dollar_coin/g;
    s/(\d+) dollar\b/\$ $1/g;
    s/((?:\d+ )*\d+)/sum(split(' ',$1))/eg;

    # remove non-essential words
    s/\b(the|a|to|of|i|is|that|it|on|you|this|for|but|with|are|have|be|at|or|was|so|if|out|not|he|she|they|has|do|did|does)\b\s*//g;

    # Step 2: assign numeric values to terms

    add_type('dollar_coin',100) if /dollar_coin/;
    add_type('half_dollar',50)  if /half_dollar/;
    add_type('quarter',25)      if /quarter/;
    add_type('dime',10)         if /dime/;
    add_type('nickel',5)        if /nickel/;
    add_type('penny',1)         if /penny/;
    add_type($1, 100 * $1) while /\$ (\d+) bill/g;

    # Step 3: determine algebraic relationships

    while (/($decimal) (?:times )?as many \$ (\d+) bill as \$ (\d+) bill/g) { push @eqns, "n_$2 = n_$3 * $1" }
    while (/($decimal) (?:times )?as many (\w+) as (\w+)/g)                 { push @eqns, "n_$2 = n_$3 * $1" }
    while (/(\d+) more (\w+) than (\w+)/g)                                  { push @eqns, "n_$2 = n_$3 + $1" }
    while (/(\d+) less (\w+) than (\w+)/g)                                  { push @eqns, "n_$2 = n_$3 - $1" }
    while (/(\d+) less \$ (\d+) bill than \$ (\d+) bill/g)                  { push @eqns, "n_$2 = n_$3 - $1" }

    if (/same number (\w+) , (\w+) (?:, )?and (\w+)/) {
        push @eqns, "n_$1 = n_$2";
        push @eqns, "n_$2 = n_$3";
    }

    if (/(\d+) (?:\w+ )*consists/ or /(?<!\$ )(\d+) coin/ or /[^\$] (\d+) bill/) {
        $count = $1; push @vars, "count: $count"
    }

    if (/total (?:\w+ )*\$ ($decimal)/ or /valu(?:e|ing) \$ ($decimal)/ or /\$ ($decimal) ((bill|coin) )?in/) {
        $total = 100 * $1;
        push @vars, "total: $total";
    }

    if (/total (?:\w+ )*($decimal)/) {
        $total = $1;
        push @vars, "total: $total";
    }

    # Step 4: tally final total value, coin count

    # sum total, dot product of values and quantities
    my $dot_product = join(' + ', map {"n_$_ * v_$_"} uniq @types);
    push @eqns, "total = $dot_product" if $total and @types;

    # count of all coins, sum of counts of each coin type
    my $trace = join(' + ', map {"n_$_"} uniq @types);
    push @eqns, "count = $trace" if $count and @types;

    # Step 5: prepare batch file for external processing, run 'MAXIMA', output results

    printf "problem: %s\n", s/\n/ /gr;  # condensed problem statement

    my $maxima_vars = join("\$\n", uniq @vars);
    my $maxima_eqns = '['. join(', ', @eqns) . ']';
    my $maxima_find = '['. join(', ', map {"n_$_"} @types) . ']';

    if (@eqns and @vars) {
        my ($fh, $maxima_script) = tempfile(UNLINK => 1);
        open $fh, '>', $maxima_script or die "Couldn't open temporary file: $!\n";
        print $fh <<~"END";
            $maxima_vars\$
            solve($maxima_eqns, $maxima_find);
            END
        close $fh;

        open my $maxima_output, "/opt/local/bin/maxima -q -b $maxima_script |" or die "Couldn't open maxima: $!\n";
        while (<$maxima_output>) {
            print "solution: $1\n" if /\(\%o\d+\)\s+\[\[([^\]]+)\]\]/; # only display solution
        }
        close  $maxima_output;
 
    } else {
        print "Couldn't deduce enough information to formulate equations.\n"
    }
    print "\n";
}

__DATA__
If a person has three times as many quarters as dimes and the total amount of money is $5.95, find the number of quarters and dimes.

A pile of 18 coins consists of pennies and nickels. If the total amount of the coins is 38¢, find the number of pennies and nickels.

A small child has 6 more quarters than nickels. If the total amount of coins is $3.00, find the number of nickels and quarters the child has.

A childs bank contains 32 coins consisting of nickels and quarters. If the total amount of money is $3.80, find the number of nickels and quarters in the bank.

A person has twice as many dimes as she has pennies and three more nickels than pennies. If the total amount of the coins is $1.97, find the numbers of each type of coin the person has.

In a bank, there are three times as many quarters as half dollars and 6 more dimes than half dollars. If the total amount of the money in the bank is $4.65, find the number of each type of coin in the bank.

A clerk is given $75 in bills to put in a cash drawer at the start of a workday. There are twice as many $1 bills as $5 bills and one less $10 bill than $5 bills. How many of each type of bill are there?

A person has 8 coins consisting of quarters and dimes. If the total amount of this change is $1.25, how many of each kind of coin are there?

A person has 3 times as many dimes as he has nickels and 5 more pennies than nickels. If the total amount of these coins is $1.13, how many of each kind of coin does he have?

A person has 9 more dimes than nickels. If the total amount of money is $1.20, find the number of dimes the person has.

A person has 20 bills consisting of $1 bills and $2 bills. If the total amount of money the person has is $35, find the number of $2 bills the person has.

A bank contains 8 more pennies than nickels and 3 more dimes than nickels. If the total amount of money in the bank is $3.10, find the number of dimes in the bank.

The twenty-six coins in my pocket are all dollar coins and quarters, and they add up to seventeen dollars in value. How many of each coin are there?

A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30. If there are three times as many nickels as quarters, and one-half as many dimes as nickels, how many coins of each kind are there?

A wallet contains the same number of pennies, nickels, and dimes. The coins total $1.44. How many of each type of coin does the wallet contain?

Suppose Ken has 25 coins in nickels and dimes only and has a total of $1.65. How many of each coin does he have?

Terry has 2 more quarters than dimes and has a total of $6.80. The number of quarters and dimes is 38. How many quarters and dimes does Terry have?

In my wallet, I have one-dollar bills, five-dollar bills, and ten-dollar bills. The total amount in my wallet is $43. I have four times as many one-dollar bills as ten-dollar bills. All together, there are 13 bills in my wallet. How many of each bill do I have?

Marsha has three times as many one-dollar bills as she does five dollar bills. She has a total of $32. How many of each bill does she have?

A vending machine has $41.25 in it. There are 255 coins total and the machine only accepts nickels, dimes and quarters. There are twice as many dimes as nickels. How many of each coin are in the machine.

Michael had 27 coins in all, valuing $4.50. If he had only quarters and dimes, how many coins of each kind did he have?

Lucille had $13.25 in nickels and quarters. If she had 165 coins in all, how many of each type of coin did she have?

Ben has $45.25 in quarters and dimes. If he has 29 less quarters than dimes, how many of each type of coin does he have?

A person has 12 coins consisting of dimes and pennies. If the total amount of money is $0.30, how many of each coin are there?
Output:
problem: person 3 times as many quarter as dime and total amount money $ 5.95 , find number quarter and dime .
solution: n_quarter = 21, n_dime = 7

problem: pile 18 coin consists penny and nickel . total amount coin 38 ¢ , find number penny and nickel .
solution: n_nickel = 5, n_penny = 13

problem: small child 6 more quarter than nickel . total amount coin $ 3.0 , find number nickel and quarter child .
solution: n_quarter = 11, n_nickel = 5

problem: childs bank contains 32 coin consisting nickel and quarter . total amount money $ 3.80 , find number nickel and quarter in bank .

solution: n_quarter = 11, n_nickel = 21

problem: person 2 times as many dime as penny and 3 more nickel than penny . total amount coin $ 1.97 , find numbers each type coin person .
solution: n_dime = 14, n_nickel = 10, n_penny = 7

problem: in bank , 3 times as many quarter as half_dollar and 6 more dime than half_dollar . total amount money in bank $ 4.65 , find number each type coin in bank .
solution: n_half_dollar = 3, n_quarter = 9, n_dime = 9

problem: clerk given $ 75 in bill put in cash drawer start workday . 2 times as many $ 1 bill as $ 5 bill and 1 less $ 10 bill than $ 5 bill . how many each type bill ?
solution: n_1 = 10, n_10 = 4, n_5 = 5

problem: person 8 coin consisting quarter and dime . total amount change $ 1.25 , how many each kind coin ?
solution: n_quarter = 3, n_dime = 5

problem: person 3 times as many dime as nickel and 5 more penny than nickel . total amount these coin $ 1.13 , how many each kind coin ?
solution: n_dime = 9, n_nickel = 3, n_penny = 8

problem: person 9 more dime than nickel . total amount money $ 1.20 , find number dime person .
solution: n_dime = 11, n_nickel = 2

problem: person 20 bill consisting $ 1 bill and $ 2 bill . total amount money person $ 35 , find number $ 2 bill person .
solution: n_1 = 5, n_2 = 15

problem: bank contains 8 more penny than nickel and 3 more dime than nickel . total amount money in bank $ 3.10 , find number dime in bank .
solution: n_dime = 20, n_nickel = 17, n_penny = 25

problem: 26 coin in my pocket all dollar_coin and quarter , and add up $ 17 in value . how many each coin ?
solution: n_dollar_coin = 14, n_quarter = 12

problem: collection 33 coin , consisting nickel , dime , and quarter , value $ 3.30 . 3 times as many nickel as quarter , and 0.5 as many dime as nickel , how many coin each kind ?
solution: n_quarter = 6, n_dime = 9, n_nickel = 18

problem: wallet contains same number penny , nickel , and dime . coin total $ 1.44 . how many each type coin wallet contain ?
solution: n_dime = 9, n_nickel = 9, n_penny = 9

problem: suppose ken 25 coin in nickel and dime only and total $ 1.65 . how many each coin ?
solution: n_dime = 8, n_nickel = 17

problem: terry 2 more quarter than dime and total $ 6.80 . number quarter and dime 38 . how many quarter and dime terry ?
solution: n_quarter = 20, n_dime = 18

problem: in my wallet , $ 1 bill , $ 5 bill , and $ 10 bill . total amount in my wallet $ 43 . 4 times as many $ 1 bill as $ 10 bill . all together , 13 bill in my wallet . how many each bill ?
solution: n_5 = 3, n_1 = 8, n_10 = 2

problem: marsha 3 times as many $ 1 bill as $ 5 bill . total $ 32 . how many each bill ?
solution: n_1 = 12, n_5 = 4

problem: vending machine $ 41.25 in . 255 coin total and machine only accepts nickel , dime and quarter . 2 times as many dime as nickel . how many each coin in machine .
solution: n_quarter = 120, n_dime = 90, n_nickel = 45

problem: michael had 27 coin in all , valuing $ 4.50 . had only quarter and dime , how many coin each kind ?
solution: n_quarter = 12, n_dime = 15

problem: lucille had $ 13.25 in nickel and quarter . had 165 coin in all , how many each type coin ?
solution: n_quarter = 25, n_nickel = 140

problem: ben $ 45.25 in quarter and dime . 29 less quarter than dime , how many each type coin ?
solution: n_quarter = 121, n_dime = 150

problem: person 12 coin consisting dime and penny . total amount money $ 0.30 , how many each coin ?
solution: n_dime = 2, n_penny = 10

Phix

The title of this task is solving coin problems, therefore I have ruthlessly eradicated stamps, sandwiches, paper, and cards. It just adds unnecessary fiddling, along with the need to add custom assets and asset-values, such as 37c stamps, $1.50 cards, etc. Hence this covers 24/28 of the Perl/Go examples. On the plus side, there is no hard limit on the number of unknowns, though all examples below are for 2 and 3 only. A couple (14 and 17) also sail perilously close to getting a divide by zero. This task was quite a bit of fun, once I got stuck in.

-- demo\rosetta\Solving_coin_problems.exw
with javascript_semantics
constant source = """
If a person has three times as many quarters as dimes and the total amount of money is $5.95, find the number of quarters and dimes.
--==>expected:quarters = 21, dimes = 7
A pile of 18 coins consists of pennies and nickels. If the total amount of the coins is 38c, find the number of pennies and nickels.
--==>expected:pennies = 13, nickels = 5
A small child has 6 more quarters than nickels. If the total amount of coins is $3.00, find the number of nickels and quarters the child has.
--==>expected:quarters = 11, nickels = 5
A child's bank contains 32 coins consisting of nickels and quarters. If the total amount of money is $3.80, find the number of nickels and quarters in the bank.
--==>expected:nickels = 21, quarters = 11
A person has twice as many dimes as she has pennies and three more nickels than pennies. If the total amount of the coins is $1.97, find the numbers of each type of coin the person has.
--==>expected:dimes = 14, pennies = 7, nickels = 10
In a bank, there are three times as many quarters as half dollars and 6 more dimes than half dollars. If the total amount of the money in the bank is $4.65, find the number of each type of coin in the bank.
--==>expected:quarters = 9, half_dollars = 3, dimes = 9
A clerk is given $75 in bills to put in a cash drawer at the start of a workday. There are twice as many $1 bills as $5 bills and one less $10 bill than $5 bills. How many of each type of bill are there?
--==>expected:one_dollar_bills = 10, five_dollar_bills = 5, ten_dollar_bills = 4
A person has 8 coins consisting of quarters and dimes. If the total amount of this change is $1.25, how many of each kind of coin are there?
--==>expected:quarters = 3, dimes = 5
A person has 3 times as many dimes as he has nickels and 5 more pennies than nickels. If the total amount of these coins is $1.13, how many of each kind of coin does he have?
--==>expected:dimes = 9, nickels = 3, pennies = 8
A person has 9 more dimes than nickels. If the total amount of money is $1.20, find the number of dimes the person has.
--==>expected:dimes = 11, nickels = 2
A person has 20 bills consisting of $1 bills and $2 bills. If the total amount of money the person has is $35, find the number of $2 bills the person has.
--==>expected:one_dollar_bills = 5, two_dollar_bills = 15
A bank contains 8 more pennies than nickels and 3 more dimes than nickels. If the total amount of money in the bank is $3.10, find the number of dimes in the bank.
--==>expected:pennies = 25, nickels = 17, dimes = 20
Your uncle walks in, jingling the coins in his pocket. He grins at you and tells you that you can have all the coins if you can figure out how many of each kind of coin he is carrying. You're not too interested until he tells you that he's been collecting those gold-tone one-dollar coins. The twenty-six coins in his pocket are all dollars and quarters, and they add up to seventeen dollars in value. How many of each coin does he have?
--==>expected:dollars = 14, quarters = 12
A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30. If there are three times as many nickels as quarters, and one-half as many dimes as nickels, how many coins of each kind are there?
--==>expected:nickels = 18, dimes = 9, quarters = 6
A wallet contains the same number of pennies, nickels, and dimes. The coins total $1.44. How many of each type of coin does the wallet contain?
--==>expected:pennies = 9, nickels = 9, dimes = 9
Suppose Ken has 25 coins in nickels and dimes only and has a total of $1.65. How many of each coin does he have?
--==>expected:nickels = 17, dimes = 8
Terry has 2 more quarters than dimes and has a total of $6.80. The number of quarters and dimes is 38. How many quarters and dimes does Terry have?
--==>expected:quarters = 20, dimes = 18
In my wallet, I have one-dollar bills, five-dollar bills, and ten-dollar bills. The total amount in my wallet is $43. I have four times as many one-dollar bills as ten-dollar bills. All together, there are 13 bills in my wallet. How many of each bill do I have?
--==>expected:one_dollar_bills = 8, five_dollar_bills = 3, ten_dollar_bills = 2
Marsha has three times as many one-dollar bills as she does five dollar bills. She has a total of $32. How many of each bill does she have?
--==>expected:one_dollar_bills = 12, five_dollar_bills = 4
A vending machine has $41.25 in it. There are 255 coins total and the machine only accepts nickels, dimes and quarters. There are twice as many dimes as nickels. How many of each coin are in the machine.
--==>expected:nickels = 45, dimes = 90, quarters = 120
Michael had 27 coins in all, valuing $4.50. If he had only quarters and dimes, how many coins of each kind did he have?
--==>expected:quarters = 12, dimes = 15
Lucille had $13.25 in nickels and quarters. If she had 165 coins in all, how many of each type of coin did she have?
--==>expected:nickels = 140, quarters = 25
Ben has $45.25 in quarters and dimes. If he has 29 less quarters than dimes, how many of each type of coin does he have?
--==>expected:quarters = 121, dimes = 150
A person has 12 coins consisting of dimes and pennies. If the total amount of money is $0.30, how many of each coin are there?
--==>expected:dimes = 2, pennies = 10""",

{texts,replacements} = columnize({{"."," ."},
                                  {","," ,"},
                                  {"had","has"},
                                  {"contain?","have?"},
                                  {"there?","have?"},
                                  {"has .","have?"},
                                  {"in the bank .","have?"},
                                  {"in the machine .","have?"},
                                  {"as many","asmany"},
                                  {" , and they add up"," . total"},
                                  {" , has a value"," . total"},
                                  {" only and has a total"," . total"},
                                  {" and has a total"," . total"},
                                  {"All together ,","total"},
                                  {"A vending machine has","total"},
                                  {"valuing","total"},
                                  {"coins in all ,","coins ."},
                                  {"coins total and","coins ."},
                                  {"find","many"},
                                  {"consists","consisting"},
                                  {"twenty-six","26"},
                                  {"seventeen dollars in value","$17.00"},
                                  {" one "," 1 "},
                                  {"three","3"},
                                  {"four","4"},
                                  {"twice","2 times"},
                                  {"ten","10"},
                                  {" and the total"," . total"},
                                  {"half dollars","half_dollars"},
                                  {"$1 bills","one_dollar_bills"},
                                  {"$2 bills","two_dollar_bills"},
                                  {"$5 bills","five_dollar_bills"},
                                  {"$10 bill","ten_dollar_bills"},
                                  {"one-dollar bills","one_dollar_bills"},
                                  {"five-dollar bills","five_dollar_bills"},
                                  {"five dollar bills","five_dollar_bills"},
                                  {"10-dollar bills","ten_dollar_bills"},
                                  {"10_dollar_bills","ten_dollar_bills"}}),

noise = split("the|a|to|of|i|is|that|it|on|you|this|for|but|with|are|have|be|at|or|was|so|if|out|not|he|she|they|has|do|does"&
              "|in|these|person|small|child|child's|bank|pile|clerk|given|put|there|cash|drawer|start|workday|his|suppose|ken"&
              "|terry|how|my|marsha|machine|accepts|michael|lucille|ben|number|type|kind|amount|collection|contains|change"&
              "|wallet|did|numbers|pocket","|"),

-- one spectacularly irksome preamble containing absolutely no useful information whatsoever...:
uncle = "your uncle walks in , jingling the coins in his pocket . "&
        "he grins at you and tells you that you can have all the coins "&
        "if you can figure out how many of each kind of coin he is carrying . "&
        "you're not too interested until he tells you that he's been collecting "&
        "those gold-tone one-dollar coins . ",

vocab = {"times","asmany","quarters","as","dimes","and","total","money","many","have?",
         "coins","consisting","pennies","nickels","more","less","than","each","coin",
         "half_dollars","bills","bill","all","dollars","one-half","same","only",
         "one_dollar_bills","two_dollar_bills","five_dollar_bills","ten_dollar_bills"},

{assets,assetv} = columnize({{"ten_dollar_bills",1000},
                             {"five_dollar_bills",500},
                             {"two_dollar_bills",200},
                             {"one_dollar_bills",100},
                             {"dollars",100},
                             {"half_dollars",50},
                             {"quarters",25},
                             {"dimes",10},
                             {"nickels",5},
                             {"pennies",1}})

integer count = 0
sequence lines = split(substitute_all(source,texts,replacements),"\n"),
         expectations = {},
         vused = repeat(false,length(vocab))
procedure cleanup_lines()
    sequence words
    for i=1 to length(lines) by 2 do
        string li = lower(lines[i])
        if match("your uncle",li)=1 then
            -- note: if you tweak texts/replacements then you may
            --       need to tweak the uncle constant to match.
            if match(uncle,li)!=1 then ?9/0 end if
            li = li[length(uncle)+1..$]
        end if
        words = split(li)
        for n=1 to length(noise) do
            words = remove_all(noise[n],words)
        end for
        if words[$]="." and find(words[$-1],{"dimes","nickels"}) then
            words[$] = "have?"
        end if
        if words[1]="," then words = words[2..$] end if
        for w=length(words) to 2 by -1 do
            -- re-join eg "$3" and ".99" (oops)
            if length(words[w])>1 and words[w][1]='.' then
                words[w-1..w] = {words[w-1]&words[w]}
            end if
        end for
        words = match_replace({",","many"},words,{".","many"})
        words = match_replace({","},words,{})
        count += 1
        lines[count] = words
        li = lines[i+1]
        if match("--==>expected:",li)!=1 then ?9/0 end if
        li = li[15..$]
        li = substitute(li," ,",",")
        expectations = append(expectations,li)
    end for
    lines = lines[1..count]
    printf(1,"%d puzzles:\n",count)
    printf(1,"Step 1: remove noise and otherwise simplify (if nothing else, down to a %d-word vocab):\n\n",length(vocab))
    for i=1 to count do
        printf(1,"%d: %s\n",{i,join(lines[i])})
    end for
end procedure 
cleanup_lines()

function add_unknowns(sequence unknowns, words)
    for i=1 to length(words) do
        string word = words[i]
        if not find(word,unknowns)
        and not find(word,{"as","consisting","all","and","than","only"}) then
            unknowns = append(unknowns,word)
        end if
    end for
    return unknowns
end function

function parse_sentence(sequence words, unknowns)
-- Converts eg {"$1.00","quarters","and","nickels"} to {100,25,5}.
-- An "equation" of {100,25,5} means "100==25*unknown[1]+5*unknown[2]".
-- Obviously this is suitably scruffy, but the 31-word vocab certainly helps!
-- It is worth noting that by this stage most sentences begin or end in a number.
-- Since we may not have the full set of unknowns, each equation ends with a code:
-- 0: pad with 0, 1: pad with 1, 'a': pad with the unknown asset values
sequence sentences = {},
         sentence,
         rest = {},
         isnumber = repeat(0,length(words))
integer k
bool set_asset_sum = false
    unknowns = deep_copy(unknowns)
    for w=1 to length(words) do
        string ww = words[w]
        k = find(ww,vocab)
        if k=0 then
            sequence r
            for f=1 to 3 do
                r = scanf(ww,{"%d","%dc","$%f"}[f])
                if r!={} then
                    isnumber[w] = iif(f=3?round(r[1][1]*100):r[1][1])
                    exit
                end if
            end for
            if r={} then ?ww ?9/0 end if
        else
            vused[k] = true
        end if
    end for
    if isnumber[1] then
        if words[2]="times" then
            if words[3]!="asmany" then ?9/0 end if
            k = find("and",words)
            if k then
                rest = words[k+1..$]
                words = words[1..k-1]
            end if
            -- eg {"3","times","asmany","quarters","as","dimes"}
            if length(words)!=6 or words[5]!="as" then ?9/0 end if
            unknowns = add_unknowns(unknowns, words[4..6])
            sentence = repeat(0,length(unknowns)+1)
            k = find(words[4],unknowns)
            sentence[k+1] = 1
            k = find(words[6],unknowns)
            sentence[k+1] = -isnumber[1]
            sentence &= 0
            sentences = append(sentences,sentence)
        elsif words[2]="coins"
           or (words[2]="bills" and length(words)>2) then
            --/* eg:
                {"18","coins","consisting","pennies","and","nickels"}
                {"26","coins","all","dollars","and","quarters"}
                {"25","coins","nickels","and","dimes"}
                {"33","coins","consisting","nickels","dimes","and","quarters"}
                {"27","coins"}
                {"20","bills","consisting","one_dollar_bills","and","two_dollar_bills"}
            --*/
            unknowns = add_unknowns(unknowns, words[3..$])
            sentence = {isnumber[1]}&repeat(1,length(unknowns))
            sentence &= 1
            sentences = append(sentences,sentence)
        elsif find(words[2],{"more","less"}) then
            k = find("and",words)
            if k then
                rest = words[k+1..$]
                words = words[1..k-1]
            end if
            --/* eg:
                {"5","more","pennies","than","nickels"}
                {"29","less","quarters","than","dimes"}
            --*/
            if length(words)!=5 or words[4]!="than" then ?9/0 end if
            unknowns = add_unknowns(unknowns, words[3..$])
            sentence = {isnumber[1]}&repeat(0,length(unknowns))
            integer less = iff(words[2]="less"?-1:+1)
            k = find(words[3],unknowns)
            sentence[k+1] = less
            k = find(words[5],unknowns)
            sentence[k+1] = -less
            sentence &= 0
            sentences = append(sentences,sentence)
        else
            --/* eg:
                {"$75","bills"}
                {"$45.25","quarters","and","dimes"}
            --*/
            if length(words)>2 then
                -- log assets:
                -- eg {"$13.25","nickels","and","quarters"}
                if words[3]!="and" or length(words)!=4 then ?9/0 end if
                unknowns = add_unknowns(unknowns, words[2..$])
            end if
            sentence = {isnumber[1]}
            set_asset_sum = true
        end if
    elsif isnumber[$] then
        if words[1]="total"
        or (length(words)=3 and words[1..2]={"coins","total"}) then
            --/*
                {"total","money","$5.95"}
                {"total","coins","38c"}
                {"total","coins","$3.00"}
                {"total","$3.74"}
                {"total","cost","$17.00"}
                {"coins","total","$1.44"}
            --*/
            sentence = {isnumber[$]}
            set_asset_sum = true
        else
            -- eg {"quarters","and","dimes","38"}
            unknowns = add_unknowns(unknowns, words[1..$-1])
            sentence = {isnumber[$]}&repeat(1,length(unknowns))
            sentence &= 1
            sentences = append(sentences,sentence)
        end if
    elsif words[1]="one-half" then
        -- eg {"one-half","asmany","dimes","as","nickels"}
        if length(words)!=5 or words[2]!="asmany" or words[4]!="as" then ?9/0 end if
        unknowns = add_unknowns(unknowns, words[3..$])
        sentence = repeat(0,length(unknowns)+1)
        k = find(words[3],unknowns)
        sentence[k+1] = -2
        k = find(words[5],unknowns)
        sentence[k+1] = 1
        sentence &= 0
        sentences = append(sentences,sentence)
    elsif words[1]="many" then
        --/* eg
            {"many","quarters","and","dimes","have?"}
            {"many","each","coin","have?"}
            {"many","each","have?"}
            {"many","each","bill","have?"}
            {"many","dimes","have?"}
            {"many","coins","each","have?"}
        --*/
        if words[$]!="have?" then ?9/0 end if
        -- no rule, as yet, just outputs everything instead.
    elsif words[1]="same" then
        -- eg {"same","pennies","nickels","and","dimes"}
        unknowns = add_unknowns(unknowns, words[2..$])
        if length(unknowns)!=3 then ?9/0 end if
        sentences = append(sentences,{0,1,-1,0,0})  -- (p==n)
        sentences = append(sentences,{0,0,1,-1,0})  -- (n==d)
    elsif words[1]="total" then
        -- eg {"total","13","bills"}
        if length(words)!=3 or not isnumber[2] or words[3]!="bills" then ?9/0 end if
        sentence = {isnumber[2]}&repeat(1,length(unknowns))
        sentence &= 1
        sentences = append(sentences,sentence)
    else
        --/* eg:
            {"one_dollar_bills","five_dollar_bills","and","ten_dollar_bills"}
            {"only","nickels","dimes","and","quarters"}
            {"only","quarters","and","dimes"}
        --*/
        -- just log assets:
        unknowns = add_unknowns(unknowns, words)
    end if
    if set_asset_sum then
        -- common code for eg {"total","$3.74"} and {"$75","bills"}
        for u=1 to length(unknowns) do
            string uu = unknowns[u]
            k = find(uu,assets)
            sentence &= assetv[k]
        end for
        sentence &= 'a'
        sentences = append(sentences,sentence)
    end if
    if length(rest) then
--      {sequence s2,unknowns} = parse_sentence(rest,unknowns)
        sequence s2
        {s2,unknowns} = parse_sentence(rest,unknowns)
        sentences &= s2
    end if
    return {sentences,unknowns}
end function

procedure solveN(integer n, sequence rules, unknowns, string expected)
--
-- Based on https://mathcs.clarku.edu/~djoyce/ma105/simultaneous.html
--  aka the ancient Chinese Jiuzhang suanshu ~100 B.C. (!!)
--
-- Example (ignoring n, which is solely for output):
--  rules = {{18,1,1},{38,1,5}}, ie 18==p+n, 38==p+5*n
--  unknowns = {"pennies","nickels"}
--  expected = "pennies = 13, nickels = 5"
--
--  In the elimination phase, both p have multipliers of 1, so we can
--  ignore those two sq_mul and just do (38=p+5n)-(18=p+n)==>(20=4n).
--  Obviously therefore n is 5 and substituting backwards p is 13.
--
    string res
    sequence sentences = rules, ri, rj
    integer l = length(rules), rii, rji
    rules = deep_copy(rules)
    for i=1 to l do
        -- successively eliminate (grow lower left triangle of 0s)
        ri = rules[i]
        if length(ri)!=l+1 then ?9/0 end if
        rii = ri[i+1]
        if rii=0 then ?9/0 end if
        for j=i+1 to l do
            rj = rules[j]
            rji = rj[i+1]
            if rji!=0 then
                rj = sq_sub(sq_mul(rj,rii),sq_mul(ri,rji))
                if rj[i+1]!=0 then ?9/0 end if -- (job done)
                rules[j] = rj
            end if
        end for 
    end for 
    for i=l to 1 by -1 do
        -- then substitute each backwards
        ri = rules[i]
        rii = ri[1]/ri[i+1] -- (all else should be 0)
        rules[i] = sprintf("%s = %d",{unknowns[i],rii})
        for j=i-1 to 1 by -1 do
            rj = rules[j]
            rji = rj[i+1]
            if rji!=0 then
                rules[j] = 0
                rj[1] -= rji*rii
                rj[i+1] = 0
                rules[j] = rj
            end if
        end for
    end for 
    res = join(rules,", ")
    printf(1,"%d: %v ==> %s\n",{n,sentences,res})
--  printf(1,"%d: %s\n",{n,res}) -- (maybe pref.)
    if res!=expected then ?9/0 end if
end procedure

printf(1,"\nStep 2: convert sentences into structures/equations, and solve them:\n")
for i=1 to count do
    sequence words = split(lines[i],{"."})
    sequence sentences = {},
             sentencii, -- (one ...but some still contain "and")
             unknowns = {}
    for w=1 to length(words) do
        {sentencii,unknowns} = parse_sentence(words[w],unknowns)
        sentences &= sentencii
    end for
    if length(sentences)>length(unknowns) then
        -- messy: puzzle has too much info!
        -- (14 aka "33 coins" and 17 "Terry" with 38 coins,
        --  eliminate wrongly and get a divide by zero...)
--      sentences = sentences[1..length(unknowns)]
        sentences[-2] = sentences[-1]
        sentences = sentences[1..length(unknowns)]
    end if
    if length(sentences)!=length(unknowns) then ?9/0 end if
    for s=1 to length(sentences) do
        -- pad any short equations, eg 3 more nickels than dimes
        -- needs a 0 for quarters, if were not mentioned before.
        sequence ss = sentences[s]
        integer padcode = ss[$]
        ss = ss[1..$-1]
        integer shortlen = length(sentences)+1-length(ss)
        if shortlen then
            switch padcode do
                case 0: ss &= repeat(0,shortlen)
                case 1: ss &= repeat(1,shortlen)
                case 'a':
                    for u=-shortlen to -1 do
                        string uu = unknowns[u]
                        integer k = find(uu,assets)
                        ss &= assetv[k]
                    end for
                default: ?9/0
            end switch
        end if
        sentences[s] = ss
    end for
    solveN(i,sentences,unknowns,expectations[i])
end for

integer k = find(false,vused)
if k then ?{"unused vocab",vocab[k]} end if
Output:

You just gotta love this Pidgin English! The problem numbering system used below is mine alone.
I was slightly unsure whether to interpolate these q&a outputs, but I think the separation chosen has its own merits.
The structures/equations of part 2 are completely unreadable at first, but quite simple really.

24 puzzles:
Step 1: remove noise and otherwise simplify (if nothing else, down to a 31-word vocab):

1: 3 times asmany quarters as dimes . total money $5.95 . many quarters and dimes have?
2: 18 coins consisting pennies and nickels . total coins 38c . many pennies and nickels have?
3: 6 more quarters than nickels . total coins $3.00 . many nickels and quarters have?
4: 32 coins consisting nickels and quarters . total money $3.80 . many nickels and quarters have?
5: 2 times asmany dimes as pennies and 3 more nickels than pennies . total coins $1.97 . many each coin have?
6: 3 times asmany quarters as half_dollars and 6 more dimes than half_dollars . total money $4.65 . many each coin have?
7: $75 bills . 2 times asmany one_dollar_bills as five_dollar_bills and 1 less ten_dollar_bills than five_dollar_bills . many each bill have?
8: 8 coins consisting quarters and dimes . total $1.25 . many each coin have?
9: 3 times asmany dimes as nickels and 5 more pennies than nickels . total coins $1.13 . many each coin have?
10: 9 more dimes than nickels . total money $1.20 . many dimes have?
11: 20 bills consisting one_dollar_bills and two_dollar_bills . total money $35 . many two_dollar_bills have?
12: 8 more pennies than nickels and 3 more dimes than nickels . total money $3.10 . many dimes have?
13: 26 coins all dollars and quarters . total $17.00 . many each coin have?
14: 33 coins consisting nickels dimes and quarters . total $3.30 . 3 times asmany nickels as quarters and one-half asmany dimes as nickels . many coins each have?
15: same pennies nickels and dimes . coins total $1.44 . many each coin have?
16: 25 coins nickels and dimes . total $1.65 . many each coin have?
17: 2 more quarters than dimes . total $6.80 . quarters and dimes 38 . many quarters and dimes have?
18: one_dollar_bills five_dollar_bills and ten_dollar_bills . total $43 . 4 times asmany one_dollar_bills as ten_dollar_bills . total 13 bills . many each bill have?
19: 3 times asmany one_dollar_bills as five_dollar_bills . total $32 . many each bill have?
20: total $41.25 . 255 coins . only nickels dimes and quarters . 2 times asmany dimes as nickels . many each coin have?
21: 27 coins . total $4.50 . only quarters and dimes . many coins each have?
22: $13.25 nickels and quarters . 165 coins . many each coin have?
23: $45.25 quarters and dimes . 29 less quarters than dimes . many each coin have?
24: 12 coins consisting dimes and pennies . total money $0.30 . many each coin have?

Step 2: convert sentences into structures/equations, and solve them:
1: {{0,1,-3},{595,25,10}} ==> quarters = 21, dimes = 7
2: {{18,1,1},{38,1,5}} ==> pennies = 13, nickels = 5
3: {{6,1,-1},{300,25,5}} ==> quarters = 11, nickels = 5
4: {{32,1,1},{380,5,25}} ==> nickels = 21, quarters = 11
5: {{0,1,-2,0},{3,0,-1,1},{197,10,1,5}} ==> dimes = 14, pennies = 7, nickels = 10
6: {{0,1,-3,0},{6,0,-1,1},{465,25,50,10}} ==> quarters = 9, half_dollars = 3, dimes = 9
7: {{7500,100,500,1000},{0,1,-2,0},{1,0,1,-1}} ==> one_dollar_bills = 10, five_dollar_bills = 5, ten_dollar_bills = 4
8: {{8,1,1},{125,25,10}} ==> quarters = 3, dimes = 5
9: {{0,1,-3,0},{5,0,-1,1},{113,10,5,1}} ==> dimes = 9, nickels = 3, pennies = 8
10: {{9,1,-1},{120,10,5}} ==> dimes = 11, nickels = 2
11: {{20,1,1},{3500,100,200}} ==> one_dollar_bills = 5, two_dollar_bills = 15
12: {{8,1,-1,0},{3,0,-1,1},{310,1,5,10}} ==> pennies = 25, nickels = 17, dimes = 20
13: {{26,1,1},{1700,100,25}} ==> dollars = 14, quarters = 12
14: {{33,1,1,1},{330,5,10,25},{0,1,-2,0}} ==> nickels = 18, dimes = 9, quarters = 6
15: {{0,1,-1,0},{0,0,1,-1},{144,1,5,10}} ==> pennies = 9, nickels = 9, dimes = 9
16: {{25,1,1},{165,5,10}} ==> nickels = 17, dimes = 8
17: {{2,1,-1},{38,1,1}} ==> quarters = 20, dimes = 18
18: {{4300,100,500,1000},{0,1,0,-4},{13,1,1,1}} ==> one_dollar_bills = 8, five_dollar_bills = 3, ten_dollar_bills = 2
19: {{0,1,-3},{3200,100,500}} ==> one_dollar_bills = 12, five_dollar_bills = 4
20: {{4125,5,10,25},{255,1,1,1},{0,-2,1,0}} ==> nickels = 45, dimes = 90, quarters = 120
21: {{27,1,1},{450,25,10}} ==> quarters = 12, dimes = 15
22: {{1325,5,25},{165,1,1}} ==> nickels = 140, quarters = 25
23: {{4525,25,10},{29,-1,1}} ==> quarters = 121, dimes = 150
24: {{12,1,1},{30,10,1}} ==> dimes = 2, pennies = 10

Wren

Translation of: Go
Library: Wren-dynamic
Library: Wren-pattern
Library: Wren-str
Library: Wren-sort
Library: Wren-fmt
import "./dynamic" for Struct
import "./pattern" for Pattern
import "./str" for Str
import "./sort" for Sort
import "./fmt" for Fmt

var Kind = Struct.create("Kind", ["name", "value", "number"])

// variable1 = constant1 * variable2 + constant2
var Relation = Struct.create("Relation", ["variable1", "variable2", "constant1", "constant2"])

var nums = {
     "one-half": "0 times", "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", "forty": "40",
    "fifty": "50", "sixty": "60", "seventy": "70", "eighty": "80", "ninety": "90", "hundred": "100"
}

var nums2 = {
    "twenty-": "2", "thirty-": "3", "forty-": "4",
    "fifty-": "5", "sixty-": "6", "seventy-": "7", "eighty-": "8", "ninety-": "9"
}

var coins = {
    "pennies": 0.01, "nickels": 0.05, "dimes": 0.10, "quarters": 0.25, "half-dollars": 0.50,
    "one-dollar": 1.00, "two-dollar": 2.00, "five-dollar": 5.00, "ten-dollar": 10.00
}

var bills = {
    "$1": "one-dollar", "$2": "two-dollar", "$5": "five-dollar", "$10": "ten-dollar"
}

var rx1 = Pattern.new("[/$+1/f|+1/d¢]")
var rx2 = Pattern.new("[pennies|nickels|dimes|quarters|half-dollar|one-dollar|two-dollar|five-dollar|ten-dollar]")
var rx3 = Pattern.new("/s[+1/d]/s")
var rx4 = Pattern.new("[+1/d] times as many [+1/y] as [~she has |][+1/y]")
var rx5 = Pattern.new("[+1/d] more [+1/y] than [~she has |][+1/y]")
var rx6 = Pattern.new("[+1/d] less [+1/y] than [~she has |][+1/y]")
var rx7 = Pattern.new("[+1/d] dollars")

var spaced = Fn.new { |s| " %(s) " }

// Gets a sorted list of monetary values.
var getValues = Fn.new { |q|
    var ss = rx1.findAll(q).map { |m| m.text.trimEnd(".") }.toList
    if (ss.count == 0) return []
    var res = []
    for (s in ss) {
        if (s == "") continue
        if (s[0] == "$") {
            s = s[1..-1]
        } else {
            s = "." + s[0..-3] // '¢' is 2 bytes
        }
        var f = Num.fromString(s)
        res.add(f)
    }
    res.sort()
    return res
}

// Gets a sorted slice of non-monetary integers.
var getNumbers = Fn.new { |q|
    var ns = rx3.findAll(q).map { |m| m.text }.toList
    if (ns.count == 0) return null
    var res = []
    for (n in ns) {
        var i = Num.fromString(n)
        res.add(i)
    }
    res.sort()
    return res
}

// Gets the 'kinds' for the problem.
var getKinds = Fn.new { |a|
    var num = Num.fromString(a[1])
    var kinds = [Kind.new(a[2], 0, 0), Kind.new(a[4], 0, 0)]
    var areCoins = false
    for (i in 0...kinds.count) {
        var v = coins[kinds[i].name]
        if (v) {
            kinds[i].value = v
            areCoins = true
        }
    }
    if (!areCoins) return [0, null]
    return [num, kinds]
}

// Checks if the problem involves 3 coins and
// also returns their names and the names of the coins which occur most.
var hasThreeCoins = Fn.new { |q|
    q = q.replace(".", "").replace(",", "")
    var words = q.split(" ")
    var coinMap = {}
    for (word in words) {
        if (coins.containsKey(word)) {
            var v = coinMap[word]
            if (v) {
                coinMap[word] = v + 1
            } else {
                coinMap[word] = 1
            }
        }
    }
    if (coinMap.count != 3) return [null, "", false]
    var maxNum = 0
    var maxNames = []
    var names = []
    for (me in coinMap) {
        names.add(me.key)
        if (me.value > maxNum) {
            maxNum = me.value
            maxNames = [me.key]
        } else if (me.value == maxNum) {
            maxNames.add(me.key)
        }
    }
    return [names, maxNames, true]
}

var errorMsg = Fn.new { |p|
    System.print(p)
    System.print("*** CAN'T SOLVE THIS ONE ***\n")
}

var printAnswers = Fn.new { |p, kinds|
    System.print(p)
    System.write("ANSWER:")
    var i = 0
    for (kind in kinds) {
        if (i > 0) System.write(",")
        System.write(" %(kind.number) %(kind.name)")
        i = i + 1
    }
    System.print("\n")
}

// Processes a problem which involves 3 coins.
var threeCoins = Fn.new { |p, q, names, maxNames|
    var relations = []
    var am = rx4.findAll(q).map { |m| [m.text] + m.capsText }.toList
    for (i in 0...am.count) {
        var res = getKinds.call(am[i])
        var mult = res[0]
        var kinds = res[1]
        relations.add(Relation.new(kinds[0].name, kinds[1].name, mult, 0))
    }
    var mt = rx5.findAll(q).map { |m| [m.text] + m.capsText }.toList
    for (i in 0...mt.count) {
        var res = getKinds.call(mt[i])
        var plus = res[0]
        var kinds = res[1]
        relations.add(Relation.new(kinds[0].name, kinds[1].name, 1, plus))
    }
    var lt = rx6.findAll(q).map { |m| [m.text] + m.capsText }.toList
    for (i in 0...lt.count) {
        var res = getKinds.call(lt[i])
        var minus = res[0]
        var kinds = res[1]
        relations.add(Relation.new(kinds[0].name, kinds[1].name, 1, -minus))
    }
    var le = relations.count
    if (le > 2) {
        errorMsg.call(p)
        return
    }
    if (le == 0) { // numbers of each coin must be the same
        var sum = 0
        for (name in names) sum = sum + coins[name]
        var tv = getValues.call(q)[-1]
        var n = (tv/sum + 0.5).floor
        var kinds = []
        for (name in names) kinds.add(Kind.new(name, 0, n))
        printAnswers.call(p, kinds)
    } else {
        var totalValue = getValues.call(q)[-1]
        for (maxName in maxNames) {
            for (i in 0...le) {
                if (relations[i].constant1 == 0) {
                    relations[i].constant1 = 0.5 // deals with 'one-half' cases
                }
                if (le == 2 && maxName == relations[i].variable1) {
                    var v = relations[i].variable2
                    relations[i].variable1 = v
                    relations[i].variable2 = maxName
                    relations[i].constant1 = 1 / relations[i].constant1
                    relations[i].constant2 = -relations[i].constant2
                }
            }
            var tv = totalValue
            var v1 = ""
            var v2 = ""
            var v3 = ""
            var n1 = 0
            var n2 = 0
            var n3 = 0
            if (le == 2) {
                var tmc = coins[relations[0].variable1] * relations[0].constant1 +
                    coins[relations[1].variable1] * relations[1].constant1 + coins[maxName]
                tv = tv - coins[relations[0].variable1] * relations[0].constant2 -
                    coins[relations[1].variable1] * relations[1].constant2
                v1 = maxName
                v2 = relations[0].variable1
                v3 = relations[1].variable1
                n1 = (tv/tmc + 0.5).floor
                n2 = (relations[0].constant1*n1 + relations[0].constant2 + 0.5).floor
                n3 = (relations[1].constant1*n1 + relations[1].constant2 + 0.5).floor
            } else {
                var tn = getNumbers.call(q)[-1]
                v1 = relations[0].variable1
                v2 = relations[0].variable2
                for (name in names) {
                    if (name != v1 && name != v2) {
                        v3 = name
                        break
                    }
                }
                var mult1 = coins[v1]
                var mult2 = coins[v2]
                var mult3 = coins[v3]
                n2 = (((tn-relations[0].constant2)*mult3-tv+relations[0].constant2*mult1)/
                    ((relations[0].constant1+1)*mult3-relations[0].constant1*mult1-mult2) + 0.5).floor
                n1 = (n2*relations[0].constant1 + relations[0].constant2 + 0.5).floor
                n3 = tn.floor - n1 - n2
            }
            var calcValue = n1 * coins[v1] + n2 * coins[v2] + n3 * coins[v3]
            if ((totalValue - calcValue).abs <= 1e-14) {
                var kinds = [Kind.new(v1, 0, n1), Kind.new(v2, 0, n2), Kind.new(v3, 0, n3)]
                printAnswers.call(p, kinds)
                return
            }
        }
        errorMsg.call(p)
    }
}

var ps = [
    "If a person has three times as many quarters as dimes and the total amount of money is $5.95, find the number of quarters and dimes.",
    "A pile of 18 coins consists of pennies and nickels. If the total amount of the coins is 38¢, find the number of pennies and nickels.",
    "A small child has 6 more quarters than nickels. If the total amount of coins is $3.00, find the number of nickels and quarters the child has.",
    "A child's bank contains 32 coins consisting of nickels and quarters. If the total amount of money is $3.80, find the number of nickels and quarters in the bank.",
    "A person has twice as many dimes as she has pennies and three more nickels than pennies. If the total amount of the coins is $1.97, find the numbers of each type of coin the person has.",
    "In a bank, there are three times as many quarters as half dollars and 6 more dimes than half dollars. If the total amount of the money in the bank is $4.65, find the number of each type of coin in the bank.",
    "A person bought 12 stamps consisting of 37¢ stamps and 23¢ stamps. If the cost of the stamps is $3.74, find the number of each type of the stamps purchased.",
    "A dairy store sold a total of 80 ice cream sandwiches and ice cream bars. If the sandwiches cost $0.69 each and the bars cost $0.75 each and the store made $58.08, find the number of each sold.",
    "An office supply store sells college-ruled notebook paper for $1.59 a ream and wide-ruled notebook paper for $2.29 a ream. If a student purchased 9 reams of notebook paper and paid $15.71, how many reams of each type of paper did the student purchase?",
    "A clerk is given $75 in bills to put in a cash drawer at the start of a workday. There are twice as many $1 bills as $5 bills and one less $10 bill than $5 bills. How many of each type of bill are there?",
    "A person has 8 coins consisting of quarters and dimes. If the total amount of this change is $1.25, how many of each kind of coin are there?",
    "A person has 3 times as many dimes as he has nickels and 5 more pennies than nickels. If the total amount of these coins is $1.13, how many of each kind of coin does he have?",
    "A person bought ten greeting cards consisting of birthday cards costing $1.50 each and anniversary cards costing $2.00 each. If the total cost of the cards was $17.00, find the number of each kind of card the person bought.",
    "A person has 9 more dimes than nickels. If the total amount of money is $1.20, find the number of dimes the person has.",
    "A person has 20 bills consisting of $1 bills and $2 bills. If the total amount of money the person has is $35, find the number of $2 bills the person has.",
    "A bank contains 8 more pennies than nickels and 3 more dimes than nickels. If the total amount of money in the bank is $3.10, find the number of dimes in the bank.",
    "Your uncle walks in, jingling the coins in his pocket. He grins at you and tells you that you can have all the coins if you can figure out how many of each kind of coin he is carrying. You're not too interested until he tells you that he's been collecting those gold-tone one-dollar coins. The twenty-six coins in his pocket are all dollars and quarters, and they add up to seventeen dollars in value. How many of each coin does he have?",
    "A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30. If there are three times as many nickels as quarters, and one-half as many dimes as nickels, how many coins of each kind are there?",
    "A wallet contains the same number of pennies, nickels, and dimes. The coins total $1.44. How many of each type of coin does the wallet contain?",
    "Suppose Ken has 25 coins in nickels and dimes only and has a total of $1.65. How many of each coin does he have?",
    "Terry has 2 more quarters than dimes and has a total of $6.80. The number of quarters and dimes is 38. How many quarters and dimes does Terry have?",
    "In my wallet, I have one-dollar bills, five-dollar bills, and ten-dollar bills. The total amount in my wallet is $43. I have four times as many one-dollar bills as ten-dollar bills. All together, there are 13 bills in my wallet. How many of each bill do I have?",
    "Marsha has three times as many one-dollar bills as she does five dollar bills. She has a total of $32. How many of each bill does she have?",
    "A vending machine has $41.25 in it. There are 255 coins total and the machine only accepts nickels, dimes and quarters. There are twice as many dimes as nickels. How many of each coin are in the machine?",
    "Michael had 27 coins in all, valuing $4.50. If he had only quarters and dimes, how many coins of each kind did he have?",
    "Lucille had $13.25 in nickels and quarters. If she had 165 coins in all, how many of each type of coin did she have?",
    "Ben has $45.25 in quarters and dimes. If he has 29 less quarters than dimes, how many of each type of coin does he have?",
    "A person has 12 coins consisting of dimes and pennies. If the total amount of money is $0.30, how many of each coin are there?"
]
for (p in ps) {
    var q = Str.lower(p).replace("twice", "two times").replace(" does ", " has ")
    for (d in ["half", "one", "two", "five", "ten"]) {
        q = q.replace(d + " dollar", d + "-dollar")
    }
    for (me in nums) {
        q = q.replace(spaced.call(me.key), spaced.call(me.value))
    }
    for (me in nums2) {
        q = q.replace(me.key, me.value)
    }
    for (me in nums) {
        q = q.replace(me.key + " ", me.value + " ")
    }
    for (me in bills) {
        q = q.replace(me.key + " ", me.value + " ")
    }
    q = q.replace(" bills", "").replace(" bill", "")
    // check if there are 3 coins involved
    var res = hasThreeCoins.call(q)
    if (res[2]){
        threeCoins.call(p, q, res[0], res[1])
        continue
    }
    var am = rx4.findAll(q).map { |m| [m.text] + m.capsText }.toList
    if (am.count == 1) {
        var res = getKinds.call(am[0])
        var mult = res[0]
        var kinds = res[1]
        if (!kinds) {
            errorMsg.call(p)
            continue
        }
        var tv = getValues.call(q)[-1]
        kinds[1].number = (tv/(mult*kinds[0].value + kinds[1].value) + 0.5).floor
        kinds[0].number = kinds[1].number * mult
        printAnswers.call(p, kinds)
        continue
    }
    var mt = rx5.findAll(q).map { |m| [m.text] + m.capsText }.toList
    if (mt.count == 1) {
        var res = getKinds.call(mt[0])
        var plus = res[0]
        var kinds = res[1]
        if (!kinds) {
            errorMsg.call(p)
            continue
        }
        var tv = getValues.call(q)[-1]
        kinds[1].number = ((tv-plus*kinds[0].value)/(kinds[0].value + kinds[1].value) + 0.5).floor
        kinds[0].number = kinds[1].number + plus
        printAnswers.call(p, kinds)
        continue
    }
    var lt = rx6.findAll(q).map { |m| [m.text] + m.capsText }.toList
    if (lt.count == 1) {
        var res = getKinds.call(lt[0])
        var minus = res[0]
        var kinds = res[1]
        if (!kinds) {
            errorMsg.call(p)
            continue
        }
        var tv = getValues.call(q)[-1]
        kinds[1].number = ((tv+minus*kinds[0].value)/(kinds[0].value + kinds[1].value) + 0.5).floor
        kinds[0].number = kinds[1].number - minus
        printAnswers.call(p, kinds)
        continue
    }
    res = getValues.call(q)
    var tv = 0
    if (res.count > 0) {
        tv = res[-1]
    } else {
        var res3 = rx7.findAll(q).map { |m| [m.text] + m.capsText }.toList
        tv = Num.fromString(res3[0][1])
    }
    var tn = getNumbers.call(q)[-1]
    var coinNames = rx2.findAll(q).map { |m| m.text }.toList
    Sort.insertion(coinNames)
    var kinds = []
    if (coinNames.count > 0) {
        kinds.add(Kind.new(coinNames[0], coins[coinNames[0]], 0))
        for (i in 1...coinNames.count) {
            if (coinNames[i] != coinNames[i-1]) {
                kinds.add(Kind.new(coinNames[i], coins[coinNames[i]], 0))
            }
        }
        if (kinds.count != 2) {
            errorMsg.call(p)
            continue
        }
    } else if (res.count >= 3) {
        kinds.add(Kind.new(Fmt.swrite("$$$.2f item", res[0]), res[0], 0))
        for (i in 1...res.count-1) {
            if (res[i] != res[i-1]) {
                kinds.add(Kind.new(Fmt.swrite("$$$.2f item", res[i]), res[i], 0))
            }
        }
        if (kinds.count!= 2) {
            errorMsg.call(p)
            continue
        }
    } else {
        errorMsg.call(p)
        continue
    }
    kinds[0].number = ((tv-tn*kinds[1].value)/(kinds[0].value-kinds[1].value) + 0.5).floor
    kinds[1].number = tn - kinds[0].number
    printAnswers.call(p, kinds)
}
Output:
If a person has three times as many quarters as dimes and the total amount of money is $5.95, find the number of quarters and dimes.
ANSWER: 21 quarters, 7 dimes

A pile of 18 coins consists of pennies and nickels. If the total amount of the coins is 38¢, find the number of pennies and nickels.
ANSWER: 5 nickels, 13 pennies

A small child has 6 more quarters than nickels. If the total amount of coins is $3.00, find the number of nickels and quarters the child has.
ANSWER: 11 quarters, 5 nickels

A child's bank contains 32 coins consisting of nickels and quarters. If the total amount of money is $3.80, find the number of nickels and quarters in the bank.
ANSWER: 21 nickels, 11 quarters

A person has twice as many dimes as she has pennies and three more nickels than pennies. If the total amount of the coins is $1.97, find the numbers of each type of coin the person has.
ANSWER: 7 pennies, 14 dimes, 10 nickels

In a bank, there are three times as many quarters as half dollars and 6 more dimes than half dollars. If the total amount of the money in the bank is $4.65, find the number of each type of coin in the bank.
ANSWER: 3 half-dollars, 9 quarters, 9 dimes

A person bought 12 stamps consisting of 37¢ stamps and 23¢ stamps. If the cost of the stamps is $3.74, find the number of each type of the stamps purchased.
ANSWER: 5 $0.23 item, 7 $0.37 item

A dairy store sold a total of 80 ice cream sandwiches and ice cream bars. If the sandwiches cost $0.69 each and the bars cost $0.75 each and the store made $58.08, find the number of each sold.
ANSWER: 32 $0.69 item, 48 $0.75 item

An office supply store sells college-ruled notebook paper for $1.59 a ream and wide-ruled notebook paper for $2.29 a ream. If a student purchased 9 reams of notebook paper and paid $15.71, how many reams of each type of paper did the student purchase?
ANSWER: 7 $1.59 item, 2 $2.29 item

A clerk is given $75 in bills to put in a cash drawer at the start of a workday. There are twice as many $1 bills as $5 bills and one less $10 bill than $5 bills. How many of each type of bill are there?
ANSWER: 5 five-dollar, 10 one-dollar, 4 ten-dollar

A person has 8 coins consisting of quarters and dimes. If the total amount of this change is $1.25, how many of each kind of coin are there?
ANSWER: 5 dimes, 3 quarters

A person has 3 times as many dimes as he has nickels and 5 more pennies than nickels. If the total amount of these coins is $1.13, how many of each kind of coin does he have?
ANSWER: 3 nickels, 9 dimes, 8 pennies

A person bought ten greeting cards consisting of birthday cards costing $1.50 each and anniversary cards costing $2.00 each. If the total cost of the cards was $17.00, find the number of each kind of card the person bought.
ANSWER: 6 $1.50 item, 4 $2.00 item

A person has 9 more dimes than nickels. If the total amount of money is $1.20, find the number of dimes the person has.
ANSWER: 11 dimes, 2 nickels

A person has 20 bills consisting of $1 bills and $2 bills. If the total amount of money the person has is $35, find the number of $2 bills the person has.
ANSWER: 5 one-dollar, 15 two-dollar

A bank contains 8 more pennies than nickels and 3 more dimes than nickels. If the total amount of money in the bank is $3.10, find the number of dimes in the bank.
ANSWER: 17 nickels, 25 pennies, 20 dimes

Your uncle walks in, jingling the coins in his pocket. He grins at you and tells you that you can have all the coins if you can figure out how many of each kind of coin he is carrying. You're not too interested until he tells you that he's been collecting those gold-tone one-dollar coins. The twenty-six coins in his pocket are all dollars and quarters, and they add up to seventeen dollars in value. How many of each coin does he have?
ANSWER: 14 one-dollar, 12 quarters

A collection of 33 coins, consisting of nickels, dimes, and quarters, has a value of $3.30. If there are three times as many nickels as quarters, and one-half as many dimes as nickels, how many coins of each kind are there?
ANSWER: 18 nickels, 6 quarters, 9 dimes

A wallet contains the same number of pennies, nickels, and dimes. The coins total $1.44. How many of each type of coin does the wallet contain?
ANSWER: 9 pennies, 9 dimes, 9 nickels

Suppose Ken has 25 coins in nickels and dimes only and has a total of $1.65. How many of each coin does he have?
ANSWER: 8 dimes, 17 nickels

Terry has 2 more quarters than dimes and has a total of $6.80. The number of quarters and dimes is 38. How many quarters and dimes does Terry have?
ANSWER: 20 quarters, 18 dimes

In my wallet, I have one-dollar bills, five-dollar bills, and ten-dollar bills. The total amount in my wallet is $43. I have four times as many one-dollar bills as ten-dollar bills. All together, there are 13 bills in my wallet. How many of each bill do I have?
ANSWER: 8 one-dollar, 2 ten-dollar, 3 five-dollar

Marsha has three times as many one-dollar bills as she does five dollar bills. She has a total of $32. How many of each bill does she have?
ANSWER: 12 one-dollar, 4 five-dollar

A vending machine has $41.25 in it. There are 255 coins total and the machine only accepts nickels, dimes and quarters. There are twice as many dimes as nickels. How many of each coin are in the machine?
ANSWER: 90 dimes, 45 nickels, 120 quarters

Michael had 27 coins in all, valuing $4.50. If he had only quarters and dimes, how many coins of each kind did he have?
ANSWER: 15 dimes, 12 quarters

Lucille had $13.25 in nickels and quarters. If she had 165 coins in all, how many of each type of coin did she have?
ANSWER: 140 nickels, 25 quarters

Ben has $45.25 in quarters and dimes. If he has 29 less quarters than dimes, how many of each type of coin does he have?
ANSWER: 121 quarters, 150 dimes

A person has 12 coins consisting of dimes and pennies. If the total amount of money is $0.30, how many of each coin are there?
ANSWER: 2 dimes, 10 pennies