Skip to content

Instantly share code, notes, and snippets.

@rodrigogiraoserrao
Last active August 6, 2020 15:32
Show Gist options
  • Save rodrigogiraoserrao/aa060988925754356166d76904823c7b to your computer and use it in GitHub Desktop.
Save rodrigogiraoserrao/aa060988925754356166d76904823c7b to your computer and use it in GitHub Desktop.
RGS's solution for Problem 4, Phase 2 of 2020 APL competition (see https://mathspp.com/blog/2020-apl-competition for my thoughts on it)
PROBLEM 4.1
revp {
(⎕IO ⎕ML ⎕WX) 0 1 3
Find reverse palindromes of lengths between 4 and 12 in a DNA character vector.
Monadic function expecting a character vector.
A substring is a reverse palindrome if the substring is equal to its reverse complement.
The complement of a DNA string changes these pairs: 'A'←→'T', 'C'←→'G'.
Returns a 2 column integer matrix as if ⎕IO←1
(+1 0) 4 12 _revp
}
_revp {
(⎕IO ⎕ML ⎕WX) 0 1 3
General form of the `revp` function.
Dyadic function expecting length delimiters on the left.
The results of this function are ⎕IO dependant.
1,
(m M)
dna
C (('ACTG'1 0)4|2+'ACTG') complementing can be seen as (+2) mod 4 if we index wisely.
and C dna
l dna
s 1+l-m the indices at which the possible revps start
ls m+1+M-m admissible lengths for the revps we care about
r ,s ., ls complete table of possible final results
is ,s .(+) ls sets of indices for the possible revps
is is / bl>/is remove sets that have indices too large; we first mix ↑ because the padding 0s won't change the result.
c.f. https://chat.stackexchange.com/transcript/message/54445629#54445629
r br remove the corresponding final results
r /(is 0 1dna) = (is ()0 1and)
}
PROBLEM 4.2
sset {
(⎕IO ⎕ML ⎕WX) 0 1 3
Compute the number of subsets you can make out of a set with size ⍵ (mod 10*6).
Monadic function expecting an integer.
This number is 2*⍵; to build any subset, for any element in the set either include it or not;
These 2 choices over the ⍵ elements give a total of 2*⍵ subsets.
Returns an integer.
0=: 1
1000000 PowerMod 2
}
PowerMod {
(⎕IO ⎕ML ⎕WX) 0 1 3
Computes big powers under a given modulus.
Dyadic function expecting two integers on the right and one integer on the left.
For integers (a b)←⍵ computes a*b mod ⍺.
For that, we decompose b to binary and use repeated squaring.
Returns an integer.
(base exp)
0=exp: 1
m
bin 2¯1 exp
l bin
powers l {l: ,m|2*¯1} base extend the vector of powers to include all (base*2*k) needed.
{m|×}/ bin/powers
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment