why my code is slow when finding Fibonacci sum? - ios
I'm writing answers for project Euler Questions in this repo
but having some performance issues in my solution
Question 2:
Each new term in the Fibonacci sequence is generated by adding the previous two terms.
By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
My Solution is
func solution2()
{
func fibonacci(number: Int) -> (Int)
{
if number <= 1
{
return number
}
else
{
return fibonacci(number - 1) + fibonacci(number - 2)
}
}
var sum = 0
print("calculating...")
for index in 2..<50
{
print (index)
if (fibonacci(index) % 2 == 0)
{
sum += fibonacci(index)
}
}
print(sum)
}
My Question is, why it gets super slow after iteration 42, i want to do it for 4000000 as the question says, any help?
solution 2
func solution2_fast()
{
var phiOne : Double = (1.0 + sqrt(5.0)) / 2.0
var phiTwo : Double = (1.0 - sqrt(5.0)) / 2.0
func findFibonacciNumber (nthNumber : Double) -> Int64
{
let nthNumber : Double = (pow(phiOne, nthNumber) - (pow(phiTwo, nthNumber))) / sqrt(5.0)
return Int64(nthNumber)
}
var sum : Int64 = 0
print("calculating...")
for index in 2..<4000000
{
print (index)
let f = findFibonacciNumber(Double(index))
if (f % 2 == 0)
{
sum += f
}
}
print(sum)
}
The most important thing about PE questions is to think about what it is asking.
This is not asking you to produce all Fibonacci numbers F(n) less than 4000000. It is asking for the sum of all even F(n) less than 4000000.
Think about the sum of all F(n) where F(n) < 10.
1 + 2 + 3 + 5 + 8
I could do this by calculating F(1), then F(2), then F(3), and so on... and then checking they are less than 10 before adding them up.
Or I could store two variables...
F1 = 1
F2 = 2
And a total...
Total = 3
Now I can turn this into a while loop and lose the recursion altogether. In fact, the most complex thing I'm doing is adding two numbers together...
I came up with this...
func sumEvenFibonacci(lessThan limit: Int) -> Int {
// store the first two Fibonacci numbers
var n1 = 1
var n2 = 2
// and a cumulative total
var total = 0
// repeat until you hit the limit
while n2 < limit {
// if the current Fibonacci is even then add to total
if n2 % 2 == 0 {
total += n2
}
// move the stored Fibonacci numbers up by one.
let temp = n2
n2 = n2 + n1
n1 = temp
}
return total
}
It runs in a fraction of a second.
sumEvenFibonacci(lessThan: 4000000)
Finds the correct answer.
In fact this... sumEvenFibonacci(lessThan: 1000000000000000000) runs in about half a second.
The second solution seems to be fast(er) although an Int64 will not be sufficient to store the result. The sum of Fibonacci numbers from 2..91 is 7,527,100,471,027,205,936 but the largest number you can store in an Int64 is 9,223,372,036,854,775,807. For this you need to use some other types like BigInteger
Because you use the recursive, and it cache in the memory.If you iteration 42, it maybe has so many fibonacci function in your memory, and recursive.So it isn't suitable for recursive, and you can store the result in the array, not the reason of the swift.
this is the answer in two different ways
func solution2_recursive()
{
func fibonacci(number: Int) -> (Int)
{
if number <= 1
{
return number
}
else
{
return fibonacci(number - 1) + fibonacci(number - 2)
}
}
var sum = 0
print("calculating...")
for index in 2..<50
{
print (index)
let f = fibonacci(index)
if( f < 4000000)
{
if (f % 2 == 0)
{
sum += f
}
}
else
{
print(sum)
return
}
}
}
solution 2
func solution2()
{
var phiOne : Double = (1.0 + sqrt(5.0)) / 2.0
var phiTwo : Double = (1.0 - sqrt(5.0)) / 2.0
func findFibonacciNumber (nthNumber : Double) -> Int64
{
let nthNumber : Double = (pow(phiOne, nthNumber) - (pow(phiTwo, nthNumber))) / sqrt(5.0)
return Int64(nthNumber)
}
var sum : Int64 = 0
print("calculating...")
for index in 2..<50
{
let f = findFibonacciNumber(Double(index))
if(f < 4000000)
{
if (f % 2 == 0)
{
sum += f
}
}
else
{
print(sum)
return
}
}
}
Related
Mathematic calculation using array of numbers and array of arithmetic operators in swift [duplicate]
I am doing a simple calculator, but when performing the multiplication and division, my code doesn't make them a priority over plus and minus. When doing -> 2 + 2 * 4, result = 16 instead of 10... How to conform to the math logic inside my switch statement? mutating func calculateTotal() -> Double { var total: Double = 0 for (i, stringNumber) in stringNumbers.enumerated() { if let number = Double(stringNumber) { switch operators[i] { case "+": total += number case "-": total -= number case "÷": total /= number case "×": total *= number default: break } } } clear() return total }
Assuming you want a generalised and perhaps extensible algorithm for any arithmetic expression, the right way to do this is to use the Shunting Yard algorithm. You have an input stream, which is the numbers and operators as the user typed them in and you have an output stream, which is the same numbers and operators but rearranged into reverse Polish notation. So, for example 2 + 2 * 4 would be transformed into 2 2 4 * + which is easily calculated by putting the numbers on a stack as you read them and applying the operators to the top items on the stack as you read them. To do this the algorithm has an operator stack which can be visualised as a siding (hence "shunting yard") into which low priority operators are shunted until they are needed. The general algorithm is read an item from the input if it is a number send it to the output if the number is an operator then while the operator on the top of the stack is of higher precedence than the operator you have pop the operator on the stack and send it to the output push the operator you read from input onto the stack repeat the above until the input is empty pop all the operators on the stack into the output So if you have 2 + 2 * 4 (NB top of the stack is on the left, bottom of the stack is on the right) start: input: 2 + 2 * 4 output: <empty> stack: <empty> step 1: send the 2 to output input: + 2 * 4 output: 2 stack: <empty> step 2: stack is empty so put + on the stack input: 2 * 4 output: 2 stack: + step 3: send the 2 to output input: * 4 output: 2 2 stack: + step 4: + is lower priority than * so just put * on the stack input: 4 output: 2 2 stack: * + step 5: Send 4 to output input: output: 2 2 4 stack: * + step 6: Input is empty so pop the stack to output input: output: 2 2 4 * + stack: The Wikipedia entry I linked above has a more detailed description and an algorithm that can handle parentheses and function calls and is much more extensible. For completeness, here is an implementation of my simplified version of the algorithm enum Token: CustomStringConvertible { var description: String { switch self { case .number(let num): return "\(num)" case .op(let symbol): return "\(symbol)" } } case op(String) case number(Int) var precedence: Int { switch self { case .op(let symbol): return Token.precedences[symbol] ?? -1 default: return -1 } } var operation: (inout Stack<Int>) -> () { switch self { case .op(let symbol): return Token.operations[symbol]! case .number(let value): return { $0.push(value) } } } static let precedences = [ "+" : 10, "-" : 10, "*" : 20, "/" : 20] static let operations: [String : (inout Stack<Int>) -> ()] = [ "+" : { $0.push($0.pop() + $0.pop()) }, "-" : { $0.push($0.pop() - $0.pop()) }, "*" : { $0.push($0.pop() * $0.pop()) }, "/" : { $0.push($0.pop() / $0.pop()) } ] } struct Stack<T> { var values: [T] = [] var isEmpty: Bool { return values.isEmpty } mutating func push(_ n: T) { values.append(n) } mutating func pop() -> T { return values.removeLast() } func peek() -> T { return values.last! } } func shuntingYard(input: [Token]) -> [Token] { var operatorStack = Stack<Token>() var output: [Token] = [] for token in input { switch token { case .number: output.append(token) case .op: while !operatorStack.isEmpty && operatorStack.peek().precedence >= token.precedence { output.append(operatorStack.pop()) } operatorStack.push(token) } } while !operatorStack.isEmpty { output.append(operatorStack.pop()) } return output } let input: [Token] = [ .number(2), .op("+"), .number(2), .op("*"), .number(4)] let output = shuntingYard(input: input) print("\(output)") var dataStack = Stack<Int>() for token in output { token.operation(&dataStack) } print(dataStack.pop())
If you only have the four operations +, -, x, and ÷, you can do this by keeping track of a pendingOperand and pendingOperation whenever you encounter a + or -. Then compute the pending operation when you encounter another + or -, or at the end of the calculation. Note that + or - computes the pending operation, but then immediately starts a new one. I have modified your function to take the stringNumbers, operators, and initial values as input so that it could be tested independently in a Playground. func calculateTotal(stringNumbers: [String], operators: [String], initial: Double) -> Double { func performPendingOperation(operand: Double, operation: String, total: Double) -> Double { switch operation { case "+": return operand + total case "-": return operand - total default: return total } } var total = initial var pendingOperand = 0.0 var pendingOperation = "" for (i, stringNumber) in stringNumbers.enumerated() { if let number = Double(stringNumber) { switch operators[i] { case "+": total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total) pendingOperand = total pendingOperation = "+" total = number case "-": total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total) pendingOperand = total pendingOperation = "-" total = number case "÷": total /= number case "×": total *= number default: break } } } // Perform final pending operation if needed total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total) // clear() return total } Tests: // 4 + 3 calculateTotal(stringNumbers: ["3"], operators: ["+"], initial: 4) 7 // 4 × 3 calculateTotal(stringNumbers: ["3"], operators: ["×"], initial: 4) 12 // 2 + 2 × 4 calculateTotal(stringNumbers: ["2", "4"], operators: ["+", "×"], initial: 2) 10 // 2 × 2 + 4 calculateTotal(stringNumbers: ["2", "4"], operators: ["×", "+"], initial: 2) 8 // 17 - 2 × 3 + 10 + 7 ÷ 7 calculateTotal(stringNumbers: ["2", "3", "10", "7", "7"], operators: ["-", "×", "+", "+", "÷"], initial: 17) 22
First you have to search in the array to see if there is a ÷ or × sign. Than you can just sum or subtract. mutating func calculateTotal() -> Double { var total: Double = 0 for (i, stringNumber) in stringNumbers.enumerated() { if let number = Double(stringNumber) { switch operators[i] { case "÷": total /= number case "×": total *= number default: break } //Remove the number from the array and make another for loop with the sum and subtract operations. } } clear() return total } This will work if you are not using complex numbers.
If you don't care speed, as it's running by a computer and you may use the machine way to handle it. Just pick one feasible calculate to do it and then repeat until every one is calculated. Just for fun here. I use some stupid variable and function names. func evaluate(_ values: [String]) -> String{ switch values[1] { case "+": return String(Int(values[0])! + Int(values[2])!) case "-": return String(Int(values[0])! - Int(values[2])!) case "×": return String(Int(values[0])! * Int(values[2])!) case "÷": return String(Int(values[0])! / Int(values[2])!) default: break; } return ""; } func oneTime(_ string: inout String, _ strings: [String]) throws{ if let first = try NSRegularExpression(pattern: "(\\d+)\\s*(\(strings.map{"\\\($0)"}.joined(separator: "|")))\\s*(\\d+)", options: []).firstMatch(in: string , options: [], range: NSMakeRange(0, string.count)) { let tempResult = evaluate((1...3).map{ (string as NSString).substring(with: first.range(at: $0))}) string.replaceSubrange( Range(first.range(at: 0), in: string)! , with: tempResult) } } func recursive(_ string: inout String, _ strings: [String]) throws{ var count : Int! repeat{ count = string.count ; try oneTime(&string, strings) } while (count != string.count) } func final(_ string: inout String, _ strings: [[String]]) throws -> String{ return try strings.reduce(into: string) { (result, signs) in try recursive(&string, signs) }} var string = "17 - 23 + 10 + 7 ÷ 7" try final(&string, [["×","÷"],["+","-"]]) print("result:" + string)
Using JeremyP method and the Shunting Yard algorithm was the way that worked for me, but I had some differences that had to do with the Operator Associativity(left or right priority) so I had to work with it and I developed the code, which is based on JeremyP answer but uses arrays. First we have the array with the calculation in Strings, e.g.: let testArray = ["10","+", "5", "*" , "4", "+" , "10", "+", "20", "/", "2"] We use the function below to get the RPN version using the Shunting Yard algorithm. func getRPNArray(calculationArray: [String]) -> [String]{ let c = calculationArray var myRPNArray = [String]() var operandArray = [String]() for i in 0...c.count - 1 { if c[i] != "+" && c[i] != "-" && c[i] != "*" && c[i] != "/" { //push number let number = c[i] myRPNArray.append(number) } else { //if this is the first operand put it on the opStack if operandArray.count == 0 { let firstOperand = c[i] operandArray.append(firstOperand) } else { if c[i] == "+" || c[i] == "-" { operandArray.reverse() myRPNArray.append(contentsOf: operandArray) operandArray = [] let uniqOperand = c[i] operandArray.append(uniqOperand) } else if c[i] == "*" || c[i] == "/" { let strongOperand = c[i] //If I want my mult./div. from right(eg because of parenthesis) the line below is all I need //-------------------------------- // operandArray.append(strongOperand) //---------------------------------- //If I want my mult./div. from left let lastOperand = operandArray[operandArray.count - 1] if lastOperand == "+" || lastOperand == "-" { operandArray.append(strongOperand) } else { myRPNArray.append(lastOperand) operandArray.removeLast() operandArray.append(strongOperand) } } } } } //when I have no more numbers I append the reversed operant array operandArray.reverse() myRPNArray.append(contentsOf: operandArray) operandArray = [] print("RPN: \(myRPNArray)") return myRPNArray } and then we enter the RPN array in the function below to calculate the result. In every loop we remove the numbers and the operand used before and we import the previous result and two "p" in the array so in the end we are left with the solution and an array of "p". func getResultFromRPNarray(myArray: [String]) -> Double { var a = [String]() a = myArray print("a: \(a)") var result = Double() let n = a.count for i in 0...n - 1 { if n < 2 { result = Double(a[0])! } else { if a[i] == "p" { //Do nothing else. Calculations are over and the result is in your hands!!! } else { if a[i] == "+" { result = Double(a[i-2])! + Double(a[i-1])! a.insert(String(result), at: i-2) a.remove(at: i - 1) a.remove(at: i - 1) a.remove(at: i - 1) a.insert("p", at: 0) a.insert("p", at: 0) } else if a[i] == "-" { result = Double(a[i-2])! - Double(a[i-1])! a.insert(String(result), at: i-2) a.remove(at: i - 1) a.remove(at: i - 1) a.remove(at: i - 1) a.insert("p", at: 0) a.insert("p", at: 0) } else if a[i] == "*" { result = Double(a[i-2])! * Double(a[i-1])! a.insert(String(result), at: i-2) a.remove(at: i - 1) a.remove(at: i - 1) a.remove(at: i - 1) a.insert("p", at: 0) a.insert("p", at: 0) } else if a[i] == "/" { result = Double(a[i-2])! / Double(a[i-1])! a.insert(String(result), at: i-2) a.remove(at: i - 1) a.remove(at: i - 1) a.remove(at: i - 1) a.insert("p", at: 0) a.insert("p", at: 0) } else { // it is a number so do nothing and go the next one } }//no over yet }//n>2 }//iterating return result }//Func
Σ Calculation in iOS SDK
I am working on a financial app where I have to perform a calculation. Finance team provide me below formula for calculation as below image [![enter image description here][1]][1] But I am unable to found how to perform below operation in Swift or Objective-C. n t-1 Σ (1+i) t=1 Can you please help me providing an idea of the above calculation? I also read this link but not interested to use the third party.
Swift's reduce function was made for this: (1...n).reduce(0) { (currentResult, t) -> Decimal in currentResult + pow(1 + i, t - 1) }
If we crack it down you have to find summation of (1 + i) ^ (t -1) where t varies from 1 to n. Equivalent function will be func evaluteSummation(n: Int, i: Int ) -> Int { int sum = 0 for t in 1...n { sum += pow(1 + i, t - 1) } return sum }
You can do code like below. func calculatePMT(targetValue : Double, interestRate : Double, time: Int) -> Double { let term = 1.0 + interestRate var denominator = 0.0 for t in 0..<time { let p = pow(term, Double(t)) denominator += p } return targetValue / denominator } let targetValue = 100000.0 let interestRate = 5.0 let time = 4 let pmt = calculatePMT(targetValue: targetValue, interestRate: interestRate, time: time) print(pmt)
Hackerrank New Year Chaos Swift
I am trying to solve Hackerrank's New Year Chaos problem in Swift. https://www.hackerrank.com/challenges/new-year-chaos/problem It is about finding the number of bribes people made on a line waiting for a roller coaster ride. For example, there is a total of 3 bribes in this list [2, 1, 5, 3, 4]. Person 2 bribed person 1. Person 5 bribed person 3 and 4. If there are more than 2 bribes by a person, the line becomes "Too chaotic". I was able to get an exponential solution. However, I want to make it linear. func minimumBribes(q: [Int]) -> Void { var bribeCount = 0 var chaotic = false // for i in 0..<q.count { // if q[i] - (i + 1) > 2 { // chaotic = true // break // } // // for j in i + 1..<q.count { // if q[i] > q[j] { // bribeCount += 1 // } // } // } var i = 0 while i < q.count - 1 { if q[i] - (i + 1) > 2 { chaotic = true break } else if q[i] > i + 1 { bribeCount += (q[i] - (i + 1)) i += 1 } else if q[i] <= i + 1 && q[i] > q[i + 1] && q.indices.contains(i + 1) { bribeCount += 1 i += 1 } else { // q[i] < q[i + 1] i += 1 } } if chaotic { print("Too chaotic") } else { print(bribeCount) } } I commented out the exponential solution, which works. But the linear solution does not work and I cannot find out why. It works with the following arrays, [3,2,1,6,5,4], [2,5,1,3,4], [1,2,5,3,7,8,6,4], [1,3,4,2,7,6,5,9,8,11,10,14,13,12]. But there is a really long array in one of the test cases of the problem, which I do not get the correct answer with my linear solution. For this long array, I get 966 with my exponential solution but the linear solution prints 905. [2,1,5,6,3,4,9,8,11,7,10,14,13,12,17,16,15,19,18,22,20,24,23,21,27,28,25,26,30,29,33,32,31,35,36,34,39,38,37,42,40,44,41,43,47,46,48,45,50,52,49,51,54,56,55,53,59,58,57,61,63,60,65,64,67,68,62,69,66,72,70,74,73,71,77,75,79,78,81,82,80,76,85,84,83,86,89,90,88,87,92,91,95,94,93,98,97,100,96,102,99,104,101,105,103,108,106,109,107,112,111,110,113,116,114,118,119,117,115,122,121,120,124,123,127,125,126,130,129,128,131,133,135,136,132,134,139,140,138,137,143,141,144,146,145,142,148,150,147,149,153,152,155,151,157,154,158,159,156,161,160,164,165,163,167,166,162,170,171,172,168,169,175,173,174,177,176,180,181,178,179,183,182,184,187,188,185,190,189,186,191,194,192,196,197,195,199,193,198,202,200,204,205,203,207,206,201,210,209,211,208,214,215,216,212,218,217,220,213,222,219,224,221,223,227,226,225,230,231,229,228,234,235,233,237,232,239,236,241,238,240,243,242,246,245,248,249,250,247,244,253,252,251,256,255,258,254,257,259,261,262,263,265,264,260,268,266,267,271,270,273,269,274,272,275,278,276,279,277,282,283,280,281,286,284,288,287,290,289,285,293,291,292,296,294,298,297,299,295,302,301,304,303,306,300,305,309,308,307,312,311,314,315,313,310,316,319,318,321,320,317,324,325,322,323,328,327,330,326,332,331,329,335,334,333,336,338,337,341,340,339,344,343,342,347,345,349,346,351,350,348,353,355,352,357,358,354,356,359,361,360,364,362,366,365,363,368,370,367,371,372,369,374,373,376,375,378,379,377,382,381,383,380,386,387,384,385,390,388,392,391,389,393,396,397,394,398,395,401,400,403,402,399,405,407,406,409,408,411,410,404,413,412,415,417,416,414,420,419,422,421,418,424,426,423,425,428,427,431,430,429,434,435,436,437,432,433,440,438,439,443,441,445,442,447,444,448,446,449,452,451,450,455,453,454,457,456,460,459,458,463,462,464,461,467,465,466,470,469,472,468,474,471,475,473,477,476,480,479,478,483,482,485,481,487,484,489,490,491,488,492,486,494,495,496,498,493,500,499,497,502,504,501,503,507,506,505,509,511,508,513,510,512,514,516,518,519,515,521,522,520,524,517,523,525,526,529,527,531,528,533,532,534,530,537,536,539,535,541,538,540,543,544,542,547,548,545,549,546,552,550,551,554,553,557,555,556,560,559,558,563,562,564,561,567,568,566,565,569,572,571,570,575,574,577,576,579,573,580,578,583,581,584,582,587,586,585,590,589,588,593,594,592,595,591,598,599,596,597,602,603,604,605,600,601,608,609,607,611,612,606,610,615,616,614,613,619,618,617,622,620,624,621,626,625,623,628,627,631,630,633,629,635,632,637,636,634,638,640,642,639,641,645,644,647,643,646,650,648,652,653,654,649,651,656,658,657,655,661,659,660,663,664,666,662,668,667,670,665,671,673,669,672,676,677,674,679,675,680,678,681,684,682,686,685,683,689,690,688,687,693,692,691,696,695,698,694,700,701,702,697,704,699,706,703,705,709,707,711,712,710,708,713,716,715,714,718,720,721,719,723,717,722,726,725,724,729,728,727,730,733,732,735,734,736,731,738,737,741,739,740,744,743,742,747,746,745,750,748,752,749,753,751,756,754,758,755,757,761,760,759,764,763,762,767,765,768,766,771,770,769,774,773,776,772,778,777,779,775,781,780,783,784,782,786,788,789,787,790,785,793,791,792,796,795,794,798,797,801,799,803,800,805,802,804,808,806,807,811,809,810,814,812,813,817,816,819,818,815,820,821,823,822,824,826,827,825,828,831,829,830,834,833,836,832,837,839,838,841,835,840,844,842,846,845,843,849,847,851,850,852,848,855,854,853,857,856,858,861,862,860,859,863,866,865,864,867,870,869,868,872,874,875,871,873,877,878,876,880,881,879,884,883,885,882,888,886,890,891,889,893,887,895,892,896,898,894,899,897,902,901,903,905,900,904,908,907,910,909,906,912,911,915,913,916,918,914,919,921,917,923,920,924,922,927,925,929,928,926,932,931,934,930,933,935,937,939,940,938,936,943,944,942,941,947,946,948,945,951,950,949,953,952,956,954,958,957,955,961,962,963,959,964,966,960,965,969,968,971,967,970,974,972,976,973,975,979,977,981,982,978,980,983,986,984,985,989,988,987,990,993,991,995,994,997,992,999,1000,996,998] Please help me figure out what is wrong with my solution. Thanks in advance!!
Here is my solution which passes all the test cases :) func minimumBribes(q: [Int]) -> Void { var bCount = 0 var isChaotic = false for (key,value) in q.enumerated() { if (value - 1) - key > 2 { isChaotic = true break } for index in stride(from: max(0, value - 2), to: key, by: 1){ if q[index] > value { bCount += 1 } } } isChaotic ? print("Too chaotic") : print("\(bCount)") }
What you basically need to do is to first check if the element in each loop is on it's correct position. And if not you find out how much further is it from the right position if its greater than 2 you print "Too chaotic". Your solution is correct uptil this point. But if the difference is less than or equal to 2 then you need to increment the bribes and swap the indices to represent updated array. Furthermore if there are two swaps then you need to represent how the array would be effected by these 2 swaps and hence swap these values before the next iteration to ensure the array is in the condition it would be after these swaps. Please refer to my solution below. It passes for all test cases: func swapValues( arr:inout [Int],index:Int, times: Int, bribes:inout Int) -> Bool { if times == 0 { return false } if arr[index] > arr[index+1] { let temp = arr[index+1] arr[index+1] = arr[index] arr[index] = temp bribes = bribes + 1 return swapValues(arr: &arr, index: index+1, times: times-1,bribes: &bribes) }else{ var diff = abs(arr[index+1] - (index+2)) if diff > 2 { print("Too chaotic") return true } var tooChaotic = swapValues(arr: &arr, index: index+1, times: diff,bribes:&bribes) if tooChaotic { return true } return swapValues(arr: &arr, index: index, times: times, bribes: &bribes) } } func minimumBribes(q: [Int]) -> Void { var qC = q var bribes = 0 var i = 0 while i <= qC.count-1{ if i+1 == qC[i] { i = i + 1 continue } let diff = abs(qC[i] - (i+1)) if diff > 2 { print("Too chaotic") return } var tooChaotic = swapValues(arr: &qC, index: i, times: diff, bribes: &bribes) if tooChaotic { return } } print(bribes) }
I found this short and easy solution. func minimumBribes(q: [Int]) -> Void { var ans = 0 var shouldShow = true for i in stride(from: (q.count - 1), through: 0, by: -1) { if (q[i] - (i+1) > 2) { shouldShow = false break; } for j in stride(from: max(0, q[i] - 2), to: i, by: 1){ if q[j] > q[i] { ans += 1 } } } if shouldShow { print(ans) } else { print("Too chaotic") } } https://github.com/AnanthaKrish/example-ios-apps
Swift convert decimal String to UInt8-Array
I have a very long String (600+ characters) holding a big decimal value (yes I know - sounds like a BigInteger) and need the byte representation of this value. Is there any easy way to archive this with swift? static func decimalStringToUInt8Array(decimalString:String) -> [UInt8] { ... }
Edit: Updated for Swift 5 I wrote you a function to convert your number string. This is written in Swift 5 (originally Swift 1.2). func decimalStringToUInt8Array(_ decimalString: String) -> [UInt8] { // Convert input string into array of Int digits let digits = Array(decimalString).compactMap { Int(String($0)) } // Nothing to process? Return an empty array. guard digits.count > 0 else { return [] } let numdigits = digits.count // Array to hold the result, in reverse order var bytes = [UInt8]() // Convert array of digits into array of Int values each // representing 6 digits of the original number. Six digits // was chosen to work on 32-bit and 64-bit systems. // Compute length of first number. It will be less than 6 if // there isn't a multiple of 6 digits in the number. var ints = Array(repeating: 0, count: (numdigits + 5)/6) var rem = numdigits % 6 if rem == 0 { rem = 6 } var index = 0 var accum = 0 for digit in digits { accum = accum * 10 + digit rem -= 1 if rem == 0 { rem = 6 ints[index] = accum index += 1 accum = 0 } } // Repeatedly divide value by 256, accumulating the remainders. // Repeat until original number is zero while ints.count > 0 { var carry = 0 for (index, value) in ints.enumerated() { var total = carry * 1000000 + value carry = total % 256 total /= 256 ints[index] = total } bytes.append(UInt8(truncatingIfNeeded: carry)) // Remove leading Ints that have become zero. while ints.count > 0 && ints[0] == 0 { ints.remove(at: 0) } } // Reverse the array and return it return bytes.reversed() } print(decimalStringToUInt8Array("0")) // prints "[0]" print(decimalStringToUInt8Array("255")) // prints "[255]" print(decimalStringToUInt8Array("256")) // prints "[1,0]" print(decimalStringToUInt8Array("1024")) // prints "[4,0]" print(decimalStringToUInt8Array("16777216")) // prints "[1,0,0,0]" Here's the reverse function. You'll notice it is very similar: func uInt8ArrayToDecimalString(_ uint8array: [UInt8]) -> String { // Nothing to process? Return an empty string. guard uint8array.count > 0 else { return "" } // For efficiency in calculation, combine 3 bytes into one Int. let numvalues = uint8array.count var ints = Array(repeating: 0, count: (numvalues + 2)/3) var rem = numvalues % 3 if rem == 0 { rem = 3 } var index = 0 var accum = 0 for value in uint8array { accum = accum * 256 + Int(value) rem -= 1 if rem == 0 { rem = 3 ints[index] = accum index += 1 accum = 0 } } // Array to hold the result, in reverse order var digits = [Int]() // Repeatedly divide value by 10, accumulating the remainders. // Repeat until original number is zero while ints.count > 0 { var carry = 0 for (index, value) in ints.enumerated() { var total = carry * 256 * 256 * 256 + value carry = total % 10 total /= 10 ints[index] = total } digits.append(carry) // Remove leading Ints that have become zero. while ints.count > 0 && ints[0] == 0 { ints.remove(at: 0) } } // Reverse the digits array, convert them to String, and join them return digits.reversed().map(String.init).joined() } Doing a round trip test to make sure we get back to where we started: let a = "1234567890987654321333555777999888666444222000111" let b = decimalStringToUInt8Array(a) let c = uInt8ArrayToDecimalString(b) if a == c { print("success") } else { print("failure") } success Check that eight 255 bytes is the same as UInt64.max: print(uInt8ArrayToDecimalString([255, 255, 255, 255, 255, 255, 255, 255])) print(UInt64.max) 18446744073709551615 18446744073709551615
You can use the NSData(int: Int, size: Int) method to get an Int to NSData, and then get the bytes from NSData to an array: [UInt8]. Once you know that, the only thing is to know the size of your array. Darwin comes in handy there with the powfunction. Here is a working example: func stringToUInt8(string: String) -> [UInt8] { if let int = string.toInt() { let power: Float = 1.0 / 16 let size = Int(floor(powf(Float(int), power)) + 1) let data = NSData(bytes: &int, length: size) var b = [UInt8](count: size, repeatedValue: 0) return data.getBytes(&b, length: size) } }
You can always do: let bytes = [UInt8](decimalString.utf8) If you want the UTF-8 bytes.
Provided you had division implemented on your decimal string you could divide by 256 repeatedly. The reminder of the first division is the your least significant byte. Here's an example of division by a scalar in C (assumed the length of the number is stored in A[0] and writes the result in the same array): void div(int A[], int B) { int i, t = 0; for (i = A[0]; i > 0; i--, t %= B) A[i] = (t = t * 10 + A[i]) / B; for (; A[0] > 1 && !A[A[0]]; A[0]--); }
Check if an integer is divisible by another integer (Swift)
I need to check if an integer is divisible by another integer exactly. If not I would like to round it up to the closest multiple of the number. Example: var numberOne = 3 var numberTwo = 5 numberTwo is not a multiple of numberOne therefore I would like it to round numberTwo up to 6. How would I do this? Thank you
1) If you want to check or an integer is divided by another integer: Swift 5 if numberOne.isMultiple(of: numberTwo) { ... } Swift 4 or less if numberOne % numberTwo == 0 { ... } 2) Function to round to the closest multiple value: func roundToClosestMultipleNumber(_ numberOne: Int, _ numberTwo: Int) -> Int { var result: Int = numberOne if numberOne % numberTwo != 0 { if numberOne < numberTwo { result = numberTwo } else { result = (numberOne / numberTwo + 1) * numberTwo } } return result }
You can use the modulo operator %: numberTwo % numberOne == 0 The modulo finds the remainder of an integer division between 2 numbers, so for example: 20 / 3 = 6 20 % 3 = 20 - 6 * 3 = 2 The result of 20/3 is 6.666667 - the dividend (20) minus the integer part of that division multiplied by the divisor (3 * 6) is the modulo (20 - 6 * 3) , equal to 2 in this case. If the modulo is zero, then the dividend is a multiple of the divisor More info about the modulo at this wikipedia page.
Swift 5 isMultiple(of:) Returns true if this value is a multiple of the given value, and false otherwise. func isMultiple(of other: Int) -> Bool let rowNumber = 4 if rowNumber.isMultiple(of: 2) { print("Even") } else { print("Odd") }
You can use truncatingRemainder. E.g., if number.truncatingRemainder(dividingBy: 10) == 0 { print("number is divisible by 10") }