2017-10-23 19 views
3

私の目標は、名前のリストを反復して、名前の最後の文字が次の名前の最初の文字と同じになるように並べ替えることができる場合にのみTrueを返すことです。リスト内の項目の最初と最後の一致

class Team(object): 
    def __init__(self, names): 
     self.names = names 

    def __iter__(self): 
     from collections import Counter 
     first = Counter(map(lambda n: n[0].lower(), self.names)) 
     last = Counter(map(lambda n: n[-1].lower(), self.names)) 
     diff = last - first 
     return any(diff.values()) <= 1 

def isCoolTeam(team): 
    return bool(Team(team)) 

print(isCoolTeam(["Rob", 
"Bobby", 
"Billy"])) 

これはFalseを返しますが、何らかの理由ですべての入力がtrueを返します。

+0

あなたは一例を挙げることができますか? "マーク"、 "ケルト"、 "ケルト"、 "ケリー"、そして最後のものは、 "マーク"、 "ケルト"、 "ケルト"、 "ケリー"のように並べ替えることができるので、Trueを返すはずです: – crook

+0

それぞれの名前の手紙は、次の最初のものと一致します。 –

+0

あなたのコードで '__iter__'は呼び出されません。 –

答えて

2
boolean

を返すany()関数(True/False)及び全てbooleans以下(<=1に等しいあります。

これはlineことを意味します

return any(diff.values()) <= 1 

常にTrueと評価されます。

+0

私はそれが私の固執のポイントだと思ったが、私はそれを働かせるために私の「any」を変えるべきものを理解することができない。私は当初、「すべて」がそれを処理すると考えましたが、それでもまだ正しく検証されていません。 –

+1

あなたのコードで '__iter__'が_not_呼び出されていません。代わりに '__bool__'をオーバーライドする必要があります。 –

+0

@ T.J。これがあなたの問題を解決するのに役立ちましたら、同意してください! **:)** –

0

ここにいくつかの変更があります。 Teamをブール値に変換するのは意味がありませんので、__bool__を定義せず、is_coolを明示的に定義します。

はまた、私はあなたが何の違いは、この場合は1よりも高くない場合、あなたはall(v <= 1 for v in diff.values())を必要があると思いチェックしたいと思う:

class Team(object): 
    def __init__(self, names): 
     self.names = names 

    def is_cool(self): 
     from collections import Counter 
     first = Counter(map(lambda n: n[0].lower(), self.names)) 
     last = Counter(map(lambda n: n[-1].lower(), self.names)) 
     diff = last - first 
     return all(v <= 1 for v in diff.values()) 

print(Team(["Rob", "Bobby", "Billy"]).is_cool()) 
# False 
print(Team(["Rob", "Nick", "Bobby", "Yann"]).is_cool()) 
# True 

ロジックとの(大きな)問題はしかし、まだあります:

print(Team(["Ab", "cd", "ef"]).is_cool()) 
# True 

この問題を解決するにはCounterで十分ではないと思います。おそらく、グラフを定義し、すべての名前を結ぶパスがあるかどうかを確認する必要があります。 NetworkXが役に立ちます。

ここにはrelated graph problemの説明があります。

0

問題はのペアのいずれかです。すべての名前がなくなるまで、特定の最初の文字と対応する最後の文字を繰り返し一致させたいとします。

Rob-> Bobby-> Yannick-> Karl->:あなたが考えてみれば

、作業が完了したときは、最後に開始時に1対になっていない最初の文字と、1対になっていない最後の文字を持っていますLuigi-> Igor-> Renee-> Edmund-> David-> Diogenes

つまり、文字数の減算は、両方向で1でなければなりません。最初の文字は不一致で1文字、不一致の最後の文字が1つあります。最後、最後まで)。 しかし、繰り返しの文字がある場合はでも、これでは十分ではないかもしれません。リストの長さを確認して(有効であることを確認して)、差異があるかどうかを確認します。

長さ0のリストがあるとします。最初/最後の文字の数は空になりますリストは短すぎます。

長さ1のリストがあるとします。最初の/最後の文字の数は1と1になり、要件を満たします。

あなたは長さ2のリストを持っていると仮定します、[「ロブ」、「ダイアン」]次に、最後の/最初の文字の合計数が2と2次のようになります。

  • は重なりがないと仮定します要件に違反している。

  • 重複はありませんが、共有文字:[brad '、' betty ']とすると、最初と最後の文字の合計数は2と2になりますが、配置は異なります。私はあなたが数を合計するべきだと思います。 ;-)

  • ['bob'、 'bob']が重複しているとします。これにより、条件を満たす空の減算が残ります。

  • ['bob'、 'betty']が部分的に重複しているとします。これはそれぞれ{b:1}と{y:1}のカウントを残しているので動作します。

あなたは違いが2+のカウントが含まれている一つの要素を持ち、その差が1以上の数を持つ複数の要素を持っているところの差が空である場合、に対処する必要があります。

私はあなたがほしいと思うと思わないany()。私は何らかの集約機能が必要だと思います。私はsum()がうまくいくと思います。

+0

あなたが正しいです、現在の方法は動作していません。 'sum'でも十分ではありません。いくつかのグラフ理論が必要です:与えられた有向グラフについては、すべてのノードを訪れるパスがありますか? –

関連する問題