Quicksort in Q/KDB+ - kdb

I found this quicksort implementation on a website:
q:{$[2>distinct x;x;raze q each x where each not scan x < rand x]};
I don't understand this part:
raze q each x where each not scan x < rand x
Can someone explain it to me step by step?

Lets do it step by step . I assume you have basic understanding of Quick Sort algo. Also, there is one correction in code you mentioned which I have corrected in step 5.
Example list:
q)x: 1 0 5 4 3
Take a random element from list which will act as pivot.
q) rand x
Suppose it gives us '4' from list.
Split list 'x' in 2 lists. One contains elements lesser that '4' and other greater(or equal) to '4'.
2.a) First compare all elements with pivot (4 in our case)
q) (x<rand x) / 11001b : output is boolean list
2.b) Using above boolean list we can get all elements from 'x' lesser than '4'. Here is the way:
q) x where 11001b / ( 1 0 3) : output
So we require other expression to get all elements greater(or equal) than pivot '4'. There are many ways to do it
but lets see the one used in code:
q)not scan (x<rand x) / (11001b;00110b) : output
So it gives the list which has 2 lists. First is result of (x < rand x) which is used to get elements lesser than pivot '4' and other is negation of this list which is done by 'not' and it is used to get all elements greater(or equal) that pivot '4'.
2.c) So now we can generate 2 lists using sample code from (2.b)
q) x where each (not scan (x<rand x)) / ((1 0 3);(5 4)): output list which has 2 lists
Now apply same function to each list to sort each of them
i.e. recursive call on each list of list ((1 0 3);(5 4))
q) q each x where each (not scan (x<rand x))
After all calculations , apply 'raze' to flatten all lists that are returned from each recursive call to output one single list.
End condition for recursive call is: when input list has only 1 distinct element just return it.
q) 2>count distinct x
Note: There is one correction. 'count' was missing in original code.

Related

kdb: can the $ function take 5 arguments?

From https://code.kx.com/q/wp/parse-trees/#the-solution
I came across below function, which translates enlisted symbols or symbol lists into the string "enlist".
ereptest:{ //returns a boolean
(1=count x) and ((0=type x) and 11=type first x) or 11=type x}
ereplace:{"enlist",.Q.s1 first x}
funcEn:{$[ereptest x;ereplace x;0=type x;.z.s each x;x]} <<<<<
In last line, it seems $ is applied to 5 arguments, but this page shows $ is of rank 2 or 3. What am I missing here?
From the kx wiki
Odd number of expressions
For brevity, nested triads can be flattened.
$[q;a;r;b;c] <=> $[q;a;$[r;b;c]]
These two expressions are equivalent:
$[0;a;r;b;c]
$[r;b;c]

how to concate list of strings by element

I have two lists for example:
x:("AA","BB","CC")
y:("1","2","3")
I would like to target the concatenation of both lists element wise as below:
z = ("AA1","BB2","CC3")
I have tried the following which only works if the lists have one string:
(x,y)
Use eachboth adverb which takes one element from each list at a time and perform operation.
Also change comma to semicolon in your x and y list to get list with 3 items.
q) x:("AA";"BB";"CC")
q) y:("1";"2";"3")
q) x,'y
Output:
("AA1";"BB2";"CC3")

Unable to pass multiple arguments to each function in kdb

How do i passed 2 variables to a lambda function, where x is a number and y is a symbol.
I have written this, but it wouldn't process
{[x;y]
// some calculation with x and y
}
each ((til 5) ,\:/: `a`b`c`d`f)
It seems to be complaining that i am missing another arg.
Here's an example that I think does what you're looking for:
q){string[x],string y}./: raze (til 5) ,\:/: `a`b`c`d`f
The issue with your example is that you need to raze the output of ((til 5) ,\:/: `a`b`c`d`f) to get your list of 2 inputs.
Passing a list of variables into a function is accomplished using "." (dot apply) http://code.kx.com/q/ref/unclassified/#apply
.e.g
q){x+y} . 10 2
12
In my example, I've then used an "each right" to then apply to each pair. http://code.kx.com/q/ref/adverbs/#each-right
Alternatively, you could use the each instead if you wrapped the function in another lamda
q){{string[x],string y} . x} each raze (til 5) ,\:/: `a`b`c`d`f
Instead of generating a list of arguments using cross or ",/:\:" and passing each of these into your function, modify your function with each left each right ("/:\:") to give you all combination. his should take the format;
x f/:\: y
Where x and y are both lists. Reusing the example {string[x],string y};
til[5] {string[x], string y}/:\:`a`b`c`d
This will give you a matrix of all combinations of x and y. If you want to flatten that list add a 'raze'

KDB+/Q: About unused parameters in inner functions

I have this function f
f:{{z+x*y}[x]/[y]}
I am able to call f without a 3rd parameter and I get that, but how is the inner {z+x*y} able to complete without a third parameter?
kdb will assume, if given a single list to a function which takes two parameters, that you want the first one to be x and the remainder to be y (within the context of over and scan, not in general). For example:
q){x+y}/[1;2 3 4]
10
can also be achieved by:
q){x+y}/[1 2 3 4]
10
This is likely what's happening in your example.
EDIT:
In particular, you would use this function like
q){{z+x*y}[x]/[y]}[2;3 4 5 6]
56
which is equivalent to (due to the projection of x):
q){y+2*x}/[3 4 5 6]
56
which is equivalent to (due to my original point above):
q){y+2*x}/[3;4 5 6]
56
Which explains why the "third" parameter wasn't needed
You need to understand 2 things: 'over' behavior with dyadic functions and projection.
1. Understand how over/scan works on dyadic function:
http://code.kx.com/q/ref/adverbs/#over
If you have a list like (x1,x2,x3) and funtion 'f' then
f/(x1,x2,x3) ~ f[ f[x1;x2];x3]
So in every iteration it takes one element from list which will be 'y' and result from last iteration will be 'x'. Except in first iteration where first element will be 'x' and second 'y'.
Ex:
q) f:{x*y} / call with -> f/ (4 5 6)
first iteration : x=4, y=5, result=20
second iteration: x=20, y=6, result=120
2. Projection:
Lets take an example funtion f3 which takes 3 parameters:
q) f3:{[a;b;c] a+b+c}
now we can project it to f2 by fixing (passing) one parameter
q) f2:f3[4] / which means=> f2={[b;c] 4+b+c}
so f2 is dyadic now- it accepts only 2 parameters.
So now coming to your example and applying above 2 concepts, inner function will eventually become dyadic because of projection and then finally 'over' function works on this new dyadic function.
We can rewrite the function as :
f:{
f3:{z+x*y};
f2:f3[x];
f2/y
}

predicate encode in prolog

I'm new in prolog and I'm trying to write the predicate encode(L,L1) which counts the duplicates of elements in L ,for example:
encode([4,4,4,3,3],L).
L=[3,4,2,3].
This is what I have written:
encode(L,L1) :- encode(L,1,L1).
encode([],_,[]).
encode([H],N,[N,H]).
encode([H,H|T],N1,[N,H|T1]) :- M is N1+1, encode([H|T],M,[N,H|T1]).
encode([H,Y|T],N,[N,H|T1]) :- H\=Y, encode([Y|T],T1).
The above predicate is not reversible. It only works if the first parameter is provided.
How can I write encode reversible?
For example:
encode(L,[3,4,2,3]).
L = [4,4,4,3,3].
I think your algorithm has a redundant counter in it. A little simplified would be:
encoded([], []).
encoded([X], [1,X]).
encoded([X,Y|T], [1,X|R]) :-
dif(X, Y),
encoded([Y|T], R).
encoded([X,X|T], [N,X|R]) :-
N #> 1,
N #= N1 + 1,
encoded([X|T], [N1,X|R]).
Note in the last clause we need to ensure that N is greater than 1 as well.