気ままな一言
2008年06月14日
LSL汎用関数 その4
さて、ネタが尽きてきました。今回はまだ使える関数です。
時刻関連の関数は標準であるといいのですが。
誰か良い時計でも作られたら私に下さい(笑)
時刻関連の関数は標準であるといいのですが。
誰か良い時計でも作られたら私に下さい(笑)
//============================================================================== // Unixタイムをグレゴリオ暦に変換します。 // time Unixタイム // diff 時差 // 戻り値 [ 年, 月, 分, 時, 分, 秒 ] のリストを返します。 //============================================================================== listunixtime2list(integer time, integer diff) { time += 57974400 + diff * 3600; // 24 * 60 * 60 * (365 + 306) integer n = time / 86400; // 24 * 60 * 60 integer day = n % 1461; // 365 + 365 + 365 + 366 integer year = n / 1461 * 4 + 1968; if (day >= 1095) { day -= 1095; year += 3; } else if (day >= 730) { day -= 730; year += 2; } else if (day >= 365) { day -= 365; ++year; } integer month = 3; n = 31; list lst = [ 0, 0, 0, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29 ]; while (day >= n) { day -= n; n = llList2Integer(lst, month); month = -(~month); } if (month > 12) { ++year; month -= 12; } return [ year, month, day + 1, time / 3600 % 24, time / 60 % 60, time % 60 ]; } 【使用方法】 list lst = unixtime2list(1199145600, 0); // lst = [ 2008, 1, 1, 0, 0, 0 ] list lst = unixtime2list(llGetUnixTime(), 9); // lst = JST(日本時間)
//============================================================================== // 日付をUnixタイムとして取得します。 // year 年(1970~2038) // month 月(1~12) // day 日(1~31) // hour 時(0~) // minute 分(0~) // second 秒(0~) // 戻り値 Unixを返します。範囲外の値は保障外です。 //============================================================================== integer maketime(integer year, integer month, integer day, integer hour, integer minute, integer second) { if (month < 3) { month += 12; --year; } year = (year * 365 + llList2Integer([ 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337 ], month - 3) + day) + llFloor(year / 4) - llFloor(year / 100) + llFloor(year / 400); return (year - 719469) * 86400 + (hour * 60 + minute) * 60 + second; } 【使用方法】 integer time = maketime(2008, 1, 1, 0, 0, 0); // time = 1199145600
// 曜日の戻り値はISO-8601形式準拠よりこの方が使いやすいよね……多分。
//============================================================================== // 曜日を求めます。 // 有効な範囲はグレゴリオ暦1582年10月15日以降です。 // year 年(西暦) // month 月 // day 日 // 戻り値 曜日を(日曜日…0 ~ 土曜日…6)で返します。 //============================================================================== integer dayofweek(integer year, integer month, integer day) { if (month < 3) { --year; month += 12; } return (year + year / 4 - year / 100 + year / 400 + (13 * month + 8) / 5 + day) % 7; } 【使用方法】 integer n = dayofweek(2008, 1, 1); // n = 2 string str = llList2String([ "日", "月", "火", "水", "木", "金", "土" ], dayofweek(2008, 1, 1)); // str = "火" MEMO [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ] [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ] [ "Dimanche", "Lundi", "Mardi","Mercredi", "Jeudi", "Vendredi", "Samedi" ]
//============================================================================== // 現在の曜日を求めます。 // diff 時差 // 戻り値 曜日を(日曜日…0 ~ 土曜日…6)で返します。 //============================================================================== integer get_dayofweek(integer diff) { return (llFloor((llGetUnixTime() + diff * 3600) / 86400) + 4) % 7; } 【使用方法】 integer n = get_dayofweek(9); // 日本時間の今日の曜日
おまけ
//============================================================================== // 西暦を和暦に変換します。 // year 西暦 // 戻り値 和暦を返します。範囲外は空リストを返します。 // [ 1 明治 / 2 大正 / 3 昭和 / 4 平成, 年数, 年号 ] //============================================================================== list to_wareki(integer year) { if (1989 <= year) { return [ 4, (year - 1988), "平成" ]; } else if (1926 <= year) { return [ 3, (year - 1925), "昭和" ]; } else if (1912 <= year) { return [ 2, (year - 1911), "大正" ]; } else if (1868 <= year) { return [ 1, (year - 1867), "明治" ]; } return []; } //============================================================================== // 和暦を西暦に変換します。 // 実際に存在しない場合も計算されます。 // n 1 明治 / 2 大正 / 3 昭和 / 4 平成 // year 和暦 // 戻り値 西暦を返します。nが正しくない場合はyearを返します。 //============================================================================== integer from_wareki(integer n, integer year) { return llList2Integer([ 0, 1867, 1911, 1925, 1988 ], n) + year; }
2008年05月29日
LSL汎用関数 その3
小中学生の頃を思い出す関数です。
はい、使い道無いですね。
はい、使い道無いですね。
//============================================================================== // 合計を求めます。 // lst 値 // 戻り値 lstの合計値を返します。 //============================================================================== float sum(list lst) { integer i; integer n = llGetListLength(lst); float a; for (i = n - 1; i >= 0; i=~(-i)) { a += llList2Float(lst, i); } return a; }
//============================================================================== // 平均を求めます。 // lst 値 // 戻り値 lstの平均値を返します。 //============================================================================== float average(list lst) { integer i; integer n = llGetListLength(lst); float a; for (i = n - 1; i >= 0; i=~(-i)) { a += llList2Float(lst, i); } return a / n; }
//============================================================================== // 標準偏差を求めます。 // lst 値 // 戻り値 lstの標準偏差を返します。 //============================================================================== float stdev(list lst) { integer i; integer n = llGetListLength(lst); float a; float b; float x; for (i = n - 1; i >= 0; i=~(-i)) { x = llList2Float(lst, i); a += x; b += llPow(x, 2); } a /= n; b = (b - llPow(a, 2) * n) / (n - 1); // 分散 if (b > 0) { return llSqrt(b); } return 0; }
//============================================================================== // 最大公約数を求めます。 // lst 最大公約数を求める値 // 戻り値 引数の最大公約数を返します。 //============================================================================== integer gcd(list lst) { integer len = llGetListLength(lst) - 1; integer a = llList2Integer(lst, len); integer b; integer r; integer i; for (i = len - 1; i >= 0; i=~(-i)) { b = llList2Integer(lst, i); while (b) { // b != 0 r = a % b; a = b; b = r; } } return llAbs(a); }
//============================================================================== // 最小公倍数を求めます。 // lst 最小公倍数を求める値 // 戻り値 引数の最小公倍数を返します。 //============================================================================== integer lcm(list lst) { integer len = llGetListLength(lst) - 1; integer a = llList2Integer(lst, len); integer b; integer r; integer m; integer n; integer i; for (i = len - 1; i >= 0; i=~(-i)) { b = llList2Integer(lst, i); m = a; n = b; while (n) { // n != 0 r = m % n; m = n; n = r; } if (m) { // m != 0 a = llAbs(a * b / m); } else { a = m; } } return a; }
//============================================================================== // 階乗を求めます。 // n 総数 // 戻り値 nの階乗を返します。 //============================================================================== integer factorial(integer n) { integer i; integer a = n; for (i = n - 1; i > 1; i=~(-i)) { a *= i; } return a; }
//============================================================================== // 順列を求めます。 // n 総数 // m 選ぶ個数 // 戻り値 n個からm個を選び出す順列の数を返します。 //============================================================================== integer permut(integer n, integer m) { integer i; integer a = n; m = n - m; for (i = n - 1; i > m; i=~(-i)) { a *= i; } return a; }
//============================================================================== // 組合せの数を求めます。 // n 総数 // m 選ぶ個数 // 戻り値 n個からm個を選び出す組合せの数を返します。 //============================================================================== integer combin(integer n, integer m) { if (n - m < m) { m = n - m; } if (!m) { return 1; } if (m == 1) { return n; } integer i; integer j; list lst = [0]; for (i = 1; i < m; i=-(~i)) { lst += [i + 2]; } for (i = m; i <= n - m + 1; i=-(~i)) { lst += [0]; } for (i = 3; i <= n - m + 1; i=-(~i)) { lst = llListReplaceList(lst, [i], 0, 0); for (j = 1; j < m; j=-(~j)) { lst = llListReplaceList(lst, [llList2Integer(lst, j) + llList2Integer(lst, j - 1)], j, j); } } return llList2Integer(lst, m - 1); }
2008年05月04日
LSLを便利に書こう
最近LSLEditorを使うことがあります。
これ便利ですね~。
以前から知っていて、これだけスクリプト書いているのに
全然使っていませんでした。
それはSciTE-EZというエディタと勘違いしていたためです。
スクリプトを始めた頃にLSLならこのエディタという記事を読んでSciTE-EZを使ってみたのですが、
これは要するに只の汎用エディタでLSL用としては特に大したことありませんでした。
標準でLSLをサポートしているので構文チェックなどは手軽にできるという利点はあるのですが、
そもそも英語ですし、使いたいと思いませんでした。
普段使用しているエディタに慣れていると、
別のエディタは使いにくく感じるという理由もあると思います
LSLEditorはその名の通りLSLに特化しており、
一部分の関数をエミュレーションしてくれます。
文字列やリストなどサーバとの連携を必要としない機能に関してはそのまま動作してくれます。
オプションでアバターのキーなども設定できるので、それに関する動作もある程度動いてくれます。
試したことありませんが、メールも使えるみたいです。
使いこなすつもりでなければ、使い方は至って簡単。
普通にスクリプトを書いて、
F6キーで構文チェック、
F5キーでスクリプトの実行を行います。
実行するとDebugというタブが追加され、
実行結果がConsole(下のウィンドウ)に出力されます。
Verboseは処理経過が出力されます。
右にはスクリプトの内容に応じてイベントに関するボタンが表示され、
それらの処理もエミュレーションすることができます。

注意しなければいけないことは
このエディタの構文チェックが甘いことです。
エディタでエラーが出なくてもInWorldでエラーとなることがあります。
また、オプションで構文チェックの設定を変えた場合にはもちろんエラーとなります。
ちょうどバージョンアップしたばかりみたいです。
InWorldでしかスクリプトを書いたこと無い方はとりあえず使う価値はあると思います。
ちなみに私は最初の一文でもわかる通り
あまり使っていませんので詳しいことまではわかりませんのであしからず。(^_^;
これ便利ですね~。
以前から知っていて、これだけスクリプト書いているのに
全然使っていませんでした。
それはSciTE-EZというエディタと勘違いしていたためです。
スクリプトを始めた頃にLSLならこのエディタという記事を読んでSciTE-EZを使ってみたのですが、
これは要するに只の汎用エディタでLSL用としては特に大したことありませんでした。
標準でLSLをサポートしているので構文チェックなどは手軽にできるという利点はあるのですが、
そもそも英語ですし、使いたいと思いませんでした。
普段使用しているエディタに慣れていると、
別のエディタは使いにくく感じるという理由もあると思います
LSLEditorはその名の通りLSLに特化しており、
一部分の関数をエミュレーションしてくれます。
文字列やリストなどサーバとの連携を必要としない機能に関してはそのまま動作してくれます。
オプションでアバターのキーなども設定できるので、それに関する動作もある程度動いてくれます。
試したことありませんが、メールも使えるみたいです。
使いこなすつもりでなければ、使い方は至って簡単。
普通にスクリプトを書いて、
F6キーで構文チェック、
F5キーでスクリプトの実行を行います。
実行するとDebugというタブが追加され、
実行結果がConsole(下のウィンドウ)に出力されます。
Verboseは処理経過が出力されます。
右にはスクリプトの内容に応じてイベントに関するボタンが表示され、
それらの処理もエミュレーションすることができます。

注意しなければいけないことは
このエディタの構文チェックが甘いことです。
エディタでエラーが出なくてもInWorldでエラーとなることがあります。
また、オプションで構文チェックの設定を変えた場合にはもちろんエラーとなります。
ちょうどバージョンアップしたばかりみたいです。
InWorldでしかスクリプトを書いたこと無い方はとりあえず使う価値はあると思います。
ちなみに私は最初の一文でもわかる通り
あまり使っていませんので詳しいことまではわかりませんのであしからず。(^_^;