unmix my strings
17.11.2023 2 min readlPaeesh 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 aList
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;
}, "");
}