I'm learning object oriented things and trying to incorporate nested functions into my code so I can gain understanding of how these different operations flow and work, specifically nested functions.
I want to pass values from one function to another then another and, depending on the calculations within each nested func, output certain final numbers. I'm having trouble understanding how to grab and re-declare return values inside a method so they can be used again.
Crude single nested example:
func increaseNumbers(numOne: Double, numTwo: Double) -> (Double, Double) {
var numOneIncreased = numOne + 2
var numTwoIncreased = numTwo + 5
func playWithNumbersMore(warpOne: Double, warpTwo: Double) -> (Double, Double) {
if warpOne < 50 {
var adjustedOne = warpOne + 16.5
var adjustedTwo = warpTwo + 20.8
} else { do nothing... }
return (adjustedOne, adjustedTwo)
}
playWithNumbersMore(warpOne: numOneIncreased, warpTwo: numTwoIncreased)
// How do i re-assign the return values inside playWithNumbersMore?
return (something, somethingTwo)
}
Crudely speaking this is what I want to do if possible:
func increaseNumbers(numOne: Double, numTwo: Double) -> (Double, Double) {
var numOneIncreased = numOne + 2
var numTwoIncreased = numTwo + 5
func playWithNumbersMore(warpOne: Double, warpTwo: Double) -> (Double, Double) {
if warpOne < 50 {
var adjustedOne = warpOne + 16.5
var adjustedTwo = warpTwo + 20.8
} else { do nothing... }
return (adjustedOne, adjustedTwo)
}
// I want to be able to take return values and do more with them... as well as redefine them
// on completion of final "parent function"
// Sort of like this:
var newNumbToPlayOne = adjustedOne
var newNumbToPlayTwo = adjustedTwo
func playMoreWithNewNumbers...
}
Is this possible or am I off the rails?
func increaseNumbers(numOne: Double, numTwo: Double) -> (Double, Double) {
var numOneIncreased = numOne + 2
var numTwoIncreased = numTwo + 5
func playWithNumbersMore(warpOne: Double, warpTwo: Double) -> (Double, Double) {
if warpOne < 50 {
var adjustedOne = warpOne + 16.5
var adjustedTwo = warpTwo + 20.8
return (adjustedOne, adjustedTwo)
}
let result = playWithNumbersMore(warpOne: numOneIncreased, warpTwo: numTwoIncreased)
numOneIncreased = result.0 // result.0 is a adjustedOne
numTwoIncreased = result.1 // result.1 is a adjustedTwo
return result
}
This is how you can use the result of playWithNumbersMore data.
Am I wrong or it is what a are look for?
Related
Already checked other question on this topic, and I can't seem to utilize it to resolve my issue, so I'm creating a new question in order to see if I can't gain some insight on this issue and help others who may run into this using the Online Swift Playground.
Getting Terminated by signal 4 using the following code:
import Foundation
//enter equation here
var equation: String = "2 +( 3* 4)/ 2+22 ="
var equationWithoutWhitespace = equation.filter {!$0.isWhitespace}
//converts String equationWithoutWhitespace to array of Charcters e
let e = Array(equationWithoutWhitespace)
func add(_ firstVal: Int, _ secondVal: Int) -> Int {return Int(firstVal + secondVal)}
func sub(_ firstVal: Int, _ secondVal: Int) -> Int {return Int(firstVal - secondVal)}
func mul(_ firstVal: Int, _ secondVal: Int) -> Int {return Int(firstVal * secondVal)}
func div(_ firstVal: Int, _ secondVal: Int) -> Int {return Int(firstVal / secondVal)}
func power(_ firstVal: Double, _ secondVal: Double) -> Int {return Int(pow(firstVal,secondVal))}
func root(_ firstVal: Double, _ secondVal: Double) -> Int {return Int(pow(firstVal,1/secondVal))}
func checkParenthesis(_ equation: [Character]) -> (low: Int, high: Int){
var low = 0
var high = 0
for (index,value) in equation.enumerated() {
if(equation[index] == "("){
low = index
}
else if(equation[index] == ")"){
high = index
}
}
return (low, high)
}
func doMath(firstVal: Character, op: Character, secondVal: Character) -> Int {
var firstVar: Int! = Int("\(firstVal)")
var secondVar: Int! = Int("\(secondVal)")
switch op {
case "+":
return add(firstVar,secondVar)
case "-":
return sub(firstVar,secondVar)
case "*":
return mul(firstVar,secondVar)
case "/":
return div(firstVar,secondVar)
case "x",
"X":
var firstV: Double! = Double("\(firstVar)")
var secondV: Double! = Double("\(secondVar)")
return power(firstV,secondV)
case "r",
"R":
var firstV: Double! = Double("\(firstVar)")
var secondV: Double! = Double("\(secondVar)")
return root(firstV,secondV)
default:
print("error with operation detection")
return 0
}
}
//create new equation
var e2 = e
//get index of parenthesis & operation
var low = checkParenthesis(e2).low
var high = checkParenthesis(e2).high - 1
var op = low + 1
//if there were parenthesis, do this
if(low != 0 && high != 0){
//remove parenthesis
e2.remove(at: checkParenthesis(e2).low)
e2.remove(at: checkParenthesis(e2).high)
print(doMath(firstVal: e2[low],op: e2[op],secondVal: e2[high]))
}
Edit: this is a partial snippet of the complete project, it is essentially a text based calculator but it utilizes different rules than normal PEMDAS
I was looking over it again today, and I found using print(e2[low], e2[op], e2[high], low, op, high), I was able to check what values I was getting for my command, and realized I was 1 position off, because earlier I was compensating for removing the parenthesis, but later moved that function further down in the program. Because of this, var high = checkParenthesis(e2).high - 1 was 1 value off and not giving me an integer, but instead a character. Changing the - 1 to - 2 fixed the issue and everything works as it should. Thanks to everyone for your help!
I'm creating some utility class stores numeric values(Int, Float, Double etc...).
It has minimum and maximum value, too.
I need convert a value to percent.
So I write the class as below on Playground:
import UIKit
class Series<T: SignedNumeric> {
let minValue: T
let maxValue: T
var datas: [T] = []
let range: T
init(minValue: T, maxValue: T) {
self.minValue = minValue
self.maxValue = maxValue
self.range = (maxValue - minValue)
self.datas = []
}
func percent(value: T) -> Float {
let v: Float = value as! Float
let m: Float = minValue as! Float
let r: Float = range as! Float
return (v - m) / r
}
}
let s = Series<Int>(minValue: -100, maxValue: 100)
s.datas = [20, 0, 40, -100, 100]
Float(s.datas[0] - s.minValue) / Float(s.range)
Float(s.datas[1] - s.minValue) / Float(s.range)
Float(s.datas[2] - s.minValue) / Float(s.range)
Float(s.datas[3] - s.minValue) / Float(s.range)
Float(s.datas[4] - s.minValue) / Float(s.range)
s.percent(value: s.datas[0]) // ERROR !!!
When call s.percent(value: s.datas[0]), it crashed.
How can I write percent() function?
Not every SignedNumeric can be converted to a Float. Recall that to be a SignedNumeric, you need to be able to:
be negative and positive
be multiplied
be added and subtracted
have a magnitude that is Comparable and Numeric
can be converted from an integer
The last 4 requirements are all inherited from Numeric. We can easily build our own type that can do all those things. Here's a contrived example:
struct MyNumber: SignedNumeric, Comparable {
private var secret: [String]
private var isNegative: Bool
private var number: Int { secret.count }
static func *= (lhs: inout MyNumber, rhs: MyNumber) {
lhs = lhs * rhs
}
static func * (lhs: MyNumber, rhs: MyNumber) -> MyNumber {
MyNumber(secret: Array(repeating: "", count: lhs.number * rhs.number), isNegative: lhs.isNegative != rhs.isNegative)
}
init(integerLiteral value: Int) {
let int = value
isNegative = int < 0
secret = Array(repeating: "", count: abs(int))
}
static func < (lhs: MyNumber, rhs: MyNumber) -> Bool {
lhs.number < rhs.number
}
init?<T>(exactly source: T) where T : BinaryInteger {
guard let int = Int(exactly: source) else {
return nil
}
self.init(integerLiteral: int)
}
var magnitude: MyNumber {
MyNumber(secret: secret, isNegative: false)
}
static func - (lhs: MyNumber, rhs: MyNumber) -> MyNumber {
if lhs < rhs {
return -(rhs - lhs)
} else {
return MyNumber(secret: Array(repeating: "", count: lhs.number - rhs.number))
}
}
prefix static func - (operand: MyNumber) -> MyNumber {
MyNumber(secret: operand.secret, isNegative: !operand.isNegative)
}
mutating func negate() {
isNegative.toggle()
}
init(secret: [String], isNegative: Bool = false) {
self.secret = secret
self.isNegative = isNegative
}
typealias Magnitude = MyNumber
static func + (lhs: MyNumber, rhs: MyNumber) -> MyNumber {
MyNumber(secret: lhs.secret + rhs.secret)
}
typealias IntegerLiteralType = Int
}
How on earth is <insert whoever is doing the conversion here> going to know that, to convert MyNumber to Float, it has to do Float(aMyNumber.secret.count)!? Not to mention that secret is private.
On the other hand, Float.init does know how to convert BinaryFloatingPoints and BinaryIntegers to Float, because those protocols define the necessary properties such that Float.init can understand how they are represented. For example, BinaryIntegers are represented by words, which is a RandomAccessCollection of UInts, indexed by Ints.
I suggest that you only add the percent method to types of Series where it actually makes sense:
extension Series where T : BinaryInteger {
func percent(value: T) -> Float {
let v: Float = Float(value)
let m: Float = Float(minValue)
let r: Float = Float(range)
return (v - m) / r
}
}
IMO, it would make sense for any T : FloatingPoint, not just T : BinaryFloatingPoint:
extension Series where T : FloatingPoint {
func percent(value: T) -> T {
let v = value
let m = minValue
let r = range
return (v - m) / r
}
}
Since FloatingPoint supports division too, you don't need to convert to Float!
thank you very much!
I added two extensions:
extension Series where T : BinaryInteger {
func percent(value: T) -> Float {
let v: Float = Float(value)
let m: Float = Float(minValue)
let r: Float = Float(range)
return (v - m) / r
}
}
extension Series where T : FloatingPoint {
func percent(value: T) -> T {
let v = value
let m = minValue
let r = range
return (v - m) / r
}
}
And now I can use percent() with Int, Float, Int16... !
Here is a linkedlist problem:
input: 2 -> 4 -> 3 and 5 -> 6 -> 4
expected 708
because 342 + 465 = 708
What confused me is:
result = result!.next in function toList()
result.next is a class, a reference type, but when I set it to result, it works like a rvalue, and result get the value type nil. Why and how could I fix it?
/**
* Definition for singly-linked list.
* public class ListNode {
* public var val: Int
* public var next: ListNode?
* public init(_ val: Int) {
* self.val = val
* self.next = nil
* }
* }
*/
class Solution {
func toInt(_ l: ListNode?) -> Int {
var power = 1, result = 0, curr = l
while curr != nil {
result += power * curr!.val
curr = curr!.next
power *= 10
}
// print("\(result)")
return result
}
func toList(_ i: Int) -> ListNode? {
var result: ListNode? = nil, num = i
while num != 0 {
result = ListNode(num % 10)
result = result!.next
num /= 10
}
return result
}
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
return toList(toInt(l1) + toInt(l2))
}
}
Try this:
func toList(_ i: Int) -> ListNode? {
var result: ListNode? = ListNode(i % 10), num = i / 10
while num != 0 {
let nextResult = ListNode(num % 10)
result!.next = nextResult
result = result!.next
num /= 10
}
return result
}
I want to know how many common characters in the given sets.
Input: J = "aA", S = "aAAbbbb"
Output: 3
In the python solution for this as follows:
lookup = set(J)
return sum(s in lookup for s in S)
I have following solution in Swift it works, but it looks too wordy. I want to learn shorter way of it.
class Solution {
func checkInItems(_ J: String, _ S: String) -> Int {
let lookup = Set(J) ;
var sy = 0;
for c in S
{
if lookup.contains(c)
{
sy += 1;
}
}
return sy;
}
}
As a small variation of Sh_Khan's answer you can use reduce to
count the number of matching elements without creating an intermediate
array:
func checkInItems(_ J: String, _ S: String) -> Int {
let lookup = Set(J)
return S.reduce(0) { lookup.contains($1) ? $0 + 1 : $0 }
}
In Swift 5 there will be a count(where:) sequence method for this purpose,
see SE-0220 count(where:).
You can try
class Solution {
func checkInItems(_ J: String, _ S: String) -> Int {
let lookup = Set(J)
return S.filter { lookup.contains($0) }.count
}
}
I want to say that if some 2d array contains the "point" format [Int,Int], then regenerate the random numbers, not counting the iteration.
for _ in 0..<33{
let j = Int(arc4random_uniform(10))
let k = Int(arc4random_uniform(10))
while live.contains(//The point j,k){
live.append(Array(arrayLiteral: j,k))
cells[j][k] = true
}
}
From what I understood your question, you want to generate an array of 2D points excluding repetition, you can use CGPoint or define your own Point
struct Point: Equatable {
let x: Int
let y: Int
}
func == (lhs: Point, rhs: Point) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
var live: [Point] = []
for _ in 0..<10{
var candidate = Point(x: Int(arc4random_uniform(10)), y: Int(arc4random_uniform(10)))
while live.contains(candidate) {
candidate = Point(x: Int(arc4random_uniform(10)), y: Int(arc4random_uniform(10)))
}
live.append(candidate)
}
or you can use tuple like so
var live: [(Int, Int)] = []
for _ in 0..<10{
var j = Int(arc4random_uniform(10))
var k = Int(arc4random_uniform(10))
while live.contains({$0 == (j, k)}) {
j = Int(arc4random_uniform(10))
k = Int(arc4random_uniform(10))
}
live.append((j,k))
}
Depending on your problem size, it might be more optimal to build an array of all possible values, and then shuffle and take first X elements every time you need new set of random points. You can optimize it further, but the code'd look similar to:
var possibleValues: [Point] = []
for x in 0..<5 {
for y in 0..<5 {
possibleValues.append(Point(x: x, y: y))
}
}
func randomPoints(numberOfPoints: Int) -> [Point] {
// shuffle original array without changing it
let shuffled = possibleValues.sorted { _ in arc4random_uniform(10) > 5 }
// take first X elements
return Array(shuffled[0..<numberOfPoints])
}
randomPoints(numberOfPoints: 10)
You can optimize this solution even further but that'd require to know more about your data set. Hope this helps