@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
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
}
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 ?
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 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.
@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.
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
@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 :)
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?
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 :/
@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.
@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?
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
@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)