Python,Battleship field validator

news/2025/3/28 15:03:44/文章来源:https://www.cnblogs.com/l25428455/p/18791435
# Battleship field validator
# https://www.codewars.com/kata/52bb6539a4cf1b12d90005b7/train/pythondef validate_battlefield(field):# 4*1 + 3*2 + 2*3 + 1*4 = 20if sum([sum(row) for row in field]) != 20:return False# cells_status=[[1]*10]*10# [1]*10创建的列表内的元素是独立的,列表中的每个元素都是独立的整数,而不是对同一个对象的10个引用# 但是[[1]*10]*10创建的二维列表内的每一个子列表实际上是对同一个列表对象的引用,# 也就是说cells_status实际上是一个引用列表,内部保存了10个对同一个列表对象的引用# 上面这种创建方式会导致所有子列表引用同一个列表对象,修改其中一个子列表会导致其他子列表也被修改# cells_status[0]和cells_status[1]是同一个对象,都是同一个[1]*10,修改cells_status[0]会导致cells_status[1]也被修改# 可以使用列表推导式创建独立的子列表cells_status=[[True]*10 for _ in range(10)]# False -- forbidden,True -- allowedships = [0,4,3,2,1]def make_forbidden(i,j):cells_status[i][j]=0for y in range(i-1,i+2):for x in range(j-1,j+2):if 0<=y<10 and 0<=x<10:cells_status[y][x]=Falsefor i in range(10):for j in range(10):if(not cells_status[i][j]):continueif field[i][j]==1:tempI = itempJ = jmake_forbidden(i,j)while field[tempI][j]==1:#向下make_forbidden(tempI,j)tempI+=1if tempI>=10:breakwhile field[i][tempJ]==1:#向右make_forbidden(i,tempJ)tempJ+=1if tempJ>=10:breakif max(tempI-i,tempJ-j)>4:return Falseships[max(tempI-i,tempJ-j)]-=1for ship in ships:if ship!=0:return Falsereturn True# best practice
#scipy.ndimage.measurements# 是 SciPy 库中的一个子模块,专门用于图像处理和分析。
# ndimage 代表 N-dimensional image(N 维图像),该模块提供了许多函数,用于处理和分析多维图像数据。
# label是一个用于标记连通区域的函数,它会返回一个标记数组和标记的数量。
# find_objects是一个用于获取标记数组中每个标记的位置的函数。
# np是numpy的别名
# np.ones((3,3))生成一个3*3的全1矩阵
from scipy.ndimage.measurements import label, find_objects
import numpy as np
def validate_battlefield(field):# numpy.array()可表示一维,二维,三维等多维数组# numpy.array()可传入列表,元组等可迭代对象,生成一个数组field = np.array(field)# field是一个10*10的数组,每个元素是0或1,表示战舰的位置#np.ones()函数用于生成一个全1数组,传入一个元组表示数组的形状labeled_array, num_features = label(field,np.ones((3,3)))#labeled_array是标记数组, num_features是标记出的联通区域的数量positions = find_objects(labeled_array)#positions是标记对象的位置,是一个切片对象的列表,每个切片对象包括行和列的范围,表示一个矩形区域result =  []for pos in positions:# pos 是一个切片对象,包括行和列的范围, 形如(slice(0, 2, None), slice(1, 4, None))ship = field[pos]# field[pos]是一个子数组,表示一个战舰的位置,是一个矩形区域,形如# [[0 1 1]#  [1 1 0]]if min(ship.shape)==1:#shape是一个数组的属性,表示数组的维度,#shape属性返回一个元组,其中包含数组每个维度的大小#min(ship.shape)==1说明ship的行数或列数为1,即ship占据一行多列或者一列多行或者只有一个元素#也就是说ship的形状是1*n或者n*1,符合要求# ship.size返回数组中元素的个数,即行数*列数# 由于ship的形状是1*n或者n*1,所以该联通区域中只有元素1,没有元素0# 即ship.size的值就是1的个数result.append(ship.size)#sorted()默认是升序排序return sorted(result) == [1,1,1,1,2,2,2,3,3,4]# original code# return sorted(#     ship.size if min(ship.shape) == 1 else 0#     for ship in (field[pos] for pos in find_objects(label(field, np.ones((3,3)))[0]))# ) == [1,1,1,1,2,2,2,3,3,4]# 关于label() ============================================================================
# label(input,structure)函数用于标记数组中的联通区域,
# 连通区域是指在数组中相邻且具有相同值的元素组成的区域。相邻的定义可以通过 structure 参数来指定。
# 只有非零元素组成的联通区域才会被标记
# 默认情况下,structure 参数是一个与输入数组维度相同且所有元素为 1 的数组,
# 这意味着所有相邻的元素(包括对角线方向)都被视为连通的。
# label()函数会为每一个联通区域分配一个唯一的整数标记,整数标记从1开始, 并返回一个标记数组和标记的数量
# 标记数组的形状和输入数组相同, 其中每个元素的值是该元素所属的联通区域的整数标记
# 创建一个二维数组
import numpy as np
from scipy.ndimage import measurements
data = np.array([[0, 0, 1, 1, 0],[0, 1, 1, 0, 0],[0, 0, 0, 0, 1],[1, 1, 0, 0, 0],[0, 0, 0, 1, 1]])# 标记连通区域
labeled_array, num_features = measurements.label(data)
print("Labeled Array:\n", labeled_array)
print("Number of Features:", num_features)
# Labeled Array:
#  [[0 0 1 1 0]
#  [0 1 1 0 0]
#  [0 0 0 0 2]
#  [3 3 0 0 0]
#  [0 0 0 4 4]]
# Number of Features: 4
#  标记数组值为1表示该元素属于第一个联通区域,值为2表示该元素属于第二个联通区域,以此类推
#  0表示该元素不属于任何联通区域
#  number_features表示联通区域的数量,这里有4个联通区域# 关于find_objects() ========================================================================
# 用于查找标记数组中每个标记对象的位置。它返回一个切片对象的列表,每个切片对象表示一个标记对象的位置。
# 输入参数
# input:标记数组,通常是由 scipy.ndimage.measurements.label 函数生成的数组。
# max_label(可选):要查找的最大标签。如果未提供,默认查找所有标签。
# 返回返回一个切片对象的列表,每个切片对象表示一个标记对象的位置。切片对象可以用于索引原始数组,以提取标记对象。# 使用上面的标记数组labeled_array
# 查找标记对象的切片
slices = measurements.find_objects(labeled_array)
print("Slices:", slices)
# Slices: [(slice(0, 2, None), slice(1, 4, None)), (slice(2, 3, None), slice(4, 5, None)), (slice(3, 4, None), slice(0, 2, None)), (slice(4, 5, None), slice(3, 5, None))]
print(data[slices[0]])
# [[0 1 1]
#  [1 1 0]]# slice(start, stop, step)表示一个切片对象,表示[start,stop)范围内的元素,step表示步长
# (slice(0, 2, None),slice(1, 4, None))表示第一个联通区域的行索引范围是[0,2),列索引范围是[1,4)# another solution
def validateBattlefield(field):  #print('\n'.join([''.join(['{:4}'.format(item) for item in row]) for row in field]))ships = []#this algorithm uses the field 2-dimensional array it self to store infomration about the size of ships found      for i in range(0, 10):            for j in range(0, 10):  #if not at end of any edge in 2d-array, check that sum of two cross diagonal elements is not more than max #if it is then two ships are two closeif j < 9 and i < 9: if field[i][j] + field[i+1][j+1] > max(field[i][j], field[i+1][j+1]): return False if field[i+1][j] + field[i][j+1] > max(field[i+1][j], field[i][j+1]):return False#if the element at position (i, j) is occupied then add the current value of position to nextif j < 9 and field[i][j] > 0 and field[i][j+1] > 0:field[i][j+1] += field[i][j]elif i < 9 and field[i][j] > 0 and field[i+1][j] > 0:field[i+1][j] += field[i][j]elif field[i][j] > 0:ships.append(field[i][j]) #since we add numbersships.sort()return ships == [1, 1, 1, 1, 2, 2, 2, 3, 3, 4] #if the ships we have found are of correct configuration then it will equal this array# 尝试重现别人的代码# try 1
from scipy.ndimage.measurements import label, find_objects
import numpy as np
def validate_battlefield_s(field):field = np.array(field)labeled_array = label(field,np.ones((3,3)))[0]positions = find_objects(labeled_array)result = []for pos in positions:ship = field[pos]if min(ship.shape)==1:result.append(ship.size)return sorted(result) == [1,1,1,1,2,2,2,3,3,4]# try 2
def validate_battlefield(field):#创建field的副本data = field[:]#使用切片操作创建field的副本ships = []for i in range(10):for j in range(10):if data[i][j]>0:#左下角if i+1<9 and j-1>=0 and data[i+1][j-1]>0:return False#右下角if i+1<9 and j+1<9 and data[i+1][j+1]>0:return Falseif j<9 and data[i][j+1]>0:data[i][j+1]+=data[i][j]elif i<9 and data[i+1][j]>0:data[i+1][j]+=data[i][j]else:ships.append(data[i][j])ships.sort()return ships==[1,1,1,1,2,2,2,3,3,4]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/905470.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue+leaflet示例:图层管理控件样式优化(附源码下载)

demo源码运行环境以及配置运行环境:依赖Node安装环境,demo本地Node版本:14.19.1。 运行工具:vscode或者其他工具。 配置方式:下载demo源码,vscode打开,然后顺序执行以下命令: (1)下载demo环境依赖包命令:npm i (2)启动demo命令:npm run dev (3)打包demo命令: n…

2025西安交大集训Day4:单调栈,单调队列,线段树

2025西安交大集训Day4:单调栈,单调队列,线段树 引入 何为单调栈?顾名思义,单调栈即满足单调性的栈结构。与单调队列相比,其只在一端进行进出。 为了描述方便,以下举例及伪代码以维护一个整数的单调递增栈为例。 过程 插入 将一个元素插入单调栈时,为了维护栈的单调性,需要…

日事清甘特图制作工具:一键生成,精准管理项目周期

还在为制作甘特图而焦虑吗?别担心,日事清甘特图重磅登场,轻松帮你完美化解难题,让复杂任务规划变得简单高效!在工作中,我们很多岗位都经常需要对项目进度进行追踪,例如人事经理需要要追踪招聘进度或员工培训计划, 项目经理负责监督项目的各个阶段以保证按计划执行, 软…

网站自动备份同步工具,自动备份同步工具有哪些?

网站自动备份同步工具是保障网站数据安全的关键,需兼顾实时性、可靠性、易用性。以下是分场景推荐的工具及部署方案:一、工具分类推荐80KM备份软件 功能:支持多种备份方式,如系统备份、磁盘备份、文件备份等,支持定时备份。 步骤:管理端点新增,不管选择从管理端备份到客…

智慧运维如何赋能现代医院?看某中西医结合医院的数字化转型之路

在医疗信息化浪潮中,某中西医结合医院作为一家集医疗、教学、科研于一体的三甲医院,始终走在创新前沿。面对业务系统庞杂、跨部门协作效率待提升等挑战,医院携手采和科技,以“智慧运维”为核心理念,开启了一场数字化转型的深度实践。 痛点破局:从“人找服务”到“服务找人…

day:29 断点

一、断点介绍 1.为什么要打断点呢? 接口测试可以不需要管前端的,主要测后端的功能 2.断点的作用: 1.开发人员,调试,出错后在某个位置打断点调试代码; 2.测试人员,测试,绕过前端的限制,测试后端的反应; 3.测试人员,构造数据,设置断点可篡改请求和返回的数据包。根据测…

UE5--002--EnhancedInput

1. IA_Pause 输入动作2. IMC_Default 输入映射上下文3. BP_FirstPersonCharacter蓝图3. 1 给PlayerController动态配置MappingContext3. 2 事件响应4. BP_FirstPersonGameMode蓝图4. Project Settings

信用消费的血栓问题-逾期订单诊断指南

在信用消费场景中,用户最怕看到的两个字莫过于“逾期”,但现实中,有相当一部分逾期记录源于系统协同中的技术误差。在本篇文章中我将揭示逾期订单的形成机制,并给出一些常见问题的解决方式,希望能帮助到大家。在信用消费场景中,用户最怕看到的两个字莫过于“逾期”——它…

Linux软件无法获取IGPV3的udp数据问题

问题 tcpdump能获取到数据,但是其他进程(内部获取udp)无法获取此udp数据 源是来自IGPV3的组播源,添加之前已经试过加入组播,但是还是无法接收到数据 解决 使用命令 systcl -a |grep rp_filter发现设备开启了严格的反向过滤关闭 net.ipv4.conf.all.rp_filter和net.ipv4.co…

如何通过接口测试驱动PLM效能提升?2025年禅道等工具实践白皮书

一、PLM系统测试的行业痛点与转型机遇 全球PLM市场规模预计2025年突破500亿美元,但企业调研显示,73%的PLM系统测试问题集中在接口兼容性与数据流断层。某汽车零部件厂商因BOM变更未触发ERP同步,导致生产线停摆4小时损失超千万。这暴露出传统测试方法的三大致命短板:数据孤岛…