ooxx7788 发表于 2017-5-14 18:45:23

Python: 每日一题 45

本帖最后由 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

我的答案:
**** Hidden Message *****





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

冬雪雪冬 发表于 2017-5-14 21:03:02

先写一个,慢慢优化。
def decodeBits(bits):
    lst1 = bits.split('0')
    lst1 = list(set(lst1))
    lst1.sort()
    freq = len(lst1)
    str2 = ''
    for i in range(len(bits) // freq):
      str2 += bits
    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

ooxx7788 发表于 2017-5-14 21:24:45

冬雪雪冬 发表于 2017-5-14 21:03
先写一个,慢慢优化。

{:5_97:}
试试看decodeBits('1')

冬雪雪冬 发表于 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 == '':
      freq = len(lst1)
    else:
      freq = len(lst1)
    str2 = ''
    for i in range(len(bits) // freq):
      str2 += bits
    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

ooxx7788 发表于 2017-5-14 21:42:00

冬雪雪冬 发表于 2017-5-14 21:03
先写一个,慢慢优化。

decodeBits(1110111)

Got 'E', expected 'M'
新三年,旧三年,缝缝补补又3年。
用1来做频率判断,可不一定对哦?

冬雪雪冬 发表于 2017-5-14 21:44:28

ooxx7788 发表于 2017-5-14 21:42
decodeBits(1110111)

Got 'E', expected 'M'


我再想想,尽量完善了再发。

jerryxjr1220 发表于 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))) > 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( for e in each.split()])
      words += ' '
    return words.strip()

print(decodeMorse(decodeBits('1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011')))

willLin 发表于 2017-5-21 10:52:03

题目都看不懂

ooxx7788 发表于 2017-5-21 11:45:07

willLin 发表于 2017-5-21 10:52
题目都看不懂

重点都标注出来了,也看不懂哦

余欲渔 发表于 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)
      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
    s=0
    lb=len(bits)
    for j in range(lb):
      if bits==w:
            s+=1
            if s==3:
                C.append(B3)
                s=0
                if j<lb-1:
                  w=bits            
      else:
            C.append(B)
            w=bits
            s=1
    return ''.join(C).strip()
            
x=decodeBits('1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011')
print(decodeMorse(x))

ooxx7788 发表于 2017-5-22 11:46:48

余欲渔 发表于 2017-5-22 11:41


10001
Got 'E', expected 'EE'

111000000000111
Got 'I', expected 'EE'

好像还有其他错误。但求值本身也是有问题的。

solomonxian 发表于 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()
    ones = min()
    hz = min(len(zeroes),len(ones))
    new_b = b[::hz] # 消去频率影响
   
    return "".join( if i!="" else " " for i in new_b.split('0')]).replace(""," ")

def decodeMorse(s):
    return "".join().strip().replace(""," ")

print(decodeMorse(decodeBits(s)))

shigure_takimi 发表于 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] = key

def getMorseCode(string):
    string = string.upper().strip().split(' ')
    eachMorse = []
    for word in string:
      if word == 'SOS':
            eachMorse.append(charToMorse)
      else:
            wordMorse = []
            for char in word:
                wordMorse.append(charToMorse)
            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( 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

grf1973 发表于 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
    return res.replace('',' ')#双空格改为单空格

testbits='1100110011001100000011000000111111001100111111001111110000000000000011001111110011111100111111000000110011001111110000001111110011001100000011'
print('接收到的字符串:',testbits)
print('转换成Morse:',decodeBits(testbits))
print('破译成可识别字符:',decodeMorse(decodeBits(testbits)))

萧丹夜 发表于 2018-7-3 19:02:04

没读懂。。。

holiday_python 发表于 2020-4-28 15:37:56

学习

19971023 发表于 2020-6-18 19:18:58

1

小陨aoq 发表于 2020-7-28 16:01:23

学习一下

wwwwwise 发表于 2021-4-12 20:04:33

完全看不懂
页: [1]
查看完整版本: Python: 每日一题 45