aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-08-23 23:28:36 +0100
committerGitHub <noreply@github.com>2025-08-23 23:28:36 +0100
commit41e1365fbbcfd547bd3e813afca23e7a32086b40 (patch)
tree1a749a7d8b51e7ce3b737010088f30d2761aac0c
parenta923e9810522db4d2ade458a4e9b670976f049ae (diff)
parent5fded4c63588ee61d55e38c0698abc6bd8a20e4a (diff)
downloadperlweeklychallenge-club-41e1365fbbcfd547bd3e813afca23e7a32086b40.tar.gz
perlweeklychallenge-club-41e1365fbbcfd547bd3e813afca23e7a32086b40.tar.bz2
perlweeklychallenge-club-41e1365fbbcfd547bd3e813afca23e7a32086b40.zip
Merge pull request #12557 from simongreen-net/master
sgreen solutions to challenge 335
-rw-r--r--challenge-335/sgreen/README.md4
-rw-r--r--challenge-335/sgreen/blog.txt1
-rwxr-xr-xchallenge-335/sgreen/perl/ch-1.pl35
-rwxr-xr-xchallenge-335/sgreen/perl/ch-2.pl84
-rwxr-xr-xchallenge-335/sgreen/python/ch-1.py37
-rwxr-xr-xchallenge-335/sgreen/python/ch-2.py71
-rwxr-xr-xchallenge-335/sgreen/python/test.py30
7 files changed, 260 insertions, 2 deletions
diff --git a/challenge-335/sgreen/README.md b/challenge-335/sgreen/README.md
index c346b56b6b..261fc0ba68 100644
--- a/challenge-335/sgreen/README.md
+++ b/challenge-335/sgreen/README.md
@@ -1,3 +1,3 @@
-# The Weekly Challenge 334
+# The Weekly Challenge 335
-Blog: [Perl has classes now 👍](https://dev.to/simongreennet/weekly-challenge-perl-has-classes-now-4n8e)
+Blog: [The Common Winner](https://dev.to/simongreennet/weekly-challenge-the-common-winner-57ka)
diff --git a/challenge-335/sgreen/blog.txt b/challenge-335/sgreen/blog.txt
new file mode 100644
index 0000000000..b6adb47a7f
--- /dev/null
+++ b/challenge-335/sgreen/blog.txt
@@ -0,0 +1 @@
+https://dev.to/simongreennet/weekly-challenge-the-common-winner-57ka \ No newline at end of file
diff --git a/challenge-335/sgreen/perl/ch-1.pl b/challenge-335/sgreen/perl/ch-1.pl
new file mode 100755
index 0000000000..222a385977
--- /dev/null
+++ b/challenge-335/sgreen/perl/ch-1.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature 'say';
+use experimental 'signatures';
+
+use List::Util 'min';
+
+sub main (@word_array) {
+ my @freq_array = ();
+ my @solution = ();
+
+ # Turn the words into a frequency dict
+ foreach my $word (@word_array) {
+ my %freq = ();
+ foreach my $letter ( split //, $word ) {
+ $freq{$letter}++;
+ }
+ push @freq_array, \%freq;
+ }
+
+ # Find the minimum frequency of each character across all words
+ foreach my $letter ( sort keys %{ $freq_array[0] } ) {
+ my $min_freq = min( map { $_->{$letter} // 0 } @freq_array );
+ if ( $min_freq > 0 ) {
+ # If the minimum frequency is greater than zero, add it to the solution
+ push @solution, ($letter) x $min_freq;
+ }
+ }
+
+ say '(' . join( ', ', map { "\"$_\"" } @solution ) . ')';
+}
+
+main(@ARGV);
diff --git a/challenge-335/sgreen/perl/ch-2.pl b/challenge-335/sgreen/perl/ch-2.pl
new file mode 100755
index 0000000000..a37e5d5c99
--- /dev/null
+++ b/challenge-335/sgreen/perl/ch-2.pl
@@ -0,0 +1,84 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature 'say';
+use experimental 'signatures';
+
+sub check_winner ($board_ref) {
+ my @board = @$board_ref;
+
+ # use Data::Dumper; say Dumper(\@board); # Debugging line
+ # Check rows and columns
+ foreach my $i ( 0 .. 2 ) {
+ if ( $board[$i][0] eq $board[$i][1] eq $board[$i][2] ne '_' ) {
+ return $board[$i][0];
+ }
+ if ( $board[0][$i] eq $board[1][$i] eq $board[2][$i] ne '_' ) {
+ return $board[0][$i];
+ }
+ }
+
+ # Check diagonals
+ if ( $board[0][0] eq $board[1][1] eq $board[2][2] ne '_' ) {
+ return $board[0][0];
+ }
+ if ( $board[2][0] eq $board[1][1] eq $board[0][2] ne '_' ) {
+ return $board[2][0];
+ }
+
+ return undef;
+}
+
+sub main (@ints) {
+ # Turn the input into pairs of moves
+ my @moves = ();
+ for ( my $i = 0 ; $i < $#ints ; $i += 2 ) {
+ push @moves, [ $ints[$i], $ints[ $i + 1 ] ];
+ }
+
+ # Initialize the board
+ my @board = ( [ '_', '_', '_' ], [ '_', '_', '_' ], [ '_', '_', '_' ], );
+
+ # Player A starts first
+ my $current_player = 'A';
+
+ foreach my $move (@moves) {
+ # Check the move is on the board and not already taken
+ if ( $move->[0] < 0
+ or $move->[0] > 2
+ or $move->[1] < 0
+ or $move->[1] > 2 )
+ {
+ die "Invalid move (out of bounds)\n";
+ }
+ if ( $board[ $move->[0] ][ $move->[1] ] ne '_' ) {
+ die "Invalid move (already taken)\n";
+ }
+
+ # Place the move on the board
+ $board[ $move->[0] ][ $move->[1] ] = $current_player;
+
+ # Check for a win
+ my $result = check_winner( \@board );
+ if ($result) {
+ say $result;
+ return;
+ }
+
+ # Switch players
+ $current_player = $current_player eq 'A' ? 'B' : 'A';
+ }
+
+ # We've made all moves, check for pending or draw
+ foreach my $row (@board) {
+ if ( grep { $_ eq '_' } @$row ) {
+ say 'Pending';
+ return;
+ }
+ }
+
+ say 'Draw';
+}
+
+main(@ARGV);
diff --git a/challenge-335/sgreen/python/ch-1.py b/challenge-335/sgreen/python/ch-1.py
new file mode 100755
index 0000000000..48a7ce776a
--- /dev/null
+++ b/challenge-335/sgreen/python/ch-1.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+
+import sys
+from collections import Counter
+
+
+def common_characters(word_list: list[str]) -> list[str]:
+ """Find common characters in all words.
+
+ Args:
+ word_list (list[str]): List of words to compare.
+
+ Returns:
+ list[str]: List of common characters sorted alphabetically.
+ """
+ solution = []
+
+ # Turn the words into a frequency dict
+ freq_list = [Counter(word) for word in word_list]
+
+ # Find the minimum frequency of each character across all words
+ for letter in sorted(freq_list[0]):
+ min_freq = min(freq[letter] for freq in freq_list)
+ if min_freq > 0:
+ # ... and add it to the solution
+ solution.extend(letter * min_freq)
+
+ return solution
+
+
+def main():
+ result = common_characters(sys.argv[1:])
+ print(result)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/challenge-335/sgreen/python/ch-2.py b/challenge-335/sgreen/python/ch-2.py
new file mode 100755
index 0000000000..bf9b286364
--- /dev/null
+++ b/challenge-335/sgreen/python/ch-2.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+
+import sys
+
+
+def check_winner(board: list[list[str]]) -> str | None:
+ """
+ Check the current state of the Tic Tac Toe board for a winner.
+
+ Args:
+ board (list[list[str]]): The current state of the Tic Tac Toe board
+
+ Returns:
+ str | None: 'A' if player A wins, 'B' if player B wins, or None if no winner yet
+ """
+ # Check rows and columns
+ for i in range(3):
+ if board[i][0] == board[i][1] == board[i][2] != '_':
+ return board[i][0]
+ if board[0][i] == board[1][i] == board[2][i] != '_':
+ return board[0][i]
+
+ # Check diagonals
+ if board[0][0] == board[1][1] == board[2][2] != '_':
+ return board[0][0]
+ if board[0][2] == board[1][1] == board[2][0] != '_':
+ return board[0][2]
+
+ return None
+
+
+def find_winner(moves: list[list[int]]) -> str:
+ # Initialize the board
+ board = [['_' for _ in range(3)] for _ in range(3)]
+
+ # Player A starts first
+ current_player = 'A'
+
+ for move in moves:
+ # Check the move is on the board and not already taken
+ if not 0 <= move[0] <= 2 and not 0 <= move[1] <= 2:
+ return "Invalid move (out of bounds)"
+ if board[move[0]][move[1]] != '_':
+ return "Invalid move (already taken)"
+
+ # Place the move on the board
+ board[move[0]][move[1]] = current_player
+
+ # Check for a win
+ result = check_winner(board)
+ if result:
+ return result
+
+ # Switch players
+ current_player = 'B' if current_player == 'A' else 'A'
+
+ # We've made all moves, check for pending or draw
+ return "Pending" if any('_' in row for row in board) else "Draw"
+
+
+def main():
+ # Convert input into integers, and pair them up
+ array = [int(n) for n in sys.argv[1:]]
+ moves = [array[i:i + 2] for i in range(0, len(array), 2)]
+
+ result = find_winner(moves)
+ print(result)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/challenge-335/sgreen/python/test.py b/challenge-335/sgreen/python/test.py
new file mode 100755
index 0000000000..2f4a95cbef
--- /dev/null
+++ b/challenge-335/sgreen/python/test.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+
+import unittest
+ch_1 = __import__('ch-1')
+ch_2 = __import__('ch-2')
+
+
+class TestClass(unittest.TestCase):
+ def test_ch_1(self):
+ self.assertEqual(ch_1.common_characters(["bella", "label", "roller"]), ["e", "l", "l"])
+ self.assertEqual(ch_1.common_characters(["cool", "lock", "cook"]), ["c", "o"])
+ self.assertEqual(ch_1.common_characters(["hello", "world", "pole"]), ["l", "o"])
+ self.assertEqual(ch_1.common_characters(["abc", "def", "ghi"]), [])
+ self.assertEqual(ch_1.common_characters(["aab", "aac", "aaa"]), ["a", "a"])
+
+ def test_ch_2(self):
+ moves_1 = [[0,0],[2,0],[1,1],[2,1],[2,2]]
+ moves_2 = [[0,0],[1,1],[0,1],[0,2],[1,0],[2,0]]
+ moves_3 = [[0,0],[1,1],[2,0],[1,0],[1,2],[2,1],[0,1],[0,2],[2,2]]
+ moves_4 = [[0,0],[1,1]]
+ moves_5 = [[1,1],[0,0],[2,2],[0,1],[1,0],[0,2]]
+ self.assertEqual(ch_2.find_winner(moves_1), "A")
+ self.assertEqual(ch_2.find_winner(moves_2), "B")
+ self.assertEqual(ch_2.find_winner(moves_3), "Draw")
+ self.assertEqual(ch_2.find_winner(moves_4), "Pending")
+ self.assertEqual(ch_2.find_winner(moves_5), "B")
+
+
+if __name__ == '__main__':
+ unittest.main()