tobiuo1990の日記

プログラマになるブログ

CODEVS2019の体験版でJava製の自前AIを動かす。

f:id:tobiuo1990:20190412011353p:plain

適当にやるとNormalAIにも圧倒的に負けます。

【追記 19/04/14】

この記事の内容的に重要なことなので最初に追記します。

以下のようなアドバイスをいただきました。

 で、実際に自分でも体験版クライアントで

java -jar xxx.jar

と「赤チームコマンド」欄に入力して実行してみるとできました!

(もちろん赤じゃなくて青チームのほうでも同様です。)

この「赤チームコマンド」というのは文字通り「コマンド」を入力する欄だったということだったんですね。(言われてみれば、それはそうという感じですけど。。恥)

なので、以下に記載している実行ファイルに変換する作業は不要となります。

もし、こちらを参考にしていた方がいらっしゃったら申し訳ございません。

これでLinux環境での問題もなくなりました。よかった。

(でも、これだと言語不問ということは、運営側があらゆる言語のランタイムを用意してくれるということなのかな?めちゃくちゃマイナーな言語とかでも大丈夫なのかな?Javaだけでもすべてのバージョン用意するのかな?)

【追記ここまで】

 

CODE VSの予選が来週月曜(4/15)から始まります。

codevs.jp


そのCODEVSにはじめて参戦してみようと思っています。

 

 まずは動くものを作ってみようとしたのですが、少し詰まったところがあったので自分の備忘録として(+おそらくいない同様な状態の人向けに)やったことを書いておきます。


環境OS:Windows10

言語:Java8


①体験版のクライアントアプリを入手する

公式サイトから入手できます。
ただ、このクライアントアプリが微妙らしく以下のツイートのようにjarファイルを直接実行するほうが安定しそうです。

 
②とりあえずルールに沿った入出力ができるようにする。

私の場合はJava8で実装しています。ほんとに入力を受け取って、ランダムに出力するだけの中身のないAIです。(これではAIと呼ばない気もする)

 

③クライアントで自分で作ったAIを実行する。

はい、ここで詰まりました。

疑問1:クライアントにどうやって自分のAIを指定するの?

クライアントにはAIを指定する場所が「赤チームコマンド」「青チームコマンド」とあるのですが、自分のファイルを指定するための「参照」ボタンみたいなのがない!となって焦りました。公式サイトをよくよく見ていると、参加方法ページの"03 CODING"のところの画像にローカルのファイルを指定している様子がありました。

コマンド欄にファイルの絶対パスを指定すればよいだけです。(気づいてみればそりゃそうだという感じではありますが。)


疑問2:作ったAIってどの形式で動作させるの?

最初は競プロ(AtCoder)のイメージで、ソースコードのファイルを一つだけ提出するもんだと勝手に思ってました。ただサイトには『※使用言語の制限はありません。』と記載があります。最初これを読んだときは「すべての言語の実行環境をそろえているなんてすごいな!」と感心したのですが、冷静になってみればそんなことありえません。でまたさっきの画像を見てみると.exeを指定しているのがわかります。なので、実行ファイルの形にしてあげれば良さそうです。今までJavaを.exeにしたことなかったので少し調べてみると以下の手順でできました。

1.AIを実装したJavaソースコードからjarを作成する。

2.exewrapでjarをexeに変換(ラップ)する

 

これで○○.exeを作成して、「赤チームコマンド」欄にそのexeのファイルを指定して、実行を押すとうまくいきました。


※jarを作成する際に、自分はeclipseのエクスポートで作成したのですが、「生成されるJARに必須ライブラリーをパッケージ」を選択すると以下のようなエラーメッセージが出てうまくいきませんでした。

Missing attributes for JarRsrcLoader in Manifest (Rsrc-Main-Class, Rsrc-Class-Path)java.lang.Error: factory already defined at java.net.URL.setURLStreamHandlerFactory(URL.java:1112) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:45)

「生成されるJARに必須ライブラリーを抽出」を選択するとうまくいきました。パッケージするかどうかで少し構成が変わったり、最初に実行されるクラスが変わったりするのが原因です。

(参考)

[Java]Eclipseで実行可能JARファイルでエクスポートした時のディレクトリ構成の違い - daybreaksnow's diary

最初に実行するクラスはMANIFEST.MFを無理やり書き換えればどうにかなりそうなので、ここら辺はもう少し試してみます。(パッケージできるようになれば、ライブラリ使用して実装できるので良さそう。)

※あと、最終的にexeの形にすることで体験版クライアントで動かせるようになりましたが、Windowsでしか動かないらしいのでLinuxで動かせるようにしないといけません。(大問題)

本当に還元は割引ほどお得ではないのか?

割引とポイント還元のどちらがお得か。
ずっと前は特に何も考えず「還元も割引も一緒」だと思ってましたが、
テレビかなんかで、実は還元は割引ほどお得ではないという話をきいて「割引の方がお得」と思うようになりました。
ただ、どっちも一緒じゃない?と最近また思うようになったのでそう思う理由を書いていきます。

 

f:id:tobiuo1990:20190405234759j:plain

まず、よく聞く「割引の方がお得」理論について説明しておきます。

例えば定価¥1000のものを買うとき
・50%割引の場合、¥500出して¥1000分を購入できる、50%のお得をしたことになる。
・50%還元の場合、¥1000で購入し500pもらうのでその500pで¥500分の買い物ができる。あわせて¥1000出して¥1500分を購入できたので33%のお得をしたことになる。
よって割引のほうがお得という話です。

しかし、この理論に対しては何か腑に落ちないところがありました。それについてぼんやり考えてみていたら
割引で¥500出して¥1000分を購入したあと、定価¥500の商品を購入した場合も¥1000出して¥1500分購入したことになるのではないか
ということに気が付きました。
「割引の方がお得」理論のズルいところは、還元の場合にだけ次回の購入分を計算に入れているため、お得が希釈されているということです。(次回購入分は定価なのでお得0%)
しかし、還元の方は次回購入時にポイントを使用することで初めてお得を享受することができるので、次回購入分を考慮しないと計算できないのです。
還元の場合は次回購入分を考慮せざるを得ないので、条件をそろえるために割引の方も一緒に次回購入分を含めて計算してあげる必要があります。
そうすると、割引も還元もお得具合は一緒ということになります。
割引は即時でお得、還元は時間差でお得*1

また、考えられる割引と還元の相違点としては、
割引は現金でお得を得られるけど、還元は(基本的には)ポイントで得る、という点です。
少し言い換えると、
割引で得たお得(=現金)はどこでも使えるけど、還元で得たお得(=ポイント)はその店でしか使えない、
ということです。
つまり、割引の場合は確実にお得だけど、還元の場合は次回以降そのお店で購入する予定がないのならお得にならない可能性があるということです。
ただ、継続的に利用するお店なら特に問題はない(=割引同等のお得を得られる)とも言えます。
割引はどこでもお得、還元はそこだけお得

これまでの話を踏まえての結論としては、
継続的に利用する店舗においては、還元も割引同等にお得。
そうでない場合は割引のほうがお得になりえる。
ということです。

私はよくAmazonで買い物をするのですが、特にKindle本を頻繁に購入します。
Kindle本はよく還元セールをやっているのですが、今までは「割引の方がお得」理論を信じていたので「50%還元って言っても、しょせん3割引き程度だからな」と思って還元セールには手を出さず、割引セールを待っていました。
けど毎回還元セールが行われているのを横目で見ていてモヤモヤがつもり、「割引の方がお得」理論を覆したかった、というのが今回のことについて考えた経緯になります。
これで心置きなく還元セールの時もKindle本を買えるようになりました!

*1:現在価値を考えると時間を要する還元のほうが不利ですが、ここで議論している金額は数百円から高々千円くらいであることを考えると時間差による不利益はほとんど無視できると思います。

初めてのブログ

はじめまして。

30を手前にして初めてブログを書いてみます。

というのも今日は4月1日で、新しいことを始めるのにうってつけの日だというのもあります。が、それ以上に今日から私は有給消化で60連休に突入したからです。その経緯などを整理して記録しておく意味で記しておきます。

f:id:tobiuo1990:20190401121410j:plain

桜ってこの時期以外に咲く花だったらここまで人気だったのかな?でも綺麗だしな。
退職しました

厳密には5月31日付けで退職することとなっていて、それまでためにため込んだ有給をありがたいことにすべて使い切る予定です。

新卒で入社した今の会社には丸5年お世話になりました。業態としてはSIerです。半年間の新入社員研修のあと、金融系の部に配属となり、決済システムをやってるお客さまを担当するチームの一員となりました。結局そのチームで最後まで4年半勤めました。配属後すぐに客先常駐で仕事をしてきたため、チーム外の同じ部の人の顔すら知らない状態で、愛社精神というものはほとんど育まれませんでした。むしろお客さまの会社の社員のような気持ちで、その会社のサービスをよくするにはどうすればよいかばかりを考えて働いていました。

仕事としてはいわゆるシステムエンジニアという職種で、お客さまから要望を受けて一緒に要件を固めていき、パートナーさんに開発タスクをお願いする、というのが大まかな仕事でした。

なぜ退職するのか

最大の理由は、「システムエンジニアではなくプログラマになりたい」と思うようになったからです。

 もともと文系卒の私ですが、これからはITの時代だしプログラムとか書くの楽しそうだし自分に向いていそう、と思い開発者を目指して就活し今の会社に入社しました。SIerでSEとして働けば色々な現場でいろんなものを作る経験ができ、しっかりと開発力を身に着けることができるのではないかと考えていました。

しかし、先ほども書いたように私がシステムエンジニアとしてやっていた仕事は「要件を詰めて開発を依頼して管理する」というようなことでした。このような状況でもスキルを身に着けられる人は身に着けられるんだと思いますが、私は『いつかできるようになるだろう』と特に何も考えずに過ごしてきてしまいました。そのため、ろくに開発経験も積まず、スキルを身に着けぬままに年次だけが上がっていき、SEとしてもっと多くのパートナーさんを抱えてプロジェクト推進できることを求められるようになってきました。つまり自分で開発する力よりも、パートナーさんに開発してもらう力(いわゆるマネジメント力)を必要とされるようになってきていました。(マネジメント力もあったほうが良いと思いますが、自分で開発する力が土台にしっかりあってこそだと考えています。)そのため『今の会社にいればいるほどもっと開発から離れていってしまって結局しっかりみっちり開発をする経験をできずに年だけ取ってしまう』と考えるようになりました。そんなことを考えながら仕事をしていると益々『自分でコーディングできる仕事に就きたい。コーディングするだけでなくよりよいシステム開発について突き詰めてみたい。』という気持ちが強くなり、今回の退職を決意しました。

次の仕事

次はフリーランスとしてプログラマをやっていこうと考えています。フリーランスと言っても最初はエージェントを仲介する形でやっていきたいと思っています。2,3年ほどフリーランスをして色々な職場で色々なサービスやシステムを開発する経験したら、次は事業会社で自社サービスを開発するエンジニアになりたいと思っています。

結構危うい選択だとは思いますが、これまで波風立たない人生を歩んできたので、30手前のチャレンジだと思って、自分の目指す姿にできるだけ近づいていこうと思っています。

今日からの60連休は精進のための60連休としたいと思います!

 

さいごに

最近はやりの退職ブログのなりそこないみたいになってしまいました。

まだブログの書き方とか設定の仕方とか慣れていないのでこれからちょっとずつよくしていくつもりです。

内容は、競プロ関連とか技術系のものを基本にしようと思っています。今回のような日記系は時々書くかもしれません。

よろしくお願いいたします。