[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
回复 2# CrLf

分析一下这里最核心的算法:  8进制, 同余原理 计算邻居数, 逻辑计算

设 3 X 3 方格区域如下
ab c
d e f
g h i

a,b,c,d,e,f,g,h,i  的值均为 0 或者 1, 0abcdefghi 可以构成一个 8 进制数, 换算成十进制就是
0abcdefghi = a*8^8 + b*8^7 + c*8^6 + d*8^5 + e*8^4 + f*8^3 + g*8^2 + h*8^1 + i*8^0
根据同余定理,  8^8, 8^7, ... 8^2, 8 对 7 的余数都是 1, 所以 0abcdefghi %% 7 = (a+b+c+d+e+f+g+h+i) %% 7
a+b+c+d+e+f+g+h+i 的值域为 [0,9], 这是 3 X 3 区域的总人口数, 取余数后有这样一个映射
[0,1,2,3,4,5,6,7,8,9] --> [0,1,2,3,4,5,6,0,1,2]

而如果去掉中间方格 e 时有
(0abcdefghi & 0111101111) %% 7 = (a+b+c+d+f+g+h+i) %% 7
a+b+c+d+f+g+h+i 的值域为 [0,8], 是中间方格的邻居总数, 取余数后有这样一个映射
[0,1,2,3,4,5,6,7,8] --> [0,1,2,3,4,5,6,0,1]

康威生命游戏的规则是 B3/S23, 即在空位置的邻居有 3 个时, 可以在此位置新生;  在某位置有生命 且 周围邻居是 2 或 3 个时, 此位置生命可以继续存活; 其他任何情况下, 一个位置的生命将死亡, 或者保持无生命.
这个规则还可以换成如下两种不同的描述:
A. 当某位置的邻居为 2 个时, 此位置的下一代保持当前状态;  当邻居数为 3 个时, 无论当前状态如何, 下一代一定有生命.
B. 当 3X3 区域的人口总数 < 3 个时, 下一代在中心位置一定没有生命; 当区域人口总数 = 3 个时, 下一代在中心位置一定有生命; 当区域人口总数 = 4 个时, 中心位置保持当前状态; 当人口总数 > 4 个时, 下一代在中心位置一定没有生命.

以下是 描述 A 的伪代码
set /a "n=(0abcdefghi & 0111101111)%%7, next=(^!(n-2) & e) +^!(n-3)"
n=(0abcdefghi & 0111101111) %%7 求得邻居数对 7 的余数, 在描述 A 中, 由于邻居数 [7,8] 和 [0,1] 的结果是一样的(在中心位置下一代都不会有生命),  所以取余映射不会造成错误
next=(^!(n-2) & e) +^!(n-3)  当 n = 2 时, 取 单元格 e 的值;  当 n = 3 时, 得 1; 其他各种情况, 最后均得 0.

以下是 描述 B 的伪代码
set /a "n=0abcdefghi %% 7, next=^!(n-4) & e | ^!(n-3)"
n=0abcdefghi %% 7 求得总人口数对 7 的余数, 在描述 B 中, 由于人口数 [7,8,9] 和 [0,1,2] 的结果是一样的(在中心位置下一代都不会有生命),  所以取余映射不会造成错误
next=^!(n-4) & e | ^!(n-3) 当 n = 4 时, 取单元格 e 的值;  当 n = 3 时, 得 1;  其他各种情况, 最后得 0.

楼主代码中
xy=^!(xy-2)*(!行%%a:~%%X,2!&1)+^!(xy-3)
也可以写成 (   !行%%a:~%%X,2!  有4种情况: 8进制: 00, 01  十进制: 10, 11  )
xy=^!(xy-2) & !行%%a:~%%X,2! | ^!(xy-3)

以下是测试代码
  1. @echo off & setlocal enableDelayedExpansion
  2. mode 80,600
  3. set "A= *"
  4. for %%a in (0 1) do for %%b in (0 1) do for %%c in (0 1) do for %%d in (0 1) do (
  5.         for %%e in (0 1) do for %%f in (0 1) do for %%g in (0 1) do for %%h in (0 1) do for %%i in (0 1) do (
  6.                 set "S=%%a%%b%%c%%d!A:~%%e,1!%%f%%g%%h%%i" & set "S=!S:0=_!"
  7.                 REM echo !S!
  8.                 set /a "popu=0x%%a%%b%%c%%d%%e%%f%%g%%h %% 15 + %%i"
  9.                 REM set /a "n=(0%%a%%b%%c%%d%%e%%f%%g%%h%%i & 0111101111) %% 7, n=^!(n-2) * (%%d%%e & 1) + ^!(n-3)"
  10.                 REM set /a "n=(0%%a%%b%%c%%d%%e%%f%%g%%h%%i & 0111101111) %% 7, n=^!(n-2) & %%e | ^!(n-3)"
  11.                 set /a "n=0%%a%%b%%c%%d%%e%%f%%g%%h%%i %% 7, n=^!(n-4) & %%e | ^!(n-3)"
  12.                 if !n!==1 (if %%e==0 (set B_!popu! !S!=1) else set S_!popu! !S!=1) else set "D_!popu! !S!=0"
  13.         )
  14. )
  15. set B_ & set S_ & set D_
  16. pause
复制代码
1

评分人数

TOP

回复 9# 523066680

美女必须登场,   比楼上 教授哥哥 还年轻两岁哦
1

评分人数

TOP

返回列表