Beginner J: Dealing Cards
摘要
该文章介绍了在J语言中使用目录运算符、转置、随机数函数和排列函数生成扑克牌、发牌和洗牌的方法。
<p><a href="https://lobste.rs/s/jgaxxy/beginner_j_dealing_cards">Comments</a></p>
查看缓存全文
缓存时间: 2026/07/27 01:42
### TL;DR
在 J 语言中,可以使用目录运算符 `{` 生成扑克牌所有组合,用转置 `|:` 调整顺序,再展平为符号数组;通过 `?` 的二元形式实现无重复发牌,用 `A.` 函数按排列索引高效洗牌。
### 创建一副标准扑克牌
#### 生成所有花色与点数组合
一副扑克牌有四种花色:`梅花`、`方块`、`红心`、`黑桃`;点数有13个等级:`2` 到 `10`、`J`、`Q`、`K`、`A`。使用目录运算符 `{`(左花括号)可以查看所有组合。分号 `;` 将两个字符串放入盒子中,目录运算符取所有盒子值的组合:
```j
'梅花';'方块';'红心';'黑桃' { '2';'3';'4';'5';'6';'7';'8';'9';'10';'J';'Q';'K';'A'
```
接着用转置运算符 `|:` 翻转结果,使输出更美观。然后将盒子中的字符串转换为符号,用 `,`(ravel)展平,并赋值给变量 `deck`:
```j
deck =: , |: '梅花';'方块';'红心';'黑桃' { '2';'3';'4';'5';'6';'7';'8';'9';'10';'J';'Q';'K';'A'
```
若希望按点数排序而非花色,去掉转置即可。检查牌堆长度:`# deck` 返回 `52`。
#### 访问牌
用 `{.`(take)抓取前四张牌(因按点数排序,得到2点)。也可以从底部发牌(用负数索引)。索引从0开始:梅花2是第0张牌,黑桃A是第51张。超出范围会报错,但允许 `-1` 到 `-52`。
### 字符串、符号与查找
#### 为什么使用符号
J 的数组要求矩形,未装箱的字符串数组长度必须相同。所有牌面恰好是两个字符,所以也可建模为 `52 2` 的字符数组,但视频作者偏好符号。符号用 `<` 装箱后传递给 `s:` 构造,或在字符串前加一个“品丝字符”分隔多个符号。例如:
```j
s: < '梅花2'
```
或使用品丝字符(空格):`'#梅花2' 1} s:`。
#### 反向查找:找到红心Q
给定字符串 `'红心Q'`,需先转为符号(因为牌堆是符号数组)。用 `i.` 在牌堆中查找符号位置:
```j
i. s: < '红心Q'
```
返回所有匹配的索引(此处只有一张),然后可用 `{` 提取对应牌。
### 随机数与发牌
#### 一元 `?`(roll)与二元 `?`(deal)
- `?` 一元形式生成随机整数(如 `?100`),每次结果不同。
- `?.` 使用固定种子。
- 二元形式 `?` 称为“发牌”(deal),保证结果不重复。例如 `5?5` 输出0到4的排列。
- 若允许重复,可用一元形式配合复制:`5#5` 产生五个5,但 `?5#5` 像掷五个五面骰子。
#### 灵活使用 `~` 交换参数
- 从牌堆取一张随机牌:`(?. # deck) { deck`,但用 `~` 可简化:`deck {~ ? # deck`。
- 发任意张牌(如5张):`deck {~ 5 ? # deck`。
- 洗整副牌:`deck {~ ?~ # deck` 等价于 `deck {~ 52?52`。`~` 在 `?` 上为自反射,使左右参数相同(`?~ 52` → `52 ? 52`);在 `{` 上为被动,交换参数。
### 洗牌与排列
#### 阶乘与排列总数
一副牌所有排列方式的数量是 `!52`(J 中的阶乘)。用扩展精度整数显示精确值(末尾加 `x`):`!52x` 得到约 `8×10^67`。
#### 字谜函数 `A.`
`A.` 可避免生成巨大的排列表。例如字符串 `'abcd'` 有 `4!` 种排列。一元形式 `A. y` 返回 y 在全部排列中的索引;二元形式 `x A. y` 返回索引 x 对应的排列(不实际构建表)。用参数 `# deck` 和随机索引即可洗牌:
```j
deck {~ (? ! # deck) A. deck
```
如果要得到按特定顺序排列的牌,只需找到该排列的索引(用一元 `A.` 查询)。
### 总结
J 通过符号、目录运算符、发牌(`?`)和字谜函数(`A.`)提供了简洁的牌组操作方式。对于面试题“生成所有排列”,J 的递归解法也可作为挑战。最终,处理一副牌的关键是善用这些原生函数,避免低效地构造完整排列表。
Source: https://www.youtube.com/watch?v=eXGKK8BkCkg
相似文章
@Jolyne_AI: 学完 C 语言语法,却卡在「不知道写什么」?网上教程又零散、难串成体系。 Project Box 把这件事做成了:一套为 C 初学者整理好的项目合集,从入门到进阶一路带你练到会。共 10 个不同难度的项目,从井字棋到网络编程,每个都有源码…
Project Box是一个为C语言初学者设计的项目合集,包含10个不同难度的项目,从井字棋到网络编程,每个项目都有源码、文档和构建配置,帮助学习者通过实践掌握C语言。
krahets/hello-algo
《Hello 算法》是一本开源的算法与数据结构教程,提供动画图解和多种编程语言实现,适合初学者自学。
From Zero to Claude Code in 19 Minutes (no code)
本文介绍了如何使用 Claude Code(无需编码知识)通过自然语言构建项目,包括计划模式、持久记忆、MCP 连接器等核心功能,并演示了打字游戏和看板应用的实际构建过程。
@QingQ77: 一个面向 AI Agent 的命理分析 Skill,用算法精确排盘(不靠 LLM 猜),支持八字独立、紫微独立、八字+紫微综合印证三种模式,一键生成水墨风 HTML 命盘海报。 https://github.com/dzcmemory-w…
一个开源命理分析 Skill,使用算法精确排盘(八字、紫微斗数),不依赖 LLM 猜测,支持三种分析模式,可一键生成水墨风 HTML 命盘海报,适用于 Claude Code、Codex、Cursor 等 AI Agent。
Simple Sprite Editor in J
本文介绍了如何在 J 语言中构建一个简单的精灵编辑器,涵盖窗口管理、网格绘制、键盘快捷键、鼠标绘图及调色板自定义等功能,展示交互式图形程序的核心技术。