Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write {(+/3<?⍵⍴6)×100÷⍵}1000 tacitly

Inspired by some Conor Hoekstra YouTube videos, I tried doing some baby steps in APL and also convert my small lines to point-free style. But for this (percentage of rolls of 4, 5, or 6 in 1000 die-6 rolls) I can't wrap my head around how to eliminate the omega before the reshape.

{(+/3<?⍵⍴6)×100÷⍵}1000

like image 593
Felix Dombek Avatar asked Nov 22 '21 02:11

Felix Dombek


Video Answer


1 Answers

Let's take it step by step:

{(+/3<?⍵⍴6)×100÷⍵}

First we need to express every part of the function that uses the argument, as a function of the argument. The multiplication combines the two main parts:

{+/3<?⍵⍴6}×{100÷⍵}

In the rightmost part, {100÷⍵}, we need the argument. There are a couple of ways we can deal with this:

  1. We can use an identity function to represent it: 100÷⊢
  2. We can bind (a.k.a. curry) the left argument, 100, to the function ÷ yielding a monadic function: 100∘÷

Let's take the last approach:

{+/3<?⍵⍴6}×100∘÷

In the left part, {+/3<?⍵⍴6}, we can do the same, but need to watch out for two things, and each can be dealt with in a few different ways:

  1. We have a constant, 6, as the rightmost part of our function.
    1. We can change the constant into a constant function: 6⍨
    2. We can commute (a.k.a. swap or switch) the arguments of and use an identity function: 6⍴⍨⊢
    3. We can bind the right argument, 6, to the function yielding a monadic function: ⍴∘6
  2. We have a monadic function, ?, in the middle.
    1. We can compose ? atop : ?⍤⍴
    2. We can compose ? beside <: <∘?

Let's take the last approach for each problem:

(+/3<∘?⍴∘6)×100∘÷

This is a fully tacit equivalent to the monadic function {(+/3<?⍵⍴6)×100÷⍵}. However, there's one more trick we can use to eliminate the parenthesis. Since × is commutative, we can swap its arguments to put the more involved expression on the right:

100∘÷×(+/3<∘?⍴∘6)

However, now we have the problem of the monadic +/ in the middle. Observe that < sees a vector on the right and a scalar on the left. In the case of F/s G v for scalar functions F and G with scalar s and vector v the inner product s F.G v is equivalent, so we can combine the summation with the comparison as follows:

100∘÷×3+.<∘?⍴∘6

Alternatively, we can observer that summation is equivalent to evaluation in base 1 because the place values in base 1 are (…,12, 11, 10) = (…, 1, 1, 1) so if we have the list (…, c, b, a) and evaluate it as a number in base 1, we get:

(… + c×12 + b×11 + a×10) =
(… + c×1 + b×1 + a×10) =
(… + c + b×1 + a×1) =
(… + c + b + a)

That is, the sum of our list. We can write this as:

100∘÷×1⊥3<∘?⍴∘6

like image 158
Adám Avatar answered Oct 11 '22 17:10

Adám