室友问我题目,把我难住了。想不出解法,遂写了个程序暴力求解。
题目如下:
A permutation is applied to the string SUPERBGOLDHAT. The same permutation is applied to the output from this operation. The second output is OGTHLEPDSUARB. What was the first output? (Note: as an example, the permutation(1 3 4) applied to WOLF gives FOWL. Write your answer in capital letters inside quotation marks, e.g. "BEARDPLUGHOST".)
上面这段文字说的是,一个变换规则作用于字符串SUPERBGOLDHAT, 生成一个新字符串。再次将相同的变换规则作用于这个新字符串,得到一个经过两次变换的字符串OGTHLEPDSUARB. 求第一次变换后的字符串。
背景知识
首先简单说明一下什么是置换。
首先给定一个序列
然后给定一个置换
那么,置换
以此类推
第一次: 3 5 2 6 4 1
第二次: 2 4 5 1 6 3
第三次: 5 6 4 3 1 2
上面表示置换的方法叫两行式,此外,我们还可以用轮换来表示一个置换
举个例子,如下是一个两行式表示的置换
它表示成是轮换是
以上的
如果一个变换将 i<sub>1</sub> $rightarrow$ i<sub>2</sub>, i<sub>2</sub> $rightarrow$ i<sub>3</sub>, $ldots $ i<sub>k</sub> $rightarrow $ i<sub>1</sub>, 而其他各元不变,那么该置换称为k-循环置换(k-cycle),写作 ( i<sub>1</sub>,i<sub>2</sub>,i<sub>3</sub> $ldots $ i<sub>k</sub> ).
除了k-循环置换之外,还有一种置换叫做非循环置换
一个k-循环置换, 总是可以表示为一个轮换
一个非循环置换,则总是可以表示成几个轮换的积
例如,非循环置换
(以上参考自: 置换群题目汇总, 《近世代数》杨子胥)
代码
下面这段Python代码通过遍历,暴力求解了文章开始我们给出的那道置换题目。
import numpy as np
import itertools
# a is something like index
# b is the second output you want
# C (capital) is the first output we guess
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
a = a-1
b = np.array([8, 7, 13, 11, 9, 4, 3, 10, 1, 2, 12, 5, 6])
b = b-1
c = np.zeros([a.size])
# traverse all permutations of a
for C in itertools.permutations(a, a.size):
print(C)
for num in C:
# c (lower case) is the second output in this iteration
c[num] = C[C[num]]
if (b == c).all():
C = [x+1 for x in C]
print('The answer is ', C)
break
这段代码中,最精髓的一句是
这个程序跑了一天,终于跑出来了(巨汗),给大家展示一下
最终的输出为
它的含义是, 序列a
但计算机真的算得太慢了,补上我新学的人脑解法 ^ _ ^