鱼C论坛

 找回密码
 立即注册
查看: 4685|回复: 18

[技术交流] Python: 每日一题 45

[复制链接]
发表于 2017-5-14 18:45:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 ooxx7788 于 2017-5-15 10:35 编辑

上一题,我们知道了,摩斯码是由 点("Dot")和划("Dash")组成。
但实际上更准确的说法,应该是摩斯码是由点、划、点和划之间的停顿、每个字符间短的停顿、每个词之间中等的停顿以及句子之间长的停顿组成的。

现在我们来定义一下各个组成部分的时间长度,为了更好的理解这部分,建议你可以自己尝试按出摩斯码的节奏。
1、点("Dot")——1个单位时间长度
2、划("Dash")——3个单位时间长度
3、每个字母内的点和划之间的停顿——1个单位时间长度
4、每个词内字母之间的停顿——3个单位时间长度
5、词与词之间的停顿——7个单位时间长度

然而,实际上无法定义‘单位时间长度’是多长。(个人认为应该是在那个手工发报的年代无法定义)。由于不同的发报人传送的速度可能是不相同的。
业余的发报人需要几秒才能传出一个字母(当你按照我上面说的自己按出摩斯码的节奏是,就会发现自己按的实际很慢),而一个专业的发报人一分钟可以发出60个字母。而机器发报则可以更快。

在这一题中,我们假定收到的是由自动化设备接收的规律性信号。
以下开始是重点了:
当线路接通时(也就是当按下发报键时),记录1。
当线路未接通时(也就是当弹起发报键时),记录0。
当整个信息被完全接收时,你会获得一个只包含了0和1的字符串。

例如:
信息:HEY JUDE
摩斯码为:···· · −·−−   ·−−− ··− −·· ·
字符串为:1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011

由此,你可以看出,转换设备非常精确的记录了信息,在这里转换设备采样线路中每个点(DOT)为两个单位时间长度。(由于对于理解转换比较关键,所以我也给出原文,防止我翻译中的不准确。)
As you may see, this transmission is perfectly accurate according to the standard, and the hardware sampled the line exactly two times per "dot".
(译注:只是在此范例中采用的是两倍时长为一个DOT的长度,并不代表所有的测试样本都是两倍时常。其可能是3倍,4倍,也可能是1倍。所以题目第一个函数的要求,就是首先要能判断出频率。)

现在,你的任务是实现两个函数:
1、函数  decodeBits(bits),用于找出信息转换中的频率,准确的将字符串信息解码为由点(.)、划(-)和空格组成的新字符串(也就是上一题中我们传入函数中的参数。)注意:会出现额外的0在开始和结尾,你应当去除掉它们。同时,如果你在辨别个别连续的1是否是点还是划时,假定其为点。
2、函数 decodeMorse(morseCode),这将以上的输出转换为一个人类可读的字符串的函数(其实也就是上一题)。

That's all.
避免我的翻译不准确跟您带来额外困扰,我给出原文的地址:https://www.codewars.com/kata/54b72c16cd7f5154e9000457

我的答案:
游客,如果您要查看本帖隐藏内容请回复






最后找了一张图,这张图说明了,解释了字母的点和划的设置是如何来的。当然,这与本题并无关。

摩斯码.jpg

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-5-14 21:03:02 | 显示全部楼层
先写一个,慢慢优化。
def decodeBits(bits):
    lst1 = bits.split('0')
    lst1 = list(set(lst1))
    lst1.sort()
    freq = len(lst1[1])
    str2 = ''
    for i in range(len(bits) // freq):
        str2 += bits[i * freq]
    print(str2)
    str3 = ''
    while str2 != '':
        if str2.startswith('0000000'):
            str3 += '   '
            str2 = str2.lstrip('0000000')
        elif str2.startswith('000'):
            str3 += ' '
            str2 = str2.lstrip('000')
        elif str2.startswith('0'):
            str2 = str2.lstrip('0')
        elif str2.startswith('111'):
            str3 += '-'
            str2 = str2.lstrip('111')
        elif str2.startswith('1'):
            str3 += '.'
            str2 = str2.lstrip('1')
        else:
            print('Error!')
            break
    return str3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-14 21:24:45 | 显示全部楼层
冬雪雪冬 发表于 2017-5-14 21:03
先写一个,慢慢优化。


试试看decodeBits('1')
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-14 21:33:16 | 显示全部楼层
ooxx7788 发表于 2017-5-14 21:24
试试看decodeBits('1')

修修补补。
def decodeBits(bits):
    lst1 = bits.split('0')
    lst1 = list(set(lst1))
    lst1.sort()
    if lst1[0] == '':
        freq = len(lst1[1])
    else:
        freq = len(lst1[0])
    str2 = ''
    for i in range(len(bits) // freq):
        str2 += bits[i * freq]
    str3 = ''
    while str2 != '':
        if str2.startswith('0000000'):
            str3 += '   '
            str2 = str2.lstrip('0000000')
        elif str2.startswith('000'):
            str3 += ' '
            str2 = str2.lstrip('000')
        elif str2.startswith('0'):
            str2 = str2.lstrip('0')
        elif str2.startswith('111'):
            str3 += '-'
            str2 = str2.lstrip('111')
        elif str2.startswith('1'):
            str3 += '.'
            str2 = str2.lstrip('1')
        else:
            print('Error!')
            break
    return str3
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-14 21:42:00 | 显示全部楼层
冬雪雪冬 发表于 2017-5-14 21:03
先写一个,慢慢优化。

decodeBits(1110111)

Got 'E', expected 'M'
新三年,旧三年,缝缝补补又3年。
用1来做频率判断,可不一定对哦?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-14 21:44:28 | 显示全部楼层
ooxx7788 发表于 2017-5-14 21:42
decodeBits(1110111)

Got 'E', expected 'M'

我再想想,尽量完善了再发。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-16 00:06:04 | 显示全部楼层
def decodeBits(rawdata):
    rawdata = rawdata.strip('0')
    for i in range(20,0,-1):
        if len(rawdata) % i != 0:
            continue
        else:
            flag = True
            for j in range(len(rawdata)//i):
                if len(set(list(rawdata[j*i:j*i+i]))) > 1:
                    flag = False
                    break
            if flag:
                data = rawdata.replace('0'*i, '0').replace('1'*i, '1')
                return data.replace('0'*7, '   ').replace('0'*3, ' ').replace('1'*3, '-').replace('1', '.').replace('0', '')

def decodeMorse(morse):
    MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5', '...---...': 'SOS', '-...': 'B', '-..-': 'X', '.-.': 'R', '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F', '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', '.----': '1', '-.-': 'K', '-..': 'D', '-....': '6', '-...-': '=', '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', '-.': 'N', '....': 'H', '.----.': "'", '...-': 'V', '--...': '7', '-.-.-.': ';', '-....-': '-', '..--.-': '_', '-.--.-': ')', '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/', '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T', '.--.-.': '@', '...-..-': ', '.---': 'J', '-----': '0', '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}
    words = ''
    morselist = morse.strip().split('   ')
    for each in morselist:
        words += ''.join([MORSE_CODE[e] for e in each.split()])
        words += ' '
    return words.strip()

print(decodeMorse(decodeBits('1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011')))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-21 10:52:03 | 显示全部楼层
题目都看不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-21 11:45:07 | 显示全部楼层

重点都标注出来了,也看不懂哦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-22 11:41:21 | 显示全部楼层
MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5', '...---...': 'SOS', '-...': 'B', '-..-': 'X', '.-.': 'R', '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F', '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', '.----': '1', '-.-': 'K', '-..': 'D', '-....': '6', '-...-': '=', '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', '-.': 'N', '....': 'H', '.----.': "'", '...-': 'V', '--...': '7', '-.-.-.': ';', '-....-': '-', '..--.-': '_', '-.--.-': ')', '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/', '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T', '.--.-.': '@', '...-..-': ', '.---': 'J', '-----': '0', '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}
def decodeMorse(morseCode):
    c=[]
    ci=morseCode.strip().split('   ')
    for i in ci:
        x=i.strip().split(' ')
        for j in x:
            c.append(MORSE_CODE[j])
        c.append(' ')
    return ''.join(c)


def decodeBits(bits):
    B={'0':'','1':'.'}
    B3={'0':' ','1':'-'}
    if '101' in bits:
        i=1
    elif '1001' in bits:
        i=2
    elif '10001' in bits:
        i=3
    else:
        i=4
    bits=bits[::i]+'0'
    bits='000000000'.join(bits.split('0000000'))
    C=[]
    w=bits[0]
    s=0
    lb=len(bits)
    for j in range(lb):
        if bits[j]==w:
            s+=1
            if s==3:
                C.append(B3[w])
                s=0
                if j<lb-1:
                    w=bits[j+1]            
        else:
            C.append(B[w])
            w=bits[j]
            s=1
    return ''.join(C).strip()
            
x=decodeBits('1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011')
print(decodeMorse(x))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-22 11:46:48 | 显示全部楼层
10001
Got 'E', expected 'EE'

111000000000111
Got 'I', expected 'EE'

好像还有其他错误。但求值本身也是有问题的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-4 21:32:52 | 显示全部楼层
个人解读一下题目:
实际收到电报内容是1和0,1是点/划,0是停顿
要从中 0、1 出现的频率解码出莫斯密码的内容,再从出莫斯密码中解密出密文

其中,点=1t, 划=3t,字母内点划间停顿=1t, 字母间停顿=3t, 单词间停顿=7t
而t是频率,因人而异,t=1,2,3,4...n
另外,电报首尾的0是无效的,特殊情况不能区分点和划时,默认为点
#这题没有测试,不确定调整方向,某些情况可能会报错
MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5',\
              '...---...': 'SOS', '-...': 'B', '-..-': 'X', '.-.': 'R', \
              '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F',\
              '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', \
              '.----': '1', '-.-': 'K', '-..': 'D', '-....': '6', '-...-': '=', \
              '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', '-.': 'N', \
              '....': 'H', '.----.': "'", '...-': 'V', '--...': '7',\
              '-.-.-.': ';', '-....-': '-', '..--.-': '_', '-.--.-': ')',\
              '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/',\
              '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T',\
              '.--.-.': '@', '...-..-': ', '.---': 'J', '-----': '0', \
              '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}
s = "1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011"

# 知道对应倍率,只要判断出频率即可,通过0/1中最短的连续次数得出频率,次数相等默认为点
def decodeBits(bits):
    morse = {'1':'.', '111':'-'}    
    b = bits.strip('0')
    if set(b)=={'1'} or set(b)=={'0'}: # 全部0或全部1的情况
        return ""
    zeroes = min([i for i in b.split('1') if i != ""])
    ones = min([i for i in b.split('0') if i != ""])
    hz = min(len(zeroes),len(ones))
    new_b = b[::hz] # 消去频率影响
    
    return "".join([morse[i] if i!="" else " " for i in new_b.split('0')]).replace("  "," ")

def decodeMorse(s):
    return "".join([MORSE_CODE.get(i) if i !="" else " " for i in s.split(" ")]).strip().replace("  "," ")

print(decodeMorse(decodeBits(s)))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-8 15:13:24 | 显示全部楼层
本帖最后由 shigure_takimi 于 2017-12-8 15:14 编辑
MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5', \
              '...---...': 'SOS', '-...': 'B', '-..-': 'X', '.-.': 'R', \
              '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F', \
              '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', \
              '.----': '1', '-.-': 'K', '-..': 'D', '-....': '6', '-...-': '=', \
              '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', '-.': 'N', \
              '....': 'H', '.----.': "'", '...-': 'V', '--...': '7', \
              '-.-.-.': ';', '-....-': '-', '..--.-': '_', '-.--.-': ')', \
              '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/', \
              '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T', \
              '.--.-.': '@', '...-..-': ', '.---': 'J', '-----': '0', \
              '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}

charToMorse = {}
for key in MORSE_CODE:
    charToMorse[MORSE_CODE[key]] = key

def getMorseCode(string):
    string = string.upper().strip().split(' ')
    eachMorse = []
    for word in string:
        if word == 'SOS':
            eachMorse.append(charToMorse[word])
        else:
            wordMorse = []
            for char in word:
                wordMorse.append(charToMorse[char])
            wordMorse = ' '.join(wordMorse)
            eachMorse.append(wordMorse)
    return '   '.join(eachMorse)

def decodeMorse(morseCode):
    morseCode = morseCode.strip().split('   ')
    allWords = []
    for word in morseCode:
        word = word.strip().split(' ')
        word = ''.join([MORSE_CODE[i] for i in word])
        allWords.append(word)
    return ' '.join(allWords)

def decodeBits(bits):
    bits = bits.strip('0')
    bits = bits.replace('00000000000000','   ')
    bits = bits.replace('000000',' ')
    bits = bits.replace('111111','-')
    bits = bits.replace('11','.')
    bits = bits.replace('00','')
    return bits

a = decodeBits('00110011001100110000001100000011111100110011111100111111000000000000001100111111001111110011111100000011001100111111000000111111001100110000001100')
print(a)
print(decodeMorse(a))

##  >>> 
##  .... . -.--   .--- ..- -.. .
##  HEY JUDE
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-12 14:06:47 | 显示全部楼层
MORSE_CODE = {'.-...': '&', '--..--': ',', '....-': '4', '.....': '5', '...---...': 'SOS', '-...': 'B', 
              '-..-': 'X', '.-.': 'R', '.--': 'W', '..---': '2', '.-': 'A', '..': 'I', '..-.': 'F', 
              '.': 'E', '.-..': 'L', '...': 'S', '..-': 'U', '..--..': '?', '.----': '1', '-.-': 'K', 
              '-..': 'D', '-....': '6', '-...-': '=', '---': 'O', '.--.': 'P', '.-.-.-': '.', '--': 'M', 
              '-.': 'N', '....': 'H', '.----.': "'", '...-': 'V', '--...': '7', '-.-.-.': ';', '-....-': '-', 
              '..--.-': '_', '-.--.-': ')', '-.-.--': '!', '--.': 'G', '--.-': 'Q', '--..': 'Z', '-..-.': '/', 
              '.-.-.': '+', '-.-.': 'C', '---...': ':', '-.--': 'Y', '-': 'T', '.--.-.': '@', '...-..-': ', 
              '.---': 'J', '-----': '0', '----.': '9', '.-..-.': '"', '-.--.': '(', '---..': '8', '...--': '3'}

def decodeBits(bits):        
    for t in range(1,len(bits)):       #第一步:用于找出信息转换中的频率t(我的理解是找出最少的连续0的个数)
        if '1'+'0'*t+'1' in bits:
            break
    #第二步:根据频率,把bits转成Morse码    
    return bits.replace('0'*7*t,' '*3).replace('1'*3*t,'-').replace('0'*3*t,' ').replace('1'*t,'.').replace('0'*t,'')    

def decodeMorse(morseCode):    #解析morse码,转成字符      
    res=''
    for ms in morseCode.strip().split(' '):
        if ms=='':
            res+=' '
        else:
            res+=MORSE_CODE[ms]
    return res.replace('  ',' ')  #双空格改为单空格

testbits='1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011'
print('接收到的字符串:',testbits)
print('转换成Morse:',decodeBits(testbits))
print('破译成可识别字符:',decodeMorse(decodeBits(testbits)))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-7-3 19:02:04 | 显示全部楼层
没读懂。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-28 15:37:56 From FishC Mobile | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-18 19:18:58 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-28 16:01:23 | 显示全部楼层
学习一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-4-12 20:04:33 | 显示全部楼层
完全看不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-16 05:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表