I have an work to get highest product I could get in an array of Ints.
Given an array of integers, find the highest product you can get from
three of the integers. If array size is less than 3, please printout
-1
here is what I tried which returned 20
func adjacentElementsProduct(inputArray: [Int]) -> Int {
let sorted = inputArray.sorted()
let count = sorted.count
if count > 1 {
return max(sorted[0] * sorted[1] * sorted[2], sorted[count - 1] * sorted[count - 2] * sorted[count - 3])
} else {
return sorted.first ?? 0
}
}
adjacentElementsProduct(inputArray: [3, 1, 2, 5, 4])
it how ever fails for this test case
adjacentElementsProduct(inputArray: [1, 10, -5, 1, -100])
it returns 500 and 5000 is expected
func adjacentElementsProduct(inputArray: [Int]) -> Int {
let sorted = inputArray.sorted()
let count = sorted.count
guard count >= 3 else {
return -1
}
return max(
sorted[count - 1] * sorted[count - 2] * sorted[count - 3],
sorted[count - 1] * sorted[0] * sorted[1]
)
}
How does it work?
There are three cases to consider. The highest product is either
The product of the 3 highest positive numbers
The product of the highest positive number multiplicated by the the product of the two lowest negative numbers (the negatives cancel out)
The product of the 3 lowest negative numbers if there are only negative numbers.
Cases 1 and 3 are covered by sorted[count - 1] * sorted[count - 2] * sorted[count - 3]. Case 2 is covered by sorted[count - 1] * sorted[0] * sorted[1].
func adjacentElementsProduct(inputArray: [Int]) -> Int {
let sorted = inputArray.sorted()
let count = sorted.count
if count < 3 {
return -1
} else {
return max(sorted[0] * sorted[1] * sorted[count - 1],
sorted[count - 1] * sorted[count - 2] * sorted[count - 3])
}
}
Related
I hope you guys can check. when I use 5 as x it should be showing me -0.17749282815107623 but it returns -0.2792375. I couldn't where I have been doing the mistake.
var evenNumbers = [Int]()
for i in 2...10 {
if i % 2 == 0 {
evenNumbers.append(i)
}
}
func power(val: Float, power: Int)->Float{
var c:Float = 1
for i in 1...power {
c *= val
}
return c
}
func bessel(x: Float)->Float{
var j0:Float = 0
var counter = 1
var lastDetermVal:Float = 1
for eNumber in evenNumbers {
print(lastDetermVal)
if counter == 1 {
lastDetermVal *= power(val: Float(eNumber), power: 2)
j0 += (power(val: x, power: eNumber))/lastDetermVal
counter = -1
}else if counter == -1{
lastDetermVal *= power(val: Float(eNumber), power: 2)
j0 -= (power(val: x, power: eNumber))/lastDetermVal
counter = 1
}
}
return 1-j0
}
bessel(x: 5)
Function 1:
Your mistake seems to be that you didn't have enough even numbers.
var evenNumbers = [Int]()
for i in 2...10 {
if i % 2 == 0 {
evenNumbers.append(i)
}
}
After the above is run, evenNumbers will be populated with [2,4,6,8,10]. But to evaluate 10 terms, you need even numbers up to 18 or 20, depending on whether you count 1 as a "term". Therefore, you should loop up to 18 or 20:
var evenNumbers = [Int]()
for i in 2...18 { // I think the 1 at the beginning should count as a "term"
if i % 2 == 0 {
evenNumbers.append(i)
}
}
Alternatively, you can create this array like this:
let evenNumbers = (1..<10).map { $0 * 2 }
This means "for each number between 1 (inclusive) and 10 (exclusive), multiply each by 2".
Now your solution will give you an answer of -0.1776034.
Here's my (rather slow) solution:
func productOfFirstNEvenNumbers(_ n: Int) -> Float {
if n == 0 {
return 1
}
let firstNEvenNumbers = (1...n).map { Float($0) * 2.0 }
// ".reduce(1.0, *)" means "multiply everything"
return firstNEvenNumbers.reduce(1.0, *)
}
func nthTerm(_ n: Int, x: Float) -> Float {
let numerator = pow(x, Float(n) * 2)
// yes, this does recalculate the product of even numbers every time...
let product = productOfFirstNEvenNumbers(n)
let denominator = product * product
return numerator / (denominator) * pow(-1, Float(n))
}
func bessel10Terms(x: Float) -> Float {
// for each number n in the range 0..<10, get the nth term, add them together
(0..<10).map { nthTerm($0, x: x) }.reduce(0, +)
}
print(bessel10Terms(x: 5))
You code is a bit unreadable, however, I have written a simple solution so try to compare your intermediate results:
var terms: [Float] = []
let x: Float = 5
for index in 0 ..< 10 {
guard index > 0 else {
terms.append(1)
continue
}
// calculate only the multiplier for the previous term
// - (minus) to change the sign
// x * x to multiply nominator
// (Float(index * 2) * Float(index * 2) to multiply denominator
let termFactor = -(x * x) / (Float(index * 2) * Float(index * 2))
terms.append(terms[index - 1] * termFactor)
}
print(terms)
// sum the terms
let result = terms.reduce(0, +)
print(result)
One of the errors I see is the fact that you are actually calculating only 5 terms, not 10 (you iterate 1 to 10, but only even numbers).
I have written this function to return the factorial of a given number
func factorial(_ n: Int) -> Int {
if n == 0 {
return 1
}
else {
return n * factorial(n - 1)
}
}
print( factorial(20) ) // 2432902008176640000
Works as it should, as long the given number does not exceed 20, because then the result becomes too high!
How can I circumvent this limit and thus calculate the factorial of higher numbers?
I have searched around and found some bignum libraries for Swift. I'm doing this to learn and be familiar with Swift, therefore I want to figure this out on my own.
Here's an approach that will let you find very large factorials.
Represent large numbers as an array of digits. For instance 987 would be [9, 8, 7]. Multiplying that number by an integer n would require two steps.
Multiply each value in that array by n.
Perform a carry operation to return a result that is again single digits.
For example 987 * 2:
let arr = [9, 8, 7]
let arr2 = arr.map { $0 * 2 }
print(arr2) // [18, 16, 14]
Now, perform the carry operation. Starting at the one's digit, 14 is too big, so keep the 4 and carry the 1. Add the 1 to 16 to get 17.
[18, 17, 4]
Repeat with the ten's place:
[19, 7, 4]
And then with the hundred's place:
[1, 9, 7, 4]
Finally, for printing, you could convert this back to a string:
let arr = [1, 9, 7, 4]
print(arr.map(String.init).joined())
1974
Applying that technique, here is a carryAll function that performs the carry operation, and a factorial that uses it to calculate very large factorials:
func carryAll(_ arr: [Int]) -> [Int] {
var result = [Int]()
var carry = 0
for val in arr.reversed() {
let total = val + carry
let digit = total % 10
carry = total / 10
result.append(digit)
}
while carry > 0 {
let digit = carry % 10
carry = carry / 10
result.append(digit)
}
return result.reversed()
}
func factorial(_ n: Int) -> String {
var result = [1]
for i in 2...n {
result = result.map { $0 * i }
result = carryAll(result)
}
return result.map(String.init).joined()
}
print(factorial(1000))
402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
You can use this library:
BigInt
Install it using CocoaPods:
pod 'BigInt'
Then you can use it like this:
import BigInt
func factorial(_ n: Int) -> BigInt {
if n == 0 {
return 1
}
else {
return BigInt(n) * factorial(n - 1)
}
}
print( factorial(50) ) // 30414093201713378043612608166064768844377641568960512000000000000
To find how many ways we have of making change for the amount 4 given the coins [1,2,3], we can create a DP algorithm that produces the following table:
table[amount][coins.count]
0 1 2 3 4
-----------
(0) 1 | 1 1 1 1 1
(1) 2 | 1 1 2 2 3
(2) 3 | 1 1 2 3 4
The last position being our answer. The answer is 4 because we have the following combinations: [1,1,1,1],[2,1],[2,2],[3,1].
My question is, is it possible to retrieve these combinations from the table I just generated? How?
For completeness, here's my algorithm
func coinChange(coins: [Int], amount: Int) -> Int {
// int[amount+1][coins]
var table = Array<Array<Int>>(repeating: Array<Int>(repeating: 0, count: coins.count), count: amount + 1)
for i in 0..<coins.count {
table[0][i] = 1
}
for i in 1...amount {
for j in 0..<coins.count {
//solutions that include coins[j]
let x = i - coins[j] >= 0 ? table[i - coins[j]][j] : 0
//solutions that don't include coins[j]
let y = j >= 1 ? table[i][j-1] : 0
table[i][j] = x + y
}
}
return table[amount][coins.count - 1];
}
Thanks!
--
Solution
Here's an ugly function that retrieves the combinations, based on #Sayakiss 's explanation:
func getSolution(_ i: Int, _ j: Int) -> [[Int]] {
if j < 0 || i < 0 {
//not a solution
return []
}
if i == 0 && j == 0 {
//valid solution. return an empty array where the coins will be appended
return [[]]
}
return getSolution(i - coins[j], j).map{var a = $0; a.append(coins[j]);return a} + getSolution(i, j - 1)
}
getSolution(amount, coins.count-1)
Output:
[[1, 3], [2, 2], [1, 1, 2], [1, 1, 1, 1]]
Sure you can. We define a new function get_solution(i,j) which means all solution for your table[i][j].
You can think it returns an array of array, for example, the output of get_solution(4,3) is [[1,1,1,1],[2,1],[2,2],[3,1]]. Then:
Case 1. Any solution from get_solution(i - coins[j], j) plus coins[j] is a solution for table[i][j].
Case 2. Any solution from get_solution(i, j - 1) is a solution for table[i][j].
You can prove Case 1 + Case 2 is all possible solution for table[i][j](note you get table[i][j] by this way).
The only problem remains is to implement get_solution(i,j) and I think it's good for you to do it by yourself.
If you still got any question, please don't hesitate to leave a comment here.
I have an array with integers [1, 2, 3, 7, 13, 11, 4] and an integer value 12. I need to return an array of a closest combination of sum of the integer values in the new array.
For example: [1, 2, 3, 7, 13, 11, 4] with value 12. The array that need to returned is [1, 2, 3, 4] because the sum of elements 1 + 2 + 3 + 4 <= 12. This is the longest array and prefered over [1, 7, 4] 1 + 7 + 4 = 12.
this solution works if you dont have repeated numbers in array.
var array = [1, 2, 3, 7, 13, 11, 4, -12, 22, 100]
print(array.sorted())
let value = 19
func close(array: [Int], value: Int) -> (Int , Int) {
let sortedArray = array.sorted()
var lastNumberBeforValue = sortedArray.first!
for (index,number) in sortedArray.enumerated() {
let sub = value - number
if sub > 0 {
lastNumberBeforValue = number
}
if sortedArray.contains(sub) && sub != number {
return (sub, number)
} else if index == sortedArray.count - 1 {
if sub < 0 {
let near = close(array: array, value: value - lastNumberBeforValue)
return (near.0, lastNumberBeforValue)
}
let near = close(array: array, value: sub)
return (near.0, number)
}
}
return (-1,-1)
}
let numbers = close(array: array, value: value)
print(numbers) //prints (4, 13)
This solution also finds the two Integers in an array which sum is closest to a given value:
let array = [1, 2, 3, 7, 13, 11, 4]
let value = 5
var difference = Int.max
var result = [Int(), Int()]
for firstInt in array {
for secondInt in array {
let tempDifference = abs((firstInt + secondInt) - value)
if tempDifference < difference {
difference = tempDifference
result[0] = firstInt
result[1] = secondInt
}
}
}
Or a solution that doesn't allow multiple use of the same value:
for (firstIndex, firstInt) in array.enumerated() {
for (secondIndex, secondInt) in array.enumerated() {
guard firstInt != secondInt else { break }
let tempDifference = abs((firstInt + secondInt) - value)
if tempDifference < difference {
difference = tempDifference
result[0] = firstInt
result[1] = secondInt
}
}
}
You can keep on nesting for-loops and guarding for multiple use of same index, if you want longer result arrays. Finally you can take the valid array with the largest result.count. This is not a vary nice solution though, since it computationally heavy, and requires the array to have a static length.
I'm not necessary good with algorithms but I would do it like that :
Since your rule is <= 5 you can sort your array : [1, 2, 3, 7, 13, 11, 4] => [1, 2, 3, 4, 7, 11, 13]
Then, as you don't need integer > 5 you can split your array in 2 parts and take only the first one : [1, 2, 3, 4]
From there you have to add 4 + 3 and match with your value. If it doesn't work do 4 + 2, then 4 + 1. If it's still > 5, loop with 3,2 ; 3,1 ; etc. I did something like this in a Swift way :
// Init
let array = [1, 2, 3, 7, 13, 11, 4]
let value = 5
let sortedArray = array.sorted()
let usefulArray = sortedArray.filter() {$0 < value}
var hasCombination = false
var currentIndex = usefulArray.count - 1
var indexForSum = currentIndex - 1
// Process
if currentIndex > 0 {
hasCombination = true
while usefulArray[currentIndex] + usefulArray[indexForSum] > value {
indexForSum -= 1
if indexForSum < 0 {
currentIndex -= 1
indexForSum = currentIndex - 1
}
if currentIndex == 0 {
hasCombination = false
break
}
}
}
// Result
if hasCombination {
let combination = [usefulArray[indexForSum], usefulArray[currentIndex]]
} else {
print("No combination")
}
I guess it works, tell me if it doesn't !
I know how to get the factorial answer with recursion
func factorial(n: Int) -> Int {
if n == 0 { return 1 }
else { return n * factorial(n - 1)
}
If I passed factorial(5) the method would return 120, but is it possible to get the calculation?
What I mean is if I had a function called breakDownFactorial and if i called breakDownFactorial(5) it would return 5 * 4 * 3 * 2 * 1, if i called breakDownFactorial(4) it would return 4 * 3 * 2 * 1
and so on.
Well, I'm not entirely sure what you mean by "get the calculation", but to get a string representation of the calculation, you can do something like this:
func breakDownFactorial(n: Int) -> String {
return (1...n).reverse().map(String.init).joinWithSeparator(" * ")
}
breakDownFactorial(5) // 5 * 4 * 3 * 2 * 1
With small modifications, factorial can be converted to breakDownFactorial which returns the string description of the factorial calculation:
func breakDownFactorial(n: Int) -> String {
if n == 0 { return "1" }
else {
return "\(n) * " + breakDownFactorial(n - 1)
}
}
breakDownFactorial(10) // "10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 * 1"
The extra "* 1" accurately reflects how the original factorial function works. If you wish to eliminate it, change the recursive base case to:
if n <= 1 { return "1" }