2013年7月28日日曜日

[TopCoder]SRM 586 Div 2

SRM 586 Div 2


Easy TeamsSelection

問題:
http://community.topcoder.com/stat?c=problem_statement&pm=12696&rd=15698

回答:

https://github.com/yuki2006/topcoder/blob/master/src/TeamsSelection.java


Midium PiecewiseLinearFunctionDiv2

問題:
http://community.topcoder.com/stat?c=problem_statement&pm=12698&rd=15698

回答:

https://github.com/yuki2006/topcoder/blob/master/src/PiecewiseLinearFunctionDiv2.java


どちらも問題の理解はちょっと難しかったけど、なんとか解けてよかった。

2013年7月27日土曜日

倍精度と整数の対応

Wikipedia「倍精度」
http://ja.wikipedia.org/wiki/%E5%80%8D%E7%B2%BE%E5%BA%A6


double型で 整数の対応可能(longに変換可能)なのは2の 53乗まで、

ただし、2のべき乗だけなら 63乗まで可能。

2013年7月26日金曜日

[Android]ActionBarSherlockからSupport Library v18 のActionBarへの移行

先日、新しいNexus7とともにAndroid 4.3 が発表されましたが、新しいOSとともに発表されるのが、Android SDKのバージョンアップ!

個人的にはこっちのほうが楽しみだったりします。


さて、今回 Android SDK付属の Android Support Libraryがv18 になり
なんと(やっと?)Action Bar UI に対応しました。
http://developer.android.com/tools/support-library/index.html

設定方法はこちらの「Adding libraries with resources」をどうぞ
http://developer.android.com/tools/support-library/setup.html


さて、わたしは今まで ActionBarSherlock というありがたいライブラリを使っておりましたが、
http://actionbarsherlock.com/

公式で対応したということで移行処理をしてみました。



単純なものは、移行は簡単なのですが、もうちょっとGoogleさんには少し頑張ってもらいたかったところ。

相変わらず onCreate時にsetThemeを設定しないといけないみたいだし。

(自分が知ったかぎりもの)
各対応するもの表にしました。

(軽い動作確認は行いましたが、コードの正確性は保証いたしませんのでご注意ください。)


2013年7月22日月曜日

[TopCoder]初心者にオススメ問題

今回も、自分用のまとめです。
気づいた時に更新します。


始めてTopCoderをする方用にオススメの練習問題。
(わかりやすい問題)



もちろんすべてDiv2、上な問題ほどわかりやすいはず。





2013年7月20日土曜日

[TopCoder]SRM 585 Div 2

ブログを書くネタもあまりないので、プログラミングつながりということで 自分のまとめも兼ねてTopCoderのソースコードも公開して行きたいと思います。
 #本当は、ちゃんとしたアーカイブしたいけど

 ちなみに、ソースコードはGitHubのURLを貼るだけです。
 #リクエストがあれば何かするかも

 TopCoder自体は2年くらい前からやってましたが、スコアは低いです。頑張ります。

 というわけで早速。


 SRM 585 Div 2

 Easy

 LISNumberDivTwo
http://community.topcoder.com/stat?c=problem_statement&pm=12446

 ソース:
 https://raw.github.com/yuki2006/topcoder/master/src/LISNumberDivTwo.java 


 Medium 

TrafficCongestionDivTwo
http://community.topcoder.com/stat?c=problem_statement&pm=12697

 ソース:
https://github.com/yuki2006/topcoder/blob/master/src/TrafficCongestionDivTwo.java



特に、TrafficCongestionDivTwo の方は、興味深かったので説明書きます。

本番で書いたコードはなんとなく見つけた法則でのメモ化再起なんですが
SRM終了後に
他の人のエレガントなアルゴリズムを考えていた時に、見つけたアルゴリズムです。
(System Testには通りましたが、理論的に説明できません。。)

しかも、「倍数の証明 ジェネレータ」
http://tma.main.jp/baisuu/

というさらに興味深いサービス見つけたので、更にはかどりました。


高さh+1の完全二分木のノード数 は 2^h -1 です。

ここで問題でいう1つのパスを 葉のノード →その上のノード →右下の葉のノード
を順番にやっていくと最小のパス集合数になるのではと思いました。
(理論的に証明できません。。


ここで、 hが偶数のとき, ノード数は3の倍数になることの証明はこちら

2^(2n)  -1 = 4^n  -1 が 3の倍数であることの証明
http://tma.main.jp/baisuu/baisuu.php?eq=4%5En-1&num=3


また hが奇数の時、ノード数は3で割ったら1余る証明はこちら (少し変形してます

2^(2n+1)  -1 -1 が  3の倍数であることの証明
http://tma.main.jp/baisuu/baisuu.php?eq=2%5E%282*n%2B1%29-2+&num=3


つまり、
hが偶数の時は、先ほどの長さ3のパスの組み合わせで構成可能
hが奇数の時は、長さ3のパスの組み合わせで構成すると根のノードだけ残る(あまり1)

つまり、
  (2^h -1)/3 の切り上げの値が 最小のパス集合の数と等しくなるではないかと思いました。

2^h-1 % 3のあまりの最大値は1なので

切り上げを表現するためにテクニカルな方法を用いて+2にしました
つまりreturn文はなんと一行で表現出来ました。

return ((long) Math.pow(2, treeHeight + 1) - 1 + 2) / 3;

ツッコミお待ちしております。




2013年7月10日水曜日

if -else を教えてる時に・・。

早速ですが、このコードの間違いを探してください。
(答えは本文で)





とある機会で、初歩からJavaプログラミングを教える機会があって、
前でプロジェクターで映しながら、こうやったらこうできますよみたいなハンズオンで説明してたんです。


文の最後には「セミコロンが要りますよ」とか基本的なことから教えて、

四則演算や%も教えました。


次に
if文を教えようと、奇数偶数を判定するようなコードを書いて、前に写して、
受講者の方に「こんなコード書いてみてください」と言って書いてもらったのですが、


そこ、受講者の方から
「奇数の時も偶数ですと出るのですが・・・」と質問されました。


そこで受講者の方が書いたのは、最初に載せたコードです。


私はパッと見た時に、すぐに気づきませんでした。。










わかりやすいようにフォーマッタをかけたのは下のコードです。






else のあとのセミコロンがあるために、elseの中身が空文として扱われてしまうんですね。

そして そのあとの{}が空ブロックとして扱われてif-elseと関係なく実行されてしまうんですね。


今まで長くプログラミングをして来ましたが、
こういうコードが書けるのというが新しい発見でした。
(使いドコロは無さそうですが)

やっぱり、プログラミングを教えたりすると、たまにこういう発見をするのが嬉しいですね。


豆知識として是非。




2013年2月9日土曜日

[Java][Android]Arrays.asListについて

Javaには
Arrays.asList()という配列をリストに変換するメソッドがあります。

仕様上の問題で、配列ではなくリストで渡さないといけないというのが
たまーにあるので重要という程でもないですが、知っていると便利なメソッドです。



こういうコードを書いてみました。

これを実行すると、asList.remove(0)で例外が発生します。



実は、Arrays.asList()で取得したリストは不変(addもremoveもできない)という仕様があります。
(ドキュメントにもちゃんと書いてあります)

たまに忘れます...


ではこのArrays.asList()で取得したリストとは何なのでしょうか。



少し調査してみました。(Java6を対象にしています)


Eclipse でasListの部分をクリックして 宣言を開く (F3) をしてみます。
ArraysクラスのasList の宣言が見れます。


そうするとあれ??
ArrayListに引数のものを入れて返してるだけじゃないですか。

つまりasList()で取得したものはArrayListということになり、可変(addもremove)も出来るはず。


しかしここに落とし穴があり。

 
さらにこのArrayListのところで F3を押して ArrayListの宣言を見てみます。





(一部分のみ)


気づきにくいですが、これは Arraysクラスの中の内部クラスとして宣言されているものなのです。

我々がよく使うArrayListとは別物なのです。

ちなみにadd メソッドは ここでは宣言されてなくて extends のAbstractListを辿って
add(E element)を辿り

add(int index, E element) 
の宣言部分

を見るとこのようになっております。
中身が例外だけ・・・・。(゚д゚)!

とりあえずこの仕組みによって例外が投げられているのですね。



ちなみに、通常のArrayListを調べると 同じくextends AbstractList されていますが、

きちんとオーバーライドでaddの中身が実装されています。


ちなみに
Arraysの中のArrayList(T[] array)という宣言は 通常のArrayListのコンストラクタにはありません。


なので配列の要素を全部渡すときは これがエレガントな方法です。


(2013/11/30 追加  yozaさんthx)




今回主にJavaに関してのことでしたが Androidアプリでも同様です
(そもそもきっかけはこちら)

ListViewの表示でよく使う ArrayAdapterで なぜかremove()をするとなぜか失敗していたので調べた結果たどり着いたのが

ArrayAdapterのコンストラクタのこの部分。
Arrays.asList()が使われてます。


つまりこれで作成されたArrayAdapterの内部で使われるリストは不変になってしまいます。

JavaDocの説明に これで渡すと不変であると書いてないじゃないですか。。。orz  
(テストしてなかったこちらも悪いですけど)

まとめ

Arrays.asList で取得したリストは不変です。
宣言の中身を見ると、同名のArrayListが使われてます。(ややこしい)

不変の理由は、addやremoveの中身が無い実装のAbstractListのため

AndroidのArrayAdapterのコンストラクタで配列を渡すと不変リストになってしまうので注意です。重要