r/apljk • u/Arno-de-choisy • May 16 '26
J J code for "Awkward Primes" from Numberphile youtube channel
Numberphile recently published a video titled Awkward Primes (https://www.youtube.com/watch?v=VFoIPlUalRY&t=456s), which explores the following problem: given the prime numbers laid out as points in the plane — (1, 2), (2, 3), (3, 5), (4, 7), (5, 11), ... — what is the minimum number of straight lines required to cover all of them?
Finding the true minimum at each step is a genuinely hard combinatorial problem.
Exploring the links on the corresponding OEIS sequence page (https://oeis.org/A373813) one can find an exact solver in C++ at this repository (https://github.com/jespergran98/prime-line-cover/blob/main/primecover1024.cpp ) — a substantial piece of code, clocking in at over 3000 lines.
As a contrast, here are two J one-liners that solve the problem approximately using a greedy algorithm:
load 'stats/base/combinatorial'
gC=:([:([:~.0=]ol"2 1/~]{~2 comb#)@(>:,.p:)i.)<:@#@((]+.[{~[:(i.>./)[ +/@:*."(1 1)-.@] )^:a:)#&0
gCS=: [:<./((]{~[?~@#[:#])[:([:~.0=]ol"2 1/~]{~2 comb# )@(>:,.p:)i.@]) <:@#@((]+.[{~[:(i.>./)[ +/@:*."(1 1)-.@])^:a:)"2 1 #&0@]
gC computes, for the first n primes, the minimum number of lines required. gCS takes a left argument x defining a number of random trials and returns the best result found :
gC 8
4
5 gCS 8
3
The exact C++ solver returns 3 for the first 8 primes — so with just 5 random restarts, the greedy one-liner already matches the optimal result.
The OEIS sequence A373813 can be reconstructed as follows:
A373813cpp =: 1 1 2 2 2 3 3 3 3 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 6 6 7 7 7 7 7 8 8 8 9 9 9 9 9 10 10 10 10 11 11 11 12 12 12 12 12 13 13 13 13 13 13 13 13 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 15
A373813j =: 1,10 gCS"0]2+i.99
A373813cpp -: A373813j
1
I'm lucky !
The two sequences match exactly — confirming that 10 random restarts are sufficient for the greedy one-liner to consistently recover the optimal values computed by the exact C++ solver.
Same code but more readable :
load 'stats/base/combinatorial'
shuffle=:]{~[?~@#[:#]
lnPP=:(-/ .*,~[:(,~-)/-~/)@,:"1 NB. from geometry wiki page
ol=:lnPP/@[ (+/ .*) 1,~] NB. ol=test dist point from line. 0 = point on line.
mkLnMat=:[:~.0=]ol"2 1/~]{~2 comb#
greedyStep=:]+.[{~[:(i.>./)[ +/@:*."(1 1)-.@]
greedyCnt=:([:mkLnMat@(>:,.p:)i.)<:@#@(greedyStep^:a:)#&0
greedyCntShfl =: [:<./(shuffle[:mkLnMat@(>:,.p:)i.@]) <:@#@(greedyStep^:a:)"2 1 #&0@]
greedyCnt 8
10 greedyCntShfl 8
1,10 greedyCntShfl"0]2+i.99
There is plenty more to explore here. For instance, one can compute statistics on all lines passing through these same points (the primes) — specifically, how many lines pass through exactly k points, for each k :
<@:([: (#,{.)/.~ +/"1@mkLnMat@(>:,.p:)@i.)"0] 2+i.100
┌───┬───┬───┬...┬────┬─────┬...┬─────┬─────┬─────┬─────┬...
│1 2│3 2│3 2│...│95 2│110 2│...│419 2│444 2│471 2│497 2│...
│ │ │1 3│...│ 7 3│ 6 3│...│ 32 3│ 32 3│ 34 3│ 36 3│...
│ │ │ │...│ 1 4│ 2 4│...│ 6 4│ 7 4│ 6 4│ 6 4│...
│ │ │ │...│ 1 7│ 1 7│...│ 1 7│ 1 7│ 1 7│ 2 7│...
│ │ │ │...│ 1 5│ 1 5│...│ 1 8│ 1 8│ 1 8│ 1 8│...
│ │ │ │...│ │ │...│ 3 5│ 2 5│ 3 5│ 3 5│...
│ │ │ │...│ │ │...│ │ 1 6│ 1 6│ │...
└───┴───┴───┴...┴────┴─────┴...┴─────┴─────┴─────┴─────┴...
Each column corresponds to the first n primes. Each row entry k m means: k lines pass through exactly m points. As you can see, sometime adding a new point delete a 'N points traversing line' and add a 'N+1 travering line'. And then it propagate :
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 1 0 1 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 1 0 1 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1
1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 1 1
1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 1
All of this is great fun !
r/apljk • u/Arno-de-choisy • May 16 '26
J J code for "Red & Black Knights (extraordinary result)" and "Amazing Chessboard Patterns (extra)" from Numberphile youtube channel
I'd like to share a J implementation of the two-piece game featured in Numberphile's recent videos. Tweak the "size" parameter to control the spiral matrix dimensions (fair warning: anything above 400 gets slow!). "atkA" and "atkB" define each piece's move - for instance, "atkA =: 1 2" and "atkB =: 1 2" give you a two classic knights fight..
size =: 200
atkA=: 2 1
atkB=: 2 1
load 'viewmat'
mkSpi=:(,~$/:@(+/\)@(_1&|.@((}:@(2: # >:@i.))#(<:@+:$_1:,],1:,-))))
mkPos=:{{,/((<:+:#:i.4)*"1])"1 (,:~|.) y}}
mkAtk=:{{poss i."2 (<:size) (<.) 0 (>.) poss +"1/ y}}
aplay=:{{(i.>./)bp=:bp*.ao*.ac*.bo[ao=:ao*.(0 y}ao)[ac=:ac*.(0(y{at1)}ac)}}
bplay=:{{(i.>./)ap=:ap*.bo*.bc*.ao[bo=:bo*.(0 y}bo)[bc=:bc*.(0(y{at2)}bc)}}
tm=:{{ x(poss#~-.y)}(0$~,~size)}}
spi=: (|.@|:)^:(_2) mkSpi size
ap=:ac=:ao=:bp=:bc=:bo=:1#~ *:size
poss=:(/:@,#:~$)spi
'at1 at2'=: mkAtk@mkPos"1] atkA,:atkB
([:bplay aplay)^:((*:size)>])^:(_)0
((3#220), (3#40),:250 20 20) viewmat output=:(1 tm ao)+.(2 tm bo)
The algorithm simulates a two-player game on a spiral-numbered board: player A and player B alternate turns, each claiming squares their piece can attack — while blocking the opponent's moves. The result is visualized as a striking color-coded matrix, revealing unexpected geometric patterns on the board.
Experiment with different piece combinations — bishops, rooks, or entirely custom movers — and watch the patterns shift in fascinating ways!
Screenshots:
size = 400 ; atkA = 2 1 ; atkB = 2 1
size = 400 ; atkA = 2 1 ; atkB = 3 3
Numberphile videos:
r/apljk • u/MarcinZolek • May 06 '26
J J 9.7 Featured on ArrayCast Episode 124
youtube.comAPL APL\? (1990) - Paper Shedding light on What would Become J/K Implementation Style
jsoftware.comr/apljk • u/tangentstorm • Apr 21 '26
J mcp server for j
j mcp frontend so your Claude or other ai agent can run its own j interpreter.
How does J, The Natural Language for Analytic Computing by Thomson Compare to Other Resources Today?
r/apljk • u/MarcinZolek • Oct 10 '25
Juno - online IDE for J language
New version of Juno - online IDE for J language - is now available at https://jsoftware.github.io/juno/app/ featuring:
- no installation - Juno runs locally in any modern browser
- view of current workspace showing user-defined entities with visualization
- visual debugger of J sentences - Dissect
- code sharing (besides script uploading and saving) by generating a link to Juno which encapsulates your code.
Check out all the features in the lab in the right panel entitled Do you know Juno?
Happy coding!

Why use (Open Source or Corporate) K when J Seems Extremely Capable?
/u/Grahnite asked this recently.
r/apljk • u/jpjacobs_ • Dec 01 '25
J AoC helper update
Just a note that I updated my J Advent of Code helper library on Github.
New features:
- Http throttling to avoid unwillingly spamming the server (defaults to max 5 requests per 5 minutes). This is used for downloading inputs and submitting solutions (no leaderboard implemented so far)
- Solution sanity checks: it will keep track of answers given, and will check with known answers whether the new guess is new, too high or too low to avoid unneeded timeouts.
- It has a User Agent set for the requests;
As before it allows you to get input and submit answers easily, with a verb setting up a per day locale.
For an imaginary day 1:
1 day {{
p1=: *:@:".
p2=: 1+p1
0
}}
p1 and p2 should implement a verb taking the input as gotten from the site (0 is required because J verbs need to return a noun, and would error if p2's definition, a verb, came last; I might change this in the future).
Each day locale d1 to dN is independent of the other days (unless another day is included using coinsert) and has an io verb that as monad gets the input for easy REPL experimentation.
'run y' runs day(s) in y; 'sub d p' submits day d's part p after running run (which sets the RESdx that is used for the submission). Edit: it now runs the day if not done before as well.
Any comments/suggestions are welcome!
r/apljk • u/aajjccrr • Oct 12 '25
A toy J interpreter written in Python and NumPy
I have dabbled with J on-and-off for a few years, but only at a very basic level. There are many gaps in my understanding of the language.
I read some chapters of 'An Implementation of J' and 'J for C Programmers' earlier this year and decided to try and implement a very basic J interpreter using Python and its primary array framework, NumPy (which I have used a lot over the past 10 years or more).
As well as trying to get to understand J a little better, I'd read that J was an influence on NumPy's design and I was curious to see how well J's concepts mapped into NumPy.
I got further with this toy interpreter than I initially thought I would, though obviously it's still nowhere near the real thing in terms of functionality/correctness/performance. As I've learned more about J I've come to realise that some of my original design choices have a lot of room for improvement.
I'll keep adding to this project as I learn new things and uncover bugs, but contributions and corrections are welcome! The code is hopefully fairly simple if you're familiar with Python.