问题背景

Py数:Py从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992,

这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22,

同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。

Py非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Py数。

现在给你一个十进制4位数n,你来判断n是不是Py数,若是,则输出Yes,否则输出No。

如n=2992,则输出Yes; n = 9999,则输出No。

解决方法

问题的核心:实现十进制向任意进制的转化

参考aaronthon:python的十进制与任意进制的转换方法,对其中的conversion函数进行改进,具体如下:

def conversion(n, d):
res=[]
if n
return [n]
else:
while(n//d >= 1):
res.append(n%d)
n = n//d
if(n%d !=0):
res.append(n%d)
return res[::-1]

其思路:

当被转换化数小于当前进制时,直接输出即可;

否则,采用$N = (N / d) * d + N%d $,进行进制转换(注:其输出是从地位到高位),所以上述改进中出现了:res[::-1].

公式理解:以下图为例:

python 16进制强制转换成2位的16进制数 python转化16进制_内置函数

(图片来源于:百度百科)

十进制整数转换为二进制整数采用"除2取余,逆序排列"法。具体做法是:用2整除十进制整数,可以得到一个商和余数;

再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,

然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来

完整程序:

# n:为被转化数
# d:为进制数
def conversion(n, d):
res=[]
if n
return [n]
else:
while(n//d >= 1):
res.append(n%d)
n = n//d
if(n%d !=0):
res.append(n%d)
return res[::-1]
if sum(conversion(n,10))==sum(conversion(n,12))\
and sum(conversion(n,10))==sum(conversion(n,16)):
print('Yes')
else:
print("No")

与内置进制转化数的对比

以123为例:

In [278]: conversion(123,2)
Out[278]: [1, 1, 1, 1, 0, 1, 1]
In [280]: bin(123)
Out[280]: '0b1111011'
In [281]: conversion(123,8)
Out[281]: [1, 7, 3]
In [282]: oct(123)
Out[282]: '0o173'
In [283]: conversion(123,16)
Out[283]: [7, 11]
In [284]: hex(123)
Out[284]: '0x7b'

从上述可以发现,通过conversion()函数转化的结果与内置函数的结果基本相同,唯一的区别是:当进制数大于10时,conversion仍然使用大于10小于进制数的余数,如123转16进制,而内置函数中关于超出来的一部分使用小写字母表示。为了保持与内置函数相同的输出类型,可以参考人民币转化通过建立字典即可。

任意进制的向10进制的还原

Python中使用内置函数int,如:

int(0x7b)
Out[285]: 123
In [286]: int(0o173)
Out[286]: 123
In [287]: int(0b1111011)
Out[287]: 123

conversion()结果的还原,比较简单。假定输出结果为res=[a,b,c],res:为转化后的进制数,结果从高位到地位,d:进制数,求被转化数位 old_num,按位加权求和即可。如:

\[old\_num=d^0*c+d^1*b+d^2*a
\]
In [302]: def converBack(res,d):^M
...: return sum([i*d**(len(res)-num-1) for num,i in enumerate(res)])
...:
In [303]: converBack([7,11],16)
Out[303]: 123
In [304]: converBack([1,7,3],8)
Out[304]: 123
In [305]: converBack([1,1,1,1,0,1,1],2)
Out[305]: 123