Page 2 of 3
Re: interleave/join strings
Posted: Sun Jan 15, 2017 3:41 pm
by Morten|Dyalog
Interesting...
Code: Select all
txt1←12345⍴,¨'this' 'is' 'a' 'sentence' ⍝ all vectors
txt2←12345⍴ 'this' 'is' 'a' 'sentence' ⍝ a scalar in the middle
cmpx '↑txt1' '↑txt2'
↑txt1 → 1.2E¯4 | 0% ⎕⎕
↑txt2 → 1.9E¯3 | +1508% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕...
And so:
Code: Select all
5↑txt←12345⍴,¨'this' 'is' 'a' 'sentence'
this is a sentence this
cmpx '⊃,/'' '',¨txt' '∊'' '',¨txt' '{n←1+≢¨⍵ ⋄ (,n∘.≥⍳⌈/n)/,'' '',↑⍵}txt'
⊃,/' ',¨txt → 2.5E¯3 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
∊' ',¨txt → 2.9E¯3 | +12% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
{n←1+≢¨⍵ ⋄ (,n∘.≥⍳⌈/n)/,' ',↑⍵}txt → 5.8E¯4 | -78% ⎕⎕⎕⎕
Vintage algorithms rock! (in this case, probably not after Roger discovers what is going on)...
Re: interleave/join strings
Posted: Sun Jan 15, 2017 4:12 pm
by Roger|Dyalog
It does not surprise me that Morten's third expression,
{n←1+≢¨⍵ ⋄ (,n∘.≥⍳⌈/n)/,' ',↑⍵}txt
is the fastest because ⍺/⍵ and ↑⍵ have been targeted by recent implementation effort whereas ∊⍵ and ,/ have not. In addition to what Dyalog will do, I myself will try to reward expressions which are either "elegant" or most apt for a task. Clearly ∊⍵ is the one in this case.
A consideration in speeding up ∊⍵ is to make faster the case where the items of ⍵ are uniform (as here where each item is a string) without measurably slowing down the general case where ⍵ contains all manner of stuff.
Re: interleave/join strings
Posted: Sun Jan 15, 2017 4:35 pm
by Roger|Dyalog
The prospective work on ∊⍵ is an illustration of what separates a mathematican from the rest. To a mathematican, writing extra code for ∊⍵ when there is already code for the general case, is an unnatural act. I am not a mathematician.
(In case there is any doubt, the above is written in jest.)
Re: interleave/join strings
Posted: Sun Jan 15, 2017 6:35 pm
by alexeyv
Wow, thanks for all the responses!
Out of all proposed versions I couldn't understand the ones with
.
Could someone explain how it works? I'm starring at this code almost an hour already ;(
Re: interleave/join strings
Posted: Sun Jan 15, 2017 7:21 pm
by Veli-Matti
That symbol resembling the ö character is the rank operator, pretty powerful and unique tool.
The expression
⍺,⍤0⊢⍵
is equivalent to
⍺(,⍤0)⍵
where the left argument is catenated to each 0-cell (element) of the right argument.
More - and better - explanations can be found in the DyalogAPL documentation.
Happy exploring!
-wm
Re: interleave/join strings
Posted: Mon Jan 16, 2017 4:05 pm
by jGoff
⍝The very laziest among us might choose to go with monadic format
]display ⍕'this' 'is' 'a' 'test'
┌→────────────────┐
│ this is a test │
└─────────────────┘
⍝and then perhaps ∇dxb "Drop eXtraneous Blanks" from the dfns library
]display dxb ⍕'this' 'is' 'a' 'test'
┌→─────────────┐
│this is a test│
└──────────────┘
Re: interleave/join strings
Posted: Mon Jan 16, 2017 5:11 pm
by Roger|Dyalog
Re using ⍕: this can fail if an item of the argument has blanks.
Re: interleave/join strings
Posted: Mon Jan 16, 2017 8:35 pm
by Veli-Matti
Just for amusement:
S←12345⍴'this' 'is' 'a' 'sentence'
↑,/((1+≢S)⌊⍋⍋(¯1+2×≢S)⍴0 1)⊃¨⊂S,' ' → 1.0E¯3 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
1↓↑,/,' ',⍤0⊢S → 1.0E¯3 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
{(' '=↑⍵)↓(2⍲/(' '=⍵),1)/⍵}⍕S → 2.7E¯3 | +161% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
1↓(,n∘.≥⍳⌈/n←1+≢¨S)/,' ',⊃S → 2.6E¯3 | +148% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
S←12345⍴'this' 'is' 'another' 'one'
↑,/((1+≢S)⌊⍋⍋(¯1+2×≢S)⍴0 1)⊃¨⊂S,' ' → 1.1E¯3 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
1↓↑,/,' ',⍤0⊢S → 1.1E¯3 | 0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
{(' '=↑⍵)↓(2⍲/(' '=⍵),1)/⍵}⍕S → 3.2E¯3 | +193% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
1↓(,n∘.≥⍳⌈/n←1+≢¨S)/,' ',⊃S → 7.2E¯4 | -35% ⎕⎕⎕⎕⎕⎕⎕⎕⎕
Vintage solutions are worth revisiting
-wm
Re: interleave/join strings
Posted: Tue Jan 17, 2017 7:42 pm
by jGoff
Re: using "dxb ⍕" can fail if an item of the argument has blanks.
To my mind, that all the algorithms use a ' ' delimiter seems to imply that the argument items are not expected to have embedded blanks. With "⍕" it's true that you are stuck with blanks as delimiters between items, but if that's okay then it offers a terse, readable solution.
My critique of my own lazyman's solution to the original problem is that once one resorts to a library dfn, then it should be the correct one. "vtol" is a better choice because it is a single function that will do everything. No need for "⍕".
Also, if you don't want "vtol" hanging around your workspace you can simply adapt the underlying code for your purposes. In this case, " ↑,/⍵,¨⊂⍺ " is a strong response to alexeyv's original "interleave/join strings" question.
Re: interleave/join strings
Posted: Tue Jan 17, 2017 10:40 pm
by jGoff
This post was written as a revision to my last post. Now that I realize that an author can edit his own post, I have done that. (Thanks Vince.)
I have also tried to delete this post, but the forum software won't accept an empty post and I cannot find the "Delete" button.