http://qiita.com/Nabetani/items/7b08b0eb9ef84d7cfe49
http://nabetani.sakura.ne.jp/hena/ord7xysort/
行列をソートするというもの。
PHPにはarray_multisort()という超絶便利関数があるので、こいつ呼ぶだけで一発だろーはっはっはー、とか思って作り始めたところ、実は全てのソート関数が値が同じときの順番を保証しないという事実が発覚して全滅。
仕方ないので自力でソートする羽目に。なんてこった。
で、キーを維持するユーザ定義ソート関数にはusort()とuksort()があるのですが、usort()はコールバックに値しか渡さない、uksort()はキーしか渡さないという意味のわからない仕様。
use使えばいいのですが、デフォでキーと値両方とも渡してくださいマジで。
array_multisortにコールバックを渡せればねえ。
残念なのですが、いまいちこれよりよさげなアルゴリズムを考えつかないのでとりあえず保留。
またいずれリベンジしたいものですね。
「オフラインリアルタイムどう書く」の一覧
http://nabetani.sakura.ne.jp/hena/ord7xysort/
行列をソートするというもの。
PHPにはarray_multisort()という超絶便利関数があるので、こいつ呼ぶだけで一発だろーはっはっはー、とか思って作り始めたところ、実は全てのソート関数が値が同じときの順番を保証しないという事実が発覚して全滅。
仕方ないので自力でソートする羽目に。なんてこった。
で、キーを維持するユーザ定義ソート関数にはusort()とuksort()があるのですが、usort()はコールバックに値しか渡さない、uksort()はキーしか渡さないという意味のわからない仕様。
use使えばいいのですが、デフォでキーと値両方とも渡してくださいマジで。
<?php
class XYSORT{
/**
* 二次元でソート
* @param String 「AvEx」みたいな文字列
* @return String 「305027」みたいな文字列
*/
public function get($input){
// 初期状態
$table = [
[4, 1, 4, 2, 1, 3],
[7, 3, 2, 0, 5, 0],
[2, 3, 6, 0, 6, 7],
[6, 4, 5, 7, 5, 1],
[3, 1, 6, 6, 2, 4],
[6, 0, 5, 5, 5, 1]
];
// 文字に対応する列
$map = [
'A'=>0, 'B'=>1, 'C'=>2, 'D'=>3, 'E'=>4, 'F'=>5,
'u'=>0, 'v'=>1, 'w'=>2, 'x'=>3, 'y'=>4, 'z'=>5
];
// 現在のテーブルが縦か横かのフラグ
$tableCol = true;
// 入力値でくるくる
for($i=0; $i<strlen($input); $i++){
// 縦か横か
$isTableCol = (strtoupper($input[$i]) === $input[$i]);
// 縦横が合ってないときは転置
if($tableCol !== $isTableCol){
$tableCol = !$tableCol;
$table = $this->getTransposed($table);
}
// ソート基準列
$columnid = (int)$map[$input[$i]];
$column = $table[$columnid];
// ソート基準列を、昇順安定ソート
uksort($column, function($a, $b) use($column){
if($column[$a] < $column[$b]){
return -1;
}elseif($column[$a] > $column[$b]){
return 1;
}else{
return $a > $b;
}
});
// テーブルを基準列に合わせてソート
$tmp = [];
foreach($column as $key=>$val){
foreach($table as $row=>$data){
$tmp[$row][] = $table[$row][$key];
}
}
$table = $tmp;
}
// 最後に転置されてたら戻す
if($tableCol === false){
$table = $this->getTransposed($table);
}
// 終了
return implode('', $table[0]);
}
/**
* 転置行列を得る
* {@see http://blog.supermomonga.com/articles/php/array-to-transverse-matrix.html }
* @param array 二次元配列
* @return array 縦横を入れ替え
*/
private function getTransposed($array){
return call_user_func_array('array_map', array_merge(array(null), $array));
}
}
// テスト
$test = [
['AvEx', '305027'],
/* 省略 */
];
$xysort = new XYSORT();
foreach($test as $key=>$data){
$answer = $xysort->get($data[0]);
if($answer !== $data[1]){
print('えらー');
}
}
いやー、想像以上に残念なコードになってしまった。array_multisortにコールバックを渡せればねえ。
残念なのですが、いまいちこれよりよさげなアルゴリズムを考えつかないのでとりあえず保留。
またいずれリベンジしたいものですね。
「オフラインリアルタイムどう書く」の一覧
PR