First, a bit of background:
I'm working on one of the Codility lessons, and, even though this is easy to solve, logistically, it is less than easy to solve, performance-wise.
I've been able to boil it down to just this:
public func solution(_ A : inout [Int]) -> Int {
let B = A // Assigning it to a local speeds it up.
return Array<Int>(Set(B)).sorted(by: {$0<$1}).reduce(0) { ($1 == $0 + 1) ? $1 : $0 } + 1
}
However, this is just a WEE bit too slow. I guess that the main reason is that the reduce goes through ALL elements of an array, even though the answer may be early. I may not be able to speed it up.
But I'd like to try. The part that I'm looking at is this:
.reduce(0) { ($1 == $0 + 1) ? $1 : $0 }
I'm wondering if I can make that comparison more efficient.
I have to check if $1 is equal to $0 + 1. I can't avoid that comparison.
The ternary operator is not actually faster than an if clause, but it looks cooler ;).
Is there a higher-performance way to compare two positive integers for equivalence than the basic "==" operator?
BTW: This is not a "do my homework for me" question. It's pretty legit, and these Codility lessons don't give you credit or anything. They are just a fun exercise. I want to know how to do this, as I'm sure I'll need it in the future.
Using the solution suggested by #TNguyen in comments, below piece of code got 100% on both correctness and performance.
You just need to generate the correct Array, containing each Integer in the range [1..(N + 1)] by calling Array(1...A.count+1). Then you sum its elements using reduce(0,+) and finally substract the sum of the elements of the input array A. The difference between the two sums gives the missing element.
public func solution(_ A : inout [Int]) -> Int {
return Array(1...A.count+1).reduce(0,+)-A.reduce(0,+)
}
An even faster solution is to use the mathematical formula1+2+...+n=n(n-1)/2 for the first sum.
public func solution(_ A : inout [Int]) -> Int {
return (A.count+1)*(A.count+2)/2-A.reduce(0,+)
}
100% score in python using an other concept:
def solution(A):
Index=0;
while (Index<len(A)):
while((A[Index]-1) != Index and A[Index]<=len(A)):
Tmp=A[Index]; #Permut
A[Index]=A[Tmp-1];
A[Tmp-1]=Tmp;
Index+=1;
Index=0;
while Index<len(A):
if((A[Index]-1) != Index) :
return Index+1;
else:
Index+=1;
return len(A)+1;
pass
The idea behind is that for a given permutation, each element A[Index]-1 should match to Index except for the missing element. Elements of the array are then permuted until the correspondence is achieved or not achieved when A[Index]>len(A).
Related
When you call reversed() on an array in Swift, you get a ReverseCollection which merely wraps the original array with reversed access. Thus this is extremely efficient:
let arr = [1,2,3,4]
for i in arr.reversed() { print(i) }
Nothing actually got reversed except the access; the time complexity of reversed here is O(1). Cool!
But when I index into reversed() by an integer and check Quick Help, it appears I've lost all that efficiency; I'm shown the Sequence reversed() which generates a new array:
let arr = [1,2,3,4]
let i = arr.reversed()[1] // ???? this is a different `reversed()`!
And this seems to be true, because a reversed() array does not, itself, support indexing by number:
let arr = [1,2,3,4]
let rev = arr.reversed()
let i = rev[1] // compile error!
So my question is: is it really true that indexing by number into a reversed() array, as in my second example, loses the efficiency of the ReverseCollection index reversal?
Yes, indexing by Int is causing you to lose your O(1) access into the reversed array. Quite the gotcha!
As you note, reversed() here is an overloaded method; on Array specifically, you have two definitions to choose from:
BidirectionalCollection.reversed(), which returns a ReversedCollection, and
Sequence.reversed(), which turns any sequence into a reversed [Element]
The overloading here is most confusing for Array itself, because it's the only Sequence type such that type(of: x) == type(of: x.reversed()).
The Swift type checker prefers more specific overloads over less-specific ones, so in general, the compiler will use the BidirectionalCollection overload instead of the Sequence one where possible. The rub: BidirectionalCollection has an opaque index type, and cannot be indexed using an Int; when you do index into the collection with an Int, the compiler is instead forced to choose the Sequence overload over the BidirectionalCollection one. This is also why your second code sample fails to compile: Swift code inference does not take into account surrounding context on other lines; on its own, rev is preferred to be a ReversedCollection<Array<Int>>, so attempting to index into it with an Int fails.
You can see this a little more clearly with the following:
func collType1<T: Collection>(_: T) {
print(T.self) // ReversedCollection<Array<Int>>
print(T.Index.self) // Index
}
func collType2<T: Collection>(_: T) where T.Index == Int {
print(T.self) // Array<Int>
print(T.Index.self) // Int
}
let x: [Int] = [1, 2, 3]
collType1(x.reversed())
collType2(x.reversed())
Lest you wonder whether the compiler can optimize around this when the fact of Int-based indexing appears to not have any other side effects, at the time of writing, the answer appears to be "no". The Godbolt output is a bit too long to reproduce here, but at the moment, comparing
func foo1(_ array: [Int]) {
if array.reversed()[100] > 42 {
print("Wow!")
}
}
with
func foo2(_ array: [Int]) {
if array.reversed().dropFirst(100).first! > 42 {
print("Wow!")
}
}
with optimizations enabled shows foo2 performing direct array access
cmp qword ptr [rdi + 8*rax + 24], 43
having optimized away the ReversedCollection wrapper entirely, while foo1 goes through significantly more indirection.
Ferber explained the reason very well.
Here's an ad-hoc solution (which may not be preferred by everyone, because we are extending types from the standard library):
// RandomAccessCollection ensures fast index creation
extension ReversedCollection where Base: RandomAccessCollection {
subscript(_ offset: Int) -> Element {
let index = index(startIndex, offsetBy: offset)
return self[index]
}
}
[1, 2, 3].reversed()[0] // 3
I need difference between first and second diagonal in square matrix array
func diagonalDifference(arr: [[Int]]) -> Int {
var sumFirstDiag = 0
for i in 0...arr.count-1 {
sumFirstDiag = sumFirstDiag + Int(arr[i][i])
}
var sumSecondDiag = 0
for y in 0...arr.count-1 {
sumSecondDiag = sumSecondDiag + Int(arr[y][arr.count - y])
}
print(abs(sumFirstDiag - sumSecondDiag))
return abs(sumFirstDiag - sumSecondDiag)
}
let array = [
[1,2,3,11],
[4,5,6,12],
[7,8,9,90],
[1,3,5,7]]
diagonalDifference(arr: array)
Error message:
Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift, line 444
I figured I'd share a more functional approach to this same problem:
// The sum of elements along the diagonal from top-left to bottom-right
func diagonal1Sum(_ input: [[Int]]) -> Int {
input.indices
.map { input[$0][$0] }
.reduce(0, +) // I wish Swift had a built-in `.sum` :(
}
// The sum of elements along the diagonal from top-right to bottom-left
func diagonal2Sum(_ input: [[Int]]) -> Int {
zip(input.indices, input.indices.reversed())
.map { input[$0][$1] }
.reduce(0, +)
}
// The absolute value of the difference in sums of the two diagonals.
func diagonalDifference(_ input: [[Int]]) -> Int {
abs(diagonal1Sum(input) - diagonal2Sum(input))
}
let array = [
[1,2,3,11],
[4,5,6,12],
[7,8,9,90],
[1,3,5,7],
]
print(diagonalDifference(array))
There's a few things to notice:
0...arr.count-1 should be just expressed as arr.indices. The first form crashes on empty arrays. See https://github.com/amomchilov/Blog/blob/master/Proper%20Array%20Iteration.md
arr[i][i] is already an Int, there's no need to convert that into an Int.
sumSecondDiag = sumSecondDiag + something is more simply written as just sumSecondDiag += something
Meaningless parameter names like arr shouldn't be keyword labels. Compare diagonalDifference(arr: array) and diagonalDifference(array). The arr: in the first form doesn't really give you any information you didn't already have. You should omit that keyword label using a _.
You should not print the result out of a function that computes a result like this. Return the result, then print it. This gives users of your function the ability to choose whether they want to print, or not.
And most importantly: you can iterate through arr.indices.reversed() to get a sequence of indices that go from high to low, allowing you to access the row elements from top right to bottom left.
This is the key to avoiding the bug you encountered. You forgot the crucial - 1, which is why you were accessing the index out of bounds and causing the crash. If you just use the reversed reverse the array first, then access the nth element, you'll get back the n-th last value, without needing to remember to do acc.count - n - 1.
To pick the row, you still need the regular "forward indices", like array.indices().
You can use zip(_:_:) to iterate both of them at the same time, using the "forward index" to select the row, and the "backward index" to select a particular number from that row.
Thanks to #Rob for this suggestion.
Update notes
I revamped my recommendation. I was previously suggesting to use input[$0].reversed()[$0] under the misunderstanding that the result of reversed would be a view onto the array that would just perform constant-time index arithmetic. This is not the case. Each of these reversed calls was doing a full linear reversal of the array.
I have a 2D array of type f32 (from ndarray::ArrayView2) and I want to find the index of the maximum value in each row, and put the index value into another array.
The equivalent in Python is something like:
import numpy as np
for i in range (0, max_val, batch_size):
sims = xp.dot(batch, vectors.T)
# sims is the dot product of batch and vectors.T
# the shape is, for example, (1024, 10000)
best_rows[i: i+batch_size] = sims.argmax(axis = 1)
In Python, the function .argmax is very fast, but I don't see any function like that in Rust. What's the fastest way of doing so?
Consider the easy case of a general Ord type: The answer will differ slightly depending on whether you know the values are Copy or not, but here's the code:
fn position_max_copy<T: Ord + Copy>(slice: &[T]) -> Option<usize> {
slice.iter().enumerate().max_by_key(|(_, &value)| value).map(|(idx, _)| idx)
}
fn position_max<T: Ord>(slice: &[T]) -> Option<usize> {
slice.iter().enumerate().max_by(|(_, value0), (_, value1)| value0.cmp(value1)).map(|(idx, _)| idx)
}
The basic idea is that we pair [a reference to] each item in the array (really, a slice - it doesn't matter if it's a Vec or an array or something more exotic) with its index, use std::iter::Iterator functions to find the maximum value according to the value only (not the index), then return just the index. If the slice is empty None will be returned. Per the documentation, the rightmost index will be returned; if you need the leftmost, do rev() after enumerate().
rev(), enumerate(), max_by_key(), and max_by() are documented here; slice::iter() is documented here (but that one needs to be on your shortlist of things to recall without documentation as a rust dev); map is Option::map() documented here (ditto). Oh, and cmp is Ord::cmp but most of the time you can use the Copy version which doesn't need it (e.g. if you're comparing integers).
Now here's the catch: f32 isn't Ord because of the way IEEE floats work. Most languages ignore this and have subtly wrong algorithms. The most popular crate to provide a total order on Ord (by declaring all NaN to be equal, and greater than all numbers) seems to be ordered-float. Assuming it's implemented correctly it should be very very lightweight. It does pull in num_traits but this is part of the most popular numerics library so might well be pulled in by other dependencies already.
You'd use it in this case by mapping ordered_float::OrderedFloat (the "constructor" of the tuple type) over the slice iter (slice.iter().map(ordered_float::OrderedFloat)). Since you only want the position of the maximum element, no need to extract the f32 afterward.
The approach from #David A is cool, but as mentioned, there's a catch: f32 & f64 do not implement Ord::cmp. (Which is really a pain in your-know-where.)
There are multiple ways of solving that: You can implement cmp yourself, or you can use ordered-float, etc..
In my case, this is a part of a bigger project and we are very careful about using external packages. Besides, I am pretty sure we don't have any NaN values. Therefore I would prefer using fold, which, if you take a close look at the max_by_key source code, is what they have been using too.
for (i, row) in matrix.axis_iter(Axis(1)).enumerate() {
let (max_idx, max_val) =
row.iter()
.enumerate()
.fold((0, row[0]), |(idx_max, val_max), (idx, val)| {
if &val_max > val {
(idx_max, val_max)
} else {
(idx, *val)
}
});
}
Does Kotlin forEach iterate through an array in real order of array or it may be sometimes in another order? I mean does this always print 1,2,3,...9 or it may print something like this 1,5,3,4,...
val numbers: Array<Int> = array(1,2,3,4,5,6,7,8,9)
numbers.forEach({(number: Int) ->
Log.d(tag,number)
})
Kotlin forEach reference
forEach iterates in order from first to last element; source code:
Collections.kt
/**
* Performs the given [action] on each element.
*/
#kotlin.internal.HidesMembers
public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
for (element in this) action(element)
}
Yeah, it keeps real order. Look at implementation:
public inline fun IntArray.forEach(action: (Int) -> Unit): Unit {
for (element in this) action(element)
}
For loop uses iterator of the array, which keeps order too.
These are two separate questions. Yes, as pointed out by the other answers, it keeps the order. But since forEach doesn't print anything, it all depends on the implementation of the printing.
For example, this will not always print the numbers 1 to 10 in order, even though it uses forEach:
fun myPrint(i: Int) = launch { println(i) }
(1..10).forEach { n -> myPrint(n) }
Since we don't know how your Log.d(...) is implemented, we can't be sure.
I am reading a text file containing key/value lines into Swift structs. One of the lines of the file has five space-separated values in the line, which I've turned into an array using componentsSeparatedByString.
The actual values are Ints, so the normal solution would be to loop over each one and copy it into the associated slot in my struct's Int array. But am I missing some Swift (or Foundation) magic here?
You can use the map function, which loops through all the elements of the array and apply a transformation to each element defined in a closure you pass to it.
var array = ["2", "4", "6", "8"]
let ints = array.map { $0.toInt()! }
Note that I am using forced unwrapping when converting to integer - so use it if you are 100% sure all elements in the array are actually integers, otherwise a runtime exception will be generated
A safer way is to map to optional integer, then filter to remove nil values, and then map again to force unwrap optionals:
let ints = array.map { $0.toInt() }.filter { $0 != nil }.map { $0! }
Note that this safer version may seem slower than using a for loop (and actually it is, because it traverses the array 3 times - unless the compiler is able to optimize it) - but I would prefer it over a loop because it's more compact and in my opinion more readable. Needless to say, I wouldn't probably use for large arrays though.
Addendum: as suggested by #MikeS, it's possible to use reduce to combine the last 2 steps of the safer version:
let ints = array.map { $0.toInt() }.reduce([]) { $1 != nil ? $0 + [$1!] : $0 }
It looks like a good alternative for small sized arrays, because it reduces the complexity from O(3n) to O(2n) - although I suspect that without compiler optimizations it might be slower because at each iteration a new array is created (if the element is not nil), because of $0 + [$1!].
But it's good to know that there are many ways to achieve the same result :)