diff --git a/posts/dyalog-apl-competition-2020.org b/posts/dyalog-apl-competition-2020.org index 1292f3e..5f7bd90 100644 --- a/posts/dyalog-apl-competition-2020.org +++ b/posts/dyalog-apl-competition-2020.org @@ -12,60 +12,182 @@ date: 2020-07-31 ** 1. Let's Split! +#+begin_quote +Write a function that, given a right argument ~Y~ which is a scalar or +a non-empty vector and a left argument ~X~ which is a single non-zero +integer so that its absolute value is less or equal to ~≢Y~, splits +~Y~ into a vector of two vectors according to ~X~, as follows: +- If ~X>0~, the first vector contains the first ~X~ elements of ~Y~ + and the second vector contains the remaining elements. +- If ~X<0~, the second vector contains the last ~|X~ elements of ~Y~ + and the first vector contains the remaining elements. +#+end_quote + #+begin_src default split←(0>⊣)⌽((⊂↑),(⊂↓)) #+end_src ** 2. Character Building +#+begin_quote +UTF-8 encodes Unicode characters using 1-4 integers for each +character. Dyalog APL includes a system function, ~⎕UCS~, that can +convert characters into integers and integers into characters. The +expression ~'UTF-8'∘⎕UCS~ converts between characters and UTF-8. + +Consider the following: + + #+begin_src default + 'UTF-8'∘⎕UCS 'D¥⍺⌊○9' +68 194 165 226 141 186 226 140 138 226 151 139 57 + 'UTF-8'∘⎕UCS 68 194 165 226 141 186 226 140 138 226 151 139 57 +D¥⍺⌊○9 + #+end_src + +How many integers does each character use? + + #+begin_src default + 'UTF-8'∘⎕UCS¨ 'D¥⍺⌊○9' ⍝ using ]Boxing on +┌──┬───────┬───────────┬───────────┬───────────┬──┐ +│68│194 165│226 141 186│226 140 138│226 151 139│57│ +└──┴───────┴───────────┴───────────┴───────────┴──┘ + #+end_src + +The rule is that an integer in the range 128 to 191 (inclusive) +continues the character of the previous integer (which may itself be a +continuation). With that in mind, write a function that, given a right +argument which is a simple integer vector representing valid UTF-8 +text, encloses each sequence of integers that represent a single +character, like the result of ~'UTF-8'∘⎕UCS¨'UTF-8'∘⎕UCS~ but does not +use any system functions (names beginning with ~⎕~) +#+end_quote + #+begin_src default characters←{(~⍵∊127+⍳64)⊂⍵} #+end_src ** 3. Excel-lent Columns +#+begin_quote +A Microsoft Excel spreadsheet numbers its rows counting up +from 1. However Excel's columns are labelled alphabetically — +beginning with A–Z, then AA–AZ, BA–BZ, up to ZA–ZZ, then AAA–AAZ and +so on. + +Write a function that, given a right argument which is a character +scalar or non-empty vector representing a valid character Excel column +identifier between A and XFD, returns the corresponding column number +#+end_quote + #+begin_src default columns←26⊥⎕A∘⍳ #+end_src ** 4. Take a Leap +#+begin_quote +Write a function that, given a right argument which is an integer +array of year numbers greater than or equal to 1752 and less than +4000, returns a result of the same shape as the right argument where 1 +indicates that the corresponding year is a leap year (0 otherwise). + +A leap year algorithm can be found [[https://en.wikipedia.org/wiki/Leap_year#Algorithm][here]]. +#+end_quote + #+begin_src default leap←1 3∊⍨(0+.=400 100 4∘.|⊢) #+end_src ** 5. Stepping in the Proper Direction +#+begin_quote +Write a function that, given a right argument of 2 integers, returns a +vector of the integers from the first element of the right argument to +the second, inclusively. +#+end_quote + #+begin_src default stepping←{(⊃⍵)+(-×-/⍵)×0,⍳|-/⍵} #+end_src ** 6. Please Move to the Front +#+begin_quote +Write a function that, given a right argument which is an integer +vector and a left argument which is an integer scalar, reorders the +right argument so any elements equal to the left argument come first +while all other elements keep their order. +#+end_quote + #+begin_src default movefront←{⍵[⍋⍺≠⍵]} #+end_src ** 7. See You in a Bit +#+begin_quote +A common technique for encoding a set of on/off states is to use a +value of $2^n$ for the state in position $n$ (origin 0), 1 if the +state is "on" or 0 for "off" and then add the values. Dyalog APL's +[[https://help.dyalog.com/17.1/#Language/APL%20Component%20Files/Component%20Files.htm#File_Access_Control][component file permission codes]] are an example of this. For example, +if you wanted to grant permissions for read (access code 1), append +(access code 8) and rename (access code 128) then the resulting code +would be 137 because that's 1 + 8 + 128. + +Write a function that, given a non-negative right argument which is an +integer scalar representing the encoded state and a left argument +which is an integer scalar representing the encoded state settings +that you want to query, returns 1 if all of the codes in the left +argument are found in the right argument (0 otherwise). +#+end_quote + #+begin_src default bits←{f←⍸∘⌽(2∘⊥⍣¯1)⋄∧/(f⍺)∊f⍵} #+end_src ** 8. Zigzag Numbers +#+begin_quote +A zigzag number is an integer in which the difference in magnitude of +each pair of consecutive digits alternates from positive to negative +or negative to positive. + +Write a function that takes a single integer greater than or equal to +100 and less than 10^{15} as its right argument and returns a 1 if the +integer is a zigzag number, 0 otherwise. +#+end_quote + #+begin_src default zigzag←∧/2=∘|2-/∘×2-/(10∘⊥⍣¯1) #+end_src ** 9. Rise and Fall +#+begin_quote +Write a function that, given a right argument which is an integer +scalar or vector, returns a 1 if the values of the right argument +conform to the following pattern (0 otherwise): + +- The elements increase or stay the same until the "apex" (highest + value) is reached +- After the apex, any remaining values decrease or remain the same +#+end_quote + #+begin_src default risefall←{∧/(⍳∘≢≡⍋)¨(⊂((⊢⍳⌈/)↑⊢),⍵),⊂⌽((⊢⍳⌈/)↓⊢),⍵} #+end_src ** 10. Stacking It Up +#+begin_quote +Write a function that takes as its right argument a vector of simple +arrays of rank 2 or less (scalar, vector, or matrix). Each simple +array will consist of either non-negative integers or printable ASCII +characters. The function must return a simple character array that +displays identically to what ~{⎕←⍵}¨~ displays when applied to the +right argument. +#+end_quote + #+begin_src default stacking←{↑⊃,/↓¨⍕¨⍵} #+end_src