用 Go 语言实现刘谦 2024 春晚魔术,还原尼格买提汗流浃背的尴尬瞬间!

本文公众号地址:Go编程世界

龙年春晚如期而至,想必大家都看( )完( )了( )吧,今年春晚最搞笑节目,当属刘谦的魔术:《守岁共此时》,不过笑点不是节目本身,而是本场魔术的 托儿(主持人)尼格买提。

小尼:已经开始流汗了 😅。

本文将带大家一起用 Go 语言来还原下整个魔术的过程。

在开始写代码前,翻车画面必须置顶 🤣:

魔术:《守岁共此时》

这是一个公式魔术,即有着固定的套路,从数学角度来看是一个「约瑟夫问题」(严格证明可以在网上搜到,如果你感兴趣可以去看下)。

不过,咱们今天不讲枯燥的数学公式,固定套路是程序的强项,今天就用 Go 语言实现这个魔术的套路。

接下来,咱们直奔主题,回忆每一个步骤的同时,用程序将其实现。

步骤

一、 准备 4 张扑克牌,随意打乱,完成洗牌。

代码实现如下:

go 复制代码
// 我们使用 `int` 类型的切片 `pokers` 来存储扑克牌
var pokers []int = []int{2, 7, 6, 5}

// 1. 洗牌,随意打乱
rand.NewSource(time.Now().UnixNano())
rand.Shuffle(len(pokers), func(i, j int) {
	pokers[i], pokers[j] = pokers[j], pokers[i]
})
fmt.Printf("1. 洗牌后的牌:%v\n", pokers)

我们以截图中刘谦手里持有的 4 张扑克牌为例,用一个 int 类型的 slice 存储这些牌。

在 Go 中可以使用 rand.Shuffle 方法来打乱 slice 的顺序。

执行程序,得到洗牌后的结果如下:

bash 复制代码
[6 7 5 2]
二、 对折,然后撕开,接着叠在一起,相当于扑克牌变成了两份,double 了,4 张变 8 张。

这一步相当于 pokers 内容 * 2,代码实现如下:

go 复制代码
pokers = append(pokers, pokers...)
fmt.Printf("2. 对折后的牌:%v\n", pokers)

复制后的 pokers 如下:

bash 复制代码
[6 7 5 2 6 7 5 2]
三、 问问自己名字有几个字,就从最上面拿出对应个数的牌放到底部。

例如「刘谦」名字有 2 个字,即将 slice 前 2 个元素取出,并放到 slice 最后,代码实现如下:

go 复制代码
pokers = append(pokers[2:], pokers[:2]...)
fmt.Printf("3. 问问自己名字有几个字,就从最上面拿出对应个数的牌放到底部:%v\n", pokers)

得到新 pokers

bash 复制代码
[5 2 6 7 5 2 6 7]
四、 拿起最上面的 3 张牌,插入中间任意位置。

代码实现如下:

go 复制代码
pokers = append(pokers[3:7], pokers[0], pokers[1], pokers[2], pokers[7])
fmt.Printf("4. 拿起最上面的 3 张牌,插入中间任意位置: %v\n", pokers)

这里将 pokers 前 3 个元素取出,并插入最后一个元素之前,得到新 pokers

bash 复制代码
[7 5 2 6 5 2 6 7]
五、 拿出最上面的 1 张牌,藏于秘密的地方,比如屁股下。

代码实现如下:

go 复制代码
top := pokers[0]
pokers = pokers[1:]
fmt.Printf("5. 拿出最上面的 1 张牌: %d, %v\n", top, pokers)

这里使用 top 变量暂存最上面的 1 张牌:

bash 复制代码
7, [5 2 6 5 2 6 7]

此时得到 top 值为 7,pokers 还剩 7 个元素。

六、 如果你是南方人,从上面拿起 1 张牌;如果你是北方人,则从上面拿起 2 张牌;假如我们不确定自己是南方人还是北方人,那就干脆拿起 3 张牌,然后插入中间任意位置。

这一步其实同第四步操作一样,假设我们是北方人,代码实现如下:

go 复制代码
pokers = append(pokers[2:6], pokers[0], pokers[1], pokers[6])
fmt.Printf("6. 从上面拿出 2 张牌: %v\n", pokers)

得到新 pokers

bash 复制代码
[6 5 2 6 5 2 7]
七、 如果你是男生,从上面拿起 1 张牌;如果你是女生,则从上面拿起 2 张牌,撒到空中(扔掉)。

假设是男生,代码实现如下:

go 复制代码
pokers = pokers[1:]
fmt.Printf("7. 如果你是男生,从上面拿起 1 张牌;如果你是女生,则从上面拿起 2 张牌,撒到空中(扔掉):%v\n", pokers)

得到新 pokers

bash 复制代码
[5 2 6 5 2 7]
八、 魔法时刻,在遥远的魔术的历史上,流传了一个七字真言「见证奇迹的时刻」,可以带给我们幸福。现在,我们每念一个字,从上面拿一张放到最底部,即需要完成 7 次同样的操作。

我们可以用 for loop 来完成重复操作,代码实现如下:

go 复制代码
for range []string{"见", "证", "奇", "迹", "的", "时", "刻"} {
	pokers = append(pokers[1:], pokers[0])
}
fmt.Printf("8. 见证奇迹的时刻:%v\n", pokers)

得到新 pokers

bash 复制代码
[2 6 5 2 7 5]
九、 最后一个环节,叫「好运留下来,烦恼丢出去」,在念到「好运留下来」时,从上面拿起 1 张牌放入底部;在念到「烦恼丢出去」时,从上面拿起 1 张牌扔掉,女生需要完成 4 次同样的操作,男生需要完成 5 次同样的操作。

因为第七步中我们选择了男生,所以现在要完成 5 次同样的操作,同样适用 for loop 来完成,代码实现如下:

go 复制代码
for range []int{1, 2, 3, 4, 5} {
	// 好运留下来
	pokers = append(pokers[1:], pokers[0])
	// 烦恼丢出去
	pokers = pokers[1:]
}
fmt.Printf("9. 好运留下来,烦恼丢出去:%v\n", pokers)

最终得到的 pokers

bash 复制代码
[7]

切片 pokers 中仅存一个元素,即手中只剩一张牌。

见证奇迹

接下来就是见证奇迹的时刻,拿出藏于屁股下的牌和手里唯一剩下的一张牌对比,正是同一张牌:

打印 top 值和 pokers 中仅存的元素。

go 复制代码
fmt.Printf("见证奇迹:%d == %d", top, pokers[0])

结果毫无悬念:

bash 复制代码
见证奇迹:7 == 7

程序完整日志输出如下:

bash 复制代码
1. 洗牌后的牌:[6 7 5 2]
2. 对折后的牌:[6 7 5 2 6 7 5 2]
3. 问问自己名字有几个字,就从最上面拿出对应个数的牌放到底部:[5 2 6 7 5 2 6 7]
4. 拿起最上面的 3 张牌,插入中间任意位置: [7 5 2 6 5 2 6 7]
5. 拿出最上面的 1 张牌:7, [5 2 6 5 2 6 7]
6. 从上面拿出 2 张牌: [6 5 2 6 5 2 7]
7. 如果你是男生,从上面拿起 1 张牌;如果你是女生,则从上面拿起 2 张牌,撒到空中(扔掉):[5 2 6 5 2 7]
8. 见证奇迹的时刻:[2 6 5 2 7 5]
9. 好运留下来,烦恼丢出去:[7]
见证奇迹:7 == 7

还原「尼格买提」神操作

在此必须回顾一下尼格买提尴尬瞬间,反复尴尬 🤣:

仔细观看回放就能发现,其实小尼错在了第六步,小尼是北方人,所以应该从上面拿起 2 张牌,插入中间任意位置,但由于操作失误,错将拿起的第 2 张牌插入到最底部。

神操作在此:

即第六步代码原本应该如下:

go 复制代码
pokers = append(pokers[2:6], pokers[0], pokers[1], pokers[6])

到小尼这里变成了:

go 复制代码
pokers = append(pokers[2:6], pokers[0], pokers[6], pokers[1])

读者可以自行修改代码后尝试运行下,我就不展示结果了,怕尴尬 😅,哈哈哈。

彩蛋

不知道大家有没有注意到,在魔术表演结束时,观众席镜头左下角那个手里拿着 AJ 的姐姐!

放大特写:

AJ 姐姐满脸洋溢着尴尬的笑容 🤣。

总结

没有总结。

本文仅供大家消遣娱乐,顺便学点编程 😄。

本文完整代码示例我放在了 GitHub 上,欢迎点击查看。

联系我

相关推荐
森焱森2 小时前
水下航行器外形分类详解
c语言·单片机·算法·架构·无人机
Piper蛋窝3 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
QuantumStack4 小时前
【C++ 真题】P1104 生日
开发语言·c++·算法
写个博客4 小时前
暑假算法日记第一天
算法
绿皮的猪猪侠5 小时前
算法笔记上机训练实战指南刷题
笔记·算法·pta·上机·浙大
hie988945 小时前
MATLAB锂离子电池伪二维(P2D)模型实现
人工智能·算法·matlab
杰克尼5 小时前
BM5 合并k个已排序的链表
数据结构·算法·链表
六毛的毛6 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack6 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669136 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端