The Weekly Challenge 335

Character Intersection & Tic-Tac-Toe!

Original Challenge Link

Task 1: Common Characters

"Intersect All: What Characters Share Every Word?"

Given an array of lowercase words, return every character that appears in each word, preserving multiplicity.

The Strategy: Build a frequency map from the first word. For each subsequent word, update to the minimum count per character. Remove characters with zero count. The result repeats each remaining character by its minimum frequency.
Perl Implementation
sub common_characters {
    my (@words) = @_;
    return () if !@words;

    my %common;
    $common{$_}++ for split //, $words[0];

    for my $word ( @words[ 1 .. $#words ] ) {
        my %freq;
        $freq{$_}++ for split //, $word;
        for my $char ( keys %common ) {
            $common{$char} = exists $freq{$char}
              ? min( $common{$char}, $freq{$char} ) : 0;
        }
        delete @common{ grep { $common{$_} == 0 } keys %common };
    }

    my @result;
    for my $char ( sort keys %common ) {
        push @result, ($char) x $common{$char};
    }
    return @result;
}
Python Implementation
from collections import Counter

def common_characters(words: list[str]) -> list[str]:
    """Characters common to all words, preserving multiplicity."""
    if not words:
        return []
    common = Counter(words[0])
    for word in words[1:]:
        freq = Counter(word)
        for ch in list(common):
            if ch in freq:
                common[ch] = min(common[ch], freq[ch])
            else:
                del common[ch]
    return sorted(common.elements())

Task 2: Find Winner

"Tic-Tac-Toe: Who Takes the Board?"

Given a sequence of tic-tac-toe moves (alternating between players A and B), determine if there is a winner, a draw, or if the game is still pending.

The Strategy: Place moves on a 3x3 board, alternating players. After all moves, check all 8 lines (3 rows, 3 columns, 2 diagonals) for a winner. If a winner exists, return the player. If all 9 cells filled without a winner, return Draw. Otherwise Pending.
Perl Implementation
sub find_winner {
    my (@moves) = @_;
    my @board  = map { [ ('_') x 3 ] } 1 .. 3;
    my $player = 'A';
    for my $move (@moves) {
        my ( $row, $col ) = @$move;
        $board[$row][$col] = $player;
        $player = $player eq 'A' ? 'B' : 'A';
    }

    my $winner = _check_winner( \\@board );
    return $winner if $winner;
    return @moves == 9 ? 'Draw' : 'Pending';
}
Python Implementation
def find_winner(moves: list[list[int]]) -> str:
    """Determine tic-tac-toe outcome from move sequence."""
    board = [["_"] * 3 for _ in range(3)]
    player = "A"
    for r, c in moves:
        board[r][c] = player
        player = "B" if player == "A" else "A"

    lines = []
    lines.extend(board)  # rows
    lines.extend([[board[r][c] for r in range(3)] for c in range(3)])  # cols
    lines.append([board[i][i] for i in range(3)])  # diag
    lines.append([board[i][2 - i] for i in range(3)])  # anti-diag

    for line in lines:
        if line[0] != "_" and line[0] == line[1] == line[2]:
            return line[0]
    return "Draw" if len(moves) == 9 else "Pending"