Checkio筆記 - Node Disconnected Users

在Checkio上做測試女嘲,到了Node Disconnected Users這一個(gè)題杖玲±堆幔花了半天時(shí)間才勉強(qiáng)通過玄叠,先記錄在這里拓提。

題目

Gridland的市長利用網(wǎng)絡(luò)給市民發(fā)送緊急信息读恃,但是這個(gè)網(wǎng)絡(luò)總是存在問題,常常一個(gè)節(jié)點(diǎn)會(huì)發(fā)生故障代态,導(dǎo)致網(wǎng)路不通暢寺惫。這個(gè)時(shí)候就需要采用信鴿來傳遞信息。但是不同的節(jié)點(diǎn)對于網(wǎng)絡(luò)的影響是不一致的蹦疑,當(dāng)故障發(fā)生的時(shí)候西雀,市長需要根據(jù)發(fā)生故障的節(jié)點(diǎn)和發(fā)送信息的地點(diǎn)來判斷需要信鴿的數(shù)量。因此歉摧,你的任務(wù)是幫助市長算出發(fā)送故障時(shí)的信鴿需求量艇肴。如下圖所示,當(dāng)C節(jié)點(diǎn)發(fā)生故障的時(shí)候叁温,從A處的信息不能通過網(wǎng)絡(luò)傳到C和D點(diǎn)再悼,所以C和D點(diǎn)的用戶都需要接收信鴿。
采用如下的方式來表示這個(gè)網(wǎng)絡(luò)及故障情況:

  • 網(wǎng)絡(luò)的連接情況表示為:[['A','B'],['B','C'],['C','D']]
  • 每個(gè)地方的用戶數(shù)用一個(gè)字典來表示:{'A':10,'B':20,'C':30,'D':40}
  • 發(fā)信息地點(diǎn)用字符表示:如'A','B','C','D'之中選一個(gè)
  • 故障發(fā)生節(jié)點(diǎn)用列表表示:A點(diǎn)發(fā)生故障為['A']膝但,AB同時(shí)發(fā)生故障為['A','B']
網(wǎng)絡(luò)圖
def disconnected_users(net, users, source, crushes):
    
    node_name = list(users.keys()) #網(wǎng)絡(luò)節(jié)點(diǎn)名稱
    node_name.remove(source) #去掉發(fā)信息的節(jié)點(diǎn)
    
    #去掉故障節(jié)點(diǎn)
    for node in crushes:
        if node != source:
            node_name.remove(node)
    
    #故障后網(wǎng)絡(luò)中剩余的網(wǎng)絡(luò)鏈接數(shù)冲九,記錄在net列表中
    for connect in net:
        for crush in crushes:
            if crush in connect:
                net.remove(connect)

    def connect_node(sours, remain, targ):
        org_targ = targ[:] #這里如果讓后面的函數(shù)改變targ的值的話,會(huì)導(dǎo)致遍歷不到所有元素跟束。所以復(fù)制一個(gè)org_targ列表
        for node in org_targ:
            if [sours,node] in remain or [node,sours] in remain:
                targ.remove(node)
                connect_node(node, remain, targ)    
        return targ

    num = 0
    for node in connect_node(source, net, node_name):
        num += users[node]
    for node in crushes:
        num += users[node]
    return num

if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing
    assert disconnected_users([
        ['A', 'B'],
        ['B', 'C'],
        ['C', 'D']
    ], {
        'A': 10,
        'B': 20,
        'C': 30,
        'D': 40
    },
        'A', ['C']) == 70, "First"

    assert disconnected_users([
        ['A', 'B'],
        ['B', 'D'],
        ['A', 'C'],
        ['C', 'D']
    ], {
        'A': 10,
        'B': 0,
        'C': 0,
        'D': 40
    },
        'A', ['B']) == 0, "Second"

    assert disconnected_users([
        ['A', 'B'],
        ['A', 'C'],
        ['A', 'D'],
        ['A', 'E'],
        ['A', 'F']
    ], {
        'A': 10,
        'B': 10,
        'C': 10,
        'D': 10,
        'E': 10,
        'F': 10
    },
        'C', ['A']) == 50, "Third"

    print('Done. Try to check now. There are a lot of other tests')

如上的代碼基于的邏輯是:

  • 將發(fā)生故障的節(jié)點(diǎn)和發(fā)信地點(diǎn)先去除莺奸,剩余的地點(diǎn)放在一個(gè)列表中,后面來判斷這個(gè)列表中的地點(diǎn)是否能通過網(wǎng)絡(luò)收到信冀宴,如果能夠憾筏,就在列表中去除
  • 在正常網(wǎng)絡(luò)列表中,將發(fā)生故障的連接去除花鹅,能否通信需要靠連接狀況來判斷
  • 寫一個(gè)遞歸函數(shù)來判斷某點(diǎn)網(wǎng)絡(luò)連接狀況氧腰,因?yàn)橹苯舆B接的可以馬上判斷出來,而二級/三級等不直接的連接,需要靠遞歸去判斷
  • 去除掉連接成功的節(jié)點(diǎn)古拴,剩下的就是不能連接成功的節(jié)點(diǎn)
  • 計(jì)算不能連接成功的節(jié)點(diǎn)的用戶數(shù)(需要加上之前去除掉的故障節(jié)點(diǎn)的用戶數(shù))

如下貼一些其他人的代碼:

代碼一:

def disconnected_users(net, users, source, crushes):
    if source in crushes: return sum(users.values())
    temp = [source]
    goodnode = []
    while temp:
        node = temp.pop(0)
        goodnode.append(node)
        for i,j in net:
            if i == node and j not in crushes and j not in goodnode:
                temp.append(j)
            elif j == node and i not in crushes and i not in goodnode:
                temp.append(i)
    return sum(users.values()) - sum(users[node] for node in goodnode)

代碼二

def disconnected_users(net, users, source, crushes):
    nodes = set()
    for link in net:
        nodes |= set(link)
    working_nodes = set(source) - set(crushes)
    while True:
        untested_links = []
        no_links = True
        for node1, node2 in net:
            if node1 in working_nodes:
                if node2 not in crushes:
                    working_nodes.add(node2)
                    no_links = False
            elif node2 in working_nodes:
                if node1 not in crushes:
                    working_nodes.add(node1)
                    no_links = False
            else:
                untested_links.append([node1, node2])
        if no_links:
            break
        net = untested_links
    nodes -= working_nodes
    unreceived_emails = 0
    for node in nodes:
        unreceived_emails += users[node]
    return unreceived_emails

代碼三

def subnetworks(net, crushes):
    result = {x: {x} for x in sum(net, []) if x not in crushes}
    for a, b in net*len(net):
        if set(crushes) & {a, b}: continue
        result[a] |= result[b] | {a, b}
        result[b] |= result[a] | {a, b}
    return result

def disconnected_users(net, users, source, crushes):
    sum_all, subs = sum(users.values()), subnetworks(net, crushes)
    return sum_all - sum([users[x] for x in subs.get(source, [])])
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末箩帚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子黄痪,更是在濱河造成了極大的恐慌紧帕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桅打,死亡現(xiàn)場離奇詭異是嗜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)挺尾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門鹅搪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人遭铺,你說我怎么就攤上這事丽柿。” “怎么了魂挂?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵甫题,是天一觀的道長。 經(jīng)常有香客問我涂召,道長坠非,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任果正,我火速辦了婚禮炎码,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舱卡。我一直安慰自己,他們只是感情好队萤,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布轮锥。 她就那樣靜靜地躺著,像睡著了一般要尔。 火紅的嫁衣襯著肌膚如雪舍杜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天赵辕,我揣著相機(jī)與錄音既绩,去河邊找鬼。 笑死还惠,一個(gè)胖子當(dāng)著我的面吹牛饲握,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼救欧,長吁一口氣:“原來是場噩夢啊……” “哼衰粹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起笆怠,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤铝耻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蹬刷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓢捉,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年办成,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泡态。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诈火,死狀恐怖兽赁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冷守,我是刑警寧澤刀崖,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站拍摇,受9級特大地震影響亮钦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜充活,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一蜂莉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧混卵,春花似錦映穗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赘淮,卻和暖如春辕录,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背梢卸。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工走诞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛤高。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓蚣旱,卻偏偏與公主長得像碑幅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子姻锁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 專業(yè)考題類型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項(xiàng)A選項(xiàng)B選項(xiàng)C選項(xiàng)D選項(xiàng)E選項(xiàng)F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 8,981評論 0 13
  • 原文地址Dynamo 摘要 面對世界上最大的電商網(wǎng)站 Amazon.com枕赵,我們遇到的最大挑戰(zhàn)之一就是海量規(guī)模下后...
    wangjie_yy閱讀 2,176評論 0 3
  • feisky云計(jì)算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,827評論 0 5
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說明:當(dāng)在唯一索引所對應(yīng)的列上鍵入重復(fù)值時(shí)位隶,會(huì)觸發(fā)此異常拷窜。 O...
    我想起個(gè)好名字閱讀 5,253評論 0 9
  • 可能大家對- (id)valueForKeyPath:(NSString *)keyPath方法不是很了解。 其實(shí)...
    如果我們是朋友閱讀 311評論 0 0