Is there something like a rolling Array index? - rust

Following mwe:
let months = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"];
println!("Seasons are:\n\tSpring ({:?})\n\tSummer ({:?})\n\tFall ({:?})\n\tWinter ({:?})",
&months[2..5],
&months[5..8],
&months[8..11],
[&months[11],&months[0],&months[1]]
)
The issue here is, that the last season is comprised of the last value of the array and the first two. For this example, I can add them manually. But in practice, with more values, this won't be viable.
Since this is a fixed (immutable) array, is there a way of something like rolling index?
For example something like
[&months[11]..+3]
or
[&months[11], &months[0..2]]
What is the most elegant way of handling such a case?

A slice is a contiguous piece of memory, so it's impossible to take a slice that wraps around the way you want since the corresponding elements are not contiguous. Depending on what you really want to do, you might be able to work with iterators and chain:
months[11..].iter().chain (months[..3].iter())
or simply with a couple of loops:
print!("Winter ([");
for m in months[11..] { // In this case, you would probably put `months[11]` directly in the first `print`
print!("{:?}, ", m);
}
for m in months[..3] {
print!("{:?}, ", m);
}
println!("])");

Related

Which is faster (time complexity) in groovy, .find() or .each()?

So I'm making a research on which method in groovy makes faster result.
Let's say we have:
def storage = [{item:"apple", amount:3, color: "red"}, {item:"mango", amount:5, color: "yellow"}]
Is doing this:
def someMap = [:]
storage.each {
someMap[it.item] = [amount: it.amount, color: it.color]
}
So when we need to get the amount of an item, we do this:
someMap["apple"].amount
Better than doing this? :
def storageFindByItem = { itemName ->
return storage.find{
i -> i.item == itemName
}
}
So when we need to get the amount of an item, we do this:
storageFindByItem("apple").amount
The short answer is that when it comes to performance assessments, you should perform your tests and decide from the results.
With that said, the first option searches an indexed map and would be presumably faster. But this is probably more likely when you're using a HashMap for someMap rather than [:] (LinkedHashMap). And of course this would take an additional amount of memory.
The second option will always be searching linearly whereas finding in a hash map runs in constant time.
All this could be speculation in the face of actual test results, which would really be encouraged.

Julia: How much can we change the objects in immutable struct type?

I have an immutable structure with four objects defined as follows:
struct FltFric
muS::Array{Float64, 2}
muD::Array{Float64, 2}
Dc::Float64
W::Array{Float64, 2}
end
muS = repmat([0.6], 100, 1) # Coefficient of static friction
muD = repmat([0.5], 100, 1) # Coefficient of dynamic friction
Dc = 0.1 # Critical slip distance
FltFriction = FltFric(muS, muD, Dc, zeros(size(muS)))
I am modifying the values of FltFric.muS as follows:
FltFriction.muS[1:20] = 100
This works fine. But when I try to modify the value of W
FltFriction.W = (FltFriction.muS - FltFriction.muD)./(FltFriction.Dc)
This gives me an error: type FltFric is immutable.
Why does the first statement not give error while the second one does? If the type is immutable, both statements should give an error. What is the difference between the two assignments?
I know that I can circumvent the problem by typing mutable struct, but I don't understand the difference in my two assignments.
I am not a Julia expert, but I think this is a more general question.
In the first assignment, you're modifying certain elements of the list FltFriction.muS. This is fine since although the struct is immutable, the list referred to by .muS is mutable. In other words, you're mutating the list by changing its elements, rather than mutating the struct.
In the second assignment, you're trying to replace the entire list .W in one fell swoop. In this case you're trying to mutate the struct directly, replacing one of its elements. For this reason, the second assignment fails while the first one succeeds.
I'm speculating here, but I suspect that if you tried to do the second assignment like so:
FltFriction.W[1:end] = ...
Then you would be fine, since you're mutating the list instead of the struct.
As pointed out by a commenter (see below), in Julia there is a "more idiomatic (and more performant)" way to do this correctly and without mutating the struct itself by using the in-place assignment operator (neat!):
FltFriction.W .= (FltFriction.muS - FltFriction.muD)./FltFriction.Dc

How to find all maximum value between every i and i + k(some constant) of a given array?

I need to find all maximum values among elements of every possible set {a[i], a[i+1],... a[i + k]} (where i is index and k is some given constant). For this I am using.
loop(b, 1, k) {
rloopl(i, b, n) {
if(a[i] < a[i-1])
a[i] = a[i-1];
}
}
but its too slow for large array. Is there any other more efficient way to do this?
I'm very sorry to tell you that, with the requirement as-presented, the answer would be: "no." If "the largest value could be anywhere," you have no choice but to "look ... everywhere."
If you are "doing this 'once and only once,'" for any particular data-set, then you're basically just gonna have to take your lumps. You're stuck with "brute-force."
However, if you're doing this more than once, and/or if you have some influence on the process by which the array in question gets loaded, the situation might start looking a little better.
For instance, if another piece of code is adding elements to this array one-at-a-time, it's trivial for that piece of code to notice the max/min value that it encounters. Code that loads a two-dimensional array might gather statistics about each row (column). And, so on. Such strategies, which are "free, at the time," can be used to eliminate (or, severely curtail) the need to do specific brute-force searches later.

How can I co-sort two Vecs based on the values in one of the Vecs?

I have two Vecs that correspond to a list of feature vectors and their corresponding class labels, and I'd like to co-sort them by the class labels.
However, Rust's sort_by operates on a slice rather than being a generic function over a trait (or similar), and the closure only gets the elements to be compared rather than the indices so I can sneakily hack the sort to be parallel.
I've considered the solution:
let mut both = data.iter().zip(labels.iter()).collect();
both.sort_by( blah blah );
// Now split them back into two vectors
I'd prefer not to allocate a whole new vector to do this every time because the size of the data can be extremely large.
I can always implement my own sort, of course, but if there's a builtin way to do this it would be much better.
I just wrote a crate "permutation" that allows you to do this :)
let names = vec!["Bob", "Steve", "Jane"];
let salary = vec![10, 5, 15];
let permutation = permutation::sort(&salary);
let ordered_names = permutation.apply_slice(&names);
let ordered_salaries = permutation.apply_slice(&salary);
assert!(ordered_names == vec!["Steve", "Bob", "Jane"]);
assert!(ordered_salaries == vec![5, 10, 15]);
It likely will support this in a single function call in the future.

add unbounded_Strings to enum ada

I am quite new to programming and Ada I have to say so I don't know if this an easy thing to do or so, I tried googling and searching this site but I can't really find it!
I want to add an array of strings to an enum (or enum_def don't know exactly what it is)
First i had
name_type is (name1, name2, name3, name4, name5, etc)
and I did my things with this that worked
But now I want to fill this name_type (so without anything in it, maybe 1 starting name) with an array of unbounded_strings, so I add the unbounded_strings one by one.
So the thing would be like :
name_type is ()
ustring_array is array (1 .. 50) of Unbounded_String;
for I in 1 .. 8 loop
ustring_array (I) := "Get_Name" -- i get this name from somewhere
end loop;
fill name_type with strings from ustring_array (not code, I don't know how to do this part )
so the ustring_array would look something like ("name1", "name2", "name3", etc)
and i want the name_type to look like (name1, name2, name3, etc) so that they are individual pieces but not strings
so that the size of my name_type is defined by the number of strings in ustring_array
Is this possible or am I asking for the impossible?
If you read the part that is connected to IO with Enumeration types in the ARM, you will find more or less the answer.
There is also a solution using the Image attribute as described here.
It sounds like, essentially, you are asking about extending enumerations. That's not possible, but it is possible to define an array that maps an enumeration to an Unbounded_String:
Type Directions is (Up, Down, Left, Right);
-- Assuming "+" renames of the string to unbounded string.
Direction_Text : Constant Array (Directions) of Unbounded_String :=
( Up => +"Upwards",
Down => +"Downwards",
Left => +"Port",
Right => +"Starboard"
);
There's also a new container Ada.Containers.Indefinite_Holders which could be used as an element in the array to hold unconstrained-length strings.

Resources