猿にいったい何解ると言うのか
はじめに
私は常々、猫にC言語はわからないのではないかと思っているのですが、 どうも最近猫だけでなく猿にもその傾向がみられるようなので、確かめました。
猿でもわかるもの
- サルでもわかるGit入門
- サルにもわかる正規表現入門
- サルでも分かるUMLメタモデル
- サルでもわかる 逆引きデザインパターン
- サルでもわかるHTML5超入門
- サルにもわかるRSA暗号
- 猿でもわかるクロージャ超入門
- サルでもわかるIOモナド
- サルでも分かるプログラミング言語の新潮流
考察
猿、すごいですね(適当)。
ところで、この「サルでもわかる」って表現の出所を気になって調べたところ、 はてなキーワード に
原型は「サルでも描けるまんが教室」(相原コージ・竹熊健太郎/小学館)であると思われる。
との記述を見つけました。 信憑性があやしいとは思いつつも、今度は「サルでも描けるまんが教室」について Wikipedia で調べてみたところ、
タイトルの「サルでもかける」は「猿の○○○」から来ている。
との、ちょっとショッキングな記述を見つけました(○は自主規制)。「猿がバンパーのところで」の奴です。
どうでもいいことを調べた果てに、下ネタにたどりつくという大変残念な結果に終わりましたが、 サルでもわかる系の記事を読んでもわからなかったときに、表現の出所がこれだと思えば多少気も晴れるんじゃないでしょうか。
将棋の棋譜中継のコメント欄を拡大する
はじめに
将棋の棋譜中継をよく見るんですが、たまにコメントが長くて スクロールさせないと下のほうのコメントを見れないときがあります。
前からちょっと面倒だなと思っていて、設定で何とかできないものかと いろいろやってみてたんですが、なかなかうまくいきませんでした。 が、最近 UserScript なるテクノロジーを知ったので、今回はそれを試してみました。
方法
棋譜中継は、柿木さんの「Kifu for Flash」の「将棋連盟版」というものを使用してるみたいで、 フリーで配布されてるのよりリッチになってるみたいです。 Flash のパラメータに「comment_line」というのがあって、例えば「10」などという値が 渡されてたりするんですが、これを UserScript を使って、無理やり「20」に変えてみます。
UserScript
KifuForFlash.user.js
// ==UserScript==
// @name Customize "Kifu for Flash"
// @namespace http://inaniwa3.hatenablog.com/
// @description This script can customize "Kifu for Flash" parameters.
// @include http://live.shogi.or.jp/*
// @version 1
// ==/UserScript==
(function(){
var ss = document.evaluate('/html/body/div/div/script',document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
if(ss.snapshotLength == 1){
eval(ss.snapshotItem(0).textContent.replace(/"comment_line", "\d+"/, '"comment_line", "20"'));
}
})();
使い方
上のコードを「(適当な名前).user.js」というファイル名で保存します。 あとはブラウザに応じて、以下のページを参考に設定してみてください。
動作を確認したのは、 Firefox の Greasemonkeyアドオンと、 Opera です。 Chrome の拡張機能では動きませんでした。原因はまだよくわかってませんが、 たぶんコードがまずいはずです。
結果
コメント欄が拡大できました。
最初の設定は面倒くさいですが、一度設定してしまえば あとは live.shogi.or.jp で中継される棋譜に関しては コメント欄の拡大が適用されるようになってるので、なかなか便利と思います。
というか、中継担当の方、 comment_line の値大きくしてください。
吉幾三の村に無いものにマッチする正規表現
はじめに
正規表現をうまく書けないので練習していたのですが、郵便番号にマッチさせたり、HTMLタグにマッチさせたりするのにも飽きてきたので、なにか飽きない練習法はないものかと考えました。
その結果、好きな曲の歌詞を使えばいいんじゃないかと思いつきました。歌詞は繰り返しもあるし、なんなら韻を踏んだりするので都合がよさそうな気がします。
今回はその一例、吉幾三の村に無いものにマッチする正規表現です。
SAMPLE INPUT
テレビも無エ ラジオも無エ
自動車もそれほど走って無エ
ピアノも無エ バーも無エ
巡査毎日ぐーるぐる
朝起きて牛連れで
二時間ちょっとの散歩道
電話も無エ 瓦斯も無エ
バスは一日一度来る
俺らこんな村いやだ 俺らこんな村いやだ
東京へ出るだ
東京へ出だなら 銭コア貯めで
東京で牛飼うだ
ギターも無エ ステレオ無エ
生まれてこのかた見だごとア無エ
喫茶も無エ 集いも無エ
まったぐ若者ア俺一人
婆さんと爺さんと数珠を握って空拝む
薬屋無エ 映画も無エ たまに来るのは紙芝居
俺らこんな村いやだ 俺らこんな村いやだ
東京へ出るだ
東京へ出だなら 銭コア貯めで
東京で馬車引くだ
ディスコも無エ のぞきも無エ
レーザー・ディスクは何者だ?
カラオケはあるけれど
かける機械を見だごとア無エ
新聞無エ 雑誌も無エ たまに来るのは回覧板
信号無エ ある訳無エ 俺らの村には電気が無エ
以下略
RESULT
$ ruby -e 'puts $<.read.scan(/(\S*?)も無エ/)' < tokyo.txt
テレビ
ラジオ
ピアノ
バー
電話
瓦斯
ギター
喫茶
集い
映画
ディスコ
のぞき
雑誌
考察
吉幾三の村に無いものがわかりました。ただ、よく見ればわかるとおり、「ステレオ」や「薬屋」「電気」などが抜けています。この正規表現では吉幾三の主張の一部が無視されてしまっており、課題が残りました。
まとめ
ちょっと頭を使うので、練習として自分にはちょうどよい感じでした。
他のお題として、「あなたが私にくれたものにマッチする正規表現」とか、「爆風スランプが無理だと言ってるものにマッチする正規表現」とかどうでしょうか。
地下トキワ荘の4コマ漫画を集める
概要
週刊誌 SPA! の投稿コーナーに掲載されている4コマ漫画が Web でも公開されています。 それらをまとめてダウンロードするという需要のないコードを書きました。
コード
#!/usr/bin/python
# coding: UTF-8
import re
import requests
for p in xrange(1, 19):
c1 = requests.get('http://nikkan-spa.jp/bakasai_tokiwa/page/' + str(p)).content
for node in set(re.findall(r'http://nikkan-spa.jp/bakasai_tokiwa/[0-9]+?"', c1)):
print node[:-1],
try:
c2 = requests.get(node[:-1]).content
r2 = re.search(r'<div class="sectionImgB"><img src="/wp-content/uploads/(.*?)" width="300"></div>\n(.*?)\n', c2)
r3 = re.search('.*/(.*)', '/' + r2.group(1))
with open('./out/' + r3.group(1), 'wb') as f:
raw = requests.get('http://nikkan-spa.jp/wp-content/uploads/' + r2.group(1)).content
f.write(raw)
print 'OK'
except:
print 'NG'
pass
カワイイをつくる
はじめに
「カワイイはつくれる」で思い出したんですが、昔「美人フィルタ」ってのがあったなーと。 で、作りたくなったので、作りました(フィルタを)。
アルゴリズムは こちら を参考にしました。
使ったもの
コード
function conv(fileIn, fileOut, coef)
imgIn = imread(fileIn);
imgIn = double(imgIn);
imgOut = imgIn;
imgOut(2:end-1, 2:end-1, :) \
= imgIn(2:end-1, 2:end-1, :) + coef * ( \
abs(imgIn(1:end-2, 2:end-1, :) - imgIn(3:end, 2:end-1, :)) \
+ abs(imgIn(2:end-1, 1:end-2, :) - imgIn(2:end-1, 3:end, :)) );
imwrite(uint8(imgOut), fileOut);
結果
> conv('shizuyo_before.bmp', 'shizuyo_after.bmp', -0.3)
→
まとめ
どうでしょうか。つくれたんじゃないでしょうか。
なお、係数を正にすると、逆のフィルタになります。
> conv('kawai_before.bmp', 'kawai_after.bmp', 0.4)
→
ザ・ファースト・スーパー・ゴルファー
はじめに
RubyKaigi 2013 の TRICK を見てたら、leonid さんが「The 1st super Ruby golfer」と紹介されてました。「ザ・ファースト・スーパー・ゴルファー」なんて名乗れたらかっこいいですよね。
「The 1st super Ruby golfer」のリンク先を見てみると Anarchy Golf の User ranking。というわけで、Anarchy Golf の User ranking でトップならザ・ファースト・スーパー・ゴルファーを名乗ってもよさそうなので、各言語のザ・ファースト・スーパー・ゴルファーを調べました。
コード
#!/usr/bin/python
# coding: UTF-8
from urllib import urlopen
import re
print '| Language | User | Score | Entries | Avg | # of 10000 |'
print '|----------|------|-------|---------|-----|------------|'
LangAll = re.findall(r'<dt>(.*?) \((.*?)\)</dt>', urlopen('http://golf.shinh.org/version.rb').read())
for Lang in LangAll:
try:
RankHtml = urlopen('http://golf.shinh.org/u.rb?' + Lang[1]).read()
TheFirst = re.search(r'<tr><td>1</td><td>(.*)</td><td>(.*)</td><td>(.*)</td><td>(.*)</td><td>(.*)</td></tr>', RankHtml).groups()
print '| ' + Lang[0] + ' | ' + ' | '.join(TheFirst) + ' |'
except:
pass
ザ・ファースト・スーパー・ゴルファー
Language | User | Score | Entries | Avg | # of 10000 |
---|---|---|---|---|---|
A+ | teebee | 558979 | 56 | 9981 | 55 |
Ada | D | 661916 | 67 | 9879 | 62 |
Arc | youz | 1283203 | 131 | 9795 | 109 |
Asymptote | teebee | 800000 | 80 | 10000 | 80 |
AWK | nn | 2500488 | 251 | 9962 | 236 |
Bash | eban | 1882445 | 205 | 9182 | 136 |
BASIC | pooq | 2743557 | 289 | 9493 | 183 |
bc | teebee | 819155 | 82 | 9989 | 80 |
Befunge | kaki | 766984 | 80 | 9587 | 62 |
Brainfuck | g33k | 490000 | 49 | 10000 | 49 |
Burlesque | clock | 1030000 | 103 | 10000 | 103 |
C | inaniwa | 2893640 | 306 | 9456 | 161 |
C# | teebee | 619055 | 62 | 9984 | 58 |
C++ | nn | 384529 | 39 | 9859 | 32 |
CLC-INTERCAL | @tttttanaka | 50000 | 5 | 10000 | 5 |
Clojure | murky-satyr | 939380 | 95 | 9888 | 80 |
COBOL | *yuko* | 1080000 | 108 | 10000 | 108 |
Common LISP | kozima | 3365842 | 340 | 9899 | 297 |
Curry | pooq | 229310 | 23 | 9970 | 22 |
Cyan | pooq | 403462 | 43 | 9382 | 26 |
D | 51b | 1844169 | 185 | 9968 | 174 |
D-compile-time | 51b | 255439 | 26 | 9824 | 23 |
dc | tails | 716177 | 72 | 9946 | 68 |
DOS | *yuko* | 280000 | 28 | 10000 | 28 |
Erlang | 51b | 1377880 | 138 | 9984 | 132 |
Euphoria | clock | 390000 | 39 | 10000 | 39 |
FerNANDo | primo | 126060 | 13 | 9696 | 11 |
fish | teebee | 438000 | 44 | 9954 | 43 |
FlogScript | milieu | 874258 | 88 | 9934 | 83 |
Forth | 51b | 955853 | 96 | 9956 | 91 |
Fortran | *yuko* | 2809454 | 281 | 9998 | 280 |
gas | breadbox | 60000 | 6 | 10000 | 6 |
gnuplot | @tttttanaka | 101250 | 11 | 9204 | 10 |
Go | uru | 575464 | 58 | 9921 | 51 |
GolfScript | tails | 1802642 | 182 | 9904 | 166 |
goruby | murky-satyr | 1725865 | 176 | 9806 | 142 |
Grass | irie | 64250 | 7 | 9178 | 6 |
Groovy | nn | 4309792 | 440 | 9794 | 327 |
Haskell | notogawa | 3666047 | 370 | 9908 | 323 |
Icon | clock | 1258190 | 126 | 9985 | 123 |
Io | pooq | 2792552 | 286 | 9764 | 226 |
J | pooq | 3537548 | 371 | 9535 | 275 |
Java | teebee | 1367159 | 137 | 9979 | 130 |
JavaScript | nn | 4400300 | 447 | 9844 | 359 |
JVM | teebee | 50000 | 5 | 10000 | 5 |
K | twobit | 1223332 | 124 | 9865 | 104 |
Kite | teebee | 529249 | 53 | 9985 | 49 |
Lazy-K | irori | 313335 | 35 | 8952 | 21 |
LilyPond | KirarinSnow | 390000 | 39 | 10000 | 39 |
LMNtal | pooq | 200000 | 20 | 10000 | 20 |
Logo | teebee | 1313322 | 132 | 9949 | 126 |
Lua | twobit | 1674140 | 169 | 9906 | 139 |
m4 | 51b | 432846 | 45 | 9618 | 42 |
Malbolge | test1 | 50000 | 5 | 10000 | 5 |
Maxima | pooq | 2834479 | 292 | 9707 | 235 |
Mind | pooq | 449342 | 45 | 9985 | 44 |
Minus | flagitious | 163724 | 17 | 9630 | 13 |
Nemerle | clock | 510000 | 51 | 10000 | 51 |
ObjC | teebee | 140000 | 14 | 10000 | 14 |
OCaml | m.ukai | 1952889 | 208 | 9388 | 134 |
Octave | inaniwa | 776944 | 78 | 9960 | 72 |
PARI/GP | clock | 898619 | 90 | 9984 | 86 |
Pascal | uru | 2310517 | 237 | 9749 | 182 |
Pefunge | kt3k | 46923 | 5 | 9384 | 4 |
Perl | teebee | 2902302 | 293 | 9905 | 250 |
Perl6 | murky-satyr | 423697 | 43 | 9853 | 39 |
PHP | clock | 1590435 | 163 | 9757 | 130 |
Postscript | yshl | 2586072 | 264 | 9795 | 206 |
Prolog | pooq | 1319575 | 133 | 9921 | 121 |
Python | hallvabo | 5038798 | 521 | 9671 | 328 |
Python3 | teebee | 70000 | 7 | 10000 | 7 |
QCL | pooq | 572082 | 60 | 9534 | 46 |
R | pooq | 2031577 | 212 | 9582 | 155 |
REBOL | clock | 959733 | 96 | 9997 | 95 |
REXX | clock | 903215 | 91 | 9925 | 83 |
Ruby | leonid | 4686062 | 475 | 9865 | 403 |
Scala | murky-satyr | 964080 | 98 | 9837 | 86 |
Scheme | kaki | 2547117 | 257 | 9910 | 228 |
sed | eban | 1295561 | 139 | 9320 | 95 |
Smalltalk | murky-satyr | 1265845 | 129 | 9812 | 104 |
SNOBOL | clock | 830000 | 83 | 10000 | 83 |
Tcl | clock | 930000 | 93 | 10000 | 93 |
Universal Lambda | hinoe | 290000 | 29 | 10000 | 29 |
Unlambda | irori | 623630 | 65 | 9594 | 57 |
VHDL | mskzzzz | 167508 | 17 | 9853 | 13 |
vi | nn | 2268696 | 239 | 9492 | 146 |
wake | clock | 868857 | 87 | 9986 | 86 |
Whirl | yowa | 89846 | 9 | 9982 | 8 |
Whitespace | flagitious | 189583 | 19 | 9978 | 18 |
x86 | shinh | 70281 | 8 | 8785 | 6 |
xgawk | teebee | 788324 | 79 | 9978 | 77 |
Xtal | pooq | 1631760 | 168 | 9712 | 123 |
z80 | *yuko* | 1854981 | 186 | 9973 | 181 |
Zsh | teebee | 479549 | 48 | 9990 | 47 |
まとめ
私は「The 1st super C golfer」と「The 1st super Octave golfer」を名乗ってもいいことになりました。 最近、CodeIQ というサイトでも「上級ショートコーダー」バッジをもらったので、いろいろ名乗り放題です。
まあ
This ranking is not fair (especially for new comers). Please don't consider this so seriously, the intention of this ranking is to show how eager you are golfing :)
なので、参考までに。
羽生さんが駒を一度も後退させずに勝った対局
はじめに
先日、第2回電王戦の第1局を見に、ニコファーレに行ってきました。
そのとき、聞き手の矢内さんが「羽生さんが駒を一度も後退させずに勝った対局ある」というお話をされていて、 会場は90へぇくらいの雰囲気になっていました。
ただ、具体的にどの対局という話はなく、矢内さんも「間違ってたらごめんね☆」という感じだったので、 実際に調べてみました。
使ったもの
方法
駒が後退したかどうかを判定するのにはCSA形式が都合がよさそうだったので、 Blunder.Converterを使用して、2ちゃんねる棋譜のKI2形式をCSA形式に変換しました。
その後、最近勉強中のPythonで棋譜を抽出するコードを書きました。
コード
#!/usr/bin/python
# coding: UTF-8
import os
CSA_DIR = './2chkifu.csa/'
for csaFile in os.listdir(CSA_DIR):
# ファイルの読み込み
csaStr = open(CSA_DIR + csaFile).read()
# 羽生さんの棋譜か
if 'N+羽生' in csaStr:
habuMove = 1 # 羽生さんが先手
elif 'N-羽生' in csaStr:
habuMove = -1 # 羽生さんが後手
else:
continue
# 羽生さんの勝ちか
csaLines = csaStr.split('\n')
if '%TORYO' not in csaLines:
continue
toryoIndex = csaLines.index('%TORYO')
preToryo = csaLines[toryoIndex - 1][0]
if (habuMove == 1 and preToryo == '-') or (habuMove == -1 and preToryo == '+'):
continue # 羽生さんの負け
# 駒が後退していないか
if '+' in csaLines:
startIndex = csaLines.index('+')
else:
continue
startIndex = startIndex + 1 + (1 - habuMove) / 2
backFlag = 0
for n in xrange(startIndex, toryoIndex, 2):
if csaLines[n][2] != '0' and int(csaLines[n][2]) * habuMove < int(csaLines[n][4])* habuMove:
backFlag = 1 # 駒が後退した
break
# 結果の表示
if backFlag == 0:
print csaFile
出力結果
00311.csa
00685.csa
01600.csa
06521.csa
07639.csa
35267.csa
45018.csa
結果を詳しく
- 第61期順位戦A級09回戦:青野照市九段 vs 羽生善治竜王:44手
- 第52期王将戦挑戦者決定リーグ2回戦:森下卓八段 vs 羽生善治竜王:56手
- 第42期王位戦七番勝負第1局:屋敷伸之七段 vs 羽生善治王位:76手
- 第16期棋王戦本戦3回戦:羽生善治竜王 vs 真部一男八段:59手
- 第10回若獅子戦2回戦第1局:羽生善治四段 vs 富岡英作五段:103手
- 第24回朝日オープン将棋選手権五番勝負第3局:羽生善治朝日 vs 藤井猛九段:63手
- 第33期棋王戦五番勝負第3局:羽生善治王座・王将 vs 佐藤康光棋王:71手
まとめ
見つかっても1局くらいなのかなと思っていたのですが、意外と多かったです。 結果を見てそりゃそうかと思ったのは、比較的短手数の対局が多かったことです。
追記 (2013-04-10)
駒落ち(CSA形式で手番が'-')の棋譜の処理が間違っていたので、その棋譜は無視するようにコードを修正しました。 結果は変わりません。