Something for the weekend?

https://learninghub.kx.com/forums/topic/something-for-the-weekend

A challenge for the weekend? Something from the Vector D?j?

A single-expression function to replace multiple embedded spaces in a string with single spaces. E.g.

 

q)rmeb “the quick brown fox” “the quick brown fox”

 

If you find yourself writing a loop, you’re on the wrong track. This is not a golfing challenge, but my best lambda is 26 chars.

Extra kudos Find the fastest expression on a million-char string.

Even more kudos To avoid typing it so often, you have a general filter function f:{y where x@y}. Define rmeb as a projection of f, using a composition as the left argument.

Hint: there is a faster test than x=" " or null x.

A surprise? Char is a sortable type and Less Than is as fast as Equals and faster than Not Equals.

q)ts:100000 “quick brown fox”>" "

13 752

q)ts:100000 “quick brown fox”<>" "

27 880

q)ts:100000 “quick brown fox”=" "

13 752

q)ts:100000 not"quick brown fox"=" "

23 864

 

{x where not(&‘:)" "=x} / 23 chars and fast f[not(&’:)" "=] / as a projection

 

One thing to consider is that the seed value for the derived function means any leading blanks will be removed. Can use prev

q){x where not(&':)" "=x}s:" the quick brown fox " 
"the quick brown fox " 
q){x where not n&prev n:null x}s 
" the quick brown fox "

 

Masking is nice but as an alternative & still taking care not to remove leading blanks

q){x where 1b,1_not" “~':x}s:” the quick brown fox " " the quick brown fox "

Appears to be faster

q)S:10000000#s 
q)ts:5 {x where not n&prev n:null x}S 
197 100663904 
q)ts:5 {x where 1b,1_not" "~':x}S 
147 83886816

caching taking place?

q)ts:5 {x where not n&prev n:null x}S 
144 100663904 
q)ts:5 {x where 1b,1_not" "~':x}S 
148 83886816