def TempConversion(ciferTemp: Double, typeDeg: String): Double = {
var celsit: Double = 0.0
var far: Double = 0.0
if (typeDeg = "c")
far = (ciferTemp - 32) / (5.0 / 9.0)
println(far + "en farhenheit")
else if (typeDeg ="f") {
celsit = (ciferTemp * (5.0 / 9.0)) + 32
println(celsit + "en celsius")}
}
I cannot figure out what is wrong with this function, it tells me a semi-colon is expected.
The problem is that you started a statement with else.
With an if block, you can only omit the {curly brackets} if there is exactly one statement. Since you put a second statement, the compiler assumes that it is not part of the if block, and therefore the else that comes after is the start of a brand new expression. Since else isn't a valid start of an expression, the compiler is confused, and gives you that error.
Since you intend have multiple lines/statements in your initial if block, you should wrap it with brackets. You should also indent both of those lines (lack of proper indentation isn't the problem here, but is still important).
(oh and you are using an assignment operator = where you should have an equality operator ==)
Here's what it ought to look like:
if(typeDeg == "c"){
far = (ciferTemp - 32) / (5.0 / 9.0)
println(far + "en farhenheit")
} else if(typeDeg == "f") {
celsit = (ciferTemp * (5.0 / 9.0)) + 32
println(celsit + "en celsius")
}
#Dylan addresses some issues with the if else and ==. Here's how you could do it with pattern matching to make it even more concise. You can add other cases to handle conversions to other units of measure and one for invalid typeDeg input.
def TempConversion(ciferTemp: Double, typeDeg: String): Double = typeDeg match {
case "c" => (ciferTemp - 32) / (5.0 / 9.0)
case "f" => (ciferTemp * (5.0 / 9.0)) + 32
}
After making some changes
def TempConversion(ciferTemp: Double, typeDeg: String): Double = {
if (typeDeg == "c") {
val far = (ciferTemp - 32) / (5.0 / 9.0)
println(far + "en farhenheit")
far
} else if (typeDeg == "f") {
val celsit = (ciferTemp * (5.0 / 9.0)) + 32
println(celsit + "en celsius")
celsit
} else {
// throw an exception, maybe?
0.0
}
}
(use == not = for comparisons, use {} around the if-else,return the result of the calculation from each part of the if/else, do something when typeDeg has neither expected value, move the declarations of far and celsit inside the relevant blocks (and change them to vals))
Related
swift: about ternary operator Question. Why my code is error code??? Please tell me why I'm wrong.
var arr = [0,1,2,3,4,5,6,7,8]
var result = 0;
for a in 0..<arr.count{
for b in 1..<arr.count - 1{
for c in 2..<arr.count - 2 {
arr[a] + arr[b] + arr[c] <= input[1] ? result = arr[a] + arr[b] +arr[c] : continue
}
}
}
[this is my error]
[1]: https://i.stack.imgur.com/UdiUB.png
In Swift, the ternary condition operator is an expression which takes the form
<condition> ? <expression if true> : <expression if false>
Expressions are part of larger statements, and the ternary specifically is one which evaluates to either the expression after the ?, or the one after the : depending on the truth of the condition.
continue, however, is not an expression but a statement on its own, which means that it cannot be on either side of the ternary.
Thinking about this another way: expressions evaluate to some value (e.g., can be put on the right-hand-side of an assignment, like x = <some expression>), while statements do not (e.g., it doesn't make sense to write x = continue).
You will need to express this in the form of a regular if-statement then:
if arr[a] + arr[b] + arr[c] <= input[1] {
result = arr[a] + arr[b] +arr[c]
} else {
continue
}
Note that the above code might be grammatically correct (in that it will compile), but it is unlikely to be what you mean: the loop will automatically continue at the end of execution even if arr[a] + arr[b] + arr[c] <= input[1] by default, which means that your result may get overwritten later in the loop. It seems likely that you mean something like
outer_loop: for a in 0 ..< arr.count {
for b in 1 ..< arr.count - 1 {
for c in 2 ..< arr.count - 2 {
if arr[a] + arr[b] + arr[c] <= input[1] {
result = arr[a] + arr[b] + arr[c]
// `break` would only exit the `c` loop, but with this label
// we can exit all loops at once.
break outer_loop
}
}
}
}
I am trying to explore Scala. I am new to Scala. This might be a simple question and searched in google to get below scenario to solve. But couldn't get answers. Instead of Scala I am getting Java related things.
My requirement to print format like below.
* * * * *
* * * *
* * *
*
Can someone suggest me how to get this format.
Thanks in advance.
Kanti
Just for the sake of illustration, here are two possible solution to the problem.
The first one is completely imperative, while the second one is more functional.
The idea is that this serves as an example to help you think how to solve problems in a programmatic way.
As many of us have already commented, if you do not understand the basic ideas behind the solution, then this code will be useless in the long term.
Here is the imperative solution, the idea is simple, we need to print n lines, each line contains n - i starts (where i is the number of the line, starting at 0). The starts are separated by an empty space.
Finally, before printing the starts, we need some padding, looking at example inputs, you can see that the padding starts at 0 and increases by 1 for each line.
def printReverseTriangle(n: Int): Unit = {
var i = 0
var padding = 0
while (i < n) {
var j = padding
while (j > 0) {
print(" ")
j -= 1
}
var k = n - i
while (k > 0) {
print("* ")
k -= 1
}
println()
i += 1
padding += 1
}
}
And here is a more functional approach.
As you can see, in this case we do not need to mutate anything, all the high level operators do that for us. And we only need to focus on the description of the solution.
def printReverseTriangle(size: Int): Unit = {
def makeReverseTriangle(size: Int): List[String] =
List.tabulate(size) { i =>
(" " * (size - i)) + ("* " * i)
}.reverse
println(makeReverseTriangle(size).mkString("\n"))
}
To add an alternative to Luis's answer, here's a recursive solution:
import scala.annotation.tailrec
def printStars(i: Int): Unit = {
#tailrec
def loop(j: Int): Unit = {
if(j > 0) {
val stars = Range(0, j).map(_ => "*").mkString(" ") // make stars
if(i == j) println(stars) // no need for spaces
else println((" " * (i - j)) + stars) // spaces before the stars
loop(j - 1)
}
}
loop(i)
}
printStars(3)
// * * *
// * *
// *
This function will take a maximum triangle size (i), and for that size until i is no longer greater than 0 it will print out the correct number of stars (and spaces), then decrement by 1.
Note: Range(0, j).map(_ => "*").mkString(" ") can be replaced with List.tabulate(j)(_ => "*").mkString(" ") per Luis's answer - I'm not sure which is faster (I've not tested it).
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
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.
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
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.
I'm trying to get the average of an array of Ints using the following code:
let numbers = [1,2,3,4,5]
let avg = numbers.reduce(0) { return $0 + $1 / numbers.count }
print(avg) // 1
Which is obviously incorrect. However, if I remove the division to the outside of the closure:
let numbers = [1,2,3,4,5]
let avg = numbers.reduce(0) { return $0 + $1 } / numbers.count
print(avg) // 3
Bingo! I think I remember reading somewhere (can't recall if it was in relation to Swift, JavaScript or programming math in general) that this has something to do with the fact that dividing the sum by the length yields a float / double e.g. (1 + 2) / 5 = 0.6 which will be rounded down within the sum to 0. However I would expect ((1 + 2) + 3) / 5 = 1.2 to return 1, however it too seems to return 0.
With doubles, the calculation works as expected whichever way it's calculated, as long as I box the count integer to a double:
let numbers = [1.0,2.0,3.0,4.0,5.0]
let avg = numbers.reduce(0) { return $0 + $1 / Double(numbers.count) }
print(avg) // 3
I think I understand the why (maybe not?). But I can't come up with a solid example to prove it.
Any help and / or explanation is very much appreciated. Thanks.
The division does not yield a double; you're doing integer division.
You're not getting ((1 + 2) + 3 etc.) / 5.
In the first case, you're getting (((((0 + (1/5 = 0)) + (2/5 = 0)) + (3/5 = 0)) + (4/5 = 0)) + (5/5 = 1)) = 0 + 0 + 0 + 0 + 0 + 1 = 1.
In the second case, you're getting ((((((0 + 1) + 2) + 3) + 4) + 5) / 5) = 15 / 5 = 3.
In the third case, double precision loss is much smaller than the integer, and you get something like (((((0 + (1/5.0 = 0.2)) + (2/5.0 = 0.4)) + (3/5.0 = 0.6)) + (4/5.0 = 0.8)) + (5/5.0 = 1.0)).
The problem is that what you are attempting with the first piece of code does not make sense mathematically.
The average of a sequence is the sum of the entire sequence divided by the number of elements.
reduce calls the lambda function for every member of the collection it is being called on. Thus you are summing and dividing all the way through.
For people finding it hard to understand the original answer.
Consider.
let x = 4
let y = 3
let answer = x/y
You expect the answer to be a Double, but no, it is an Int. For you to get an answer which is not a rounded down Int. You must explicitly state the values to be Double. See below
let doubleAnswer = Double(x)/Double(y)
Hope this helped.