Check numbers divisible by 2 and print them in Kotlin - arrays

I am working on a task as part of my Kotlin course and I've been really stuck on this. I feel like it's something simple but I can't see it. Here is the explanation of what to do for this task:
You are given a List of integers. Iterate through the given List and print in a single line the elements that are divisible by 2.
Sample Input:
8 11 13 2
Sample Output:
8 2
This is my code (I have printed the numbers list to see what numbers I was being provided with, as I am not choosing them, they are given by the course automatically without me seeing them):
fun solution(numbers: List<Int>) {
var divisible = intArrayOf()
for (i in 0..numbers.lastIndex) {
if (numbers[i] % 2 == 0){
divisible = intArrayOf(numbers[i])
}
}
println("$numbers")
println("${divisible.joinToString("")}")
This was my output:
[8, 11, 13, 2]
2
I think I have done the part of checking if the numbers are divisible by 2 correctly, but I don't fully understand why it only prints 2, and why not 8 first if it divisible by 2. At first I was using a list instead of an array for the divisible variable, so I thought that might have been it, as lists are immutable if I'm not wrong, but it looks like that wasn't it. If anyone could explain to me what I'm doing wrong, I would really appreciate it!

You can use filter with predicate
Example :
val list = listOf(8,2,11,15)
the solution is so simple with kotlin
val result = list.filter { it % 2 == 0 }

You rewrite result holder (divisible = intArrayOf()) on each item that is divisible by 2, that's why only last match is stored in divisible array.
Instead of
divisible = intArrayOf(numbers[i])
you should write
divisible.add(numbers[i]) // no need to re-initialize
UPDATE: I've missed that array has no add operation. If it's suitable you can use list instead of array in order to have add operation available:
var divisible = mutableListOf<Int>()
P.S. There is a shorter way to do that with Kotlin:
fun solution(numbers: List<Int>) {
val divisible = numbers.filter { it % 2 == 0 }
println("$numbers")
println("${divisible.joinToString(" ")}")
}

Related

Returning the least number of multiplications it took to find an adjacent pair of duplicate numbers

I'm not very good with algorithms and I am completely stuck on this and have not been able to find the help I was looking for. The problem I am trying to solve is the following:
Have the function ArrayChallenge(num) take the num parameter being passed and perform the following steps. First take all the single digits of the input number (which will always be a positive integer greater than 1) and add each of them into a list. Then take the input number and multiply it by any one of its own integers, then take this new number and append each of the digits onto the original list. Continue this process until an adjacent pair of the same number appears in the list. Your program should return the least number of multiplications it took to find an adjacent pair of duplicate numbers.
Example: if num is 134 then first append each of the integers into a list: [1, 3, 4]. Now if we take 134 and multiply it by 3 (which is one of its own integers), we get 402. Now if we append each of these new integers to the list, we get: [1, 3, 4, 4, 0, 2]. We found an adjacent pair of duplicate numbers, namely 4 and 4. So for this input your program should return 1 because it only took 1 multiplication to find this pair.
Example: if num is 46 then we append these integers onto a list: [4, 6]. If we multiply 46 by 6, we get 276, and appending these integers onto the list we now have: [4, 6, 2, 7, 6]. Then if we take this new number, 276, and multiply it by 2 we get 552. Appending these integers onto the list we get: [4, 6, 2, 7, 6, 5, 5, 2]. Your program should therefore return 2 because it took 2 multiplications to find a pair of adjacent duplicate numbers (5 and 5 in this case).
The problem can be formulated as "Find the shortest path in a decision tree". Where each decision is "Which digit should I use for the next multiplication".
As this decision tree can have infinitely long paths (e.g. start with 12 and always multiply by 1), we can't use a simple depth-first search and instead should implement a breadth first approach.
That means, we should first check for each digit if we reach a desired result, and if not note down the multiplication result. Then, if we didn't find a pair, continue for each noted down number with its digits and so on.
I implemented this as an example in kotlin, but you should be able to transfer this easily to any language:
fun Int.getDigits() = toString().map { it.toString().toInt() }
fun List<Int>.getNum() = joinToString("").toInt()
fun List<Int>.hasAdjacentPair() = zipWithNext().any { (a, b) -> a == b }
fun arrayChallenge(num: Int): Int {
if (num.getDigits().hasAdjacentPair()) return 0
val check = mutableListOf(Pair(num.getDigits(), 1))
while (true) {
val (digits, multiplications) = check.removeFirst()
for (digit in digits.distinct()) {
val multDigits = (digit * digits.getNum()).getDigits()
if (digits.last() == multDigits.first() || multDigits.hasAdjacentPair()) {
return multiplications
}
check.add(Pair(multDigits, multiplications + 1))
}
}
}

(Swift) Trying to iterate through remaining elements in array, add those elements independently, and check to see if they match random number given

Disclaimer: new to swift.
I have a simple dice game that needs to match the number shown on dice to the tiles(ints) remaining on the board. I am able to enumerate through the array for a direct match but, if the dice show a greater number than the tiles individually I need to check if those tiles(ints), in any combination, can also match the number on dice shown.
for loops, do-while, enumerations.....head is starting to explode. Example below shows a condensed version of where i think i'm going. any help would be great.
var array = [1,2,3,4]
func roundOver () {
var ran = Int(arc4random_uniform(7) % 7 + 1)
for (index,value)in enumerate(array) {
if value == ran {
println("match")
} else if value != ran {
do {..........huh?
If I understand your question correctly, you need to solve the "Subset sum problem":
Given a set S and a number x, is there a subset of S whose sum is equal to x?
This problem can be efficiently solved with "dynamic programming", as described in
the Wikipedia article. For small sets, a brute-force algorithm can be used which
simply tries all possible subsets. This can be recursively written as
func isSummableTo(array: [UInt], _ value: UInt) -> Bool {
if value == 0 {
// We have reached the exact sum
return true
} else if array.count == 0 {
// No elements left to try
return false
}
// Split into first element and remaining array:
var array1 = array
let first = array1.removeAtIndex(0)
// Try to build the sum without or with the first element:
return isSummableTo(array1, value) || (value >= first && isSummableTo(array1, value - first))
}
(Here I have assumed that you work only with non-negative integers.)
For example
isSummableTo([1, 3, 5, 10], 6) == true
because 1 + 5 = 6, and
isSummableTo([1, 3, 5, 10], 7) == false
because there is not subset of the numbers 1, 3, 5, 10 that sums up to 7.

How do I deal with specific elements only in an array?

So I know how to add up all the elements of an array using a for loop. But how would I go about adding up only the positive elements?
Say my array included {3, -9, 2, -10}
I want to: 3 + 2 (giving 5)
NOT: 3 +-9 +2 +-10 (giving -14)
Also how would I get the amount of positive elements in an array? (i.e. in this example there are two positive elements)
Im using Java/Eclipse
Thanks so much for the answers - i now know what to do! This is my first time here - do i have to mark this as answered or something?
You can just add a condition in your loop :
arrays = {3, -9, 2, -10};
sum = 0;
nb_elem = 0;
for (i = 0 ; i < arrays.length ; i++)
{
if (arrays[i] > 0)
{
sum += arrays[i];
nb_elem++;
}
}
I don't know what language you are using, so I'll give you example in Python
def sum_up_positive_values(array):
result = 0
for value in array:
if value > 0:
result += value
return result

How do I perform a duplicate check in code?

This might be a no-brainer to some, but I'm trying to check if there are any duplicate values in my code.
To be clearer, I am creating 5 variable Integers that randomizes a number once they are created. Let's say they're named i1, i2, i3, i4, i5.
I want to run a loop to check on each other to make sure they don't have any possible duplicates. If they do, I'll re-random the second Integer that's being checked. (e.g if (i1 == i4) { i4.rand(); }) That's to make sure i1 doesn't need to get re-checked against all the previously checked values or being stuck in a long loop until a different number is found.
This is what I'm thinking if it was an entire if else statement : if (i1 == i2), if (i1 == i3), if (i1 == i4), if (i1 == i5), if (i2 == i3), if (i2 == i4), if (i2 == i5), if (i3 == i4), if (i3 == i5), if (i4 == i5)
I know I can probably do it "manually" by creating lots of if / else statements, but is there a better way to do it? It probably isn't very feasible if I increase my Integer limit to 20 and I have to if / else my way through 20 value checks. I know there is, but I just can't remember. Search on Google is turning up nothing (maybe I'm searching for the wrong keywords), which is why I'm asking over here at StackOverflow.
All I want to know is how do I do it, theory-wise (how would you check for duplicates in theory?). The answer doesn't necessarily need to be a workable function.
If you want to create a demo code using the programming language I'm using for this problem, itsExcel VBA. But I think this information would be able to apply theory-wise to a lot of other programming languages, so feel free to write in javascript/jQuery, C++, C#, etc. Just remember to comment!
You are looking for Set;
Set<Integer> hs = new HashSet<Integer>();
hs.add(i1);
if(!hs.add(i2)){
randomize(i2);
}
Hope this helps. Let me know, if you have any questions.
The above is just a concept of what to do.
To get the logic for your code, it will be
Set<Integer> hs = new HashSet<Integer>();
for(int count=0; count<Array.length; count++){ // Store the data into the array and loop
dataToInsert = Array[count];
while(hs.add(dataToInsert)){
dataToInsert = randomize(dataToInsert);
}
}
Here is a simple way to get your integers assuming you want to generate them in the range from 1 to N
Generate an integer from 1:N
Generate an integer from 1:N-1
Generate an integer from 1:N-2
Generate an integer from 1:N-(k-1)
Now interpret these as the position of the integer that you generated (in the set of total available integers for that number) and construct your real integer.
Example, N = 5, k=4
3
1
2
2
i1 = 3
i2 = 1
i3 = 4 (the available integers are 2 4 5)
i4 = 5
Note that this requires the minimum amount of random number generations.
To be clear, what you are attempting is the wrong approach. Theoretically, checking for duplicates and "re-randomizing" when one is found, could execute for an infinitely long time because existing integers could continuously be chosen.
What you should be doing is constructing the collection of integers in such a way that there will be no duplicates in the first place. Dennis Jaheruddin's answer does this. Alternatively, if you have a specific set of integers to choose from (like 1-20), and you simply want them in a random order, you should use a shuffling algorithm. In any event, you should start by searching for existing implementations of these in your language, since it has almost certainly been done before.
What you could do is loop over the List<int> and, for each element x at index i, loop while list.Take(i-1).Contains(x) and replace x with a new random number.
If you simply wanted a relatively inexpensive check that a given List<int> is full of unique numbers, however, you could do something like:
bool areAllUnique = list.Count() != list.Distinct().Count()`
2 ways I can think of.
1: Looping over all the values in your set and comparing each one to what you're adding.
2: Creating a simplistic version of a hash map:
var set
var map_size
create_set(n):
set <- array of size n of empty lists
map_size <- n
add_number(num_to_add):
if num_to_add not in set[num_to_add % map_size]:
add num_to_add to set[num_to_add % map_size]
return success
else:
return failure
populate_set():
loop 5 times:
i <- random_number()
while(add_number(i) == failure):
i <- random_number()
This way, each time you add a number, instead of checking against every other number in your set, you're only checking against at most [max value of integer] / [map size] values. And on average [number of elements in set] / [map size] (I think, correct me if I'm wrong) values.
Try
ArrayList<Integer> list = new ArrayList<Integer>();
while (list.size() < 5)
{
int i = Math.random() * max;
if (!list.contains(i))
{
list.add(i);
}
}
and you'll got in list 5 different Integers.
Pseudo-code:
Create an empty set S.
Generate a pseudo-random number r.
If r is in S, go to 2. Else, go to 4.
Add R to S.
If there are still variables to initialize, go to 2.
Exemplary implementation in Java:
public static void main(String[] args)
{
System.out.println(getUniqueRandoms(5, 10));
}
public static Set<Integer> getUniqueRandoms(int howMany, int max)
{
final Set<Integer> uniqueRandoms = new HashSet<Integer>(howMany);
while (uniqueRandoms.size() < howMany)
{
uniqueRandoms.add((int) (Math.random() * max));
}
return uniqueRandoms;
}
Output:
[8, 2, 5, 6, 7]
If you would like to have them in array, not in Set, just call toArray() on your Set.
In R is pretty simple...
i <- as.integer(runif(5, 1, 10))
for(l in seq_along(i)){
while(any(i[l]==i[-l])) # checks each against all the other
i[l] <- as.integer(runif(1, 1, 10))
}
However in R there is the function sample that picks random elements from a given vector without duplicates ( even though you can choose to have them)
> sample(1:10, 5)
[1] 2 5 1 9 6
> sample(1:10, 5)
[1] 3 5 8 2 1
> sample(1:10, 5)
[1] 8 3 5 9 4
> sample(1:10, 5)
[1] 1 8 9 10 5
HashSet<Integer> set = new HashSet<Integer>();
for(int i = 0; i < 5; i++)
{
int x;
do
{
x = random();
}
while(!set.Add(x));
}
int i1 = set.ElementAt(0),
i2 = set.ElementAt(1),
i3 = set.ElementAt(2),
i4 = set.ElementAt(3),
i5 = set.ElementAt(4);

Computing LCM of M consecutive numbers in an array of N integers

I came across this problem here. It was a programming contest held earlier this year.
Here is the summary :
Given an array of N integers, find LCM of all consecutive M integers.
For e.g.
Array = [3,5,6,4,8] (hence N = 5)
M = 3
Output :
LCM(3,5,6) = 30
LCM(5,6,4) = 60
LCM(6,4,8) = 24
In fact there's a solution sketch here but I couldn't understand the Dynamic Programming Part.
So if someone could elaborate on the same solution with some examples it will be great.
A new, easy to understand solution will also be appreciated.
I can not access the solution any more (maybe the link is broken?), but here is what I would do:
I would have my program work like a pyramid. On the lowest row, I would have the array with the given numbers. On each row above, I would have an array with one field less than the array below. It would store the LCM of two values from the array below.
[ 30 ]
[ 15, 30 ]
[3, 5, 6]
This way you can work with a recursive function and you have to build M-1 layers of the pyramid. Here's a Pseudo-Code implementation:
rekursivePyramid (Integer[] numbers, Integer height) {
if (height == 0) return numbers;
else {
newNumbers = Integer[numbers.size() - 1];
for (i=0; i<newNumbers.size(); i++) {
newNumbers[i] = LCM ( numbers[i], numbers[i+1]);
}
return rekursivePyramid( newNumbers, height-1);
}
}
This will give you an array, where you find the LCM of the first M numbers in first field, the LCM from the second to the M+1st number in the second field, etc.

Resources