⍝ -*- mode:dyalog -*-
vin{
    ⎕IO0
    C(⊢,10 0 9,⊢)2+⍳7
    check(⎕D,'X')11|C+/⍤×10|(⎕D,' ',⎕A/⍨(3@17)(2@8)261)⍳⊢
    ~∧⎕D,⎕A~'IOQ':¯1 ⍝ Case: invalid charset
    16=≢⍵:(check x)@8x((2@8)161)/
    17=≢⍵:⍵[8]=check 
    ¯1 ⍝ Case: invalid length
}

⍝⎕←vin vin'1M8GDM9AKP042788'
⍝⎕←vin¨'5GZCZ43D13S812715' 'SGZCZ43D13S812715'

sortVersions{
    ⎕IO1
    V{2'.'⎕VFI}@3¨'-'(~⊆⊢)¨
    ⍝ Yes, grade works on nested array too
    [V]
}

⍝⎕←sortVersions'a-b-1.2.1' 'a-b-1.2.10' 'a-b-1.2.2'
⍝pkgs←⎕JSON⊃⎕NGET'pkgs.json'
⍝⎕←sortVersions'a-b-1.2.3-test' 'a-b-1.2.3-prod' 'a-c-1.2.3-dev' 'a-b-1.2.3-dev'
⍝⎕←⍪sortVersions,pkgs

⍝ An obviously correct brutal force method is:
⍙makeChange{⎕IO0  M⌿⍨=+.×M⌽⍉B⊤⍳×B1+⌽⌊÷}
⍝ Using  i←B⊤n  to exhaustive search the combination.
⍝ The initial  B  is  1+⌊⍵÷⍺  which sets the upper
⍝ bound of each type of currency.
⍝ However, the upper bounds for  i  can
⍝ shrink as  i  increases. To ensure the
⍝ algorithm terminates, B  needs to be
⍝ recomputed after each time  i  changes, but
⍝ that is only necessary when the sum of  i
⍝ is bigger than  A .
⍝ We could also fast forward the last digit when
⍝ the sum is less than  A  instead
⍝ of test out every combination.
⍝ BENCHMARK:
⍝ Using structured programming keywords
⍝ can enhance performance compared to old school
⍝  →  based control flow.
⍝ Unfortunately, compiling this function would
⍝ compromise its performance.
⍝ TRIVIA:
⍝ A few thing I tried but didn't work:
⍝ This seems to be similar to knapsack problem,
⍝ however, since the goal is to list all
⍝ combinations instead of optimizing, the
⍝ various related algorithms just won't apply.

⍝ I have heard dfs works well for this problem
⍝ but to be honest I never had the idea
⍝ of using dfs in APL.

⍝ I worried that my algorithm would
⍝ be less efficient when the  denom  would
⍝ be co-prime to each others. Since the
⍝ it is much less likely to be the case of
⍝ currency amount, I stopped worry about
⍝ optimization for this, but still paid some
⍝ attention to correctness on this case.

⍝ I did some test to show the above issue:
⍝ euro makeChange 200  would need 147080 iterations
⍝ for 73682 results.
⍝ euro makeChange 100  needs 9084 for 4563 results.
⍝ 3 7 9 11 12 makeChange 100  needs 2254 iterations
⍝ for only 346 result.

⍝ Feedback:
⍝ The drafting version I had has more overlapping
⍝ conditions, redundant safe guards and variables.
⍝ Still, I think doing the prototype in other
⍝ non-array languages would be more difficult.
⍝ By working in the mindset of equation
⍝ rewriting approach, I derived an optimized
⍝ answer from the brutal forced search algorithm.
RW makeChange A;B;O;i;t
 WW ⍝ Reversed denom
 R00,≢W ⍝ Result
 O⎕io+¯1+≢W ⍝ lowest digit
 i1-≢W ⍝ i: search index
 :Repeat
     tW+.×i
     :If t<A ⍝ Fast forward
         i[O]+(A-t)÷⊢/W
     :Else
         :If t=A  Ri  :EndIf
         ⍝ Shrink the search bound
         iBB(¯1i),⊢/B1+0⌈⌈W÷A-0,+\¯1W×i
     :EndIf
 :Until t=0 ⍝ i overflows
 RR

euro1 2 5 10 20 50 100 200 500 1000 5000 10000 20000
usa1 5 10 25 50 100 500 1000 2000 5000 10000
⍝⎕←≢usa makeChange 132
⍝⎕←≢usa makeChange 200
⍝ Requires about 0.6 secs
⍝⎕←≢euro makeChange 200
⍝a←euro makeChange 60
⍝b←euro ⍙makeChange 60
⍝⎕←a≡b
⍝⎕←3 7 9 11 12 makeChange 40
⍝⎕←3 7 9 11 12 ⍙makeChange 40

partition{
    ⎕IO1
    M11⊃, ⍝ move
    C1≢⍴ ⍝ coordinates
    _'←,⍺',(≢,)'S' '(S M)' '(S M C)'
    SS,1C-S ⍝ window size rank padding
    MM,1C-M ⍝ movement rank padding
    MSS-1+⍴ ⍝ shape mask to remove stencil padding
    MM,⊃∘.(C-1)(⊢↑⊢,0)¨MS¨1¨M ⍝ move/start mask
    MM/({,0=}S(⍤/⍥,){}S) ⍝ select subarray
}

⍝⎕←3 partition 5 5⍴⎕A
⍝⎕←(2 2)(2 3)partition 5 5⍴⎕A
⍝⎕←(3 2)(2 1)(2 2 2)partition 4 5 6⍴⍳120
⍝⎕←⍴¨1partition⍳5