PKUで自分の上下3位までの人が解いているものの中で、その中の多くの人に解かれている問題を抽出するスクリプト
わりと解けるものが無くなりつつあり、PKUで問題を解くたびに眺めていたあるサイトが最近動かない感じになってしまったせいでモチベーションが下がり気味。
仕方ないので、全然脈絡はないですがここ2〜3ヶ月使っている自作のrubyスクリプトを貼り付けてみようと思います。
以下のようなものです。
rubyはあまり書き慣れていない上に、ifにendをつけるのが(tabとかを考えると)野暮ったいと思ったせいで、妙に読みにくいところもあるかもしれません。
# -*- coding: cp932 -*- require 'net/http' Net::HTTP.version_1_2 # おまじない def get_rival_solved_list(name) ret=Hash.new(0) Net::HTTP.start('poj.org',80){|http| usol=Hash.new body=http.get('/userstatus?user_id='+name).body body.scan(/p\((....)\)/){|re| usol[re[0]]=true} body.scan(/(?:userstatus\?user_id=)(.*?)>/){|user| next if user[0]==name http.get('/userstatus?user_id='+user[0]).body.scan(/p\((....)\)/){|re| ret[re[0]]+=1 if !usol.key?(re[0]) } $stderr.puts user[0] puts user[0]+'<br>' puts ret.size.to_s+'<br>' } } return ret end user='atetubou' list=get_rival_solved_list(user).to_a.sort puts '<br><br>' def url(no) url ='http://poj.org/problem?id='+no puts '<a href='+url+'>'+url+'</a><br>' end [6,5,4,3].each{|i| puts i.to_s+" rivals solved<br>" list.each{|pa| url(pa[0]) if pa[1]==i } puts '<br>' }
これは簡単に言ってしまえば、solvedで自分の上下3位までの人が解いた問題のうち、6人に解かれている問題、5人に・・・、4人・・・、3・・・、で自分は解いていないものを抽出するというスクリプトになっています。
userを自分と同じIDにすれば自分と上下3位までの人の差分が取れます。
ただ、解いた問題が10問に見たないような人はあまり使っても意味ないような気がします。
出力が標準出力になっているので、スクリプトを保存したらuserを自分のIDに書き換えて
ruby pku.rb >pku.html
みたいな感じで、実行してみてください。
それでpku.htmlを開くと上下6人に解かれている問題、5人に・・・、4人・・・、3・・・、といった感じで問題のURLリストが得られます。
pkuからhtmlを7ページ取ってくることになるので、微妙に実行時間はかかりますが、30秒くらいで終わるはずなので、気長にまってやってください。
同じようなコードをpythonで書こうとしたのですが、pythonの正規表現だとrubyのようなコードをどのように書けばいいのか分からなかったので断念しました。
本当はphpのコードを最初に書いていて、どっかのサーバーで動かそうとおもったのですが、実行時間がかかる上に、外部のサーバーにアクセスするようなCGIを置いても大丈夫そうなサーバーというのが見つからなかったのでここで公開するという形になりました。
もしphpのほうのコードが見たい方がいたらコメントにでも書いてください。
(ただし、phpのほうはhtmlのパーサーライブラリを使用しております)