Created
August 9, 2020 17:18
-
-
Save saweiss/2e134bff9539e17ad4d6dbde58ada219 to your computer and use it in GitHub Desktop.
Dyalog APL Contest 2020 solutions as submitted by Sam Weiss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
P1←(1≠(×⊣))⌽↑{⊆⍺⍵}↓ | |
P2←(128∘>∨191∘<)⊂⊢ | |
P3←26⊥⎕A∘⍳ | |
P4←≠⌿0=400 100 4∘.|⊢ | |
P5←⊢{⍵,⍵-(××⍳∘|)-/⍺}⊃ | |
P6←(⊣(⌿⍨)(+⌿=))⍪~⍨ | |
P7←{⍺=2⊥∧/(2∘⊥⍣¯1)⍺⍵} | |
P8←¯1∧.=2×/(×2-/10∘⊥⍣¯1) | |
P9←{1∧.=≢∘∪¨⊆⍨2@(¯1∘=)×0~⍨(+\⍣¯1)⍵} | |
P10←↑((⊢⍴⍨(×/⍴))~((⊂' '⍴⍨(⍴⊃))))∘(↓(↑⍕¨)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:Namespace Contest2020 | |
⍝ === VARIABLES === | |
L←⎕av[3+⎕io] | |
AboutMe←L,'' | |
FilePath←'' | |
Reaction←L,'' | |
⎕ex 'L' | |
⍝ === End of variables definition === | |
(⎕IO ⎕ML ⎕WX)←1 1 3 | |
:Namespace Problems | |
(⎕IO ⎕ML ⎕WX)←1 1 3 | |
∇ parts←Balance nums;n;K;T;P;S;i;j;H | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 8, Task 1 - Balance | |
⍝ Put your code and comments below here | |
⍝ NOTE: I wasn't sure if ⎕IO could be used in the competition, so the | |
⍝ comments use 0-based indexing and the code uses 1-based. | |
T←+/nums | |
⍝ Return ⍬ if the sum of nums is odd; can't split evenly. | |
:If 2∘|T | |
parts←⍬ | |
:Else | |
n←≢nums | |
K←T÷2 | |
⍝ Boolean table where each column, j, represents the first j | |
⍝ elements of nums, where j is in range [0,n] (empty set is 0). | |
⍝ Each row, i, represents the ith partial sum in range [0,K]. | |
⍝ Let P[i;j] be 1 if a subset of the jth subset sums to i. | |
⍝ Otherwise, P[i;j] is 0. Initialize the top row to 1 because | |
⍝ the null set is a subset of all sets, and it sums to 0. | |
P←((1⍴⍨1∘+)⍪0⍴⍨(K,1∘+))n | |
⍝ Store the parent of P[i;j]'s row index, i-nums[j], in S[i;j] if | |
⍝ the last element of the jth subset was included in the sum to i. | |
S←(1∘+K n)⍴⍬ | |
:For i j :In 1∘+⍳K n | |
⍝ A smaller subset that excludes j already sums to i. | |
:If P[i;j]←P[i;j-1] | |
⍝ Can't sum to i if j is larger. | |
:ElseIf i>nums[j-1] | |
⍝ Including nums[j] in the sum to i compares the same as | |
⍝ excluding nums[j] and summing to i-nums[j]. | |
:AndIf P[i;j]←P[i-nums[j-1];j-1] | |
S[i;j]←(i-nums[j-1]) | |
:EndIf | |
:EndFor | |
i←1+K | |
H←⍬ | |
⍝ From the last element of S, traverse backwards and collect the | |
⍝ columns that contain parents pointers which directly produced the | |
⍝ last element of S. Theses columns correspond to the indexes of | |
⍝ nums which make up one element of parts. | |
:For j :In ⌽1+⍳n | |
:If (i∘≠∧0∘≠)S[i;j] | |
H,←j-1 | |
i←S[i;j] | |
:EndIf | |
:EndFor | |
⍝ If the last value of P is 1, then split nums by equal sums. | |
⍝ Otherwise, nums can't be split evenly, so return ⍬. | |
parts←{P[1+K;1+n]:⊆nums[H](nums[H~⍨⍳n]) ⋄ ⍬}⍬ | |
:EndIf | |
∇ | |
CheckDigit←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 7, Tasl 1 - CheckDigit | |
⍝ Put your code and comments below here | |
⍝ Given an array of 11 UPC-A digits, compute the check digit. | |
⍝ | |
⍝ Starting at the right, label digits alternately odd and even. | |
⍝ multiply odd digits by 3 and even digits by 1. Sum all resulting | |
⍝ numbers. The distance from this sum to the next highest multiple | |
⍝ of 10 is the check digit. If the sum is a multiple of 10, then | |
⍝ the check digit is 0, i.e., 0 numbers away from a multiple of 10. | |
10|10-10|⍵+.×11⍴3 1 | |
} | |
DiveScore←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 1, Task 1 - DiveScore | |
⍝ Put your code and comments below here | |
⍝ ⍺: Single degree of dificulty (⍺ > 1). | |
⍝ ⍵: Two or more judges' scores, each in range [0,10]. | |
⍝ Calculate the diving score to at most 2 decimal places. | |
⍝ | |
⍝ Throw out all but the three median judges' scores. The remaining | |
⍝ scores are summed and multiplied by the degree of dificultly. | |
⍎2⍕⍺×+/(¯1+⌊2÷⍨≢⍵){(-⍺)↓⍺↓⍵[⍋⍵]}⍵ | |
} | |
∇ text←templateFile Merge jsonFile;t;m;n;v;z;s;q;i;j | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 6, Task 1 - Merge | |
⍝ Put your code and comments below here | |
⍝ Read in the template and json files. | |
(t m)←⊃∘⎕NGET¨templateFile jsonFile | |
⍝ Convert the JSON into a namespace. | |
n←⎕JSON m | |
⍝ Get the variable names in the namespace. | |
v←n.⎕NL ¯2 | |
⍝ Get the corresponding namespace variable values, prepend @. | |
z←(⊂'@'),n⍎¨v | |
⍝ Prepend a blank corresponding to @, then surround each with @. | |
v←(1⌽'@@'∘,)¨(⊂''),v | |
⍝ Partition the template so merge areas are in their own boxes. | |
s←t⊆⍨{(⍳≢⍵)/⍨⍵+1 ¯1⍴⍨≢⍵}≢¨⊂⍨'@'=t | |
⍝ Find merge areas that are missing from the JSON file. | |
q←v~⍨{⍵/⍨'@'∊¨⍵}∪s | |
⍝ Prepend the missing merge area names to the existing ones. | |
v,⍨←q | |
⍝ For each missing merge area, prepend ??? to the replacements. | |
z,⍨←(≢q)⍴⊂'???' | |
⍝ Replace each merge area with its corresponding replacement. | |
:For i j :InEach v z | |
s←((⊂j)@{(⊂i)⍷s})s | |
:EndFor | |
⍝ Reassemble into a single character vector. | |
text←⊃,/s | |
∇ | |
PastTasks←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 3, Task 1 - PastTasks | |
⍝ Put your code and comments below here | |
⍝ Get the HTML from the given URL and convert to matrix form. | |
w←⎕XML(#.HttpCommand.Get ⍵).Data | |
⍝ Find the indexes of the ⍺ string in the ⍵ list of strings. | |
f←{(⊂,⍺)⍸⍤⍷⍵} | |
⍝ Filter the attributes column by the 'a' and 'base' elements. | |
(a b)←{⍵[⍺ f ⍵[;2];4]}∘w¨'a' 'base' | |
⍝ Filter the value column by 'href' for all attributes. | |
(h j)←{⊃¨'href'∘{⍵[⍺ f ⍵[;1];2]}¨⍵}¨a b | |
⍝ Filter 'a' element attribute values by the PDF file ending. | |
p←h[1+('.pdf'⎕S 2)h] | |
⍝ Attach the URL base to each relative URL. | |
j,¨p | |
} | |
ReadUPC←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 7, Task 3 - ReadUPC | |
⍝ Put your code and comments below here | |
⍝ Ensure the input contains 95 bits | |
95≠≢⍵:¯1 | |
⍝ Split up the 7 bit arrays by left and right sides (drop padding). | |
B←{⍉6 7⍴⍵[⍺+⍳42]} | |
U←B∘⍵¨3 50 | |
⍝ Ensure one side has even parity and the other has odd. | |
D←∧/¨2|¨+⌿¨U | |
⍲/0 1∊D:¯1 | |
⍝ Put odd parity matrix on left side and match the parities. | |
U←↑,/(~@1)(⌽∘(⌽∘⊖¨)⍣(¯1=×-/D))U | |
⍝ Even parity barcode digits 0-9 converted to decimal then ASCII. | |
DG←'rflB\NPDHt' | |
⍝ Convert from binary to decimal according to conversion table. | |
R←¯1+DG⍳⎕UCS 2⊥U | |
⍝ Ensure the check digit is valid. | |
(¯1↑R)≠CheckDigit ¯1↓R:¯1 | |
R | |
} | |
Steps←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 2, Task 1 - Steps | |
⍝ Put your code and comments below here | |
⍝ No ⍺ is the same as a step size of 1. | |
⍺←1 | |
⍝ The first endpoint. | |
f←⊃⍵ | |
⍝ No steps is just the first endpoint because no steps were made. | |
0≡⍺:f | |
⍝ Indexes from 1 to |∘⊢ all times the sign of ⊢. | |
j←(××⍳∘|)⊢ | |
⍝ Positive ⍺ gives the step size from ⍵[1] to ⍵[2], the endpoints. | |
⍝ Truncate the last step size if ⍺ doesn't divided evenly into the | |
⍝ the absolute diffence between the endpoints. | |
1≡×⍺:∪1⌽(⌽⍵),f-⍺×j⌊-/⍵÷⍺ | |
⍝ Negative ⍺'s floor magnitude gives the number of equally sized | |
⍝ steps to take between the endpoints. | |
f,f-⍵((-/÷)×j)|⌊⍺ | |
} | |
∇ weights←Weights filename;m;k;x;y;v;a;q;b;j;e;c;l;u;d;p;t;n;o;f;s;i;r;h | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 9, Task 1 - Weights | |
⍝ Put your code and comments below here | |
⍝ Read the mobile diagram into a character matrix. | |
m←↑⊃⎕NGET filename 1 | |
⍝ Sort ascending. | |
k←{⍵[⍋⍵]} | |
⍝ Sort ascending by columns. | |
x←{⌽¨k⌽¨⍵} | |
⍝ Append the first of ⍺ to the difference between the last ⍺ and ⍵. | |
y←{(⊃⍺),⍵-⍥(1∘↓)⍺} | |
⍝ Get the indexes of each vector of ⍺ in vector of vectors ⍵. | |
v←{⍵∘{⊃(⊂⍵)⍸⍤⍷⍺}¨⍺} | |
⍝ Get the indexes of each letter in alphabetical order. | |
a←⍸27≠⎕A∘⍳m | |
⍝ Get the indexes of all turning points. | |
q←⍸('┐'∘=∨'┌'∘=)m | |
⍝ Get the indexes of all fulcrums. | |
b←'┴'⍸⍤=m | |
⍝ Reshape 'a' so a single row can be taken from it. | |
a←{(1,⍴⍵)⍴⍵}a | |
:Repeat | |
⍝ Get the last row of 'a'. | |
e←{(¯1↑⍴⍵)⍴⍵}¯1↑[1]a | |
⍝ Place turning point indexes next to fulcrums/letters below them. | |
c←x∪q,e | |
⍝ Check for any that reached the parent fulcrum. | |
u←b[1]≡¨e | |
⍝ Climb the tree if not already at the top. | |
d←c[¯1+u+e v c] | |
a⍪←d | |
⍝ Place fulcrum indexes next to their related turning points. | |
p←k∪b,d | |
⍝ Get each turning point direction; ¯1 for left and 1 for right. | |
t←¯2+'┐ ┌'⍳m[d] | |
⍝ Traverse the tree from the turning points to fulcrums. | |
n←p[(t×~u)+d v p] | |
a⍪←n | |
⍝ Stop when the last row of 'a' contains only the parent fulcrum. | |
:Until b[1]∧.≡n | |
⍝ Drop the locations of the letters. | |
a←1↓[1]a | |
⍝ Get the signs of the last turns made by each letter. | |
j←1,⍨¨{1=≢b:1 1 ⋄ ⊃-/{∨⌿b[⍺]⍷⍵}∘⍵¨2 3}a | |
⍝ Apply the signs in 'j' to the rows of 'a' except ¯1 stays 1. | |
a←1@{0,⍨¯1=⊃⍵}¨↑(⊂j)×↓a | |
⍝ Substract pairs of tree rows, keeping the first values the same. | |
a←{,⌿y/¨⍵⊆[1]⍨2/⍳2÷⍨≢⍵}a | |
⍝ Get the unique tree row numbers. | |
o←∪⊃¨⊃,/a | |
⍝ Group each column by tree row numbers, then get just the columns. | |
⍝ The result is a matrix for of the needed system of equations. | |
f←↑{2⊃¨⊃¨(~∘(⊃⍵,./⍨⍺{⍺≠⊃⍵}¨¨⍵))¨⍵}∘a¨o | |
⍝ Scale a vector by its GCD. | |
s←⊢÷∨/ | |
⍝ Generate an identity matrix of the given size. | |
i←∘.=⍨⍳ | |
⍝ Compute a right inverse of the given non-square matrix. | |
r←⍉+.×(⌹⊢+.×⍉) | |
⍝ Compute the smallest nontrivial integer solution to the given | |
⍝ singular homogeneous integer coefficient system. | |
h←s(+/i∘(1↓⍴)-r+.×⊢) | |
weights←h f | |
∇ | |
WriteUPC←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 7, Task 2 - WriteUPC | |
⍝ Put your code and comments below here | |
⍝ Ensure input length is exactly 11. | |
11≠≢⍵:¯1 | |
⍝ Ensure input contains only single digits. | |
~∧/⍵∊¯1+⍳10:¯1 | |
⍝ Convert decimal to binary. | |
DB←2∘⊥⍣¯1 | |
⍝ Beginning and ending digits. | |
BE←DB 5 | |
⍝ Middle digits. | |
MD←0,BE,0 | |
⍝ Even parity barcode digits 0-9 converted to decimal then ASCII. | |
DG←'rflB\NPDHt' | |
⍝ Convert input to bit array (tacking the check digit on the end). | |
TD←,⍉DB ⎕UCS DG[1+⍵,CheckDigit ⍵] | |
⍝ Negate left bits for parity, and insert start, middle, end bits. | |
42{↑,/BE(~⍺↑⍵)MD(⍺↓⍵)BE}TD | |
} | |
pv←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 5, Task 2 - pv | |
⍝ Put your code and comments below here | |
⍝ Given an ⍺ of cash flows and an ⍵ of corresponding interest | |
⍝ rates, compute the present value. | |
⍝ | |
⍝ The present value is the dot product between the current values | |
⍝ and the reciprocal of 1 + the cumulative interest rates. | |
⍺+.÷×\1+⍵ | |
} | |
revp←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 4, Task 1 - revp | |
⍝ Put your code and comments below here | |
⍝ Complement pairs AT and CG are equidistant from the space. | |
d←'AC GT' | |
⍝ Replace complements by equal and opposite integers. | |
e←¯3+d⍳⍵ | |
⍝ Table of indexes up to ⍺ with a sliding ⍵-width window. | |
i←{↑⍵,/⍳⍺} | |
⍝ Moving width index tables for widths in range [4,12]. | |
m←(≢⍵)i¨2+2×⍳5 | |
⍝ Tables of complement numbers for each window width. | |
n←e∘(⊣⌷⍨∘⊂)¨m | |
⍝ Location and length pairs for each reverse palindrome. | |
↑↑,/(((⍸(∧/0∘=)),¨¯1∘↑∘⍴)(⊢+⌽))¨n | |
} | |
rr←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 5, Task 1 - rr | |
⍝ Put your code and comments below here | |
⍝ Given an ⍺ of cash flows and an ⍵ of corresponding interest | |
⍝ rates, compute the future values for each (⍺[i],⍵[i]) pair. | |
⍝ | |
⍝ The previous results are appended to the current result | |
⍝ at each step of the reduction. | |
1↓⌽⊃{⍵,⍨⊃⍺+⊃⍵×1+1↓⍺}/⌽⍺,¨⍵ | |
} | |
sset←{ | |
⍝ 2020 APL Problem Solving Competition Phase II | |
⍝ Stub function for Problem 4, Task 2 - sset | |
⍝ Put your code and comments below here | |
⍺←2 | |
m←1000000∘| | |
⍝ Compute 2*⍵ (mod 1e6) using the right-to-left binary method. | |
⍝ NOTE: Conversion of ⍵ to binary is implicit. Normally, one | |
⍝ would expect that ⍵ must be converted with (2∘⊥⍣¯1), but | |
⍝ in this specific case, it works without it. Bug or feature? | |
(≢⍵)=≢⍺:m⍤×/⍵/⍺ ⋄ (⍺,⍨m2*⍨1↑⍺)∇ ⍵ | |
} | |
u←(⊂¯1 0)∘+ | |
:EndNamespace | |
:EndNamespace |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment