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

用 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. Atcoder ABC244E - King Bombee 题解

    原题: Atcoder ABC244E - King Bombee 题意 给你一张图,从 \(S\) 到 \(T\),经过 \(k\) 条边, 经过 \(X\) 号点偶数次的方案数. 做法 设 \(f ...

  2. 【技术积累】Mysql中的SQL语言【技术篇】【三】

    聚合函数 SUM函数 在MySQL中,SUM函数是用于计算数值列的总和的聚合函数.它接受一个数值列作为参数,并返回该列中所有值的总和. 以下是一个使用SUM函数的示例: 假设我们有一个名为" ...

  3. PostgreSQL 10 文档: PostgreSQL 服务器程序

    PostgreSQL 服务器应用 这一部分包含PostgreSQL服务器应用和支持工具的参考信息.这些命令只在数据库服务器所在的主机上运行才有用.其他工具程序在PostgreSQL 客户端应用中列出. ...

  4. git报错:error: Your local changes to the following files would be overwritten by checkout:

    原因 原本想切换到dev分支,拉取远程dev分支,但我将分支上的数据修改了,此时切换分支报错 解决方案 方法一: 存到暂存区 # 暂存 git add . git stash 之后切换分支到dev,执 ...

  5. 你真的知道吗?catch、finally和return哪个先执行

    我的一位朋友前阵子遇到一个问题,问题的核心就是try--catch--finally中catch和finally代码块到底哪个先执.这个问题看起来很简单,当然是"catch先执行.final ...

  6. K8S | Config应用配置

    绕不开的Config配置: 一.背景 在自动化流程中,对于一个应用来说,从开发阶段的配置管理,到制作容器镜像,再到最后通过K8S集群发布为服务,整个过程涉及到的配置非常多: 应用环境:通常是指代码层面 ...

  7. Linux下apt与dpkg的详解

    apt是一个包管理工具,用于管理Debian和Ubuntu等基于Debian的Linux发行版中的软件包.它是"Advanced Packaging Tool"的缩写,允许用户在系 ...

  8. 优化nginx参数(基本通用参数)

    全局域配置参数 worker_processes auto; worker_cpu_affinity auto; worker_rlimit_nofile 65530; 前两个参数用于开启nginx多 ...

  9. DirtyCow 脏牛提权漏洞(CVE-2016-5195)

    描述: 该漏洞是 Linux 内核经典漏洞,内核内存子系统在处理写时拷贝(Copy-on-Write)时存在条件竞争漏洞, 导致可以破坏私有只读内存映射.黑客可以在获取低权限的的本地用户后,利用此漏洞 ...

  10. Sourcetrail 代码分析工具的使用

    Sourcetrail 概述 Sourcetrail 是一个代码分析工具,它旨在帮助开发人员理解和导航复杂的代码库.它可以创建代码库的可视化图形,显示代码中的类.函数.变量.依赖关系等信息,从而帮助开 ...