[#4766] Wiki — "Glen Stampoultzis" <trinexus@...>

21 messages 2000/09/04
[#4768] RE: Wiki — "NAKAMURA, Hiroshi" <nahi@...> 2000/09/04

Hi, Glen,

[#4783] Re: Wiki — Masatoshi SEKI <m_seki@...> 2000/09/04

[#4785] Re: Wiki — "NAKAMURA, Hiroshi" <nakahiro@...> 2000/09/05

Howdy,

[#4883] Re-binding a block — Dave Thomas <Dave@...>

16 messages 2000/09/12

[#4930] Perl 6 rumblings -- RFC 225 (v1) Data: Superpositions — Conrad Schneiker <schneik@...>

Hi,

11 messages 2000/09/15

[#4936] Ruby Book Eng. translation editor's questions — Jon Babcock <jon@...>

20 messages 2000/09/16

[#5045] Proposal: Add constants to Math — Robert Feldt <feldt@...>

15 messages 2000/09/21

[#5077] Crazy idea? infix method calls — hal9000@...

This is a generalization of the "in" operator idea which I

17 messages 2000/09/22

[#5157] Compile Problem with 1.6.1 — Scott Billings <aerogems@...>

When I try to compile Ruby 1.6.1, I get the following error:

15 messages 2000/09/27

[ruby-talk:5173] Re: methods w/ ! giving nil

From: Davide Marchignoli <marchign@...>
Date: 2000-09-28 12:32:09 UTC
List: ruby-talk #5173
> Actually Ruby does have its own qsort routine in C (in util.c), which
> is compatible with original qsort(3).  Only problem left is re-design
> and hack the routine.   I'm afraid it's a tough task, for me at least.

Changing swap does not work since swap can be invoked also for equal
values and it one has to be careful in defining if the list is changed or
not. The only other solution (I can think of) is checking if the array is
already sorted. The check is already present in the ruby_sort code so this
small change does not affect performances.

In any case, the *average* cost of checking if an array is sorted is a
*small* constant number of comparisons.

The following patch should do the job:


for util.h:
--------------------------------
39c39
< void ruby_qsort _((void*, int, int, int (*)()));
---
> int ruby_qsort _((void*, int, int, int (*)()));
--------------------------------

for util.c:
--------------------------------
617c617,618
< void ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp)();
---
> int ruby_qsort (base, nel, size, cmp)
> void* base; int nel; int size; int (*cmp)();
619,620c620,621
<  register char *l, *r, *m;          	/* l,r:left,right group   m:median point */
<  register int  t, eq_l, eq_r;       	/* eq_l: all items in left group are equal to S */
---
>  register char *l, *r, *m;          	/* l,r,m: left,right,median point */
>  register int  t, eq_l, eq_r;    /* eq_l: items in left group are equal to S */
623c624
<  int  chklim = 63;                      /* threshold of ordering element check */
---
>  int  chkord = 1;                       /* check ordering of elements */
626c627
<  if (nel <= 1) return;        /* need not to sort */
---
>  if (nel <= 1) return 1;                /* need not to sort */
627a629,631
>  if (nel == 2) {
>    if ((*cmp)(L,R) > 0) {mmswap(L,R); return 0;} else return 1;
>  }
631c635
<  if (stack == top) return;    /* return if stack is empty */
---
>  if (stack == top) return 0;            /* return if stack is empty */
636c640,641
<    if (L + size == R) {if ((*cmp)(L,R) > 0) mmswap(L,R); goto nxt;}/* 2 elements */
---
>    if (L + size == R)                   /* 2 elements */
>      {if ((*cmp)(L,R) > 0) mmswap(L,R); goto nxt;}
665,682c670
<    if ((t = (*cmp)(l,m)) < 0) {                             /*3-5-?*/
<      if ((t = (*cmp)(m,r)) < 0) {                           /*3-5-7*/
<        if (chklim && nel >= chklim) {   /* check if already ascending order */
<          char *p;
<          chklim = 0;
<          for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) > 0) goto fail;
<          goto nxt;
<        }
<        fail: goto loopA;                                    /*3-5-7*/
<      }
<      if (t > 0) {
<        if ((*cmp)(l,r) <= 0) {mmswap(m,r); goto loopA;}     /*3-5-4*/
<        mmrot3(r,m,l); goto loopA;                           /*3-5-2*/
<      }
<      goto loopB;                                            /*3-5-5*/
<    }
<    
<    if (t > 0) {                                             /*7-5-?*/
---
>    if ((t = (*cmp)(l,m)) > 0) {                             /*7-5-?*/
684c672
<        if (chklim && nel >= chklim) {   /* check if already ascending order */
---
>        if (chkord) {   /* check if already descending order */
686,687c674,675
<          chklim = 0;
<          for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) < 0) goto fail2;
---
>          chkord = 0;
>          for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) < 0) goto fail;
691c679
<        fail2: mmswap(l,r); goto loopA;                      /*7-5-3*/
---
>        fail: mmswap(l,r); goto loopA;                       /*7-5-3*/
698a687,704
> 
>    if (t < 0) {                                             /*3-5-?*/
>      if ((t = (*cmp)(m,r)) > 0) {
>        if ((*cmp)(l,r) <= 0) {mmswap(m,r); goto loopA;}     /*3-5-4*/
>        mmrot3(r,m,l); goto loopA;                           /*3-5-2*/
>      }
>      if (chkord) {   /* check if already ascending order */
>        char *p;
>        chkord = 0;
>        for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) > 0) goto fail2;
>        if ((l == base) && (r == (char *)base + size*(nel - 1)))
> 	 return 1;
>        goto nxt;
>      }
>    fail2:
>      if (t < 0) goto loopA;                                 /*3-5-7*/
>      goto loopB;                                            /*3-5-5*/
>    }   
700,701c706,716
<    if ((t = (*cmp)(m,r)) < 0)  {goto loopA;}                /*5-5-7*/
<    if (t > 0) {mmswap(l,r); goto loopB;}                    /*5-5-3*/
---
>    if ((t = (*cmp)(m,r)) > 0) {mmswap(l,r); goto loopB;}    /*5-5-3*/
>    if (chkord) {   /* check if already ascending order */
>      char *p;
>      chkord = 0;
>      for (p=l; p<r; p+=size) if ((*cmp)(p,p+size) > 0) goto fail3;
>      if ((l == base) && (r == (char *)base + size*(nel - 1)))
>        return 1;
>      goto nxt;
>    }
>  fail3:
>    if (t < 0)  {goto loopA;}                                /*5-5-7*/
711c726
<    loopA: eq_l = 1; eq_r = 1;  /* splitting type A */ /* left <= median < right */
---
>    loopA: eq_l = 1; eq_r = 1;  /* splitting type A: left <= median < right */
730c745
<    loopB: eq_l = 1; eq_r = 1;  /* splitting type B */ /* left < median <= right */
---
>    loopB: eq_l = 1; eq_r = 1;  /* splitting type B: left < median <= right */
----------------------------------------

Best Regards,

						Davide


In This Thread

Prev Next