Skip to content

Instantly share code, notes, and snippets.

@heyajulia
Created May 30, 2021 11:07
Show Gist options
  • Save heyajulia/7bb6f451edfb10f7d94d2338d989c3eb to your computer and use it in GitHub Desktop.
Save heyajulia/7bb6f451edfb10f7d94d2338d989c3eb to your computer and use it in GitHub Desktop.
# Usage: echo words | raku scrambler.raku
sub scramble-word(Str $word --> Str) {
if $word.chars <= 3 {
return $word;
}
my @letters = $word.comb;
my $first-letter = @letters[0];
my $last-letter = @letters[*-1];
my @middle-letters = @letters[1..*-2];
my @scrambled-word = @middle-letters.pick(@middle-letters);
@scrambled-word.prepend: $first-letter;
@scrambled-word.push: $last-letter;
return @scrambled-word.join;
}
slurp()
.words
.map(-> $word { scramble-word $word })
.join(" ")
.print;
@heyajulia
Copy link
Author

Cool!

To make things simpler:

my $first-letter = @letters.shift;
my $last-letter = @letters.pop;
return $first-letter ~ @letters.pick(*).join ~ $last-letter;

Wow, pretty cool. Thanks @lizmat!

How does @letters.pick(*) work?

@lizmat
Copy link

lizmat commented May 30, 2021

Well, * means "whatever", so in this context it just means "until exhausted".

Or is that not what you meant?

@heyajulia
Copy link
Author

Oohhh, that makes sense. That's really clever.

@holli-holzer
Copy link

holli-holzer commented May 30, 2021

Did you learn about multis yet?

multi scramble-word(Str $word, Int $keep where $word.chars >= 2 + ( 2 * $keep ) = 1 --> Str) {
    join( '', flat .head($keep), .skip.head(*-$keep).pick(*), .tail($keep) ) with $word.comb.cache
}

multi scramble-word(Str $word, | --> Str) {
    $word
}

This solves the problem for arbitrary characters to keep at the start and the end, the default is 1

@heyajulia
Copy link
Author

Cool!

@gfldex
Copy link

gfldex commented May 31, 2021

sub scramble-word(Str $word) {
    return $word if $word.chars ≤ 3;

    $word.comb[0,1..*-2,*-1].&(-> ($a, $b, $c){ $a, $b.pick(*), $c})[*;*].join()
}

This is my take and yes, I used to code in Perl. :)

@gfldex
Copy link

gfldex commented Jun 1, 2021

The above can be simplyfied to:

sub scramble-word(Str $word) {
     (.[0], .[1..*-2].pick(*), .[*-1])[*;*].join with $word.comb
}

However, it can not be simply explained. :)

@holli-holzer
Copy link

[*;*] flattens the list. It can be replaced by .flat. But why does it work that way?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment