diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2023-03-13 21:53:13 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-13 21:53:13 +0000 |
| commit | 2cb00557ab6964716d9bd448dd2067875520e1c9 (patch) | |
| tree | 8501bf78213b710e518382d514eca88995ae5d13 | |
| parent | 784cb54bac261893b8064ccf8c9018328cb7c471 (diff) | |
| parent | 021477f72d3a160def575c197b93afa1a7fb2ae1 (diff) | |
| download | perlweeklychallenge-club-2cb00557ab6964716d9bd448dd2067875520e1c9.tar.gz perlweeklychallenge-club-2cb00557ab6964716d9bd448dd2067875520e1c9.tar.bz2 perlweeklychallenge-club-2cb00557ab6964716d9bd448dd2067875520e1c9.zip | |
Merge pull request #7724 from LubosKolouch/master
Challenge 009 010 LK Perl Python
| -rw-r--r-- | challenge-009/lubos-kolouch/perl/ch-1.pl | 24 | ||||
| -rw-r--r-- | challenge-009/lubos-kolouch/perl/ch-2.pl | 61 | ||||
| -rw-r--r-- | challenge-009/lubos-kolouch/python/ch-1.py | 16 | ||||
| -rw-r--r-- | challenge-009/lubos-kolouch/python/ch-2.py | 46 | ||||
| -rw-r--r-- | challenge-010/lubos-kolouch/perl/ch-1.pl | 73 | ||||
| -rw-r--r-- | challenge-010/lubos-kolouch/perl/ch-2.pl | 66 | ||||
| -rw-r--r-- | challenge-010/lubos-kolouch/python/ch-1.py | 48 | ||||
| -rw-r--r-- | challenge-010/lubos-kolouch/python/ch-2.py | 53 |
8 files changed, 387 insertions, 0 deletions
diff --git a/challenge-009/lubos-kolouch/perl/ch-1.pl b/challenge-009/lubos-kolouch/perl/ch-1.pl new file mode 100644 index 0000000000..d22b052c14 --- /dev/null +++ b/challenge-009/lubos-kolouch/perl/ch-1.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $num = 1; + +while (1) { + my $square = $num * $num; + my @digits = split( //, $square ); + my %unique_digits; + + foreach my $digit (@digits) { + $unique_digits{$digit} = 1; + } + + if ( scalar( keys %unique_digits ) >= 5 ) { + print +"The first square number with at least 5 distinct digits is: $square\n"; + last; + } + + $num++; +} diff --git a/challenge-009/lubos-kolouch/perl/ch-2.pl b/challenge-009/lubos-kolouch/perl/ch-2.pl new file mode 100644 index 0000000000..545fc1211b --- /dev/null +++ b/challenge-009/lubos-kolouch/perl/ch-2.pl @@ -0,0 +1,61 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +sub standard_ranking { + my @scores = @_; + my @sorted_scores = sort { $b <=> $a } @scores; + my @ranks; + my $rank = 1; + foreach my $score (@sorted_scores) { + push @ranks, $rank + if ( !$ranks[-1] || $score != $sorted_scores[ -$ranks[-1] ] ); + $rank++; + } + my @standard_ranks = map { + my $index = $_; + scalar( grep { $sorted_scores[$_] > $sorted_scores[$index] } + 0 .. $#sorted_scores ) + $ranks[$_] + } 0 .. $#scores; + return @standard_ranks; +} + +sub modified_ranking { + my @scores = @_; + my @sorted_scores = sort { $b <=> $a } @scores; + my %ranks; + my $rank = 1; + foreach my $score (@sorted_scores) { + $ranks{$score} = $rank if !$ranks{$score}; + $rank++ unless $score == $sorted_scores[ -$ranks{$score} ]; + } + my @modified_ranks = map { $ranks{$_} } @scores; + return @modified_ranks; +} + +sub dense_ranking { + my @scores = @_; + my @sorted_scores = sort { $b <=> $a } @scores; + my %ranks; + my $rank = 1; + foreach my $score (@sorted_scores) { + $ranks{$score} = $rank unless $ranks{$score}; + $rank++ unless $score == $sorted_scores[ -$ranks{$score} ]; + } + my @dense_ranks = map { $ranks{$_} } @scores; + return @dense_ranks; +} + +# Test the functions +my @scores = ( 10, 20, 30, 20, 40, 50, 10, 30 ); +print "Scores: ", join( ", ", @scores ), "\n"; + +my @standard_ranks = standard_ranking(@scores); +print "Standard Ranking: ", join( ", ", @standard_ranks ), "\n"; + +my @modified_ranks = modified_ranking(@scores); +print "Modified Ranking: ", join( ", ", @modified_ranks ), "\n"; + +my @dense_ranks = dense_ranking(@scores); +print "Dense Ranking: ", join( ", ", @dense_ranks ), "\n"; diff --git a/challenge-009/lubos-kolouch/python/ch-1.py b/challenge-009/lubos-kolouch/python/ch-1.py new file mode 100644 index 0000000000..2983cff8f6 --- /dev/null +++ b/challenge-009/lubos-kolouch/python/ch-1.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import math + +num = 1 + +while True: + square = num * num + digits = set(str(square)) + + if len(digits) >= 5: + print(f"The first square number with at least 5 distinct digits is: {square}") + break + + num += 1 diff --git a/challenge-009/lubos-kolouch/python/ch-2.py b/challenge-009/lubos-kolouch/python/ch-2.py new file mode 100644 index 0000000000..416cd27092 --- /dev/null +++ b/challenge-009/lubos-kolouch/python/ch-2.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#!/usr/bin/env python3 + + +def standard_ranking(scores): + sorted_scores = sorted(scores, reverse=True) + ranks = [sorted_scores.index(score) + 1 for score in scores] + return ranks + + +def modified_ranking(scores): + sorted_scores = sorted(scores, reverse=True) + ranks = [] + rank = 1 + for score in sorted_scores: + if score not in ranks: + rank = sorted_scores.index(score) + 1 + ranks.append(rank) + return [ranks[sorted_scores.index(score)] for score in scores] + + +def dense_ranking(scores): + sorted_scores = sorted(scores, reverse=True) + ranks = [1] + for i in range(1, len(sorted_scores)): + if sorted_scores[i] == sorted_scores[i - 1]: + ranks.append(ranks[i - 1]) + else: + ranks.append(ranks[i - 1] + 1) + return [ranks[sorted_scores.index(score)] for score in scores] + + +# Test the functions +scores = [10, 20, 30, 20, 40, 50, 10, 30] +print("Scores: ", scores) + +standard_ranks = standard_ranking(scores) +print("Standard Ranking: ", standard_ranks) + +modified_ranks = modified_ranking(scores) +print("Modified Ranking: ", modified_ranks) + +dense_ranks = dense_ranking(scores) +print("Dense Ranking: ", dense_ranks) diff --git a/challenge-010/lubos-kolouch/perl/ch-1.pl b/challenge-010/lubos-kolouch/perl/ch-1.pl new file mode 100644 index 0000000000..f6c7d1821a --- /dev/null +++ b/challenge-010/lubos-kolouch/perl/ch-1.pl @@ -0,0 +1,73 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +sub encode_roman { + my $number = shift; + my @roman_map = ( + [ 'M', 1000 ], + [ 'CM', 900 ], + [ 'D', 500 ], + [ 'CD', 400 ], + [ 'C', 100 ], + [ 'XC', 90 ], + [ 'L', 50 ], + [ 'XL', 40 ], + [ 'X', 10 ], + [ 'IX', 9 ], + [ 'V', 5 ], + [ 'IV', 4 ], + [ 'I', 1 ] + ); + my $roman_numeral = ''; + foreach my $pair (@roman_map) { + my ( $numeral, $value ) = @$pair; + while ( $number >= $value ) { + $roman_numeral .= $numeral; + $number -= $value; + } + } + return $roman_numeral; +} + +sub decode_roman { + my $roman_numeral = shift; + my @roman_map = ( + [ 'M', 1000 ], + [ 'CM', 900 ], + [ 'D', 500 ], + [ 'CD', 400 ], + [ 'C', 100 ], + [ 'XC', 90 ], + [ 'L', 50 ], + [ 'XL', 40 ], + [ 'X', 10 ], + [ 'IX', 9 ], + [ 'V', 5 ], + [ 'IV', 4 ], + [ 'I', 1 ] + ); + my $number = 0; + foreach my $pair (@roman_map) { + my ( $numeral, $value ) = @$pair; + while ( $roman_numeral =~ /^$numeral/ ) { + $number += $value; + $roman_numeral =~ s/^$numeral//; + } + } + return $number; +} + +# Test the functions +my $roman_numeral = 'CCXLVI'; +my $number = decode_roman($roman_numeral); +print "$roman_numeral = $number\n"; +my $shortest_numeral = encode_roman($number); +print "$number = $shortest_numeral\n"; + +my $decimal_number = 39; +$roman_numeral = encode_roman($decimal_number); +print "$decimal_number = $roman_numeral\n"; +$number = decode_roman($roman_numeral); +print "$roman_numeral = $number\n"; diff --git a/challenge-010/lubos-kolouch/perl/ch-2.pl b/challenge-010/lubos-kolouch/perl/ch-2.pl new file mode 100644 index 0000000000..693bc0faa3 --- /dev/null +++ b/challenge-010/lubos-kolouch/perl/ch-2.pl @@ -0,0 +1,66 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +sub jaro_winkler_distance { + my ( $s1, $s2, $p ) = @_; + $p ||= 0.1; # default scaling factor + + # Step 1: Calculate the Jaro distance + my $matches = 0; + my $transpositions = 0; + my $s1_len = length($s1); + my $s2_len = length($s2); + my $match_distance = int( max( $s1_len, $s2_len ) / 2 ) - 1; + my %s2_matches = (); + for ( my $i = 0 ; $i < $s1_len ; $i++ ) { + my $c1 = substr( $s1, $i, 1 ); + my $start = max( 0, $i - $match_distance ); + my $end = min( $i + $match_distance + 1, $s2_len ); + for ( my $j = $start ; $j < $end ; $j++ ) { + if ( !$s2_matches{$j} && substr( $s2, $j, 1 ) eq $c1 ) { + $matches++; + $s2_matches{$j} = 1; + last; + } + } + } + return 0 if ( $matches == 0 ); # no matches found + my $jaro_distance = + ( $matches / $s1_len + + $matches / $s2_len + + ( $matches - $transpositions / 2 ) / $matches ) / 3; + + # Step 2: Calculate the Jaro-Winkler distance + my $prefix_len = 0; + for ( my $i = 0 ; $i < min( $s1_len, $s2_len ) ; $i++ ) { + if ( substr( $s1, $i, 1 ) eq substr( $s2, $i, 1 ) ) { + $prefix_len++; + } + else { + last; + } + } + my $jaro_winkler_distance = + $jaro_distance + $prefix_len * $p * ( 1 - $jaro_distance ); + return $jaro_winkler_distance; +} + +# Helper function to find the max of two values +sub max { + my ( $a, $b ) = @_; + return $a > $b ? $a : $b; +} + +# Helper function to find the min of two values +sub min { + my ( $a, $b ) = @_; + return $a < $b ? $a : $b; +} + +# Test the function +my $s1 = 'MARTHA'; +my $s2 = 'MARHTA'; +my $distance = jaro_winkler_distance( $s1, $s2 ); +print "Jaro-Winkler distance between '$s1' and '$s2' is $distance\n"; diff --git a/challenge-010/lubos-kolouch/python/ch-1.py b/challenge-010/lubos-kolouch/python/ch-1.py new file mode 100644 index 0000000000..bbb3ac7a67 --- /dev/null +++ b/challenge-010/lubos-kolouch/python/ch-1.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +roman_map = { + "I": 1, + "IV": 4, + "V": 5, + "IX": 9, + "X": 10, + "XL": 40, + "L": 50, + "XC": 90, + "C": 100, + "CD": 400, + "D": 500, + "CM": 900, + "M": 1000, +} + + +def encode_to_roman(number): + result = "" + for roman, value in sorted(roman_map.items(), key=lambda x: -x[1]): + while number >= value: + result += roman + number -= value + return result + + +def decode_to_decimal(roman): + result = 0 + index = 0 + while index < len(roman): + if index < len(roman) - 1 and roman[index : index + 2] in roman_map: + result += roman_map[roman[index : index + 2]] + index += 2 + else: + result += roman_map[roman[index]] + index += 1 + return result + + +# Test the functions +roman_numeral = "CCXLVI" +print(f"Roman Numeral: {roman_numeral} -> Decimal: {decode_to_decimal(roman_numeral)}") + +decimal_num = 39 +print(f"Decimal: {decimal_num} -> Roman Numeral: {encode_to_roman(decimal_num)}") diff --git a/challenge-010/lubos-kolouch/python/ch-2.py b/challenge-010/lubos-kolouch/python/ch-2.py new file mode 100644 index 0000000000..d0466443ce --- /dev/null +++ b/challenge-010/lubos-kolouch/python/ch-2.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +def jaro_winkler_distance(s1, s2, p=0.1): + # Calculate the Jaro distance + m = 0 + s1_len = len(s1) + s2_len = len(s2) + match_distance = max(s1_len, s2_len) // 2 - 1 + s1_matches = [False] * s1_len + s2_matches = [False] * s2_len + for i in range(s1_len): + start = max(0, i - match_distance) + end = min(i + match_distance + 1, s2_len) + for j in range(start, end): + if s2_matches[j]: + continue + if s1[i] != s2[j]: + continue + s1_matches[i] = True + s2_matches[j] = True + m += 1 + break + if m == 0: + return 0.0 + transpositions = 0 + j = 0 + for i in range(s1_len): + if not s1_matches[i]: + continue + while not s2_matches[j]: + j += 1 + if s1[i] != s2[j]: + transpositions += 1 + j += 1 + jaro_distance = (m / s1_len + m / s2_len + (m - transpositions / 2) / m) / 3 + + # Calculate the Jaro-Winkler distance + l = 0 + for i in range(min(s1_len, s2_len)): + if s1[i] != s2[i]: + break + l += 1 + jaro_winkler_distance = jaro_distance + l * p * (1 - jaro_distance) + return jaro_winkler_distance + + +# Test the function +s1 = "MARTHA" +s2 = "MARHTA" +distance = jaro_winkler_distance(s1, s2) +print(f"Jaro-Winkler distance between '{s1}' and '{s2}' is {distance}") |
