aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <mohammad.anwar@yahoo.com>2025-08-22 00:14:43 +0100
committerMohammad Sajid Anwar <mohammad.anwar@yahoo.com>2025-08-22 00:14:43 +0100
commitec6cd1c30040e2337fd679057608aba79aa17427 (patch)
tree48753ff62d01d340bcbd2b3a1fcc637d3afe6807
parente70ffde9646ffed0d9a0e955099041c25c74e306 (diff)
downloadperlweeklychallenge-club-ec6cd1c30040e2337fd679057608aba79aa17427.tar.gz
perlweeklychallenge-club-ec6cd1c30040e2337fd679057608aba79aa17427.tar.bz2
perlweeklychallenge-club-ec6cd1c30040e2337fd679057608aba79aa17427.zip
- Added solutions by Ulrich Rieke.
-rwxr-xr-xchallenge-335/ulrich-rieke/cpp/ch-1.cpp76
-rwxr-xr-xchallenge-335/ulrich-rieke/cpp/ch-2.cpp86
-rwxr-xr-xchallenge-335/ulrich-rieke/haskell/ch-1.hs45
-rwxr-xr-xchallenge-335/ulrich-rieke/haskell/ch-2.hs81
-rwxr-xr-xchallenge-335/ulrich-rieke/perl/ch-1.pl60
-rwxr-xr-xchallenge-335/ulrich-rieke/perl/ch-2.pl103
-rwxr-xr-xchallenge-335/ulrich-rieke/raku/ch-1.raku25
-rwxr-xr-xchallenge-335/ulrich-rieke/raku/ch-2.raku93
-rwxr-xr-xchallenge-335/ulrich-rieke/rust/ch-1.rs47
-rwxr-xr-xchallenge-335/ulrich-rieke/rust/ch-2.rs81
-rw-r--r--stats/pwc-current.json21
-rw-r--r--stats/pwc-language-breakdown-2019.json2
-rw-r--r--stats/pwc-language-breakdown-2020.json2
-rw-r--r--stats/pwc-language-breakdown-2021.json2
-rw-r--r--stats/pwc-language-breakdown-2022.json2
-rw-r--r--stats/pwc-language-breakdown-2023.json2
-rw-r--r--stats/pwc-language-breakdown-2024.json2
-rw-r--r--stats/pwc-language-breakdown-2025.json8
-rw-r--r--stats/pwc-language-breakdown-summary.json6
-rw-r--r--stats/pwc-leaders.json8
-rw-r--r--stats/pwc-summary-1-30.json2
-rw-r--r--stats/pwc-summary-121-150.json2
-rw-r--r--stats/pwc-summary-151-180.json2
-rw-r--r--stats/pwc-summary-181-210.json2
-rw-r--r--stats/pwc-summary-211-240.json2
-rw-r--r--stats/pwc-summary-241-270.json2
-rw-r--r--stats/pwc-summary-271-300.json2
-rw-r--r--stats/pwc-summary-301-330.json6
-rw-r--r--stats/pwc-summary-31-60.json2
-rw-r--r--stats/pwc-summary-61-90.json2
-rw-r--r--stats/pwc-summary-91-120.json2
-rw-r--r--stats/pwc-summary.json8
-rw-r--r--stats/pwc-yearly-language-summary.json8
33 files changed, 755 insertions, 39 deletions
diff --git a/challenge-335/ulrich-rieke/cpp/ch-1.cpp b/challenge-335/ulrich-rieke/cpp/ch-1.cpp
new file mode 100755
index 0000000000..e516fd314a
--- /dev/null
+++ b/challenge-335/ulrich-rieke/cpp/ch-1.cpp
@@ -0,0 +1,76 @@
+#include <iostream>
+#include <vector>
+#include <sstream>
+#include <string>
+#include <algorithm>
+#include <numeric>
+#include <map>
+
+std::vector<std::string> split( const std::string & text , char delimiter) {
+ std::vector<std::string> tokens ;
+ std::istringstream istr { text } ;
+ std::string word ;
+ while ( std::getline( istr , word , delimiter ))
+ tokens.push_back( word ) ;
+ return tokens ;
+}
+
+std::string findCommonCharacters( const std::string & aWord ,
+ const std::string & bWord ) {
+ std::string common ;
+ for ( auto l : aWord ) {
+ if ( bWord.find( l ) != std::string::npos ) {
+ common.push_back( l ) ;
+ }
+ }
+ std::sort( common.begin( ) , common.end( ) ) ;
+ auto last = std::unique( common.begin( ) , common.end( ) ) ;
+ common.erase( last , common.end( ) ) ;
+ return common ;
+}
+
+int main( ) {
+ std::cout << "Enter some words separated by whitespace!\n" ;
+ std::string line ;
+ std::getline( std::cin , line ) ;
+ auto tokens { split( line , ' ' ) } ;
+ std::map<char , std::vector<int>> letterfrequencies ;
+ std::string common { findCommonCharacters( tokens[0] ,
+ tokens[1]) } ;
+ for ( int i = 1 ; i < tokens.size( ) ; i++ ) {
+ common = findCommonCharacters( common , tokens[i] ) ;
+ }
+ if ( common.empty( ) ) {
+ std::cout << "()\n" ;
+ }
+ else {
+ for ( auto w : tokens ) {
+ std::map<char , int> frequency_in_word ;
+ for ( auto l : w ) {
+ if ( common.find( l ) != std::string::npos ) {
+ frequency_in_word[l]++ ;
+ }
+ }
+ for ( auto it = frequency_in_word.begin( ) ; it !=
+ frequency_in_word.end( ) ; ++it ) {
+ letterfrequencies[it->first].push_back( it->second ) ;
+ }
+ }
+ std::vector<char> result ;
+ std::sort( common.begin( ) , common.end( ) ) ;
+ for ( char l : common ) {
+ auto foundFrequencies = letterfrequencies.find( l )->second ;
+ int howmany = *std::min_element( foundFrequencies.begin( ) ,
+ foundFrequencies.end( ) ) ;
+ for ( int i = 0 ; i < howmany ; i++ ) {
+ result.push_back( l ) ;
+ }
+ }
+ std::cout << "( " ;
+ for ( char l : result ) {
+ std::cout << l << ' ' ;
+ }
+ std::cout << ")\n" ;
+ }
+ return 0 ;
+}
diff --git a/challenge-335/ulrich-rieke/cpp/ch-2.cpp b/challenge-335/ulrich-rieke/cpp/ch-2.cpp
new file mode 100755
index 0000000000..d80899b5dc
--- /dev/null
+++ b/challenge-335/ulrich-rieke/cpp/ch-2.cpp
@@ -0,0 +1,86 @@
+#include <vector>
+#include <iostream>
+#include <regex>
+#include <utility>
+#include <string>
+#include <array>
+#include <algorithm>
+
+int main( ) {
+ std::cout << "Enter some integers between 0 and 2 in brackets, separated by ,!\n" ;
+ std::string line ;
+ std::getline( std::cin , line ) ;
+ std::string for_number ( "\\d" ) ;
+ std::regex np { for_number } ;
+ std::vector<int> numbers ;
+ auto end = std::sregex_token_iterator{} ;
+ for ( auto it = std::sregex_token_iterator{ std::begin( line ) ,
+ std::end( line ) , np } ; it != end ; ++it ) {
+ numbers.push_back( std::stoi( *it ) ) ;
+ }
+ std::vector<std::pair<int , int>> boardpoints ;
+ int len = numbers.size( ) ;
+ for ( int i = 0 ; i < len - 1 ; i += 2 )
+ boardpoints.push_back( std::make_pair( numbers[i] , numbers[i + 1] ) ) ;
+ //tictactoe board as an array of characters
+ std::array<char , 3> row ;
+ row.fill( '_' ) ;
+ std::array<std::array<char , 3> , 3> tictactoe ;
+ tictactoe.fill( row ) ;
+ for ( int i = 0 ; i < boardpoints.size( ) ; i++ ) {
+ int row = boardpoints[i].first ;
+ int column = boardpoints[i].second ;
+ if ( i % 2 == 0 ) {
+ tictactoe[row][column] = 'A' ;
+ }
+ else {
+ tictactoe[row][column] = 'B' ;
+ }
+ }
+ //one row with equal characters ?
+ auto rit = std::find_if( tictactoe.begin( ) , tictactoe.end( ) , []( const auto & r)
+ { char c = r[0] ; return std::all_of( r.begin( ) , r.end( ) , [c]( auto
+ letter) { return letter == c && letter != '_' ; } ) ;}) ;
+ if ( rit != tictactoe.end( ) ) {
+ std::cout << (*rit)[0] << '\n' ;
+ return 0 ;
+ }
+ //one column with equal characters ?
+ std::vector<char> column ;
+ std::vector<std::vector<char>> transposed ;
+ for ( int c = 0 ; c < 3 ; c++ ) {
+ for ( int r = 0 ; r < 3 ; r++ ) {
+ column.push_back( tictactoe[r][c] ) ;
+ }
+ transposed.push_back( column ) ;
+ }
+ auto it = std::find_if( transposed.begin( ) , transposed.end( ) , []( const auto r )
+ { char head = r[0] ; return std::all_of( r.begin( ) , r.end( ) , [head]( auto
+ letter ) { return letter == head && letter != '_' ; } ) ;}) ;
+ if ( it != transposed.end( )) {
+ std::cout << (*it)[0] << '\n' ;
+ return 0 ;
+ }
+ //is one diagonal filled with the same characters ?
+ if ( tictactoe[0][0] == tictactoe[1][1] && tictactoe[1][1] == tictactoe[2][2] &&
+ tictactoe[1][1] != '_' ) {
+ std::cout << tictactoe[0][0] << '\n' ;
+ return 0 ;
+ }
+ //what about the other diagonal ?
+ if ( tictactoe[2][0] == tictactoe[1][1] && tictactoe[1][1] == tictactoe[0][2] &&
+ tictactoe[1][1] != '_' ) {
+ std::cout << tictactoe[2][0] << '\n' ;
+ return 0 ;
+ }
+ //no decision so far and all fields filled with letters => draw!
+ if ( std::all_of( tictactoe.begin( ) , tictactoe.end( ) , []( const auto & r ) {
+ return std::all_of( r.begin( ) , r.end( ) , []( const auto letter ) {
+ return (letter == 'A' || letter == 'B') ; }) ;})) {
+ std::cout << "Draw\n" ;
+ return 0 ;
+ }
+ //if we haven't returned up to this point it's pending
+ std::cout << "Pending\n" ;
+ return 0 ;
+}
diff --git a/challenge-335/ulrich-rieke/haskell/ch-1.hs b/challenge-335/ulrich-rieke/haskell/ch-1.hs
new file mode 100755
index 0000000000..6d7ac4be65
--- /dev/null
+++ b/challenge-335/ulrich-rieke/haskell/ch-1.hs
@@ -0,0 +1,45 @@
+module Challenge355
+ where
+import qualified Data.Set as S
+import Data.List ( sortOn , groupBy , intersperse)
+
+findCommonChars :: [String] -> [Char]
+findCommonChars = S.toList . foldl1 S.intersection . map S.fromList
+
+count :: Eq a => a -> [a] -> Int
+count _ [] = 0
+count d (x:xs)
+ |d == x = 1 + count d xs
+ |otherwise = count d xs
+
+wordFrequencies :: String -> String -> [(Char , Int)]
+wordFrequencies aWord common = map (\l -> (l , count l aWord )) $ filter
+ (\l -> elem l common ) aWord
+
+consolidate :: [[(Char , Int)]] -> [(Char , [Int])]
+consolidate frequencies =
+ let consolidated = concat frequencies
+ sorted = sortOn fst consolidated
+ grouped = groupBy(\a b -> fst a == fst b ) sorted
+ in map(\subli -> ( fst $ head subli, map snd subli)) grouped
+
+findFrequencies :: [String] -> [(Char , [Int])]
+findFrequencies theWords =
+ let commonChars = findCommonChars theWords
+ frequenciesInWords = map (\w -> wordFrequencies w commonChars )
+ theWords
+ in consolidate frequenciesInWords
+
+printResult :: [(Char , [Int])] -> String
+printResult letterlists = intersperse ',' $ concat $ map (\p ->
+ replicate ( snd p )( fst p )) $ map (\p -> ( fst p , minimum $ snd p ))
+ $ sortOn fst letterlists
+
+main :: IO ( )
+main = do
+ putStrLn "Enter some words separated by whitespace!"
+ wordline <- getLine
+ print $ printResult $ findFrequencies $ words wordline
+
+
+
diff --git a/challenge-335/ulrich-rieke/haskell/ch-2.hs b/challenge-335/ulrich-rieke/haskell/ch-2.hs
new file mode 100755
index 0000000000..ad06867aa3
--- /dev/null
+++ b/challenge-335/ulrich-rieke/haskell/ch-2.hs
@@ -0,0 +1,81 @@
+{-# LANGUAGE MultiWayIf #-}
+module Challenge335_2
+ where
+import Data.List ( (!!) , transpose , findIndex , findIndices)
+import Data.Char ( digitToInt )
+import Data.List.Split ( chunksOf )
+
+parseEntryLine :: String -> [(Int , Int)]
+parseEntryLine line = map (\i -> ( digitToInt (line !! (i + 1 )) , digitToInt (line !! (i + 3 ))))
+ $ findIndices ( == '[' ) line
+
+tictacboard :: [String]
+tictacboard = ["___" , "___" , "___"]
+
+modifyBoard :: [String] -> (Int , (Int , Int)) -> [String]
+modifyBoard board (n , p )
+ |even n = if
+ |offset == 0 -> chunksOf 3 ( "A" ++ drop 1 letterrow )
+ |offset > 0 && offset < 8 -> chunksOf 3 ( take offset letterrow ++ "A" ++ drop ( offset + 1 )
+ letterrow )
+ |offset == 8 -> chunksOf 3 ( take 8 letterrow ++ "A" )
+ |otherwise = if
+ |offset == 0 -> chunksOf 3 ( "B" ++ drop 1 letterrow )
+ |offset > 0 && offset < 8 -> chunksOf 3 ( take offset letterrow ++ "B" ++ drop ( offset + 1 )
+ letterrow )
+ |offset == 0 -> chunksOf 3 ( take 8 letterrow ++ "B" )
+ where
+ letterrow = concat board
+ offset = fst p * 3 + snd p
+
+modifyTictacBoard coordinates =
+ let zipped = zip [0 , 1 ..] coordinates
+ in foldl modifyBoard tictacboard zipped
+
+rowEqual :: [String] -> Bool
+rowEqual board = any (\r -> all (\l -> l == r !! 0 && l /= '_' ) r ) board
+
+columnEqual :: [String] -> Bool
+columnEqual = rowEqual . transpose
+
+oneDiagonal :: [String] -> Bool
+oneDiagonal board = and [board !! 0 !! 0 == board !! 1 !! 1 , board !! 1 !! 1 ==
+ board !! 2 !! 2 , board !! 1 !! 1 /= '_' ]
+
+otherDiagonal :: [String] -> Bool
+otherDiagonal board = and [board !! 2 !! 0 == board !! 1 !! 1 , board !! 1 !! 1 ==
+ board !! 0 !! 2 , board !! 1 !! 1 /= '_' ]
+
+isDraw :: [String] -> Bool
+isDraw board =
+ let values = [rowEqual board , columnEqual board , oneDiagonal board , otherDiagonal board]
+ in all (== False ) values && all (\r -> all ( (/= '_') ) r ) board
+
+isPending :: [String] -> Bool
+isPending board =
+ let values = [rowEqual board , columnEqual board , oneDiagonal board, otherDiagonal board,
+ isDraw board]
+ in all (== False ) values
+
+findOutput :: [String] -> String
+findOutput board
+ |rowEqual board = case findIndex (\r -> all (\l -> l == (r !! 0)) r ) board of
+ Just i -> [board !! i !! 0]
+ Nothing -> " "
+ |columnEqual board = case findIndex(\r -> all (\l -> l == ( r !! 0 )) r ) transposed of
+ Just i -> [transposed !! i !! 0]
+ Nothing -> " "
+ |oneDiagonal board = [board !! 0 !! 0]
+ |otherDiagonal board = [board !! 2 !! 0 ]
+ |isDraw board = "Draw"
+ |isPending board = "Pending"
+ where
+ transposed = transpose board
+
+main :: IO ( )
+main = do
+ putStrLn "Enter some numbers between 0 and 2 in brackets separated by commas!"
+ numberline <- getLine
+ let pairs = parseEntryLine numberline
+ board = modifyTictacBoard pairs
+ print $ findOutput board
diff --git a/challenge-335/ulrich-rieke/perl/ch-1.pl b/challenge-335/ulrich-rieke/perl/ch-1.pl
new file mode 100755
index 0000000000..a85f5c9b69
--- /dev/null
+++ b/challenge-335/ulrich-rieke/perl/ch-1.pl
@@ -0,0 +1,60 @@
+#!/usr/bin/perl ;
+use strict ;
+use warnings ;
+use feature 'say' ;
+use List::Util qw ( min ) ;
+
+#common letters of two words
+sub intersect {
+ my $first = shift ;
+ my $second = shift ;
+ my %firstfreq ;
+ my %secondfreq ;
+ my %common ;
+ map { $firstfreq{$_}++ } split( // , $first ) ;
+ map {$secondfreq{$_}++ } split( // , $second ) ;
+ for my $letter( keys %firstfreq ) {
+ if ( exists( $secondfreq{$letter} ) ) {
+ $common{$letter}++ ;
+ }
+ }
+ return join( '' , keys %common ) ;
+}
+
+say "Enter some words separated by whitespace!" ;
+my $line = <STDIN> ;
+chomp $line ;
+my @words = split( /\s+/ , $line ) ;
+my $len = scalar( @words ) ;
+#find common letters of all words , if there are any
+my $common = intersect( $words[0] , $words[1] ) ;
+for my $i ( 1..$len - 2 ) {
+ $common = intersect( $common , $words[$i + 1] ) ;
+}
+my %commonfrequencies ;#for every letter common to all words , it holds
+ #their respective frequencies
+for my $w ( @words ) {
+ my %wordfrequencies ;#frequencies of the common letters
+ for my $letter( split( // , $w ) ) {
+ if ( index( $common , $letter ) != -1 ) {
+ $wordfrequencies{$letter}++ ;
+ }
+ }
+ for my $letter( keys %wordfrequencies ) {
+ push( @{$commonfrequencies{$letter}} , $wordfrequencies{$letter} ) ;
+ }
+}
+if ( $common ) {#do we have common letters ?
+ my @solution ;
+ my @sorted = sort split( // , $common ) ;
+ for my $letter( split( // , $common ) ) {
+ my $times = min ( @{$commonfrequencies{$letter}} ) ;
+ for (1..$times) {
+ push( @solution , $letter ) ;
+ }
+ }
+ say '('. join( ',' , @solution ) . ')' ;
+}
+else {
+ say "()" ;
+}
diff --git a/challenge-335/ulrich-rieke/perl/ch-2.pl b/challenge-335/ulrich-rieke/perl/ch-2.pl
new file mode 100755
index 0000000000..688d90b3bf
--- /dev/null
+++ b/challenge-335/ulrich-rieke/perl/ch-2.pl
@@ -0,0 +1,103 @@
+#!/usr/bin/perl ;
+use strict ;
+use warnings ;
+use feature 'say' ;
+use List::Util qw ( all ) ;
+
+say "Enter some numbers between 0 and 2 in brackets!" ;
+my $line = <STDIN> ;
+chomp $line ;
+my @pairs ;
+while ( $line =~ /\[\s*(\d+)\s*\,\s*(\d+)\s*\]/cg ) {
+ push ( @pairs , [$1 , $2] ) ;
+}
+my @tictactoe ; #an array of strings as a substitute for the board
+for (1..3 ) {
+ push( @tictactoe , "___" ) ;
+}
+my $counter = 0 ;
+for my $pair( @pairs ) {
+ if ( $counter % 2 == 0 ) {
+ substr( $tictactoe[$pair->[0]] , $pair->[1] , 1 ) = 'A' ;
+ }
+ else {
+ substr( $tictactoe[$pair->[0]] , $pair->[1] , 1 ) = 'B' ;
+ }
+ $counter++ ;
+}
+my $row_equal = 0 ; # all letters in a row equal ? supposed to be wrong
+for my $str( @tictactoe ) {
+ if ( $str eq "AAA" || $str eq "BBB" ) {
+ $row_equal = 1 ;
+ }
+}
+my @transposed ; #transpose the tictactoe field
+for my $col( 0..2 ) {
+ my $transpo ;
+ for my $row( 0..2 ) {
+ $transpo .= substr( $tictactoe[$row] , $col , 1 ) ;
+ }
+ push( @transposed , $transpo ) ;
+}
+my $column_equal = 0 ;#are all columns equal ? supposed to be wrong
+for my $str( @transposed ) {
+ if ( $str eq "AAA" || $str eq "BBB" ) {
+ $column_equal = 1 ;
+ }
+}
+my $first_diagonal .= substr($tictactoe[0] , 0 , 1 ) . substr( $tictactoe[1] , 1 ,
+ 1 ) . substr( $tictactoe[2] , 2 , 1 ) ;
+my $left_diagonal_down = 0 ;
+if ( $first_diagonal eq "AAA" || $first_diagonal eq "BBB" ) {
+ $left_diagonal_down = 1 ;
+}
+my $second_diagonal .= substr( $tictactoe[2] , 0 , 1 ) . substr( $tictactoe[1] ,
+ 1 , 1 ) . substr( $tictactoe[0] , 2 , 1 ) ;
+my $from_left_up = 0 ;
+if ( $second_diagonal eq "AAA" || $second_diagonal eq "BBB" ) {
+ $from_left_up = 1 ;
+}
+my $maybe_drawn = 0 ;
+if (all { $_ == 0 } ($column_equal , $row_equal , $left_diagonal_down ,
+ $from_left_up )) {
+ $maybe_drawn = 1 ;
+}
+my $is_drawn = 0 ;
+if ( $maybe_drawn) {
+ if ( all { $_ !~ /_/ } @tictactoe ) {
+ $is_drawn = 1 ;
+ }
+}
+if ( all { $_ == 0 } ( $column_equal , $row_equal , $left_diagonal_down ,
+ $from_left_up , $is_drawn) ) {
+ say "Pending" ;
+}
+if ( $row_equal ) {
+ for my $string( @tictactoe ) {
+ if ( $string eq "AAA" ) {
+ say "A" ;
+ }
+ if ( $string eq "BBB" ) {
+ say "B" ;
+ }
+ }
+}
+if ( $column_equal ) {
+ for my $string( @transposed ) {
+ if ( $string eq "AAA" ) {
+ say "A" ;
+ }
+ if ( $string eq "BBB" ) {
+ say "B" ;
+ }
+ }
+}
+if ($left_diagonal_down ) {
+ say substr( $tictactoe[0] , 0 , 1 ) ;
+}
+if ( $from_left_up ) {
+ say substr( $tictactoe[2] , 0 , 1 ) ;
+}
+if ( $is_drawn ) {
+ say "Draw" ;
+}
diff --git a/challenge-335/ulrich-rieke/raku/ch-1.raku b/challenge-335/ulrich-rieke/raku/ch-1.raku
new file mode 100755
index 0000000000..c3ea2d0370
--- /dev/null
+++ b/challenge-335/ulrich-rieke/raku/ch-1.raku
@@ -0,0 +1,25 @@
+use v6 ;
+
+say "Enter some words separated by whitespace!" ;
+my $line = $*IN.get ;
+my @singleWords = $line.words ;
+my @charSets = @singleWords.map( {$_.comb.Set} ) ;
+my $common = [(&)] @charSets ;
+my @commonLetters = $common.keys ;
+my %frequencies ;
+for @singleWords -> $word {
+ my %wordfreq ;
+ for $word.comb -> $letter {
+ %wordfreq{$letter}++ ;
+ }
+ for @commonLetters -> $letter {
+ %frequencies{$letter}.push( %wordfreq{$letter} ) ;
+ }
+}
+my @solution ;
+for %frequencies.keys -> $l {
+ for (1..%frequencies{$l}.min( ) ) {
+ @solution.push( $l ) ;
+ }
+}
+say '(' ~ @solution.join( ',' ) ~ ')' ;
diff --git a/challenge-335/ulrich-rieke/raku/ch-2.raku b/challenge-335/ulrich-rieke/raku/ch-2.raku
new file mode 100755
index 0000000000..1d4dc0dc3a
--- /dev/null
+++ b/challenge-335/ulrich-rieke/raku/ch-2.raku
@@ -0,0 +1,93 @@
+use v6 ;
+
+say "Enter some numbers between 0 and 2 in brackets separated by ,!" ;
+my $line = $*IN.get ;
+my @pairs ;
+my @parts = $line.split( /\] ',' \s*\[/ ) ;
+for @parts -> $pair {
+ if ($pair ~~ /(\d+)\s* ',' \s* (\d+) / ) {
+ my $numberpair = [+$0 , +$1] ;
+ @pairs.push( $numberpair ) ;
+ }
+}
+#define the tictactoe as an array of strings, for simplicity
+my @tictactoe ;
+for (1..3) {
+ @tictactoe.push( "___") ;
+}
+my $counter = 0 ;
+for @pairs -> $pair {
+ if ( $counter %% 2 ) {
+ @tictactoe[$pair[0]].substr-rw( $pair[1] , 1 ) = 'A' ;
+ }
+ else {
+ @tictactoe[$pair[0]].substr-rw( $pair[1] , 1 ) = 'B' ;
+ }
+ $counter++ ;
+}
+my $row_equal = False ;
+for @tictactoe -> $str {
+ if ( $str eq "AAA" || $str eq "BBB" ) {
+ $row_equal = True ;
+ }
+}
+my @transposed ;
+for ( 0..2 ) -> $col {
+ for (0..2) -> $row {
+ my $transpo ~= @tictactoe[$row].substr( $col , 1 ) ;
+ }
+ @transposed.push( $transpo ) ;
+}
+my $column_equal = False ;
+for @transposed -> $str {
+ if ( $str eq "AAA" || $str eq "BBB" ) {
+ $column_equal = True ;
+ }
+}
+my $first_diagonal = @tictactoe[0].substr( 0 , 1 ) ~ @tictactoe[1].substr( 1 , 1 )
+ ~ @tictactoe[2].substr( 2 , 1 ) ;
+my $left_down_diagonal = ( $first_diagonal eq "AAA" || $first_diagonal eq "BBB" ) ;
+my $second_diagonal = @tictactoe[2].substr( 0 , 1 ) ~ @tictactoe[1].substr( 1 , 1 )
+ ~ @tictactoe[0].substr( 2 , 1 ) ;
+my $right_up_diagonal = ( $second_diagonal eq "AAA" || $second_diagonal eq "BBB" ) ;
+my $maybe_drawn = ( (not $row_equal) && not ( $column_equal ) && ( not
+ $left_down_diagonal ) && ( not $right_up_diagonal )) ;
+my $is_drawn ;
+if ( $maybe_drawn ) {
+ if ( @tictactoe.grep( {$_ ~~ /^('A' | 'B')+$/ } ).elems == 3 ) {
+ $is_drawn = True ;
+ }
+}
+if (( $column_equal , $row_equal , $left_down_diagonal , $right_up_diagonal ,
+ $is_drawn ).none ) {
+ say "Pending" ;
+}
+if $row_equal {
+ for @tictactoe -> $string {
+ if ($string eq "AAA" ) {
+ say "A" ;
+ }
+ if ( $string eq "BBB" ) {
+ say "B" ;
+ }
+ }
+}
+if $column_equal {
+ for @transposed -> $string {
+ if ( $string eq "AAA" ) {
+ say "A" ;
+ }
+ if ( $string eq "BBB" ) {
+ say "B" ;
+ }
+ }
+}
+if $left_down_diagonal {
+ say @tictactoe[0].substr( 0 , 1 ) ;
+}
+if ( $right_up_diagonal ) {
+ say @tictactoe[2].substr( 0 , 1 ) ;
+}
+if $is_drawn {
+ say "Draw" ;
+}
diff --git a/challenge-335/ulrich-rieke/rust/ch-1.rs b/challenge-335/ulrich-rieke/rust/ch-1.rs
new file mode 100755
index 0000000000..07a904cc8f
--- /dev/null
+++ b/challenge-335/ulrich-rieke/rust/ch-1.rs
@@ -0,0 +1,47 @@
+use std::io ;
+use std::collections::{HashMap , HashSet} ;
+
+fn count_characters( word : &str ) -> HashMap<char , usize> {
+ let mut frequencies : HashMap<char , usize> = HashMap::new( ) ;
+ for c in word.chars( ) {
+ *frequencies.entry( c ).or_insert( 0 ) += 1 ;
+ }
+ frequencies
+}
+
+fn main() {
+ println!("Enter some words separated by whitespace!");
+ let mut inline : String = String::new( ) ;
+ io::stdin( ).read_line( &mut inline ).unwrap( ) ;
+ let frequencylist : Vec<HashMap<char, usize>> = inline.trim( ).split_whitespace( ).map(
+ |s| count_characters( s ) ).collect( ) ;
+ let sets : Vec<HashSet<char>> = frequencylist.iter( ).map( |f| {
+ let keys = f.keys( ) ;
+ let mut keyset : HashSet<char> = HashSet::new( ) ;
+ for c in keys {
+ keyset.insert( *c ) ;
+ }
+ keyset
+ }).collect( ) ;
+ let common : HashSet<char> = sets.clone().into_iter( ).fold( sets[0].clone( ) , |mut acc , s| {
+ acc.retain( |item| s.contains( item ) ) ;
+ acc
+ } ) ;
+ let mut common_frequencies : Vec<(char , usize)> = Vec::new( ) ;
+ for c in common {
+ let mut numbers : Vec<usize> = Vec::new( ) ;
+ for f in &frequencylist {
+ let num = f.get( &c ).unwrap( ) ;
+ numbers.push( *num ) ;
+ }
+ let mini = numbers.into_iter( ).min( ).unwrap( ) ;
+ common_frequencies.push( (c , mini) ) ;
+ }
+ let mut solution : Vec<char> = Vec::new( ) ;
+ for pair in common_frequencies {
+ for _ in 0..pair.1 {
+ solution.push( pair.0 ) ;
+ }
+ }
+ println!("{:?}" , solution ) ;
+}
diff --git a/challenge-335/ulrich-rieke/rust/ch-2.rs b/challenge-335/ulrich-rieke/rust/ch-2.rs
new file mode 100755
index 0000000000..afd4b3ba6d
--- /dev/null
+++ b/challenge-335/ulrich-rieke/rust/ch-2.rs
@@ -0,0 +1,81 @@
+use std::io ;
+use regex::Regex ;
+
+fn parse_pair( bracket : &str ) -> (usize , usize) {
+ let re = Regex::new( r"([0-9]+)").unwrap( ) ;
+ let numbers : Vec<usize> = re.find_iter( bracket ).map( |m| {
+ let found = m.as_str( ) ;
+ let num : usize = found.parse::<usize>( ).unwrap( ) ;
+ num
+ }).collect( ) ;
+ (numbers[0] , numbers[1])
+}
+
+fn main() {
+ println!("Enter some tictactoe coordinates in brackets separated by ,!");
+ let mut inline : String = String::new( ) ;
+ io::stdin( ).read_line( &mut inline ).unwrap( ) ;
+ let re = Regex::new( r"\[\s*([0-9]+)\s*\,\s*([0-9]+)\]").unwrap( ) ;
+ let trimmed = inline.trim( ) ;
+ let parts : Vec<&str> = re.find_iter(trimmed).map( |m| m.as_str( )).
+ collect( ) ;
+ let coordinates : Vec<(usize , usize)> = parts.into_iter( ).map( |s|
+ parse_pair( s ) ).collect( ) ;
+ let row : [char ; 3] = ['_' ; 3 ] ;
+ let mut tictacboard : [[char ; 3] ; 3] = [row ; 3] ;
+ let mut counter : usize = 0 ;
+ for p in coordinates {
+ if counter % 2 == 0 {
+ tictacboard[p.0][p.1] = 'A' ;
+ }
+ else {
+ tictacboard[p.0][p.1] = 'B' ;
+ }
+ counter += 1 ;
+ }
+ //test on row equality
+ let rows_equal : bool = tictacboard.iter( ).any( |r| {
+ let head : char = r[0] ;
+ r.iter( ).all( |c| *c == head && *c != '_')
+ }) ;
+ let column_equal : bool = {
+ let heads : [usize ; 3] = [0 , 1 , 2] ;
+ heads.into_iter( ).any( |p| tictacboard[0][p] == tictacboard[1][p] &&
+ tictacboard[1][p] == tictacboard[2][p] && tictacboard[0][p] != '_')
+ } ;
+ let left_down_diagonal : bool = tictacboard[0][0] == tictacboard[1][1] &&
+ tictacboard[1][1] == tictacboard[2][2] && tictacboard[0][0] != '_' ;
+ let right_up_diagonal : bool = tictacboard[2][0] == tictacboard[1][1] &&
+ tictacboard[1][1] == tictacboard[0][2] && tictacboard[2][0] != '_' ;
+ let is_drawn : bool = tictacboard.iter( ).all( |r| r.iter( ).all( |c| *c == 'A'
+ || *c == 'B')) ;
+ if rows_equal {
+ let found = tictacboard.iter( ).position( |r| {
+ let head : char = r[0] ;
+ r.iter( ).all( |c| *c == head )
+ }) ;
+ let pos = found.unwrap( ) ;
+ println!("{}" , tictacboard[pos][0] ) ;
+ }
+ if column_equal {
+ let heads = [0 , 1 , 2] ;
+ let found = heads.into_iter( ).position( |n| tictacboard[0][n] ==
+ tictacboard[1][n] && tictacboard[1][n] == tictacboard[2][n] ) ;
+ let pos : usize = found.unwrap( ) ;
+ println!("{}" , tictacboard[0][pos] ) ;
+ }
+ if left_down_diagonal {
+ println!("{}" , tictacboard[0][0] ) ;
+ }
+ if right_up_diagonal {
+ println!("{}" , tictacboard[2][0] ) ;
+ }
+ if is_drawn {
+ println!("Draw") ;
+ }
+ let possibilities : Vec<bool> = vec![rows_equal , column_equal ,
+ left_down_diagonal , right_up_diagonal , is_drawn ] ;
+ if possibilities.into_iter( ).all( |p| p == false ) {
+ println!("Pending") ;
+ }
+}
diff --git a/stats/pwc-current.json b/stats/pwc-current.json
index f217cf5dba..09e32b79aa 100644
--- a/stats/pwc-current.json
+++ b/stats/pwc-current.json
@@ -143,6 +143,20 @@
2
],
[
+ "Raku",
+ 2
+ ]
+ ],
+ "id" : "Ulrich Rieke",
+ "name" : "Ulrich Rieke"
+ },
+ {</