「第6回 オフラインリアルタイムどう書く」参考問題: へなちょこ解答(Java)

世間はクリスマスイブですね。聞くところによると、サンタの実在を信じていた期間が長いほどリア充なのだそうです。あなたはどうですか?

というわけで(?)、どう書くの参考問題を解きました。

今回は、L-intersectionです!(L字交点、と訳せばよいのでしょうか)

Qiitaのこちらのトピックで、ほかの方の解答を見ることができます。

自分の解答

なんと、今回はJavaなのに60行くらいで書けました。やりましたね!

おそらくこれはクリスマスプレゼントです。どう書くのサンタさんアリガトー\(^o^)/

import java.util.HashSet;
import java.util.Set;

/**
 * 問題: http://nabetani.sakura.ne.jp/hena/ord6lintersection/
 */
public class Lintersection {

	public String solve(String input) {
		String[] split = input.split(",");
		String[] first = split[0].split("-");
		String[] second = split[1].split("-");

		Set<String> firstL = getL(first);
		Set<String> secondL = getL(second);

		int counter = 0;
		for (String string : secondL) {
			boolean canAdd = firstL.add(string);
			if (canAdd == false) {
				counter++;
			}
		}
		return String.valueOf(counter);
	}

	protected Set<String> getL(String[] points) {

		int x0 = Integer.valueOf(String.valueOf(points[0].charAt(0)));
		int y0 = Integer.valueOf(String.valueOf(points[0].charAt(1)));
		int x1 = Integer.valueOf(String.valueOf(points[1].charAt(0)));
		int y1 = Integer.valueOf(String.valueOf(points[1].charAt(1)));

		Set<String> tmp = new HashSet<>();
		Set<String> firstBlock = makeBlock(x0, y0, x1, y1, tmp);

		int x2 = Integer.valueOf(String.valueOf(points[2].charAt(0)));
		int y2 = Integer.valueOf(String.valueOf(points[2].charAt(1)));

		Set<String> result = makeBlock(x2, y2, x0, y0, firstBlock);
		return result;
	}

	protected Set<String> makeBlock(int x0, int y0, int x1, int y1,
			Set<String> set) {
		Set<String> result = new HashSet<>(set);
		int maxX = x0 < x1 ? x1 : x0;
		int minX = x0 < x1 ? x0 : x1;
		int maxY = y0 < y1 ? y1 : y0;
		int minY = y0 < y1 ? y0 : y1;

		for (int i = minX; i < maxX + 1; i++) {
			for (int k = minY; k < maxY + 1; k++) {
				result.add(String.valueOf(i) + String.valueOf(k));
			}
		}

		return result;
	}
}

考え方

短いおかげで自明な気がしますが、一応メモ。

この問題に必要なのは、次の2つの処理です。

  1. L字を構成するマス目座標の検出
  2. 2つのL字に共通するマス目座標の検出
L字を構成するマス目座標の検出

与えられた3つの座標のうち、「1つ目の座標位置と2つ目の座標位置を対角に持つ長方形」(長方形1)と「3つ目の座標位置と1つ目の座標位置を対角に持つ長方形」(長方形2)を合わせたものが、L字であると考えました。

(図は、問題ページからお借りしました。なんだかクリスマスカラーですね。バクハツしろ!

図のように、長方形1と長方形2には共通部分があります。

長方形1と長方形2を構成するマスを、同一のSetに詰め込むことで、重複を排除し、共通部分を二度数えないようにしました。

2つのL字に共通するマス目座標の検出

ここでも、1つ目のLと2つ目のLのマスを、同一のSetに詰め込みます。

(追記 2012/12/25) 図を修正しました。(右の出っ張りを共通部分に入れ忘れていました)

すでにそのマスがSetの要素にあった場合、falseが返るので、それをカウントすることで、共通部分のマス目を算出しました。

そんな感じです。