You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

图灵机实现:从一元编码序列中按左向右选第k个元素

图灵机数字选择函数修正问题

数字选择函数定义

输入:序列𝑥₁,𝑥₂,…,𝑥ₙ,𝑘,满足:

  • 每个𝑥ᵢ为非负整数;
  • 𝑘为正整数;
  • 所有数字采用一元编码:用a的重复次数代表数值,b作为分隔符,输入编码格式为a^x₁ba^x₂…ba^xₙa^k(最后一个元素𝑥ₙ后无b,直接接𝑘的编码)。

输出:第k个数字𝑥ₖ的一元编码a^xₖ,无末尾b。非法输入(如k=0、k>n)需触发崩溃。

当前问题

我的思路是通过标记k的编码a递减计数,但现有代码会从右往左选取第k个元素。例如输入序列1,5,2,3(对应编码abaaaaabaabaaa),代码选取的是从右数第3个元素,而我需要按左向右顺序选取第3个元素(即2)。使用的是仅向右无限扩展的Tuatara模拟器,磁头从磁带最左端开始。

原代码

createTuring({
    transitions: [
        // First, move to the end of the tape
        { state: "start",  read: "a",               move: "R", nextState: "start" },
        { state: "start",  read: "b",               move: "R", nextState: "start"  },
        { state: "start",  read: "_",               move: "L", nextState: "init"   },
        
        // Begin the algorithm from the end
        { state: "init",   read: "a",   write: "A", move: "L", nextState: "get"    },
        { state: "init",   read: "b",              move: "L", nextState: "reject" },
        { state: "init",   read: "_",              move: "L", nextState: "reject" },
        
        { state: "get",    read: "a",   write: "_", move: "L", nextState: "findb"  },
        { state: "get",    read: "B",   write: "_", move: "L", nextState: "wipe"   },
        { state: "get",    read: "b",   write: "_", move: "L", nextState: "keep"   },
        
        { state: "findb",  read: "aB",              move: "L", nextState: "findb"  },
        { state: "findb",  read: "b",   write: "B", move: "R", nextState: "rewind" },
        { state: "findb",  read: "_",               move: "R", nextState: "reject" },
        
        { state: "rewind", read: "aB",              move: "R", nextState: "rewind" },
        { state: "rewind", read: "_",               move: "L", nextState: "get"    },
        
        { state: "wipe",   read: "aB",  write: "_", move: "L", nextState: "wipe"   },
        { state: "wipe",   read: "b",   write: "_", move: "L", nextState: "keep"   },
        { state: "wipe",   read: "_",               move: "R", nextState: "reject" },
        
        { state: "keep",   read: "a",               move: "L", nextState: "keep"   },
        { state: "keep",   read: "_",               move: "R", nextState: "pickup" },
        { state: "keep",   read: "b",   write: "_", move: "L", nextState: "trim"   },
        
        { state: "trim",   read: "ab",  write: "_", move: "L", nextState: "trim"   },
        { state: "trim",   read: "_",               move: "R", nextState: "pickup" },
        
        { state: "pickup", read: "a",   write: "_", move: "R", nextState: "roll"   },
        { state: "pickup", read: "_",               move: "R", nextState: "pickup" },
        { state: "pickup", read: "A",   write: "_",            nextState: "accept" },
        
        { state: "roll",   read: "a",               move: "R", nextState: "roll"   },
        { state: "roll",   read: "_",   write: "a", move: "L", nextState: "left"   },
        { state: "roll",   read: "A",   write: "a",            nextState: "accept" },
        
        { state: "left",   read: "a",               move: "L", nextState: "left"   },
        { state: "left",   read: "_",               move: "R", nextState: "pickup" },
    ],
    initState: "start",
    tape: "abaaaaabaabaaa"
});
<script src="https://trincot.github.io/turing.js"></script>

修改方案

核心思路

  1. 标记k的编码:先找到最后一个b之后的所有a(即k的编码),将其替换为标记K,用于后续递减计数。
  2. 左向右遍历计数:回到磁带最左端,逐个遍历元素,每遇到一个b就代表完成一个元素的遍历,此时删除一个K(k减1),直到K全部删除(k=0),此时当前遍历的元素就是目标𝑥ₖ。
  3. 清理磁带输出结果:删除磁带上的其他内容,只保留目标元素的a编码。

修改后的代码

createTuring({
    transitions: [
        // 第一步:找到最后一个b,标记k的a为K
        { state: "start", read: "a", move: "R", nextState: "start" },
        { state: "start", read: "b", move: "R", nextState: "mark_k_start" },
        { state: "start", read: "_", move: "L", nextState: "reject" }, // 无b说明只有k,非法
        
        // 标记k的所有a为K
        { state: "mark_k_start", read: "a", write: "K", move: "R", nextState: "mark_k" },
        { state: "mark_k_start", read: "_", move: "L", nextState: "reject" }, // k=0,非法
        { state: "mark_k", read: "a", write: "K", move: "R", nextState: "mark_k" },
        { state: "mark_k", read: "_", move: "L", nextState: "find_last_b" },
        
        // 回到最后一个b的位置,再返回磁带开头
        { state: "find_last_b", read: "K", move: "L", nextState: "find_last_b" },
        { state: "find_last_b", read: "b", move: "L", nextState: "go_to_start" },
        { state: "go_to_start", read: "a", move: "L", nextState: "go_to_start" },
        { state: "go_to_start", read: "b", move: "L", nextState: "go_to_start" },
        { state: "go_to_start", read: "_", move: "R", nextState: "count_elements" },
        
        // 第二步:逐个遍历元素,递减k计数
        { state: "count_elements", read: "a", move: "R", nextState: "count_elements" },
        { state: "count_elements", read: "b", move: "R", nextState: "decrement_k" },
        { state: "count_elements", read: "K", move: "R", nextState: "reject" }, // k>n,非法
        
        // 递减k:删除一个K,然后回到当前元素的开头
        { state: "decrement_k", read: "a", move: "R", nextState: "decrement_k" },
        { state: "decrement_k", read: "b", move: "R", nextState: "decrement_k" },
        { state: "decrement_k", read: "K", write: "_", move: "L", nextState: "go_back_to_current" },
        { state: "decrement_k", read: "_", move: "L", nextState: "reject" }, // k>n,非法
        
        // 返回当前元素的起始位置
        { state: "go_back_to_current", read: "a", move: "L", nextState: "go_back_to_current" },
        { state: "go_back_to_current", read: "b", move: "R", nextState: "check_k" },
        { state: "go_back_to_current", read: "_", move: "R", nextState: "check_k" },
        
        // 检查k是否已减到0
        { state: "check_k", read: "a", move: "R", nextState: "check_k" },
        { state: "check_k", read: "b", move: "R", nextState: "check_k" },
        { state: "check_k", read: "K", move: "L", nextState: "count_elements" }, // k还没到0,继续遍历
        { state: "check_k", read: "_", move: "L", nextState: "target_found" }, // k=0,找到目标元素
        
        // 第三步:清理磁带,保留目标元素的a
        { state: "target_found", read: "a", move: "L", nextState: "target_found" },
        { state: "target_found", read: "b", move: "R", nextState: "clear_left" },
        { state: "target_found", read: "_", move: "R", nextState: "clear_left" },
        
        // 删除目标元素左侧的所有内容
        { state: "clear_left", read: "a", write: "_", move: "L", nextState: "clear_left" },
        { state: "clear_left", read: "b", write: "_", move: "L", nextState: "clear_left" },
        { state: "clear_left", read: "_", move: "R", nextState: "clear_right" },
        
        // 删除目标元素右侧的所有内容(包括K和b)
        { state: "clear_right", read: "a", move: "R", nextState: "clear_right" },
        { state: "clear_right", read: "b", write: "_", move: "R", nextState: "clear_right" },
        { state: "clear_right", read: "K", write: "_", move: "R", nextState: "clear_right" },
        { state: "clear_right", read: "_", move: "L", nextState: "accept" },
        
        // 拒绝状态
        { state: "reject", read: "_", move: "R", nextState: "reject" }
    ],
    initState: "start",
    tape: "abaaaaabaabaaa"
});

关键修改说明

  • 新增mark_k相关状态:专门标记k的编码为K,避免和元素的a混淆。
  • 调整遍历方向:从磁带最左端开始,逐个元素计数,每完成一个元素就递减k的标记K,直到k为0。
  • 新增非法输入判断:比如k=0(无a标记)、k>n(遍历完所有元素后还有K剩余)都会触发reject状态。
  • 清理逻辑优化:精准保留目标元素的a,删除其他所有内容,输出符合要求的结果。

内容的提问来源于stack exchange,提问作者Tien Hung Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:05:04