Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

palindrome-products: require factors in solution #2006

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

ellnix
Copy link
Contributor

@ellnix ellnix commented Jan 30, 2025

Apologies if I did something wrong, struggled a little bit with the rust-tooling.

Please let me know of any mistake, miss, or decisions you disagree with, no matter how small. No hard feelings.

The HashSet

Used a HashSet<(u64, u64)> for factors to avoid dealing with ordering of the factors and simultaneously communicate that the order doesn't matter. I thought leaving the inner tuple sorted made sense since that's how it appears in the instructions:

[...] The largest palindrome product is 9. Its factors are (1, 9) and (3, 3).

A sorted Vec would probably be fine, and the change can be made easily enough if you think it would be more appropriate.

The extra tests

There were two extra tests on the now-defunct Palindrome::new function. I felt those only made sense if this exercise still contained the newtype pattern. I can add them again if appropriate.

Corresponding forum post: https://forum.exercism.org/t/palindrome-products-description-mentions-factors/

Copy link
Contributor

This PR touches files which potentially affect the outcome of the tests of an exercise. This will cause all students' solutions to affected exercises to be re-tested.

If this PR does not affect the result of the test (or, for example, adds an edge case that is not worth rerunning all tests for), please add the following to the merge-commit message which will stops student's tests from re-running. Please copy-paste to avoid typos.

[no important files changed]

For more information, refer to the documentation. If you are unsure whether to add the message or not, please ping @exercism/maintainers-admin in a comment. Thank you!

Copy link
Contributor

Hello. Thanks for opening a PR on Exercism 🙂

We ask that all changes to Exercism are discussed on our Community Forum before being opened on GitHub. To enforce this, we automatically close all PRs that are submitted. That doesn't mean your PR is rejected but that we want the initial discussion about it to happen on our forum where a wide range of key contributors across the Exercism ecosystem can weigh in.

You can use this link to copy this into a new topic on the forum. If we decide the PR is appropriate, we'll reopen it and continue with it, so please don't delete your local branch.

If you're interested in learning more about this auto-responder, please read this blog post.


Note: If this PR has been pre-approved, please link back to this PR on the forum thread and a maintainer or staff member will reopen it.

Copy link
Contributor

Hello 👋 Thanks for your PR.

This repo does not currently have dedicated maintainers. Our cross-track maintainers team will attempt to review and merge your PR, but it will likely take longer for your PR to be reviewed.

If you enjoy contributing to Exercism and have a track-record of doing so successfully, you might like to become an Exercism maintainer for this track.

Please feel free to ask any questions, or chat to us about anything to do with this PR or the reviewing process on the Exercism forum.

(cc @exercism/cross-track-maintainers)

{%- endif%}
assert_eq!(pal.value(), {{ test.expected.value }});
assert_eq!(pal.factors(), &HashSet::from([
{{- test.expected.factors | join(sep=", ") | replace(from="[", to="(") | replace(from="]", to=")") -}}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the last PR:

I also had this instead of the one-liner:

Suggested change
{{- test.expected.factors | join(sep=", ") | replace(from="[", to="(") | replace(from="]", to=")") -}}
{%- for factor in test.expected.factors -%}
({{ factor | join(sep=", ") }}){% if not loop.last %}, {% endif %}
{%- endfor -%}

I didn't really like either of them, but thought I'd drop this here just in case. There's probably some jinja-fu that can be done instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too worried about the beauty of these templates. It seems like a write-only thing to me. If the exercise is changed substantially, there's a good chance the test template will have to be done basically from scratch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, as someone who has tried to make tera templates pretty in the past, I can say you have the right attitude.

@senekor senekor reopened this Jan 30, 2025
@senekor
Copy link
Contributor

senekor commented Jan 30, 2025

struggled a little bit with the rust-tooling

Yeah that's something I cooked up on my own. What were you struggling with? It could point us to potential improvements or at least missing documentation. Did you stumble on docs/CONTRIBUTING.md#tooling?

@ellnix
Copy link
Contributor Author

ellnix commented Jan 30, 2025

struggled a little bit with the rust-tooling

Yeah that's something I cooked up on my own. What were you struggling with? It could point us to potential improvements or at least missing documentation. Did you stumble on docs/CONTRIBUTING.md#tooling?

Not at all, honestly there's a ton of documentation on exercism in general and the tracks specifically that getting started on doing something is a bit of a challenge. But, it looks like I did exactly what I was supposed to, read a bunch of source code, created the problem-specifications symlink myself after investigating why things weren't working.

I'll make sure to read everything properly in the future.

{%- endif%}
assert_eq!(pal.value(), {{ test.expected.value }});
assert_eq!(pal.factors(), &HashSet::from([
{{- test.expected.factors | join(sep=", ") | replace(from="[", to="(") | replace(from="]", to=")") -}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too worried about the beauty of these templates. It seems like a write-only thing to me. If the exercise is changed substantially, there's a good chance the test template will have to be done basically from scratch.

use std::collections::HashSet;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Palindrome;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub struct Palindrome;
pub struct Palindrome {
// TODO
}

While solving exercises, I sometimes wasn't sure what I was supposed to change and what to leave as it is. So I think it could remove some friction to mark this explicitly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, added.

/// Get the value of this palindrome.
pub fn into_inner(self) -> u64 {
todo!("return inner value of a Palindrome");
pub fn factors(&self) -> &HashSet<(u64, u64)> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should return on owned hashset here? Having the reference there forces the internal representation of Palindrome to store the hashset. I think that's a good approach, but maybe we shouldn't force it.

Returning an owned hashset might lead to additional heap allocations, but that doesn't matter in my view. If desired, we could do something like fn into_factors(self) -> HashSet, maybe that would yield the most flexibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea, done! 👍

ellnix added a commit to ellnix/exercism-rust that referenced this pull request Jan 30, 2025
ellnix added a commit to ellnix/exercism-rust that referenced this pull request Jan 30, 2025
@ellnix ellnix requested a review from senekor January 30, 2025 10:54
ellnix and others added 2 commits January 30, 2025 11:56
@ellnix ellnix force-pushed the palindrome-products-factors branch from 4b11e3d to 5dfe332 Compare January 30, 2025 10:57
@senekor
Copy link
Contributor

senekor commented Jan 30, 2025

I'll let you merge yourself so you can decide on the squashed commit message. The default setting is to use the PR description. This is useful, because you can add the [no important files changed] tag at the beginning in the PR description and then you won't forget to add it at merge-time. (Not saying the tag should be added on this PR, it's not applicable.)

@ellnix
Copy link
Contributor Author

ellnix commented Jan 30, 2025

I'll let you merge yourself so you can decide on the squashed commit message. The default setting is to use the PR description. This is useful, because you can add the [no important files changed] tag at the beginning in the PR description and then you won't forget to add it at merge-time. (Not saying the tag should be added on this PR, it's not applicable.)

Thanks, but I don't have write access for now. I'm guessing I should wait to be added as a maintainer.

@senekor
Copy link
Contributor

senekor commented Jan 30, 2025

Jeremy says he added you, so it should work now 👍

@ellnix
Copy link
Contributor Author

ellnix commented Jan 30, 2025

Jeremy says he added you, so it should work now 👍

Github says no:
image

Maybe I just need to wait.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants