Ad
  • Custom User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Custom User Avatar

    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. A Box<[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.

  • Custom User Avatar

    Why does the Rust version use i32s when the instructions specify that the input will always be positive?

  • Custom User Avatar

    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 possible f64 inputs. Second, the answer should never be negative, so you should encode that in the type system by using an unsigned int.

  • Custom User Avatar

    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 a Vec, not when you generally need a reference to a list of things.

  • Custom User Avatar

    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.

  • Custom User Avatar

    The input should not be named sq when it's stated in the problem that it might not be a perfect square.

  • Custom User Avatar

    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 5 u32s 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 of customers. In a similar vein, if n == 1, then the answer is just customers.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 with peek_mut. Using pop followed by push, the heap gets rebalanced during the pop and again during the push. Using peek_mut, you modify the minimum value and then rebalance only once.

  • Custom User Avatar

    Love this use of step_by! It makes it so much cleaner compared to manually computing the odd numbers up to n.

  • Custom User Avatar

    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.

  • Custom User Avatar

    Not sure what you mean by this. I haven't seen a single solution that uses .count().

  • Custom User Avatar

    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.