2012年8月30日木曜日

Haskellで三項演算子のような物を定義する

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

こう書きたい


if-then-elseはなんだか嫌だなぁと。でもガードじゃなくてワンライナーで書きたいなぁと。
出来るのかもしれないが、知らないので。教えて・・・。

>[x>5?1:2 | x <- [1..10]]
>[2,2,2,2,2,1,1,1,1,1]

無理だ


そもそも":"はリストを生成する為の演算子なので上のような書き方はシンタックスエラーで死ぬ。
"1:2"は"1:2:[]"と書け!と怒られる。
なので諦める。":"は諦める。

似非三項演算子


結果こうなった。
x ? (a, b) = if x then a else b
if-thenで返す値とelseで返す値をペアで取る事にした。
使う時はこう
>[(x>5)?(1,2) | x <- [1..10]]
>[2,2,2,2,2,1,1,1,1,1]

やったぜ!

2012年8月23日木曜日

[java] クイックソート 効率はよくない

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

クイックソート。

package jp.dip.sys1.yagi.sort;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
public class QuickSort {
/**
* クイックソートやで
* @param list ソート対象のリスト
* @param comp 比較関数
* @return ソート済みのリスト
*/
public static <T> List<T> sort(List<T> list, Comparator<T> comp) {
if(list.isEmpty()){
return list;
}
//ピボットより値の小さいリスト
List<T> smaller = new ArrayList<T>();
//ピボットより値の大きいリスト
List<T> greater = new ArrayList<T>();
Random p = new Random(System.currentTimeMillis());
//ピボット
int index = p.nextInt(list.size());
T pv = list.get(index);
//ピボットより小さい値、大きい値で各リストに振り分ける
for (int i = 0; i < list.size(); i++) {
if (i != index) {
T l = list.get(i);
if (comp.compare(pv, l) >= 0) {
smaller.add(l);
} else {
greater.add(l);
}
}
}
//ピボットより値の小さいリスト、ピボットより値の大きいリストをそれぞれクイックソートにかける
//ピボットを真ん中にして連結して返す
List<T> result = new ArrayList<T>();
result.addAll(QuickSort.sort(smaller, comp));
result.add(pv);
result.addAll(QuickSort.sort(greater, comp));
return result;
}
//sample
public static void main(String[] args) {
Integer[] l = new Integer[] { 1, 20, 4205, 539, 5, 2, 104, 100, 6, 1, 7, 239, 2, 55 };
List<Integer> list = Arrays.asList(l);
list = QuickSort.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
for (Integer r : list) {
System.out.println(r);
}
}
}
view raw QuickSort.java hosted with ❤ by GitHub

[Java] ヒープソート 遅い

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

Javaでヒープソート。
もう見なくてもヒープソートも実装できる様になったわー。
この実装は再起を使っているので遅いらしい。
次はHaskellでやる。

package jp.dip.sys1.yagi.sort;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class HeapSort {
/**
* ヒープソートやで
* @param list ソート対象のリスト
* @param comp 要素の比較関数
*/
public static <T> void sort(List<T> list, Comparator<T> comp){
for (int i = 0; i < list.size(); i++) {
HeapSort.build(list, 0, i, comp);
}
}
/**
* 指定したoffset以降の要素をヒープ構造に並べ替える
* @param list 対象のリスト
* @param index ノードのインデックス
* @param offset 未ソート状態のリストの開始位置
* @param comp 比較関数
*/
public static <T> void build(List<T> list, int index, int offset, Comparator<T> comp) {
T l = HeapSort.left(list, index, offset);
if (l != null) {
HeapSort.build(list, 2 * index + 1, offset, comp);
l = HeapSort.left(list, index, offset);
HeapSort.swap(list, index, offset, l, 2 * index + 1, comp);
}
T r = HeapSort.right(list, index, offset);
if (r != null) {
HeapSort.build(list, 2 * index + 2, offset, comp);
r = HeapSort.right(list, index, offset);
HeapSort.swap(list, index, offset, r, 2 * index + 2, comp);
}
}
/**
* 子ノードを取り出す
* @param list 対象のリスト
* @param index ノードのインデックス
* @param offset 未ソート状態のリストの開始位置
* @param leaf 左か右か。1=左 2=右
* @return 子ノード。存在しない場合はnull
*/
public static <T> T child(List<T> list, int index, int offset, int leaf) {
int i = 2 * index + leaf + offset;
if (list.size() <= i) {
return null;
} else {
return list.get(i);
}
}
public static <T> T left(List<T> list, int index, int offset) {
return HeapSort.child(list, index, offset, 1);
}
public static <T> T right(List<T> list, int index, int offset) {
return HeapSort.child(list, index, offset, 2);
}
/**
* 親ノードと子ノードを比較し、必要があれば入れ替える
* @param list 対象のリスト
* @param index ノードのインデックス
* @param offset 未ソート状態のリストの開始位置
* @param value 子ノードの値
* @param leaf 左か右か。1=左 2=右
* @param comp 比較関数
*/
public static <T> void swap(List<T> list, int index, int offset, T value, int leaf, Comparator<T> comp) {
if (value != null) {
if (comp.compare(list.get(index + offset), value) < 0) {
T tmp = list.get(index + offset);
list.set(index + offset, list.get(leaf + offset));
list.set(leaf + offset, tmp);
}
}
}
//sample
public static void main(String[] args) {
Integer[] l = new Integer[] { 5, 2, 104, 100, 6, 1, 7, 239, 2, 55 };
List<Integer> list = Arrays.asList(l);
HeapSort.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
for (Integer r : list) {
System.out.println(r);
}
}
}
view raw HeapSort.java hosted with ❤ by GitHub

2012年8月17日金曜日

[Haskell] FizzBuzzをやる

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

メモ。すぐ忘れそうなので。
cycleが名前長いのが気に入らない。
take 100でリスト取り出してるだけなんで要件満たしてない気もする。
bとcが空かどうかを評価する部分が気に入らない
zip3使うのが何か負けた気がする
無限リスト楽しい。

take 100 [if b=="" && c=="" then show a else concat [b,c]|(a,b,c)<-(zip3 (cycle [1..]) (cycle["","","Fizz"]) (cycle ["","","","","Buzz"]))]