【问题标题】:Python Dice : Avoiding Triple RepetitionsPython Dice:避免三次重复
【发布时间】:2019-09-03 21:02:15
【问题描述】:

我要解决这个 DICE 难题,但我的思绪停留在一个场景上。


在试验中发生了多少次,恰好两个 6 依次滚动?例如,在序列56611166626634416 中出现了两次,恰好两个6 相继抛出。


问题是:如何避免让计数器计算那些 666。

注意:我已经尝试了多个跟踪器(键),但是我遇到了另一个问题:

IndexError: 列表索引超出范围

Throws=[6,6,2,6,6,6,3,6,6,3,6,6,6]
Counter_6 = 0
X=0


for i in range (0,len(Throws)):

    if i==len(Throws) or i+1>len(Throws) or i+2>len(Throws):
        key1= Throws[i]
        key2=0
        key3=0

    elif i+2>=len(Throws):
        key1 = Throws[i]
        key2 = Throws[i + 1]
        key3 = 0

    else:
        key1=Throws[i]
        key2 = Throws[i + 1]
        key3 = Throws[i + 2]
    print("key 1 is", key1)
    print("key 2 is", key2)
    print("key 3 is", key3)

    if key1==6 and key2==6 and key3!=6 and X==0:
        Counter_6 = Counter_6 + 1
        X=1
    elif key1!=6 and key2 ==6 and key3==6 and X==0:
        Counter_6 = Counter_6 + 1
        X=1
    elif key1==6 and key2==6 and key3==6:
        Counter_6 = Counter_6
        X=0

print("number of double 6 are: ",Counter_6)

计数器应该等于 2

【问题讨论】:

    标签: python-3.x dice


    【解决方案1】:

    使用while循环

    Throws=[6,6,2,6,6,6,3,6,6,3,6,6,6]
    Counter_6 = 0
    i=0
    while i < len(throws)-1:
     if throws[i]==throws[i+1] and throws[i] == 6:
      i=i+2
      Counter_6= Counter_6 + 1
    else:
      i=i+1
    print(Counter_6)
    

    【讨论】:

      【解决方案2】:

      一种可能的方法是使用正则表达式。这样您可以指定准确的模式并简单地计算它们出现的次数,另外还有一个好处是这也适用于具有字母或符号。

      import re
      
      throws = [6, 6, 2, 6, 6, 6, 3, 6, 6, 3, 6, 6, 6]
      
      throws_string = "".join(str(x) for x in throws)  # Make the list into a string to be able to apply regex to it.
      
      match = re.findall(r"(?:[^6]|\A)(6{2})(?:[^6]|\Z)", throws_string)
      
      assert len(match) == 2
      

      中间的捕获组(6{2}) 匹配我们需要的,而它周围的非捕获组确保我们不匹配任何 3 个或更多 6 的集群。 \A\Z 必须匹配字符串的开头和结尾,否则“不是六”[^6] 将寻找不同的字符而找不到。

      请注意,Python 中的变量名应该使用snake_case,并且至关重要的是,第一个字母应该小写以区分变量和类名。

      【讨论】:

      • 我认为这个正则表达式最后会漏掉一对六(即throws = [ 6, 6]
      • 谢谢,我更正了。我忘了包括我在笔记中提到的\Z
      【解决方案3】:

      itertools.groupby() 将为您提供或多或少开箱即用的连续数字组:

      from itertools import groupby
      
      throws =  [6,6,2,6,6,6,3,6,6,3,6,6,6]
      [tuple(v) for k,v in groupby(throws)]
      
      >> [(6, 6), (2,), (6, 6, 6), (3,), (6, 6), (3,), (6, 6, 6)]
      

      您可以将其与 collections.Counter 结合起来以获取 (6,6) 元组的计数:

      from itertools import groupby
      from collections import Counter
      
      throws =  [6,6,2,6,6,6,3,6,6,3,6,6,6]
      c = Counter(tuple(v) for k,v in groupby(throws))
      c[(6,6)]
      
      >> 2
      

      【讨论】:

      • 谢谢,这些都是不错的工具,但由于某种原因我不能使用 collections.counter,它会自动变灰(((此检查检测到应该解析但没有解析的名称。由于动态调度和鸭子打字,这在有限但有用的情况下是可能的。顶级和类级项目比实例项目更受支持。)))
      • 这真是太糟糕了@puzzler - 集合是 Python 标准库的一部分,那里有大量的优化工具。我注意到我在Counter 中有一个带有小写“c”的链接。不确定这是否是问题所在。
      【解决方案4】:

      这是一个简单有效的解决方案,无需使用任何扩展库。我们定义stack 等于我们看到的连续6 的数量,每次出现6 以外的任何数字时(或循环我们的抛出后)我们检查stack 是否等于@ 987654325@,如果是这样,我们增加 counter_6 并将 stack 重置为 0

      throws = [6,6,2,6,6,6,3,6,6,3,6,6,6]
      counter_6 = 0
      stack = 0
      
      for i in throws:
          if i == 6:
              stack += 1
          else:
              if stack == 2:
                  counter_6 += 1
              stack = 0
      if stack == 2:
          counter_6 += 1
      
      print(counter_6) # --> 2
      

      【讨论】:

        【解决方案5】:

        我能想到的一种更简单的方法是用一个不能在掷骰子时出现的整数来标记 3 个连续六点中的第三个六点。例如-1

        throws=[6,6,2,6,6,6,3,6,6,3,6,6,6]
        counter = 0
        
        for i in range (0, len(throws)-2):
        
            if throws[i] == 6 and throws[i+1] == 6:
                if throws[i+2] == 6:
                    throws[i+2] = -1
        print(throws)
        #[6, 6, 2, 6, 6, -1, 3, 6, 6, 3, 6, 6, -1]
        

        之后,你可以遍历列表,当你遇到两个连续的 6 并且第三个元素不是 -1 时创建计数器

        for i in range (0, len(throws)-2):
        
            if throws[i] == 6 and throws[i+1] == 6 and throws[i+2] != -1:
                counter+=1
        
        print(counter)
        #2
        

        这种方法肯定可以改进。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多