Loading collection data...
Collections are a way for you to organize kata so that you can create your own training routines. Every collection you create is public and automatically sharable with other warriors. After you have added a few kata to a collection you and others can train on the kata contained within the collection.
Get started now by creating a new collection.
This comment is hidden because it contains spoiler information about the solution
A vector always uses more space than an array, and will always be slower if you know the length you need ahead of time. A vector has to store the values on the heap, and store its pointer, length, and capacity on the stack. An array just keeps its length and values on the stack. The only reason I can think of to use a vector over an array is if the length of the list needs to change at runtime. If the length doesn't change at runtime, but is determined once at runtime and then fixed, it's usually a good idea to use a
Box<[T]>
, since those are still heap allocated but don't keep track of their capacity because they can't change length. ABox<[T]>
can also help in the rare occasion that you want to use an array that's too big for the stack space the OS gives you.Why does the Rust version use
i32
s when the instructions specify that the input will always be positive?There is no reason for the Rust version of this kata to have an
i32
return value. First,i32
isn't big enough for all possiblef64
inputs. Second, the answer should never be negative, so you should encode that in the type system by using an unsigned int.The Rust version has an unidiomatic type signature. It is almost always better for a function to take a
&[T]
rather than a&Vec<T>
, since&Vec<T>
is one of several types that the compiler can automatically convert to a&[T]
with deref coercion.&Vec<T>
is only for when you absolutely need a reference to aVec
, not when you generally need a reference to a list of things.There's no need to use a vector here when you know the list will only ever be length 256. An array works fine and performs better.
The input should not be named
sq
when it's stated in the problem that it might not be a perfect square.Very nice idea to use a min-heap! I would also note that you can save space by making the capacity of the heap equal to
min(n as usize, customers.len())
. If there are 10 tills and only 5 customers, then we don't need to keep track of what the other 5 tills are doing, so we don't need to allocate 5u32
s of space for them in our min-heap.Better yet, we can avoid allocating a heap at all if
n >= customers.len()
, since then the answer is just the maximum ofcustomers
. In a similar vein, ifn == 1
, then the answer is justcustomers.iter().sum()
.If we add both of those special cases at the top, then we only allocate a min-heap when it's actually helpful. Although checking for those special cases does take time, I would expect that to be negligible compared to the time needed to allocate memory for the min-heap.
Edit: This approach can be optimized further by replacing the
pop
-then-push
withpeek_mut
. Usingpop
followed bypush
, the heap gets rebalanced during thepop
and again during thepush
. Usingpeek_mut
, you modify the minimum value and then rebalance only once.Love this use of step_by! It makes it so much cleaner compared to manually computing the odd numbers up to n.
Not only is 2kB an insignificant amount of memory to use for this, but also you already have that memory available. On most systems, the default stack size for the main thread is 2MB. Unless the rest of your program is using 99.9% of its available stack, it costs almost nothing to dedicate 2kB of stack to make this array, and pop it from the stack after this function finishes.
As for heap allocation, I'm not very familiar with Rust's allocator, but it's quite possible that creating a hash map for this will in some cases be forced to take 4kB, since most operating systems think about memory in 4kB chunks.
Not sure what you mean by this. I haven't seen a single solution that uses .count().
This is a stack, not a queue. You're always removing the thing you added last. With a queue, you remove the thing you added first.