之前在网上看到徐大佬更新的一篇文章:

用 TypeScript 类型运算实现一个中国象棋程序

在线预览地址:https://tsplay.dev/Nd4n0N 把鼠标放在最后几行的走棋结果上,惊喜的一幕出现了,有点发现新大陆的感觉,哇,炫酷。

后面就很好奇,是如何实现的呢?

我们先看大佬说的第一句话,“众所周知,TypeScript 是图灵完备的……”为什么说ts是图灵完备的呢?下面开始了我的探索。

什么是图灵完备?

维基百科是这样定义的:

一个计算系统可以计算任何图灵-可计算函数,被称作图灵完全(或者图灵完备)。或者任何可以模拟通用图灵机的系统。

即如果一个设备可以模拟图灵机,那么它就可以执行任何种类的计算。

它意味着任何实现以下八条指令的机器都是一台计算机(因此可以执行任何种类的计算)。

  • . ,: 输入或输出一个指令
  • + -: 加或减内存中的值
  • > <: 将当前的指针向左或向右移动。
  • [ ]: 执行循环

如果某种语言可以执行以上八种指令,就可以称为是图灵完备的。

我们用以上八种指令,验证一下,狗狗是否是图灵完备的,狗狗叫小花。

1、输入/输出

我拍了拍小花的头,她看了看我,然后继续趴着。

输入:拍头

输出:抬头,趴着

完成!

2、增加/减少内存中的值

瓷砖格子很像图灵机的纸条,我把狗粮撒在瓷砖上,小花可以直接从地板吃下去,她可以吃掉,也可以吐出来。

所以她可以增加/减少内存中的值。

完成!

3、将当前记忆头指针向前或向后移动

一天,小花跟yoyo疯跑,把她的饭盒移动,狗粮撒的到处都是。

如上图,在制造这个混乱的时候,她把她的饭盒移开了。

移开她的饭盒意味着她会把她的狗粮洒在另一块瓷砖上。

这算作转移记忆头,编辑另一个记忆单元。存储指针移动啦!

完成!

4、执行循环

刚把地上打扫干净,小花一会又把地上弄乱了。

实现循环

完成!

以上,我们证明小花是图灵完备的,那如何利用她的完备性进行程序计算呢?

好吧,让小花来执行一段:

好像不行哎~

尽管她是图灵完备的,但也不是专门用来程序计算的。所以能进行程序计算的一定是图灵完备的,图灵完备的不一定能进行程序计算。

不过,既然可以实现象棋,而且是用中文写的哦,超级厉害!

那TS是可以进行计算的,我也来试试吧!

之前公众号写过python实现汉诺塔的图解递归算法,改改

//核心:每个类型可以看成一个函数,传入的泛型是函数参数,并且也是一个类型,最后再返回一个新的类型
type 塔一 = 'A' type 塔二 = 'B' type 塔三 = 'C' // type 塔 = 塔一 | 塔二 | 塔三
type 得到长度<数组 extends any[]> = 数组["length"]; //exstends 和后边的 ? 构成了一个三元表达式,如果 extends 前面的类型能够赋值给 extends 后面的类型,那么表达式判断为真,否则为假。
type 转为数组< 某数 extends number, 对应数组 extends any[] = [] // 默认值赋一个空数组,外部调用的时候不需要传 > = 得到长度<对应数组> extends 某数 // 长度是否等于了需要的长度 ? 对应数组 // 如果长度等于所需要的了就返回 : 转为数组<某数, [any, ...对应数组]>; // 否则再添加一个元素进入数组,然后递归调用 type 相加<某数甲 extends number, 某数乙 extends number> = 得到长度< [...转为数组<某数甲>, ...转为数组<某数乙>]
>; type 数组减一<某数组类型 extends any[]> = (( ...参数: 某数组类型 ) => any) extends (拆一个元素: any, ...剩下的数组: infer 剩下的数组类型) => any ? 剩下的数组类型 : []; //将数字转为对应数组,数组减去一个元素,然后恢复为数字即可。
type 减一<某数 extends number> = 得到长度<数组减一<转为数组<某数>>>; //汉诺塔关键函数
type 汉诺塔<某数 extends number,塔一,塔二,塔三> = 某数 extends 1 ? [塔一,"--->",塔三]
:
[汉诺塔<减一<某数>,塔一,塔三,塔二>,
[塔一,"--->",塔三],
汉诺塔<减一<某数>,塔二,塔一,塔三>] //渲染
type 测试 = 汉诺塔<3,塔一,塔二,塔三>

其中还涉及ts相关知识点,详细了解typeScript,不做详细展开说明了。

TS实现汉诺塔算法,以及图灵完备讨论的更多相关文章

  1. 汉诺塔算法详解之C++

    汉诺塔: 有三根杆子A,B,C.A杆上有N个(N>1)穿孔圆环,盘的尺寸由下到上依次变小.要求按下列规则将所有圆盘移至C杆: 每次只能移动一个圆盘: 大盘不能叠在小盘上面. 提示:可将圆盘临时置 ...

  2. 汉诺塔算法的递归与非递归的C以及C++源代码

    汉诺塔(又称河内塔)问题其实是印度的一个古老的传说. 开天辟地的神勃拉玛(和中国的盘古差不多的神吧)在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一 个小, ...

  3. Java-Runoob-高级教程-实例-方法:03. Java 实例 – 汉诺塔算法-un

    ylbtech-Java-Runoob-高级教程-实例-方法:03. Java 实例 – 汉诺塔算法 1.返回顶部 1. Java 实例 - 汉诺塔算法  Java 实例 汉诺塔(又称河内塔)问题是源 ...

  4. java利用递归实现汉诺塔算法

    package 汉诺塔; //引入Scanner包,用于用户输入 import java.util.Scanner; public class 汉诺塔算法 { public static void m ...

  5. java实现汉诺塔算法

    package com.ywx.count; import java.util.Scanner; /** * @author Vashon * date:20150410 * * 题目:汉诺塔算法(本 ...

  6. 汉诺塔算法c++源代码(递归与非递归)[转]

     算法介绍: 其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n - 1(有兴趣的可以自己证明试试看).后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了.首先把三根柱 ...

  7. Java汉诺塔算法

    汉诺塔问题[又称河内塔]是印度的一个古老的传说. 据传开天辟地之神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把 ...

  8. python实现汉诺塔算法

    汉诺塔 算法分析 1.步骤1:如果是一个盘子,直接将a柱子上的盘子从a移动到c 否则 2.步骤2:先将A柱子上的n-1个盘子借助C移动到B(图1) 已知函数形参为hanoi(n,a,b,c),这里调用 ...

  9. 如何用Go语言实现汉诺塔算法

    package main import ( "fmt" ) func print(n int,x rune,y rune)(){ fmt.Printf("moving d ...

  10. python 递归实现汉诺塔算法

    def move(n,a,b,c): if (n == 1): print ( "第 ", n ," 步: 将盘子由 " ,a ," 移动到 &quo ...

随机推荐

  1. CMU15-445 Project4 Concurrency Control心得

    一.概述 过瘾!过瘾!过瘾!P4 真过瘾!写 P3 的博客时我说过"感觉自己在数据库方面真正成长了",但写完 P4 之后最大的感受就是,我终于理解了 andy 在第一课说过的&qu ...

  2. ASP.NET 6 使用工作单元操作 MongoDB

    大家好,我是Edison. 最近工作中需要用到MongoDB的事务操作,因此参考了一些资料封装了一个小的组件,提供基础的CRUD Repository基类 和 UnitOfWork工作单元模式.今天, ...

  3. Blazor前后端框架Known-V1.2.6

    V1.2.6 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行. Gitee: https://gitee.com/known/Known Gith ...

  4. TOML是什么格式

    TOML(Tom's Obvious, Minimal Language)是一种用于配置文件的轻量级.易读的数据序列化格式.它由Tom Preston-Werner创建,旨在成为一种简单直观的配置文件 ...

  5. 沃罗诺伊图 (Voronoi diagram)

    沃罗诺伊图 (Voronoi diagram) Introduction: what is voronoi diagram? 沃罗诺伊图 (Voronoi diagram),取名自俄罗斯数学家乔治·沃 ...

  6. IIC、SPI、UART三者对比

    下面将对比三者的各自差异: 参考资料: 1.(112条消息) UART, SPI, IIC的详解及三者的区别和联系_iic spi uart_静思心远的博客-CSDN博客

  7. 模型权重保存、加载、冻结(pytorch)

    1. 保存整个网络 torch.save(net, PATH) model = torch.load(PATH) 2. 保存网络中的参数(速度快,占空间小) torch.save(net.state_ ...

  8. 日志监控平台搭建(Loki+promtail+grafana)

    搭建Loki+promtail+grafana日志监控平台,可以直接在grafana的UI界面查看系统应用日志,使日志查看起来更方便.快捷.   Loki:主服务器,负责存储日志和处理查询. Prom ...

  9. centos7.X安装mysql5.7 – 东凭渭水流

    1.下载mysql5.7 可以使用windows下载好后上传至Linux.网络条件好的推荐使用 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/m ...

  10. springboot集成seata1.5.2+nacos2.1.1

    一.前言 Seata出现前,大部分公司使用的都是TCC或者MQ(RocketMq)等来解决分布式事务的问题,TCC代码编写复杂,每个业务均需要实现三个入口,侵入性强,RocketMQ保证的是最终一致性 ...