すげーどうでもいいけど、今この時間になって会社帰りに寄ったコンビニに傘を置き忘れてきたことを思い出した。どうせもうなくなってるだろうから取りにいくつもりはないけど、今年に入ってから何本目だよ傘なくすのって。
意外と広告打てば応募って来るものなんだなー。ま、あくまでも「応募」だけの話なんで、こっから面接にたどり着かない人も結構いるんだけどね。面接と筆記試験で落とされるのも一定数いて、それを差し引くと当初の応募者のうちどんだけ残るかというと、半分も残らないかもという感じだ。なのでまずは応募者を増やさないといけないってのはわかるんだ。でもなあ。
ちなみに今回採用強化に踏み切った上司も、まったく勉強しないでソフトウェアの会社を受けにくる奴らばかりというのには流石に不満とか疑問を持っていて、やっぱ内心どうにかしたいとは思っているらしい。いや、なんつーかそれは俺も同じなんだけど、でも結局は本人の意識次第でしかないんだよな。インターネットに接続してる PC があればいくらでもプログラミングについて調べられる以上、まったく何も知らずにやってくるのはつまりそういう奴だって事。
その一方で、俺の同期にまったくの未経験でやってきてからプログラミングにきちんと取り組んで、今では Lisp の勉強を始めてる奴もいるわけで、そういう何かしらの切っ掛けや刺激さえあれば伸びる部類の人へ門戸を閉ざすってのも俺としては賛同しかねる部分がある。ただ、そういうのはあくまでもレアキャラで、そのレアキャラのためにクソみたいなコーダーを量産する事が果たして正しいのかと言われると悩む(レアキャラ以外を切り捨てると会社の売上が落ちるか潰れるかするのでここでは除外)。規約や標準にゲロみたいな項目が大量に盛り込まれて、その一方でまともな開発ツールが導入されなくて、それで下がった生産性と増大した管理ワークに管理職の人らが忙殺される原因の一つが、かなりの数のゴミが現場に送り込まれるからだろうからな。
……そういや、週明けにやってくる奴らってまたもや未経験なんだよな。今渡こそ、入社までに何かしらのことはしてきて欲しいと思うよ。
何か流石にできの悪い研修生対策として、月水金は研修に専念してくれという指令が出た。ってちょっとまて、そうなると週二日しか今のプロジェクトに専念できんぞ。確かに今の状態じゃ微妙通り越してヤバいのはわかるし、ここでさらにバンバカ切っちゃったら士気への影響とか採用にかかったコストの回収とか、いろいろあるってのもわかるんだが。
で、その問題になってるレベルの奴がどういうコードを書いているかというとだな……まずは一般的に初学者がやりがちなミスから見せるか。
SomeClass sc = new SomeClass();
List<SomeClass> list = new ArrayList<SomeClass>();
while (/* 適当な条件文 */) {
sc.setFoo(...);
sc.setBar(...);
list.add(sc);
}
同じインスタンスを使いまわして残念という奴で、こういうのは何がわかってないのか見た瞬間に当たりが付くので教え易い部類に入る(いや、参照型の概念を教えるのは結構面倒くさいんだけどよ)。もっとも、このコードも自力でスクラッチから書けたわけではないのがアレなんだが。まあそれは不問にしておこう。
それにしても次のコードはねえだろうと思った。
private int someMethod(SomeClass a, AnotherClass b) {
a = new SomeClass();
b = new AnotherClass();
...
}
お前この一ヶ月半近くの間何やってきたんだよ。本気でこればっかりは意味がわからなかったのでよくよく話を聞いてみたら、他のメソッドが全部次のように冒頭でローカル変数を作っていて、それを深く考えずに真似したらしい。
private List<SomeClass> makeSomeClassList() {
SomeClass sc = new SomeClass();
List<SomeClass> list = new ArrayList<SomeClass>();
...
}
private List<AnotherClass> makeAnotherClassList() {
AnotherClass sc = new AnotherClass();
List<AnotherClass> list = new ArrayList<AnotherClass>();
...
}
……まあ、最初のうちは思わず閉口するようなヘマをするのは仕方がないので、これも不問にしたいといえばしたいんだが、そいつの問題点ってまさに「下手の考え休むに似たる」って感じで、要するに講師の俺がちょくちょく見に行ってやらないと一時間でも二時間でもコードとにらめっこしたまま固まって、上みたいなコードを書くのならまだしも何もできてない事があるんだよな。多分だけど、一日放っておいたらマジで一日固まってると思う(今のところ途中で俺が痺れを切らして話しかけてしまってる)。
そしてこれでも、話を聞きにいくと多少は進展するだけ前に採用拒否した奴よりもマシってのが、なんていうか終わってるところだよなー。まあ下を見たらキリがないのでそれはもう忘れておこう。
しかしこういう何度言ってもアドバイスを受けに来ないで固まりっぱなしの奴ってどうすりゃいいんだろうな。とりあえず俺は採用拒否以外にはノーアイディア。
sumim’s smalltalking-tos 経由で http://www.flownet.com/ron/papers/lisp-java/instructions.html なんてものを知ったので、とりあえず解いてみた。一応言っとくけど、言語は Python な。きちんと計ってないけど、かかった時間は以下のとおりだったと思う。
なので問題文を読む時間含めて 2 時間と 30 分ってところか。正直 Python 使ってこれというのは時間かかりすぎな気がしなくもないけど、まあそれが俺の実力なんだろうな。辞書の作り方とかそんなことより、 flatten を書き損じて頭を抱えてたのは内緒だ。
def str2tuple(s):
r = []
for c in s:
r.append(c.lower())
r.append(c.upper())
return tuple(r)
def word2num(word, mapping):
r = []
for c in (i for i in word if i.isalpha()):
for k in mapping:
if c in k:
r.append(str(mapping[k]))
return ''.join(r)
def words2dict(wlist, mapping):
r = []
for w in wlist:
r.append((word2num(w, mapping), w))
return tuple(r)
def encode(phone, dictionary):
def _encode():
found = False
if not phone: yield '', 0
else:
for s in (phone[:i] for i in range(len(phone), 0, -1)):
for k, v in ((a, b) for a, b in dictionary if s == a):
found = True
yield v, len(s)
if not found:
yield phone[0], 1
for e, l in _encode():
if l > 0 and l < len(phone):
for x in [[e] + [e2] for e2 in encode(phone[l:], dictionary)]:
yield x
else:
yield [e]
def flatten(arg, none=''):
def _(ls):
if not ls: yield none
for l in ls:
if isinstance(l, list):
for i in flatten(l):
yield i
else:
yield l
r = list(_(arg))
return r
def escape(s):
return s.replace('-', '').replace('/', '')
def validate(args):
orig, enc = args
esc = escape(orig)
if len(esc) < len(enc):
return False
is_num = False
for c in enc:
if c.isdigit():
if is_num:
return False
is_num = True
else:
is_num = False
return True
slist = 'E', 'JNQ', 'RWX','DSY', 'FT', 'AM', 'CIV', 'BKU', 'LOP', 'GHZ'
wlist = """an
blau
Bo"
Boot
bo"s
da
Fee
fern
Fest
fort
je
jemand
mir
Mix
Mixer
Name
neu
o"d
Ort
so
Tor
Torf
Wasser""".split()
phones = """112
5624-82
4824
0721/608-4067
10/783--5
1078-913-5
381482
04824""".split()
mapping = dict(map(lambda xi: (str2tuple(xi[1]), xi[0]), enumerate(slist)))
dictionary = words2dict(wlist, mapping)
for e in filter(validate,
reduce(lambda a, b: a + b,
map(lambda x:
[(x, flatten(v)) for v in encode(escape(x), dictionary)],
phones))):
print e[0] + ': ' + ' '.join(e[1])
割とコードの切り詰め競争的な意味合いもある気がしたので、若干詰めて書いた。文字列をハードコードしてる部分とかを抜いた論理行だけなら 70 弱といったところで、正直まだまだ詰められるけどまあ俺はそっち方面にはさほど興味は無いのでこれでいいや。ちなみに本題のファイルは使ってない。そっち使うとなるともうちょっとデータ構造もアルゴリズムも変える必要があると思うけど、面倒になった(元は会社での気分転換だしな)。
特にこのコードに付いては書くことがないのだけど、あえて書くなら再帰とジェネレータと内部関数だな。この手の処理になると、ほぼ手癖でこういうコードになっちまう。
夏休みなので今日はお休み。しかし三連休の間ずっと天気が悪いって、一体どれだけ引きが弱いんだ。
冷蔵庫に何も入ってないし家賃も払わないといけないしということで、雨が降ってるけど出かける事にする。
通勤時間の暇つぶし用ゲームにアクション RPG 系が欲しいなーと思って立ち寄った店で、「ソーマブリンガー」ってのを見つけたんで試しに買ってみた。別にそんなに期待してなかったんだけど、ちと立ち上げてやってみたらかなりの時間ぶっ続けでやってしまった。
「世界樹の迷宮」とか「ダンジョンエクスプローラー」にも言えることだけど、どうにも俺はいびつにキャラクターをカスタマイズできるゲームが好きらしい。現状、攻撃力をバカみたいに伸ばしてローキック一発で雑魚を屠って遊んでる。
あとこの手のゲームでありがちな「ストーリーをどこまで進めたか忘れる」という事故への対策として、シナリオのあらすじを読み返せるとかが付いてるのは好印象。俺は割とイベントシーンとか流しちゃうんで、「俺は一体どこに行けば良いんだ」という状況に割となりがちだからな。これでイベントシーンをうっかり飛ばしても大丈夫だ。
しかし公式ページが途中で投げっ放しになってることからも、実はあんまりプッシュされてるゲームじゃなかったのかねえ。

この怪文書はクリエイティブ・コモンズ・ライセンスの元でライセンスされています。引用した文章など Kuwata Chikara に著作権のないものについては、それらの著作権保持者に帰属します。