<gh_stars>1-10
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# author: bigfoolliu


"""
二进制手表顶部有 4 个 LED 代表 小时（0-11），底部的 6 个 LED 代表 分钟（0-59）。每个 LED 代表一个 0 或 1，最低位在右侧。

例如，下面的二进制手表读取 "3:25" 。


（图源：WikiMedia - Binary clock samui moon.jpg ，许可协议：Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) ）

给你一个整数 turnedOn ，表示当前亮着的 LED 的数量，返回二进制手表可以表示的所有可能时间。你可以 按任意顺序 返回答案。

小时不会以零开头：

例如，"01:00" 是无效的时间，正确的写法应该是 "1:00" 。
分钟必须由两位数组成，可能会以零开头：

例如，"10:2" 是无效的时间，正确的写法应该是 "10:02" 。
 

示例 1：

输入：turnedOn = 1
输出：["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]
示例 2：

输入：turnedOn = 9
输出：[]
 

提示：

0 <= turnedOn <= 10

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/binary-watch
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""

import doctest
from typing import List


class Solution:
    """
    todo:
    """

    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        """
        遍历最简洁写法
        """
        return [str(a) + ":" + str(b).rjust(2, '0') for a in range(12) for b in range(60) if
                (bin(a) + bin(b)).count('1') == turnedOn]

    def readBinaryWatch2(self, turnedOn: int) -> List[str]:
        """
        遍历的简洁写法
        二进制的表，可以通过二进制位为1表示这个灯为亮的，且需要限制时钟和分钟的值
        """
        ans = list()
        for h in range(12):
            for m in range(60):
                if bin(h).count('1') + bin(m).count('1') == turnedOn:
                    ans.append(f"{h}:{m:02d}")
        return ans

    def readBinaryWatch3(self, turnedOn: int) -> List[str]:
        """
        严格遵循规则，分别计算时钟和分钟的时间然后将结果组合
        上4个灯：8 4 2 1
        下6个灯：32 16 8 4 2 1
        小时为：0-11
        分钟为：0-59
        小时不会以0开头；分钟必须是两位数
        """
        # 时针亮了a个，则分针亮了 turnedOn - a个
        # 分别计算时针和分针的各种可能，将结果组合

        from itertools import combinations

        def get_hour1(a) -> List[str]:
            """因为可能性比较少，直接返回，速度更快"""
            # 时钟为0-11，最多亮3个
            if a > 3:
                return []
            hours = [1, 2, 4, 8]
            if a == 0:
                return ['0']
            if a == 1:
                return ['1', '2', '4', '8']
            if a == 2:
                return ['3', '5', '9', '6', '10']
            if a == 3:
                return ['7', '11']

        def get_hour(a) -> List[str]:
            # 时钟为0-11，最多亮3个
            if a > 3:
                return []

            nums = [1, 2, 4, 8]
            if a == 0:
                return ['0']
            hs = combinations(nums, a)
            ret = []
            for h in hs:
                if 0 < sum(h) <= 11:
                    ret.append(str(sum(h)))
            return ret

        def get_minute(b) -> List[str]:
            # 分钟为0-59，最多亮5个
            if b > 5:
                return []

            nums = [1, 2, 4, 8, 16, 32]
            if b == 0:
                return ['00']
            cs = combinations(nums, b)  # 从nums中任选b个组合
            ret = []
            for c in cs:
                if 0 < sum(c) <= 59:
                    ret.append(str(sum(c)) if sum(c) >= 10 else '0' + str(sum(c)))
            return ret

        times = []
        for a in range(turnedOn + 1):
            b = turnedOn - a
            hours = get_hour(a)
            if not hours:
                continue
            minutes = get_minute(b)
            if not minutes:
                continue

            # 将时钟和分钟组合
            for hour in hours:
                for minute in minutes:
                    times.append(hour + ':' + minute)
        return times


if __name__ == '__main__':
    doctest.testmod()

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# author: bigfoolliu


"""
二进制手表顶部有 4 个 LED 代表 小时（0-11），底部的 6 个 LED 代表 分钟（0-59）。每个 LED 代表一个 0 或 1，最低位在右侧。

例如，下面的二进制手表读取 "3:25" 。


（图源：WikiMedia - Binary clock samui moon.jpg ，许可协议：Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) ）

给你一个整数 turnedOn ，表示当前亮着的 LED 的数量，返回二进制手表可以表示的所有可能时间。你可以 按任意顺序 返回答案。

小时不会以零开头：

例如，"01:00" 是无效的时间，正确的写法应该是 "1:00" 。
分钟必须由两位数组成，可能会以零开头：

例如，"10:2" 是无效的时间，正确的写法应该是 "10:02" 。
 

示例 1：

输入：turnedOn = 1
输出：["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"]
示例 2：

输入：turnedOn = 9
输出：[]
 

提示：

0 <= turnedOn <= 10

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/binary-watch
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""

import doctest
from typing import List


class Solution:
    """
    todo:
    """

    def readBinaryWatch(self, turnedOn: int) -> List[str]:
        """
        遍历最简洁写法
        """
        return [str(a) + ":" + str(b).rjust(2, '0') for a in range(12) for b in range(60) if
                (bin(a) + bin(b)).count('1') == turnedOn]

    def readBinaryWatch2(self, turnedOn: int) -> List[str]:
        """
        遍历的简洁写法
        二进制的表，可以通过二进制位为1表示这个灯为亮的，且需要限制时钟和分钟的值
        """
        ans = list()
        for h in range(12):
            for m in range(60):
                if bin(h).count('1') + bin(m).count('1') == turnedOn:
                    ans.append(f"{h}:{m:02d}")
        return ans

    def readBinaryWatch3(self, turnedOn: int) -> List[str]:
        """
        严格遵循规则，分别计算时钟和分钟的时间然后将结果组合
        上4个灯：8 4 2 1
        下6个灯：32 16 8 4 2 1
        小时为：0-11
        分钟为：0-59
        小时不会以0开头；分钟必须是两位数
        """
        # 时针亮了a个，则分针亮了 turnedOn - a个
        # 分别计算时针和分针的各种可能，将结果组合

        from itertools import combinations

        def get_hour1(a) -> List[str]:
            """因为可能性比较少，直接返回，速度更快"""
            # 时钟为0-11，最多亮3个
            if a > 3:
                return []
            hours = [1, 2, 4, 8]
            if a == 0:
                return ['0']
            if a == 1:
                return ['1', '2', '4', '8']
            if a == 2:
                return ['3', '5', '9', '6', '10']
            if a == 3:
                return ['7', '11']

        def get_hour(a) -> List[str]:
            # 时钟为0-11，最多亮3个
            if a > 3:
                return []

            nums = [1, 2, 4, 8]
            if a == 0:
                return ['0']
            hs = combinations(nums, a)
            ret = []
            for h in hs:
                if 0 < sum(h) <= 11:
                    ret.append(str(sum(h)))
            return ret

        def get_minute(b) -> List[str]:
            # 分钟为0-59，最多亮5个
            if b > 5:
                return []

            nums = [1, 2, 4, 8, 16, 32]
            if b == 0:
                return ['00']
            cs = combinations(nums, b)  # 从nums中任选b个组合
            ret = []
            for c in cs:
                if 0 < sum(c) <= 59:
                    ret.append(str(sum(c)) if sum(c) >= 10 else '0' + str(sum(c)))
            return ret

        times = []
        for a in range(turnedOn + 1):
            b = turnedOn - a
            hours = get_hour(a)
            if not hours:
                continue
            minutes = get_minute(b)
            if not minutes:
                continue

            # 将时钟和分钟组合
            for hour in hours:
                for minute in minutes:
                    times.append(hour + ':' + minute)
        return times


if __name__ == '__main__':
    doctest.testmod()
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # author: bigfoolliu 二进制手表顶部有 4 个 LED 代表 小时（0-11），底部的 6 个 LED 代表 分钟（0-59）。每个 LED 代表一个 0 或 1，最低位在右侧。  例如，下面的二进制手表读取 "3:25" 。   （图源：WikiMedia - Binary clock samui moon.jpg ，许可协议：Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) ）  给你一个整数 turnedOn ，表示当前亮着的 LED 的数量，返回二进制手表可以表示的所有可能时间。你可以 按任意顺序 返回答案。  小时不会以零开头：  例如，"01:00" 是无效的时间，正确的写法应该是 "1:00" 。 分钟必须由两位数组成，可能会以零开头：  例如，"10:2" 是无效的时间，正确的写法应该是 "10:02" 。    示例 1：  输入：turnedOn = 1 输出：["0:01","0:02","0:04","0:08","0:16","0:32","1:00","2:00","4:00","8:00"] 示例 2：  输入：turnedOn = 9 输出：[]    提示：  0 <= turnedOn <= 10  来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/binary-watch 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。 todo: 遍历最简洁写法 遍历的简洁写法         二进制的表，可以通过二进制位为1表示这个灯为亮的，且需要限制时钟和分钟的值 严格遵循规则，分别计算时钟和分钟的时间然后将结果组合         上4个灯：8 4 2 1         下6个灯：32 16 8 4 2 1         小时为：0-11         分钟为：0-59         小时不会以0开头；分钟必须是两位数 # 时针亮了a个，则分针亮了 turnedOn - a个 # 分别计算时针和分针的各种可能，将结果组合 因为可能性比较少，直接返回，速度更快 # 时钟为0-11，最多亮3个 # 时钟为0-11，最多亮3个 # 分钟为0-59，最多亮5个 # 从nums中任选b个组合 # 将时钟和分钟组合