Here is my code.
import UIKit
var str = "Hello, playground"
//There are two sorted arrays nums1 and nums2 of size m and n respectively.
//Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
//Example 1:
//nums1 = [1, 3]
//nums2 = [2]
//
//The median is 2.0
//Example 2:
//nums1 = [1, 2]
//nums2 = [3, 4]
//
//The median is (2 + 3)/2 = 2.5
var num1 = [1,2,2,5]
var num2 = [2,3,9,9]
class Solution {
func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
var A = nums1
var B = nums2
var m = nums1.count
var n = nums2.count
var max_of_left : Int = 0
var min_of_right = 0
if n < m {
var temp : [Int]
var tempt : Int
temp = nums1
tempt = m
A = nums2
B = temp
m = n
n = tempt
}
if n == 0{
fatalError("Arrays must be fulfilled")
}
var imin = 0
var imax = m
let half_len = Int((m+n+1)/2)
while imin <= imax {
let i = Int((imin + imax) / 2)
let j = half_len - i
if i > 0 && A[i-1] > B[j]{
imax = i - 1
}
else if i < m && A[i] < B[j-1]{
imin = i + 1
}
else
{
if i == 0{
max_of_left = B[j-1]
}
else if j == 0{
max_of_left = A[i-1]
}
else
{
max_of_left = max(A[i-1], B[j-1])
}
if m+n % 2 == 1{
return Double(max_of_left)
}
if i==m{
min_of_right = B[j]
}
else if j == n{
min_of_right = A[i]
}
else{
min_of_right = min(A[i], B[j])
//editor indicates error here
}
return Double((Double(max_of_left+min_of_right) / 2.0))
}
}
}
}
var a = Solution()
print(a.findMedianSortedArrays(num1, num2))
error: day4_Median_of_Two_Sorted_Arrays.playground:86:13: error: missing return in a function expected to return 'Double'
Since I put my return out of if statement, I think it will be okay because it will stop while looping when it meets return.
But editor says it's not.
I want to know why. Please explain me why.
Every code path through your findMedianSortedArrays() must return a Double.
So you need a return of a Double placed outside of your while loop. Even if you had every code path within the while loop have a return double, if imin > imax you wouldn't even enter the while loop, and so would need a return of a double outside it.
I fixed it by putting another return out of while loop.
//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
//There are two sorted arrays nums1 and nums2 of size m and n respectively.
//Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
//Example 1:
//nums1 = [1, 3]
//nums2 = [2]
//
//The median is 2.0
//Example 2:
//nums1 = [1, 2]
//nums2 = [3, 4]
//
//The median is (2 + 3)/2 = 2.5
var num1 = [1,2,2,5]
var num2 = [2,3,9,9]
class Solution {
func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
var A = nums1
var B = nums2
var m = nums1.count
var n = nums2.count
var max_of_left : Int = 0
var min_of_right = 0
if n < m {
var temp : [Int]
var tempt : Int
temp = nums1
tempt = m
A = nums2
B = temp
m = n
n = tempt
}
if n == 0{
fatalError("Arrays must be fulfilled")
}
var imin = 0
var imax = m
let half_len = Int((m+n+1)/2)
while imin <= imax {
let i = Int((imin + imax) / 2)
let j = half_len - i
if i > 0 && A[i-1] > B[j]{
imax = i - 1
}
else if i < m && A[i] < B[j-1]{
imin = i + 1
}
else
{
if i == 0{
max_of_left = B[j-1]
}
else if j == 0{
max_of_left = A[i-1]
}
else
{
max_of_left = max(A[i-1], B[j-1])
}
if m+n % 2 == 1{
return Double(max_of_left)
}
if i==m{
min_of_right = B[j]
}
else if j == n{
min_of_right = A[i]
}
else{
min_of_right = min(A[i], B[j])
}
return Double((Double(max_of_left+min_of_right) / 2.0))
}
}
return Double((Double(max_of_left+min_of_right) / 2.0))
}
}
var a = Solution()
print(a.findMedianSortedArrays(num1, num2))
Related
I'm writing a function thats supposed to loop though a 2D array diagonally(top left to bottom right). However, the code does not add to the outer while loop(i), it keeps it at 0. arr is 9X9
var i = 0
var j = 0
while(i < arr.count-1){
while (j < arr.count-1) {
print("i = \(i) --- j = \(j)")
if(i == j){
sumDiagonalLeft += arr[j][i]
print(sumDiagonalLeft)
if(arr[j][i] == 1){
informationUsed += 1
arr[i][j] = 2
}
}
j += 1
}
i += 1
}
Thank you for your time :)
try this,
var array:[[Int]] = []
array.append([1,2,3,4,5,6,7,8,9])
....
array.append([1,2,3,4,5,6,7,8,9])
for (index, element) in array.enumerated(){
for (innerIndex,innerElement) in element.enumerated(){
print(innerElement) // you can do your logics here
}
}
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).
This question already has an answer here:
Swift - fatal error: Array index out of range
(1 answer)
Closed 3 years ago.
Below is the small code snippet written in swift,gives below error, although looking at code nothing seems wrong.
Fatal error: Index out of range
Illegal instruction: 4
Not clear to me what is the exact cause of problem ? Would be really helpful if someone can share insights on it.
func getBinary(ValueInDecimal:Int) -> [Int]
{
var valueToPlayWith = ValueInDecimal
var aryBinary = [Int]()
var i:Int = 0
while valueToPlayWith != 0 {
aryBinary[i] = valueToPlayWith % 2
valueToPlayWith = valueToPlayWith / 2
i = i + 1
}
return aryBinary
}
// calling of function
let aryBin = getBinary(ValueInDecimal:10)
print(aryBin)
Expected answer is binary value of passed decimal number in array of 0s and 1s.
So I think if I will use it like this then syntax array[i] = value will work.
func getBinary(ValueInDecimal:Int) -> [Int:Int]
{
var valueToPlayWith = ValueInDecimal
var aryBinary = [Int:Int]()
var i:Int = 0
while valueToPlayWith != 0 {
aryBinary[i] = valueToPlayWith % 2
valueToPlayWith = valueToPlayWith / 2
i = i + 1
}
return aryBinary
}
let aryBin = getBinary(ValueInDecimal:10)
print(aryBin)
This is an empty array
var aryBinary = [Int]()
so this will crash as index 0 doesn't exist
aryBinary[i] = valueToPlayWith % 2
Fatal error: Index out of range
You may need
func getBinary(_ valueInDecimal:Int) -> [Int] {
var valueToPlayWith = valueInDecimal
var aryBinary = [Int]()
while valueToPlayWith != 0 {
aryBinary.append(valueToPlayWith % 2)
valueToPlayWith = valueToPlayWith / 2
}
return aryBinary
}
let aryBin = getBinary(10)
print(aryBin) /// [0, 1, 0, 1]
I want to add the numbers together and print every 4 elements, however i cannot wrap my head around using the stride function, if i am using the wrong approach please explain a better method
var numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13]
func addNumbersByStride(){
var output = Stride...
//first output = 1+2+3+4 = 10
//second output = 5+6+7+8 = 26 and so on
print(output)
}
It seems you would like to use stride ...
let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13]
let by = 4
let i = stride(from: arr.startIndex, to: arr.endIndex, by: by)
var j = i.makeIterator()
while let n = j.next() {
let e = min(n.advanced(by: by), arr.endIndex)
let sum = arr[n..<e].reduce(0, +)
print("summ of arr[\(n)..<\(e)]", sum)
}
prints
summ of arr[0..<4] 10
summ of arr[4..<8] 26
summ of arr[8..<12] 42
summ of arr[12..<13] 13
You can first split the array into chunks, and then add the chunks up:
extension Array {
// split array into chunks of n
func chunked(into size: Int) -> [[Element]] {
return stride(from: 0, to: count, by: size).map {
Array(self[$0 ..< Swift.min($0 + size, count)])
}
}
}
// add each chunk up:
let results = numbers.chunked(into: 4).map { $0.reduce(0, +) }
If you would like to discard the last sum if the length of the original array is not divisible by 4, you can add an if statement like this:
let results: [Int]
if numbers.count % 4 != 0 {
results = Array(numbers.chunked(into: 4).map { $0.reduce(0, +) }.dropLast())
} else {
results = numbers.chunked(into: 4).map { $0.reduce(0, +) }
}
This is quite a basic solution and maybe not so elegant. First calculate and print sum of every group of 4 elements
var sum = 0
var count = 0
for n in stride(from: 4, to: numbers.count, by: 4) {
sum = 0
for i in n-4..<n {
sum += numbers[i]
}
count = n
print(sum)
}
Then calculate the sum of the remaining elements
sum = 0
for n in count..<numbers.count {
sum += numbers[n]
}
print(sum)
I have updated Xcode (7.3) and there are a lot of changes; C-like for expressions will be deprecated. For a simple example,
for var i = 0; i <= array.count - 1; i++
{
//something with array[i]
}
How do I write this clear and simple C-like for-loop to be compliant with the new changes?
for var i = 0, j = 1; i <= array.count - 2 && j <= array.count - 1; i++, j++
{
//something with array[i] and array[j]
}
Update.
One more variant
for var i = 0; i <= <array.count - 1; i++
{
for var j = i + 1; j <= array.count - 1; j++
{
//something with array[i] and array[j]
}
}
And more ...
for var i = 0, j = 1, g = 2; i <= array.count - 3 && j <= array.count - 2 && g <= array.count - 1; i++, j++, g++
{
//something with array[i] and array[j] and array[g]
}
Update2 After several suggestions for me while loop is preferable universal substitution for all cases more complicated than the simple example of C-like for-loop (suitable for for in expression). No need every time to search for new approach.
For instance: Instead of
for var i = 0; i <= <array.count - 1; i++
{
for var j = i + 1; j <= array.count - 1; j++
{
//something with array[i] and array[j]
}
}
I can use
var i = 0
while i < array.count
{
var j = i + 1
while j < array.count
{
//something with array[i] and array[j]
j += 1
}
i += 1
}
charl's (old) answer will crash. You want 0..<array.count:
for index in 0..<array.count {
// ...
}
If you want something like your i/j loop you can use stride and get i's successor:
for i in 0.stride(through: array.count, by: 1) {
let j = i.successor()
// ...
}
Just make sure to check i.successor() in case you go out of bounds.
for var i = 0; i <= array.count - 1; i++ {
//something with array[i]
}
Here you don't need the element index at all, so you can simply
enumerate the array elements:
for elem in array {
// Do something with elem ...
}
for var i = 0, j = 1; i <= array.count - 2 && j <= array.count - 1; i++, j++ {
//something with array[i] and array[j]
}
To iterate over pairs of adjacent elements, use zip()
and dropFirst():
for (x, y) in zip(array, array.dropFirst()) {
// Do something with x and y ...
print(x, y)
}
Output:
1 2
2 3
3 4
4 5
For other distances, use dropFirst(n):
for (x, y) in zip(array, array.dropFirst(3)) {
// Do something with x and y ...
print(x, y)
}
Output:
1 4
2 5
There are probably many solutions to do
for var i = 0; i <= <array.count - 1; i++ {
for var j = i + 1; j <= array.count - 1; j++ {
//something with array[i] and array[j]
}
}
without a C-style for-loop, here is one:
for (index, x) in array.enumerate() {
for y in array.dropFirst(index + 1) {
print(x, y)
}
}
If you want to do something with subsequent pairs there are many other ways to do it.
Something like this would work...
var previousItem = array.first
for index in 1..<array.count {
let currentItem = array[index]
// do something with current and previous items
previousItem = currentItem
}
for (i, j) in zip(array.dropLast(), array.dropFirst())
{
// something
}
What you're really doing here is enumerating two parallel sequences. So, create those sequences and use zip to turn them into a single sequence.
Do enumeration
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
for (i, suite) in suits.enumerate() {
// ...
}
or to compare neighbors
import Foundation
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
for (i, suite1) in suits.enumerate() {
let j = i.successor()
if j < suits.count {
let suite2 = suits[j]
// ...
}
}
or zipping and enumerating
let suits = ["♠︎", "♥︎", "♣︎", "♦︎"]
let combination = zip(suits, suits.dropFirst())
for (i, (s1,s2)) in combination.enumerate() {
print("\(i): \(s1) \(s2)")
}
result
0: ♠︎ ♥︎
1: ♥︎ ♣︎
2: ♣︎ ♦︎
Worst case, you can convert it to a while loop.
var i = 0
var j = 1
while i <= array.count -2 && j <= array.count - 1 {
// something
i += 1
j += 1
}
-- EDIT --
Because you said, "while loop is preferable universal substitution for all cases more complicated than the simple example of C-like for-loop"... I feel the need to expand on my answer. I don't want to be responsible for a bunch of bad code...
In most cases, there is a simple for-in loop that can handle the situation:
for item in array {
// do something with item
}
for (item1, item2) in zip(array, array[1 ..< array.count]) {
// do something with item1 and item2
}
for (index, item1) in array.enumerate() {
for item2 in array[index + 1 ..< array.count] {
// do soemthing with item1 and item2
}
}
For your last case, you might be justified using a for look, but that is an extremely rare edge case.
Don't litter your code with for loops.
to compare neighbouring elements from the same array you can use
let arr = [1,2,2,5,2,2,3,3]
arr.reduce(nil) { (i, j)->Int? in
if let i = i {
print(i,"==",j,"is",i == j)
}
return j
}
it prints
1 == 2 is false
2 == 2 is true
2 == 5 is false
5 == 2 is false
2 == 2 is true
2 == 3 is false
3 == 3 is true
more 'generic' approach without using subscript but separate generators
let arr1 = [1,2,3,4,5,6,7,8,9,0]
var g1 = arr1.generate()
var g2 = (arr1.dropFirst(5) as AnySequence).generate()
var g3 = (arr1.dropFirst(6) as AnySequence).generate()
while true {
if let a1 = g1.next(),
let a2 = g2.next(),
let a3 = g3.next() {
print(a1,a2,a3)
} else {
break
}
}
/* prints
1 6 7
2 7 8
3 8 9
4 9 0
*/