8 ms·
Paraphrasing an earlier Reddit post, here's how it might look in K3. Generate a range of numbers up to 20 (for brevity), inclusive: 1+!20 1 2 3 4 5
by RodgerTheGreat 10y ago
Paraphrasing an earlier Reddit post, here's how it might look in K3.
Generate a range of numbers up to 20 (for brevity), inclusive:
1+!20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Apply a function ({x!/:3 5}), which takes an element modulo 3 and 5, to the range:
{x!/:3 5}1+!20
(1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2
1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0)
Taking the negation (~) shows us the places the elements divide evenly:
{~x!/:3 5}1+!20
(0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0
0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1)
Convert these into base-2 indices:
{2 _sv~x!/:3 5}1+!20
0 0 2 0 1 2 0 0 2 1 0 2 0 0 3 0 0 2 0 1
We can then use those indices to select from a list. Note the addition of a map ('), because if we continue performing all these operations in parallel we won't have access to x as some particular item of the list:
{(x;"Buzz";"Fizz";"FizzBuzz")2 _sv~x!/:3 5}'1+!20
(1;2;"Fizz";4;"Buzz";"Fizz";7;8;"Fizz";"Buzz";11;"Fizz";13;14;"FizzBuzz";16;17;"Fizz";19;"Buzz")
- Avshalom 10y agoTo translate that as literally as possible into Dyalog fizzbuzz ← { {(⍵ 'buzz' 'fizz' 'fizzbuzz')[1+2⊥0=3 5∘.|⍵]}¨⍵ } called as fizzbuzz ⍳100 or just {(⍵ 'buzz' 'fizz' 'fizzbuzz')[1+2⊥0=3 5∘.|⍵]}¨⍳100 with unnecessary parens {(⍵ 'buzz' 'fizz' 'fizzbuzz')[1+(2⊥(0=((3 5)∘.|⍵)))]}¨⍳100
- jxy 10y agoSince you are using ¨, ⍵ is a scalar, so you don't need the ∘. Translated back to J ((;'Buzz';'Fizz';'FizzBuzz'"_){~2#.0=3 5|])"0>:i.100 The boxed list in J feels a bit cumbersome compared to mixed arrays in APL.
- Avshalom 10y agoFair enough. Like most APL I wrote it backwards until it worked.
- lokedhs 10y agoWorks out-of-the box in GNU APL as well, if someone wants to try it with a free version of APL.
- RodgerTheGreat 10y agoTo that end, my K version can be tweaked slightly to work with oK, an open-source interpreter based on k6: {(x;"Buzz";"Fizz";"FizzBuzz")@2 2/~3 5!\:x}'1+!20 k6 swapped the argument order of "mod" and made change of base into an overload of "/", rather than a named builtin. See it in action here: http://johnearnest.github.io/ok/index.html?run=%20%7B%28x%3B%22Buzz%22%3B%22Fizz%22%3B%22FizzBuzz%22%29%402%202%2F~3%205%21%5C%3Ax%7D%271%2B%21100 http://johnearnest.github.io/ok/index.html?run=%20%7B%28x%3B...
- usr381 10y agoNice, clever use of base change. What about something like n{:[~#y;$x;y]}'{,/("Fizz";"Buzz")@&~x!/:3 5}'n:1+!20 to avoid duplicating the string combinations? The conditional is unfortunate, would like to get rid of it. But should be straightforward to extend if we want to introduce further string combinations for numbers divisible by, e.g., 7. Though anticipating such things goes against the spirit of k I suppose. :-)