AI 的早期萌芽?用 Swift 演绎约翰·康威的「生命游戏」
文章目录
- 摘要
- 描述
- 题解答案
- 题解代码分析
- 示例测试及结果
- 时间复杂度
- 空间复杂度
- 总结
摘要
你有没有想过,能不能通过简单的规则模拟出生与死亡?「生命游戏」正是这样一种充满魅力的数学模拟系统。这篇文章我们来聊聊它的规则到底有多神奇,并用 Swift 实现一个原地更新的算法,完全不需要额外内存空间,还能用得很优雅。如果你是算法练习者或者对模型仿真感兴趣,这篇你一定不能错过。
描述
生命游戏最早由数学家 John Conway 提出,是一种“零玩家游戏”。什么意思?就是说,一旦设置好初始状态,系统会自动演化,不再需要人为干预。
我们把一个二维网格当作世界,每个格子就是一个细胞。每个细胞的状态可能是“活”或“死”,状态变化完全依赖它周围八个邻居的状态。核心的规则有这几条:
- 活细胞周围活邻居少于 2 个 → 死(孤独)
- 活细胞周围 2 或 3 个活邻居 → 继续活着
- 活细胞周围超过 3 个活邻居 → 死(过度拥挤)
- 死细胞周围恰好有 3 个活邻居 → 复活!
所以我们要做的就是根据这四条规则,在原数组上进行原地更新,生成下一轮的世界。
题解答案
我们使用一个小技巧来原地记录状态的变化:
- 活→死 用
-1
表示 - 死→活 用
2
表示
这样我们在遍历的时候可以保留旧状态(通过 abs(board[i][j])
取得),等所有状态都计算完之后再统一转换回 0
或 1
。
题解代码分析
func gameOfLife(_ board: inout [[Int]]) {let m = board.countlet n = board[0].countlet directions = [(-1,-1), (-1,0), (-1,1),( 0,-1), ( 0,1),( 1,-1), ( 1,0), ( 1,1)]for i in 0..<m {for j in 0..<n {var liveNeighbors = 0// 统计活邻居数量for dir in directions {let x = i + dir.0let y = j + dir.1if x >= 0 && x < m && y >= 0 && y < n {if abs(board[x][y]) == 1 {liveNeighbors += 1}}}// 应用规则if board[i][j] == 1 && (liveNeighbors < 2 || liveNeighbors > 3) {board[i][j] = -1 // 活→死}if board[i][j] == 0 && liveNeighbors == 3 {board[i][j] = 2 // 死→活}}}// 最终状态统一替换for i in 0..<m {for j in 0..<n {board[i][j] = board[i][j] > 0 ? 1 : 0}}
}
示例测试及结果
我们用几个例子跑一下看看效果。
var board1 = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]gameOfLife(&board1)
print(board1)
// 输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]var board2 = [[1,1],[1,0]]gameOfLife(&board2)
print(board2)
// 输出:[[1,1],[1,1]]
你可以把这段代码直接贴到 Xcode Playground 或命令行 Swift 项目里跑一跑,观察每轮世界的变化,非常直观。
时间复杂度
我们遍历了整个二维数组一次,并对每个元素最多再遍历 8 个邻居,所以:
时间复杂度:O(m * n)
其中 m 和 n 是二维数组的行数和列数。
空间复杂度
我们没有使用额外的数组,只是在原数组中用 -1
和 2
来标记变化。
空间复杂度:O(1)(原地算法)
总结
“生命游戏”听起来像是一种编程游戏,但其实它也是模拟系统、分布式模型、甚至人工生命研究中的一个缩影。通过这种原地算法优化,我们不仅节省空间,还能更贴近“状态转移”的本质。
这道题的亮点在于如何处理状态切换时的数据保存问题,如果直接改掉原始数据,我们就没法知道旧值是否活着。而用 -1
和 2
的技巧正好帮我们保留了历史信息,最终只需一轮替换就能搞定。
相关文章:

AI 的早期萌芽?用 Swift 演绎约翰·康威的「生命游戏」
文章目录 摘要描述题解答案题解代码分析示例测试及结果时间复杂度空间复杂度总结 摘要 你有没有想过,能不能通过简单的规则模拟出生与死亡?「生命游戏」正是这样一种充满魅力的数学模拟系统。这篇文章我们来聊聊它的规则到底有多神奇,并用 S…...
【DBA】MySQL经典250题,改自OCP英文题库中文版(2025完整版)
【DBA】MySQL经典250题,改自OCP英文题库中文版(2025完整版) ——2025.5.15 文章目录 P1:1-50(划重点)P2:51-100(划重点)P3:101-150(划重点打标记&…...
Cursor 编辑器介绍:专为程序员打造的 AI 编程 IDE
在现代软件开发中,AI 辅助编程正逐步改变开发者的工作方式。Cursor 正是这场变革中的佼佼者,它不仅是一个现代化的代码编辑器,更是将强大的 AI 编程助手深度集成到 IDE 的一次探索性尝试。 一、什么是 Cursor? Cursor 是一款基于…...

go|channel源码分析
文章目录 channelhchanmakechanchansendchanrecvcomplieclosechan channel 先看一下源码中的说明 At least one of c.sendq and c.recvq is empty, except for the case of an unbuffered channel with a single goroutine blocked on it for both sending and receiving usin…...

【大模型学习】项目练习:视频文本生成器
🚀实现视频脚本生成器 视频文本生成器 📚目录 一、游戏设计思路二、完整代码解析三、扩展方向建议四、想说的话 一、⛳设计思路 本视频脚本生成器采用模块化设计,主要包含三大核心模块: 显示模块:处理用户输入和…...

【Rust】Rust获取命令行参数以及IO操作
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...

【Redis】Zset 有序集合
文章目录 常用命令zaddzcardzcountzrange && zrevrangezrangebyscorezpopmax && bzpopmaxzpopmin && zpopmaxzrank && zrevrankzscorezremzremrangebyrankzremrangebyscorezincrby 集合间操作交集 zinterstore并集 zunionstore 内部编码应用场…...

manus对比ChatGPT-Deep reaserch进行研究类论文数据分析!谁更胜一筹?
目录 没有账号,只能挑选一个案例 1、manus的效果 Step-1:直接看结果 Step-2:看看其他文件的细节 Step-3:看最终报告 2、Deep reaserch 3、Deep reaserch进行行业分析 总结一下: 大家好这里是学术Ananÿ…...

【 HarmonyOS 5 入门系列 】鸿蒙HarmonyOS示例项目讲解
【 HarmonyOS 5 入门系列 】鸿蒙HarmonyOS示例项目讲解 一、前言:移动开发声明式 UI 框架的技术变革 在移动操作系统的发展历程中,UI 开发模式经历了从命令式到声明式的重大变革。 根据华为开发者联盟 2024 年数据报告显示,HarmonyOS 设备…...
AWS Transit Gateway实战:构建DMZ隔离架构,实现可控的网络互通
在企业云网络架构中,如何实现不同VPC之间的安全互通是一个常见挑战。本文将通过AWS Transit Gateway实战,展示如何构建一个DMZ隔离架构,使DMZ可以与Test和Production环境互通,而Test和Production环境之间相互隔离。 1. Transit Gateway架构设计概述 在开始实践前,让我们先…...

用提示词写程序(3),VSCODE+Claude3.5+deepseek开发edge扩展插件V2
edge扩展插件;筛选书签,跳转搜索,设置背景 链接: https://pan.baidu.com/s/1nfnwQXCkePRnRh5ltFyfag?pwd86se 提取码: 86se 导入解压的扩展文件夹: 导入扩展成功: edge扩展插件;筛选书签,跳转搜索,设置背景...
栈与队列:数据结构的有序律动
在数据结构的舞台上,栈与队列宛如两位优雅的舞者,以独特的节奏演绎着数据的进出规则。它们虽不像顺序表与链表那般复杂多变,却有着令人着迷的简洁与实用,在众多程序场景中发挥着不可或缺的作用。今天,就让我们一同去探…...

初识PS(Photoshop)
初识PS(Photoshop) 1、Photoshop界面 2、常用快捷键...

go语言的GMP(基础)
1.概念梳理 1.1线程 通常语义中的线程,指的是内核级线程,核心点如下: (1)是操作系统最小调度单元; (2)创建、销毁、调度交由内核完成,cpu 需完成用户态与内核态间的切…...

电路图识图基础知识-高、低压供配电系统电气系统的继电自动装置(十三)
电气系统的继电自动装置 在供电系统中为保证系统的可靠性,保证重要负荷的不间断供电,常采用自动重合闸装置和备用电源自动投入装置。 1 自动重合闸装置 供配电系统多年运行实践表明,架空线路发生的故障多属于暂时性故障,如雷击…...
JDK21深度解密 Day 9:响应式编程模型重构
【JDK21深度解密 Day 9】响应式编程模型重构 引言:从Reactor到虚拟线程的范式转变 在JDK21中,虚拟线程的引入彻底改变了传统的异步编程模型。作为"JDK21深度解密"系列的第91天,我们将聚焦于响应式编程模型重构这一关键主题。通过…...
在 Linux 服务器上无需 sudo 权限解压/打包 .7z 的方法(实用命令)
7z的压缩比很高,可以把100G的文件压到3-5G,在大文件传输上很有优势但是一般服务器上是只有tar解压,用户没法(没有权限)直接安装7z工具来解压因此使用conda安装p7zip库可以很好地解决这个问题~ 关于7z的相关背景知识&am…...
微信小程序(uniapp)实现腾讯云 IM 消息撤回
uniapp 实现腾讯云 IM 消息撤回功能实战指南 一、功能实现原理 腾讯云 IM 的消息撤回功能通过 消息修订(Message Revision) 机制实现,核心流程如下: 发送方调用撤回 API 删除指定消息云端生成撤回通知消息(类型为 T…...
设计学生管理系统的数据库
在设计学生管理系统的数据库时,需要考虑多个实体及其关系。以下是一个基本的学生管理系统表结构设计,涵盖了核心实体和关系: 1. 用户表 (user) 存储所有系统用户的基本信息,包括学生、教师和管理员。 sql CREATE TABLE user (u…...
ArcGIS Pro 3.4 二次开发 - 图形图层
环境:ArcGIS Pro SDK 3.4 + .NET 8 文章目录 图形图层1.1 创建图形图层1.2 访问GraphicsLayer1.3 复制图形元素1.4 移除图形元素2 创建图形元素2.1 使用CIMGraphic创建点图形元素2.2 使用CIMGraphic创建线图元素2.3 使用 CIMGraphic 的多边形图形元素2.4 使用CIMGraphic创建多…...
Linux配置DockerHub镜像源配置
个人博客地址:Linux配置DockerHub镜像源配置 | 一张假钞的真实世界 因为某些原因,DockerHub官方镜像源已不可用,国内一些镜像源也已不可用,大家可以搜索可用的镜像源并修改配置。推荐一篇良心博文:https://zhuanlan.z…...
JDK21深度解密 Day 11:云原生环境中的JDK21应用
【JDK21深度解密 Day 111】云原生环境中的JDK21应用 本文是《JDK21深度解密:从新特性到生产实践的全栈指南》专栏的第11天内容,聚焦云原生环境中的JDK21应用。我们将深入探讨如何在容器化、微服务、Serverless等云原生架构中充分发挥JDK21的技术优势,提升Java应用的性能、稳…...
如何学习才能更好地理解人工智能工程技术专业和其他信息技术专业的关联性?
要深入理解人工智能工程技术专业与其他信息技术专业的关联性,需要跳出单一专业的学习框架,通过 “理论筑基 - 实践串联 - 跨学科整合” 的路径构建系统性认知。以下是分阶段、可落地的学习方法: 一、建立 “专业关联” 的理论认知框架 绘制知…...

Qt实现的水波进度条和温度进度条
一.效果 二.原理 1.水波 要模拟波浪,就要首先画出一条波浪线,正弦余弦曲线就很适合。 y=A*sin(ω*x+φ)+k y=A*cos(ω*x+φ)+k 这是正弦余弦曲线的公式,要想实现水波效果,那需要两条曲线,一条曲线的波峰对着另外一条曲线的波谷,要实现这样的曲线效果,只有让正弦曲线前移…...
3516cv610在sample_aiisp上多创一路编码流,方法
3516cv610在sample_aiisp上多创一路编码流,方法 首先确保 vpss grp0有视频流 最好保证 已经有一路视频流能推出来 多创一路编码流思路为 将 vpss grp0又绑定给 vpss_chn1 vpss_chn1有绑定给 venc_chn1 这样我们就多创了一路视频流。 这里思路完全正确 可以实现…...

WEBSTORM前端 —— 第3章:移动 Web —— 第4节:移动适配-VM
目录 一、适配方案 二、VM布局 编辑 三、vh布局 四、案例—酷我音乐 一、适配方案 二、VM布局 三、vh布局 四、案例—酷我音乐...
Android第十一次面试补充篇
Livedata内存泄漏解决 1. 未正确绑定 LifecycleOwner 原因: 使用 observe() 时未传入正确的 LifecycleOwner(如 Activity/Fragment),或误用 Application 等长生命周期对象,导致观察者无法自动解除绑定。 …...

【Zephyr 系列 3】多线程与调度机制:让你的 MCU 同时干多件事
好的,下面是Zephyr 系列第 3 篇:聚焦 多线程与调度机制的实践应用,继续面向你这样的 Ubuntu + 真板实战开发者,代码清晰、讲解通俗、结构规范,符合 CSDN 高质量博客标准。 🧠关键词:Zephyr、线程调度、k_thread、k_sleep、RTOS、BluePill 📌适合人群:想从裸机开发进…...

Kotlin-特殊类型
文章目录 数据类型枚举类型匿名类和伴生对象单例类伴生对象 数据类型 声明一个数据类非常简单: //在class前面添加data关键字表示为一个数据类 data class Student(var name: String, var age: Int)数据类声明后,编译器会根据主构造函数中声明的所有属性自动为其生成以下函数…...

nssctf第二题[SWPUCTF 2021 新生赛]简简单单的逻辑
这是题目,下载后得到一个python文件,打开 解读代码: for i in range(len(list)):key (list[i]>>4)((list[i] & 0xf)<<4)result str(hex(ord(flag[i])^key))[2:].zfill(2)list[i]>>4:从列表中取数字同时高4位向右位…...