
背景需求
之前做了“6个孩子(双数)围圈,两两拍手,求单独人数”
【办公类-101-01】拍手围圈(1)——6个孩子(双数)围圈,两两拍手,求单独人数-优快云博客文章浏览阅读576次,点赞16次,收藏10次。【办公类-101-01】拍手围圈(1)——6个孩子(双数)围圈,两两拍手,求单独人数
https://blog.youkuaiyun.com/reasonsummer/article/details/146355874?spm=1011.2415.3001.5331
发现双数人数,空缺人数是双数,

单数人数,空缺人数是单数

现在来制作具体的空缺人数排在圆圈的那个位置。
这个代码只考虑1位数,所以只做2,4,6,8
代码展示
'''
双数孩子围一个圈,两两拍手,有多少人空,找不到搭档,递归样式,6可以拆分成1+2+1+2,递归方式有几种,
具体排列方式(圆圈)
1、排除相邻两个11,排除头尾都是1
2、包含2+2+2
星火讯飞、阿夏
20250329
'''
print('-----1、排列的递归样式[[1, 2, 1, 2], [2, 1, 2, 1], [2, 2, 2]]-----------')
from builtins import sum # Ensure we are using the built-in sum function
def split_number(n, current):
# If n equals 0, it means we've reached the bottom of the recursion
if n == 0:
# Check if the current combination contains both 1 and 2
if 1 in current and 2 in current:
# Check for adjacent two 1s
if any(current[i] == 1 and current[i + 1] == 1 for i in range(len(current) - 1)):
return
# Check if the first and last elements are both 1
if len(current) >= 2 and current[0] == 1 and current[-1] == 1:
return
# Add valid combinations to the result list
result.append(current)
# If the current combination is all 2s, add it to the result list
elif all(x == 2 for x in current):
result.append(current)
return
# If n is less than 0, the path is invalid, return immediately
elif n < 0:
return
# Recursively try adding 1 and 2 to the current combination
split_number(n - 1, current + [1])
split_number(n - 2, current + [2])
start_values = [2, 4, 6, 8]
for start in start_values:
end = start + 2
for people in range(start, end, 2):
result = [] # Initialize result list
split_number(people, []) # Initial call, starting with number of people, empty list as current combination
# Print result list
print(f"{people}人围圈,基本排列样式(递归)", result)
print(f"{people}人围圈,基本排列样式数量", len(result))
# Read result inside every element, count the number of 1s, make a list, then remove duplicates and sort
one_counts = [sum(1 for x in combo if x == 1) for combo in result]
unique_sorted_one_counts = sorted(set(one_counts))
print(f"Unique sorted counts of 1s: {unique_sorted_one_counts}")
# Custom combinations function
def custom_combinations(lst, pattern):
result = []
index = 0
for p in pattern:
if index + p <= len(lst):
part = ''.join(map(str, lst[index:index + p]))
result.append(part)
index += p
else:
break
return result
double = []
single = []
a = [i + 1 for i in range(people)]
print('111', a)
for i in range(people):
# Move the last element to the front
a = [a[-1]] + a[:-1]
print(a)
# Get adjacent two numbers combined together into combinations
combinations = [(a[i], a[i + 1]) for i in range(0, len(a), 2)]
# Convert combinations to string form and print results
combinations_str = [''.join(map(str, combo)) for combo in combinations]
# Sort combinations internal elements by size and remove duplicates using set
sorted_combinations_str = sorted(combinations_str)
print("Sorted Combinations:", sorted_combinations_str)
# Use set to remove duplicates
double.append(sorted_combinations_str)
double_combinations = list(map(list, set(map(tuple, double))))
# Get custom combinations based on the first pattern from result
custom_comb = custom_combinations(a, result[0]) # Pass the first pattern from result
# Sort and remove duplicates for custom combinations
sorted_custom_comb = sorted(set(custom_comb))
single.append(sorted_custom_comb)
single_combinations = list(map(list, set(map(tuple, single))))
print("双人组合0人空缺:", double_combinations)
doubles = list(map(lambda x: x, double_combinations))
print("单人组合双数人空缺:", single_combinations)
singles = list(map(lambda x: x, single_combinations))
all_combinations = doubles + singles
print('222', all_combinations)
# # 画一张图,中间一个圆圈,围绕画出8个数字,如果列表里面元素长度为1,就把这个数字锁在的坐标上画一个圈。
from PIL import Image, ImageDraw, ImageFont
import math
import os
for zz in range(len(all_combinations)):
# 创建400x400的白色图片
width, height = 400, 400
image = Image.new('RGB', (width, height), 'white')
draw = ImageDraw.Draw(image)
# 设置字体和大小
font_size = 30
font = ImageFont.truetype("arial.ttf", font_size)
# 圆心坐标和半径
center_x, center_y = width // 2, height // 2
radius = 150
sums=start
g=360/sums
# 用于存储每个数字的中心点坐标
center_points = []
# 计算每个数字的位置并绘制
for i in range(1,sums+1):
angle = math.radians((i - 1) * g + 270) # 每个数字之间的角度间隔是45度,并且从12点位置开始
x = center_x + radius * math.cos(angle) - font_size // 2
y = center_y + radius * math.sin(angle) - font_size // 2
draw.text((x, y), str(i), fill='black', font=font)
# 计算中心点坐标
center_point_x = center_x + radius * math.cos(angle)
center_point_y = center_y + radius * math.sin(angle)
center_points.append((center_point_x, center_point_y))
print(f"数字 {i} 的中心点坐标: ({center_point_x}, {center_point_y})")
# 遍历中心点坐标列表,如果x是一位数,在列表里根据索引获取x(int)的坐标。画圆圈
one_digit_indices = all_combinations[zz]
for index, (center_point_x, center_point_y) in enumerate(center_points):
if str(index + 1) in one_digit_indices: # 检查数字是否在指定的一位数列表中
print(f"在中心点 ({center_point_x}, {center_point_y}) 上画圆圈")
draw.ellipse([center_point_x - 20, center_point_y - 20, center_point_x + 20, center_point_y + 20], outline='black', width=2)
# 保存图片
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250329拍手单独情况'
image.save(os.path.join(path, f'{people}_{zz:05}.png'))


















后续把数字改成02的样式,再做两位数的双数和单数。