Task 1: Complex Number
You are given two complex numbers as strings. Write a script to return the multiplication of the given complex numbers using the formula: (a + bi) x (c + di) = (ac - bd) + (ad + bc)i.
Method Explanation
The challenge specifies a particular string format for complex numbers, including negative components like 1+(-1)i or 50+(-20)i.
- Parsing: We use regular expressions to extract the real part $a$ and imaginary coefficient $b$. The regex accommodates both positive coefficients (
3+4i) and parenthesized negative coefficients (3+(-4)i). - Arithmetic: We evaluate: $$\text{Real part} = ac - bd$$ $$\text{Imaginary part} = ad + bc$$
- Formatting: If the resulting imaginary part is negative, we format it as
Real+(-Imag)i, otherwise asReal+Imagito conform precisely to the test suite format.
Perl Implementation
sub _parse_complex ($s) {
if ( $s =~ /\A\s*([+-]?\d+)\s*\+\s*(?:\(([-+]?\d+)\)|([-+]?\d+))\s*i\s*\z/ ) {
my $real = $1;
my $imag = defined $2 ? $2 : $3;
return ( int($real), int($imag) );
}
die "Invalid complex number format: $s";
}
sub _format_complex ( $real, $imag ) {
if ( $imag < 0 ) {
return "$real+($imag)i";
}
return "$real+${imag}i";
}
sub multiply_complex ( $num1, $num2 ) {
( $num1, $num2 ) = $STRS_CHECK->( $num1, $num2 );
my ( $a, $b ) = _parse_complex($num1);
my ( $c, $d ) = _parse_complex($num2);
my $real = $a * $c - $b * $d;
my $imag = $a * $d + $b * $c;
return _format_complex( $real, $imag );
}
Python Implementation
def _parse_complex(s: str) -> tuple[int, int]:
"""Parse complex string in format a+bi or a+(-b)i."""
match = re.match(r"^\s*([+-]?\d+)\s*\+\s*(?:\(([-+]?\d+)\)|([-+]?\d+))\s*i\s*$", s)
if not match:
raise ValueError(f"Invalid complex number format: {s}")
real_str = match.group(1)
imag_str = match.group(2) if match.group(2) is not None else match.group(3)
return int(real_str), int(imag_str)
def _format_complex(real: int, imag: int) -> str:
"""Format complex number to match specification."""
if imag < 0:
return f"{real}+({imag})i"
return f"{real}+{imag}i"
def multiply_complex(num1: str, num2: str) -> str:
"""Multiply two complex numbers and return formatted product."""
a, b = _parse_complex(num1)
c, d = _parse_complex(num2)
real = a * c - b * d
imag = a * d + b * c
return _format_complex(real, imag)
Task 2: Word Squares
You are given a list of equal length words. Write a script to arrange a set of words into a grid that reading across any row gives the exact same word as reading down its corresponding column.
Method Explanation
An $N \times N$ word square requires that for all $0 \le r, c < N$, the character at grid position $(r, c)$ equals the character at $(c, r)$.
This property gives us an immediate search pruning strategy:
- Suppose we have successfully selected the first $k$ rows of the word square.
- The $(k+1)$-th row must start with the prefix formed by taking column $k$ of the already chosen rows: $$\text{required\_prefix} = \text{grid}[0][k] + \text{grid}[1][k] + \dots + \text{grid}[k-1][k]$$
- By pre-indexing all dictionary words by every possible prefix (using a hash map or Trie), we can instantly filter candidates for row $k$ in $O(1)$ lookup time.
- We use depth-first backtracking to find the first complete square configuration.
Perl Implementation
sub word_squares ($words) {
($words) = $WORDS_CHECK->($words);
return [] if !@$words;
my $n = length( $words->[0] );
for my $w (@$words) {
die 'All words must have the same length' if length($w) != $n;
}
my %prefix_map;
for my $w (@$words) {
for my $len ( 0 .. $n ) {
my $p = substr( $w, 0, $len );
push @{ $prefix_map{$p} }, $w;
}
}
my @current_square;
my $result;
my $search;
$search = sub ($step) {
return 1 if defined $result;
if ( $step == $n ) {
$result = [@current_square];
return 1;
}
my $required_prefix = '';
for my $row ( 0 .. $step - 1 ) {
$required_prefix .= substr( $current_square[$row], $step, 1 );
}
my $candidates = $prefix_map{$required_prefix} // [];
for my $word (@$candidates) {
push @current_square, $word;
$search->( $step + 1 );
return 1 if defined $result;
pop @current_square;
}
return 0;
};
$search->(0);
return $result // [];
}
Python Implementation
def word_squares(words: Sequence[str]) -> list[str]:
"""Find an N x N word square from the given words."""
if not words:
return []
n = len(words[0])
for w in words:
if len(w) != n:
raise ValueError("All words must have the same length")
prefix_map: dict[str, list[str]] = defaultdict(list)
for w in words:
for length in range(n + 1):
prefix_map[w[:length]].append(w)
current_square: list[str] = []
result: list[str] | None = None
def search(step: int) -> bool:
nonlocal result
if result is not None:
return True
if step == n:
result = list(current_square)
return True
required_prefix = "".join(current_square[row][step] for row in range(step))
for word in prefix_map.get(required_prefix, []):
current_square.append(word)
if search(step + 1):
return True
current_square.pop()
return False
search(0)
return result if result is not None else []