まだ解いてないPKUの問題を列挙するクソコード
$perl pku_tool.pl username password case pagerange
のように引数を4つ取る。
caseは 1 or 2 の数字で入力
1のとき、ACの降順
2のとき、pageごとの問題の総AC/各問題のACの値で昇順
pagerangeは 1-10 のように入力
上記だと、1〜10ページまでを計算して出力
デフォルトで上位50位まで出力させています
example:
$perl pku_tool.pl hoge pass 1 1-10
#!/usr/local/bin/perl -w use Socket; use strict; my $host = 'acm.pku.edu.cn'; my $port = getservbyname('http','tcp'); my $iaddr = inet_aton($host) or die "$host is none\n"; my $sock_addr = pack_sockaddr_in($port, $iaddr); my $username; my $password; my $sock; my $setcookie; my $case; my $pagerange; my ($range1,$range2); ($#ARGV+1 == 4) or die "error:\$perl ~.pl username password (case:1 or case:2) pagerange(e.g.: 1-2)\n"; $username = $ARGV[0]; $password = $ARGV[1]; $case = $ARGV[2]; ($case==1||$case==2) or die "error:case...\n"; $pagerange= $ARGV[3]; if($pagerange=~/(\d{1,2})-(\d{1,2})/){ ($1<=$2 && 1<=$1 && $2<=28) or die "error:pagerange...\n"; $range1 = $1; $range2 = $2; }else{ die "error:pagerange...\n"; } socket($sock, PF_INET, SOCK_STREAM, 0) or die "error:failed socket(head)\n"; connect($sock, $sock_addr) or die "error:failed connect(head)\n"; select($sock); $|=1; select(STDOUT); print $sock "HEAD /JudgeOnline/login HTTP/1.1\r\n"; print $sock "Host: $host\r\n"; print $sock "\r\n"; while(<$sock>){ if( /^Set-Cookie: ([^;]+).*$/ ){ $setcookie = $1; last; } } socket($sock, PF_INET, SOCK_STREAM, 0) or die "error:failed socket(post)\n"; connect($sock, $sock_addr) or die "error:failed connect(post)\n"; # after get cashe my $postdata ="user_id1=$username&password1=$password&B1=login&url=/JudgeOnline/"; my $size = length($postdata); my $url = "http://acm.pku.edu.cn/JudgeOnline/"; print $sock "POST /JudgeOnline/login HTTP/1.1\r\n"; print $sock "Host: $host\r\n"; print $sock "Connection: close\r\n"; print $sock "Content-Length: $size\r\n"; print $sock "Content-Type: application/x-www-form-urlencoded\r\n"; print $sock "Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"; print $sock "Cookie: $setcookie\r\n"; print $sock "\r\n"; print $sock "$postdata"; while(<$sock>){last;} sub get_socket{ my ($number,$sock,$host,$setcookie) = @_; my $url = "/JudgeOnline/problemlist?volume=$number"; print $sock "GET $url HTTP/1.1\r\n"; print $sock "Host: $host\r\n"; print $sock "Connection: close\r\n"; print $sock "Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"; print $sock "Cookie: $setcookie\r\n"; print $sock "\r\n"; } my @data = (); for(my $i=$range1; $i<=$range2; $i++){ my $sum = 0; my @t_data = (); socket($sock, PF_INET, SOCK_STREAM, 0) or die "error:failed socket(get)\n"; connect($sock, $sock_addr) or die "error:failed connect(get)\n"; &get_socket($i,$sock,$host,$setcookie); while(<$sock>){ if( /^<tr align=center>(<td>(.*)<\/td>){0,1}<td>(\d{4})<\/td><td align=left><a lang="en-US" href=problem\?id=\d{4}>(.+)<\/a><\/td><td>(.{1,4})\(<a href=problemstatus\?problem_id=\d{4}>(\d+)<\/a>\/<a href=status\?problem_id=\d{4}>(\d+)<\/a>\)<\/td><td>\d{4}-\d{1,2}-\d{1,2}<\/td><\/tr>$/ ){ defined($1) or die "error: login failed(may...)\n"; if( $2 eq "" or $2 eq "<img src=images/wrong.gif>" ){ #print "yes: _$1 _$2 _$3 $4 $5/$6 $7\n"; push(@t_data,{'num'=>$3,'name'=>$4,'cent'=>$5,'b'=>$6,'a'=>$7,'cost'=>0}) } $sum += $6; } } for my $i (0..$#t_data){ if( $t_data[$i]{'b'} == 0 ){ $t_data[$i]{'b'} = 1; } if ( $case==2 ){ $t_data[$i]{'cost'} = $sum/$t_data[$i]{'b'}; } elsif( $case==1 ){ $t_data[$i]{'cost'} = -$t_data[$i]{'b'}; } } push(@data,@t_data); } @data = sort{$a->{'cost'} <=> $b->{'cost'}} @data; for my $i (0..49){ printf("%3d: %4d, %4s, %d/%d, %s\n",$i+1,$data[$i]{'num'}, $data[$i]{'cent'},$data[$i]{'b'},$data[$i]{'a'},$data[$i]{'name'}); }