Count a streak of numbers with a reset?

Hello,

I’d like to count rows with like sided numbers in a row and then if there’s an opposite side reset the count.

q)t:(number:“I”$())

number    streak

2                 1

3                 2

4                 3

-2                1

-7                2

1                 1

4                 2

2                 3 

Thanks, All

q)select number,streak:{1+(x;0)y}[1;differ signum number] from tab

number streak


2      1

3      2

4      3

-2     1

-7     2

1      1

4      2

2      3

Cheers, Thanks Terry

Very nice!<o:p></o:p>

<o:p> </o:p>

Added to the qidioms page, where all good concise code deserves to be: http://code.kx.com/wiki/Qidioms#q_idioms<o:p></o:p>

<o:p> </o:p>

From: personal-kdbplus@googlegroups.com [mailto:personal-kdbplus@googlegroups.com] On Behalf Of Terry Lynch
Sent: Friday, August 14, 2015 11:52 AM
To: Kdb+ Personal Developers
Subject: Re: [personal kdb+] Count a streak of numbers with a reset?<o:p></o:p>

<o:p> </o:p>

q)select number,streak:{1+(x;0)y}[1;differ signum number] from tab<o:p></o:p>

number streak<o:p></o:p>

-------------<o:p></o:p>

2      1<o:p></o:p>

3      2<o:p></o:p>

4      3<o:p></o:p>

-2     1<o:p></o:p>

-7     2<o:p></o:p>

1      1<o:p></o:p>

4      2<o:p></o:p>

2      3<o:p></o:p>

<o:p> </o:p>

On Fri, Aug 14, 2015 at 2:00 PM, Roni Hoffman <hoffmanroni@gmail.com> wrote:<o:p></o:p>

Hello,<o:p></o:p>

<o:p> </o:p>

I’d like to count rows with like sided numbers in a row and then if there’s an opposite side reset the count.<o:p></o:p>

<o:p> </o:p>

q)t:(number:“I”$())<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

number    streak<o:p></o:p>

2                 1<o:p></o:p>

3                 2<o:p></o:p>

4                 3<o:p></o:p>

-2                1<o:p></o:p>

-7                2<o:p></o:p>

1                 1<o:p></o:p>

4                 2<o:p></o:p>

2                 3 <o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

Thanks, All<o:p></o:p>

<o:p> </o:p>


Submitted via Google Groups

Thanks David!

In fact, I think “differ x>0” achieves the same thing as “differ signum x” (with less work) so this would be slightly better

select number,streak:{1+(x;0)y}[1;differ number>0] from tab

Terry

<0a6f01d0d6c7$a60a6740$f21f35c0$@aquaq.co.uk> To: Terry Lynch , Kdb+ Personal Developers
It depends on he wants to treat 0 - should that=E2=80=8E reset the count or have it continue the previous series or have it increase? Or does 0 not appear in the dataset?

From: Terry Lynch
Sent: Friday, August 14, 2015 13:00
To: Kdb+ Personal Developers
Reply To: personal-kdbplus@googlegroups.com
Subject: Re: FW: [personal kdb+] Count a streak of numbers with a reset?

Thanks David!

In fact, I think "differ x>0" achieves the same thing as "differ signum x" (with less work) so this would be slightly better

select number,streak:{1+(x;0)y}\[1;differ number>0] from tab

Terry


Another option, certainly not as elegant as Terry’s response, but figured it was worthwhile sharing for performance purposes:

(assumes no nulls, but can be easily modified to get around that)

q)\S 10

q)n:-5+(`int$1e7)?10

q)\ts {1+(x;0)y}[1;differ signum n]

6334 378104240

q)\ts raze sums each not null where[differ signum n] cut n

3796 474005520

Here’s another one: 

q)\ts a:{1+(x;0)y}[1;differ signum n]                                                                                                                

3677 445213216

q)\ts b:{1+t - maxs (t:til count x)*differ signum x}n                                                                                                 

181 536871520

q)a~b                                                                                                                                                 

1b

Jonny

Good logic.

Nice one Jonny, this is the optimal solution.

However, it’s great and all that but I’m afraid to say I’ve got you beat :)

q)\ts b:{1+t - maxs (t:til count x)*differ signum x}n

200 536871520

q)k)\ts c:{1+t-|(t:!#x)*~~':(x>0)-x<0}n

199 536871520

/Thread closed/

I bow to your superiority Terry!

Sent from my iPhone