<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>寝る前にラーメン &#187; Java</title>
	<atom:link href="http://thleave.com/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>http://thleave.com</link>
	<description>学生エンジニアのコードに関する忘備録</description>
	<lastBuildDate>Mon, 30 Aug 2010 15:41:01 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Google Code Jam 2010 Round1B</title>
		<link>http://thleave.com/contests/271</link>
		<comments>http://thleave.com/contests/271#comments</comments>
		<pubDate>Tue, 25 May 2010 06:36:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[プログラミングコンテスト]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[CodeJam]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=271</guid>
		<description><![CDATA[1Aは寝坊しました！
最近実務ばかりで、PHPしか書いてないから最初戸惑ったが、、、Javaバンザイ。
Google Code Jam 2010 is in Dublin!
http://code.google.com/ [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>1Aは寝坊しました！<br />
最近実務ばかりで、PHPしか書いてないから最初戸惑ったが、、、Javaバンザイ。</p>
<p><strong>Google Code Jam 2010 is in Dublin!</strong><br />
<a href="http://code.google.com/codejam">http://code.google.com/codejam</a></p>
<p><span id="more-271"></span></p>
<h3>File Fix-it</h3>
<p>Unixのディレクトリー構造。知ってることが問題だと楽。<br />
mkdirの-pオブションをつけずにディレクトリーを作っていく場合の手数を出す。<br />
Largeでもmax(N)=max(M)=100なので、JavaならばHashSetですぐ。</p>
<h3>Picking Up Chicks</h3>
<p>最初問題の意味がさっぱり分からなかった。<br />
チキンをどうするんだ！チキンを！</p>
<p>相当悩む。テストケース見て意味を探る。<br />
Kの意味の理解に苦しんだ。<br />
最低限スワップする数？？や、この数だけチキンが来ればいいんだ！（ここでアハ体験）<br />
（ここで30分以上かかった）</p>
<p>問題の解釈。</p>
<ul>
<li>（スワップしなければ）並び順通りにゴールしていく！入力が優しい。</li>
<li>順に見ていくうちに時間過ぎたら、それ以降の奴らはスワップしない限り間に合わない</li>
<li>（それでもKに満たないならば、）後ろにいる時間内にゴールできるやつを前に出す。<br />
抜いた分だけがコスト</li>
<li>後ろまでみてKに満たないならばそれはミッションインポッシブル！</li>
</ul>
<p>ここからは書くだけ。<br />
スワップを何で実装しようか迷ったけど、せっかくJavaなんだからLinkedList使うことにした。<br />
[java]<br />
LinkedList<Double> time = new LinkedList<Double>();<br />
// 先頭に追加<br />
time.addFirst(t);<br />
// jに追加<br />
time.add(j, target);<br />
// jを削除<br />
time.remove(j);<br />
[/java]<br />
なんてらくちんな。</p>
<h3>Your Rank is Pure</h3>
<p>やー、全く問題の意味がわからなかった。<br />
なにこれ？<br />
サンプルも２つしか載ってないし。<br />
まだ１時間以上残ってたけど全く解ける気がしなかった。</p>
<p>30分切ったくらいで諦める。2問解いて56pだしいけるんじゃない？って。<br />
したら、みんなsmallはどんどん解いていく。。。どこをどう解釈したら？？</p>
<p>それでも解けないでモヤモヤしてたら終了！その時点で1070位前後。あー。<br />
largeでどれだけ落ちるかと期待したけれど、結果1010位！あと9人！！あと1分ちょい早ければ！！！</p>
<p>これはすげーへこんだ。。<br />
なので、次の日あるのにチャンピオンズリーグを見てしまいましたとさ！<br />
（この終了時間は絶対CL決勝を意識したんだろう！と思ってしまう笑）</p>
<p>1Cは出られなかったので、これで今年のGCJは終わり。<br />
来年また頑張ります。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/contests/271/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>漸近的計算量と計算時間の相関</title>
		<link>http://thleave.com/coding/256</link>
		<comments>http://thleave.com/coding/256#comments</comments>
		<pubDate>Tue, 11 May 2010 15:06:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=256</guid>
		<description><![CDATA[GoogleCodeJamのQualificationに参加してみて、
どのくらいまでのオーダーの計算量ならコンテスト中に処理できるのか
気になったので簡単なプログラムを作って計測してみました。

テストに使ったのはこん [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>GoogleCodeJamのQualificationに参加してみて、<br />
どのくらいまでのオーダーの計算量ならコンテスト中に処理できるのか<br />
気になったので簡単なプログラムを作って計測してみました。</p>
<p><span id="more-256"></span></p>
<p>テストに使ったのはこんなコード。<br />
ぐちゃぐちゃだけど気にしないで！<br />
[java]<br />
	public static void main(String[] args) {<br />
		for (int order = 1; order <= 15; order++) {<br />
			long start = System.currentTimeMillis();<br />
			long temp = 0;<br />
			long end = (long) Math.pow(10, order);<br />
			for (long i = 0; i < end; i++) {<br />
				if (i % 2 == 0) {<br />
					temp -= i;<br />
				} else {<br />
					temp += i;<br />
				}<br />
			}</p>
<p>			long diff = System.currentTimeMillis() - start;<br />
			System.out.printf("O(10^%d) %d:%02d.%04d\n", order, diff / 1000 / 60, diff / 1000 % 60, diff % 1000);<br />
		}</p>
<p>	}<br />
[/java]</p>
<p>以下が出力結果ですー！</p>
<p>[text]<br />
O(10^1) 0:00.0000<br />
O(10^2) 0:00.0000<br />
O(10^3) 0:00.0000<br />
O(10^4) 0:00.0000<br />
O(10^5) 0:00.0000<br />
O(10^6) 0:00.0026<br />
O(10^7) 0:00.0438<br />
O(10^8) 0:04.0543<br />
O(10^9) 0:46.0106<br />
O(10^10) 7:43.0682<br />
[/text]</p>
<ul>
<li>O(10^7)までは計算量と時間に一応の相関関係はみえる。一応の。</li>
<li>O(10^8)までがコンテストなら許容範囲かな？</li>
<li>O(10^8)からは計算量と時間にはっきりと比例関係がみえる。</li>
<li>O(10^5)まではミリ秒単位でもゼロ！改めてコンピュータの計算力って凄いね。</li>
</ul>
<p>コンパイラのバージョンはjdk1.6でした。<br />
もちろん計測するコンピュータによって結果が変わってくると思うので参考程度に使ってください。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/coding/256/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GoogleCodeJam2010 Qualification に参加しました。</title>
		<link>http://thleave.com/contests/253</link>
		<comments>http://thleave.com/contests/253#comments</comments>
		<pubDate>Sun, 09 May 2010 09:28:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[プログラミングコンテスト]]></category>
		<category><![CDATA[CodeJam]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=253</guid>
		<description><![CDATA[先日開催されたGCJ2010のオンライン予選に参加しました。
ここんところ就活漬けで、コンテスト系のコードにはあまり触れられてなかったんですが、
自分にしてはまずまずの出来だったと思います。

結果から先に言うと、
(s [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>先日開催されたGCJ2010のオンライン予選に参加しました。<br />
ここんところ就活漬けで、コンテスト系のコードにはあまり触れられてなかったんですが、<br />
自分にしてはまずまずの出来だったと思います。</p>
<p><span id="more-253"></span></p>
<p>結果から先に言うと、<br />
(small,large)<br />
A (o,o) +33p<br />
B (x,x)<br />
C (o,x) +10p<br />
43p<br />
で、5809位でした。</p>
<h3>A, Snapper Chain</h3>
<p>問題文を解読するのに時間がかかった。<br />
解読し終わった後に最終的に式に落とし込めそうな気がしたので、<br />
ちょっとずつ共通項をあぶり出していった。</p>
<p>まず、Nに対する手数は固定で、max(N)=30だったので、先に計算して辞書でOK<br />
加えて、電気が付いている状態というのは、コストとほぼ同義。<br />
一度点いたあとはスナッパーが全部OFFになるので、その後は１を挟んで繰り返し。</p>
<p>[java]<br />
	public SnapperChain(Scanner sc, PrintStream ps){<br />
		int[] dic = new int[31];<br />
		dic[1] = 1;<br />
		dic[2] = 3;<br />
		for (int i = 3; i <= 30; i++) {<br />
			dic[i] = (dic[i - 1] - dic[i - 2]) * 2 + dic[i - 1];<br />
		}</p>
<p>		int T = sc.nextInt();<br />
		for (int i = 1; i <= T; i++) {<br />
			int N = sc.nextInt();<br />
			int K = sc.nextInt();<br />
			int cost = dic[N];</p>
<p>			while(true) {<br />
				K -= cost;<br />
				if (K <= 0) break;<br />
				K--;<br />
			}</p>
<p>			if (K == 0) {<br />
				ps.println("Case #"+i+": "+"ON");<br />
			} else {<br />
				ps.println("Case #"+i+": "+"OFF");<br />
			}<br />
		}</p>
<p>		ps.close();<br />
	}<br />
[/java]</p>
<h3>B, Fair Warning</h3>
<p>集中力がきれていて、もうさっぱりわからなかった。<br />
ひとまず、BigInteger使ってひたすら枝刈りした方針は合っているんだろうか？<br />
smallすら通らなかった。</p>
<p>解法は後で読みます。</p>
<p>http://code.google.com/codejam/contest/dashboard?c=433101#s=a&#038;a=1</p>
<h3>C, Theme Park</h3>
<p>smallは問題文の通りコードに起こすだけなので、small正答率も一番高かった模様。<br />
けど、largeはそう簡単には通らないよね。<br />
つい面倒くさくなってすぐlargeやったら通りませんでした。反省してます。</p>
<p>これも後で解法読んで書き直します。</p>
<p>http://code.google.com/codejam/contest/dashboard?c=433101#s=a&#038;a=2</p>
<p>[java]<br />
	public ThemePark(Scanner sc, PrintStream ps) {<br />
		int T = sc.nextInt();<br />
		for (int i = 0; i < T; i++) {<br />
			int R = sc.nextInt();<br />
			int K = sc.nextInt();<br />
			int N = sc.nextInt();</p>
<p>			int[] group = new int[N];<br />
			for (int j = 0; j < N; j++) {<br />
				group[j] = sc.nextInt();<br />
			}</p>
<p>			long res = 0;<br />
			int index = 0;<br />
			int startIndex = 0;<br />
			for (int j = 0; j < R; j++) {<br />
				startIndex = index;<br />
				int k = K;<br />
				while (true) {<br />
					if (k >= group[index]) k -= group[index++];<br />
					else break;<br />
					if (index == N) index = 0;<br />
					if (startIndex == index) break;<br />
				}<br />
				res += K &#8211; k;<br />
			}</p>
<p>			ps.println(&#8220;Case #&#8221;+(i+1)+&#8221;: &#8220;+res);<br />
			System.out.println(&#8220;Case #&#8221;+(i+1)+&#8221;: &#8220;+res);<br />
		}<br />
		ps.close();<br />
	}<br />
[/java]</p>
<h3>Result</h3>
<p>予選は通過できたのは良いこと。<br />
だけど、6000位近いポジションじゃぁ次で落ちるなあ。</p>
<p>もっと頭柔らかくして、しっかり準備して次にのぞもうと思います。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/contests/253/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SRM463 div2</title>
		<link>http://thleave.com/topcoder/234</link>
		<comments>http://thleave.com/topcoder/234#comments</comments>
		<pubDate>Tue, 02 Mar 2010 14:24:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[TopCoder]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=234</guid>
		<description><![CDATA[今日も疲労困憊で参戦。
そして、初の自宅以外での環境。

Easy BunnyPuzzle
ウサギパズル。ウサギかわいいよね。
ちょっとエンジンかかるの遅くて時間かかった。
179.60
Midium RabbitNum [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>今日も疲労困憊で参戦。<br />
そして、初の自宅以外での環境。</p>
<p><span id="more-234"></span></p>
<h3>Easy BunnyPuzzle</h3>
<p>ウサギパズル。ウサギかわいいよね。<br />
ちょっとエンジンかかるの遅くて時間かかった。</p>
<p>179.60</p>
<h3>Midium RabbitNumbering</h3>
<p>ウサギを数字でindentifyする。<br />
後で気づいたけど、0以上チェック要らないね。</p>
<p>[java]<br />
public class RabbitNumbering {<br />
	public int theCount(int[] maxNumber) {<br />
		final int N = maxNumber.length;<br />
		Arrays.sort(maxNumber);<br />
//		System.out.println(Arrays.toString(maxNumber));<br />
		long count = 1L;<br />
		for (int i = 0; i < N; i++) {<br />
			if (maxNumber[i] - i > 0) {<br />
				count *= maxNumber[i] &#8211; i;<br />
				count %= 1000000007;<br />
			} else {<br />
				return 0;<br />
			}<br />
		}<br />
//		System.out.println(&#8220;long=&#8221;+count);<br />
//		return (int)(count % 1000000007);<br />
		return (int)count;<br />
	}<br />
}<br />
[/java]</p>
<p>335.29</p>
<h3>Hard Nisoku</h3>
<p>「にそく」っていうカードゲーム（実在するのかは知らない、しないだろう）</p>
<p>任意の数のカードがある山から２枚とって足すか掛けるかしてその値のカードを戻す。<br />
最後の１枚の最大値を求める。</p>
<p>さっぱりわからなかった。<br />
最初与えられる山の配列が1.5~10.0なのが鍵くさいけど分からない。<br />
ちょっとここは勉強する。</p>
<p>0.0</p>
<h3>Challenge Phase</h3>
<p>傍観。<br />
立ち上がりのHard落としが今の流行？</p>
<p>0.0</p>
<h3>Result</h3>
<p>もうちょっと集中してやりたかったなあ。</p>
<p><strong>Total</strong> 509.89<br />
<strong>Rating</strong> 1009(+19)</p>
<p>レートの上がり方が異様に鈍い。<br />
前の戦績も影響するのかな。</p>
<p>みなさんお疲れ様でした。精進します。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/topcoder/234/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SRM459 div2</title>
		<link>http://thleave.com/topcoder/220</link>
		<comments>http://thleave.com/topcoder/220#comments</comments>
		<pubDate>Tue, 19 Jan 2010 18:09:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[TopCoder]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=220</guid>
		<description><![CDATA[今日は平和な部屋だった。
つか、問題が平和だった。

Easy RecursiveFigures
円と正方形の面積を足したり引いたりする問題。
楽勝・・・のはずが、型にやられた。
2.0とすべきところを2にしてしまった。 [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>今日は平和な部屋だった。<br />
つか、問題が平和だった。</p>
<p><span id="more-220"></span></p>
<h3>Easy RecursiveFigures</h3>
<p>円と正方形の面積を足したり引いたりする問題。<br />
楽勝・・・のはずが、型にやられた。<br />
2.0とすべきところを2にしてしまった。しねばよい。</p>
<p>撃墜されず、システムで落ちた。<br />
当然のごとく、2.0にしたら通った <img src='http://thleave.com/wordpress/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>0.0</p>
<h3>Midium Inequalities</h3>
<p>不等号で表されている部分集合の式がたくさん渡されて、一番かぶる場所はどこ？って問題。<br />
ゴリ押しか良いアルゴリズムがあるか考えてみたけれど、<br />
時間が無くなったのでゴリ押しで書いた。</p>
<p>[java]<br />
    public int maximumSubset(String[] inequalities) {<br />
    	int[] subset = new int[2100];</p>
<p>    	for (int i = 0; i < inequalities.length; i++) {<br />
			String[] s = inequalities[i].split(" ");<br />
			int n = Integer.parseInt(s[2]);<br />
			if (s[1].equals(">=&#8221;)) {<br />
				for (int j = 2010; j >= n * 2 + 1; j&#8211;) subset[j]++;<br />
			} else if (s[1].equals(&#8220;>&#8221;)) {<br />
				for (int j = 2010; j > n * 2 + 1; j&#8211;) subset[j]++;<br />
			} else if (s[1].equals(&#8220;=&#8221;)){<br />
				subset[n*2+1]++;<br />
			} else if (s[1].equals(&#8220;<")) {<br />
				for (int j = 0; j < n * 2 + 1; j++) subset[j]++;<br />
			} else if (s[1].equals("<=")) {<br />
				for (int j = 0; j <= n * 2 + 1; j++) subset[j]++;<br />
			}<br />
		}</p>
<p>    	int result = 1;<br />
    	for (int i = 0; i < subset.length; i++) {<br />
			result = Math.max(result, subset[i]);<br />
		}<br />
    	return result;<br />
    }<br />
[/java]</p>
<p>そしたらみんなゴリ押しだったから笑った。<br />
すぐに書けばよかったなぁ。慎重すぎるかなあ。</p>
<h3>Hard ParkAmusement</h3>
<p>時間なかったから、問題よんだだけ。<br />
面白そうだったから後でやる。</p>
<h3>Challenge Phase</h3>
<p>なんか平和だった。<br />
部屋で撃墜0だったし、俺も突く場所がみつからなかった。</p>
<p>結果、<strong>219.64</strong>で341位。<br />
システム入る前で345位だったから、みんな相当落ちたんだね。</p>
<p><strong>941(+16)</strong></p>
<p>Easyとれば200位ぐらいだったみたいだから勿体無かったけど、<br />
こんな落とし方してもレート下がらなくなってきたのは良い傾向。</p>
<p>来月もがんばろう。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/topcoder/220/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>幅優先探索をJavaを使って覚える</title>
		<link>http://thleave.com/coding/218</link>
		<comments>http://thleave.com/coding/218#comments</comments>
		<pubDate>Sat, 16 Jan 2010 16:59:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=218</guid>
		<description><![CDATA[下らない内容だなぁと思い人もたくさんいるかと思いますが、
自分は今まで幅優先探索が苦手で敬遠してきました！(笑
そんなお仲間がいらっしゃればご参考になればと。
この記事はそれ以上でもそれ以下でもございません。

まず、き [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>下らない内容だなぁと思い人もたくさんいるかと思いますが、<br />
自分は今まで幅優先探索が苦手で敬遠してきました！(笑</p>
<p>そんなお仲間がいらっしゃればご参考になればと。<br />
この記事はそれ以上でもそれ以下でもございません。</p>
<p><span id="more-218"></span></p>
<p>まず、きっかけです。<br />
最近いろいろなところで目にしたので、是非解きたいと思った問題がありまして、、</p>
<p>人材獲得作戦・４　試験問題ほか | 人生を書き換える者すらいた。<br />
<a href="http://okajima.air-nifty.com/b/2010/01/post-abc6.html">http://okajima.air-nifty.com/b/2010/01/post-abc6.html</a></p>
<p>これなんですが、読んでみたら簡単そうなんですが、どうやら幅優先探索(BFS:BreadthFirstSearch)を使いそう。<br />
TopCoderでは、「BFSがベストアンサー！」みたいな問題は今まで見かけなかったので放置していたんですが、<br />
腹をくくって勉強。<br />
DFSは得意なんだよね。なぜか、あの再帰具合が。</p>
<p>で、たまたまITMediaで連載中の講座でも探索が！<br />
これは偶然だけども。</p>
<p>知れば天国、知らねば地獄――「探索」虎の巻 | 最強最速アルゴリズマー養成講座<br />
<a href="http://www.itmedia.co.jp/enterprise/articles/1001/16/news001.html">http://www.itmedia.co.jp/enterprise/articles/1001/16/news001.html</a></p>
<p>探索は基本だよねえ。うん。</p>
<h3>Javaでの実装に使うもの</h3>
<p>そこを読ませて頂いても、Wikipediaの解説を読んでも、キュー(Queue)を使うのが基本らしい。<br />
幅優先っていう概念はわかりやすいんだけどね。実装がねー</p>
<p>JavaでQueueだと、Queueインターフェイスを実装した<a href="http://java.sun.com/javase/ja/6/docs/ja/api/java/util/LinkedList.html">LinkedList</a>なんかがお手頃。<br />
※ 話が逸れるけど、Eclipseで「LLi」ってとこまでいれて保管すると一番上にLinkedListがでる。</p>
<p>で、問題はなんのメソッドを使うか。<br />
Stackインターフェイスも実装しているからややこしいんだけど、<br />
Queueは先入れ先出し(FIFO)が原則なので、後方から入れて先頭から出すようにする。<br />
行列と同じ。以下の２つのメソッドを使う。</p>
<p><strong>LinkedList#offer(e)</strong><br />
リストの末尾に追加。</p>
<p><strong>LinkedList#poll()</strong><br />
リストの先頭を取得して削除。</p>
<p>Stackに関係するメソッドは有名だから知ってたけど、<br />
この２つは最近まで全然知らなかった。（のは俺だけかもしれない）</p>
<h3>実装</h3>
<p>後は書くしか無い。</p>
<p>ALGORITHM NOTE | 幅優先探索 Breadth First Search<br />
<a href="http://algorithms.blog55.fc2.com/blog-entry-127.html">http://algorithms.blog55.fc2.com/blog-entry-127.html</a></p>
<p>参考にしました。このサイトにはいつも助けられてます。</p>
<p>自分で分かりやすく書きたかったので、結構だらだら長いコードだけど、こんな感じ。<br />
[java]<br />
public class BreadthFirstSearch {<br />
	Point[] move = new Point[]{new Point(0, -1), new Point(-1,0), new Point(1, 0), new Point(0,1)};<br />
	char[] directions = new char[]{&#8216;r&#8217;, &#8216;d&#8217;, &#8216;u&#8217;, &#8216;l&#8217;};</p>
<p>	public BreadthFirstSearch(int[][] input, int sx, int sy){<br />
		class Puzzle {<br />
			int[][] map = new int[3][3];<br />
			int x = 0;<br />
			int y = 0;<br />
			String path;</p>
<p>			public Puzzle(int[][] map, int x, int y, String path) {<br />
				this.map = map;<br />
				this.x = x;<br />
				this.y = y;<br />
				this.path = path;<br />
			}</p>
<p>			public boolean check(){<br />
				for (int i = 0; i < 8; i++) {<br />
					if (this.map[i / 3][i % 3] != i+1) return false;<br />
				}<br />
				return true;<br />
			}<br />
		}</p>
<p>		LinkedList<Puzzle> queue = new LinkedList<Puzzle>();<br />
		queue.push(new Puzzle(input, sx, sy, &#8220;&#8221;));</p>
<p>		BFS : while (queue.size() > 0) {<br />
			Puzzle p = queue.poll();</p>
<p>			for (int i = 0; i < 4; i++) {<br />
				int x = p.x + move[i].x;<br />
				int y = p.y + move[i].y;</p>
<p>				if (x >= 0 &#038;&#038; x <= 2 &#038;&#038; y >= 0 &#038;&#038; y <= 2) {<br />
					int[][] map = this.dc(p.map);<br />
					map[p.x][p.y] = map[x][y];<br />
					map[x][y] = 0;</p>
<p>					Puzzle moved = new Puzzle(map, x, y, p.path + directions[i]);<br />
					if (moved.check()) {<br />
						System.out.println(moved.path);<br />
						break BFS;<br />
					}</p>
<p>					queue.add(moved);<br />
				}<br />
			}<br />
		}</p>
<p>		System.out.println("#END");<br />
	}</p>
<p>	public int[][] dc(int[][] input){<br />
		int[][] output = new int[input.length][input[0].length];<br />
		for (int i = 0; i < input.length; i++) {<br />
			output[i] = input[i].clone();<br />
		}<br />
		return output;<br />
	}</p>
<p>	public static void main(String[] args) throws FileNotFoundException {<br />
		FileInputStream fis = new FileInputStream("src/study/puzzle.in");<br />
		Scanner sc = new Scanner(fis);</p>
<p>		int[][] puzzle = new int[3][3];<br />
		int x = 0;<br />
		int y = 0;</p>
<p>		for (int i = 0; i < 9; i++) {<br />
			char input = sc.next().charAt(0);<br />
			if (input == 'x') {<br />
				x = i / 3;<br />
				y = i % 3;<br />
				puzzle[i / 3][i % 3] = 0;<br />
			} else {<br />
				puzzle[i / 3][i % 3] = input - '0';<br />
			}<br />
		}</p>
<p>		new BreadthFirstSearch(puzzle, x, y);<br />
	}<br />
}</p>
<p>[/java]</p>
<p>次に本命のあのサイト。<br />
せっかくだからTopCoderっぽくコストから出してみた。<br />
かなり回りくどいけど、書いてて自分で勉強になった。</p>
<p>[java]<br />
public class Kuma4_1 {<br />
	static final int width = 26;<br />
	static final int height = 13;<br />
	Point[] movable = new Point[]{new Point(1, 0), new Point(0, 1), new Point(-1, 0), new Point(0, -1)};</p>
<p>	public Kuma4_1(char[][] map, int sx, int sy, int gx, int gy) {<br />
		LinkedList<Point> queue = new LinkedList<Point>();<br />
		queue.add(new Point(sx, sy));<br />
		int cost = 1;<br />
		int[][] costMap = new int[height][width];<br />
		char[][] copiedMap = this.dc(map);</p>
<p>		BFS: while (queue.size() > 0) {<br />
			Point now = queue.poll();</p>
<p>			for (int i = 0; i < movable.length; i++) {<br />
				int x = now.x + movable[i].x;<br />
				int y = now.y + movable[i].y;</p>
<p>				if (map[x][y] == 'G') {<br />
					costMap[x][y] = cost;<br />
					this.out(copiedMap, costMap, gx, gy);<br />
					break BFS;</p>
<p>				} else if (map[x][y] == ' ') {<br />
					costMap[x][y] = cost;<br />
					map[x][y] = '#';<br />
					queue.offer(new Point(x,y));<br />
				}<br />
			}</p>
<p>			cost++;<br />
		}</p>
<p>		System.out.println("#process end");<br />
	}</p>
<p>	public void out(char[][] map, int[][] costMap, int gx, int gy){<br />
		int cost = costMap[gx][gy];<br />
		Point p = new Point(gx, gy);<br />
		while (cost > 1){<br />
			cost&#8211;;<br />
			for (int i = 0; i < movable.length; i++) {<br />
				int x = p.x + movable[i].x;<br />
				int y = p.y + movable[i].y;</p>
<p>				if (costMap[x][y] == cost) {<br />
					map[x][y] = &#8216;$&#8217;;<br />
					p = new Point(x,y);<br />
				}<br />
			}<br />
		}</p>
<p>		for (int i = 0; i < map.length; i++) {<br />
			System.out.println(new String(map[i]));<br />
		}<br />
	}</p>
<p>	public void out(int[][] map) {<br />
		for (int i = 0; i < map.length; i++) {<br />
			for (int j = 0; j < map[i].length; j++) {<br />
				System.out.printf(&#8220;%3d&#8221;, map[i][j]);<br />
			}<br />
			System.out.println();<br />
		}<br />
	}</p>
<p>	public void out(char[][] map) {<br />
		for (char i = 0; i < map.length; i++) {<br />
			System.out.println(new String(map[i]));<br />
		}<br />
	}</p>
<p>	public char[][] dc(char[][] input){<br />
		char[][] output = new char[input.length][input[0].length];<br />
		for (char i = 0; i < input.length; i++) {<br />
			output[i] = input[i].clone();<br />
		}<br />
		return output;<br />
	}</p>
<p>	public static void main(String[] args) throws FileNotFoundException {<br />
		FileInputStream fis = new FileInputStream(&#8220;src/study/kuma4.in&#8221;);<br />
		Scanner sc = new Scanner(fis);</p>
<p>		char[][] map = new char[height][width];</p>
<p>		for (int i = 0; sc.hasNext(); i++) {<br />
			String line = sc.nextLine();<br />
			map[i] = line.toCharArray();<br />
		}</p>
<p>		int sx=0, sy=0, gx=0, gy=0;<br />
		for (int i = 0; i < map.length; i++) {<br />
			for (int j = 0; j < map[0].length; j++) {<br />
				if (map[i][j] == &#8216;S&#8217;) {<br />
					sx = i;<br />
					sy = j;<br />
				} else if (map[i][j] == &#8216;G&#8217;) {<br />
					gx = i;<br />
					gy = j;<br />
				}<br />
			}<br />
		}</p>
<p>		new Kuma4_1(map, sx, sy, gx, gy);<br />
	}<br />
[/java]</p>
<p>しかしなげぇ。でも、書く時間自体はそんなかからなかった。30分弱くらいかなあ。<br />
でも、アルゴリズム調べてからだから、そう考えると論外だとも。</p>
<p>とにかく、ぼくはこれで幅優先探索をやっと覚えました！ばっちこい。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/coding/218/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SRM454 div2</title>
		<link>http://thleave.com/topcoder/184</link>
		<comments>http://thleave.com/topcoder/184#comments</comments>
		<pubDate>Mon, 07 Dec 2009 15:02:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[TopCoder]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=184</guid>
		<description><![CDATA[眠いけど、一応出た。

Easy MinimalDifference
問題文を忠実にコードに起こすだけ。
速攻テスト通ったー！と思って油断してたら、for文の範囲ミスってて撃墜されたorz
2文字切っただけでシステム通っ [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>眠いけど、一応出た。</p>
<p><span id="more-184"></span></p>
<h3>Easy MinimalDifference</h3>
<p>問題文を忠実にコードに起こすだけ。<br />
速攻テスト通ったー！と思って油断してたら、for文の範囲ミスってて撃墜されたorz<br />
2文字切っただけでシステム通った。</p>
<p>0.0</p>
<h3>Midium WordsGame</h3>
<p>文字がN個xN個の格子状に配置されていて、<br />
与えられた長さNの文字列に<strong>一致(*1)</strong>するように<strong>swap(*2)</strong>を繰り返す。<br />
*1 <strong>一致</strong>は「上から下」か「左から右」のみ。斜めとかなし。<br />
*2 <strong>swap</strong>は列同士か行同士しかできない。文字単位ではNG<br />
もし完成すれば最小コストを返せという問題。</p>
<p>N <= 50なので、単純な探索は無理。</p>
<p>ただ、swapできると言っても、列か行単位のみ。<br />
ということは、もし「左から右」の行で完成する場合は、列swapのみ。<br />
逆に、「上から下」の列で完成する場合は、行swapしかしないことになる。</p>
<p>なので、列か行単位でみてけばよい。<br />
2N個の長さNの文字配列を与えられた長さNの文字列に近づける。<br />
ずいぶん簡単になった。</p>
<p>[java]<br />
public class WordsGame {<br />
	String[] strings;<br />
	int cost = Integer.MAX_VALUE;</p>
<p>	public int minimumSwaps(String[] grid, String word) {<br />
		strings = new String[grid.length * 2];</p>
<p>		for (int i = 0; i < grid.length; i++) {<br />
			strings[i] = grid[i];<br />
		}<br />
		for (int i = 0; i < grid.length; i++) {<br />
			StringBuilder sb = new StringBuilder();<br />
			for (int j = 0; j < grid.length; j++) {<br />
				sb.append(grid[j].charAt(i));<br />
			}<br />
			strings[i + grid.length] = sb.toString();<br />
		}</p>
<p>		for (int i = 0; i < strings.length; i++) {<br />
			solve(word, strings[i], 0, 0);<br />
		}</p>
<p>		return (this.cost == Integer.MAX_VALUE) ? -1 : this.cost;<br />
	}</p>
<p>	public void solve(String s, String t, int index, int cost) {<br />
//		System.out.println("#solve index="+index+", cost="+cost+", src="+s+", target="+t);</p>
<p>		char[] src = s.toCharArray();<br />
		char[] target = t.toCharArray();</p>
<p>		if (src[index] == target[index]) {<br />
			if (src.length == index + 1) {<br />
				// 完全まっち！ => END<br />
				this.cost = Math.min(cost, this.cost);<br />
			} else {<br />
				solve(s, t, index + 1, cost);<br />
			}<br />
		} else {<br />
			int pos = index;<br />
			LinkedList<Integer> hit = new LinkedList<Integer>();<br />
			while (true) {<br />
				pos = search(target, src[index], pos);<br />
				if (pos == -1) break;<br />
				hit.add(pos++);<br />
			}</p>
<p>			if (hit.size() > 0) {<br />
				while (hit.size() > 0) {<br />
					int to = hit.poll();<br />
					swap(target, index, to);<br />
					solve(s, new String(target), index + 1, cost + 1);<br />
					swap(target, to, index);<br />
				}<br />
			}<br />
		}<br />
	}</p>
<p>	public void swap(char[] c, int from, int to) {<br />
		char temp = c[from];<br />
		c[from] = c[to];<br />
		c[to] = temp;<br />
	}</p>
<p>	public int search(char[] c, char target, int start) {<br />
		for (int i = start; i < c.length; i++) {<br />
			if (c[i] == target)<br />
				return i;<br />
		}<br />
		return -1;<br />
	}<br />
}<br />
[/java]</p>
<p>0.0</p>
<p>でも、競技中に間に合わなかった(笑<br />
超レート下がったyo</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/topcoder/184/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>アンダースコア記法をキャメル記法に</title>
		<link>http://thleave.com/coding/118</link>
		<comments>http://thleave.com/coding/118#comments</comments>
		<pubDate>Sun, 06 Sep 2009 07:45:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Cayenne]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=118</guid>
		<description><![CDATA[テーブルのカラム名をEnumにして、関連づけを全部そこに任せていたんだけど、
ApacheCayenneはカラム名などをキャメル記法で渡す。う゛ぁーって感じ。
なので変換メソッドを作った。
[java]
	public  [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>テーブルのカラム名をEnumにして、関連づけを全部そこに任せていたんだけど、<br />
ApacheCayenneはカラム名などをキャメル記法で渡す。う゛ぁーって感じ。<br />
なので変換メソッドを作った。</p>
<p>[java]<br />
	public static String camelize(String s){<br />
		char[] c = s.toLowerCase().toCharArray();<br />
		StringBuilder r = new StringBuilder(s.length());<br />
		int diff = &#8216;A&#8217; &#8211; &#8216;a&#8217;;<br />
		for (int i = 0; i < c.length; i++) {<br />
			if (c[i] == &#8216;_&#8217;) {<br />
				r.append((char)(c[++i] + diff));<br />
			} else {<br />
				r.append(c[i]);<br />
			}<br />
		}<br />
		return r.toString();<br />
	}<br />
[/java]</p>
<p>動作良好。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/coding/118/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ApacheCayenneに関する備忘録</title>
		<link>http://thleave.com/coding/94</link>
		<comments>http://thleave.com/coding/94#comments</comments>
		<pubDate>Sun, 16 Aug 2009 16:10:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Cayenne]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=94</guid>
		<description><![CDATA[どんどん追加していこう。

CayenneModelerでモデリングするとカラムの順番が滅茶苦茶になる
しっかり順番意識して作ってもpkカラムがテーブルの中央にきたりするありえなさ。
なので、別のモデリングソフト使ってモ [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>どんどん追加していこう。</p>
<ul>
<li>CayenneModelerでモデリングするとカラムの順番が滅茶苦茶になる<br />
しっかり順番意識して作ってもpkカラムがテーブルの中央にきたりするありえなさ。<br />
なので、別のモデリングソフト使ってモデリングしてSQL発行してテーブル作ってます。<br />
ただ、auto_pk_support忘れがち。
</li>
<li>DataObject <=> PK<br />
<a href="http://cayenne.apache.org/doc20/dataobjectutils.html">http://cayenne.apache.org/doc20/dataobjectutils.html</a><br />
DataObjectUtilsという便利なクラスがあって、それを使ってPKとDataObjectの相互変換が簡単にできる。</li>
</ul>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/coding/94/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache Maven2を使ったApache WicketのQuick Start</title>
		<link>http://thleave.com/coding/71</link>
		<comments>http://thleave.com/coding/71#comments</comments>
		<pubDate>Sun, 09 Aug 2009 14:29:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=71</guid>
		<description><![CDATA[ルー語みたいなタイトルになっちゃいました。
前にもやったことがあったのですが、
開発環境が変わりやり方も忘れてしまったので、
今度は忘れないように備忘録として。
&#8212;
Apache Mavenは現在v2が主流。 [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>ルー語みたいなタイトルになっちゃいました。</p>
<p>前にもやったことがあったのですが、<br />
開発環境が変わりやり方も忘れてしまったので、<br />
今度は忘れないように備忘録として。</p>
<p>&#8212;</p>
<p>Apache Mavenは現在v2が主流。<br />
<a href="http://maven.apache.org/">http://maven.apache.org/</a></p>
<ol>
<li>落としてきて適当な場所に解凍する。</li>
<li>ローカルリポジトリを設定する。<br />
最初にやっとかないと、デフォルトのディレクトリ（~/.m2/以下）にファイルが沢山ダウンロードされちゃう。</p>
<p>[解凍先]/conf/settings.xml<br />
local_repositoryっぽい場所があるので、好きな場所に変更する。</li>
<li>（コマンドプロンプトから実行するので）環境変数を設定する。<br />
PATH=[解凍先]/bin/<br />
JAVA_HOME=[JDKのディレクトリ]</li>
<li>試しに行してみる。<br />
$mvn &#8211;version<br />
など。返事が返ってくれば成功。</li>
<li>プロジェクトを作成したいディレクトリに移動。<br />
カレントディレクトリにプロジェクトが作成されるので、<br />
EclipseのWorkspace内など、好きな場所へ。</li>
<li>Apache Wicket Quick Start!<br />
<a href="http://wicket.apache.org/quickstart.html">http://wicket.apache.org/quickstart.html</a><br />
詳しくはリンク先を読んでください。</li>
<li>自動生成されたコマンドを実行する。<br />
EclipseなどIDEとの連携を考えている人は、<br />
上記リンク先の下の方もちゃんと読む！（必要なコマンドがあります）</li>
</ol>
<p>以上でおわり。</p>
<p>さぁ、作業作業。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/coding/71/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
