I am new to Kotlin and am trying to compare the elements of two arrays by seeing which array has the greater element. The arrays are created via user input. The error that I am having is that when I repeat the second for loop (inner loop), which contains the contents of the second array, it will not increment to the next element of the second array unlike the first for loop. So if a = {1,2} and b = {2,1}, a would increment through both 1 and 2, but b would stay at 2 through both iterations of the loop. Here is my function that is giving me a problem:
fun practiceCompareArray(a: Array<Int>, b: Array<Int>): Array<Int> {
var j: Array<Int>
var aPoints = 0
var bPoints = 0
for (x:Int in a) {
---------> for (y: Int in b) {
if (x > y) {
aPoints++
} else if (x < y) {
bPoints++
break
}
}
j = arrayOf(aPoints, bPoints)
return j
}
The for loop with the arrow is giving me the problem. I think it is because of the break statement at the end of the inner loop. Do I even need the inner loop to compare each array? Any help or documentation would be helpful.
If you know that both array have the same length and you want to compare them elementwise you could do something like:
fun practiceCompareArray(a: Array<Int>, b: Array<Int>): Array<Int> {
var aPoints = 0
var bPoints = 0
for ((x,y) in a.zip(b)) {
if (x>y) {
aPoints ++
} else {
bPoints ++
}
}
return arrayOf(aPoints, bPoints)
}
or in a more functional style
fun practiceCompareArray(a: Array<Int>, b: Array<Int>): Array<Int> {
val (aPoints, bPoints) = a.zip(b)
.fold(Pair(0,0), {(aScore, bScore), (x,y) ->
if (x > y) Pair(aScore + 1, bScore) else Pair(aScore, bScore + 1)})
return arrayOf(aPoints, bPoints)
}
Related
I'm trying to solve the following problem, given an array of String, of size n, list all n-tuples from this array, that is:
let A: [String] = ["a","b","c",...]
determine all the tuples
["abc..","bac..",...], of which there are exactly n!.
I've written a solution in Swift, but I'm not quite happy with the result, as it uses closures, making it difficult to iterate over the tuples.
Here's the code, just in case:
public func tuple(seq:[String], value:String, block:(String) -> ()) {
if seq.count > 0 {
for i in 0..<seq.count {
var uu = seq;
let kk:String = uu[i];
uu.remove(at: i)
self.tuple(seq:uu,value: value + kk, block: block)
}
} else {
block(value)
}
}
Anyone with a valid solution without closure?
Using the code from Sequence-based enumeration of permutations in lexicographic order on Code Review (updated for
Swift 4, and with the suggestions from Hamish's answer implemented):
extension Array where Element: Comparable {
/// Replaces the array by the next permutation of its elements in lexicographic
/// order.
///
/// It uses the "Algorithm L (Lexicographic permutation generation)" from
/// Donald E. Knuth, "GENERATING ALL PERMUTATIONS"
/// http://www-cs-faculty.stanford.edu/~uno/fasc2b.ps.gz
///
/// - Returns: `true` if there was a next permutation, and `false` otherwise
/// (i.e. if the array elements were in descending order).
mutating func permute() -> Bool {
// Nothing to do for empty or single-element arrays:
if count <= 1 {
return false
}
// L2: Find last j such that self[j] < self[j+1]. Terminate if no such j
// exists.
var j = count - 2
while j >= 0 && self[j] >= self[j+1] {
j -= 1
}
if j == -1 {
return false
}
// L3: Find last l such that self[j] < self[l], then exchange elements j and l:
var l = count - 1
while self[j] >= self[l] {
l -= 1
}
self.swapAt(j, l)
// L4: Reverse elements j+1 ... count-1:
var lo = j + 1
var hi = count - 1
while lo < hi {
self.swapAt(lo, hi)
lo += 1
hi -= 1
}
return true
}
}
struct PermutationSequence<Element : Comparable> : Sequence, IteratorProtocol {
private var current: [Element]
private var firstIteration = true
init(startingFrom elements: [Element]) {
self.current = elements
}
init<S : Sequence>(_ elements: S) where S.Iterator.Element == Element {
self.current = elements.sorted()
}
mutating func next() -> [Element]? {
var continueIterating = true
// if it's the first iteration, we avoid doing the permute() and reset the flag.
if firstIteration {
firstIteration = false
} else {
continueIterating = current.permute()
}
// if the array changed (and it isn't the first iteration), then return it,
// else we're at the end of the sequence.
return continueIterating ? current : nil
}
}
one can very efficiently iterate over all permutations of an array:
let a = ["a", "b", "c"]
let permSeq = PermutationSequence(startingFrom: a)
for tuple in permSeq {
print(tuple.joined())
}
Each call to the iterator creates the next permutation, and only a
fixed amount of additional storage is needed (one array for the
current permutation, and a boolean variable).
I am not sure why you need the closure to just generate the list. Here is what have used in the past. There is probably a 1 liner using flatmap.
func tuple(_ input:[String])->[String]{
print()
if input.count == 1 {return input}
var output = Array<String>()
for a in 0...input.count-1 {
var temp = input
temp.remove(at: a)
output += tuple(temp).map{input[a]+$0}
}
return output
}
print(tuple(a))
developers, i am new in Kotlin I am trying to take input in Array by using loop and after that, i print the all values of array by using loop but t get only input and not show the other chunk and through the error which is shiwn on attach image
fun main(args: Array<String>) {
var arrayint = Array<Int>(5){0}
var x = 1
val abc:Int = arrayint.size
while( x <= abc)
{
arrayint[x] = readLine()!!.toInt()
x++
}
for(index in 0..4)
{
println(arrayint[index])
}
}
The following is a little more succinct
var arrayint = Array<Int>(5) { readLine()!!.toInt() }
for(x in arrayint)
println(x)
On the first line, instead of using the initializer lambda { 0 }, I use a lambda that call readLine.
On line 2, instead of having to know my range (0..4), I let the language do it for me (an Array is iterable).
Try this:
fun main (args:Array<String>){
var arrayint = Array<Int>(5){0}
var x:Int = 0
val abc:Int = arrayint.size
while( x < abc)
{
arrayint[x] = readLine()!!.toInt()
x++
}
for(index in 0..4)
{
println(arrayint[index])
}
}
You should change x <= abc to x < abc and x = 1 to x = 0. It doesn't work now because if abc = 5 and you loop 4 times then x = 5 but arrays in Kotlin (and Java) start at index 0 which means that array of size 5 has the following indexes: 0, 1, 2, 3, 4 which means that arrayint[5] doesn't exist as 5 is out of bounds (> 4)
One of the shorthand for taking n data elements of data input in an array of predefined size is as follow.
Here the user is going to input a integer
n = number of elements then then the array elements
import java.util.*
fun main(){
val read = Scanner(System.`in`)
val n = read.nextInt()
var arr = Array(n) {i-> read.nextInt()} // taking input
arr.forEach{
println(it) // this loop prints the array
}
}
Following code is taking input in array using loop
import java.util.*
fun main(args: Array<String>) {
var num = arrayOfNulls<Int>(5)
var read= Scanner(System.`in`)
println("Enter array values")
for(i in 0..4)
{
num[i] = read.nextInt()
}
println("The array is")
for(x in num){
println(x)}
}
Following code is taking input of array size and then it's elements
fun main() {
print("Enter Array size: ")
val arraySize = readLine()!!.toInt()
println("Enter Array Elements")
val arr = Array<Int>(arraySize) { readLine()!!.toInt() }
for (x in arr)
println(x)
}
Let say I have an array of Int, I want to find a pair of number in this array that the sum of this pair is equal to an number, like so:
func findPair(list: [Int], _ sum: Int) -> (Int, Int)? {
for i in 0..<list.count - 1{
for j in (i+1)..<list.count {
let sumOfPair = list[i] + list[j]
if sumOfPair == sum {
return (list[i], list[j])
}
}
}
return nil
}
The first parameter is an array of Int, the second parameter is an number that we need to compare some pairs in that array.
For example:
findPair([1,2,3,4,5], 7) // will return (2, 5), because 2 + 5 = 7
But the complexity of this algorithm is O(n^2).
Is there any way faster?
Try the following approach:
sort(arr,arr+n);//Sort the array
low=0;
high=n-1; // The final index number (pointing to the greatest number)
while(low<=high)
{
if(arr[low]+arr[high]==num)
{ print(low,high);
break;
}
else if(arr[low]+arr[high]<num)
low++;
else if(arr[low]+arr[high]>num)
high--;
}
Basically, you are following the greedy Approach over here... Hope it works.. :)
Try with this:
func findPair(list: [Int], _ sum: Int) -> (Int, Int)? {
//save list of value of sum - item.
var hash = Set<Int>()
var dictCount = [Int: Int]()
for item in list {
//keep track of count of each element to avoid problem: [2, 3, 5], 10 -> result = (5,5)
if (!dictCount.keys.contains(item)) {
dictCount[item] = 1
} else {
dictCount[item] = dictCount[item]! + 1
}
//if my hash does not contain the (sum - item) value -> insert to hash.
if !hash.contains(sum-item) {
hash.insert(sum-item)
}
//check if current item is the same as another hash value or not, if yes, return the tuple.
if hash.contains(item) &&
(dictCount[item] > 1 || sum != item*2) // check if we have 5+5 = 10 or not.
{
return (item, sum-item)
}
}
return nil
}
There surely is much faster O(n log(n)) to solve this problem. Below is the pseudo algorithm for that :-
1) Sort the given array.
2) Take two pointers. One pointing to the beginning and other pointing to the end.
3) Check if sum of two values pointed by two pointer is equal to given number.
4) If yes then return.
5) If greater than increment first pointer and go to step 3.
6) Else decrement second pointer and go to step 3.*
I'm not really on point with Swift yet and there is a problem that is starting to be a tad annoying.
I just want to add integer in a double dimensional array but it is always returning the same error code : "fatal error : Array index out of range"
var arrayVolley = [[Int]]()
init(){
self.arrayVolley = [[]]
}
Here is where I try to insert :
func addPoints(score : Int, x : Int, y : Int){
if (score > 11 || score < 0){ //11 will be translated as 10x
println("Error on score value")
}
else {
if (x>6 || y>6){
println("Out of array")
}
else{
arrayVolley[x][y]=score
}
}
}
And this is my main :
var i=0
var j=0
for i in 0...6 {
for j in 0...6{
println("Entrez le score")
var scoreinput=input()
var score = scoreinput.toInt()
distance.addPoints(score!, x: i, y: j)
}
}
Thanks a lot for your help in advance
Try to use append to add the integer to the array it is automatically the next idex. It think if the index was never used it gives an error e.g.
var test = [Int]()
test.append(2) // array is empty so 0 is added as index
test.append(4)
test.append(5) // 2 is added as max index array is not [2,4,5]
test[0] = 3 // works because the index 0 exist cause the where more then 1 element in array -> [3,4,5]
test[4] = 5 // does not work cause index for never added with append
or you intialize the array in the correct size, but it's need a size:
var test = [Int](count: 5, repeatedValue: 0) // [0,0,0,0,0]
test[0] = 3 //[3,0,0,0,0]
test[4] = 5 [3,0,0,0,5]
It hope this helps you if not please feel free to comment.
I'm not sure how to ask my question in a succinct way, so I'll start with examples and expand from there. I am working with VBA, but I think this problem is non language specific and would only require a bright mind that can provide a pseudo code framework. Thanks in advance for the help!
Example:
I have 3 Character Arrays Like So:
Arr_1 = [X,Y,Z]
Arr_2 = [A,B]
Arr_3 = [1,2,3,4]
I would like to generate ALL possible permutations of the character arrays like so:
XA1
XA2
XA3
XA4
XB1
XB2
XB3
XB4
YA1
YA2
.
.
.
ZB3
ZB4
This can be easily solved using 3 while loops or for loops. My question is how do I solve for this if the # of arrays is unknown and the length of each array is unknown?
So as an example with 4 character arrays:
Arr_1 = [X,Y,Z]
Arr_2 = [A,B]
Arr_3 = [1,2,3,4]
Arr_4 = [a,b]
I would need to generate:
XA1a
XA1b
XA2a
XA2b
XA3a
XA3b
XA4a
XA4b
.
.
.
ZB4a
ZB4b
So the Generalized Example would be:
Arr_1 = [...]
Arr_2 = [...]
Arr_3 = [...]
.
.
.
Arr_x = [...]
Is there a way to structure a function that will generate an unknown number of loops and loop through the length of each array to generate the permutations? Or maybe there's a better way to think about the problem?
Thanks Everyone!
Recursive solution
This is actually the easiest, most straightforward solution. The following is in Java, but it should be instructive:
public class Main {
public static void main(String[] args) {
Object[][] arrs = {
{ "X", "Y", "Z" },
{ "A", "B" },
{ "1", "2" },
};
recurse("", arrs, 0);
}
static void recurse (String s, Object[][] arrs, int k) {
if (k == arrs.length) {
System.out.println(s);
} else {
for (Object o : arrs[k]) {
recurse(s + o, arrs, k + 1);
}
}
}
}
(see full output)
Note: Java arrays are 0-based, so k goes from 0..arrs.length-1 during the recursion, until k == arrs.length when it's the end of recursion.
Non-recursive solution
It's also possible to write a non-recursive solution, but frankly this is less intuitive. This is actually very similar to base conversion, e.g. from decimal to hexadecimal; it's a generalized form where each position have their own set of values.
public class Main {
public static void main(String[] args) {
Object[][] arrs = {
{ "X", "Y", "Z" },
{ "A", "B" },
{ "1", "2" },
};
int N = 1;
for (Object[] arr : arrs) {
N = N * arr.length;
}
for (int v = 0; v < N; v++) {
System.out.println(decode(arrs, v));
}
}
static String decode(Object[][] arrs, int v) {
String s = "";
for (Object[] arr : arrs) {
int M = arr.length;
s = s + arr[v % M];
v = v / M;
}
return s;
}
}
(see full output)
This produces the tuplets in a different order. If you want to generate them in the same order as the recursive solution, then you iterate through arrs "backward" during decode as follows:
static String decode(Object[][] arrs, int v) {
String s = "";
for (int i = arrs.length - 1; i >= 0; i--) {
int Ni = arrs[i].length;
s = arrs[i][v % Ni] + s;
v = v / Ni;
}
return s;
}
(see full output)
Thanks to #polygenelubricants for the excellent solution.
Here is the Javascript equivalent:
var a=['0'];
var b=['Auto', 'Home'];
var c=['Good'];
var d=['Tommy', 'Hilfiger', '*'];
var attrs = [a, b, c, d];
function recurse (s, attrs, k) {
if(k==attrs.length) {
console.log(s);
} else {
for(var i=0; i<attrs[k].length;i++) {
recurse(s+attrs[k][i], attrs, k+1);
}
}
}
recurse('', attrs, 0);
EDIT: Here's a ruby solution. Its pretty much the same as my other solution below, but assumes your input character arrays are words: So you can type:
% perm.rb ruby is cool
~/bin/perm.rb
#!/usr/bin/env ruby
def perm(args)
peg = Hash[args.collect {|v| [v,0]}]
nperms= 1
args.each { |a| nperms *= a.length }
perms = Array.new(nperms, "")
nperms.times do |p|
args.each { |a| perms[p] += a[peg[a]] }
args.each do |a|
peg[a] += 1
break if peg[a] < a.length
peg[a] = 0
end
end
perms
end
puts perm ARGV
OLD - I have a script to do this in MEL, (Maya's Embedded Language) - I'll try to translate to something C like, but don't expect it to run without a bit of fixing;) It works in Maya though.
First - throw all the arrays together in one long array with delimiters. (I'll leave that to you - because in my system it rips the values out of a UI). So, this means the delimiters will be taking up extra slots: To use your sample data above:
string delimitedArray[] = {"X","Y","Z","|","A","B","|","1","2","3","4","|"};
Of course you can concatenate as many arrays as you like.
string[] getPerms( string delimitedArray[]) {
string result[];
string delimiter("|");
string compactArray[]; // will be the same as delimitedArray, but without the "|" delimiters
int arraySizes[]; // will hold number of vals for each array
int offsets[]; // offsets will holds the indices where each new array starts.
int counters[]; // the values that will increment in the following loops, like pegs in each array
int nPemutations = 1;
int arrSize, offset, nArrays;
// do a prepass to find some information about the structure, and to build the compact array
for (s in delimitedArray) {
if (s == delimiter) {
nPemutations *= arrSize; // arrSize will have been counting elements
arraySizes[nArrays] = arrSize;
counters[nArrays] = 0; // reset the counter
nArrays ++; // nArrays goes up every time we find a new array
offsets.append(offset - arrSize) ; //its here, at the end of an array that we store the offset of this array
arrSize=0;
} else { // its one of the elements, not a delimiter
compactArray.append(s);
arrSize++;
offset++;
}
}
// put a bail out here if you like
if( nPemutations > 256) error("too many permutations " + nPemutations+". max is 256");
// now figure out the permutations
for (p=0;p<nPemutations;p++) {
string perm ="";
// In each array at the position of that array's counter
for (i=0;i<nArrays ;i++) {
int delimitedArrayIndex = counters[i] + offsets[i] ;
// build the string
perm += (compactArray[delimitedArrayIndex]);
}
result.append(perm);
// the interesting bit
// increment the array counters, but in fact the program
// will only get to increment a counter if the previous counter
// reached the end of its array, otherwise we break
for (i = 0; i < nArrays; ++i) {
counters[i] += 1;
if (counters[i] < arraySizes[i])
break;
counters[i] = 0;
}
}
return result;
}
If I understand the question correctly, I think you could put all your arrays into another array, thereby creating a jagged array.
Then, loop through all the arrays in your jagged array creating all the permutations you need.
Does that make sense?
it sounds like you've almost got it figured out already.
What if you put in there one more array, call it, say ArrayHolder , that holds all of your unknown number of arrays of unknown length. Then, you just need another loop, no?