Python解决Cipher Map问题

题目

声明:题目来源为Checkio
Help Sofia write a decrypter for the passwords that Nikola will encrypt through the cipher map. A cipher grille is a 4×4 square of paper with four windows cut out. Placing the grille on a paper sheet of the same size, the encoder writes down the first four symbols of his password inside the windows (see fig. below). After that, the encoder turns the grille 90 degrees clockwise. The symbols written earlier become hidden under the grille and clean paper appears inside the windows. The encoder then writes down the next four symbols of the password in the windows and turns the grille 90 degrees again. Then, they write down the following four symbols and turns the grille once more. Lastly, they write down the final four symbols of the password. Without the same cipher grille, it is difficult to discern the password from the resulting square comprised of 16 symbols. Thus, the encoder can be confident that no hooligan will easily gain access to the locked door.
problem

题意理解

Cipher Map问题的大意是:给定一个解码器和一个加密后的密码,解码器和密码都是4*4的(如上图所示),其中解码器中包含四个“窗口”,将解码器和密码重叠,四个窗口中的内容按从左到右,从上到下的顺序组合起来就是密码的一部分,然后将解码器顺时针旋转90°,重复上述操作直至解码器旋转270°为止,四部分组合起来就是密码。

输入

解码器元组和密码元组都是数据类型为字符串的元组,解码器元组和密码元组都分别包含4个串长为4的字符串,解码器元组中的字符串使用’X’代表窗口所在的位置,输入样例如下:

#解码器
('X...',
 '..X.',
 'X..X',
 '....')
 #密码
('itdf',
'gdce',
'aton',
'qrdi')

输出

输出结果为解密后的字符串,例如上述样例的输出结果为:

'icantforgetiddqd'

解题思路

根据题意,只需要对解码器与密码重叠,找到加密后的4*4密码中’X‘所对应的元素提取出来,重复如此,直至解码器旋转满270°,其中解码器每顺时针旋转90°就要重叠提取一次,那么问题的关键就变成了如何将解码器旋转90°。其实,实现解码器旋转90°也很简单,按逆序(从最后一个字符串开始到第一个字符串为止)依次提取对应位置的第一个字符作为第一行,接着按同样的顺序提取四个字符串的第二个字符作为第二行,依次类推直至取完4个字符,这样就可以的得到原4*4数组旋转90°后的新4*4数组。

代码

def recall_password(cipher_grille, ciphered_password):
    ciphers = []
    ciphers.append(cipher_grille)
    for i in range(3):
        cipher_grille = [[cipher_grille[i][j] for i in reversed(range(4))] for j in range(4)]
        ciphers.append(cipher_grille)
    
    out = ''
    for cipher in ciphers:
        for i,item in enumerate(cipher):
            for j,ch in enumerate(item):
                if ch == 'X':
                    out += ciphered_password[i][j]

    return out


if __name__ == '__main__':
    assert recall_password(
        ('X...',
         '..X.',
         'X..X',
         '....'),
        ('itdf',
         'gdce',
         'aton',
         'qrdi')) == 'icantforgetiddqd', 'First example'

    assert recall_password(
        ('....',
         'X..X',
         '.X..',
         '...X'),
        ('xhwc',
         'rsqx',
         'xqzz',
         'fyzr')) == 'rxqrwsfzxqxzhczy', 'Second example'
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯曦巍峨

码文不易,有条件的可以支持一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值