1

I'm looking to create a function that returns a solve for x math equation that can be preformed in ones head (Clearly thats a bit subjective but I'm not sure how else to phrase it).

Example problem: (x - 15)/10 = 6

Note: Only 1 x in the equation

I want to use the operations +, -, *, /, sqrt (Only applied to X -> sqrt(x))

I know that let mathExpression = NSExpression(format: question) converts strings into math equations but when solving for x I'm not sure how to go about doing this.

I previously asked Generating random doable math problems swift for non solving for x problems but I'm not sure how to convert that answer into solving for x

Edit: Goal is to generate an equation and have the user solve for the variable.

Community
  • 1
  • 1
huddie96
  • 1,240
  • 2
  • 13
  • 26
  • 3
    Solving equations is not trivial, unless you restrict the allowed input to a very small set. Even with your restricted set of operations, you could have something like `sqrt(x) = 2*x+3`, which *is* doable, but already requires some algebraic transformation. Or what about polynomial equations, which do not have explicit solutions if the degree exceeds 4? – Martin R Apr 09 '17 at 20:36
  • Is your goal to generate a string like "(x - 15)/10 = 6"? Or is the string supplied by the user, and you're trying to solve for x? – Robert Apr 09 '17 at 20:37
  • @Robert Goal is to generate the string and have the user solve for x. The equation cannot be sqrt(x) = 2*x+3 because there should only be 1 x (or variable) in the equation. – huddie96 Apr 09 '17 at 20:39
  • @MartinR see my comment above as to why that equation couldn't be. I am updating the question though – huddie96 Apr 09 '17 at 20:40
  • @huddie96 there is only 1 variable in that equation. It can appear twice. – xaxxon Apr 09 '17 at 20:47
  • @xaxxon 1 x as in the variable only comes up once – huddie96 Apr 09 '17 at 20:49
  • @huddie96 it's clearly solvable: https://www.wolframalpha.com/input/?i=sqrt(x)%3D2*x%2B3 <== stackoverflow doesn't create the proper link – xaxxon Apr 09 '17 at 20:50
  • @xaxxon I agree it is solvable but im looking to generate an equation with a single x – huddie96 Apr 09 '17 at 20:51
  • @huddie96 what kind of equation are you looking to generate? linear? All linear equations can be put into the form `y = β1*x + β0`. The problem then becomes generating the coefficients `β0` and `β1` – taylor swift Apr 09 '17 at 20:52
  • @taylorswift Yes a linear equation is okay but also an equation where theres a sqrt over the variable x – huddie96 Apr 09 '17 at 20:55
  • The first step would be to (unambiguously) define the possible input. Then you need a parser which parses the input string into some internal representation, like the one used in your previous question. *Then* you can start solving the expression for `x`. – Therefore the question in its current form seems too broad to me. – Martin R Apr 09 '17 at 21:15
  • @MartinR he wants to *generate* equations, not solve them. I’m guessing it’s for some sort of electronic homework problem generator. – taylor swift Apr 09 '17 at 21:28
  • It's for an app I'm building to provide multiple choice questions not homework but yes I'm looking to generate questions – huddie96 Apr 09 '17 at 21:34
  • @huddie96: Should your program *generate* equations or *solve* equations? – You initially say "create a function that returns a solve for x", but later "have the user solve". – Martin R Apr 09 '17 at 21:36
  • @MartinR returns a solve for x math equation. That's a. Equation not an answer. Sorry for the miscommunication – huddie96 Apr 09 '17 at 21:40

2 Answers2

2

Since all you want is a string representing an equation and a value for x, you don't need to do any solving. Just start with x and transform it until you have a nice equation. Here's a sample: (copy and paste it into a Playground to try it out)

import UIKit

enum Operation: String {
    case addition = "+"
    case subtraction = "-"
    case multiplication = "*"
    case division = "/"


    static func all() -> [Operation] {
        return [.addition, .subtraction, .multiplication, .division]
    }

    static func random() -> Operation {
        let all = Operation.all()
        let selection = Int(arc4random_uniform(UInt32(all.count)))
        return all[selection]
    }

}


func addNewTerm(formula: String, result: Int) -> (formula: String, result: Int) {
    // choose a random number and operation
    let operation = Operation.random()
    let number = chooseRandomNumberFor(operation: operation, on: result)
    // apply to the left side
    let newFormula = applyTermTo(formula: formula, number: number, operation: operation)
    // apply to the right side
    let newResult = applyTermTo(result: result, number: number, operation: operation)
    return (newFormula, newResult)
}

func applyTermTo(formula: String, number:Int, operation:Operation) -> String {
    return "\(formula) \(operation.rawValue) \(number)"
}

func applyTermTo(result: Int, number:Int, operation:Operation) -> Int {
    switch(operation) {
    case .addition: return result + number
    case .subtraction: return result - number
    case .multiplication: return result * number
    case .division: return result / number
    }
}

func chooseRandomNumberFor(operation: Operation, on number: Int) -> Int {
    switch(operation) {
    case .addition, .subtraction, .multiplication:
        return Int(arc4random_uniform(10) + 1)
    case .division:
        // add code here to find integer factors
        return 1
    }
}


func generateFormula(_ numTerms:Int = 1) -> (String, Int) {
    let x = Int(arc4random_uniform(10))
    var leftSide = "x"
    var result = x

    for i in 1...numTerms {
        (leftSide, result) = addNewTerm(formula: leftSide, result: result)
        if i < numTerms {
            leftSide = "(" + leftSide + ")"
        }
    }

    let formula = "\(leftSide) = \(result)"

    return (formula, x)
}

func printFormula(_ numTerms:Int = 1) {
    let (formula, x) = generateFormula(numTerms)
    print(formula, "                      x = ", x)
}


for i in 1...30 {
    printFormula(Int(arc4random_uniform(3)) + 1)
}

There are some things missing. The sqrt() function will have to be implemented separately. And for division to be useful, you'll have to add in a system to find factors (since you presumably want the results to be integers). Depending on what sort of output you want, there's a lot more work to do, but this should get you started.

Here's sample output:

(x + 10) - 5 = 11                       x =  6
((x + 6) + 6) - 1 = 20                       x =  9
x - 2 = 5                       x =  7
((x + 3) * 5) - 6 = 39                       x =  6
(x / 1) + 6 = 11                       x =  5
(x * 6) * 3 = 54                       x =  3
x * 9 = 54                       x =  6
((x / 1) - 6) + 8 = 11                       x =  9
Robert
  • 6,660
  • 5
  • 39
  • 62
0

Okay, let’s assume from you saying “Note: Only 1 x in the equation” that what you want is a linear equation of the form y = 0 = β1*x + β0, where β0 and β1 are the slope and intercept coefficients, respectively.

The inverse of (or solution to) any linear equation is given by x = -β0/β1. So what you really need to do is generate random integers β0 and β1 to create your equation. But since it should be “solvable” in someone’s head, you probably want β0 to be divisible by β1, and furthermore, for β1 and β0/β1 to be less than or equal to 12, since this is the upper limit of the commonly known multiplication tables. In this case, just generate a random integer β1 ≤ 12, and β0 equal to β1 times some integer n, 0 ≤ n ≤ 12.

If you want to allow simple fractional solutions like 2/3, just multiply the denominator and the numerator into β0 and β1, respectively, taking care to prevent the numerator or denominator from getting too large (12 is again a good limit).

Since you probably want to make y non-zero, just generate a third random integer y between -12 and 12, and change your output equation to y = β1*x + β0 + y.

Since you mentioned could occur over the x variable only, that is pretty easy to add; the solution (to 0 = β1*sqrt(x) + β0) is just x = (β0/β1)**2.

Here is some very simple (and very problematic) code for generating random integers to get you started:

import func Glibc.srand
import func Glibc.rand
import func Glibc.time

srand(UInt32(time(nil)))
print(rand() % 12)

There are a great many answers on this website that deal with better ways to generate random integers.

Community
  • 1
  • 1
taylor swift
  • 2,039
  • 1
  • 15
  • 29