Tag Archives: どう書く?.org

『数字混じり文字列ソート』投稿

どう書く?.org』に投稿。

 お題はこちら
 自然順アルゴリズムで配列をソートしてくださいというものです。

 例えば、1.txt, 10.txt, 2.txtであれば、1.txt, 10.txt, 2.txt ではなく、1.txt, 2.txt, 10.txt というように。

 PHPではnatcasesort()という要求そのままの関数が存在するのですが(大文字小文字を区別するならnatsort()です)、この関数はキーの関係を保持してソートするため、キーを持たない配列をソートした場合に期待した結果になりません。

 例えば、

$a = array( ‘1.txt’, ’10.txt’, ‘2.txt’ );

この配列をnatcasesortすると、
[cc lang=”PHP”]
Array
(
[0] => 1.txt
[2] => 2.txt
[1] => 10.txt
)
[/cc]
こうなる。
 foreachで回すならこれで良いのですが、forで回す場合にはソートされていないように見えてしまいます。

 このため、お題の回答は以下にしました。
 第2パラメータを省略またはFALSEを渡せばnatcasesort()と同等、TRUEでキーの関係を保持しない結果となります。

[cc lang=”PHP”]
function NaturalSort( &$target, $sw = FALSE )
{
natcasesort( $target );
if ( $sw ) {
foreach ( $target as $value ) {
$buf[] = $value;
}
$target = $buf;
}
}
[/cc]

投稿:
http://ja.doukaku.org/comment/21159/
PHP Rank:10(74.6%)

『文字列で+を表示する』投稿

 『どう書く?.org』連投。
 お題はこちら
 与えられた文字列で十字を描けというもの。

 PHPで書(描)きました。
 ブラウザで出力するなら<pre>タグで括ると良い。

[cc lang=PHP]
$str = ‘abracadabra’;

$slen = strlen( $str );
$bar = $str.$str[0];

echo sprintf( “% “.strval($slen*2+1).”s\n”, $bar );
for ( $i = 0; $i < $slen-1; $i++ ) { echo sprintf( "% ".strval($slen+1)."s% ".strval($slen)."s\n", $str[$slen-$i-1], $str[$i+1] ); } echo sprintf( "%s% ".strval($slen*2)."s\n", $bar, $bar ); for ( $i = 0; $i < $slen-1; $i++ ) { echo sprintf( "%s% ".strval($slen*3)."s\n", $str[$slen-$i-1], $str[$i+1] ); } echo sprintf( "%s% ".strval($slen*2)."s\n", $bar, $bar ); for ( $i = 0; $i < $slen-1; $i++ ) { echo sprintf( "% ".strval($slen+1)."s% ".strval($slen)."s\n", $str[$slen-$i-1], $str[$i+1] ); } echo sprintf( "% ".strval($slen*2+1)."s\n", $bar); [/cc]  $strに任意の文字列を設定すれば、それに応じた十字が描かれる。  関数化できる箇所があるけど、わかりやすさ優先でわざと同じものを書いている。  仕様として、文字列は半角英数字2文字以上とする。ガードは入れてない。  文字列'abc'の場合以下の結果となる。 [cc lang=PHP] abca c b b c abca abca c b b c abca abca c b b c abca [/cc] 投稿: http://ja.doukaku.org/comment/11244/
PHP Rank:16(61.6%)

 どう書く.orgへのスパム何とかしてほしい。

『階層的なキーの連想配列化』投稿

 『どう書く?.org』への投稿ひさびさ。

 お題はこちら
 今回は与えられたテーブルを元に階層的な連送配列を作りなさいというもの。
 配列を&で渡しているのがポイント。

[cc lang=PHP]
$tokyo = array(
array(‘東京都’, ‘区部’, ‘千代田区’, ‘object1’)
,array(‘東京都’, ‘区部’, ‘中央区’, ‘object2’)
,array(‘東京都’, ‘区部’, ‘港区’, ‘object3’)
,array(‘東京都’, ‘多摩地域’, ‘支部’, ‘昭島市’, ‘object4’)
,array(‘東京都’, ‘多摩地域’, ‘支部’, ‘あきる野市’, ‘object5’)
,array(‘東京都’, ‘多摩地域’, ‘西多摩郡’, ‘奥多摩町’, ‘object6’)
,array(‘東京都’, ‘島嶼部’, ‘大島支庁’, ‘大島町’, ‘object7’)
,array(‘東京都’, ‘島嶼部’, ‘三宅支庁’, ‘三宅村’, ‘object8’)
);

$tokyo_tree = array();

foreach ( $tokyo as $obs ) {
$w = &$tokyo_tree;
$cnt = count( $obs );
for ( $i = 0; $i < $cnt; $i++ ) { if ( $i == $cnt-1 ) { $w = $obs[$i]; } else { $w = &$w[$obs[$i]]; } } } print_r( $tokyo_tree ); [/cc] 結果はこんなかんじ。 [cc lang=PHP] Array ( [東京都] => Array
(
[区部] => Array
(
[千代田区] => object1
[中央区] => object2
[港区] => object3
)

[多摩地域] => Array
(
[支部] => Array
(
[昭島市] => object4
[あきる野市] => object5
)

[西多摩郡] => Array
(
[奥多摩町] => object6
)

)

[島嶼部] => Array
(
[大島支庁] => Array
(
[大島町] => object7
)

[三宅支庁] => Array
(
[三宅村] => object8
)

)

)

)
[/cc]

投稿:
http://ja.doukaku.org/comment/10876/
PHP Rank:17(61.1%)

『IPv4アドレスのマスクの変換』投稿2

 『どう書く?.org』への投稿

お題:IPv4アドレスのマスクの変換
 以前PHPで書いたものを秀丸マクロで書く。
 ようするに、255.255.255.128などのネットマスクをビット値に変換すればよい。またその逆変換も求められている。
 秀丸マクロの場合、2進数⇔10進数の変換サブルーチンを用意しなければならず、その分stepがかさんでいる。

Mask2Bit:
##c=0;
##bit=0;
while (strlen($$1)) {
$b = leftstr($$1,1);
$$1 = rightstr($$1, strlen($$1)-1);
if ($b == “.”) {
##c = ##c + 1;
} else if (val($b) == 0 && $b != “0”) {
break;
} else {
$$aar[##c] = $$aar[##c] + $b;
}
}
while (0 <= ##c) {
call Dec2Bin val($$aar[##c]);
while (strlen($$return)) {
##bit = ##bit + val(leftstr($$return,1));
$$return = rightstr($$return, strlen($$return)-1);
}
##c = ##c – 1;
}
return ##bit;

Bit2Mask:
$$b_str = “”;
$$mask = “”;
while (strlen($$b_str) < 32) {
if (0<##1) {
$$b_str = $$b_str + “1”;
} else {
$$b_str = $$b_str + “0”;
}
##1 = ##1 – 1;
}
while (strlen($$b_str)) {
call Bin2Dec leftstr($$b_str, 8);
$$mask = $$mask + str(##return);
$$b_str = rightstr($$b_str, strlen($$b_str)-8);
if (strlen($$b_str)) {
$$mask = $$mask + “.”;
}
}
return $$mask;

Bin2Dec:
##dec = 0;
##val = 1;
while (strlen($$1)) {
if (rightstr($$1, 1) == “1”) {
##dec = ##dec + ##val;
}
##val = ##val*2;
$$1 = leftstr($$1, strlen($$1)-1);
}
return ##dec;

Dec2Bin:
$$str = “”;
if (##1!=0) {
while (##1!=1) {
$$str = str(##1%2)+$$str;
##1 = ##1/2;
}
$$str = “1”+$$str;
} else {
$$str = “0”;
}
return $$str;

投稿:
秀丸マクロ rank:33 (15.6)

『クリップボードへの転送』投稿

 『どう書く?.org』へ投稿。

お題:クリップボードへの転送
http://ja.doukaku.org/188/

クリップボード(や同等の機能)へテキストを転送するプログラムをお願いします。 また可能でしたらクリップボードのデータを取り出すプログラムもお願いします。

 秀丸マクロ。
 はじめから用意されているので3step。

setclipboard input(“input str.”);
beginclipboardread;
message getclipboard;

投稿:
秀丸マクロ rank:33 (15.1%)

『LL Golf Hole 8 – 横向きのピラミッドを作る』投稿

 『どう書く?.org』への投稿

お題:LL Golf Hole 8 – 横向きのピラミッドを作る
http://ja.doukaku.org/203/

与えられた自然数 n について、横向きで n 段のピラミッドを作ってください。 たとえば、 n に 4 が与えられた場合は以下のようなピラミッドを作ります。

4
*
**
***
****
***
**
*

 言語の入門書によくある問題。
 これを、秀丸マクロで書く。
 できるだけ小さく書けとリクエストされているので不要なものは極力排除しているが、なにせ秀丸マクロなのでなかなか小さくならない。
 読みやすさを優先して、改行の排除は最小限に抑えている。

#h=4;
while(y-#h+1<#h){
#a=y-#h+1;
if(#a<0)#a=#a*-1;
$p=””;
while(strlen($p)<#h-#a)$p=$p+”*”;
insert$p+”\n”;
}

 標準でabs関数が使えればもう少しシンプルになる。
投稿:
秀丸マクロ rank:34 (14.5%)

『キッチンタイマー』投稿

どう書く?.org』への投稿
お題:キッチンタイマー
http://ja.doukaku.org/240/

キッチンタイマーを作ってください。
要件は以下のとおりです。

・タイマーが鳴るまでの時間を入力可能
・残り時間を表示
・タイマーが切れたら音がなる

 秀丸マクロで組む。
 inputダイアログボックスから秒を入力すると、残り時間がデクリメントされていく。
 タイムアウトでbeep。

#sec = val(input(“input sec.”));
insert str(#sec)+”\n”;
#start = tickcount;
while (#sec) {
if ((#start + 1000) <= tickcount) {
#start = tickcount;
#sec = #sec – 1;
moveto 0,0;
beginsel;
golineend;
endsel;
insert str(#sec);
gofileend;
}
}
beep;
endmacro;

秀丸マクロ rank:35 (14.0%)

『バイナリクロック』投稿2

どう書く?.org』への投稿

 秀丸マクロでバイナリクロック。
お題:バイナリクロック
http://ja.doukaku.org/275/
 特に変わった事はしていない。0と1で刻むクロック。
 秀丸マクロにはfor文が存在しなかったり、インクリメント/デクリメントの書式が理解されなかったりするので、コードが賑やかになりがち。

$bin[0] = “”;
$bin[1] = “”;
$bin[2] = “”;
insert “\n\n\n”;

while (1) {
#i = 0;
while (#i < 3) {
call GetBinTime #i;
if ($bin[#i] != $$return) {
$bin[#i] = $$return;
moveto 0,#i;
beginsel;
golineend;
endsel;
insert $bin[#i];
gofileend;
}
#i = #i+1;
}
}
endmacro;

GetBinTime:
refreshdatetime;
if (##1 == 0) {
call Dec2Bin val(hour);
} else if (##1 == 1) {
call Dec2Bin val(minute);
} else {
call Dec2Bin val(second);
}
while (strlen($$return) < 6) {
$$return = ” “+$$return;
}
return $$return;

Dec2Bin:
$$str = “”;
if (##1!=0) {
while (##1!=1) {
$$str = str(##1%2)+$$str;
##1 = ##1/2;
}
$$str = “1”+$$str;
}
return $$str;

投稿:
http://ja.doukaku.org/comment/9432/
秀丸マクロ rank:36(13.4%)

『ラングトンのアリの描画』投稿2

 『どう書く?.org』への投稿。

 これまでお題に対する挑戦はPHPオンリーだったけど、ラングトンのアリを秀丸マクロで書いた。
 秀丸マクロは今まで書いた事が無かったので、マクロヘルプを参照しつつコーディング。
お題:
 マクロを実行すると、100×100の全角スペースフィールドの中心に蟻(○)が落ちる。

#w = 100;
#dct = 0;
$sp = “ ”;
$line = “”;

#i = 0;
while (#i < #w) {
$line = $line+$sp;
#i = #i + 1;
}
$line = $line+”\n”;

#i = 0;
while (#i < #w) {
insert $line;
#i = #i + 1;
}
movetolineno #w,#w/2;

#i = 0;
while (1) {
$ant = gettext(x, y, x+2, y);
if ($ant == $sp) {
overwrite “○”;
#dct = (#dct+1)%4;
} else {
overwrite $sp;
#dct = (((#dct+1)%4)+2)%4;
}
left;
if (#dct == 0) {
up;
} else if (#dct == 1) {
right;
} else if (#dct == 2) {
down;
} else if (#dct == 3) {
left;
}
if ((x > #w*2-1)||(x == 0)||(y == 0)||(y > #w-1)) {
endmacro;
}
}
endmacro;

 この投稿で、秀丸マクロの言語ランクは39。まだまだ。
投稿:
秀丸マクロ Rank:39 (12.9%)

『IPv4アドレスのマスクの変換』投稿

どう書く?.org』への投稿

お題:IPv4アドレスのマスクの変換
http://ja.doukaku.org/253/
 ようするに、「255.255.255.128」を「25」にしたり、「24」を「255.255.255.0」にしてくださいという問題。
 特に面白い事はしていない。

function mask2bits($ddn_str)
{
    $bits = 0;
    $decs = explode(‘.’, $ddn_str);
    foreach ( $decs as $dec ) {
        $bits += substr_count(decbin($dec), ‘1’);
    }
    return $bits;
}

function bits2mask($bits)
{
    $bits_str = strrev(sprintf(‘%032s’, str_repeat(“1”, $bits)));
    $bins = str_split($bits_str, 8);
    foreach ($bins as $bin) {
        $decs[] = bindec($bin);
    }
    return implode(‘.’, $decs);
}

投稿:
PHP rank:17(63.0%)