aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2023-03-13 21:53:13 +0000
committerGitHub <noreply@github.com>2023-03-13 21:53:13 +0000
commit2cb00557ab6964716d9bd448dd2067875520e1c9 (patch)
tree8501bf78213b710e518382d514eca88995ae5d13
parent784cb54bac261893b8064ccf8c9018328cb7c471 (diff)
parent021477f72d3a160def575c197b93afa1a7fb2ae1 (diff)
downloadperlweeklychallenge-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.pl24
-rw-r--r--challenge-009/lubos-kolouch/perl/ch-2.pl61
-rw-r--r--challenge-009/lubos-kolouch/python/ch-1.py16
-rw-r--r--challenge-009/lubos-kolouch/python/ch-2.py46
-rw-r--r--challenge-010/lubos-kolouch/perl/ch-1.pl73
-rw-r--r--challenge-010/lubos-kolouch/perl/ch-2.pl66
-rw-r--r--challenge-010/lubos-kolouch/python/ch-1.py48
-rw-r--r--challenge-010/lubos-kolouch/python/ch-2.py53
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}")