Here's a rundown of definitions in my .jprofile.ijs
, which get loaded in all J sessions.
Some of these are so simple they don't need names, but sometimes I just put things in here so I don't forget how to spell them.
Not all the functions are the most efficient, they're just there for playing with data. Often in a script, I will copy a function in, or re-write one that is more specific to the given problem domain.
NB. AlphaNumerics || Golf versions
azuc =: (65 ,: 26) ];.0 a. NB. u: 65 + i. 26
azlc =: (97 ,: 26) ];.0 a. NB. u: 97 + i. 26
digits =: (48 ,: 10) ];.0 a. NB. u: 48 + i. 10
alnum =: azuc,azlc,digits
These are useful in light string parsing, and also as test data
B =: 0&$: : {{
B0 =. ((u: 183 9619) { ~ ])"2
B1 =. (u: 16b20 16b2584 16b2580 16b2588) {~ (,:~2 1) #.@,;._3 ]
B2 =. (,:~4 2) (10240 u:@+ 40283 #.@A. ,);._3 ]
B3 =. ((u: 11036 11035) { ~ ])"2
B0`B1`B2`B3@.x y
}}
I originally had just B
defined like B0
, but I then I nabbed the others from here.
Example usage
B (<:/&i. -) 5
▓▓▓▓▓
▓▓▓▓·
▓▓▓··
▓▓···
▓····
1 B (<:/&i. -) 10
█████████▀
███████▀
█████▀
███▀
█▀
2 B (<:/&i. -) 20
⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋
⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀
⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀
⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀
⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀
Over =: (8!:1)@,:&(<"_1)
On =: {{
x ((,:&(<"_1))`((,~ <"_1)~)@.(32 = (3!:0) {. y)) y
}}
Over
is a convenience function for comparing 2 arrays that may be of different types (hence the boxing).
Similar to the ,[0.5]
thingy in APL.
(Over azlc&i.) 'alphabetical'
┌─┬──┬──┬─┬─┬─┬─┬──┬─┬─┬─┬──┐
│a│l │p │h│a│b│e│t │i│c│a│l │
│0│11│15│7│0│1│4│19│8│2│0│11│
└─┴──┴──┴─┴─┴─┴─┴──┴─┴─┴─┴──┘
(Over B@e.&'aeiou') 'iversonian'
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│i│v│e│r│s│o│n│i│a│n│
│▓│·│▓│·│·│▓│·│▓│▓│·│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
On
is a more heavy-weight version that doesn't format the output, and can stack multiple lists
(i. 4) On 'RULD' On (, -) =/~ i. 2
┌───┬───┬────┬────┐
│0 │1 │2 │3 │
├───┼───┼────┼────┤
│R │U │L │D │
├───┼───┼────┼────┤
│1 0│0 1│_1 0│0 _1│
└───┴───┴────┴────┘
I use Over
more, so I should probably swap the names around 🤷
For ℕatural numbers (well... Whole numbers, cos 0
, but I like the name Nats)
Nats =: {{ ". ('1234567890 ') {~ '1234567890' i. y }}
Or Integerℤ (again... I just perfer the name Nums)
Nums =: '1234567890_ ' ".@:{~ '1234567890-' i. ]
Pass a string with something separating the numbers
*/ Nats '175m × 50m'
8750
Nums '12 + -3 == 9'
12 _3 9
I guess I should add '.' and make a Rats
verb, but it hasn't come up.
P =: {{ (1, 2 </\ x) u;.1&((0 < x)&#) y }}
This closely mimics the APL operator, and - among other uses - can also be used to extract numbers from a string.
digits (e.~ <P ]) '175m × 50m'
┌───┬──┐
│175│50│
└───┴──┘
*/ digits (e.~ ".P ]) '175m × 50m'
8750
See this gist for more examples.
Credit to @tubular on The APL Discord for this
E =: +./@(-@(#: [: i. */)@$@[ |. E.)
Like E.
but the resulting mask include the whole match (not just the upper left corner), with possible overlaps
< B ('ab',:'ba') E 'ab' {~ ? 10 20 $ 2
┌────────────────────┐
│····················│
│········▓▓··········│
│········▓▓··········│
│··············▓▓····│
│▓▓···▓▓·····▓▓▓▓····│
│▓▓··▓▓▓·····▓▓▓▓▓···│
│····▓▓·······▓▓▓▓···│
│·········▓▓·▓▓······│
│·········▓▓▓▓▓······│
│···········▓▓·······│
└────────────────────┘
Runs =: {{ y u;.1~ 1, 2 ~:/\ v y }}
Conjunction for processing "runs" of values.
- v defines how to identify runs,
- u defines what to do with those runs
<Runs] 'aabcccaaaaabbbc'
┌──┬─┬───┬─────┬───┬─┐
│aa│b│ccc│aaaaa│bbb│c│
└──┴─┴───┴─────┴───┴─┘
#Runs] 'aabcccaaaaabbbc'
2 1 3 5 3 1
<Runs('a'=]) 'aabcccaaaaabbbc'
┌──┬────┬─────┬────┐
│aa│bccc│aaaaa│bbbc│
└──┴────┴─────┴────┘
If you don't care about false runs, use P
(('a'=]) <P ]) 'aabcccaaaaabbbc'
┌──┬─────┐
│aa│aaaaa│
└──┴─────┘
Adjust =: (@:{)`[`]} NB. {{ (u x { y) x} y }}
Alter =: {{ x } y ,: u y }}
Adjust
is Like Amend }
but takes a function to modify selected items
2 3 (*&10) Adjust i. 6
0 1 20 30 4 5
] a =. 1 (< ;~ i. 3)} 5 5 $ 0
1 1 1 0 0
1 1 1 0 0
1 1 1 0 0
0 0 0 0 0
0 0 0 0 0
(<1 2 3;1 2 3) (1 XOR ]) Adjust a
1 1 1 0 0
1 0 0 1 0
1 0 0 1 0
0 1 1 1 0
0 0 0 0 0
Alter
is a similar function which takes a mask instead of indices
This is kinda like BQN's "Under Select" {𝔽⌾(𝕨⊸/)𝕩}
0 1 1 0 0 toupper Alter 'alter'
aLTer
(];.0 a) (1 XOR ]) Alter a
1 1 1 0 0
1 1 1 0 0
1 1 0 1 1
0 0 1 1 1
0 0 1 1 1
A minor concern you might have is that Alter
performs u
to the whole of y
, which may be wasteful.
Use can modify the fork ($ #: I.@,)
(which converts a boolean matrix to indices) to use a mask with Adjust
(($ <@#: I.@,) (];.0 a)) (1 XOR ]) Adjust a
1 1 1 0 0
1 1 1 0 0
1 1 0 1 1
0 0 1 1 1
0 0 1 1 1
Amend. Adjust. Alter. Yes, I used a thesaurus.
Insert =: {{ m ({. , x , }.) y }}
Inserts x
in y
, at position m
'Three' 6 Insert 'OneTwoFour'
OneTwoThreeFour
Shuffle =: $ $ ({~ ?~@#)@,
Randomises position of all items in a matrix across ranks.
Use it with Rank "
to limit it's effect
<"_1 Shuffle i. 2 2 3
┌───────┬─────┐
│5 10 11│7 8 1│
│0 4 9│6 3 2│
└───────┴─────┘
<"_1 Shuffle"1 i. 2 2 3
┌─────┬───────┐
│1 0 2│ 6 7 8│
│3 5 4│11 9 10│
└─────┴───────┘
<"_1 Shuffle"_1 i. 2 2 3
┌─────┬───────┐
│3 5 4│11 8 9│
│1 0 2│ 6 7 10│
└─────┴───────┘
Iinv =: e.~ i.@>:@{:
Simple Indices inverse (only works with sorted lists)
NB. I.^:_1
(or I.inv
) is now availble in the latest (J9.6) engine, but leaving it here in case I need it on the Playground or something.
] p =. /:~ 10 ? 20
1 5 6 7 8 9 10 11 15 17
Iinv p
0 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1 0 1
I. Iinv p
1 5 6 7 8 9 10 11 15 17
To =: ([ + i.@(>:@-~))`(|.@$:~)@.>
Return a [closed, closed] range from x
to y
, either ascending or descending.
_3 To 11
_3 _2 _1 0 1 2 3 4 5 6 7 8 9 10 11
11 To _3
11 10 9 8 7 6 5 4 3 2 1 0 _1 _2 _3
If I want [closed, open), I can always just }:
Cmp =: {.@(/: - \:)@,&<
Get single "order" - like <
or >
- but on Array
1 2 3 Cmp 1 3 2
_1
'alpha' Cmp 'beta'
_1
'gamma' Cmp 'beta'
1
Odm =: #: i.@(*/)
Like K's !
|: Odm 3 3
0 0 0 1 1 1 2 2 2
0 1 2 0 1 2 0 1 2
Iota =: #: i.
Like APL's ⍳
or BQN's ↕
, given multiple values
<"1 Iota 3 3
┌───┬───┬───┐
│0 0│0 1│0 2│
├───┼───┼───┤
│1 0│1 1│1 2│
├───┼───┼───┤
│2 0│2 1│2 2│
└───┴───┴───┘
Some shorter (possibly inverse-able) versions of existing functions.
Ord =: (u:^:_1) :. (u:)
Chr =: (u:) :. (u:^:_1)
Uc =: toupper :. tolower
Lc =: tolower :. toupper
NB. Left-shift and Right-shift
Ls =: (1&$:) : (|.!.'')
Rs =: Ls&.|.
ts =: {{
echo < dtbs,/ 'timespacex × ',('c' (8!:2) x)
result =. x&{{ y ; (8!:0) (x, 1) * x timespacex y }}@> cutopen y
echo ,. ('expr';'time';'space') , result
}}
A subjectively prettier timespacex
1e6 ts '> , { ;~ i: 1';',/ ,"0/~ i: 1'
┌──────────────────────┐
│timespacex × 1,000,000│
└──────────────────────┘
┌─────────────┬────────┬─────┐
│expr │time │space│
├─────────────┼────────┼─────┤
│> , { ;~ i: 1│1.834701│3520 │
├─────────────┼────────┼─────┤
│,/ ,"0/~ i: 1│1.389705│2880 │
└─────────────┴────────┴─────┘
curfile =: {{ _1 {:: (4!:3) $ 0 }}
curpath =: ] ,~ 0 {:: fpathname@curfile
chdir =: (1!:44)
The cur*
verbs are probably not 100% reliable but works for my use case. Probably named poorly, because it's not cwd
. Maybe should be scriptpath
, but whatever.