aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2024-09-29 15:18:51 +0100
committerPaulo Custodio <pauloscustodio@gmail.com>2024-09-29 15:18:51 +0100
commit3bfbde53c142da8b0a3176380aa87a7534658fca (patch)
tree93957d7fa86a73a1f8965096ea5218a34fa40beb
parent85dfd261a678406d6d22eb45168fd3fb4d93c3a3 (diff)
downloadperlweeklychallenge-club-3bfbde53c142da8b0a3176380aa87a7534658fca.tar.gz
perlweeklychallenge-club-3bfbde53c142da8b0a3176380aa87a7534658fca.tar.bz2
perlweeklychallenge-club-3bfbde53c142da8b0a3176380aa87a7534658fca.zip
Add Python solution to challenge 162
-rw-r--r--challenge-001/paulo-custodio/go.pl5
-rw-r--r--challenge-162/paulo-custodio/python/ch-1.py28
-rw-r--r--challenge-162/paulo-custodio/python/ch-2.py105
3 files changed, 136 insertions, 2 deletions
diff --git a/challenge-001/paulo-custodio/go.pl b/challenge-001/paulo-custodio/go.pl
index 3904778b45..b41860b43a 100644
--- a/challenge-001/paulo-custodio/go.pl
+++ b/challenge-001/paulo-custodio/go.pl
@@ -9,8 +9,9 @@ my $nr = sprintf("%03d", $ARGV[0]);
path("challenge-$nr/paulo-custodio")->mkpath;
#for my $dir (qw(ada awk basic bc brainfuck c cpp d forth fortran lua pascal perl python t)) {
-# path("challenge-$nr/paulo-custodio/$dir")->mkpath;
-#}
+for my $dir (qw( perl python t )) {
+ path("challenge-$nr/paulo-custodio/$dir")->mkpath;
+}
path("challenge-$nr/paulo-custodio/README")->spew("Solution by Paulo Custodio\n");
if (! -f "challenge-$nr/paulo-custodio/Makefile") {
diff --git a/challenge-162/paulo-custodio/python/ch-1.py b/challenge-162/paulo-custodio/python/ch-1.py
new file mode 100644
index 0000000000..1b31447b25
--- /dev/null
+++ b/challenge-162/paulo-custodio/python/ch-1.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+
+# Challenge 162
+#
+# Task 1: ISBN-13
+# Submitted by: Mohammad S Anwar
+# Write a script to generate the check digit of given ISBN-13 code. Please
+# refer wikipedia for more information.
+#
+# Example
+# ISBN-13 check digit for '978-0-306-40615-7' is 7.
+
+import sys
+
+def isbn13_check_digit(isbn):
+ m = 1
+ sum_ = 0
+ isbn = isbn.replace('-', '')
+ for i in range(12):
+ digit = int(isbn[i])
+ sum_ += m * digit
+ m = 3 if m==1 else 1
+ digit = sum_ % 10
+ if digit != 0:
+ digit = 10-digit
+ return digit
+
+print(isbn13_check_digit(sys.argv[1]))
diff --git a/challenge-162/paulo-custodio/python/ch-2.py b/challenge-162/paulo-custodio/python/ch-2.py
new file mode 100644
index 0000000000..aad3aadf83
--- /dev/null
+++ b/challenge-162/paulo-custodio/python/ch-2.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+
+# Challenge 162
+#
+# Task 2: Wheatstone-Playfair
+# Submitted by: Roger Bell_West
+# Implement encryption and decryption using the Wheatstone-Playfair cipher.
+#
+# Examples:
+# (These combine I and J, and use X as padding.)
+#
+# encrypt("playfair example", "hide the gold in the tree stump")
+# = "bmodzbxdnabekudmuixmmouvif"
+#
+# decrypt("perl and raku", "siderwrdulfipaarkcrw") = "thewexeklychallengex"
+
+class WPcipher:
+ def __init__(self, key_phrase):
+ self.key = [[] for _ in range(5)]
+ self.letters = {}
+ self.make_key(key_phrase)
+
+ def make_key(self, key_phrase):
+ row, col = 0, 0
+ for c in (key_phrase.lower() + ''.join(chr(i) for i in range(ord('a'), ord('z') + 1))):
+ if not c.isalpha() or c not in 'abcdefghijklmnopqrstuvwxyz':
+ continue
+ c = 'i' if c == 'j' else c
+ if c in self.letters:
+ continue
+
+ self.key[row].append(c)
+ self.letters[c] = (row, col)
+
+ col += 1
+ if col >= 5:
+ row += 1
+ col = 0
+ if row >= 5:
+ break
+
+ def peek(self, row, col):
+ return self.key[(row + 5) % 5][(col + 5) % 5]
+
+ def encrypt_pair(self, a, b, direction):
+ for char in (a, b):
+ if char not in 'abcdefghiklmnopqrstuvwxyz':
+ raise ValueError(f"Invalid character: {char}")
+ if a == b:
+ raise ValueError("Characters must not be the same")
+
+ row1, col1 = self.letters[a]
+ row2, col2 = self.letters[b]
+
+ if row1 == row2:
+ return (self.peek(row1, col1 + direction),
+ self.peek(row2, col2 + direction))
+ elif col1 == col2:
+ return (self.peek(row1 + direction, col1),
+ self.peek(row2 + direction, col2))
+ else:
+ return (self.peek(row1, col2),
+ self.peek(row2, col1))
+
+ def encrypt_string(self, text, direction):
+ text = text.lower()
+ out = ""
+ while text:
+ if len(text) == 1:
+ text += "x"
+ if text[0] == text[1:2]: # repeated first character
+ a = text[0]
+ b = "x"
+ text = text[1:]
+ else:
+ a = text[0]
+ b = text[1]
+ text = text[2:]
+
+ x, y = self.encrypt_pair(a, b, direction)
+ out += x + y
+ return out
+
+ def encrypt(self, text):
+ text = ''.join(filter(str.isalpha, text)).lower().replace('j', 'i')
+ return self.encrypt_string(text, 1)
+
+ def decrypt(self, code):
+ return self.encrypt_string(code, -1)
+
+
+import sys
+
+if len(sys.argv) != 4:
+ raise ValueError("Usage: ch-2.py -e|-d key text")
+
+op, key_phrase, text = sys.argv[1], sys.argv[2], sys.argv[3]
+
+wp = WPcipher(key_phrase)
+if op == "-e":
+ print(wp.encrypt(text))
+elif op == "-d":
+ print(wp.decrypt(text))
+else:
+ raise ValueError("Usage: ch-2.py -e|-d key text")