知道这个题目,是在任晓祎的博客里,据悉是加德纳改编的。题目如下:

某天, 老师召集了他最聪明的两个学生P和S, 递给每人一张纸条, 然后说, 有两个不小于2的整数x和y,满足x != y, 且x+y < 100. 给P的纸条上写有两个数的乘积p = x * y, 给S的纸条上写有两个数的和s = x+y, 请他们确定这两个数具体的值是多少. 于是P和S进行对话:

  1. P: 我无法确定这两个数是多少.
  2. S: 我知道你无法确定这两个数是多少.
  3. P: 既然这样, 那我知道这两个数是多少了.
  4. S: 既然这样, 那我也知道这两个数是多少了.
    请读者根据以上信息确定这两个数是多少.

当时看到这个题目后,和绍祝师兄一起做这道题,同时告诉海龙同学。和师兄讨论后,知道了题意,于是着手写代码,师兄用C++,我用C,结果两人都没写出来。很快海龙同学就得到了一个答案,是用手算得到的。我和师兄两人都汗颜了,有趣的是,这个答案就是唯一解。

回顾这道题,理清题意,大致如下:

1.P:我无法确定这两个数是多少。从这里可以得到,乘积p的分解不只一种,如12,可以分解成2 6, 3 4。

2.S:我知道你无法确定这两个数是多少。从这里可以得到,和s的分解中,x和y得到的乘积的分解不只一种,所有分解都满足条件1.如s为11时,可以分成2 + 9, 3 + 8, 4 + 7, 5 + 6,其中2和9的乘积为18,可以分解成2 9, 3 6; 对于3和8,4和7,5和6也是类似。

3.P: 既然这样, 那我知道这两个数是多少了。从这里可以得到乘积p的所有分解中,只有一个分解满足条件2。如18,18可以分解成2 9, 3 6,只有2和9的和11满足条件2,3和6的乘积不满足条件2.类似的还有24,28.

4.S: 既然这样, 那我也知道这两个数是多少了. 从这里可以得到s的所有分解中只有一组满足条件3.所以11不满足这个条件,因为11的分解中2 + 9, 3 + 8, 4 + 7,分别得到的18,24,28都满足条件3.

对于这种题目,还是用Python写比较方便。写成代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#coding:utf-8
from math import sqrt

def pone(p, u):
c = 0
for x in xrange(2, int(sqrt(p)) + 1):
if p % x == 0 and x + p / x < u:
c += 1
return c >= 2

def sone(s, u):
for x in xrange(2, s / 2):
y = s - x
if not pone(x * y, u):
return False
return True

def ptwo(p, u):
c = 0
for x in xrange(2, int(sqrt(p)) + 1):
if p % x == 0 and x + p / x < u:
y = p / x
if sone(x + y, u):
c += 1
return c == 1
def stwo(s, u):
c = 0
for x in xrange(2, s / 2):
y = s - x
if ptwo(x * y, u):
c += 1
return c == 1

if __name__ == "__main__":
u = 100
for x in xrange(2, u / 2):
for y in xrange(x + 1, u - x):
p = x * y
s = x + y
if pone(p, u) and sone(s, u) and ptwo(p, u) and stwo(s, u):
print "x:%d, y:%d, p:%d, s:%d " % (x, y, p, s)

联系作者

使用sed -i ‘s/text/test/‘ *.sh将当前目录下(不包括子目录),所有shell脚本的text替换为test, 其中-i参数是指示需要进行文件内替换,也就是改变文件的内容。

如果需要将子目录的也替换,则可以与find命令结合使用,使用find . -name “*.sh” | xargs sed -i ‘s/text/test/‘ 将当前目录下(包括子目录),所有shell脚本的text替换为test,

联系作者

在登陆后台的时候,要输入用户名和密码,此时希望打开页面,焦点就直接停留在用户名输入框,这样就可以省去移动鼠标的麻烦。

如以下一个登陆表单。

1
2
3
4
5
<form action="login.php" method="post" name="login">
用户名:<input name="username" type="text" value="" />
密码:<input name="password" type="password" />
<input type="submit" value="登陆" />
</form>

此时可以编写如下javascript:

1
2
3
4
5
6
7
window.onload = function() {
if (document.forms.login.username.value == "") {
document.forms.login.username.focus();
} else {
document.forms.login.password.focus();
}
}

联系作者

今天收到了金融学的结业证书,心中的一个结也解开了。两年前就选修这门课,可是由于时间因素,没有学完,心中一直耿耿于怀。今年抽空把这么课学完,并拿到了结业证书。

事实上,学完之后,很多知识又忘记了。可是上完这么课后,我知道了,股票是一个好东西。

金融学结业证书

联系作者

因为不会写MVC,所以只好使用模版,而在PHP中,一般使用Smarty.以下是自己在使用过程中,遇到的一些问题,以及需要注意的地方。
1.一般评论都是通过一个textarea输入,在显示的时候需要将换行幅\n替换成标签,当尝试使用replace : ‘\n’ : ‘
‘’时,一直不可行,后来才知道,原来有nl2br这个函数。

2.对于使用addslashes过滤的内容,则需要使用stripslashes将添加的\去掉。

3.对于left_delimiter和right_delimiter的选择,我的经验是{{和}}比较好,对于<{和}>最好不用,否则会遇到很多问题。使用判断语句如{{if}} {{elseif}} {{else}} {{/if}}时,千万不能在{{和关键字中留出空格,否则会出错。如写成{{ /if }} {{ else }}这些都会出错.

联系作者

经过三个月的时间,金融学公开课终于告一个段落了。两年之前就选修过这门课,可是当时由于时间问题,还是未能完成,一直心有不甘。现在工作之后,腾出周末的时间选修了这门课,所以想好好学完这门课。

这门课整体来说难度不大,只有到了统计部分才发现有点难度,这时也才知道以前学的数理统计还是有用的,可是我已经忘的差不多了。幸亏Gautam Kaul教导有方,对这部分总算有个了解。

我的感悟是,学习的过程最重要还是要做笔记和练习,否则太容易忘记了,即便是当时已经弄懂了,过了很久之后,还是会忘记当初的想法,就像现在,即使已经学完了,很多内容又忘的差不多了,真是可恶。可是有一点还是不能忘记的,那就是价值的创造是来自于伟大的想法,而金融运作并不创造价值。

下面是自己用Python写的一些函数,还是很实用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def pv(rate,nper,pmt,fv=0):
v = pmt * (( 1 + rate) ** nper - 1) / rate / ( (1 + rate) ** nper)
v += fv / ((1 + rate) ** nper)
return v
def pmt(rate,nper,pv,fv=0):
p = pv * ((1 + rate) ** nper ) * rate / ((1 + rate) ** nper - 1)
p += fv * rate / ((1 + rate) ** nper - 1)
return p
def fv(rate,nper,pmt,pv=0):
v = pmt * ((1 + rate) ** nper - 1) / rate
v += pv / ((1 + rate) ** nper)
return v
def paf(r,n,g):
return 1.0 / (r - g) * (1 - (1 + g) ** n / (1 + r) **n)

联系作者

因为项目需要用到分页功能,所以需要用到SetLimits函数,结果就出现了Error: searchd error: offset out of bounds (offset=9500, max_matches=1000)

于是找原因,发现配置文件中有max_matches这个选项,于是将它改为10000,可是依然出现Error: searchd error: offset out of bounds (offset=9500, max_matches=1000)错误,真是莫名其妙的错误,仔细看了SetLimits的函数说明以及SphinxClient.java,才知道使用SetLimits这个函数时,如果没有提供max_matches这个参数的值,则max_matches默认为1000,而9500超过了1000,所以溢出了。

现在终于明白原因,也就是说使用Sphinx一共可以在两个地方设置max_matches,一个是在searchd,也就是引擎端,提供给searchd的配置文件中进行设置;而在SphinxClient中,也就是客户端,如果在SetLimits函数中没有设置max_matches,则默认使用1000.这里有一点需要注意的是,客户端的max_matches一定要小于服务器端,否则会报错。而offset也一定要小于客户端的max_matches,这样offset才不会溢出。

联系作者

TCP建立连接时一般要发送三次包,也就是俗称的三次握手。首先客户端向服务器端发送一个建立连接请求,告诉服务器自己的序列号;服务器收到这个请求包后,进行确认,同时告诉客户端自己的序列号;之后客户端对这个包进行确认。如果一切正常,三次握手就已经完成。

在网络状况不好的时候,如果在发送的过程中任意一个包丢失会怎样呢?

首先来看看第一个包。这种情况显而易见,如果客户端建立连接的请求包丢失,那么服务器端根本不知道有这么一个请求,客户端只有重新发送这个包。

再来看看第二个包。这种情况也是显而易见,如果服务器的确认包丢失,那么客户端无法知道服务器是否收到这个请求,此时服务器端必须再次发送这个确认包。

最后来看看第三个包。这种情况就不是那么显而易见了。如果客户端的确认包丢失,一个明显的解决办法是客户端再次发送这个确认包,然而这是不可行的,因为即使再次发送,客户端依然不知道服务器端是否收到这个确认包。解决的办法是服务器端再次发送三次握手的第二个包。这样就可以说明服务器端没有收到客户端的确认包,所以它需要再次发送第二个包,当客户端再次收到这个包时,也就知道自己此前发送的确认包丢失了,于是再次发送确认包。

联系作者

有些时候,想让脚步运行在后台中,而且只存在一个这样的脚步,这时一种可行的方法是将脚步的运行的进程ID写在一个文件中,当再次运行这个脚步时,去读取这个文件,读出ID,如果这个ID有进程在运行,就退出。这时需要知道进程ID,而在shell中,它是一个特殊变量,也就是$$.当运行shell脚步时,$$就是输出进程ID。

而有些时候,在shell中会编写一些函数,并返回结果,这是需要一个变量保存函数运行结果。这个变量就是$?.

而又有些时候,在shell中想知道运行脚步的名字,这个变量就是$0.

还有许多很有用的特殊变量,只是我不知道还有哪些。google之后可以知道,只是很好奇的是,这些人是怎么知道这些变量的呢?

联系作者