:Namespace Contest2020 AboutMe←,⊂'I am a Data Scientist. Even if I do not use APL in my day job (except' AboutMe,←⊂'if you count Numpy), I dabbled in it for a few years for little' AboutMe,←⊂'one-liners. I picked up APL because I love learning new languages, and' AboutMe,←⊂'APL is a significantly different from any paradigm I tried before.' Reaction←,⊂'The challenges were super fun! This is by far the largest amount of' Reaction,←⊂'code in APL that I have written. In the process, I discovered many' Reaction,←⊂'aspects of APL I enjoy (the interactivity, natural data' Reaction,←⊂'manipulation). The challenges about data manipulation were great' Reaction,←⊂'(e.g. UPC). The challenges with complex computations (e.g. rates of' Reaction,←⊂'return) were excellent for learning APL and complex functions and' Reaction,←⊂'operators. The most difficult (or boring) part was everything related' Reaction,←⊂'to parsing and IO. Reading a file, interacting with the web, well,' Reaction,←⊂'it is not something APL was designed for, and you feel like fighting' Reaction,←⊂'the system.' :Namespace Problems (⎕IO ⎕ML ⎕WX)←1 1 3 ∇ score←dd DiveScore scores ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 1, Task 1 - DiveScore :If 7=≢scores scores←scores[¯2↓2↓⍋scores] :ElseIf 5=≢scores scores←scores[¯1↓1↓⍋scores] :Else scores←scores :EndIf score←2(⍎⍕)dd×+/scores ∇ ∇ steps←{p}Steps fromTo;segments;width ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 2, Task 1 - Steps width←|-/fromTo :If 0=⎕NC'p' ⍝ No left argument: same as Problem 5 of Phase I segments←0,⍳width :ElseIf p<0 ⍝ -⌊p is the number of equally-sized steps to take segments←(-⌊p){0,⍵×⍺÷⍨⍳⍺}width :ElseIf p>0 ⍝ p is the step size segments←p{⍵⌊⍺×0,⍳⌈⍵÷⍺}width :ElseIf p=0 ⍝ As if we took zero step segments←0 :EndIf ⍝ Take into account the start point and the direction. steps←fromTo{(⊃⍺)+(-×-/⍺)×⍵}segments ∇ ∇ urls←PastTasks url;r;paths ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 3, Task 1 - PastTasks r←HttpCommand.Get url paths←('[a-zA-Z0-9_/]+\.pdf'⎕S'&')r.Data urls←('https://www.dyalog.com/'∘,)¨paths ∇ ⍝ Test if a DNA string is a reverse palindrome. isrevp←{⍵≡⌽'TAGC'['ATCG'⍳⍵]} ⍝ Generate all subarrays (position, length) pairs, for ⍝ 4 ≤ length ≤ 12. subarrays←{⊃,/(⍳⍵),¨¨3↓¨⍳¨12⌊1+⍵-⍳⍵} ∇ r←revp dna;positions ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 4, Task 1 - revp positions←subarrays⍴dna ⍝ Filter subarrays which are reverse palindromes. r←↑({isrevp dna[¯1+⍵[1]+⍳⍵[2]]}¨positions)/positions ∇ ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 4, Task 2 - sset sset←{((1E6|2∘×)⍣⍵)1} ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 5, Task 1 - rr ⍝ First solution: ((1+⊢)⊥⊣) computes the total return ⍝ for a vector of amounts ⍺ and a vector of rates ⍝ ⍵. It is applied to every prefix subarray of amounts ⍝ and rates to get all intermediate values. However, ⍝ this has quadratic complexity. ⍝ rr←(,\⊣)((1+⊢)⊥⊣)¨(,\⊢) ⍝ Second solution: We want to be able to use the ⍝ recurrence relation (recur) and scan through the ⍝ vectors of amounts and rates, accumulating the total ⍝ value at every time step. However, APL evaluation is ⍝ right-associative, so a simple Scan ⍝ (recur\amounts,¨values) would not give the correct ⍝ result, since recur is not associative and we need ⍝ to evaluate it left-to-right. (In any case, in this ⍝ case, Scan would have quadratic complexity, so would ⍝ not bring any benefit over the previous solution.) ⍝ What we need is something akin to Haskell's scanl ⍝ function, which would evaluate left to right in O(n) ⍝ time. This is what we do here, accumulating values ⍝ from left to right. (This is inspired from ⍝ dfns.ascan, although heavily simplified.) rr←{recur←{⍵[1]+⍺×1+⍵[2]} ⋄ 1↓⌽⊃{(⊂(⊃⍵)recur⍺),⍵}/⌽⍺,¨⍵} ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 5, Task 2 - pv ⍝ Simply apply the formula for cashflow calculations. pv←{+/⍺÷×\1+⍵} ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 6, Task 1 - Merge ∇ val←ns getval var :If ''≡var ⍝ literal '@' val←'@' :ElseIf (⊂var)∊ns.⎕NL ¯2 val←⍕ns⍎var :Else val←'???' :EndIf ∇ ∇ text←templateFile Merge jsonFile;template;ns template←⊃⎕NGET templateFile 1 ns←⎕JSON⊃⎕NGET jsonFile ⍝ We use a simple regex search and replace on the ⍝ template. text←↑('@[a-zA-Z]*@'⎕R{ns getval ¯1↓1↓⍵.Match})template ∇ ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 7, Task 1 - CheckDigit CheckDigit←{10|-⍵+.×11⍴3 1} ⍝ Left and right representations of digits. Decoding ⍝ the binary representation from decimal is more ⍝ compact than writing everything explicitly. lrepr←⍉(7⍴2)⊤13 25 19 61 35 49 47 59 55 11 rrepr←~¨lrepr ∇ bits←WriteUPC digits;left;right ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 7, Task 2 - WriteUPC :If (11=≢digits)∧∧/digits∊0,⍳9 left←,lrepr[1+6↑digits;] right←,rrepr[1+6↓digits,CheckDigit digits;] bits←1 0 1,left,0 1 0 1 0,right,1 0 1 :Else bits←¯1 :EndIf ∇ ∇ digits←ReadUPC bits ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 7, Task 3 - ReadUPC :If 95≠⍴bits ⍝ incorrect number of bits digits←¯1 :Else ⍝ Test if the barcode was scanned right-to-left. :If 0=2|+/bits[3+⍳7] bits←⌽bits :EndIf digits←({¯1+lrepr⍳⍵}¨(7/⍳6)⊆42↑3↓bits),{¯1+rrepr⍳⍵}¨(7/⍳6)⊆¯42↑¯3↓bits :If ~∧/digits∊0,⍳9 ⍝ incorrect parity digits←¯1 :ElseIf (⊃⌽digits)≠CheckDigit ¯1↓digits ⍝ incorrect check digit digits←¯1 :EndIf :EndIf ∇ ∇ parts←Balance nums;subsets;partitions ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Problem 8, Task 1 - Balance ⍝ This is a brute force solution, running in ⍝ exponential time. We generate all the possible ⍝ partitions, filter out those which are not ⍝ balanced, and return the first matching one. There ⍝ are more advanced approach running in ⍝ pseudo-polynomial time (based on dynamic ⍝ programming, see the "Partition problem" Wikipedia ⍝ page), but they are not warranted here, as the ⍝ input size remains fairly small. ⍝ Generate all partitions of a vector of a given ⍝ size, as binary mask vectors. subsets←{1↓2⊥⍣¯1⍳2*⍵} ⍝ Keep only the subsets whose sum is exactly ⍝ (+/nums)÷2. partitions←nums{((2÷⍨+/⍺)=⍺+.×⍵)/⍵}subsets⍴nums :If 0=≢,partitions ⍝ If no partition satisfy the above ⍝ criterion, we return ⍬. parts←⍬ :Else ⍝ Otherwise, we return the first possible ⍝ partition. parts←nums{((⊂,(⊂~))⊃↓⍉⍵)/¨2⍴⊂⍺}partitions :EndIf ∇ ∇ weights←Weights filename;mobile;branches;mat ⍝ 2020 APL Problem Solving Competition Phase II ⍝ Stub function for Problem 9, Task 1 - Weights ⍝ Put your code and comments below here ⍝ Parse the mobile input file. mobile←↑⊃⎕NGET filename 1 branches←⍸mobile∊'┌┴┐' ⍝ TODO: Build the matrix of coefficients mat. ⍝ Solve the system of equations (arbitrarily setting ⍝ the first variable at 1 because the system is ⍝ overdetermined), then multiply the coefficients by ⍝ their least common multiple to get the smallest ⍝ integer weights. weights←((1∘,)×(∧/÷))mat[;1]⌹1↓[2]mat ∇ :EndNamespace :EndNamespace