« first day (1555 days earlier)      last day (1092 days later) » 

4:29 AM
CMC: Given a multi-line text (vector-of-vectors/matrix/linebreak-vector) with equally many words on each line, align spaces vertically:
Lorem ipsum dolor
sit amet consectetur
adipiscing elit sed
becomes
Lorem       ipsum dolor
sit         amet  consectetur
adipiscing  elit  sed
 
      ⊃,/,∘' '¨↑¨↓⍉↑' '(≠⊆⊢)¨'Lorem ipsum dolor' 'sit amet consectetur' 'adipiscing elit sed'
Lorem      ipsum dolor
sit        amet  consectetur
adipiscing elit  sed
 
      s←'Lorem ipsum dolor' 'sit amet consectetur' 'adipiscing elit sed' ⋄ ' (?! )'⎕R''⍤1⍕↑' '(≠⊆⊢)¨s
Lorem      ipsum dolor
sit        amet  consectetur
adipiscing elit  sed
Damn, regex replace is too long
J: ;:inv|:<"1@:>"1|:;:&>s
where s is a vector of boxed lines like 'Lorem ipsum dolor';'sit amet consectetur';'adipiscing elit sed'
 
 
2 hours later…
RGS
7:12 AM
@rak1507 For an overview of tradfns you can take a look at the appropriate MDAPL chapter: mastering.dyalog.com/User-Defined-Functions
 
7:24 AM
Or simply look at apl.wiki/tradfn
 
 
1 hour later…
8:28 AM
@Razetime Nice
 
9:24 AM
there are no dyalog webinars/baa meetings today right?
 
thanks
ooh, mandelbrot, cool
 
BAA's are every 2 weeks, and Dyalog's are every 4 weeks.
 
we need something else every 4 weeks to fill the remaining slot
 
RGS
@rak1507 Let me gain some momentum
I'd love to convince Dyalog to let me use that slot for smth cool :P
 
9:29 AM
haha I was joking but if you did actually do something that would be great
 
@RGS I don't think that'll be a problem. We did run webinars every 2 weeks last year.
 
RGS
@Adám Yeah I know, was just trying to distract ppl from the real reason I haven't done anything about it yet, which was the previous message, namely me needing more momentum :P
 
10:24 AM
I want to find if two strings of equal lengths overlap, ie the end of the first matches the beginning of the second by half the length or more, and if so, return the "merged" string:
    'ATTAGACCTG' mrg 'AGACCTGCCG'
ATTAGACCTGCCG
I have this, but I feel that it can be bettered:
mrg←{
    l←≢⍺
    h←⌊2÷⍨l
    pre←⍵∘{⍵↑⍺}¨h+⍳l-h
    suf←⍺∘{⍺↑⍨-⍵}¨h+⍳l-h
    m←⍸≡⌿↑suf pre
    ⍬≡m:⍬
    ⍺,⍵↑⍨≢pre⊃⍨⊃m
}
 
bettered in terms of speed?
{m←⍸(⌽¨,\⌽⍺)≡¨(,\⍵) ⋄ m≡⍬:⍬ ⋄ ⍺,m↓⍵} here's my attempt
your suffixes and prefixes can use ,\ instead which is probably faster, not that I've checked
 
10:50 AM
Nice! I was concerned with APL-ness, rather than speed, and yours sure qualify there :)
 
just noticed I don't need the brackets around (,\⍵)
 
11:03 AM
(note that neither mine nor rak's solutions check the "by half the length or more" part)
 
{merged←⍺,⍵↓⍨⊃⍸(⌽¨,\⌽⍺)≡¨,\⍵ ⋄ (≢merged)≤⌈1.5×≢⍵:merged ⋄ ⍬} length check + slightly different method
if there's no match, you can drop 0 from ⍵ and then the merged thing will just be ⍺,⍵
note this uses ⎕IO←1, convenience over principles :P
 
how come "123ABC"‿"ABC456" doesn't merge to 123ABC456?
 
oh, "by half the length or more" includes precisely half, but xpqz's original answer doesn't
 
ah, ok
 
11:13 AM
also there are more bugs
yours (and mine) still fail for 'AAAAAA' as both args
 
ah, ⊃⍸ should be ⊃⌽⍸
related CMC: given two strings, length not necessarily equal, return the shortest string s so that s starts with ⍺ and ends with ⍵
(or do you think this would make an ok codidact challenge?)
 
@rak1507 yeah
 
alright, no one answer :P
 
11:22 AM
@rak1507 more suggested tests - 'abcd', 'abcd' -> 'abcd'; '', '' -> ''
 
done, thanks
 
11:45 AM
@rak1507 {⍺,⍵↓⍨⌈/0,⍸(↑∘⍵≡-↑⍺⍨)¨⍳⍺⌊⍥≢⍵}
 
can you get any shorter?
 
Dunno. Can you?
 
yes
I have a 26
 
Same method?
Actually, do I really need to worry about which string is shorter?
 
not the same method
well, similar
 
11:50 AM
I think {⍺,⍵↓⍨⌈/0,⍸(↑∘⍵≡-↑⍺⍨)¨⍳≢⍵} works. And that's 26.
 
stupid method that fails if the input contains semicolons
 
you can knock two bytes off that fairly easily
@dzaima lol, cheating
 
@rak1507 {⍺,⍵↓⍨⊃⌽⍸(↑∘⍵≡-↑⍺⍨)¨⍳≢⍵}
 
yep
my 26 was {⍺,⍵↓⍨⊃⌽⍸≡⌿↑(⌽¨,\⌽⍺)(,\⍵)}
 
@Adám fails on 'abc ' f ' abc '
 
11:55 AM
:-(
So then I do need ⍺⌊⍥≢⍵
 
@dzaima will add that as a test case, thanks
 
@rak1507 i mean, it's pretty damn specific to APL and trying to use prototypes
 
@dzaima good point
 
Got dzaima's BQN one down to 23 but I'm suspecting that's not good enough.
 
@Marshall fails on "abc " F " abc "
 
So you have to use only the last ⌊○≠ diagonals. Even less competitive then.
 
 
2 hours later…
RGS
2:28 PM
@rak1507 Hm so people don't use codegolf.stackexchange anymore..?
 
they do, I just post all my questions on codidact to try and encourage some activity
 
RGS
@rak1507 is codidact discussed in some CG.SE meta conversation?
i.e. why do you want activity there? :)
 
a few people don't use cgse for various reasons, and codidact seems like a better platform
 
RGS
Alrighty, thanks for the short update. I haven't been golfing either way :P
Btw do we know about specific users at codidact that (probably) aren't @ CGSE?
↑ Marshall is one such person, right?
 
3:38 PM
With a 2D array, and a same size 2D array of scalar offsets, can I match them up row-wise so counters[offsets]+←1 but the first row of offsets are into the first row of counters, the second row of offsets are into the second row of counters, etc. Like combining [] with ⍤1 ?
 
RGS
@TessellatingHeckler Doesn't something like {⍵[⍺] +← 1}⍤1 work?
 
can you give an example?
 
@RGS That looks like it will work, it also looks like it will apply a function lots of times, I was trying to get to a bulk-array-transform
 
RGS
@TessellatingHeckler It felt like you wanted it to happen in that specific way, as you asked "can I match them up row-wise"
 
please give an example I have absolutely no idea what you mean
 
RGS
3:46 PM
But I can try to come up w/ smth more clever if we see what the final thing you want to happen is
 
yes, so it's a character counter. e.g. `counter←0 0 0 0 0` counts 'a' in first position, 'b' in second position, 'c' in third position. Then:

⎕io←0
counter←0 0 0 0 0
counter[¯97+⎕ucs'acae']+←1
counter
┌→────────┐
│2 0 1 0 1│
└~────────┘
 
RGS
@TessellatingHeckler But the point is that you have 2 matrices of those?
 
ok forget the code formatting
and I want to do that with counter←2 5⍴0 and words←↑'acae' 'cbee'
except 25,000 words
 
RGS
So you want to count the number of letters a matrix of words uses?
(Row-wise)
 
⍉+/'abcde'∘.=words if that's your actual problem and not a fake example
 
RGS
3:53 PM
+← 1
 
yeah not sure if you want chars←∪,⍵ and chars in place of 'abcde'
 
Hello
 
@rak1507 That looks much more APL-y and appropriate
 
@Adám are you saying to use ⌸ here somehow or is ⌸ meant to be an emoji (or something else entirely)
 
Use
 
3:57 PM
how?
 
the problem with the "X,Y problem" is that the thing I'm curious about is "can indexing work this way using [;] or ⍤ or ⌷", rather than "can someone else solve the problem in a completely different way"
like, it works in a 1D array for multiple indexing, it feels like it should generalise to 2D without having to make lots of nested (0 1) (0 2) (0 3) pairs of indices.
 
@TessellatingHeckler You should be able to use scatter indexing.
Yeah, unfortunately, massive arrays of multi-dimensional indices are expensive.
 
RGS
@TessellatingHeckler Well I already solved it with ⍤ but you "complained" that f⍤1 would apply f many times – which is true, regardless of whether f is a dfn I wrote or a primitive.
 
@RGS Except primitive⍤1 might well be optimised.
 
RGS
So I just didn't understand the spirit of your question :)
 
4:02 PM
@rak1507 ¯1+{≢⍵}⌸⍤1⊢'abcde',⍤1⊢words
(Always annoying how doesn't let you choose an order.)
 
is that any faster?
 
No, this is sad:
      ]runtime -c "¯1+{≢⍵}⌸⍤1⊢'abcde',⍤1⊢words" "⍉+/'abcde'∘.=words"

  ¯1+{≢⍵}⌸⍤1⊢'abcde',⍤1⊢words → 3.5E¯3 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
  ⍉+/'abcde'∘.=words          → 1.2E¯4 | -97% ⎕
 
oh, why use ⌸ then
 
In general, it is faster, but probably not when repeated on tiny arguments like this.
 
ah
 
4:06 PM
Interesting:
      words←'abcde'[?25000 5⍴5]
      ]runtime -c "⍉+/'abcde'∘.=words" "+/[2]words∘.='abcde'"

  ⍉+/'abcde'∘.=words   → 1.1E¯4 |    0% ⎕⎕⎕⎕
  +/[2]words∘.='abcde' → 1.0E¯3 | +853% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕
 
⌷⍤0 99⍤1 does the trick for multidimensional indexing I think @TessellatingHeckler
 
But you probably can't use that for modified assignment.
 
oh, true
 
↑ is there an implementation of this spec?
 
I don't think so.
 
4:13 PM
sad, I saw it on the fibonacci question and thought it existed :(
 
@rak1507 doesn't seem to give results I can make sense of
 
      ⍉+/'abcde' ∘.= ↑'acae' 'cbee'
2 0 1 0 1
0 1 1 0 2
 
gah, I've been forgetting ↑ in my tests
ok yes that's it
that is significantly faster!
 unscramble←{
     words←⊃⎕NGET'd:/downloads/nine_letter_words.txt' 1
     alph←'abcdefghijklmnopqrstuvwxyz'
     wordcounts←⍉+/alph∘.=↑words
     words/⍨wordcounts≡⍤1⊢(+/alph∘.=⍵)
 }
takes ~12ms to load and check the 25,000 words. My first version with sort¨ to put them all in alphabetical order was around 80ms.
 
4:29 PM
Btw, for next time, so you don't have to bother typing it out, use ⎕C⎕A
 
@Adám What is scatter indexing?
 
array[(indexA)(indexB)]
 
unscramble←{
primes←2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101
words←↑⊃⎕NGET'd:/downloads/nine_letter_words.txt' 1
primify←{×/primes[⎕A⍳1⎕C⍵]}
words⌿⍨words=⍥primify⊢⍵
}
@TessellatingHeckler just for fun can you try this?
(note: I don't know if this works, can't test locally for obvious reasons)
 
@Adám Good suggestion; it takes most of my concentration to get an array answer to work at all, I don't have many braincells spare for other ways of doing things.
@rak1507 I will try it; it's this wordlist ( raw.githubusercontent.com/dolph/dictionary/master/enable1.txt ) and I filtered 9 letter words out and saved them to a separate file.
 
thanks
 
4:41 PM
      ]runtime -compare 'rak ''stepdmaes''' 'unscramble ''stepdmaes'''
┌→─────────────────────────────────────────────────────────────────────────────────┐
↓                                                                                  │
│  rak 'stepdmaes'        → 8.1E¯3 |   0% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕           │
│* unscramble 'stepdmaes' → 1.1E¯2 | +33% ⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕⎕ │
└──────────────────────────────────────────────────────────────────────────────────┘
 
stampedes :)
 
:) and 'stepdames', apparently
 
not high enough probability to be in my list of memorised anagrams for scrabble
 
That appears to work, and is very fast. I wrote a version in APL which does sort¨ on the wordlist and it ran in 80ms. I wrote a comparable one in Rust (as a novice) using Vec<u8>.Sort() and it ran in 22ms, and there's about a 10ms process start penalty on Windows. I rewrote the Rust one to use something like this - indexing into vectors for counting, and it runs in ~17-20ms. Handwaving a lot for measurement error and process start time, your code is neck and neck.
 
replacing = with ∊ in mine, you can pass it a matrix like ↑'stepdmaes' 'aasvgoels' and it will return a matrix of the words, although with no separation to determine which word corresponds to which anagrams
 
4:48 PM
@rak1507 I am not that aggressive with Scrabble, I think if I started studying it my parents would refuse to play our weekend games, and that would be sad :)
 
haha, my parents stopped playing with me long ago
passing a word list in as the left argument you can go tacit like this
primes←2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101
primify←{×/primes[⎕A⍳1 ⎕C ⍵]}
unscramble←∊⍥primify⊢⍤⌿⊣
would be even nicer if you didn't have to do the ⊢⍤⌿ hack
 
I have some vague idea that the primes are there because multiplying them in different combinations will never produce a clash (if a=1, b=2, and you sum them, you can't distinguish 1x'b' from 2x'a').
might it be cheaper to lowercase 26 letters in ⎕A once, instead of uppercasing 250,000 letters in the wordlist?
 
yep, exactly, it's a rudimentary 'hash' in a sense
@TessellatingHeckler lol, good point, yeah probably
 
that must mean "no multiple of 37 will ever be a multiple of 3"?
guess that's what it means to be prime
 
@TessellatingHeckler well 3×37 is a multiple of 3 lol
 
4:59 PM
uh, then how do you distinguish 37x'B' from 3x'L' ? [or, uhhhh, 5x'B' from 3x'C' which might happen in 9 letters]
 
RGS
@TessellatingHeckler You encode the quantities in the exponents
(2*a)×(3*b)×(5*c)...
e.g. abca is 60
because 60=4×3×5
 
yeah, 2×3×5×2
 
RGS
@rak1507 no power of 37 will ever be a multiple of 3
 
@RGS yeah
 
RGS
maths, baby (☞゚ヮ゚)☞
 
5:06 PM
also this method not only makes it easy to recognise anagrams, but also subanagrams
 
RGS
@rak1507 You mean by checking divisibility?
 
yep
 
@RGS that is an idea; if we had the quantities of each letter as input, we wouldn't need this?
 
RGS
@TessellatingHeckler not sure if you were asking me smth? If you were, I didn't get it.
 
I know that apps often use tries for this but I wonder if this method would work better.. obviously the numbers would get pretty large, 15 Zs would be 101*15
there would probably be potential clashes with floating point :/
 
5:10 PM
@RGS started out trying to count the quantities of each letter as the goal; if this needs to know the quantities of each letter to use them as exponents, there's not much need to do the exponentiation, if we have the counts we can compare the counts.
 
this doesn't need to know the counts in that it doesn't calculate them separately
 
And the question mark was to make it less statement and not criticism, but just thinking aloud
 
it maps each letter to a prime and takes the product, which is the same as using counts as exponents, but without actually calculating counts
 
RGS
↑ @rak1507 's point is a fine one, you can map each letter to its prime and then multiply everything, you don't need to figure out the actual counts.
 
one benefit is you then get word -> scalar, rather than word -> vector, which then makes comparing easier I assume
 
RGS
5:12 PM
I just tried to make more explicit that the counts are then encoded in the exponents of the primes
 
@rak1507 aren't we then back to the risk of aaa being (prime 2)x(3 times) = 6, and bb being (prime 3)x(2 times) also = 6 and matching as the same word?
 
RGS
@TessellatingHeckler no
aaa maps to 2 × 2 × 2 which is 2*3
      ×/(2 3 5 7)[⎕A⍳'BB']
9

      ×/(2 3 5 7)[⎕A⍳'AAA']
8
 
because (2) (3 times) isn't (2 times 3) :facepalm:
 
RGS
Your "(prime 2)×(3 times)" really means "prime 2 showed up 3 times" and to avoid clashes, you multiply all the primes together.
 
RGS
5:18 PM
:)
Yup, 2 showing up thrice in a multiplication gives 2 to the power of 3
 
:)
must try this approach in Rust later
 
 
2 hours later…
RGS
7:08 PM
I just love APL.
Was trying to solve one of this year's competition problems, and this one in particular is quite a classical algorithmic problem, and I spent some time there thinking how I'd go about solving that, because the only thing that popped to mind was the classical solution you are taught in CS courses.
And I wanted to go for something a bit more array-oriented. My solution isn't perfect, but I'm just so proud of what I wrote :P
 
 
2 hours later…
8:55 PM
interesting, don't suppose you can say which one it was? I assume it was lcsq
 
9:09 PM
@TessellatingHeckler (I did; then pre-computing the prime-hashes, sorting into order, inlining them in the source code so the program is just one calculation of the scrambled word and a binary_search lookup, is tremendously fast, at the cost of 3min compile time)
 
:D offloading your computation to compile time - best optimisation trick in the book!
 
 
2 hours later…
RGS
11:25 PM
@rak1507 It was the LCSQ one, yes. I guess I can say it because my msg gave nothing away about the program I wrote :P
 
interesting, I've struggled finding a good solution for that, have to try harder :P
 
RGS
@rak1507 Recall that I didn't say my solution was good, I just said I was happy about it.
 
haha
 
RGS
:)
 

« first day (1555 days earlier)      last day (1092 days later) »