Ad
  • Default User Avatar

    overload )) I thought the fork was removed ))

  • Default User Avatar

    So, you fork a Kumite titled "...without converting to string", and put a string conversion in the code..

    Perhaps fork one of the ones that have done this predictable, inefficient approach to death..

  • Default User Avatar

    You don't really need number of digits for this; you can just repeatedly divide the input number by 10 on each loop until it hits zero (or mods to 3)

  • Default User Avatar

    If you're going to do this you don't need the ToCharArray or the ToList; LINQ will operate on a string as if it were a sequence of chars

  • Custom User Avatar

    If you want to add a prolog-specific part of the description, you should use formatting blocks so that other languages do not see it.

    ~~~if:prolog
    Prolog specific part
    can go here
    ~~~
    

    ^ like this

  • Custom User Avatar

    Hi. Thanks for the review.
    Here is my answer:

    • I hesitated to choose bool as type. The problem is the description refers to 1 and 0, and there is no equivalency in Rust between boolean and integers, so it would actually change the problem. Moreover at the time of printing stuff (for example when a test fails), it is visually very ugly if we display booleans, this would require a conversion, extra explanations to the user, etc. All this moves away from the task as it is described, so I prefer to avoid it. Note that among current languages, only C uses bool (which fully is justified IMO: in C, 1 is true and 0 is false).
    • When I began to make Rust translation, I also had the tendancy to use usize as soone as it refered to the count of something, like you are doing here I guess. Then some experienced users made me notice that usize are just platform dependent numbers, I searched for documentation, examples, explanation and indeed, I believe it is not suited in general. Does it make a sense here to consider n is in a way platform dependent? We are talking about the number of moves in a game, why would this depend on the architecture? You can see I don't need to cast usize in my solution. If a user needs to use it at usize, it's easy to cast it. Now I almost never use usize in parameter or output types, one rare exception is when it is refering explicitly to indices (in this case it makes sense).
    • For the datatypes, I just use the common data types for the language, that are the ones used in most katas and in all other languages. Vec is the basic variable sized container. In all katas I can remember, when you are passed an array as input and you are supposed to return a similar data structure after doing the task, you must return a vector. Once again: if users want to use a deque a hashmap or some other map (seriously???), they are free to do it, but those are uncommon data structures, they require imports..., this gets away from the description and from what is done in other languges, I won't use them. For example, I have solved many katas in Python, and I cannot remember a single one where one is passed in or is supposed to return a deque. At first you provide a list (the basic data structure container), at the end you must return a list. Intermediary steps are the choice of user. What you prefer because it is easier to use is one thing, what the kata is asking is something else.

    For the 4th point, AFAIK this is what is done in all katas in Rust (I know one exception, and it is justified). I just stuck with it, just like with the rest.

    You idea to implememt impl IntoIterator<Item=bool> is interesting, I believe it is more idiomatic, but once again, this takes us away from the kata itself as it is explained in the description and what we have in other languages. And it is relatively advanced stuff IMO. Look at the description and the detailed example at the end:

    • from the list [1] and iterating 5 times:
    • [0, 1, 0]
    • [1, 1, 1]
    • ... the result will be [1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1]

    This is the task as it is explained in the description. I just tried to implement it in the most straightforward and generic way. It is clear there is no point in returning some kind of map here. It's a bad idea to arbitrarily diverge from the task as it is presented, just because personnally you would do it this way or you would prefer this, or because it could be more idiomatic to do it this way in particular language. The concrete implementation of the algorithm, the intermediate datatypes, are left to the user; but the function itself must be the most generic to match with the task as it is described in the kata.

  • Custom User Avatar

    Hey thanks for translating this, I had fun solving it!

    My only suggestion is that the function signature look more like this:

    fn rule30(list: &[bool], n: usize) -> impl IntoIterator<Item=bool>
    

    Here's my reasoning:

    1. It feels more typesafe to use bool rather than u8 because any value except 0 or 1 are invalid for this problem.
    2. The number of iterations requested n would be ever so slightly nicer to work with if it were a usize. This allows the implementor to compute max allocation sizes without having to cast to usize themself.
    3. It's not clear that a Vec is necessarily the best datastructure to return. For instance, I found VecDeques easier to use since the world could be extended efficiently. It would also allow the use of BTreeMap<usize, bool>s (or some other ordered map) to be used, which some might find more ergonomic.
    4. I like that the initial input (list) is provided as a slice because that places the responsibility of allocating the input on the caller, not the implementor, but prevents mutation (like if a Vec were provided instead).
  • Custom User Avatar

    I've reviewed your solution and tests, and I've written a working Haskell solution, does that count?

  • Custom User Avatar

    If you reviewed it correctly (tests design + you have an own solution that matches them), let me know and I can approve it myself.

  • Custom User Avatar

    Looks good to me. I hope this gets approved!

  • Custom User Avatar

    Ah, yes, I have heard of it. I didn’t know how exactly it worked though. Thanks!

  • Custom User Avatar

    Have you heard of that cool thing where an Iterator<Item = Option/Result<T>> can be collected into a Option/Result<Vec<T>>? I think it would let you say .collect().unwrap() instead of .map(Option::unwrap).collect().

  • Custom User Avatar

    Nice! I wish slice::array_windows was stable, that would let you do something like:

    .filter(|[a, b, c]| {
      a != b && b == c
    })
    
  • Custom User Avatar