Swift compound arithmetic operation ERROR - swift

var ret = -100.0 + (2.0 * 1.3) + (3.0 * 4.0) + (0.2 * 2.0 * 2.0) + 0.1 * 2.0 * 3.0
//output: Cannot invoke '+' with an argument list of type '($T24, $T31)'
When I perform the operation above, error occurs, it's very strange! Is it too complex for swift to compute?

The full error message can be found in the Build log in the Report Navigator:
main.swift:15:66: error: cannot invoke '+' with an argument list of type '($T24, $T31)'
var ret = -100.0 + (2.0 * 1.3) + (3.0 * 4.0) + (0.2 * 2.0 * 2.0) + 0.1 * 2.0 * 3.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
main.swift:15:66: note: expression was too complex to be solved in reasonable time;
consider breaking up the expression into distinct sub-expressions
var ret = -100.0 + (2.0 * 1.3) + (3.0 * 4.0) + (0.2 * 2.0 * 2.0) + 0.1 * 2.0 * 3.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
So yes, this expression is too complex for the current (beta 6) Swift compiler.
I would suggest to file a bug report.
At present, the only workaround seems to be to split the expression in two parts,
e.g.
var ret = -100.0 + (2.0 * 1.3) + (3.0 * 4.0)
ret += (0.2 * 2.0 * 2.0) + 0.1 * 2.0 * 3.0
Of course the parentheses are not necessary here, but removing them does not solve
the problem with the original expression.

Related

How do you make an equation in swift with multiple variables? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am trying to make something and I am trying to use an equation in Swift. This is the equation:
((((((((((calculation.d/100)/2) * Int(0.98) * (sqrt(calculation.vbottle * 1005.967 * (calculation.psi + (calculation.psi * (calculation.vbottle - (calculation.vol/1000))/2)/2) * ((((calculation.d/100)/2) * Int(0.98) * (sqrt(calculation.vbottle * 1005.967 * (calculation.psi + (calculation.psi * (calculation.vbottle - (calculation.vol/1000))/2)/2) /1005.967 * (3.14159 * ((d / 100)/2) * ((d / 100)/2)))) - (((calculation.mempty/1000) + ((calculation.vol * 0.972)/1000))/2) * calculation.g) / (((calculation.mempty/1000) + ((calculation.vol * 0.972)/1000))/2)) * ((1005.967 * (calculation.vol / 1000000) / (((calculation.d/100)/2) * Int(0.98) * (sqrt(calculation.vbottle * 1005.967 * (calculation.psi + (calculation.psi * (calculation.vbottle - (calculation.vol/1000))/2)/2) * 6894.76))))) * 2) sin 2(calculation.theta) / calculation.g) * (1 - calculation.dc))
This might seem complicated but if you understand it, it isn't (for a computer). All the variables have been defined and the error message says:
Missing argument for parameter 'verbatim' in call and another error that says: Unterminated string literal
I am unsure why and whenever I google it up, an actual result never comes up and when one does, it's always about Playgrounds, not the actual Swift that is used to make apps and stuff.
EDIT:
Here is the reproducible example:
'''
//
// ContentView.swift
// MRE File
//
// Created by Go Peter on 2021/06/18.
//
import SwiftUI
struct Calculation {
var vbottle:Int = 2
var g:Int = Int(9.807)
var vol:Int = 250
var d:Int = 2
var theta:Int = 90
var psi:Int = 40
var mempty:Int = 70
}
struct ContentView: View {
var body: some View {
Text("\(((((((((((calculation.d/100)/2) * Int(0.98) * (sqrt(calculation.vbottle * 1005.967 * (calculation.psi + (calculation.psi * (calculation.vbottle - (calculation.vol/1000))/2)/2) * ((((calculation.d/100)/2) * Int(0.98) * (sqrt(calculation.vbottle * 1005.967 * (calculation.psi + (calculation.psi * (calculation.vbottle - (calculation.vol/1000))/2)/2) /1005.967 * (3.14159 * ((d / 100)/2) * ((d / 100)/2)))) - (((calculation.mempty/1000) + ((calculation.vol * 0.972)/1000))/2) * calculation.g) / (((calculation.mempty/1000) + ((calculation.vol * 0.972)/1000))/2)) * ((1005.967 * (calculation.vol / 1000000) / (((calculation.d/100)/2) * Int(0.98) * (sqrt(calculation.vbottle * 1005.967 * (calculation.psi + (calculation.psi * (calculation.vbottle - (calculation.vol/1000))/2)/2) * 6894.76))))) * 2) sin 2(calculation.theta) / calculation.g) * (1 - calculation.dc)))m")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
'''
There are a few errors I see:
You need a space in /1005.967 after the / operator -- there are likely other spots like this as well.
Near the end of the expression, you have a floating sin that doesn't have an operator before it and isn't followed with parenthesis at all
There are many spots where you refer to just d, but probably mean calculation.d
You have a mismatched number of open and closed parenthesis.
You don't actually have a Calculation property defined on your view, so there's nothing to do the calculations on yet.
Because I don't know the intent of some of this stuff, I can't actually fix it for you. But, I'd recommend trying to clean up the code a little -- at the least, it'll make it easier to debug.
To start, move this out of the interpolated String and into a computed property:
var calc : Int { //Int? -- see comment about this
//your calculation here
}
var body: some View {
Text("\(calc)m")
}
Then, I'd break the calculation up into much smaller expressions that are more readable and would let you find your errors more easily than trying to sift through so many parenthesis, etc. Even a computer can theoretically handle a long, tough-to-read expression, it makes it a challenging debugging issue for us humans.
I'd also be really surprised if you truly want Int for these properties. You have a bunch of spots where you're doing things like Int(0.98), which doesn't make sense, because it'll get rounded to 1. Perhaps you instead want to use Double or Float for everything? You'll see as you start breaking the instructions up and the compiler starts to find more errors once it can parse everything correctly that you're going to end up with type mismatches between things like Int and Double in the existing expressions.

Algorithm to Derive All Possible Math Expressions In a Set To get a Target Value

I am new to Swift Programming, and while I could figure the rest of this out for this app I have floating in my head, I'm having a hard time figuring out how to derive a algorithm that could handle this problem:
Given a set of 4 values (probably best to use Double because some can even be fractions), derive all possible combinations that return a result of a target value--in my case, 24.
For example, a+b+c+d, a+b+d+c, a+d+b+c, d+a+b+c, and all arrangements of that set, plus all possible mathematical operators such as (a*b)^(c-d) or (a+b+c)/d.
I was able to find this article, but it doesn't quite match what I'm looking for, especially as order doesn't matter for me
Number of ways to sum the items in a set to get a target value - Order matters
so for example, I could manually do each combination this way:
if a + b + c + d == 24 {
print("\a + \b + \c + \d")
}
My goal is for the user to enter 4 values and let IOS generate a list of all possible mathematical expressions that result in 24.
Patrick
Here is one approach. Start with an array of expressions and an array of values. Initially, the expressions is just the String value of the values:
let expressions = ["1", "2", "3", "4"]
let values = [1, 2, 3, 4]
Pick two expressions (for example "1" and "2", and a binary operator ("+"), and combine them creating an expressions and values with 3 values:
expressions = ["3", "4", "(1 + 2)"]
values = [3, 4, 3]
Repeat this process combining again two of the expressions with an operation:
expressions = ["3", "(4 + (1 + 2))"]
values = [3, 7]
Finally, combine the last two expressions with "+":
expressions = ["(3 + (4 + (1 + 2)))"]
values = [10]
Once you reach a single expression, check to see if the value matches your target.
The following is a recursive function that tries all combinations of values and operations to create the expressions in search of a target:
import Foundation
// An array of tuples containing an operator name and a closure
// that performs the operation
let ops: [(name: String, function: (Double, Double) -> Double)] = [
("+", { $0 + $1 }),
("-", { $0 - $1 }),
("*", { $0 * $1 }),
("/", { $0 / $1 }),
("^", { pow($0, $1) })
]
func compute(expressions: [String], values: [Double], target: Double) {
// base case of the recursion: if there is only one
// expression and one value, check if the value is the
// target value we're looking for and print the expression
// and value if the target is matched
if expressions.count == 1 {
if values[0] == target {
print("\(expressions[0]) = \(values[0])")
}
} else if expressions.count >= 2 {
// loop through all of the expressions choosing each
// as the first expression
for idx1 in expressions.indices {
// copy the expressions and values arrays so that
// we can remove the expression and value
// without modifying the original arrays
// which will be needed for the next try
var expcopy = expressions
var valcopy = values
let exp1 = expcopy.remove(at: idx1)
let val1 = valcopy.remove(at: idx1)
// loop through the remaining expressions to find
// the second one
for idx2 in expcopy.indices {
// again, copy the arrays to keep from modifying
// the originals while searching
var expcopy2 = expcopy
var valcopy2 = valcopy
let exp2 = expcopy2.remove(at: idx2)
let val2 = valcopy2.remove(at: idx2)
// now try all possible operations to combine
// the two expressions
for op in ops {
// use the closure to compute the value
let value = op.function(val1, val2)
// combine the expressions into a new string
// expression with the operator in the
// middle and surrounded by () if this is
// not the top level expression
var exp = "\(exp1) \(op.name) \(exp2)"
if !expcopy2.isEmpty {
exp = "(\(exp))"
}
// now that we've reduced the number of
// expressions by 1, recurse by calling
// compute again on the reduced list of
// expressions
compute(expressions: expcopy2 + [exp], values: valcopy2 + [value], target: target)
}
}
}
}
}
// This helper function creates the array of expressions from
// the array of values, and then calls the main function above
// to do the real work
func search(values: [Double], target: Double) {
compute(expressions: values.map { String($0) }, values: values, target: target)
}
Example 1:
search(values: [1, 2, 3, 4], target: 121)
Output:
(1.0 - (3.0 * 4.0)) ^ 2.0 = 121.0
((3.0 * 4.0) - 1.0) ^ 2.0 = 121.0
(1.0 - (4.0 * 3.0)) ^ 2.0 = 121.0
((4.0 * 3.0) - 1.0) ^ 2.0 = 121.0
Example 2:
search(values: [1, 2, 3], target: 1)
Output:
3.0 / (1.0 + 2.0) = 1.0
(1.0 + 2.0) / 3.0 = 1.0
3.0 - (1.0 * 2.0) = 1.0
(1.0 ^ 2.0) ^ 3.0 = 1.0
(1.0 * 3.0) - 2.0 = 1.0
2.0 - (1.0 ^ 3.0) = 1.0
(1.0 ^ 3.0) ^ 2.0 = 1.0
3.0 / (2.0 + 1.0) = 1.0
(2.0 + 1.0) / 3.0 = 1.0
(2.0 - 1.0) ^ 3.0 = 1.0
3.0 - (2.0 * 1.0) = 1.0
3.0 - (2.0 / 1.0) = 1.0
3.0 - (2.0 ^ 1.0) = 1.0
1.0 ^ (2.0 + 3.0) = 1.0
1.0 ^ (2.0 - 3.0) = 1.0
1.0 ^ (2.0 * 3.0) = 1.0
1.0 ^ (2.0 / 3.0) = 1.0
1.0 ^ (2.0 ^ 3.0) = 1.0
2.0 / (3.0 - 1.0) = 1.0
(3.0 - 1.0) / 2.0 = 1.0
(3.0 * 1.0) - 2.0 = 1.0
(3.0 / 1.0) - 2.0 = 1.0
(3.0 ^ 1.0) - 2.0 = 1.0
1.0 ^ (3.0 + 2.0) = 1.0
1.0 * (3.0 - 2.0) = 1.0
1.0 / (3.0 - 2.0) = 1.0
1.0 ^ (3.0 - 2.0) = 1.0
(3.0 - 2.0) * 1.0 = 1.0
(3.0 - 2.0) / 1.0 = 1.0
(3.0 - 2.0) ^ 1.0 = 1.0
1.0 ^ (3.0 * 2.0) = 1.0
1.0 ^ (3.0 / 2.0) = 1.0
1.0 ^ (3.0 ^ 2.0) = 1.0
Eliminating Duplicate Solutions
With 4 or more values, or even with fewer values that aren't unique, you can end up with duplicate expressions. The way to eliminate the duplicates is to use a Set<String> to keep track of the expressions you've already found and check if that set contains your new expression before printing it as a new solution.
import Foundation
// An array of tuples containing an operator name and a closure
// that performs the operation
let ops: [(name: String, function: (Double, Double) -> Double)] = [
("+", { $0 + $1 }),
("-", { $0 - $1 }),
("*", { $0 * $1 }),
("/", { $0 / $1 }),
("^", { pow($0, $1) })
]
func compute(expressions: [String], values: [Double], target: Double, solutions: inout Set<String>) {
// base case of the recursion: if there is only one
// expression and one value, check if the value is the
// target value we're looking for and print the expression
// and value if the target is matched and we don't already
// have that expression in our set of solutions
if expressions.count == 1 {
if values[0] == target && !solutions.contains(expressions[0]) {
print("\(expressions[0]) = \(values[0])")
solutions.insert(expressions[0])
}
} else if expressions.count >= 2 {
// loop through all of the expressions choosing each
// as the first expression
for idx1 in expressions.indices {
// copy the expressions and values arrays so that
// we can remove the expression and value
// without modifying the original arrays
// which will be needed for the next try
var expcopy = expressions
var valcopy = values
let exp1 = expcopy.remove(at: idx1)
let val1 = valcopy.remove(at: idx1)
// loop through the remaining expressions to find
// the second one
for idx2 in expcopy.indices {
// again, copy the arrays to keep from modifying
// the originals while searching
var expcopy2 = expcopy
var valcopy2 = valcopy
let exp2 = expcopy2.remove(at: idx2)
let val2 = valcopy2.remove(at: idx2)
// now try all possible operations to combine
// the two expressions
for op in ops {
// use the op's function to compute the value
let val = op.function(val1, val2)
// combine the expressions into a new string
// expression with the operator in the
// middle and surrounded by () if this is
// not the top level expression
var exp = "\(exp1) \(op.name) \(exp2)"
if !expcopy2.isEmpty {
exp = "(\(exp))"
}
// now that we've reduced the number of
// expressions by 1, recurse by calling
// compute again on the reduced list of
// expressions
let newexp = expcopy2 + [exp]
let newval = valcopy2 + [val]
compute(expressions: newexp, values: newval, target: target, solutions: &solutions)
}
}
}
}
}
// This helper function creates the array of expressions from
// the array of values, creates a Set to hold the solutions, and
// then calls the main function above to do the real work
func search(values: [Double], target: Double) {
// create a set to keep track of solutions found so far
var solutions = Set<String>()
compute(expressions: values.map { String($0) }, values: values, target: target, solutions: &solutions)
print("\n\(solutions.count) unique solutions were found")
}
Example:
search(values: [2, 2, 1], target: 5)
Output:
1.0 + (2.0 + 2.0) = 5.0
(2.0 + 2.0) + 1.0 = 5.0
1.0 + (2.0 * 2.0) = 5.0
(2.0 * 2.0) + 1.0 = 5.0
1.0 + (2.0 ^ 2.0) = 5.0
(2.0 ^ 2.0) + 1.0 = 5.0
2.0 + (2.0 + 1.0) = 5.0
(2.0 + 1.0) + 2.0 = 5.0
2.0 + (1.0 + 2.0) = 5.0
(1.0 + 2.0) + 2.0 = 5.0
10 unique solutions were found
A simple approach not covered in the solutions referenced in the first few comments is to generate your candidate expressions in reverse polish notation (RPN). If you've studied CS, or owned a HP calculator, you might recall this. RPN has the advantage that it contains no parentheses and is evaluated in strict left-to-right order. Follow the link for a full description, here are a couple of examples:
Algebraic: (a+b)*c
RPN: ab+c*
Algebraic: a+(b*c)
RPN: abc*+
In outline to evaluate an RPN expression left-to-right you push any variable you find onto a stack. For any operator you pop 2 values of the stack, combine the with the operation, and push the result back onto the stack.
To generate a single expression for your problem an outline algorithm is:
while there are variables unused or fewer than (number of variables - 1) operators
either:
add any unused variable
or:
if the number of added variables is at least two greater than the
number of added operators add any operator
That will give you a single expression, to generate all of them think recursion. At each stage you iterate through all the choices as above and for each one recurse passing in the partial expression, unused variables, etc. You can store the partial expression in an array, each element being a variable or an operator (think enum). As Swift passes arrays by value as you recurse each call can continue to add elements to the array without effecting other calls.
In pseudocode:
generate(expression: array, variables: variable collection) -> collection
results <- empty collection
for nextVar in variables
add generate(expression + nextVar, variables - nextVar) to results
if #variables in expression - #operators in expression >= 2
for every possible operator
add generate(expression + operator, variables) to results
return results
When a complete expression is generated your can evaluate it and add it to solutions if the result is 24. As a possible optimisation you can evaluate as you go down the recursion to save recalculation of the partial expressions. RPN evaluation can use a stack, which you can build from an array in Swift and pass down in each recursive call. Exploring other optimisation is left to you.
If you get stuck after designing your algorithm and writing some code you can ask a new question - include a link to this one, your algorithm, your code, and your problem; someone will undoubtedly help you along.
HTH

What is the difference between querying by distance and using the earthdistance module in postgres?

In postgres, there are two ways that I know of to query based on distance.
The first is "querying by distance" using a particular algorithm (as seen here http://daynebatten.com/2015/09/latitude-longitude-distance-sql/).
SELECT zcta.*,
3958.755864232 * 2 *
ASIN(SQRT(POWER(SIN((41.318301 - zcta.latitude) *
PI() / 180 / 2), 2) + COS(41.318301 * PI() / 180) *
COS(zcta.latitude * PI() / 180) *
POWER(SIN((-83.6174935 - zcta.longitude) *
PI() / 180 / 2), 2))) AS distance,
MOD(CAST((ATAN2( ((zcta.longitude - -83.6174935) / 57.2957795),
((zcta.latitude - 41.318301) / 57.2957795)) *
57.2957795) + 360 AS decimal), 360) AS bearing
FROM "zcta"
WHERE (zcta.latitude BETWEEN 40.59464208444576
AND 42.04195991555424
AND zcta.longitude BETWEEN -84.58101890178294
AND -82.65396809821705
AND (3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((41.318301 - zcta.latitude) *
PI() / 180 / 2), 2) + COS(41.318301 * PI() / 180) * COS(zcta.latitude *
PI() / 180) * POWER(SIN((-83.6174935 - zcta.longitude) *
PI() / 180 / 2), 2))))
BETWEEN 0.0
AND 50)
ORDER BY distance ASC
The second is the earthdistance module (https://www.postgresql.org/docs/8.3/static/earthdistance.html) for geospatial queries.
select *
from zcta
where earth_box(ll_to_earth(41.318301, -83.6174935), 63067.2) #>
ll_to_earth(zcta.latitude, zcta.longitude)
What is the difference here? Which is better to use? Which is more accurate? How do each work?
A bit late answer, but my addition. The first is a roll-your-own solution, whereas the latter is a Postgresql extension or module called earthdistance. To install, in psql:
CREATE EXTENSION IF NOT EXISTS earthdistance;
You might need to do the same for cube first as they share resources. Or...
CREATE EXTENSION IF NOT EXISTS earthdistance CASCADE;
Here is the documentation.

Distance calculation in query with slick database

I am using slick with scala to find the distance of the user to the closes spot. But I'm not sure how to properly do this with slick. I've tried different ways, but I keep getting errors with symbols or not getting the appropriate answers. The SQL query that I'm looking to convert is:
SELECT *, 3956 * 2 * sin(sqrt( pow(sin((spot_lat -
abs(lat)) * Pi/180 / 2),2) + cos(spot_lat * Pi/180 ) * cos(abs(lat) * Pi/180) *
pow(sin((spot_lon – lon) * Pi/180 / 2), 2) )) as distance
FROM Spots
Where lat and lon have been given as inputs
First, define your database trig functions so that they can be used by slick:
val dbSin = SimpleFunction.unary[Double, Double]("sin")
val dbCos = SimpleFunction.unary[Double, Double]("cos")
val dbSqrt = SimpleFunction.unary[Double, Double]("sqrt")
val dbPow = SimpleFunction.binary[Double, Double, Double]("pow")
val dbAbs = SimpleFunction.unary[Double, Double]("abs")
When you use these functions in a slick query, it generates the SQL query with calls to the database function. Also, make sure that the trig functions are defined in the database you are using. Read more about it at: http://slick.typesafe.com/doc/2.1.0/userdefined.html
Now you can use these functions in your query:
import scala.math._
def distance(lat: Double, lon: Double) = globals.spots map { spot =>
3956 * 2 * dbSin(dbSqrt(dbPow(dbSin((spot.splot_lat - Pi / 180.0 / 2.0), 2) +
dbCos(spot.spot_lat * Pi / 180.0) * dbCos(dbAbs(lat) * Pi / 180.0) *
dbPow(dbSin((spot.spot_lon - lon) * Pi / 180.0 / 2.0), 2)))
}
Please double check that I copied the equation correctly.

Math calculation breaks in coffeescript

I have a long equation written in coffeescript, which turns in a function call when compiled to JavaScript:
CoffeeScript:
#u[idx] = #max(0, currU + t * ((#dU * ((#uu[right] + #uu[left] + #uu[bottom] + #uu[top]) -4 * currU) - d2) + currF * (1.0 - currU)))
JavaScript:
this.max(0, currU + t * ((this.dU * ((this.uu[right] + this.uu[left] + this.uu[bottom] + this.uu[top])(-4 * currU)) - d2) + currF * (1.0 - currU)));
The problem is this part:
((#uu[right] + #uu[left] + #uu[bottom] + #uu[top]) -4 * currU)
which turns into a function call:
((this.uu[right] + this.uu[left] + this.uu[bottom] + this.uu[top])(-4 * currU))
Can someone explain whats going on here.
You want this:
#u[idx] = #max(0, currU + t * ((#dU * ((#uu[right] + #uu[left] + #uu[bottom] + #uu[top]) - 4 * currU) - d2) + currF * (1.0 - currU)))
Which compiles to:
this.u[idx] = this.max(0, currU + t * ((this.dU * ((this.uu[right] + this.uu[left] + this.uu[bottom] + this.uu[top]) - 4 * currU) - d2) + currF * (1.0 - currU)));
The silly little issue is the -4, vs - 4.
Without the space, the compiler assumes the -4 * currU to be an argument to the 'function' , (#uu[right] + #uu[left] + #uu[bottom] + #uu[top]).