/now
projects
ramblings
smol projects

unmix my strings

17.11.2023 2 min read

lPaeesh le pemu mnxit ehess rtnisg! Oh, sorry, that was supposed to say: Please help me unmix these strings!

Somehow my strings have all become mixed up; every pair of characters has been swapped. Help me undo this so I can understand my strings again.

unmix("123456") ➞ "214365"
unmix("hTsii  s aimex dpus rtni.g") ➞ "This is a mixed up string."
unmix("badce") ➞ "abcde"

Crystal:

def unmix(s : String)
  s.chars.map_with_index { |curr, i|
    next unless i % 2 == 0
    nex = s[i + 1] if i != s.size - 1
    "#{nex}#{curr}"
  }.reject { |el| el.nil? }.join
end

We use map_with_index to go through the array. We reverse the strings on the way up, and pass if the index is odd. When we’re done, we have some Nil elements from when we called next, so we filter those out. (Crystal has a chunk method, but I’m not sure how that works.)

Nim:

func unmix(s: string): string =
    let sArr = s.toSeq
    let collected = collect(newSeq):
        for i in 0 ..< sArr.len:
            if i mod 2 != 0: continue
            if sArr.len mod 2 != 0 and i == s.len - 1: $sArr[i]
            else: sArr[i + 1] & sArr[i]
    collected.join("")

For Nim, we have to use collect, which is similar to a list comprehension? …according to the docs. It’s my first time using collect - I didn’t want to mutate the data, so I had to rummage through Nim’s stdlib for something I could use.

Raku:

sub unmix($s) {
    do for $s.comb -> $a, $b = "" {$b ~ $a}.join;
}

Er… once again, the Raku version is awfully concise. From the docs:

A for loop can produce a List of the values produced by each run of the attached block. To capture these values, put the for loop in parenthesis or assign them to an array

We can provide a default argument so it doesn’t mess up on odd numbers, and we no longer have to keep track of i. Quite nice.

Javascript:

function unmix(s: string) {
  return s.split("").reduce((acc, curr, i) => {
    if (s.length % 2 !== 0 && i == s.length - 1) {
      return `${acc}${curr}`;
    }

    if (i % 2 == 0) {
      return `${acc}${s[i + 1]}${curr}`;
    }

    return acc;
  }, "");
}
Built with Astro and Tailwind 🚀