[#17017] 標準添付案 — Kazuhiro NISHIYAMA <zn@...>

西山和広です。

21 messages 2002/05/08
[#17019] Re: 標準添付案 — "Akinori MUSHA" <knu@...> 2002/05/08

At Wed, 8 May 2002 19:50:17 +0900,

[#17021] Re: 標準添付案 — GOTO Kentaro <gotoken@...> 2002/05/08

At Wed, 8 May 2002 22:45:06 +0900,

[#17031] double acosh — WATANABE Hirofumi <eban@...>

わたなべです。

25 messages 2002/05/10
[#17032] Re: double acosh — nobu.nakada@... 2002/05/10

なかだです。

[#17033] Re: double acosh — WATANABE Hirofumi <eban@...> 2002/05/10

わたなべです。

[#17036] Re: double acosh — matz@... (Yukihiro Matsumoto) 2002/05/10

まつもと ゆきひろです

[#17039] Re: double acosh — WATANABE Hirofumi <eban@...> 2002/05/10

わたなべです。

[#17134] argv[0] — Tanaka Akira <akr@...17n.org>

ふと ruby インタプリタの C における argv[0] を知りたくなったんですが、

23 messages 2002/05/18
[#17139] Re: argv[0] — matz@... (Yukihiro Matsumoto) 2002/05/18

まつもと ゆきひろです

[#17144] Re: msvcrt — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

18 messages 2002/05/19

[#17179] コマンドラインオプションの順序制約 — Kazuhiro NISHIYAMA <zn@...>

西山和広です。

13 messages 2002/05/22
[#17181] Re: コマンドラインオプションの順序制約 — matz@... (Yukihiro Matsumoto) 2002/05/22

まつもと ゆきひろです

[#17228] Re: [ruby-list:35305] Re: ((1.2)..(3.4)).to_a — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

28 messages 2002/05/30

[ruby-dev:17210] Re: [RCR] Array#rotate{,!}

From: nobu.nakada@...
Date: 2002-05-23 12:45:00 UTC
List: ruby-dev #17210
なかだです。

At Thu, 23 May 2002 17:05:22 +0900,
U.Nakamura <usa@osb.att.ne.jp> wrote:
> | RCR(http://www.rubygarden.org/article.php?sid=237)に書いときま
> | したが、Array#rotate{,!}というのはどうでしょうか。自明かとは思
> | いますが、
> 
> 回転寿司シミュレータ(なんじゃそりゃ)に便利かも。

オヤジがまわってる?

> | --- Array#rotate!(index)
> |     self[index]が先頭になるように回転する。変更されたときはself、
> |     されなかったときはnilを返す。
> | 
> | --- Array#rotate(index)
> |     回転された新しいArrayを返す。
> 
> 省略時引数として index = 1 というのを消極的に提案します。

うーむ。indexをmoduloにしたりして消極的なパッチ。


Index: array.c
===================================================================
RCS file: /cvs/ruby/src/ruby/array.c,v
retrieving revision 1.83
diff -u -2 -p -r1.83 array.c
--- array.c	2002/05/22 05:57:08	1.83
+++ array.c	2002/05/23 10:34:08
@@ -1027,4 +1027,15 @@ rb_ary_to_a(ary)
 }
 
+static void
+ary_reverse(p1, p2)
+    VALUE *p1, *p2;
+{
+    while (p1 < p2) {
+	VALUE tmp = *p1;
+	*p1++ = *p2;
+	*p2-- = tmp;
+    }
+}
+
 VALUE
 rb_ary_reverse(ary)
@@ -1032,5 +1043,4 @@ rb_ary_reverse(ary)
 {
     VALUE *p1, *p2;
-    VALUE tmp;
 
     rb_ary_modify(ary);
@@ -1039,11 +1049,6 @@ rb_ary_reverse(ary)
     p1 = RARRAY(ary)->ptr;
     p2 = p1 + RARRAY(ary)->len - 1;	/* points last item */
+    ary_reverse(p1, p2);
 
-    while (p1 < p2) {
-	tmp = *p1;
-	*p1++ = *p2;
-	*p2-- = tmp;
-    }
-
     return ary;
 }
@@ -1064,4 +1069,99 @@ rb_ary_reverse_m(ary)
 }
 
+static unsigned long
+modulo_index(x, y)
+    long x;
+    unsigned long y;
+{
+    /* x must not be LONG_MIN */
+    if (x < 0) {
+	if (x == LONG_MIN) return y - (-(LONG_MIN+1UL) % y + 1) % y;
+	return y - (unsigned long)-x % y;
+    }
+    else {
+	return (unsigned long)x % y;
+    }
+}
+
+VALUE
+rb_ary_rotate(ary, cnt)
+    VALUE ary;
+    long cnt;
+{
+    rb_ary_modify(ary);
+
+    if (cnt != 0) {
+	VALUE *ptr = RARRAY(ary)->ptr;
+	long len = RARRAY(ary)->len;
+
+	cnt = modulo_index(cnt, len);
+	if (cnt == 0) return Qnil;
+
+	--len;
+	if (cnt > 1) ary_reverse(ptr, ptr + cnt - 1);
+	if (cnt < len) ary_reverse(ptr + cnt, ptr + len);
+	if (len > 0) ary_reverse(ptr, ptr + len);
+	return ary;
+    }
+
+    return Qnil;
+}
+    
+static long
+rotate_arg(argc, argv)
+    int argc;
+    VALUE *argv;
+{
+    long n = 1;
+
+    switch (argc) {
+      case 1:
+	n = NUM2LONG(argv[0]);
+      case 0:
+	break;
+      default:
+	rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
+    }
+
+    return n;
+}
+
+static VALUE
+rb_ary_rotate_bang(argc, argv, ary)
+    int argc;
+    VALUE *argv;
+    VALUE ary;
+{
+    long n = rotate_arg(argc, argv);
+
+    if (RARRAY(ary)->len <= 1) return Qnil;
+    return rb_ary_rotate(ary, n);
+}
+
+static VALUE
+rb_ary_rotate_m(argc, argv, ary)
+    int argc;
+    VALUE *argv;
+    VALUE ary;
+{
+    VALUE rotated;
+    VALUE *ptr = RARRAY(ary)->ptr;
+    long len = RARRAY(ary)->len;
+    long n = rotate_arg(argc, argv);
+
+    if (len > 1 && n != 0)
+	n = modulo_index(n, len);
+    else
+	n = 0;
+
+    rotated = rb_ary_new2(len);
+    DUPSETUP(rotated, ary);
+    RARRAY(rotated)->len = len;
+    len -= n;
+    MEMCPY(RARRAY(rotated)->ptr, ptr + n, VALUE, len);
+    MEMCPY(RARRAY(rotated)->ptr + len, ptr, VALUE, n);
+    return rotated;
+}
+
 int
 rb_cmpint(cmp)
@@ -1879,4 +1979,6 @@ Init_Array()
     rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0);
     rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0);
+    rb_define_method(rb_cArray, "rotate", rb_ary_rotate_m, -1);
+    rb_define_method(rb_cArray, "rotate!", rb_ary_rotate_bang, -1);
     rb_define_method(rb_cArray, "sort", rb_ary_sort, 0);
     rb_define_method(rb_cArray, "sort!", rb_ary_sort_bang, 0);


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread