2014-05-13 2 views
1

파이썬 학습에 대한 제 여행의 일부로 불스와 소를 구현하고 있습니다.
목록 작성을 사용하는 작업 구현이 있지만 생성자와 reduce()- 최종 결과 -를 사용하여이를 해결하는 좋은 해결책이 될 수 있다고 생각했습니다.튜플 목록 축소

그래서 난 내 발전기가 :

def bullsandcows(given, number): 
    for i in range(given.__len__()): 
     if given[i] == number[i]: 
      yield (given[i], None) 
     elif given[i] in number: 
      yield (None, given[i]) 

을 그리고 내 줄일 구현 : given은 사용자 입력 및 number 사용자가 추측하기 무작위로 생성 된 번호입니다

(bulls, cows) = reduce(\ 
    lambda (bull, cow), (b, c): \ 
     (bull + 1, cow + 1), bullsandcows(given, number), (0, 0)) 

.

여기서 알 수 있듯이, 이것은 정확히 작동하는 구현은 아니며, yield ed 튜플의 개수를 반환합니다.

내가 필요한 것은 (bull + 1, cow + 1)의 대체품이며, 어떻게 구성해야할지 모르겠다.

  • number는 임의로 생성 된 번호라고되어 1234
  • given는 사용자에 의해 입력되고, 말 : 8241
  • bullsandcows(given, number)의 결과가 될 것이다 : [('2', None), (None, '4'), (None, '1']
  • reduce 결과이어야 : (1, 2), 이는 첫 번째 요소의 모든 비 - None 값의 수이고 두 번째 요소의 모든 비 - None 값의 수입니다.
  • 내가 제대로 과정을 이해하면 63,210
+0

은'사용하지 마십시오 .__ 렌()'(주어)'명확 __ 대신'zip()'을 사용할 수있을 때'range()'를 사용하지 마십시오. –

+0

맞습니다. '황소 새끼 '의 생산량을 무시하는 것처럼 보이지 않습니다. 결과는 항상 생성자의 결과 수를 포함하는 두 요소 튜플입니다. –

+0

람다에서'(b, c) '튜플을 무시하고 있습니다. –

답변

2

, 당신은 bull의하지 None이 무엇인지 계산하려면, 얼마나 많은 cow들하지 None 있습니다

reduce(lambda (bcount, ccount), (b, c): (bcount + (b is not None), ccount + (c is not None)), 
     bullsandcows(given, number), (0, 0)) 

이가 카운터를 증가에만 bull 또는 cow 값은 경우 None이 아닙니다. 이 테스트는 int의 하위 클래스 인 boolean을 생성하고 False == 0True == 1과 같습니다. 정수와 부울을 합하면 다른 정수가됩니다.

당신이 비어 있지 않은 문자열을 공급하고 있기 때문에, 당신은 그것을 단순화 수 있습니다 : 나는 다시 것

reduce(lambda (bcount, ccount), (b, c): (bcount + bool(b), ccount + bool(c)), 
     bullsandcows(given, number), (0, 0)) 

bullsandcows()에 :

def bullsandcows(given, number): 
    given, number = map(str, (given, number)) 
    for g, n in zip(given, number): 
     if g == n: 
      yield (g, None) 
     elif g in number: 
      yield (None, g) 

예를 들어, zip()을 사용하여 givennumber의 숫자를 쌍으로 묶으십시오.

데모 : 함수 인수에 개봉하는 것은 파이썬 3에서 제거하고 reduce() 내장 된 라이브러리 기능에 위임 된 것을

>>> def bullsandcows(given, number): 
...  given, number = map(str, (given, number)) 
...  for g, n in zip(given, number): 
...   if g == n: 
...    yield (g, None) 
...   elif g in number: 
...    yield (None, g) 
... 
>>> given, number = 8241, 1234 
>>> list(bullsandcows(given, number)) 
[('2', None), (None, '4'), (None, '1')] 
>>> reduce(lambda (bcount, ccount), (b, c): (bcount + bool(b), ccount + bool(c)), 
...  bullsandcows(given, number), (0, 0)) 
(1, 2) 

참고; 귀하의 코드는 확실히 파이썬 2 전용입니다.

는 당신이 functools.reduce()을 가져 풀기를 사용하지 람다을 조정해야 파이썬 3에서 작동하려면 :`렌 때

from functools import reduce 

reduce(lambda counts, bc: (counts[0] + bool(bc[0]), counts[1] + bool(bc[1])), 
     bullsandcows(given, number), (0, 0)) 
+0

'elif g str (number) : – mtadd

+0

@mtadd : 그것에 도달했습니다. :-) –

+0

고마워요! 이것은 내 문제를 완전히 해결합니다. 내가 코드를 향상시킬 수있는 방법과 이유를 설명함으로써 추가 마일을 얻는 것에 대한 또 하나의 상위 투표를 해줄 수 있었으면 좋겠다. –