2

The Rust Programming Language has a task to print The Twelve Days of Christmas taking advantage of its repetitiveness.

My idea was to gather all the presents in an array and push them to the vector which would be printed from iteration to iteration.

It seems that it's either impossible, not easy, or I don't get something.

The code:

fn main() {
    let presents = [
        "A song and a Christmas tree",
        "Two candy canes",
        "Three boughs of holly",
    ];

    let mut current_presents = Vec::new();

    for day in presents {
        current_presents.push(presents[day]);
        println!(
            "On the {} day of Christmas my good friends brought to me",
            day + 1
        );
        println!("{current_presents} /n");
    }
}
error[E0277]: the type `[&str]` cannot be indexed by `&str`
  --> src/main.rs:11:31
   |
11 |         current_presents.push(presents[day]);
   |                               ^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
   |
   = help: the trait `SliceIndex<[&str]>` is not implemented for `&str`
   = note: required because of the requirements on the impl of `Index<&str>` for `[&str]`

error[E0369]: cannot add `{integer}` to `&str`
  --> src/main.rs:14:17
   |
14 |             day + 1
   |             --- ^ - {integer}
   |             |
   |             &str

error[E0277]: `Vec<_>` doesn't implement `std::fmt::Display`
  --> src/main.rs:16:20
   |
16 |         println!("{current_presents} /n");
   |                    ^^^^^^^^^^^^^^^^ `Vec<_>` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `Vec<_>`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

Please help me debug or push me in the right direction that wouldn't be typing down 12 separate strings and printing them 1 by 1.

3 Answers 3

3

This works:

fn main() {
    let presents = [
        "A song and a Christmas tree",
        "Two candy canes",
        "Three boughs of holly",
    ];

    let mut current_presents = Vec::new();

    for (day, present) in presents.iter().enumerate() {
        current_presents.push(present);
        println!(
            "On the {} day of Christmas my good friends brought to me",
            day + 1
        );
        println!("{current_presents:?}\n");
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you very much! Is there perhaps a leaner approach to get a similar effect in this language?
@Swantewit do you mean iterating by index like it seems you wanted to do in your question? You would do for day in 0..presents.len()
I am a little dissapointed that there isn't some kind function in Vector to load from an array or something generic like a (abstract) collection. Am I off-track?
@will, I believe in this instance the Vec is supposed to grow by one item each iteration to match the well-known verse.
Yes, I see now. My mistake.
0

The final answer looks like this (you can add all the verses up to 12th):

fn main() {
    let presents = [
        "A song and a Christmas tree",
        "Two candy canes",
        "Three boughs of holly",
        "Four coloured lights",
    ];

    for (day, _) in presents.iter().enumerate() {
        let mut presents = presents;

        let current_presents = &mut presents[0..day + 1];

        println!(
            "On the {} day of Christmas my good friends brought to me",
            day + 1
        );

        current_presents.reverse();

        current_presents
            .iter()
            .for_each(|present| print!("{} \n", present));
        println!("\n")
    }
}

Comments

0

I suspect I've found a satisfying answer for my dissapointment:

 let a = [10, 20, 30, 40]; // a plain array
 let v = a.to_vec();

See manual:

Credits to coder wall:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.