■
MacBook Air 11インチ欲しい!
当たったらどーすっかなー
解いてみた
ITmedia の「あなたのスキルで飯は食えるか? 史上最大のコーディングスキル判定」ってのを解いてみた。
馬鹿正直なコードすぎて恥ずかしい。
もっとかっこいいコードが書きたい。
あとバグ出したんで3時間以上かかってます。
同じ牌が4枚しかないこと、チートイツについては考慮してません。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;public class MachiChecker {
public static void main(String[] args) {
//標準入力を読んで空改行じゃなければ待ちチェック
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
while (true) {
String line = reader.readLine();
if (line != null && line.length() > 0) {
showMachi(line);
} else {
System.exit(0);
}
}
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}public static void showMachi(String str) {
//入力をソートして配列化。13番目の要素(待ち)は0とする
final int[] pais = new int[14];
for (int i = 0; i < 13; i++) {
pais[i] = Integer.parseInt(str.substring(i, i + 1));
}
pais[13] = 99;
Arrays.sort(pais);
pais[13] = 0;
//順子と刻子をすべて取り出して、ソート
ListpaiSets = findJuntu(pais);
paiSets.addAll(findKoutu(pais));
Collections.sort(paiSets, new Comparator() {
@Override
public int compare(PaiSet o1, PaiSet o2) {
int val1 = pais[o1.pai1] * 100 + pais[o1.pai2] * 10 + pais[o1.pai3];
int val2 = pais[o2.pai1] * 100 + pais[o2.pai2] * 10 + pais[o2.pai3];
return val1 - val2;
}
});
//すべての頭を取り出す
Listatamas = findAtama(pais);
//見つかった待ち文字列
Setfound = new HashSet ();
//牌のインデックスのセット
Setnums = new HashSet ();
for (Atama atama : atamas) {
nums.add(atama.pai1);
nums.add(atama.pai2);
//順子、刻子の組み合わせで牌のインデックスがかぶらない物をfoundに追加
for (int i = 0; i < paiSets.size(); i++) {
PaiSet set1 = paiSets.get(i);
if (addNumbers(nums, set1)) {
for (int j = i + 1; j < paiSets.size(); j++) {
PaiSet set2 = paiSets.get(j);
if (addNumbers(nums, set2)) {
for (int k = j + 1; k < paiSets.size(); k++) {
PaiSet set3 = paiSets.get(k);
if (addNumbers(nums, set3)) {
for (int l = k + 1; l < paiSets.size(); l++) {
PaiSet set4 = paiSets.get(l);
if (addNumbers(nums, set4)) {
found.add(atama.toString(pais) + set1.toString(pais)
+ set2.toString(pais) + set3.toString(pais) + set4.toString(pais));
removeNumbers(nums, set4);
}
}
removeNumbers(nums, set3);
}
}
removeNumbers(nums, set2);
}
}
removeNumbers(nums, set1);
}
}
nums.remove(atama.pai1);
nums.remove(atama.pai2);
}//結果表示
for (String yaku : found) {
System.out.println(yaku);
}
}private static List
findJuntu(int[] pais) {
Listrtn = new ArrayList ();
for (int i = 0; i < pais.length; i++) {
for (int j = i + 1; j < pais.length; j++) {
for (int k = j + 1; k < pais.length; k++) {
if ((pais[i] == pais[j] - 1 && pais[j] == pais[k] - 1)
|| (pais[i] == pais[j] - 1 && k == 13)
|| (pais[i] == pais[j] - 2 && k == 13)) {
rtn.add(new PaiSet(i, j, k));
}
}
}
}
return rtn;
}private static List
findKoutu(int[] pais) {
Listrtn = new ArrayList ();
for (int i = 0; i < pais.length; i++) {
for (int j = i + 1; j < pais.length; j++) {
for (int k = j + 1; k < pais.length; k++) {
if ((pais[i] == pais[k] && pais[j] == pais[k])
|| (pais[i] == pais[j] && k == 13 && j != 13)) {
rtn.add(new PaiSet(i, j, k));
}
}
}
}
return rtn;
}private static List
findAtama(int[] pais) {
Listrtn = new ArrayList ();
for (int i = 0; i < pais.length; i++) {
for (int j = i + 1; j < pais.length; j++) {
if (pais[i] == pais[j] || j == 13) {
rtn.add(new Atama(i, j));
}
}
}
return rtn;
}private static boolean addNumbers(Set
set, PaiSet paiSet) {
if(set.contains(paiSet.pai1) || set.contains(paiSet.pai2) || set.contains(paiSet.pai3)) {
return false;
}
set.add(paiSet.pai1);
set.add(paiSet.pai2);
set.add(paiSet.pai3);
return true;
}
private static void removeNumbers(Setset, PaiSet paiSet) {
set.remove(paiSet.pai1);
set.remove(paiSet.pai2);
set.remove(paiSet.pai3);
}
}class Atama {
public int pai1;
public int pai2;public Atama(int pai1, int pai2) {
this.pai1 = pai1;
this.pai2 = pai2;
}public String toString(int[] pais) {
if(pai1 != 13 && pai2 != 13) {
return "("+ pais[pai1] + "" + pais[pai2] + ")";
} else {
return "["+ pais[pai1] + "]";
}
}
}class PaiSet {
public int pai1;
public int pai2;
public int pai3;
public PaiSet(int pai1, int pai2, int pai3) {
this.pai1 = pai1;
this.pai2 = pai2;
this.pai3 = pai3;
}
public String toString(int[] pais) {
if(pai3 != 13) {
return "("+ pais[pai1] + "" + pais[pai2] + "" + pais[pai3] + ")";
} else {
return "["+ pais[pai1] + "" + pais[pai2] + "]";
}
}
}
結果
1112224588899
(99)(111)(222)[45](888)
1122335556799
(55)(123)(123)(567)[99]
(99)(123)(123)[55](567)
(99)(123)(123)(555)[67]
1112223335559
[9](111)(222)(333)(555)
[9](123)(123)(123)(555)
1223344888999
[4](123)(234)(888)(999)
[1](234)(234)(888)(999)
(44)(123)[23](888)(999)
1112345678999
(11)(123)[45](678)(999)
(99)(111)(234)[56](789)
[2](111)(345)(678)(999)
(99)(111)(234)(567)[89]
(11)[12](345)(678)(999)
(11)(123)(456)[78](999)
(11)(123)(456)(789)[99]
[5](111)(234)(678)(999)
(99)[11](123)(456)(789)
(99)(111)[23](456)(789)
[8](111)(234)(567)(999)
なっげー
かっこわるーい
一応解説すると、入力された数字を14要素の数値の配列にし(最後の要素はワイルドカードとして考える)、
そこからあり得る全ての頭、順子、刻子をリストアップして、牌がかぶらない組み合わせを
表示してます。
九蓮宝燈の場合、頭が19、順子と刻子が42あり、それらを全部組み合わせると
19*42*41*40*39/(1*2*3*4)=2126670
通りの組み合わせになりますが、牌がかぶる組み合わせは試さずに切り捨ててるので
(ソースのネストしまくって汚い辺り)実際のところは28676回の試行で済み、
数ミリ秒(Core2Duo 2.13GHzのMac。数回目の試行でHotSpotで最適化された後の数字)
と比較的実用レベルの速度におさまりました。
追記:ちょっとバグってたんで直しました。
さらに追記:カンチャン待ちを忘れてたんで追加しました。
さらに追記:よく見たら余計なコードがあったんで整理
また引っ越します
たびたび恐縮ですが、jFDのページの引越しに伴い、またこのページを引っ越します。
tDiaryを試してみたかっただけなんですが。
移転先はこちら。
http://www.starseed.ne.jp/ikemen/diary/tdiary/
リンク、ブックマークの変更をお願いします。
大落ち込み
本潜水艦はこれより水面下2000メートルを目指し、深く深く落ち込みます。
ブクブクブク・・・
ふーらふら
相変わらずジムには足繁く通っているのだが、仕事が始まってから時間が足りず、
一回1時間程度しか練習できていない。
そうなると最後になる筋トレが省かれることが多かったのだが、
久しぶりに目いっぱい、2時間半みっちり練習したら筋トレで体がガタガタになった。
最近、体力がかなり落ちてるみたいで、マスなんかやった日には
あっという間にスタミナが切れるし。
まずいなあ・・・
ちょっと前から新しいトレーナーの人が入ったのだが、初めてミットをやってもらった。
慎重180センチを超える大柄な人で、すごくがっちりした体をしている。
ミットはうまいトレーナーほどいい音がするものだが(ミットをパンチに当ててくるので)、
この人は極端にいい音がして、あまりにも強い力でミットをパンチに当ててくるので
僕のジャブ程度だと打ち負けていた。
すごいもんだ。