Skip to content

Instantly share code, notes, and snippets.

@steveAllen0112
Forked from mlliarm/oldtimer_APL_code.md
Last active February 26, 2022 08:47
Show Gist options
  • Save steveAllen0112/cc63727cbada016804280290d7c548db to your computer and use it in GitHub Desktop.
Save steveAllen0112/cc63727cbada016804280290d7c548db to your computer and use it in GitHub Desktop.
An oldtimer's APL code

An oldtimer's APL code

What

Some pretty cool code from the 70s'-80s' that a Reddit user shared at this question.

Here's what u/snarkuzoid wrote:

5x5 Knight's Tour in APL

It puts an A in the middle, then randomly does a knight's tour, marking each cell with the next letter until it runs out of moves. Yes, it's terrible code by modern standards. For some reason we were obsessed with very short programs.

Here's the printout:

5x5 Knight's Tour in APL

There's more to the story of the above code snippet:

Alas, I don't know of any other code fragments I might have laying around.

I only had this one because it was published as winner of the "Nice Knight" contest and I had a copy of the announcement.

Thanks again. This really made my day.

So apparently with this code the Reddit user had won a Leetcode competition of their time.

Pretty, cool, right?

Code

In modern Dyalog APL, v.18.0:

⎕IO1  If it's set to 0 instead, there's no 'A' character in the center and thus the code behaves incorrectly!
ZEX2
  V13+I0×A25'0'
  Z 5 5 A,0A[C1V]'ABCDEFGHIJKLMNOPQRSTUVWXY'[II+1]
  R(2,V)(0.8+V÷5),1+5|¯1+V(A='0')/25
  T(2,V)(0.8+C÷5),1+5|C-1
  2×0V(?8)((10|T-R) 21 12)/V

Results

Here are the results when run the above tradfn a couple times, with ⎕IO←1:

      EX2
00ELG
DMHQ0
IRAFK
NCJSP
0TOB0
      EX2
00000
0E0C0
00AF0
00D0B
0000G
      EX2
GBO00
N0FIP
CHALE
0MDQJ
0RK00
      EX2
GBK00
L0F0J
CHA0E
0MDI0
000N0

The above results are correct.

Correctness of the results

This requires ⎕IO←1 to be correct.

Try it out

According to Dyalog, tradfns should work on tryapl.org.

Alternatively, rewritten as a dfn, without any compression/code golfing, looks like this:

KNIGHTS←{
	⎕IO←1                                     ⍝ Guarantee indexes starting at 1

	t←⍵*2                                     ⍝ (t)otal # of spaces on the board
	s←⍵ ⍵⍴⍳t                                   ⍝ (s)paces on the board, numbered
	i←↑∪⍸s                                     ⍝ (i)ndexes of the board (2-dimensional)
	c←⍵-⍨⍵⊥⌈2⍴⍵÷2				  ⍝ (c)enter space # on the board

	valid←{⍵~⍨⍸21 12∊⍨10⊥|⍉i-t 2⍴⊃⍸s⍷⍨⊃⌽⍵}	⍝ Generate list of (valid) moves from a given space
	moves←{0=⍴v←valid ⍵:⍵⋄∇⍵,(?∘≢⊃⊢)v}	  ⍝ Generate the move list

	⍵ ⍵⍴((⍳≢)@(moves c))t⍴0			  ⍝ Fill the moves into a zeroed-out board
}

When made linear (simply by putting in between each line), this works on tryapl.org "as is".

Just for fun, here it is as a one-liner, with the functions all embedded. I'm open to anyone's suggestions on how to code golf/go tacit/etc with this one.

{s←↑∪⍸i←⍵ ⍵⍴⍳t←⍵*2×⎕IO←1⋄⍵ ⍵⍴((⍳≢)@({0=⍴v←{⍵~⍨⍸21 12∊⍨10⊥|⍉s-t 2⍴⊃⍸i⍷⍨⊃⌽⍵}⍵:⍵⋄∇⍵,(?∘≢⊃⊢)v}⍵-⍨⍵⊥⌈2⍴⍵÷2))t⍴0}

Code Golf

KNIGHTS_cg←{
    s←↑∪⍸i←⍵ ⍵⍴⍳t←⍵*2×⎕IO←1
    ⍵ ⍵⍴((⍳≢)@({0=⍴v←{⍵~⍨⍸21 12∊⍨10⊥|⍉s-t 2⍴⊃⍸i⍷⍨⊃⌽⍵}⍵:⍵⋄∇⍵,(?∘≢⊃⊢)v}⍵-⍨⍵⊥⌈2⍴⍵÷2))t⍴0
}

Changes in the dfn:

  • Takes a dimension for the board as the right argument to the function. For even dimensions, the starting point is the space immediately to the upper left of the board center, since the board center is not a space at all in those cases.
  • Returns numbers in a number matrix instead of characters in a character matrix. This is because of the ability to specify higher dimensions.
  • No longer fills in the board on each iteration. Rather, it creates the move list first, then uses that as an index replacement vector for the sequence. This is made possible by .

Here is a function to convert the output to a character vector as in the original.

{('0',⎕A)[,⍵+⎕IO]⍴⍨⍴⍵} ⍝ Note that this is index independent :)

Thanks

  • To the user u/mlliarm who made this public and did a lot of the initial investigation.
  • To the user u/snarkuzoid who trusted us with his code.
  • To bubbler from APLjk discord server that found the IO bug.
  • To Adám for trying to debug the tradfn error that appeared in tryapl.org.
@mlliarm
Copy link

mlliarm commented Feb 26, 2022

@steveAllen0112 amazing work, thanks a lots !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment