Kolakoski Wins
with Raku

by Arne Sommer

Kolakoski Wins with Raku

[388] Published 18. January 2026.

This is my response to The Weekly Challenge #356.

#356.1 Kolakoski Sequence You are given an integer, $int > 3.

Write a script to generate the Kolakoski Sequence of given length $int and return the count of 1 in the generated sequence. Please follow the wikipedia page for more information.

Example 1:
Input: $int = 4
Output: 2

(1)(22)(11)(2) => 1221
Example 2:
Input: $int = 5
Output: 3

(1)(22)(11)(2)(1) => 12211
Example 3:
Input: $int = 6
Output: 3

(1)(22)(11)(2)(1)(22) => 122112
Example 4:
Input: $int = 7
Output: 4

(1)(22)(11)(2)(1)(22)(1) => 1221121
Example 5:
Input: $int = 8
Output: 4

(1)(22)(11)(2)(1)(22)(1)(22) => 12211212

File: kolakoski_sequence
#! /usr/bin/env raku

unit sub MAIN (UInt $int where $int > 3, :v(:$verbose));  # [1]

my $kolakoski := gather                                   # [2]
{
  take 1;                                                 # [3]
  take 22;                                                # [4]

  my @length = (2,);                                      # [5]
  my $curr   = 1;                                         # [6]
  
  loop                                                    # [7]
  {
    my $count = @length.shift;                            # [8]

    if $count == 1                                        # [9]
    {
      take $curr;                                         # [9a]
      @length.push($curr);                                # [9b]
    }
    else # $count == 2                                    # [10]
    {
      take "$curr$curr".Int;                              # [10a]
      @length.append($curr, $curr);                       # [10b]
    }

    $curr = $curr == 1 ?? 2 !! 1;                         # [11]
  }
}

my $seq  = $kolakoski[^$int];                             # [12]
my @ones = $seq.grep( * == 1 | 11 );                      # [13]

if $verbose
{
  say ": Sequence:  { $seq.raku }";
  say ": Ones:      { @ones.raku }";
}

say @ones.elems;                                          # [14]

[1] Ensure an unsigned (UInt) integer greater than 3.

[2] This task is suitable for gather/take, where we use gather to collect the parts (the digit blocks).

See my Raku Gather, I Take article or docs.raku.org/language/control#gather/take for more information about gather/take.

[3] The first value in the sequence.

[4] The second one. Note that we return both digits as one number, and not separately as the wikipedia article says.

[5] The length (as in «how many digits») of the upcoming element(s) in the sequence.

[6] The current digit to use in the sequence.

[7] An eternal loop. This works out, as the sequence (in [2]) is lazy, only evaluating the values (from the start) to the requested one(s) (in [13]).

[8] Get the number of digits to use for the current value.

[9] Only one digit? Return it [9a] and add the length to the length buffer [9b].

[10] Two digits? Return them, by coercing the two-digit string to an integer [10a]. (We could have multiplied the digit with 11 instead.) and add the length twice (as we have two digits here) to the length buffer [10b].

[11] Change the current digit from 1 to 2 or vice versa, ready for the next iteration.

[12] Get the requested number of elements from the sequence.

[13] Keep the «1» and «11» elements only.

[14] Print the number of elements (from [13]) .

Running it:

$ ./kolakoski_sequence 4
2

$ ./kolakoski_sequence 5
3

$ ./kolakoski_sequence 6
3

$ ./kolakoski_sequence 7
4

$ ./kolakoski_sequence 8
4

Looking good.

With verbose mode:

$ ./kolakoski_sequence -v 4
: Sequence: $(1, 22, 11, 2)
: Ones:     [1, 11]
2

$ ./kolakoski_sequence -v 5
: Sequence: $(1, 22, 11, 2, 1)
: Ones:     [1, 11, 1]
3

$ ./kolakoski_sequence -v 6
: Sequence: $(1, 22, 11, 2, 1, 22)
: Ones:     [1, 11, 1]
3

$ ./kolakoski_sequence -v 7
: Sequence: $(1, 22, 11, 2, 1, 22, 1)
: Ones:     [1, 11, 1, 1]
4

$ ./kolakoski_sequence -v 8
: Sequence: $(1, 22, 11, 2, 1, 22, 1, 22)
: Ones:     [1, 11, 1, 1]
4

#356.2 Who Wins It's NFL playoff time. Since the 2020 season, seven teams from each of the league’s two conferences (AFC and NFC) qualify for the playoffs based on regular season winning percentage, with a tie-breaking procedure if required. The top team in each conference receives a first-round bye, automatically advancing to the second round.

The following games are played. Some times the games are played in a different order. To make things easier, assume the order is always as below.

- Week 1: Wild card playoffs
  - Team 1 gets a bye
  - Game 1: Team 2 hosts Team 7
  - Game 2: Team 3 hosts Team 6
  - Game 3: Team 4 hosts Team 5
- Week 2: Divisional playoffs
  - Game 4: Team 1 hosts the third seeded winner from the previous week.
  - Game 5: The highest seeded winner from the previous week hosts the
            second seeded winner.
- Week 3: Conference final
  - Game 6: The highest seeded winner from the previous week hosts the
            other winner
You are given a six character string containing only H (home) and A away which has the winner of each game. Which two teams competed in the the conference final and who won?

Example 1:
NFC Conference 2024/5. Teams were Detroit, Philadelphia, Tampa Bay, Los Angeles Rams, Minnesota, Washington and Green Bay. Philadelphia - seeded second - won.

Input: $results = "HAHAHH"
Output: "Team 2 defeated Team 6"

In Week 1, Team 2 (home) won against Team 7, Team 6 (away) defeated
Team 3 and Team 4 (home) were victorious over Team 5. This means the
second week match ups are Team 1 at home to Team 6, and Team 2 hosted
Team 4.

In week 2, Team 6 (away) won against Team 1, while Team 2 (home)
beat Team 4. The final week was Team 2 hosting Team 6

In the final week, Team 2 (home) won against Team 6.
Example 2:
Input: $results = "HHHHHH"
Output: "Team 1 defeated Team 2"

Example 3:
AFC Conference 2021/2. Teams were Tennessee, Kansas City, Buffalo, Cincinnati, Las Vegas, New England and Pittsburgh. Cincinnati - seeded fourth - won.

Input: $results = "HHHAHA"
Output: "Team 4 defeated Team 2"
Example 4:
Input: $results = "HAHAAH"
Output: "Team 4 defeated Team 6"

Example 5:
NFC Conference 2020/1. Teams were Green Bay, New Orleans, Seattle, Washington, Tampa Bay, Los Angeles Rams and Chicago. Tampa Bay - seeded fifth - won.

Input: $results = "HAAHAA"
Output: "Team 5 defeated Team 1"
File: who-wins
#! /usr/bin/env raku

unit sub MAIN ($results where * ~~ /^ <[HA]> ** 6 $/,            # [1]
              :n($nice),                                         # [2]
              :v(:$verbose));


my @results = $results.comb;                                     # [3]

## Week 1 ##

my ($winner1, $looser1) = @results[0] eq "H" ?? (2,7) !! (7,2);  # [4]
my ($winner2, $looser2) = @results[1] eq "H" ?? (3,6) !! (6,3);  # [4a]
my ($winner3, $looser3) = @results[2] eq "H" ?? (4,5) !! (5,4);  # [4b]

my @seeded1 = ($winner1, $winner2, $winner3).sort;               # [5]

## Week 2 ##

my ($winner4, $looser4) = @results[3] eq "H"
  ?? (1, @seeded1[2]) !! (@seeded1[2], 1);                       # [6]

my ($winner5, $looser5) = @results[4] eq "H"
  ?? (@seeded1[0], @seeded1[1]) !! (@seeded1[1], @seeded1[0]);   # [6a]

my @seeded2 = ($winner4, $winner5).sort;                         # [7]

## Week 3 ##

my ($winner6, $looser6) = @results[5] eq "H"
  ?? (@seeded2[0], @seeded2[1]) !! (@seeded2[1], @seeded2[0]);   # [8]

if $verbose
{
  my %ha = ( H => 'home', A => 'away' );

  say ": Week 1: Team $winner1 (%ha{@results[0]}) won against team $looser1";
  say ": Week 1: Team $winner2 (%ha{@results[1]}) won against team $looser2";
  say ": Week 1: Team $winner3 (%ha{@results[2]}) won against team $looser3";
  say ": Week 2: Team $winner4 (%ha{@results[3]}) won against team $looser4";
  say ": Week 2: Team $winner5 (%ha{@results[4]}) won against team $looser5";
}

say "Team $winner6 { $nice ?? "won against" !! "defeated" } \
  Team $looser6";                                                # [9]

[1] The result string, containing «A»s and «H»s only, six in total.

[2] Nice mode; shown at the very end of this article.

[3] Get the result as an array of individual characters.

[4] Get the winner and looser of the first, second [4a] and third [4b] games.

[5] Get the list of seeded winners from the first week.

[6] Get the winner and looser of the fourth and fifth [6a] games.

[7] Get the list of seeded winners from the second week.

[8] Get the overall winner and looser.

[9] Print the result of the final game.

Running it:

$ ./who-wins -v HAHAHH
Team 2 defeated Team  6

$ ./who-wins -v HHHHHH
Team 1 defeated Team  2

$ ./who-wins -v HHHAHA
Team 4 defeated Team  2

$ ./who-wins -v HAHAAH
Team 4 defeated Team  6

$ ./who-wins -v HAAHAA
Team 5 defeated Team  1

Looking good.

With verbose mode:

$ ./who-wins -v HAHAHH
: Week 1: Team 2 (home) won against team 7
: Week 1: Team 3 (away) won against team 6
: Week 1: Team 4 (home) won against team 5
: Week 2: Team 6 (away) won against team 1
: Week 2: Team 2 (home) won against team 4
Team 2 defeated Team  6

$ ./who-wins -v HHHHHH
: Week 1: Team 2 (home) won against team 7
: Week 1: Team 3 (home) won against team 6
: Week 1: Team 4 (home) won against team 5
: Week 2: Team 1 (home) won against team 4
: Week 2: Team 2 (home) won against team 3
Team 1 defeated Team  2

$ ./who-wins -v HHHAHA
: Week 1: Team 2 (home) won against team 7
: Week 1: Team 3 (home) won against team 6
: Week 1: Team 4 (home) won against team 5
: Week 2: Team 4 (away) won against team 1
: Week 2: Team 2 (home) won against team 3
Team 4 defeated Team  2

$ ./who-wins -v HAHAAH
: Week 1: Team 2 (home) won against team 7
: Week 1: Team 3 (away) won against team 6
: Week 1: Team 4 (home) won against team 5
: Week 2: Team 6 (away) won against team 1
: Week 2: Team 4 (away) won against team 2
Team 4 defeated Team  6

$ ./who-wins -v HAAHAA
: Week 1: Team 2 (home) won against team 7
: Week 1: Team 3 (away) won against team 6
: Week 1: Team 4 (away) won against team 5
: Week 2: Team 1 (home) won against team 6
: Week 2: Team 5 (away) won against team 2
Team 5 defeated Team  1

Use the «-n» (or «-nice») command line option to treat the loosing (i.e. non-winning) team nicer:

$ ./who-wins HAAHAA
Team 5 defeated Team  1

$ ./who-wins -n HAAHAA
Team 5 won against Team 1

And that's it.