Akka Streams - How to produce the size of a List followed by the entire List - akka-stream

I would like to consume a list of elements and then forward the size of the list followed by the full list of elements.
E.g.
Given List (1, 2, 3, 4, 5)
When the source is fully consumed
Then the next processing-stage receives the elements List(5, 1, 2, 3, 4, 5)
This is a toy problem I am attempting to solve; I appreciate that it's bad practice to fully consuming the list before the next processing stage receives its first element.
I have the code that will calculate the size of the list.
val length: RunnableGraph[Future[Int]] = FileIO.fromPath(Paths.get("myList.txt")).toMat(Sink.fold(0) {
case (length, s) => length + s.length
})(Keep.right)
I'm not sure how to fully consume the list before sending the list to the next processing stage (preceded by the size of the list).

You could use fold to accumulate both the size of the List and the List elements themselves, then use flatMapConcat and concat:
val data = List(1, 2, 3, 4, 5)
Source(data)
.fold((0, List.empty[Int]))((acc, curr) => (acc._1 + 1, acc._2 :+ curr))
.flatMapConcat {
case (size, elems) => Source.single(size).concat(Source(elems))
}
.runForeach(println)
The above code prints:
5 // size of the list
1
2
3
4
5
Note that while the above code works in this toy example, it's not "streamlike" because it copies the entire List into memory (which negates the whole point of using streams). Hopefully this example serves to illustrate a few pieces of Akka Stream functionality, but don't follow this approach in production code.

Related

Finding max sum with operation limit

As an input i'm given an array of integers (all positive).
Also as an input i`m given a number of "actions". The goal is to find max possible sum of array elements with given number of actions.
As an "action" i can either:
Add current element to sum
Move to the next element
We are starting at 0 position in array. Each element could be added only once.
Limitation are:
2 < array.Length < 20
0 < number of "actions" < 20
It seems to me that this limitations essentially not important. Its possible to find each combination of "actions", but in this case complexity would be like 2^"actions" and this is bad...))
Examples:
array = [1, 4, 2], 3 actions. Output should be 5. In this case we added zero element, moved to first element, added first element.
array = [7, 8, 9], 2 actions. Output should be 8. In this case we moved to the first element, then added first element.
Could anyone please explain me the algorithm to solve this problem? Or at least the direction in which i shoudl try to solve it.
Thanks in advance
Here is another DP solution using memoization. The idea is to represent the state by a pair of integers (current_index, actions_left) and map it to the maximum sum when starting from the current_index, assuming actions_left is the upper bound on actions we are allowed to take:
from functools import lru_cache
def best_sum(arr, num_actions):
'get best sum from arr given a budget of actions limited to num_actions'
#lru_cache(None)
def dp(idx, num_actions_):
'return best sum starting at idx (inclusive)'
'with number of actions = num_actions_ available'
# return zero if out of list elements or actions
if idx >= len(arr) or num_actions_ <= 0:
return 0
# otherwise, decide if we should include current element or not
return max(
# if we include element at idx
# we spend two actions: one to include the element and one to move
# to the next element
dp(idx + 1, num_actions_ - 2) + arr[idx],
# if we do not include element at idx
# we spend one action to move to the next element
dp(idx + 1, num_actions_ - 1)
)
return dp(0, num_actions)
I am using Python 3.7.12.
array = [1, 1, 1, 1, 100]
actions = 5
In example like above, you just have to keep moving right and finally pickup the 100. At the beginning of the array we never know what values we are going to see further. So, this can't be greedy.
You have two actions and you have to try out both because you don't know which to apply when.
Below is a python code. If not familiar treat as pseudocode or feel free to convert to language of your choice. We recursively try both actions until we run out of actions or we reach the end of the input array.
def getMaxSum(current_index, actions_left, current_sum):
nonlocal max_sum
if actions_left == 0 or current_index == len(array):
max_sum = max(max_sum, current_sum)
return
if actions_left == 1:
#Add current element to sum
getMaxSum(current_index, actions_left - 1, current_sum + array[current_index])
else:
#Add current element to sum and Move to the next element
getMaxSum(current_index + 1, actions_left - 2, current_sum + array[current_index])
#Move to the next element
getMaxSum(current_index + 1, actions_left - 1, current_sum)
array = [7, 8, 9]
actions = 2
max_sum = 0
getMaxSum(0, actions, 0)
print(max_sum)
You will realize that there can be overlapping sub-problems here and we can avoid those repetitive computations by memoizing/caching the results to the sub-problems. I leave that task to you as an exercise. Basically, this is Dynamic Programming problem.
Hope it helped. Post in comments if any doubts.

How do/ can I print an arrays contents into a textView in Android Studios Kotlin

lets say I'm making a simple dnd dice roller (cause I am), I get results and I turn it into an array.
Now I want to print the results of the array into a textView that would say:
randNumResultsDisplay.text = "Rolled " then it would spit out all results in the array, in order that they were put in.
I'm not entirely sure where you are stuck here, but if you want to convert an array into a String, one option is to use the java.utils.Arrays class:
val myArray = arrayOf(1, 2, 3)
val contents = Arrays.toString(myArray)
println(contents) // prints "[1, 2, 3]"
So to inject that in your text view as you suggested:
randNumResultsDisplay.text = "Rolled ${Arrays.toString(yourValuesArray)}"
That being said, you would get it for free if you used List instead of Array (which is very much advised):
randNumResultsDisplay.text = "Rolled $yourList"
Another option as pointed out in the comments is the joinToString method, which works on both arrays and lists and allows you to customize the formatting:
println("Rolled: ${myArray.joinToString()}")
// Rolled 1, 2, 3
println("Rolled: ${myArray.joinToString(prefix = "[", postfix = "]")}")
// Rolled [1, 2, 3]
println("Rolled: ${myArray.joinToString(separator = "|")}")
// Rolled 1|2|3

Creating a list of many ndarrays (different size) in python

I am new to python. Do we have any similar structure like Matlab's Multidimensional structure arrays in Python 2.7 that handles many ndarrays in a list. For instance, I have 15 of these layers (i.e. layer_X, X=[1,15]) with different size but all are 4D:
>>>type(layer_1)
<type 'numpy.ndarray'>
>>> np.shape(layer_1)
(1, 1, 32, 64)
>>> np.shape(layer_12)
(1, 1, 512, 1024)
How do I assign a structure that handles these ndarray with their position X?
You can use a dictionary:
layer_dict = {}
for X in range(1,16):
layer_dict['layer_' + str(X)] = np.ndarray(shape=(1, 1, 32, 64))
This allows to store arrays of various sizes (and any other datatypes to be precise), add and remove components. It also allows you to access your arrays efficiently.
To add a layer type:
layer_dict['layer_16'] = np.ndarray(shape=(1, 1, 512, 1024))
To delete one:
del layer_dict['layer_3']
Note that the items are not stored in order, but that does not prevent you from efficient in-order processing with approaches similar to one in the initial construction loop. If you want to have an ordered dictionary, you can use OrderedDict from the collections module.
If there is any particular rule for choosing the size of each layer, update your question and I will edit my answer.
This is an example of sequential usage:
for X in range(1,16):
temp = layer_dict['layer_' + str(X)]
print type(temp)
The type of temp is an ndarray that you can use as any other ndarray.
A more detailed usage example:
for X in range(1,16):
temp = layer_dict['layer_' + str(X)]
temp[0, 0, 2, 0] = 1
layer_dict['layer_' + str(X)] = temp
Here each layer is fetched into temp, modified, and then reassigned to layer_dict.
You can just use a list:
layers = [layer_1, layer_12]

Save integers into array given by first integer

I need to know, how to save integers from stdin into array, given by first integer in line... Ehm... hope you understand. I will give you an example.
On stdin I have:
0 : [ 1, 2, 3 ]
5 : [ 10, 11, 12, 13]
6 : [ 2, 4, 9 ]
0 : [ 4, 9, 8 ]
5 : [ 9, 6, 7 ]
5 : [ 1 ]
And I need save these integers to the arrays like this:
0={1, 2, 3, 4, 9, 8}
5={10, 11, 12, 13, 9, 6, 7, 1}
6={2, 4, 9}
I absolutely don't how to do it. There is a problem, that the number of arrays(in this case - 0, 5, 6 - so 3 arrays ) can be very high and I need to work effectively with memory...So I guess i will need something like malloc and free to solve this problem, or am I wrong? The names of arrays (0, 5, 6) can be changed. Number of integers in brackets has no maximum limit.
Thank you for any help.
I go with the assumption, this is homework, and I go with the assumption, this isn't your first homework to do, so I won't present you a solution but instead some tips that would help you to solve it yourself.
Given the input line
5 : [ 10, 11, 12, 13]
I will call "5" the "array name" and 10, 11, 12 and 13 the values to add.
You should implement some system to map array names to indices. A trivial approach would be like this:
.
size_t num_arrays;
size_t * array_names;
Here, in your example input, num_arrays will end up being 3 with array_names[3] = { 0, 5, 6}. If you find a new array name, realloc and add the new array name. Also you need the actual arrays for the values:
int * * array;
you need to realloc array for each new array name (like you realloc array_names). array[0] will represent array array_names[0] here array 0, array[1] will represent array array_names[1] here array 5 and array[2] will represent array array_names[2] here array 6.
To access an array, find it's index like so:
size_t index;
for (size_t index = 0; index < num_arrays && array_names[index] != search; ++index) ;
The second step is easy. Once you figured out, you need to use array[index] to add elemens, realloc that one (array[index] = realloc(array[index], new size)) and add elements there array[index][i+old_size] = new_value[i].
Obviously, you need to keep track of the number of elements in your separate arrays as well ;)
Hint: If searching for the array names take too long, you will have to replace that trivial mapping part by some more sophisticated data structure, like a hash map or a binary search tree. The rest of the concept may stay more or less the same.
Should you have problems to parse the input lines, I suggest, you open a new question specific on this parsing part.
In algorithmic terms, you need map (associative array) from ints to arrays. This is solved long ago in most higher level languages.
If you have to implement it manually, you have a few options:
simple "master" array where you store your 0, 5, 6, 1000000 and then map them to indices 0, 1, 2, 3 by doing search in for each time you have to access it (it's too time consuming when ;
hash table: write simple hash function to map 0, 5, 6, 1000000 (they're called keys) to values less than 1000, allocate array of 1000 elements and then make "master" array structures for each hash function result;
some kind of tree (e.g. red-black tree), may be a bit complex to implement manually.
Last two structures are part of programming classic and are well described in various articles and books.

Scala: what is the best way to append an element to an Array?

Say I have an Array[Int] like
val array = Array( 1, 2, 3 )
Now I would like to append an element to the array, say the value 4, as in the following example:
val array2 = array + 4 // will not compile
I can of course use System.arraycopy() and do this on my own, but there must be a Scala library function for this, which I simply could not find. Thanks for any pointers!
Notes:
I am aware that I can append another Array of elements, like in the following line, but that seems too round-about:
val array2b = array ++ Array( 4 ) // this works
I am aware of the advantages and drawbacks of List vs Array and here I am for various reasons specifically interested in extending an Array.
Edit 1
Thanks for the answers pointing to the :+ operator method. This is what I was looking for. Unfortunately, it is rather slower than a custom append() method implementation using arraycopy -- about two to three times slower. Looking at the implementation in SeqLike[], a builder is created, then the array is added to it, then the append is done via the builder, then the builder is rendered. Not a good implementation for arrays. I did a quick benchmark comparing the two methods, looking at the fastest time out of ten cycles. Doing 10 million repetitions of a single-item append to an 8-element array instance of some class Foo takes 3.1 sec with :+ and 1.7 sec with a simple append() method that uses System.arraycopy(); doing 10 million single-item append repetitions on 8-element arrays of Long takes 2.1 sec with :+ and 0.78 sec with the simple append() method. Wonder if this couldn't be fixed in the library with a custom implementation for Array?
Edit 2
For what it's worth, I filed a ticket:
https://issues.scala-lang.org/browse/SI-5017
You can use :+ to append element to array and +: to prepend it:
0 +: array :+ 4
should produce:
res3: Array[Int] = Array(0, 1, 2, 3, 4)
It's the same as with any other implementation of Seq.
val array2 = array :+ 4
//Array(1, 2, 3, 4)
Works also "reversed":
val array2 = 4 +: array
Array(4, 1, 2, 3)
There is also an "in-place" version:
var array = Array( 1, 2, 3 )
array +:= 4
//Array(4, 1, 2, 3)
array :+= 0
//Array(4, 1, 2, 3, 0)
The easiest might be:
Array(1, 2, 3) :+ 4
Actually, Array can be implcitly transformed in a WrappedArray

Resources