简单的问题复杂着解决

这段时间互联网上火热的流传着一个智力测试题。题目出现的形式有多种,但大多看起来是这个样子:

如果是学龄前儿童,5-10分钟能解决这个问题,普通程序员要1个小时,受过更高教育的人 … 🙂

8809=6

7111=0

2172=0

6666=4

1111=0

3213=0

7662=2

9313=1

0000=4

2222=0

3333=0

5555=0

8193=3

8096=5

7777=0

9999=4

7756=1

6855=3

9881=5

5531=0

2581=?

谜底揭示 …

.

.

.

.

.

.

.

.

.

.

答案跟每个数字里有多少个圈圈有关。在形状上,8有2个圈,所以记两次。0是一个大圈,记1次。所以2581=2。很有趣,不是吗?这是一种通过隐含的计算方式得出的另一种数值对应关系。

而困扰着我的却是如何能以一种不基于数字形状的方法来找到这种数值对应关系。我如何能编程让计算机来解决这个问题?我认真思考了一下,因为我喜欢自认为是一个计量经济学家,这道题看起来颇像一个可以通过一个OLS(ordinary least squares)表达式来解决的联立方程式。那么,如何能将这个问题和涉及到的数据转化成一个小小的OLS表达式呢?我需要将每行的数字队列转换成一个描述数字出现频率的表格。这样,对于8809=6来说,我需要重构出来的数据应该类似于这样:

1,0,0,0,0,0,0,0,2,1 = 6

在这种形式的公式中,10个数字分别代表着数字0-9在每串数据中出现的次数。我不知道如何得出这张频次表,于是,按照我的习惯,我把这个问题做了一个简洁的描述,张贴在StackOverflow.com上,如我愿的得到了一个极好的方案。一旦我建好了频次表,问题就变成了一个简单的关于10个独立变量的线性表达式。

我的整个运算脚本——如果你十分感兴趣的话——就是下面这些,你可以把它粘贴到R语言解释器里运行。

## read in the training data
## more lines than it should be because of the https requirement in Github
temporaryFile <- tempfile()
download.file("https://raw.github.com/gist/2061284/44a4dc9b304249e7ab3add86bc245b6be64d2cdd/problem.csv",destfile=temporaryFile, method="curl")

series <- read.csv(temporaryFile)

## munge the data to create a frequency table
freqTable <- as.data.frame( t(apply(series[,1:4], 1, function(X) table(c(X, 0:9))-1)) )

names(freqTable) <- c("zero","one","two","three","four","five","six","seven","eight","nine")

freqTable$dep <- series[,5]

## now a simple OLS regression with no intercept
myModel <- lm(dep ~ 0 + zero + one + two + three + four + five + six + seven + eight + nine, data=freqTable)

round(myModel$coefficients)

Created by Pretty R at inside-R.org

最终的输出结果如下:

> round(myModel$coefficients)
zero   one   two three  four  five   six seven eight  nine

  1     0     0     0    NA     0     1     0     2     1
你可以看到,0,6和9对应的值是1,而8对应的值是2。其它数字对应的都是0。而4得出的是NA,这是因为数字序列中没有出现4。
哈哈。我也跟学龄前儿童一样聪明了。而且我还用程序做了验证。
[英文原文:Solving easy problems the hard way ]
分享这篇文章:

18 Responses to 简单的问题复杂着解决

  1. cyler123 says:

    赞!
    这才是真正的科研精神啊!
    用数理化模型解释问题,才是真正的解决问题啊~

  2. zyz says:

    太强了.学习这种精神

  3. 流年 says:

    译文有个错误:

    “在这种形式的公式中,9个数字分别代表着数字1-9在每串数据中出现的次数”

    首先,是 10 个数字,其次,是 0-9 的出现次数

  4. 四不象 says:

    这里解题时已经忽略数字排列顺序对结果的影响了。

  5. 尧钦伟 says:

    小错误:”那么,如何能讲将这个问题和涉及到的数据转化成一个小小的OLS表达式呢?”
    如何能讲将……–>如何能将……

  6. pfeng says:

    计算机擅长的是“重复”

  7. vincent says:

    我真心不认为小朋友能搞出这个答案。但是不同的人看到问题的角度不同,这是事实

  8. haitao says:

    能从各种可能的角度、方面想到这个角度、方面,就不简单了
    可能小孩的知识面、理解方式决定了他的“各种可能的角度、方面”比较少,找到这个反而容易很多

  9. rosenyun says:

    应该是数里面的圆圈吧,是2

  10. Leone says:

    赞一个,很关注!

  11. yangyang.gnu@gmail.com says:

    还有一个规律,等号右边的数字,连续3个非零数字有【求和】关系(最小原则)。所有等号右边非零数字,按连续3个罗列如下:(6,4,2),(1,4,3),(5,4,1),(3,5,?),SO~~~, U GET IT~~

  12. jiafeimao says:

    赞钻研精神
    粗看了下, 对于8809=6来说,训练数据还是基于人工的知识(圆圈数这个特征)去处理成了 1,0,0,0,0,0,0,0,2,1 = 6
    如果是基于原始数据(8809, 6)这个pair 来训练,也能求解 就太牛了

  13. huyilin says:

    我是学零钱儿童。。。。

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据