~pmikkelsen/dyalog-competition-2022

8df5d5a902b81fb00126fe7d7c8530cea61ed50d — Peter Mikkelsen 2 years ago
Initial commit
3 files changed, 71 insertions(+), 0 deletions(-)

A base85.apln
A reshape.apln
A subspace.apln
A  => base85.apln +31 -0
@@ 1,31 @@
:Namespace base85
    ∇ result←variant Base85 data
      ;chunksizeFrom;chunksizeTo;fill;transform;nchunks;extra
      ;coded;baseFrom;baseTo;preProcess;postProcess;⎕IO
      ⍝ We use ⎕IO zero since the range of input data starts at zero.
     
      ⍝ The idea is that encoding and decoding follows the same pattern
      ⍝ of padding the data, changing base, and removing extra elements
      ⍝ from the end. Thus we just set the few things that differ inside
      ⍝ an :If :Else block.
      ⎕IO←0
      preProcess←⊢ ⍝ Pre-processing of a chunk before base change
      postProcess←⊢ ⍝ Post-processing of a chunk after base change
      :If ' '=⊃0⍴data
          (chunksizeFrom chunksizeTo baseFrom baseTo fill)←5 4 85 256(⊃⌽variant)
          data←(data∊variant)⌿data ⍝ Remove items from data, which are not in variant
          preProcess←⍳
      :Else
          (chunksizeFrom chunksizeTo baseFrom baseTo fill)←4 5 256 85 0
          postProcess←{⍺[⍵]}
      :EndIf
     
      ⍝ We now define the function which encodes/decodes one chunk of data
      transform←⊣postProcess(chunksizeTo⍴baseTo)⊤baseFrom⊥preProcess
      nchunks←⌈chunksizeFrom÷⍨≢data
      extra←(chunksizeFrom×nchunks)-≢data
      data←nchunks chunksizeFrom⍴data,extra⍴fill ⍝ The data is padded
      coded←,variant transform⍤1⊢data ⍝ Each chunk is transformed and the result is combined
      result←(-extra)↓coded ⍝ Extra elements are removed from the end again
:EndNamespace

A  => reshape.apln +11 -0
@@ 1,11 @@
:Namespace reshape
      reshape←{
          data←(|⍺)⍴⍵
          rotations←∊⍸,⊖⍺<0
          ⊃{⊖⍤⍺⊢⍵}⌿rotations,⊂data
      }
      reshape2←{
          (dims data)←⍺ process ⍵
          dims reshape data
      }
:EndNamespace

A  => subspace.apln +29 -0
@@ 1,29 @@
:Namespace subspace
    ⍝ the runs and fill functions do almost the same thing,
    ⍝ except that they combine the subspaces differently,
    ⍝ and that runs isn't expected to handle multi-dimensional left arguments.
    ⍝ This is modelled by a helper operator 'createsubspaces' 
    ⍝ with ⍺⍺ as the combine function
      runs←{
          combine←{∨⌿⍵}
          ⍺ combine createsubspaces ⍵
      }
      fill←{
          combine←{⌈⌿(⍳≢⍵)(×⍤0 ¯1)⍵}
          ⍺ combine createsubspaces ⍵
      }
      createsubspaces←{
          ⍝ Create one subspace for each row, then combine them using ⍺⍺
          createsubspace←{
              newshape←2,2÷⍨⍴⍵
              (start size)←↓newshape⍴⍵
              (⍳⍺)∊¯1+start(+⍤1 0)⍳size
          }
          ⍺⍺ ⍺∘createsubspace⍤1⊢⍵
      }
      subspaces←{
          count←⌈⌿,⍵
          subspace←(⊃,1+⌽-⍥⊃⊢)⍸⍤⍷⍨
          ↑⍵∘subspace¨⍳count
      }
:EndNamespace