Skip to content

Instantly share code, notes, and snippets.

@saweiss
Created August 9, 2020 17:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saweiss/2e134bff9539e17ad4d6dbde58ada219 to your computer and use it in GitHub Desktop.
Save saweiss/2e134bff9539e17ad4d6dbde58ada219 to your computer and use it in GitHub Desktop.
Dyalog APL Contest 2020 solutions as submitted by Sam Weiss
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←↑((⊢⍴⍨(×/⍴))~((⊂' '⍴⍨(⍴⊃))))∘(↓(↑⍕¨))
: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