ここに表がありますhttp://en.wikipedia.org/wiki/File:Vigen%C3%A8re_square_shading.svg
このテーブルを Python で実装するにはどうすればよいですか? これにはどのような方法がありますか?
たとえば、行: L & 列 G を確認する方法についての手がかりは、R へようこそになります。
ここに表がありますhttp://en.wikipedia.org/wiki/File:Vigen%C3%A8re_square_shading.svg
このテーブルを Python で実装するにはどうすればよいですか? これにはどのような方法がありますか?
たとえば、行: L & 列 G を確認する方法についての手がかりは、R へようこそになります。
>>> letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> mat = [(letters * 2)[i:i+26] for i in range(26)]
>>> print '\n'.join(mat)
ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDEFGHIJKLMNOPQRSTUVWXYZA
CDEFGHIJKLMNOPQRSTUVWXYZAB
DEFGHIJKLMNOPQRSTUVWXYZABC
EFGHIJKLMNOPQRSTUVWXYZABCD
FGHIJKLMNOPQRSTUVWXYZABCDE
GHIJKLMNOPQRSTUVWXYZABCDEF
HIJKLMNOPQRSTUVWXYZABCDEFG
IJKLMNOPQRSTUVWXYZABCDEFGH
JKLMNOPQRSTUVWXYZABCDEFGHI
KLMNOPQRSTUVWXYZABCDEFGHIJ
LMNOPQRSTUVWXYZABCDEFGHIJK
MNOPQRSTUVWXYZABCDEFGHIJKL
NOPQRSTUVWXYZABCDEFGHIJKLM
OPQRSTUVWXYZABCDEFGHIJKLMN
PQRSTUVWXYZABCDEFGHIJKLMNO
QRSTUVWXYZABCDEFGHIJKLMNOP
RSTUVWXYZABCDEFGHIJKLMNOPQ
STUVWXYZABCDEFGHIJKLMNOPQR
TUVWXYZABCDEFGHIJKLMNOPQRS
UVWXYZABCDEFGHIJKLMNOPQRST
VWXYZABCDEFGHIJKLMNOPQRSTU
WXYZABCDEFGHIJKLMNOPQRSTUV
XYZABCDEFGHIJKLMNOPQRSTUVW
YZABCDEFGHIJKLMNOPQRSTUVWX
ZABCDEFGHIJKLMNOPQRSTUVWXY
または、その場で要素を計算することもできます。
def get_elem(row, col):
return 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[(ord(row) + ord(col)) % 26]
print get_elem('L', 'G')
私は、可能な限り標準ライブラリを使用して、自分のコードをローリングしたり、うっかり書き忘れたり (文字を誤って置き忘れたり、忘れたりするなど) することを避けたいと考えています。
import string
import collections
def vigsquare(printable=False):
'''
Returns a string like a vigenere square,
printable joins each row with a newline so it's literally square
printable=False (defaul) joins without newlines for easier
searching by row and column index
'''
alpha = string.ascii_uppercase
rotater = collections.deque(alpha)
vigsquare_list = []
for i in xrange(26):
vigsquare_list.append(''.join(rotater))
rotater.rotate(-1)
if printable:
return '\n'.join(vigsquare_list)
else:
return ''.join(vigsquare_list)
と
def vigenere(row, column):
'''
Return a character from a vigenere square by
row and column letter.
vigenere('L', 'G') returns 'R'
'''
alpha = string.ascii_uppercase
rowindex = alpha.find(row)
columnindex = alpha.find(column)
return vigsquare()[rowindex*26 + columnindex]
print vigsquare(printable=True)
vigenere('L', 'G')
あなたにあげる:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
BCDEFGHIJKLMNOPQRSTUVWXYZA
CDEFGHIJKLMNOPQRSTUVWXYZAB
DEFGHIJKLMNOPQRSTUVWXYZABC
EFGHIJKLMNOPQRSTUVWXYZABCD
FGHIJKLMNOPQRSTUVWXYZABCDE
GHIJKLMNOPQRSTUVWXYZABCDEF
HIJKLMNOPQRSTUVWXYZABCDEFG
IJKLMNOPQRSTUVWXYZABCDEFGH
JKLMNOPQRSTUVWXYZABCDEFGHI
KLMNOPQRSTUVWXYZABCDEFGHIJ
LMNOPQRSTUVWXYZABCDEFGHIJK
MNOPQRSTUVWXYZABCDEFGHIJKL
NOPQRSTUVWXYZABCDEFGHIJKLM
OPQRSTUVWXYZABCDEFGHIJKLMN
PQRSTUVWXYZABCDEFGHIJKLMNO
QRSTUVWXYZABCDEFGHIJKLMNOP
RSTUVWXYZABCDEFGHIJKLMNOPQ
STUVWXYZABCDEFGHIJKLMNOPQR
TUVWXYZABCDEFGHIJKLMNOPQRS
UVWXYZABCDEFGHIJKLMNOPQRST
VWXYZABCDEFGHIJKLMNOPQRSTU
WXYZABCDEFGHIJKLMNOPQRSTUV
XYZABCDEFGHIJKLMNOPQRSTUVW
YZABCDEFGHIJKLMNOPQRSTUVWX
ZABCDEFGHIJKLMNOPQRSTUVWXY
と
'R'
ここで興味深い別の解決策がありましたが、理解できなかったので信頼できませんでした。そのため、自分のコードと他のコードを単体テストして、信頼できるかどうかを確認します。
def vig_2(row, col):
return string.ascii_uppercase[(ord(row) + ord(col)) % 26]
そして、両方のアプローチを比較して単体テストを行いました。2番目のもの(私が今賛成票を投じているNPEから借りたもの)は、それが正しい場合、よりパフォーマンスが高い可能性があります。
import unittest
class VigTestCase(unittest.TestCase):
def test_vigenere(self):
self.assertEqual(vigenere('L', 'G'), 'R')
def test_vigsquare(self):
self.assertEqual(vigsquare(printable=False), 'ABCDEFGHIJKLMNOPQRSTUVWXYZBCDEFGHIJKLMNOPQRSTUVWXYZACDEFGHIJKLMNOPQRSTUVWXYZABDEFGHIJKLMNOPQRSTUVWXYZABCEFGHIJKLMNOPQRSTUVWXYZABCDFGHIJKLMNOPQRSTUVWXYZABCDEGHIJKLMNOPQRSTUVWXYZABCDEFHIJKLMNOPQRSTUVWXYZABCDEFGIJKLMNOPQRSTUVWXYZABCDEFGHJKLMNOPQRSTUVWXYZABCDEFGHIKLMNOPQRSTUVWXYZABCDEFGHIJLMNOPQRSTUVWXYZABCDEFGHIJKMNOPQRSTUVWXYZABCDEFGHIJKLNOPQRSTUVWXYZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMNPQRSTUVWXYZABCDEFGHIJKLMNOQRSTUVWXYZABCDEFGHIJKLMNOPRSTUVWXYZABCDEFGHIJKLMNOPQSTUVWXYZABCDEFGHIJKLMNOPQRTUVWXYZABCDEFGHIJKLMNOPQRSUVWXYZABCDEFGHIJKLMNOPQRSTVWXYZABCDEFGHIJKLMNOPQRSTUWXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVWYZABCDEFGHIJKLMNOPQRSTUVWXZABCDEFGHIJKLMNOPQRSTUVWXY')
def test_vig2(self):
for i in string.ascii_uppercase:
for j in string.ascii_uppercase:
self.assertEqual(vig_2(i, j), vigenere(i, j))
unittest.main()
...
----------------------------------------------------------------------
Ran 3 tests in 0.038s
OK
したがって、NPE には非常に優れたソリューションがあったようです。