{"id":974,"date":"2025-11-24T13:19:26","date_gmt":"2025-11-24T11:19:26","guid":{"rendered":"https:\/\/www.mariusb.net\/blog\/?p=974"},"modified":"2025-11-24T13:19:26","modified_gmt":"2025-11-24T11:19:26","slug":"rust-bytes-zigzag-merge","status":"publish","type":"post","link":"https:\/\/www.mariusb.net\/blog\/2025\/11\/rust-bytes-zigzag-merge\/","title":{"rendered":"Rust Bytes: ZigZag Merge"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"alignleft size-full is-resized\"><a href=\"https:\/\/i0.wp.com\/www.mariusb.net\/blog\/wp-content\/uploads\/2025\/11\/RB94_ZigZag_Merge.png?ssl=1\" rel=\"lightbox[974]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"646\" height=\"908\" src=\"https:\/\/i0.wp.com\/www.mariusb.net\/blog\/wp-content\/uploads\/2025\/11\/RB94_ZigZag_Merge.png?resize=646%2C908&#038;ssl=1\" alt=\"ZigZag Merge\" class=\"wp-image-973\" style=\"width:105px;height:auto\" srcset=\"https:\/\/i0.wp.com\/www.mariusb.net\/blog\/wp-content\/uploads\/2025\/11\/RB94_ZigZag_Merge.png?w=646&amp;ssl=1 646w, https:\/\/i0.wp.com\/www.mariusb.net\/blog\/wp-content\/uploads\/2025\/11\/RB94_ZigZag_Merge.png?resize=213%2C300&amp;ssl=1 213w\" sizes=\"auto, (max-width: 646px) 100vw, 646px\" \/><\/a><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Problem Statement:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Implement an iterator that merges two input iterators of i32 by alternating yields (first from iter1, then iter2, etc.) until both are exhausted.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If one ends early, continue with the remaining from the other.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>assert_eg!(zigzag_merge(vec!&#91;1, 3, 5].into_iter(), vec!&#91;2, 4, 6].into_iter()).collect::&lt;Vec&lt;i32&gt;&gt;(), vec!&#91;1, 2, 3, 4, 5, 6]);\nassert_eq!(zigzag_merge(vec!&#91;1, 3].into_iter(), vec!&#91;2, 4, 6].into_iter()).collect::&lt;Vec&lt;132&gt;&gt;(), vec!&#91;1, 2, 3, 4, 6]);\nassert_eq!(zigzag_merge(vec!&#91;1, 3, 5].into_iter(), vec!&#91;2, 4].into_iter()).collect::&lt;Vec&lt;132&gt;&gt;(), vec!&#91;1, 2, 3, 4, 5]);\nassert_eq!(zigzag_merge(vec!&#91;1, 2, 3].into_iter(), vec!&#91;].into_iter()).collect::&lt;Vec&lt;i32&gt;&gt;(), vec!&#91;1]);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>Note:<\/em><\/strong> <em>The last assert is wrong, the right should be <code>vec![1, 2, 3]<\/code><\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Solution:<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>fn main() {\n    println!(\"Zig Zag Merge Iterator\");\n}\n\npub struct Zigzag&lt;A, B>\nwhere\n    A: Iterator&lt;Item = i32>,\n    B: Iterator&lt;Item = i32>,\n{\n    a: A,\n    b: B,\n    turn_a: bool,\n}\n\nimpl&lt;A, B> Zigzag&lt;A, B>\nwhere\n    A: Iterator&lt;Item = i32>,\n    B: Iterator&lt;Item = i32>,\n{\n    pub fn new(a: A, b: B) -> Self {\n        Zigzag { a, b, turn_a: true }\n    }\n}\n\npub fn zigzag_merge&lt;A, B>(a: A, b: B) -> Zigzag&lt;A, B>\nwhere\n    A: Iterator&lt;Item = i32>,\n    B: Iterator&lt;Item = i32>,\n{\n    Zigzag::new(a, b)\n}\n\nimpl&lt;A, B> Iterator for Zigzag&lt;A, B>\nwhere\n    A: Iterator&lt;Item = i32>,\n    B: Iterator&lt;Item = i32>,\n{\n    type Item = i32;\n\n    fn next(&amp;mut self) -> Option&lt;Self::Item> {\n        if self.turn_a {\n            match self.a.next() {\n                Some(v) => {\n                    self.turn_a = false;\n                    Some(v)\n                }\n                None => self.b.next(),\n            }\n        } else {\n            match self.b.next() {\n                Some(v) => {\n                    self.turn_a = true;\n                    Some(v)\n                }\n                None => self.a.next(),\n            }\n        }\n    }\n}\n\n#&#91;cfg(test)]\nmod tests {\n    use super::*;\n\n    #&#91;test]\n    fn both_equal_length() {\n        let out: Vec&lt;i32> = zigzag_merge(vec!&#91;1, 3, 5].into_iter(), vec!&#91;2, 4, 6].into_iter()).collect();\n        assert_eq!(out, vec!&#91;1, 2, 3, 4, 5, 6]);\n    }\n\n    #&#91;test]\n    fn second_longer() {\n        let out: Vec&lt;i32> = zigzag_merge(vec!&#91;1, 3].into_iter(), vec!&#91;2, 4, 6].into_iter()).collect();\n        assert_eq!(out, vec!&#91;1, 2, 3, 4, 6]);\n    }\n\n    #&#91;test]\n    fn first_longer() {\n        let out: Vec&lt;i32> = zigzag_merge(vec!&#91;1, 3, 5].into_iter(), vec!&#91;2, 4].into_iter()).collect();\n        assert_eq!(out, vec!&#91;1, 2, 3, 4, 5]);\n    }\n\n    #&#91;test]\n    fn second_empty() {\n        let out: Vec&lt;i32> = zigzag_merge(vec!&#91;1, 2, 3].into_iter(), vec!&#91;].into_iter()).collect();\n        assert_eq!(out, vec!&#91;1, 2, 3]);\n    }\n    #&#91;test]\n    fn forth_as_per_instructions() {\n        let out: Vec&lt;i32> = zigzag_merge(vec!&#91;1, 2, 3].into_iter(), vec!&#91;].into_iter()).collect();\n        assert_eq!(out, vec!&#91;1,]);\n    }\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Test Results:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I have included all 4 asserts from the challenge and added a 5th one which is the version of the 4th that passes. Here are the results.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>running 5 tests\ntest tests::both_equal_length ... ok\ntest tests::second_empty ... ok\ntest tests::first_longer ... ok\ntest tests::second_longer ... ok\ntest tests::forth_as_per_instructions ... FAILED\n\nfailures:\n\n---- tests::forth_as_per_instructions stdout ----\n\nthread 'tests::forth_as_per_instructions' (28510400) panicked at src\/main.rs:91:9:\nassertion `left == right` failed\n  left: &#91;1, 2, 3]\n right: &#91;1]\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n\n\nfailures:\n    tests::forth_as_per_instructions<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Code Repo:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The code can be found in this <a href=\"https:\/\/github.com\/mariusb\/rb94_zigzag_merge\" target=\"_blank\" rel=\"noreferrer noopener\">Github Repo<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The task involves creating an iterator that merges two input iterators of i32 by alternating values from each until both are exhausted. The solution includes a Zigzag struct with a next method for alternating yields. Test cases verify correct functionality but one assertion fails regarding handling an empty iterator.<\/p>\n","protected":false},"author":1,"featured_media":973,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_seo_schema_type":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[188],"tags":[189,190],"class_list":["post-974","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-rust","tag-rust","tag-rust_bytes"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mariusb.net\/blog\/wp-content\/uploads\/2025\/11\/RB94_ZigZag_Merge.png?fit=646%2C908&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p1SHVw-fI","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/posts\/974","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/comments?post=974"}],"version-history":[{"count":13,"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/posts\/974\/revisions"}],"predecessor-version":[{"id":987,"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/posts\/974\/revisions\/987"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/media\/973"}],"wp:attachment":[{"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/media?parent=974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/categories?post=974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mariusb.net\/blog\/wp-json\/wp\/v2\/tags?post=974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}