mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-23 16:55:02 +00:00
init-commit
This commit is contained in:
commit
18a552597a
3461 changed files with 1150579 additions and 0 deletions
170
internbootcamp/libs/Skyscrapers/main.py
Executable file
170
internbootcamp/libs/Skyscrapers/main.py
Executable file
|
|
@ -0,0 +1,170 @@
|
|||
#!/usr/bin/python3.6
|
||||
import itertools
|
||||
from operator import mul
|
||||
from functools import reduce
|
||||
import sys
|
||||
from time import time
|
||||
from math import floor
|
||||
|
||||
def satisfies_r(s, row, r):
|
||||
return satisfies_l(s, list(reversed(row)), r)
|
||||
|
||||
def satisfies_l(s, row, l):
|
||||
if len(set(row)) < s:
|
||||
return False
|
||||
if l == 0:
|
||||
return True
|
||||
seen = 0
|
||||
curr_max = 0
|
||||
for entry in row:
|
||||
if entry > curr_max:
|
||||
curr_max = entry
|
||||
seen += 1
|
||||
if entry == s or seen > l:
|
||||
break
|
||||
return l == seen
|
||||
|
||||
def possible_rows(s, l, r):
|
||||
p = []
|
||||
for row in itertools.permutations(range(1, s + 1)):
|
||||
if satisfies_l(s, row, l) and satisfies_r(s, row, r):
|
||||
p.append(list(row))
|
||||
return p
|
||||
|
||||
def format_time(s):
|
||||
sinm = 60
|
||||
sinh = 60 * sinm
|
||||
sind = 24 * sinh
|
||||
d = h = m = 0
|
||||
r = s
|
||||
if s > sind:
|
||||
d = floor(r / sind)
|
||||
r -= d * sind
|
||||
if s > sinh:
|
||||
h = floor(r / sinh)
|
||||
r -= h * sinh
|
||||
if s > sinm:
|
||||
m = floor(r / sinm)
|
||||
r -= m * sinm
|
||||
return f'{d}:{h:02d}:{m:02d}:{r:02d}'
|
||||
|
||||
def print_time(done, total, s):
|
||||
eta = format_time(int((total / done - 1) * s))
|
||||
print(f'progress: {done} / {total} = {done * 100 / total:.2f}%, est. max. time left: {eta}')
|
||||
|
||||
def print_time_found(done, total, s):
|
||||
dhms = format_time(int(s))
|
||||
print(f'Solution found after searching {done} / {total} = {done * 100 / total:.2f}% in {dhms}')
|
||||
|
||||
def is_valid_solution(s, solution, t, b):
|
||||
count = 0
|
||||
for i in range(s):
|
||||
c = [row[i] for row in solution]
|
||||
if not (satisfies_l(s, c, t[i]) and satisfies_r(s, c, b[i])):
|
||||
break
|
||||
count += 1
|
||||
return count == s
|
||||
|
||||
def solve(s, l, r, t, b, verbose,simple_output):
|
||||
rows = [possible_rows(s, l[i], r[i]) for i in range(s)]
|
||||
sol_count = 0
|
||||
total = reduce(mul, [len(row) for row in rows], 1)
|
||||
first_time = time()
|
||||
prev_time = first_time
|
||||
curr_time = first_time
|
||||
start_freq = 10000
|
||||
time_freq = start_freq
|
||||
log = "" # 初始化日志变量
|
||||
|
||||
# 记录排列总数
|
||||
log += f"现在通过笛卡尔积遍历的方式尝试所有可能的排列组合,总共有 {total} 种可能的排列组合需要尝试。\n"
|
||||
if verbose > 0:
|
||||
print(f'{total} possible solutions')
|
||||
|
||||
for solution in itertools.product(*rows):
|
||||
sol_count += 1
|
||||
|
||||
if (simple_output and sol_count < 4) or not simple_output:
|
||||
log += f"现在判断第 {sol_count} 个可能的排列组合:。\n" # 记录当前尝试的解
|
||||
|
||||
log += f"这是基于每行的可能排列组合生成的解。\n"
|
||||
for i, row in enumerate(solution):
|
||||
log += f" - 第 {i + 1} 行是从该行的所有可能排列中选出的一个。\n"
|
||||
log += f" 当前这一行的所有可能排列是:{rows[i]}。\n"
|
||||
log += f" 我们选择了排列 {row} 作为第 {i + 1} 行。\n"
|
||||
log += f"逐行拼接这些排列,形成完整棋盘{solution}。\n"
|
||||
if simple_output and (sol_count == 4):
|
||||
log += f"...像这样判断下去。\n"
|
||||
|
||||
# 输出进度信息
|
||||
if verbose > 0 and sol_count % time_freq == 0:
|
||||
curr_time = time()
|
||||
if curr_time >= prev_time + verbose:
|
||||
if time_freq == start_freq:
|
||||
time_freq = sol_count / 10
|
||||
elapsed_time = curr_time - first_time
|
||||
progress_info = f"已尝试 {sol_count} 个解,共计 {total} 个解。\n"
|
||||
log += progress_info # 记录进度信息
|
||||
print(progress_info)
|
||||
prev_time = curr_time
|
||||
|
||||
# 检查当前解是否符合要求
|
||||
if is_valid_solution(s, solution, t, b):
|
||||
curr_time = time()
|
||||
elapsed_time = curr_time - first_time
|
||||
found_info = f"这样,就找到了一个符合要求的解,这是第 {sol_count} 个尝试。\n"
|
||||
log += found_info
|
||||
log += f"有效解为:{solution}。\n"
|
||||
if verbose > 0:
|
||||
print(found_info)
|
||||
return solution, log # 返回解和日志
|
||||
else:
|
||||
if (simple_output and sol_count < 4) or not simple_output:
|
||||
log += f"很遗憾,这样的组合并不满足规则,它不是有效的解,现在进行下一次尝试。\n"
|
||||
|
||||
# 如果没有找到解
|
||||
log += "所有排列组合尝试完毕,未找到符合条件的解。\n"
|
||||
return ["无解"], log # 返回无解信息和日志
|
||||
|
||||
|
||||
|
||||
def solver_main(size: int, left: list[int], right: list[int], top: list[int], bottom: list[int],simple_output):
|
||||
"""
|
||||
Main function to solve the skyscraper puzzle.
|
||||
|
||||
Parameters:
|
||||
size (int): The dimension of the grid (maximum 9).
|
||||
left (list[int]): Left-side views.
|
||||
right (list[int]): Right-side views.
|
||||
top (list[int]): Top-side views.
|
||||
bottom (list[int]): Bottom-side views.
|
||||
"""
|
||||
# Validate size
|
||||
if size > 9:
|
||||
print('Error: size should be 9 or smaller')
|
||||
return
|
||||
|
||||
# Validate the lengths of the view lists
|
||||
if len(left) != size or len(right) != size or len(top) != size or len(bottom) != size:
|
||||
print('Error: All view lists must have a length equal to the size of the grid')
|
||||
return
|
||||
|
||||
# Optional verbosity for debugging
|
||||
verbose = 1
|
||||
if verbose > 0:
|
||||
print("Input Parameters:")
|
||||
print(f"Size: {size}")
|
||||
print(f"Left: {left}")
|
||||
print(f"Right: {right}")
|
||||
print(f"Top: {top}")
|
||||
print(f"Bottom: {bottom}")
|
||||
|
||||
# Solve the skyscraper puzzle
|
||||
solution,log = solve(size, left, right, top, bottom, verbose,simple_output)
|
||||
|
||||
return solution,log
|
||||
# Print the solution grid
|
||||
print("Solution:")
|
||||
for row in solution:
|
||||
print(row)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue