How dose it work? (about map function in Kotlin) - kotlin

I can't understand below logic.
I think when put 'a' into () in result, the value of result is 32.
Because of (0 until 1-1 -> 0), lastDays[it] is 31.
So result is 31 + 1 = 32.
But the value is 1.
I am studying Kotlin now.
val a = 1
var b = 1
val lastDays = listOf(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
val result = (0 until a - 1).map {
lastDays[it]
}.sum() + b
Please borrow me your wisdom.

0 until a - 1 results in 0 until 0, so it is an empty range. Mapping the empty range results in an empty list. Calling sum() on an empty list returns 0. Then you add 0 + b where b is 1.

Related

Is this how I initialize a list with values in Kotlin?

I want to store a number of counts per value, something like this:
value count
0 -> 6
1 -> 2
2 -> 0
3 -> 7
As shown in the example, the values start at 0 and are consecutive integers.
I want to initialize all counts with 0, so that I can then increment them.
This is what I came up with:
val histogram = Array(numBuckets) { 0 }.toMutableList() as ArrayList
histogram[2]++
It works, but the initialization feels a bit convoluted. Is there a better way? Is the ArrayList the correct collection for the job in the place?
You can just use the MutableList constructor:
val histogram = MutableList(numBuckets) { 0 }
Kevin Coppock's answer works well if the values in the value-count pairs are consecutive and starting at 0. Then the array or list index stands for the value in the value-count pair.
If more flexibility is needed, for example if the values
do not start at zero,
have a step which is not 1,
or have irregular steps (e.g. logarithmic),
it might make sense to introduce pairs, either as Pair<Int, Int> or in the form of a data class:
import kotlin.math.pow
data class HistogramEntry(
var value: Int,
var count: Int
)
Example:
val numBuckets = 5
val regularHistogram = List(numBuckets) { HistogramEntry(it, 0) }
regularHistogram[2].count++
regularHistogram(::println)
Output:
HistogramEntry(value=0, count=0)
HistogramEntry(value=1, count=0)
HistogramEntry(value=2, count=1)
HistogramEntry(value=3, count=0)
HistogramEntry(value=4, count=0)
Another example:
val numBuckets = 5
val logarithmicHistogram = List(numBuckets) { HistogramEntry(10f.pow(it + 1).toInt(), 0) }
logarithmicHistogram[2].count = 12345
logarithmicHistogram.forEach(::println)
Output:
HistogramEntry(value=10, count=0)
HistogramEntry(value=100, count=0)
HistogramEntry(value=1000, count=12345)
HistogramEntry(value=10000, count=0)
HistogramEntry(value=100000, count=0)
And of course a HistogramEntry list could also be built manually:
val list = listOf(
HistogramEntry(value = 234, count = 0),
HistogramEntry(value = 36, count = 0),
HistogramEntry(value = 9, count = 0),
HistogramEntry(value = 178, count = 0),
HistogramEntry(value = 11, count = 0)
)

Pulp solves multiple combinatorial problems

As the title says,
I want to solve a problem similar to the summation of multiple schemes into a fixed constant, However, when I suggest the constrained optimization model, I can't get all the basic schemes well. Part of the opinion is to add a constraint when I get a solution. However, the added constraint leads to incomplete solution and no addition leads to a dead cycle.
Here is my problem description
I have a list of benchmark data detail_list ,My goal is to select several numbers from the benchmark data list(detail_list), but not all of them, so that the sum of these data can reach the sum of the number(plan_amount) I want.
For Examle
detail_list = [50, 100, 80, 40, 120, 25],
plan_amount = 20,
The feasible schemes are:
detail_list[2]=20 can be satisfied, detail_list[1](noly 10) + detail_list[3](only 10) = plan_amount(20) , detail_list[1](only 5) + detail_list[3](only 15) = plan_amount(20) also can be satisfied, and detail_list1 + detail_list2 + detail_list3 = plan_amount(20). But you can't take four elements in the detail_list are combined, because number = 3, indicating that a maximum of three elements are allowed to be combined.
from pulp import *
num = 6 # the list max length
number_max = 3 # How many combinations can there be at most
plan_amount = 20
detail_list = [50, 100, 80, 40, 120, 25] # Basic data
plan_model = LpProblem("plan_model")
alpha = [LpVariable("alpha_{0}".format(i+1), cat="Binary") for i in range(num)]
upBound_num = [int(detail_list_money) for detail_list_money in detail_list]
num_channel = [
LpVariable("fin_money_{0}".format(i+1), lowBound=0, upBound=upBound_num[i], cat="Integer") for i
in range(num)]
plan_model += lpSum(num_channel) == plan_amount
plan_model += lpSum(alpha) <= number_max
for i in range(num):
plan_model += num_channel[i] >= alpha[i] * 5
plan_model += num_channel[i] <= alpha[i] * detail_list[i]
plan_model.writeLP("2222.lp")
test_dd = open("2222.txt", "w", encoding="utf-8")
i = 0
while True:
plan_model.solve()
if LpStatus[plan_model.status] == "Optimal":
test_dd.write(str(i + 1) + "times result\n")
for v in plan_model.variables():
test_dd.write(v.name + "=" + str(v.varValue))
test_dd.write("\n")
test_dd.write("============================\n\n")
alpha_0_num = 0
alpha_1_num = 0
for alpha_value in alpha:
if value(alpha_value) == 0:
alpha_0_num += 1
if value(alpha_value) == 1:
alpha_1_num += 1
plan_model += (lpSum(
alpha[k] for k in range(num) if value(alpha[k]) == 1)) <= alpha_1_num - 1
plan_model.writeLP("2222.lp")
i += 1
else:
break
test_dd.close()
I don't know how to change my constraints to achieve this goal. Can you help me

Cratedb loop over column Array and see if the values fall between X and Y

Hey stack overflow so I have a column called itemPrices that is an Array of integers;
[43, 44, 55]
So I have an api that gives me two numbers, X and Y. I want to take those two numbers and compare it against the Array. If the number in the object falls within X and Y I would like to retrieve the contents. How would i do such a thing in crateDB?
This can also be solved by using the array_min(array) and array_max(array) scalar functions:
cr> CREATE TABLE t1 (arr ARRAY(INTEGER));
CREATE OK, 1 row affected (1.918 sec)
cr> INSERT INTO t1 (arr) VALUES ([43, 44, 45]), ([42, 22, 105]);
INSERT OK, 2 rows affected (0.112 sec)
cr> SELECT arr FROM t1 WHERE array_min(arr) >= 43 AND array_max(arr) <= 45;
+--------------+
| arr |
+--------------+
| [43, 44, 45] |
+--------------+
SELECT 1 row in set (0.008 sec)
CREATE OR REPLACE FUNCTION filter_item_price(ARRAY(REAL), INTEGER, INTEGER) RETURNS BOOLEAN
LANGUAGE JAVASCRIPT
AS 'function filter_item_price(array_integer, min_value, max_value) {
if(array_integer === null || array_integer === undefined) {
return false;
}
return array_integer.some(element => element >= min_value && element <= max_value);
}';
SELECT "itemPrices"
FROM scp_service_transaction.transactions_v2
WHERE "tenantId" = 'aptos-denim'
AND "retailLocationId" IN (161)
AND array_find("itemPrices", 98, 100) limit 100;
This can be solved with a User-Defined Function.
If you want to find the elements in the array, you could use a function like this:
CREATE OR REPLACE FUNCTION array_filter(ARRAY(INTEGER), INTEGER, INTEGER) RETURNS ARRAY(INTEGER)
LANGUAGE JAVASCRIPT
AS 'function array_filter(array_integer, min_value, max_value) {
return Array.prototype.filter.call(array_integer, element => element >= min_value && element <= max_value);
}';
SELECT array_filter([5, 7, 20], 2, 8)
-- returns [5, 7]
If you only want to identify if there is a value within the given boundaries, you can also do this:
CREATE OR REPLACE FUNCTION array_find(ARRAY(INTEGER), INTEGER, INTEGER) RETURNS BOOLEAN
LANGUAGE JAVASCRIPT
AS 'function array_find(array_integer, min_value, max_value) {
return Array.prototype.find.call(array_integer, element => element >= min_value && element <= max_value) !== undefined;
}';
SELECT array_find([5, 7, 20], 5, 300);
-- returns true
SELECT array_find([5, 7, 20], 25, 300);
-- returns false

find the first element in a list beyond some index and satisfying some condition

I have as Input:
A givenIndex
A list
I want to find the index of the first positive element in that list but ignoring all the indices that are strictly smaller than givenIndex
For example if givenIndex=2 and the list is listOf(1, 0, 0, 0, 6, 8, 2), the expected output is 4 (where the value is 6).
The following code gives the first positive element but It doesn't take into account ignoring all the indices that are smaller than givenIndex.
val numbers = listOf(1, 0, 0, 0, 6, 8, 2)
val output = numbers.indexOfFirst { it > 0 } //output is 0 but expected is 4
val givenIndex = 2
val output = numbers.withIndex().indexOfFirst { (index, value) -> index >= givenIndex && value > 0 }

Find the first element in a list that verify a condition

Assuming we are given a list of integers R = [3,5,3,6,0,6,7], an threshold x (integer) and a window size (integer) p. For example, x=4 and p = 2.
I need to find the first index t that verifies the the following conditions:
R[t] >= 4, R[t+1] >= 4. Since p=2, we need to only verify for two boxes t and t+1. If p was equal to 3 we will need to verify for t, t+1 and t+2.
Here the t I am looking for is 5 (indexing is starting from 0).
How to write this in a elegant way in Kotlin (rather than looping on the elements).
A tentative that is giving an error (x=4 and p = 2. The output should be 3 since we start indexing by 0):
val numbers = listOf(1, 2, 3, 4, 6, 8, 2)
val firstIndex = numbers.find { it >= 4 for it in it..it+2-1}
val numbers = listOf(1, 2, 3, 4, 6, 8, 2)
val p = 2
val x = 4
val t = numbers.windowed(p).indexOfFirst { window -> window.all { it >= x } } // t == 3
t will be equal to -1 in case if no matches will be found
Use windowed to check groups of values for each index in the list. Use withIndex() so you are iterating with the indices, which you need in your final result. Then use firstOrNull() (which find() is a redundant alias of). And finally, take ?.index to get the index of the first entry that satisfies the condition, or null if none satisfy.
val x = 4
val p = 3
val list = listOf(2,5,3,6,0,6,7)
val t = list
.windowed(p)
.withIndex()
.firstOrNull { (_, sublist) -> sublist.all { it >= x } }
?.index
find Returns the first element matching the given predicate, or null if no such element was found.
If I've understood correctly, this should work:
fun main() {
val list = listOf(3,5,3,6,0,6,7)
val p = 2
val x = 4
val t = list.withIndex().windowed(p).firstOrNull() { window ->
window.all { it.value >= x }
}?.first()?.index
println(t)
}
Output:
5