text:
Quines that print what their index is
We all know what a quine is. A quine is a program which prints its own source code. And we also know about the printable ASCII characters. Well... this challenge mixes both.
Your mission, should you accept it, is to create an index quine. An index quine is a non-empty program, composed only of the printable ASCII characters, which prints its own index.
The index of a string is its position within an infinite dictionary where all strings composed of exactly the printable ASCII characters appear, sorted by size then ASCII code.
The index is a non-negative whole number, assigning 0 to the empty string then continuing with the space, !, " onward.
For example, *! precedes ** as the ending ! in the first string has lower ASCII code than the ending * in the second, but both are preceded by {, which has a higher ASCII code than the characters of the last two examples, but is shorter.
The printed index should be in base 10, outputted through STDOUT or closest equivalent, with no other output unless your language requires trailing newlines/other characters. Also, a bit like actual quines, do not access your source code directly (as a file, etc.)
Your program should be non-empty, as a reminder to those reading these rules.
If there are multiple programs of shortest length, the tiebreaker is the program with the lower index.
The shortest program following these very rules wins. Have fun.

I think you mean sorted by size then ascii code, or else some strings don't have finite index. (Actually, maybe I'm just interpreting "then" differently)

@xnor I had to double check that for a moment, since in order to "sort by size then ascii code", in practice, I'd sort by ascii code first, then sort by size, using a stable sort. :)

Yeah, I can see it both ways now. I was thinking that to sort, you first compare size, and if those are unequal, then you look at ascii value.

@Arnauld Here is the new program to get the index.

If the code is required to print its own index and be a quine, does that not mean that the code can only consist of some run of the digits 0-9?

@Dingus I think the question's definition of index quine is meant to be entirely separate from that of a standard quine.

@mathjunkie I suspect you're right. But then why call it a quine? A program that prints its own index is a more correct description, isn't it?

@Dingus A quine shouldn't read its own source code.

Here is another program to get the index.

There must be a language where a space outputs 1. I tried to find one, but couldn't. TIO's interpreter for FRACTRAN outputs 2 for a space :( Retina outputs 1 for an empty program, but a space is significant in regex, so a space outputs 0.

"Quine" on this site has some complications. (TL;DR: a proper quine should have "data" and "code" sections clearly visible.) If you don't want that, you can use [tag:self-referential] instead.

Could you some example programs with their indexes?

And here is a 'check' to get the original program back from the index.

Take a moment to wonder at how crazy a bf answer would be... (If it exists)

BF has comments in the form of using any non-instruction, which makes it marginally easier. The real difficulty is doing this in something like ///...

Deorst, 1 byte

Try it online!
Commentator, 1 byte

Try it online!
Snails, 1 byte

Try it online!

So far, I have found three one-byte solutions, all of which print 1 with a space in the source code.
The first two languages were created by @cairdcoinheringaahing, and the last one by @feersum.

J, 52 bytes
echo-95x#.31-3 u:(,quote)'echo-95x#.31-3 u:(,quote)'

Try it online!
How it works
echo-95x#.31-3 u:(,quote)'echo-95x#.31-3 u:(,quote)'
                         '...'  NB. a string literal
                 (,quote)       NB. concatenate self with single-quoted self
             3 u:  NB. convert to Unicode codepoints
          31-      NB. subtract from 31 (negation of 1-based index)
     95x#.         NB. convert from base 95 to integer (using extended integer)
    -              NB. negate
echo               NB. print with newline

Pyth, 39 37 33 bytes
-2 bytes thanks to @Mukundan
hiR95]m-Cd31jN B"hiR95]m-Cd31jN B

Try it online!
hiR95]m-Cd31jN B"...
                "...   ( String literal
               B       ( Wrap in an array and duplicate
            jN         ( Join using `"` (this gives us the full source code)
      m-Cd31           ( For each character, take its codepoint minus 31
     ]                 ( Wrap in an array
 iR95                  ( Map base 95-conversion to that array
h                      ( Take the first (only) element

-2 byes by using  B instead of *2[. Try it online!

@Mukundan Thanks :)

Python 3.8 (pre-release), 82 66 63 bytes
-3 bytes thanks to @dingledooper
exec(a:='g=0\nfor i in b"exec(a:=%r)"%a:g=g*95+i-31\nprint(g)')

Try it online!

-3 bytes using a b-string.

@dingledooper Thanks

C# (.NET Core), 471 bytes
using System.Numerics;class A{static void Main(){var s="using System.Numerics;Class A{{static void Main(){{var s={0}{1}{0};System.Console.Write(V(string.Format(s,(char)34,s)));}}static BigInteger V(string s){{BigInteger r=0;for(int i=0;i<s.Length;++i)r+=(s[i]-31)*BigInteger.Pow(95,i);return r;}}}}";System.Console.Write(V(string.Format(s,(char)34,s)));}static BigInteger V(string s){BigInteger r=0;for(int i=0;i<s.Length;++i)r+=(s[i]-31)*BigInteger.Pow(95,i);return r;}}

Try it online!
This is the basic C# quine with the scoring function built in. Is my scoring function a little off? It doesn't quite agree with the Python one linked in the comments.

Gol><>, 15 bytes
"r3lMF`_*+fs-|h

Try it online!
An extension from my own 6-byte quine.
How it works
"r3lMF`_*+fs-|h
"...             Start string ("), push all characters, and end string(")
 r3              Reverse the stack and push 3 (= 34 - 31)
   lMF       |   Loop (stack length - 1) times...
      `_*+         [... n2 n1] -> [... n2+n1*95]
          fs-      Subtract 31
                 equivalent to "-31 from each except top and base 95 convert"
              h  Print the top number and halt

Python 2, 68 65 bytes
-3 bytes thanks to @Mukundan
x="g=0\nfor i in'x=%r;exec x'%x:g=95*g+ord(i)-31\nprint g";exec x

Try it online!

-3 bytes by using a for loop instead of the reduce

@Mukundan That’s great, thanks!

R + GMP, 156 116 bytes
or 126 bytes in R
"->a;t=utf8ToInt(a)-31;sum(as.bigz(95)^(115:0)*c(3,t,3,t))"->a;t=utf8ToInt(a)-31;sum(as.bigz(95)^(115:0)*c(3,t,3,t))

Try it online!
Edit: Big improvement by re-arranging to start immedidately with quoted string, which really simplifies the re-construction of the full program text.
This seems horribly uncompetitive, but I don't seem to be able to do any better, I'm afraid.  The enormously-verbose utf8ToInt() function name isn't really helping much.

Java (OpenJDK 8), 724 bytes
import java.math.*;class D{public static void main(String[]a0){char q=34;String s="import java.math.*;class D{public static void main(String[]a0){char q=34;String s=;String u=s.substring(0,82)+q+s+q+s.substring(82);BigInteger n=new BigInteger(s.substring(60,61));for(int i=0;i<u.length();)n=n.add(new BigInteger(new Long(95).toString()).pow(i).multiply(new BigInteger(new Long(u.charAt(u.length()-i++-1)-31).toString())));System.out.print(n);}}";String u=s.substring(0,82)+q+s+q+s.substring(82);BigInteger n=new BigInteger(s.substring(60,61));for(int i=0;i<u.length();)n=n.add(new BigInteger(new Long(95).toString()).pow(i).multiply(new BigInteger(new Long(u.charAt(u.length()-i++-1)-31).toString())));System.out.print(n);}}

Try it online!

Stax, 34 bytes
1-byte difference with Pyth, since I can't get rid of the prepending quote in Stax.
"c34|Ss+{31-m95|E"c34|Ss+{31-m95|E

Try it online!
Explanation
"..."                 The second half of the program
     c                Copy this operand
      34|S            Surround it with quotes
          s+          Prepend the quoted string with the original string
            {   m     Map: (Since direct - removes items)
             31-      Codepoint - 31 (Stax strings consist of codepoints)
                 95|E Convert from base 95

Stax, 12 bytes
0|?F31-s94*+

Run and debug it
Note that this uses the |? program source operand, which may be cheating
0   # Push a zero to the stack
|?  # Return program's source as a string
F   # for each character (as an ascii value)...
31- # subtract 31 from the character's value
s   # get the running total
94* # multiply it by 94
+   # add the character's value

Perl 5 + -Mbigint -M5.10.0, 71 bytes
$_=q($n+=(95**(70-$-++))*(-31+ord)for"\$_=q($_);eval"=~/./g;say$n);eval

Try it online!


text:
Solve a separable differential equation
A first order separable ordinary differential equation is (arguably) the easiest type of differential equation to solve, and takes the form of
$$N(y)\frac{dy}{dx} = M(x) \\
y(x_0) = y_0$$
For two given functions \$N(y)\$ and \$M(x)\$ and an initial condition \$y(x_0) = y_0\$.
Your task is to take \$N(y)\$, \$M(x)\$, \$x_0\$ and \$y_0\$ and output the solution to that differential equation.
How to solve a separable differential equation
The differential equation
$$N(y)\frac{dy}{dx} = M(x)$$
can be solved through the following method:
$$
\begin{align}
N(y)\frac{dy}{dx} & = M(x) \\
\int{N(y)\frac{dy}{dx}dx} & = \int{M(x)dx} \\
\int{N(y)dy} & = \int{M(x)dx}
\end{align}
$$
Once the integrals have been calculated, we can remove one of the constants of integration, leaving the equation
$$f(y) = g(x) + c$$
where
$$
f(y) = \int{N(y)dy} \\
g(x) = \int{M(x)dx}
$$
After this, \$c\$ can be calculated by applying the initial condition:
$$
c = f(y_0) - g(x_0)
$$
and a final solution for \$f(y)\$ can be given.
Challenge
You are to take in four inputs:

The function \$N(y)\$
The function \$M(x)\$
\$x_0\$
\$y_0\$

Both \$x_0\$ and \$y_0\$ can be any real number, and can be taken as input in many reasonable manner (i.e. a list, tuple, two integers etc.). The functions, in order to avoid having to focus on parsing mathematical input, will be limited to a type of Laurent polynomials - i.e polynomials in the form
$$
p(x) = \alpha \cdot x^n + \beta \cdot x^{n-1} + \dots + \gamma + \delta \cdot x^{-2} + \epsilon \cdot x^{-3} + \dots + \zeta \cdot x^{-m+1} + \eta \cdot x^{-m} \\
\alpha, \beta, \dots, \eta \in \mathbb{R}, \:\: n, m \in \mathbb{N}
$$
Notice that we'll never have \$x^{-1}\$ in the polynomial, and that because of this, the integrals will always be Laurent polynomials of the same form (with \$x^{-1}\$ included after integrating).
With inputs in this format, there are multiple ways you could represent them for input. As with the mapping, any reasonable representation is acceptable, and if you aren't sure, ask. However, here are some that are definitely allowed (for the example \$p(x) = 3x^2 + x + 6 - 2x^{-2} + 7x^{-5}\$):

Nested list: [[3, 2], [1, 1], [6, 0], [-2, -2], [7, -5]]
A pair of lists of coefficients: [3, 1, 6] and [0, -2, 0, 0, 7]
A string representation: "3x^2 + x + 6 - 2x^-2 + 7x^-5"
etc.

Given these four inputs, you are to output the solution to the differential equation they represent.
In order to avoid having to algebraically manipulate your solutions to get into the form \$y(x) = ...\$, you can output two Laurent polynomials, in the same form as the input; one representing \$y\$ and the other \$x\$.
This is code-golf so the shortest code in bytes wins!
Test cases
Both the MathJax and text-based inputs will be included for each example, where the text based will use the nested list input format above. In addition, I will walk through the first example for clarity.
In:
  N = [[1, -2]]
  M = [[6, 1]]
  1 -> 1/25 = 0.04
Out:
  y = [[-1, -1]]
  x = [[3, 2], [28, 0]]

$$
\begin{align}
\frac{1}{y^2}\frac{dy}{dx} & = 6x \\
y(1) & = \frac{1}{25} = 0.04 \\
\\
\int{N(y)dy} & = \int{M(x)dx} \\
\int{\frac{1}{y^2}dy} & = \int{6xdx} \\
-\frac{1}{y} & = 3x^2 + c \\
-25 & = c + 3 \implies c = -28 \\
-\frac{1}{y} & = 3x^2 - 28
\end{align}
$$
In:
  N = [[2, 1], [-4, 0]]
  M = [[3, 2], [4, 1], [-4, 0]]
  1 -> 3
Out:
  y = [[1, 2], [-4, 1]]
  x = [[1, 3], [2, 2], [-4, 1], [-2, 0]]

$$
N(y) = 2y - 4, \:\: M(x) = 3x^2 + 4x - 4 \\
y(1) = 3 \\
\:\\
y^2 - 4y = x^3 + 2x^2 - 4x + c \\
c = -2 \\
y^2 - 4y = x^3 + 2x^2 - 4x - 2 \\
$$
In:
  N = [[1, 0]]
  M = [[3, 2], [2, 0]]
  0 -> 0
Out:
  y = [[1, 1]]
  x = [[1, 3], [2, 1]]

$$
N(y) = 1, \:\: M(x) = 3x^2 + 2 \\
y(0) = 0 \\
\:\\
y = x^3 + 2x + c \\
c = 0 \\
y = x^3 + 2x \\
$$

Sandbox. Please do not hesitate to leave any and all suggestions for improvements.

Python 2, 123 122 bytes
def f(p,P):R=[[[a/-~b,b+1]for a,b in F]for F in P];a,b=map(lambda F,x:sum(a*x**b for a,b in F),R,p);R[1]+=[a-b,0],;print R

Try it online!
Straight-forward implementation. A function that takes arguments in the form (y, x), (N, M), and prints the resulting 2 polynomials to STDOUT.

SageMath, 60 59 58 bytes
Saved a byte thanks to Dingus!!!
lambda N,M,b:desolve(diff(y,x)*N-M,y,b)
y=function('y')(x)

Try it online!
Inputs two functions \$N(y)\$ and \$M(x)\$ and a boundary condition \$[x_0,y_0]\$  and returns the solution to the differential equation \$N(y)\frac{dy}{dx}=M(x)\$ where \$y(x_0)=y_0\$.

Wolfram Language (Mathematica), 33 bytes
DSolve[{y'@x#==#2,y@#3==#4},y,x]&

Try it online!
Tool for the job, and all that. Uses Mathematica's builtin DSolve. The TIO link shows the input and output formats (a warning message is issued for the second case, but the solution is correct). This builtin does automatically solve for \$y\$ in terms of \$x\$.

Maxima, 50 bytes
f(N,M,a,b):=ic1(ode2(N*'diff(y,x)=M,y,x),x=a,y=b);

Try it online!
Takes maths-like expressions as input, e.g. 3*x^2+4*x-4. Outputs a quaint formatted ASCII string!

Love the ASCII art output! :D

JavaScript (ES6), 114 bytes
Just a port of @SurculoseSputum's answer.
Takes input as ([y, x])([N, M]).
p=>P=>(R=P.map(p=>p.map(([a,b])=>[a/++b,b])))[1].push([(g=i=>R[i].reduce((t,[a,b])=>t+a*p[i]**b,0))(0)-g(1),0])&&R

Try it online!

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Solve the Rook's Round Trip
The riddle
In yesterday's newspaper, I found a puzzle in which a Rook should start in the lower-left corner of a 12x12 checkerboard and then, during a round trip, visit each field exactly once except for a selection which must be avoided. The puzzle came with a picture that identified the fields to be avoided as black:

After some minutes, I came up with a solution, that you can find here.(There's no pic of the solution because you might want to challenge yourself by solving it first...)
The challenge
To write code that produces the same output as my code (that's in TikZ):
\documentclass[tikz,border=1cm]{standalone}\def~{document}\begin~\tikz{\def~{)rectangle++(,)(}\filldraw[step=1]grid(12,12)(8,0~4,~0,3~8,5~11,5~,8~11,9~2,10~4,11~7,11~,);\def~#1#2#3{)-|++(6-#1,4-#2)-|++(6-#3,4-}\draw[line width=2mm,red](.5,.5~1355~5353~5356~7540~7375~7575~7375~7373~7372~5555~5553~5552~7375~7373~7345~5355~5555~5355~5272~5395~5673~7373~7583~9555~7955~5555~8376);\fill[blue](.5,.5)circle(.3)}\end~

of the picture that shows the solution to the Rook's Round Trip. This is Code Golf!
Requirement(s) for the In-/Output

Use whatever language you want.
From your output, be able to somehow produce the pixelwise
exact same PNG as in the code section below.

PNG code
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABXoAAAV6AgMAAAAuWCySAAAADFBMVEX///8AAAD/AAAAAP8xSkYMAAAKsklEQVR4Aezdx5HcRhSA4a2aOz2TYBLDEOg6CUSxSeAuRwclsfHotFdZSBiJLftqt7deA0Po+6+vHlDzVcuCM7g4myRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJksqt04s7+D5fYVCiwo0H0eBp82d/0HvAly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvlNylw2+N9z8ixbfZ1NuX5ynL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fC9Tnh/f3jfYePB3rXbfGKVl8IwvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX75840ptWhpLQvVSCRvDMnhbGmrcaLjUi1XOb/tpbD/xD9pP47bnly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvny7v80tLvaN+2KjDb58+fLly5cvX758+fLly5cvX758+fLly5cvX758+W7rG8M3+7bfI//ZbryR8sSZL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fMvNnXzHcmYN02+9Tdi4/aVerHJ+442dnN+nfPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5Zv//reWjfZL5b+0jS9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvvv0DT57341gkP+YmC9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnyzfUttWhpLQ4kb4WBYBm9LXLiRMOh5fkvU7s9vfA++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPnyTfHNf2Nc6Bv2xRobfPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny3YFv1g+r1hIeEwcb6ffgy5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cv31I7oYwlo8RLhQ3LPd6ueo8XDa7Jh8755cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL99gEJa0sf1r3vjy5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5bsD34ZB1j3aP2K8kTqo8eXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLl2+pTUtjqbUMghIuNSyDtyUu3kgfvNjs/Dq/fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5bvpi+G2e81b0C58+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLlW0vYqGU8Jq51HfDly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5dvqZ1QxlKLB3HxRnrDco+3Zc1e/I/P79NmlPAeTz8fX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLlG7bGxhcpvje8Rm8Hvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58k3fCAcBY5ZvwqVqfPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5Vtq09JYGsrbiAfDMngbD+JSLuX81kFQ/qX48uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXL99xe8xb7hn2xwcZmvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58t30wXLDk9rGx8S9L8WXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++5eZOWmM8jzc2aVhu/rbHpV5k+jq/CeeXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPu/GG7717ztwJcvX758+fLly5cvX758+fLly5cvX758+fLly5cvX77pP6waD+KP2P7ZEy7Fly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLtyW+fPny5cuXL1++fPk2dEIZMzbiwbAM3jYMgoKNpsGLO/g+v/vA+eXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly/fM3nN22Xn17ztyZcvX758+fLly5cvX758+fLly5cvX758+fLly5cvX74xymWfB8tBDxoGjShJvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uVbaieUsdTiQVz7Rn7DcvO3d9+IBy/O9PyWqP2fX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fJtq913Wuc1b0G78OXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLl2+tfdDse5n/bLfbBl++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPmW2rQ0lk2Kbz4sg7fxIC5/40X/85s/SDq/TyOjF/nnly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLdx++387z/EM3X77z0lUnRr7351OdGPnOv3fdhZHv/fmPujDyPX7yverAyPcwf+q6AyPf+9X3pw6MfI9zrQMj3/nPrvim+x7+4nvNN933/l98f+rqy3fmm+57/KvvFd9s33k9X77XfJN9Dyv68v2Jb7Lvfb58d+M7T9sU+4a1+7aX4Hvky3c/vt/x/RRfvnxnvnz58uXLly9fvnz5rpv/fuPLly/fqcbX8yG+fDd7fhz0oHkQ++bd47P48yV8r/km+16s6Mv3im+273E9X76pWnz7f7+F76GrL9+Lvt9/43vs+v1Nvve7fv+Y76Hr9+f5XvT9/Qe+x66/D8P3UP/20IGRbz3AV30Y+R7q8eWb7lv/Fa2DFt8K/FO+Ft8gvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvrv0Lbp1v7YHBwQAABAAgEz0f40ZoMqAKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAO+uutlkASEAAAAASUVORK5CYII=

Bonus imaginary internet points

Write the code in TikZ
Your TikZ-code should compile without any errors, warnings, and boxes.
You should be able to produce a PNG-file with Overleaf that, when saved in the same dimensions, must be able to withstand a bitwise comparsion with my solution.

What are the exact requirements for output?

@Unrelated String: Thank you for asking this question. I will clarify above within the post.

@Joe85AC I edited the first paragraph in an attempt to make it easier to understand, please do review the change.

@Jonathan Allan: Thank you, these changes are perfect. There's seems to be quite a difference between native speakes and non-native speakers... ;-)

Requiring the output to be exactly the same as the image seems unnecessarily restrictive to me. What if there's another solution to this puzzle? Also, please consider allowing other languages to compete, I don't think many of us golf in TikZ.

After solving this, it seems like this puzzle has a unique solution. Great puzzle I must say.

The ,border=1cm can be deleted right? Also 2mm can be replaced by 6 which looks similar but I'm not sure it's exactly the same.

To reiterate the second part of @SurculoseSputum comment: would sure be a lot more fun for everybody if we could just solve this puzzle as a straight-up code-golf challenge. Maybe add a Bonus imaginary internet points section for  TikZ solutions that are shorter than yours. You could also post your answer as part of the competition! :-)

Borderline dupe, other than the restrictive output format here.

@Surculose Sputum: The answer is unique, as you already found out.
For your personal coding pleasure, I'll change a couple of the rules :-)

@Noodle9 I'll iterate over the rules. :)

@79037662 The border was also part of the image in the newspaper, so I decided to include it in my TikZ. The 6 looks similar, but would compute to 2.11667mm

@Joe85AC You should decide what the challenge is going to be and make it so. You can't leave in this state of being two challenges in one and thus not a well specified challenge.

@Noodle9 As I'm a Newbie, I'd appreciate your help to edit the challenge in a way that it becomes acceptable for the community. Please let me learn from you edits.

@Joe85AC I've attempted to refactor the question to address Noodle9's feedback. Feel free to roll it back if you disagree with any of the edits

@mathjunkie Great! This seems much better now. My next question will hopefully better right from the start!

@Joe85AC It was still really two challenges so I've made some more changes to your already altered post. Feel free to roll it back or make additional changes if you don't like what I've done.

@Noodle9 Wow, the challenge became even better now. It seems like the headline was still a major bummer. Thanks!

"when saved, must be able to withstand a bitwise comparison" -- compression does not produce the same results with different compressors and different settings (and not even necessarily produces the same results with the same compressor with the same settings), so this requirement restricts us to either storing a compressed raw .PNG file or programming in your own favorite environment.

Feedback on the question: this is all framed as the rook-solving problem, but ultimately, the goal is simply to generate a particular PNG string? IMHO it doesn't leave a lot of scope for creativity. Would be more interesting if the output just had to "closely resemble" the picture, without requiring pixel perfection or a particular image format.

I have an answer that doesn't quite beat yours : https://rentry.co/fbtce :)

@SteveBennett Note that "from your output" you need to "somehow" produce a png. Your output can be a vector that, if you --later on, with some other tools -- clip, compress, upscale, downscale, rotate, will produce the pixelperfect PNG. This does not mean that your output HAS TO BE the PNG itself...

@mypronounismonicareinstate Note that "from your output" you need to "somehow" produce a png. bitwise comparison is only for the TikZ version...

What is the Note that "from your output" you need to "somehow" produce a png. sentence supposed to mean? I do not understand it at all. None of "clip, compress, upscale, downscale, rotate" were mentioned in the question. "This does not mean that your output HAS TO BE the PNG itself" - the question quite clearly says it must be.

@Joe85AC Well, ok, but that doesn't change the fact that the whole "rook's tour puzzle" bit is a red herring. The problem is just "draw this picture, exactly as follows".

C (gcc), 959 947 937 bytes
-12 -10 bytes thanks to ceilingcat!
#define Z g&&S(r,c+40,20,q,1)
#define W write(o
H=1402;y=4206;char*s="VDRMOSMWK[I^HaGcFeEgDiCkBlAnAo@p@q?r?s>t>u>u=v=w=w=w<x<x<x<x<x<x<x<x<x=w=w=w=v=v>u>t>t?s?r@q@pAoBmBlCjDhEfFdGbI_J]LYNUPPSJ",*I,d[]="\0o\20\x90\xef",*G=",&&* ,* ,&&*%* %&#%*%*,#,#,&*,*%*)) ) %*%#%*%#%*),*%*,*%*,*)))%*%#%*%#%#)%*%*,*) ,* %*%*%#%#,#%* %*%*,*,#,*),*%*%#%#,#)))%&# ,*,#,#)%&&&&#%# %&#";P[]={0,255,~0<<16,~0},o,C,u,v,i,j,r,c,q=60,z=100;S(a,b,w,h,X){for(h+=a;h/a;h--)for(C=b+w;C/b;)bcopy(P+X,I+h*y+C--*3,3);}main(g){I=memset(malloc(y*H),~0,y*H);for(W=open("a.png",33537),"\x89PNG\r\n\32\n\0\0\0\rIHDR\0\0\5z\0\0\5z\b\2\0\0\0\xDCTSV\0Z\eNIDAT\b\35",43);++i<13;)for(j=0;j<12;8&Z)g=*G++%32,u=j++==5,v=i==7,S(r=i*z+i/7,c=j*z|j>6,z+u,z+v,0),g&&S(r+!v,c+1,98+u,98+v,3),1&Z,r+=40,g&2&&S(r,c,q,20,1),g&4&&S(r,c+40,q,20,1);for(r=61;r--;)S(1281-r,s[r*2]+q,s[r-~r]-q,0,2);for(r=H;r--;I+=W,I,y))*d=!r,W,d,6);W,"\xfc\xa3\xea\xe1\xe8\x93\274a\0\0\0\0IEND\256B`\x82",20);}

Try it online!
Each position on the board is stored in the lower four nibbles of the characters of the string G. A zero means a black tile, otherwise each bit corresponds to one "arm" of a junction:
 0
1 2
 3

So a ┌ junction would be stored as the bits 1100, for example.
We simply loop through the string and draw tiles accordingly. Care is taken to match the jankiness that occurs in the middle of the board (slightly wider tiles and therefore everything shifted down/right thenceforth).
Everything is drawn as filled rectangles. An empty tile is just a black rectangle with slightly smaller white rectangle painted over it.
The circle caused some headache; just the data for it takes almost as much as the data for the rest of the board. I tried some circle-drawing methods, but the circle is not symmetrical, so no luck.
Various CRCs and similar are hardcoded, since we will always output the same image.
Stores output to "a.png".

@ceilingcat Hm, getting "a.png  CRC error in chunk IDAT (computed 64aecef3, expected 00004945)" with that. Something to do with the wide-char, it looks like.

If you're using gcc on windows, try -fno-short-wchar and see if the wchar_t* literal works

929 bytes

If the wchar_t* literal doesn't work, try this one "\xfc\xa3\xea\xe1\xe8\x93\274a\0\0\0\0IEND\256B\\x82"`

@ceilingcat No such luck on the wide-chars, but well on the second string.

Mathematica, 1900 bytes
"H4sIAAAAAAAACsVWa1ATVxSOtRQNYFqIIkrEgiAUQrQODW0Eq6AFKYICrRQlWKjtqCQgYFA24KPBYcCgqGQwBca3xRaoHQwQWEQwMQOIj9ZYNFlDCA8xWZIAIYQk3bR11D/rdPujO3P3nr3nce+53zlnT1Hsps+c8IvwOBzOKTIifAsOZ3fANt6ajawEbg0oQybH2M/j1yOzFWd7Ic850uJQhJybEZGYhcM5uNjGLNyZHxYiRHtk+Nr43D617JdMZTDxnZR9NyImtnr7ai8G3krYNpd391BUPS1jwIe4/fmnzV6GALVEFFg157jzhHmEbz8HSlkhLD599/nFry2MhWMqf8Comw8CRjwdvMmj0BVdvLoxVdeXUy8WAQ7Fxvln8YX434svxF+xYeO8tGHjvLRh47xiw8ZxHktfRlO7gSwXYplH8B/a8g9aCqWWj9YeQhQQKVUX798SVE0ePbj0PYhOmHhXy6a0cO3R1ZIvwaknTMpVbI+2RIlpP+jm68ZhYdwbIaJNS9Yo6jtz4jy1Z8tIV8H6Isf58G1STWWaVcRKBcRtxx4dk+aHjmGzruoybGRfzu0hp3JPehfKd/LPHUHX0U8PytU7p0RDV1gC/r2V06IK7Bc78ngm9Ajc3FT/03RMg9/9E7R4msRCboymZFlBjLeFEMxuqiH9+hPu4TDvzf0kdPHtJczhM40p4sgdfdWRmHekQFlAqazDWRq91I5WxkmgPwofjNjX6RBkYO4tvwVDJR9PYXZHcJDZ/q28DIxb7ej67CmqCtxgFNUVnSQ1URvsKGyHO+2Y3eGPhzQ7+Y5eCsfPO91dU526asQ9XWJeDGVPYgYbMObHXdF1JzHEYbvUcdno4WroA8I497JKmnzyCbtb9ZiBgd3AnvcRXHqknQ6SzqNfTXCi07hp4uF1u62feGDGJC8ETFhSyFdUCGLt0YXreqih8de89i92b/PhEoKab/wHRNLnucU+7JEuQxyh9SdOZO054/dAPmZhO51fNpSLPXTpoFSZpHJrfcI96gk29Q5r0YE5wL48HOyXNuOorgC/KezHnjFmy6OQgEzZ21vqvRK3IrhcON49fJax3yoqyMzpjsVcLVV5ib0t3mwloSNB84ZsaQF/TQ4Ykv/GbfKppRIxxzXzvsDIfufnHJeIlvMpX5gH+IvCGrzZaqjZhB0SqpI22pFB+LEh5h56EkP+OnJu9MxuSHzbWSnt1J7FXmgM7lCJo++oJ0lys4ayx5OT1h9WSexbBcAbiM+xJ70OAfmhrX5lhehF6K5ETbJLiPjkgOUUtpLjF1iOOQS6WG3MV5IFv/P3GNDvfuaW7yjZVh/XQQA9LtBCxmlK5KJrrX5WIfiQ0PGGTFnHRioxZxskXsQSvqneodnxYZcWk8obGYORe3W2PwteUqKxeSLnLC+FIempzcIZPUpzY1gNrWmuNRUzg6DaXgdoI+hxhCkWlMEEuaaCOR+yXoczZ+vJz4TmcbYiqZ1lkOQFL50qHw9xJ8hcIDx4VKnIwOnJI3kD5tUHjQvGZeYBU7egERbHgDHA1el9QLGJIaTYr4AOgyRoBKg2LpiUaSvvGoqYOyACCLgqH8t6T11gis6nN4Fa4phMpxK6Q2v+OtgDgfK18xYUIN91BdbWXXRDGMBT0sTmTB2eKjiuoB3g+lus3gLb1vVwFfw9SAGiTAzjpiHhUFIfaxIWBDxhiQU1cL4GbiPLWDS9gcrTmFbqDaU8jZBvNOmjDLLeGROh2CC7YzKtQKZKdwLQNZ3PeOoK5gAsKwQCDibLlFdfFZMMFRyqngRGjcmxaD0jIrfh2oMqhb/d/9Dkvr7laSZgnbVnKNulsP9gkK3bj1y/Kbx2XcrhPwH+UUsXJwwAAA=="~ImportString~"Base64"

I tried to use the grid-board to my advantage, and it still probably would be, but the thicknesses of the lines seem to very by 1 px either way, making this a likely comparable solution in length.

Python 2, 3864 3846 3832 3815 bytes
I’m new, so I could use help shortening it. It outputs to a file in the same folder called i.png.
from base64 import*
open('i','wb').write(b64decode("iVBORw0KGgoAAAANSUhEUgAABXoAAAV6AgMAAAAuWCySAAAADFBMVEX///8AAAD/AAAAAP8xSkYMAAAKsklEQVR4Aezdx5HcRhSA4a2aOz2TYBLDEOg6CUSxSeAuRwclsfHotFdZSBiJLftqt7deA0Po+6+vHlDzVcuCM7g4myRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJkiRJksqt04s7+D5fYVCiwo0H0eBp82d/0HvAly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvlNylw2+N9z8ixbfZ1NuX5ynL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fC9Tnh/f3jfYePB3rXbfGKVl8IwvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX75840ptWhpLQvVSCRvDMnhbGmrcaLjUi1XOb/tpbD/xD9pP47bnly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvny7v80tLvaN+2KjDb58+fLly5cvX758+fLly5cvX758+fLly5cvX758+W7rG8M3+7bfI//ZbryR8sSZL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fMvNnXzHcmYN02+9Tdi4/aVerHJ+442dnN+nfPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5Zv//reWjfZL5b+0jS9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvvv0DT57341gkP+YmC9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnyzfUttWhpLQ4kb4WBYBm9LXLiRMOh5fkvU7s9vfA++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPnyTfHNf2Nc6Bv2xRobfPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny3YFv1g+r1hIeEwcb6ffgy5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cv31I7oYwlo8RLhQ3LPd6ueo8XDa7Jh8755cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL99gEJa0sf1r3vjy5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5bsD34ZB1j3aP2K8kTqo8eXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLl2+pTUtjqbUMghIuNSyDtyUu3kgfvNjs/Dq/fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5bvpi+G2e81b0C58+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLlW0vYqGU8Jq51HfDly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5dvqZ1QxlKLB3HxRnrDco+3Zc1e/I/P79NmlPAeTz8fX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLlG7bGxhcpvje8Rm8Hvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58k3fCAcBY5ZvwqVqfPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5Vtq09JYGsrbiAfDMngbD+JSLuX81kFQ/qX48uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXL99xe8xb7hn2xwcZmvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58t30wXLDk9rGx8S9L8WXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++5eZOWmM8jzc2aVhu/rbHpV5k+jq/CeeXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPu/GG7717ztwJcvX758+fLly5cvX758+fLly5cvX758+fLly5cvX77pP6waD+KP2P7ZEy7Fly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLtyW+fPny5cuXL1++fPk2dEIZMzbiwbAM3jYMgoKNpsGLO/g+v/vA+eXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly/fM3nN22Xn17ztyZcvX758+fLly5cvX758+fLly5cvX758+fLly5cvX74xymWfB8tBDxoGjShJvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uVbaieUsdTiQVz7Rn7DcvO3d9+IBy/O9PyWqP2fX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fLly5cvX758+fJtq913Wuc1b0G78OXLly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLl2+tfdDse5n/bLfbBl++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPny5cuXL1++fPmW2rQ0lk2Kbz4sg7fxIC5/40X/85s/SDq/TyOjF/nnly9fvnz58uXLly9fvnz58uXLly9fvnz58uXLdx++387z/EM3X77z0lUnRr7351OdGPnOv3fdhZHv/fmPujDyPX7yverAyPcwf+q6AyPf+9X3pw6MfI9zrQMj3/nPrvim+x7+4nvNN933/l98f+rqy3fmm+57/KvvFd9s33k9X77XfJN9Dyv68v2Jb7Lvfb58d+M7T9sU+4a1+7aX4Hvky3c/vt/x/RRfvnxnvnz58uXLly9fvnz5rpv/fuPLly/fqcbX8yG+fDd7fhz0oHkQ++bd47P48yV8r/km+16s6Mv3im+273E9X76pWnz7f7+F76GrL9+Lvt9/43vs+v1Nvve7fv+Y76Hr9+f5XvT9/Qe+x66/D8P3UP/20IGRbz3AV30Y+R7q8eWb7lv/Fa2DFt8K/FO+Ft8gvnz58uXLly9fvnz58uXLly9fvnz58uXLly9fvrv0Lbp1v7YHBwQAABAAgEz0f40ZoMqAKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAO+uutlkASEAAAAASUVORK5CYII="))
I could use advice on shortening it. This is the first time I have ever done anything like this.

Would it be shorter to store the PNG in a bytestring directly, escaping all offending characters? (there's also base64.b85encode and base64.b8decode; these seem to be better than base64) Besides, you can remove c.close(), and the with statement seems unnecessary because the program will shortly exit and close everything anyway. You can also skip the definitions of b and a and simply use c.write(a2b_base64("long_string")).

I removed c.close() and defining b and a, but on my editor it wouldn’t run without the with statement. I don’t know how to use the base64.decode(), but I can look it up. Thank you for the help!

You can rearrange everything a bit to cut it down to 3815 bytes.

Thanks for the suggestion on cutting it! I didn’t change the import statement but I did cut the with statement. It didn’t produce a png when written to a file without an extension, or it could have been 4 bytes shorter.

@BardicWizard file name should be irrelevant, as the format is still PNG. You can check that by opening the file in any PNG viewer (or even web browser like Google Chrome). Also I'm not sure why you don't want to change the import statement, as it saves 1 byte.

I had the bytecount wrong last time, so I updated to use your version @SurculoseSputum. Thanks! I hadn’t thought about the extension and it was fine when saved to a file.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
The Double-Castle Numbers™
Introduction
A double-castle number™ is a positive integer number that has a pattern of $$\underbrace{a\cdots a}_{m\text{ }a\text{s}}b\underbrace{a\cdots a}_{m\text{ }a\text{s}}b\underbrace{a\cdots a}_{m\text{ }a\text{s}}\underbrace{a\cdots a}_{n\text{ }a\text{s}}b\underbrace{a\cdots a}_{n\text{ }a\text{s}}b\underbrace{a\cdots a}_{n\text{ }a\text{s}}$$
Where \$m>0\$, \$n>0\$ and \$a-b=1\$ are all non-negative integers, when represented in an integer base \$B\$ where \$B\ge2\$. It is so named because a bar chart representing the base-\$B\$ digits of such a number resembles two castles of the same height place- side by side.
For example, \$7029\$* is a double-castle number because when represented in base 2 it becomes \$1101101110101_2\$, which can be split into \$11011011\$ and \$10101\$.

This is the case when \$m=2\$, \$n=1\$, \$a=1\$, \$b=0\$ and \$B=2\$.
\$305421994212\$ is also a double-castle number because when represented in base 8 it becomes \$4343444344344_8\$, which can be split into \$43434\$ and \$44344344\$.

This is the case when \$m=1\$, \$n=2\$, \$a=4\$, \$b=3\$ and \$B=8\$.
For \$a>=10\$, \$a\$ should be treated as a single base-\$B\$ "digit" with the value of \$a\$ in base-10. \$206247763570426655730674346\$ is a double-castle number in base-16, whose representation in base-16 is \$\text{AA9AA9AAAAAA9AAAA9AAAA}_{16}\$. Here, \$a=10\$ but is treated as a single digit \$(10)_{16}=\text{A}_{16}\$.

This is the case when \$m=2\$, \$n=4\$, \$a=10\$, \$b=9\$ and \$B=16\$.
Challenge
Write a program or function that, given integers \$m>0\$, \$n>0\$, \$1\le a<B\$ and \$B\ge2\$, calculate the corresponding double-castle number™ and output it in base-10.
Test Cases
The input below are in base-10, but in the case say when \$a=11\$ and \$B=12\$ the input should be understood as \$B_{12}\$.
m, n, a,  B  => Output
1, 1, 1,  2  => 693
2, 1, 1,  2  => 7029
1, 2, 3,  4  => 62651375
1, 2, 4,  8  => 305421994212
1, 4, 7,  10 => 7676777776777767777
2, 4, 8,  16 => 164983095594247313234036872
2, 4, 10, 16 => 206247763570426655730674346

Winning Condition
This is a code-golf challenge, the shortest submission in each language wins. No standard loopholes allowed.
*7029 comes from my ID minus it written reversed.

How are numbers > 10 in the input to be represented. Say, for base 16, will it be "10, 11, 12, 16", or "A, B, C, 16"? Are we free to pick?

Could you add one or multiple test case where $a\geq10$? Both my answers apparently failed those cases.. (i.e. 2, 4, 10, 16 => 206247763570426655730674346). Also, maybe some test cases where n and m are larger than 10. And change the term 'digits' to 'numbers' in the sentence "It is so named because a bar chart representing the digits of such a number resembles two castles of the same height placed side by side." please, since it's incorrect and actually made me thing we only had to work with digits.

@KevinCruijssen I have clarified that the inputs are shown in base-10 but should be treated as the digit with the same value in base-B.

@Abigail Oops I may have misunderstood your question, I mean you may receive like 10 as an input in base-16 but the number should be treated as $A_{16}$ instead of $10_{16}$ when calculating.

@KevinCruijssen To further clarify the case I am going to add an image illustrating what I mean “the base-B digits”.

Python 2, 83 81 79 72 bytes
-9 bytes thanks to @ovs!
-2 bytes thanks to @dingledooper!
m,n,a,B=input()
r=0
for s in n,m+n,m,m:r+=B**n;n-=~s
print~-B**n/~-B*a-r

Try it online!
Calculate aaaa...aaa in base B, then subtract 1 at the appropriate digits.

79 bytes

@dingledooper Thanks, I didn't know ** takes precedence over ~-.

72 bytes as a full program.

@ovs Updating n is really clever, thanks!

@ovs Why did you delete your answer? I think you can make it work for arbitrary a at a cost of only 2 bytes (build up the first number using '1' instead of \a`and then multiply bya`).

@Neil Pythons int function just doesn‘t work for any base >37: Try it online!.

C (gcc) -lm, 83 \$\cdots\$ 81 80 bytes
Saved 1 2 bytes thanks to ceilingcat!!!
#define P-pow(B,n
f(m,n,a,B){n=-(1 P*3+3*m+4))/~-B*a P)P-~n)P*3+2+m)P*3+3+2*m);}

Try it online!
Calculates the wall to full height first and then crenellation is performed through subtraction.

05AB1E, 10 12 bytes
иεÐ)²<.ý}˜sβ

Try it online or verify all test cases.
+2 bytes as bugfix for \$a\geq10\$ (initial 10-byter answer: ×εÐ¬<ý}Jsö - Try it online or verify all test cases).
Explanation:
и             # Repeat the second (implicit) input the first (implicit) inputs amount of
              # times as list
              #  i.e. [1,2] and 4 → [[4],[4,4]]
 ε            # Map each to:
  Ð           #  Triplicate the value
              #   i.e. STACK: [4,4],[4,4],[4,4]
   )          #  Wrap them into a list
              #   i.e. STACK: [[4,4],[4,4],[4,4]]
    ²<        #  Push the second input - 1
              #   i.e. STACK: [[4,4],[4,4],[4,4]],3
      .ý      #  Intersperse this list with this value
              #   i.e. STACK: [[4,4],3,[4,4],3,[4,4]]
        }˜    # After the map: flatten the list
              #  i.e. [[[4],3,[4],3,[4]],[[4,4],3,[4,4],3,[4,4]]]
              #   → [4,3,4,3,4,4,4,3,4,4,3,4,4]
          s   # Swap to get the third (implicit) input
           β  # Base-convert the list we created to an integer using the input as base
              #  i.e. [4,3,4,3,4,4,4,3,4,4,3,4,4] and 8 → 305421994212
              # (after which the result is output implicitly)

K (ngn/k), 26 bytes
{z/,/(2+3*x)#'(x#'y),'y-1}

Explanation
{z/,/(2+3*x)#'(x#'y),'y-1} / using x=2 1; y=1; z=2 as an example
              (x#'y)       / (m;n) copies of a;     ex: (1 1;1)
                    ,'y-1  / append b=a-1 to each   ex: (1 1 0;1 0)
     (2+3*x)               / length of each sublist ex: (8;5)
            #'             / copy to each length    ex: (1 1 0 1 1 0 1 1; 1 0 1 0 1)
   ,/                      / join                   ex: (1 1 0 1 1 0 1 1 1 0 1 0 1)
 z/                        / convert from base B    ex: 7029

Try it online!

perl -Mbigint -alp, 87 bytes
($m,$n,$a,$B)=@F;$o=$o*$B+$_ for(($a)x$m,$a-1)x2,($a)x$m,(($a)x$n,$a-1)x2,($a)x$n;$_=$o

Try it online!
We take the input, turn it into a corresponding list of digits, then convert it to base 10. Input is taken as space separated numbers on STDIN.
The TIO code does have some header code; this is just there so it works with multiple inputs -- without the header, it will only do the first line correctly. (those header bytes aren't counted).

Jelly,  12  11 bytes
‘3×þṬạṖ€Ẏḅ⁵

A full program accepting three arguments: [m,n] a B which prints the result.
Try it online!
How?
‘3×þṬạṖ€Ẏḅ⁵ - Main Link: [m,n]; a
‘           - increment -> [m+1, n+1]
 3          - three
   þ        -   outer product ([1, 2, 3] by [m+1, n+1]) with:
  ×         -     multiplication -> indexes of low points (with an extra low on the
                                     right for each of castle)
    Ṭ       - un-truth (vectorises) -> two lists of 1s and zeros (1s at low points)
     ạ      - absolute difference (with a) -> convert zeros to a and 1s to a-1=b
      Ṗ€    - pop from each -> remove the extra low points)
        Ẏ   - tighten -> from a list of two lists to a flat list
          ⁵ - programs 5th argument = B
         ḅ  - convert dfrom base
            - implicit print

Charcoal, 27 bytes
Ｎθ≔⭆Ｅ²Ｎ⪫Ｅ³×0ι1δＩ⁻×Ｎ⍘⭆δ1θ⍘δθ

Try it online! Link is to verbose version of code. Takes input in the order B, m, n, a. Explanation:
Ｎθ

Input B.
≔⭆Ｅ²Ｎ⪫Ｅ³×0ι1δ

Input m and n. For each value, create a string of that many 0s. Join 3 of those strings with 1s. Join the final strings together.
Ｉ⁻×Ｎ⍘⭆δ1θ⍘δθ

Replace all of the characters in the string with 1s, convert from base B, multiply by a, then subtract the string converted from base B, and output in decimal.
Note that although Charcoal's string based conversion accepts numeric bases higher than 62 this only succeeds when (as here) all the digit values are less than 62.
Slightly shorter solutions are possible that place upper limits on the supported value of B:
ＮθＩ↨Ｅ⭆Ｅ²Ｎ⪫Ｅ³×ι℅θ℅⊖θ℅ιＮ

Try it online! Link is to verbose version of code. Takes input in the order a, m, n, B. Works for B up to 65536. Works by creating a string of characters whose ordinal is a or b, then converting back into ordinals and decoding using base B. 22 bytes.
ＮθＩ⍘⭆Ｅ²Ｎ⪫Ｅ³×ι⍘θφ⍘⊖θφＮ

Try it online! Link is to verbose version of code. Takes input in the order a, m, n, B. Works for B up to 62. Works by creating a string of characters whose base B code is a or b, then decoding using base B. 21 bytes.
Ｉ⍘⭆Ｅ²Ｎ⪫Ｅ³×ιεＩ⊖εＮ

Try it online! Link is to verbose version of code. Takes input in the order a, m, n, B. Works for B up to 10. Works by creating a string of characters whose value is a or b, then decoding using base B. 16 bytes.

Husk, 12 11 bytes
`BṁȯJ←¹R3`R

Try it online!
Takes arguments in the order a [m,n] B.
Explanation
`BṁȯJ←¹R3`R  Implicit arguments a, [m,n], B.
             Say a=3, m=1, n=2, B=4.
  ṁȯ         Map over [m,n] and concatenate:
               Use n=2 as example.
         `R    Repeat a that many times: [3,3]
       R3      Repeat three times: [[3,3],[3,3],[3,3]]
     ←¹        a decremented: 2
    J          Join by it: [3,3,2,3,3,2,3,3]
             Result: [3,2,3,2,3,3,3,2,3,3,2,3,3]
`B           Interpret in base B: 62651375

APL (Dyalog Unicode), 16 bytes
⎕⊥⎕-~1\⍨∊5⍴¨⎕,¨0

Try it online!
A full program that takes m n, a, B on three lines of stdin.
How it works
⎕⊥⎕-~1\⍨∊5⍴¨⎕,¨0
            ⎕     ⍝ Take (m n) from stdin
             ,¨0  ⍝ Append 0 to each; (m 0)(n 0)
         5⍴¨      ⍝ Repeat each to length 5; (m 0 m 0 m)(n 0 n 0 n)
        ∊  ⍝ Flatten; (m 0 m 0 m n 0 n 0 n)
     1\⍨   ⍝ Expand 1 by above: m/n become m/n copies of 1, 0 becomes single 0
    ~      ⍝ Boolean negate the above
  ⎕-       ⍝ Subtract each from a (taken from stdin)
⎕⊥         ⍝ Convert from base B (taken from stdin) to integer

Does J have any analog of APL's ⎕?  It seems to help a lot in challenges with many args.

@Jonah IIRC anything close to stdin costs at least 5 bytes, so I'd just use explicit adverb 1 :'body' / conjunction 2 :'body'.

J, 35 bytes
{:@[#.((#10$5$0 1-~{.)~[:,5$"1,.&1)

Try it online!

JavaScript, 75 bytes
There may be rounding errors due to JavaScript's integer limit.
(m,n,a,B)=>B**(3*(m+n)+4)/~-B*a-B**(n-~n)-B**(m+3*n+2)-B**(2*m-3*~n)-B**n-1

Try it online!


text:
Name the Aztec year
It's time for another Mesoamerican calendar! The Xiuhnelpilli was used by the Aztecs (more properly, the Mexica) to name their years. Each year has a number and a sign. Here's part of the cycle:
Input; Output
1089; 13 Calli
1090; 1 Tochtli
1091; 2 Acatl
1092; 3 Tecpatl
1093; 4 Calli
1094; 5 Tochtli
1095; 6 Acatl
1096; 7 Tecpatl
1097; 8 Calli
1098; 9 Tochtli
1099; 10 Acatl
1100; 11 Tecpatl
1101; 12 Calli
1102; 13 Tochtli
1103; 1 Acatl
1104; 2 Tecpatl
1105; 3 Calli
1106; 4 Tochtli
1107; 5 Acatl
1108; 6 Tecpatl
1109; 7 Calli
1110; 8 Tochtli
1111; 9 Acatl
1112; 10 Tecpatl
1113; 11 Calli
1114; 12 Tochtli
1115; 13 Acatl
1116; 1 Tecpatl
1117; 2 Calli
1118; 3 Tochtli
1119; 4 Acatl
1120; 5 Tecpatl
1121; 6 Calli
1122; 7 Tochtli
1123; 8 Acatl
1124; 9 Tecpatl
1125; 10 Calli
1126; 11 Tochtli
1127; 12 Acatl
1128; 13 Tecpatl
1129; 1 Calli
1130; 2 Tochtli
1131; 3 Acatl
1132; 4 Tecpatl
1133; 5 Calli
1134; 6 Tochtli
1135; 7 Acatl
1136; 8 Tecpatl
1137; 9 Calli
1138; 10 Tochtli
1139; 11 Acatl
1140; 12 Tecpatl
1141; 13 Calli
1142; 1 Tochtli

The pattern should be clear enough: the number is counting up to 13, and the sign goes Tochtli, Acatl, Tecpatl, Calli. After 52 years the pattern repeats itself.
The program will take as input an integer between 1064 (the year the Mexica left their mythological homeland of Aztlan) and 1521 (fall of Tenochtitlan to the Spaniards), inclusive, and output the corresponding year name. It can be a single string (in which case there needs to be a space between number and sign), or a tuple (e.g. ["2", "Calli"]) of your preferred format. The sign name is always capitalised.
Handling years outside the specified range is not necessary. It's code-golf, so the shortest code wins!
Test cases
The entire example list above, plus:
Input; Output
1064; 1 Tecpatl
1521; 3 Calli

Can we output the numbers 1-13 with 0 indexing? i.e. can I output numbers 0-12? Do I have to output the 4 strings for the signs of the years? Can I output 4 distinct numbers? Or can I just output the first two letters, e.g. "To, Ac, Te, Ca"? or maybe 4 distinct letters, one per sign? e.g. "tOchtli, Acatl, tEcpatl, Calli"?

@RGS No and no. Otherwise this would just be modding the year twice. The goal is a sensible Aztec name for a year, and they did not count from zero.

What about the third question? Can I output one letter per sign, namely OAEC for Tochtli, Acatl, Tecpatl and Calli respectively?

@RGS Same reasoning: no.

Does case matter? Can we output all uppercase or all lowercase?

@Shaggy The sign must be capitalised. So title case.

05AB1E, 30 bytes
Ì13%>.•19ŠSBÿ®Ï¿¾Ñλ1Ï7qι•#™Iè‚

Try it online or verify all test cases.
Explanation:
Ì       # Increase the (implicit) input by 2
 13%    # Take modulo-13 on that
    >   # And increase it by 1
.•19ŠSBÿ®Ï¿¾Ñλ1Ï7qι•
        # Push compressed string "tecpatl calli tochtli acatl"
  #     # Split it on spaces: ["tecpatl","calli","tochtli","acatl"]
   ™    # Titlecase each: ["Tecpatl","Calli","Tochtli","Acatl"]
    Iè  # Index the input into it (0-based and with automatic wraparound)
‚       # Pair the two together
        # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress strings not part of the dictionary?) to understand why .•19ŠSBÿ®Ï¿¾Ñλ1Ï7qι• is "tecpatl calli tochtli acatl".

Python 3, 68 62 59 bytes
Saved 6 9 bytes thanks to my pronoun is monicareinstate!!!
lambda n:((n+2)%13+1,"TCTAeaocclcaplhtaitlt l l i"[n%4::4])

Try it online!

62 bytes without := assignment

@mypronounismonicareinstate Nice one - thanks! :-)

59 bytes with every-nth-element indexing

@mypronounismonicareinstate Ah yes, very good - thanks! :D

dc, 63 62 characters
[Tecpatl]0:y[Calli]1:y[Tochtli]2:y[Acatl]3:y?d2+13%1+n32P4%;yp

Explained:
[Tecpatl] 0 :y    # store the string "Tecpatl" in array y at index 0
[Calli]   1 :y    # store the string "Calli" in array y at index 1
[Tochtli] 2 :y    # store the string "Tochtli" in array y at index 2
[Acatl]   3 :y    # store the string "Acatl" in array y at index 3
?                 # read input input
d                 # duplicate it to keep a copy for later
2+ 13% 1+ n       # the usual formula: (year + 2) % 13 + 1, then print it
32 P              # print a space
4 %               # use the left copy of input for formula: year % 4
;y p              # get the value from array y at the given index, then print it

Sample run:
bash-5.0$ dc -e '[Tecpatl]0:y[Calli]1:y[Tochtli]2:y[Acatl]3:y?d2+13%1+n[ ]n4%;yp' <<< 1111
9 Acatl

Try it online! / Try all test cases online!

perl -pl, 61 bytes
$_=(($_+3)%13||13).$".(qw[Tecpatl Calli Tochtli Acatl])[$_%4]

Try it online!
Nothing special going on, modding the year twice, with some aligning. $" is a variable which by default holds a space.

59 bytes

As well as Arnauld's change, you can use barewords instead of qw[...] and using -n and say+($_...,$",... instead of -p saves one too!

Java 8, 63 62 bytes
y->1-~-~y%13+" "+"Tecpatl Calli Tochtli Acatl".split(" ")[y%4]

-1 byte thanks to @ceilingcat.
Try it online.
Explanation:
y->          // Method with integer parameter and String return-type
  1-         //  Decrease 1 by:
    ~-~y     //   (-y-2)
        %13  //   Modulo-13
  +" "       //  Append a space
  +"Tecpatl Calli Tochtli Acatl".split(" ")
             //  Split these four words as array
    [y%4]    //  And take the (0-based) year-modulo-4'th value

Whitespace, 344 bytes
[S S S N
_Push_0][S N
S _Duplicate_0][T   N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve][S N
S _Duplicate_input][S S S T S N
_Push_2][T  S S S _Add][S S S T T   S T N
_Push_13][T S T T   _Modulo][S S S T    N
_Push_1][T  S S S _Add][T   N
S T _Print_as_integer][S S S T  S S T   N
_Push_9_tab][T  N
S S _Print_as_character][S S S T    S S N
_Push_4][T  S T T   _Modulo][S N
S _Duplicate][N
T   S S N
_If_0_Jump_to_Label_0][S S S T  N
_Push_1][T  S S T   _Subtract][S N
S _Duplicate][N
T   S T N
_If_0_Jump_to_Label_1][S S S T  N
_Push_1][T  S S T   _Subtract][N
T   s S S N
_If_0_Jump_to_Label_2][S S S T  T   N
_Push_3_l][S S S T  S T T   N
_Push_11_t][S S T   T   S S S N
_Push_-8_a][S S T   T   T   S N
_Push_-6_c][S S T   T   S T S S S N
_Push_-40_A][N
S S N
_Create_Label_PRINT_LOOP][S S S T   T   S T S S T   N
_Push_105][T    S S S _Add][T   N
S S _Print_as_character][N
S N
N
_Jump_to_Label_PRINT_LOOP][N
S S S N
_Create_Label_0][S N
N
_Discard][S S S T   T   N
_Push_3_l][S S S T  S T T   N
_Push_11_t][S S T   T   S S S N
_Push_-8_a][S S S T T   T   N
_Push_7_p][S S T    T   T   S N
_Push_-6_c][S S T   T   S S N
_Push_-4_e][S S T   T   S T S T N
_Push_-21_T][N
S N
N
_Jump_to_Label_PRINT_LOOP][N
S S T   N
_Create_Label_1][S N
N
_Discard][S S S N
_Push_0_i][S S S T  T   N
_Push_3_l][S N
S _Duplicate_3_l][S S T T   S S S N
_Push_-8_a][S S T   T   S S T   T   S N
_Push_-38_C][N
S N
N
_Jump_to_Label_PRINT_LOOP][N
S S S S N
_Create_Label_2][S S S N
_Push_0_i][S S S T  T   N
_Push_3_l][S S S T  S T T   N
_Push_11_t][S S T   T   N
_Push_-1_h][S S T   T   T   S N
_Push_-6_c][S S S T T   S N
_Push_6_o][S S T    T   S T S T N
_Push_-21_T][N
S N
N
_Jump_to_Label_PRINT_LOOP]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.
Try it online (with raw spaces, tabs and new-lines only).
Explanation in pseudo-code:
Integer year = STDIN as integer
Print (year+2) modulo-13 + 1 as integer to STDOUT
Print '\t' as character to STDOUT
Integer temp = year modulo-4
If(temp == 0):
  Push the codepoints of "ltapceT" minus 105 to the stack
If(temp-1 == 0):
  Push the codepoints of "illaC" minus 105 to the stack
If(temp-2 == 0):
  Push the codepoints of "ilthcoT" minus 105 to the stack
Else:
  Push the codepoints of "ltacA" minus 105 to the stack
Start PRINT_LOOP:
  Add 105 to the top integer on the stack
  Print this integer as character with this codepoint to STDOUT
  Go to the next iteration of PRINT_LOOP

Uses this Whitespace tip of mine to print the output, which will exit the program with an error as soon as we're done with printing and the stack is empty. The optimal constant 105 is generated by this Java program.

jq (with -r switch), 57 characters
"\((.+2)%13+1) "+("Tecpatl Calli Tochtli Acatl"/" ")[.%4]

Sample run:
bash-5.0$ jq -r '"\((.+2)%13+1) "+("Tecpatl Calli Tochtli Acatl"/" ")[.%4]' <<< 1111
9 Acatl

Try it online! / Try all test cases online!

APL (Dyalog Unicode), 55 54 bytesSBCS
{((4 7⍴'TecpatlCalli  TochtliAcatl  ')⌷⍨4|⍵),1+13|2+⍵}

Try it online!

@KeizerHarm thanks! Fixed :)

Use brackets for 51, or 48 with cyclic indexing trick.

C (gcc), 87 \$\cdots\$ 70 69 bytes
Saved 2 bytes thanks to my pronoun is monicareinstate!!!
Saved a byte thanks to ceilingcat!!!
f(n){printf("%d %.7s",1-~-~n%13,"TecpatlCalli  TochtliAcatl"+n%4*7);}

Try it online!

"%.7s" I did not know printf can do this. 7*(n%4) -> n%4*7 should work.

@mypronounismonicareinstate Yeah, printf has lots of formatting tricks - thanks! :)

Jelly, 36 bytes
+3ịⱮ13R,“©ȥƒị Œñ⁾<ŻĠ)?ỵ%uxÐZỵȯẏ1»Ḳ¤¤

Try it online!
How?
+3ịⱮ13R,“...»Ḳ¤¤ - Link: integer, Y
+3               - add three (to Y)
               ¤ - nilad followed by link(s) as a nilad:
    13R          -   range(13) = [1,2,3,4,5,6,7,8,9,10,11,12,13]
              ¤  -   nilad followed by link(s) as a nilad:
        “...»    -     compressed string = "Tochtli Acatl Tecpatl Calli"
             Ḳ   -     split at spaces = ["Tochtli","Acatl","Tecpatl","Calli"]
       ,         -   pair these together = [[1,2,3,4,5,6,7,8,9,10,11,12,13],["Tochtli","Acatl","Tecpatl","Calli"]]
   Ɱ             - map accross (these two lists) with:
  ị              -   index into (1-based & modular)

Befunge-93, 100 bytes
&:2+67+%1+.4%:#v_"ltapceT",,v
<"Calli"_v#!-1:<@,,,,, <    <
         >2`!#v_"ltacA"^
^  ,,"Tochtli"<

Try it online!
Reads the year from input, and duplicates it. Adds 2, mods it with 13, adds 1 to the result and prints it. Then mods the year with 4, and using a series if if statements, selects the right name to print.

In Befunge-98 (it's going to be less obvious in 93, but probably possible as well), a more usual-ish approach is likely possible: drop the first n%4*7 characters of "TecpatlCalli  TochtliAcatl" with the help of k, then print 7 more characters of it.

J, 43 bytes
Straightforward implementation. Takes a number like 1090, returns boxed tuple [1|Tochtli].
(1+13|2+]);Tecpatl`Calli`Tochtli`Acatl{~4|]

Try it online!
How it works
(1+13|2+]);Tecpatl`Calli`Tochtli`Acatl{~4|]
                                        4|] x mod 4
           Tecpatl`Calli`Tochtli`Acatl{~    select from boxes
(1+13|2+])                                  ((x + 2) mod 4) + 1
          ;                                 join left & right side

Charcoal, 38 bytes
ＮθＩ⊕﹪⁺²θ¹³ §⪪”(0«βxo%↔W^⊘Ｓ≧L≔Z⮌⍘｜Nº” θ

Try it online! Link is to verbose version of code. Explanation:
ＮθＩ⊕﹪⁺²θ¹³

Input the year, add 2, reduce modulo 13, add 1, and print as a string, followed by a space.
§⪪”(0«βxo%↔W^⊘Ｓ≧L≔Z⮌⍘｜Nº” θ

Split the compressed string Tecpatl Calli Tochtli Acatl on spaces and print the entry cyclically indexed using the year.

Ruby, 54 bytes
->y{[(y+2)%13+1,%w[Tecpatl Calli Tochtli Acatl][y%4]]}

Try it online!

Pyth, 41 bytes
(h%+2Q13@c." t£>Ì<ëWÈ¶Adh|Å],%œ¯s")%Q4

Try it online!
The number is calculated with 1+((x+2)%13)), x being the input.
The sign is retrieved by indexing into a packed string, split on whitespace.
Oddly enough, using repeated indexing for the string (like in other answers) yielded the same bytecount for me.

JavaScript, 58 57 bytes
-1 byte using the numerical method from @ceilingcat used in Kevin Cruijssen's Java answer
n=>[1-~-~n%13,["Tecpatl","Calli","Tochtli","Acatl"][n%4]]

Try it online!
It's been a long time since I got to a question fast enough to post a Javascript answer. (July 15, 2017 appears to have been my last for one that wasn't a king of the hill challenge.)
Pretty straightforward, get the right number with some basic modular arithmetic and get the sign with some array indexing mod 4.

PHP, 69 bytes
fn($n)=>(($n+2)%13+1).' '.['Tecpatl','Calli','Tochtli','Acatl'][$n%4]

Try it online!
Just a port of Abigail's perl answer using Arnauld's edit suggestion, i fear.. but I had to, it's a 69

Kotlin, 72 bytes
fun f(x:Int)=(x+2)%13+1 to "Tecpatl Calli Tochtli Acatl".split(" ")[x%4]

Try it online!


text:
Fizz! Buzz! 'ave a banana!
Here's one for fans of Cabin Pressure. There is an episode in which the characters devise a new version of Fizz Buzz, which is simplified to contain absolutely no mathematics.
It has these rules:

If someone says "fizz", you say "buzz".
If someone says "buzz", you sing "'ave a banana"
If someone says your name, you say "fizz".

The result is that whenever a name is uttered, that person says "fizz" and the sequence has to run to completion.

Let's write some code.
I'd like you to write a program/function/whatever which works thus:

It accepts one single string of text as input.
If the string equals the name of the language your code is written in, it outputs "fizz".
If the string equals "fizz", it outputs "buzz".
If the string equals "buzz", it outputs "'ave a banana" (note the apostrophe at the start).
If the input is not one of these things, it should terminate.
Here's the kicker: The output string must go to two places.

Output to be seen by the user

Back into your code as input

I don't really care if they are output in each iteration, or build a string for eventual output.
Outputs must be separated by new lines (in console or result string)

Rules

This is code golf, write in any language you like and attempt to make your code as small as possible.
Standard loopholes apply.
I'd like to see links to an online interpreter.
The language name can be a full name or common short-form of the language the answer is written in. E.g. JS is acceptable, but shortening Ruby to R is not).

Test Cases
Input
'buzz'

Output
'ave a banana

Input
'fizz'

Output
buzz
'ave a banana

Input
ruby # or the name of the language your answer is written in

Output
fizz
buzz
'ave a banana

Input
something else

No output

What is the name of my language?

@Adám Whichever language you are writing your answer in. Is there a better way I could express that?

@KrzysztofSzewczyk Nope.

@AJFaraday I meant to ask what kind of freedom we have. JavaScript/js/ES6; APL/Dyalog APL (Unicode); Python/Python 3/Python 3.8…

@Adám I’m happy with short forms like ES6 or JS.

But what happens if your name is Buzz? Or Banana?

@darrylyeo That's an interesting question. I am unable to find any programming languages named Fizz or Banana (it's free real estate ¯_(ツ)_/¯ ). There is a language named Buzz, but it appears to be designed to instruct swarming automata, so I'm fairly confident we're not going to get any answers in buzz.

@darrylyeo As for the game being played by people, I'd expect it to become a kind of rhythmic ostinato until Buzz gets bored of playing and gives it up.

Apart from this answer, and this and (this)[https://codegolf.stackexchange.com/a/205822/63348], everyone seems to be missing The output string must go [...] Back into your code as input, thus rendering the challenge as just (in Python-like pseudocode) print text[findIndex(input)+1:].join('\n').

@KenY-N I'm treating them based on the output, not the method.

@AJFaraday However, a language called "A" does exist...

@Chronocidal That's okay, "'ave a banana" |= 'A'

I'm voting this as unclear until there is a specification for how we determine a language's name.

@AdHocGarfHunter That's fairly petty.

I have looked up the meaning of petty, but I don't know what you are trying to communicate to me.

@AdHocGarfHunter I have clarified what can be used as the language name.

perl -M5.010 -n, 47 bytes
"Perl\nfizz\nbuzz\n'ave a banana"=~/\b$_/;say$'

Try it online!
Prints whatever is following the input, or nothing if there is no match. Assumes input is newline terminated.

Nice! Can't get anything shorter using lists... You can save three bytes using literal newlines though!

Jelly, 26 bytes
“Çȥȧ>$ỌĿɦ@⁴Ƙ½Æ/ṠṫḞƇ»Ỵṣ⁸ḊẎY

Try it online!
How?
“...»Ỵṣ⁸ḊẎY - Link: list of characters, W
“...»       - compressed string = "Jelly\nfizz\nbuzz\n'ave a banana"
     Ỵ      - split at newlines = ["Jelly","fizz","buzz","'ave a banana"]
      ṣ     - split at:
       ⁸    -   chain's left argument, W  e.g. "Jelly" -> [[],["fizz","buzz","'ave a banana"]]
        Ḋ   - dequeue                                   = [["fizz","buzz","'ave a banana"]]
         Ẏ  - tighten                                   = ["fizz","buzz","'ave a banana"]
          Y - join with new lines                       = "fizz\nbuzz\n'ave a banana"

Bash, 63 bytes
bash=fizz
fizz=buzz
buzz="'ave a banana"
echo ${x=${!1}}&&$0 $x

Try it online!
This requires . to be in your PATH.  If that's not acceptable, then replace $0 with ./$0 (assuming the program is being run from the current working directory) at the cost of 2 bytes (65 bytes total).
Input is passed as an argument, output is on stdout. The language name is entered as bash.
(There's spurious output to stderr, but that's OK under our generic rules.)

05AB1E, 46 33 bytes
’
05AB1E
fizz
ÒÖ
'ž™ a æé’I¶.ø¡¦θ

-13 bytes by porting @Abigail's Perl answer, so make sure to upvote her!!
Outputs [] for invalid inputs.
Try it online.
Original 46 bytes approach:
"fizz"U•äƵí•hRQiX=}XQi'ÒÖ=}'ÒÖQi’'ž™ a æé’,}õ?

Outputs nothing for invalid inputs.
Try it online.
Explanation:
’
05AB1E
fizz
ÒÖ
'ž™ a æé’         '# Push dictionary string "\n05AB1E\nfizz\nbuzz\n'ave a banana"
         I         # Push the input
          ¶.ø      # Surround it with leading and trailing newline
             ¡     # Split the string on this
              ¦    # Remove the first part (for invalid inputs)
               θ   # Pop and only leave the last part (or an empty list)
                   # (and output it implicitly as result)

"fizz"U            # Puts "fizz" in variable `X`
•äƵí•              # Push compressed integer 14793296
     h             # Convert it to hexadecimal: E1BA50
      R            # Reverse it to 05AB1E
       Qi  }       # If the (implicit) input-string is equal to this:
         X         #  Push "fizz" from variable `X`
          =        #  Print it with trailing newline without popping
X                  # Push "fizz" from variable `X`
 Qi    }           # If the top of the stack equals "fizz",
                   # which will use the (implicit) input if the stack is empty:
   'ÒÖ            '#  Push dictionary string "buzz"
      =            #  Print it with trailing newline without popping
'ÒÖQi           } '# If the top of the stack (or implicit input) equals "buzz":
     ’'ž™ a æé’   '#  Push dictionary string "'ave a banana"
               ,   #  Pop and print it
õ?                 # Print "" without newline
                   # (for invalid input, which otherwise would be output implicitly)

See this 05AB1E tip of mine (sections How to use the dictionary? and How to compress large integers?) to understand why •äƵí• is 14793296; 'ÒÖ is "buzz"; and ’'ž™ a æé’ is "'ave a banana".

You forgot to check for word boundaries. I initially made that mistake as well.

@Abigail Thanks for letting me know. Fixed at the cost of 4 bytes.

JavaScript (ES6), 64 bytes
Expects "js" for the language name. Returns an array of strings.
s=>[k="js","fizz","buzz","'ave a banana"].filter(w=>k*(k|=s==w))

Try it online!

Retina 0.8.2, 56 bytes
$
¶Retina¶fizz¶buzz¶'ave a banana
^(.*¶)(.*¶)*?(\1|.*$)

Try it online! Link includes test cases. Explanation:
$
¶Retina¶fizz¶buzz¶'ave a banana

Append the possible inputs and outputs.
^(.*¶)(.*¶)*?(\1|.*$)

Try to delete only up to and including a line matching the original input. If this is not possible, then just delete everything.

Python 3, 77 76 bytes
t="Python","fizz","buzz","'ave a banana"
*map(print,t[t.index(input())+1:]),

Try it online!
Takes input from STDIN, and print the results to STDOUT.

@JoKing that's really cool, thanks! Not sure why putting the comma makes it work.

It is the creation of a tuple (defined by a single comma) and using PEP 448 that makes it work.

APL (Dyalog Unicode), 43 bytes
'APL' 'fizz' 'buzz' '''ave a banana'(↑⍳↓⊣)⊂

Try it online!
List of string literals is quite expensive...
How it works
S←'APL' 'fizz' 'buzz' '''ave a banana'  ⍝ Let's call this array S
S(↑⍳↓⊣)⊂  ⍝ The function
S( ⍳  )⊂  ⍝ 1-based index of the input in S, 5 if not found
    ↓⊣    ⍝ Drop that many items from the start of S
  ↑       ⍝ Convert the remaining items to be placed on each line

Java (OpenJDK 8), 117 bytes
void a(String s){System.out.println(s=s=="fizz"?"buzz":s=="buzz"?"'ave a banana":s=="java"?"fizz":"");if(s!="")a(s);}

Try it online!

112 bytes (because the OP says it's OK not to follow the method as long as the output is the correct one)

Charcoal, 39 bytes
≔⪪“Jε(h&]⦄_⁷¦⊗‹f·ⅈ⦄⊗x⍘ς3➙Ａ⁸“↑”¶υΦυ№…υκθ

Try it online! Link is to verbose version of code. Explanation:
≔⪪“Jε(h&]⦄_⁷¦⊗‹f·ⅈ⦄⊗x⍘ς3➙Ａ⁸“↑”¶υ

Split the string Charcoal\nfizz\nbuzz\n'ave a banana on newlines and save the result in a variable.
Φυ№…υκθ

Filter on the result and show only those entries that appear after the input.

C (gcc), 115 \$\cdots\$ 105 98 bytes
Saved 4 bytes thanks to ceilingcat!!!
Saved 7 bytes thanks to Neil!!!
i;*y[]={"c","fizz","buzz","'ave a banana"};f(char*s){for(i=0;i<3;)strcmp(s,y[i++])||puts(s=y[i]);}

Try it online!

I think strcmp(s,y[i++])||puts(s=y[i]); saves you 7 bytes.

@Neil Clever, was thinking there must be a away to just keep on looping - thanks! :-)

Python 2, 102 79 bytes
a='fizz'
b='buzz'
def f(s):t={'Python':a,a:b,b:"'ave a banana"}[s];print t;f(t)

Try it online!
Uses a different approach from the other answer, recursive function
Edit: Thanks @SurculoseSputum for saving 23 bytes!

You can get it down to 91 bytes by rearranging everything a bit.

79 bytes if terminating the function with exception is allowed.

@SurculoseSputum well, your answer uses exceptions i think, so sure, thanks! :)

Brachylog, 52 47 bytes
∧"Brachylog
fizz
buzz
'ave a banana"ṇ;?⟨a₁h⟩b~ṇ

Try it online!
The predicate fails on inputs on which it should "terminate". If outputting an unbound variable is more desirable, +2 bytes for .∨; if an empty string is necessary, +1 on top of that for Ẹ.

Kotlin, 103 bytes
fun f(x:String){listOf("fizz","buzz","'ave a banana").fold("Kotlin"){a,b->if(x==a){println(b);f(b)};b}}

Try it online!


text:
Implement SKI combinator calculus
This challenge is to golf an implementation of SKI formal combinator calculus.
Definition
Terms
S, K, and I are terms.
If x and y are terms then (xy) is a term.
Evaluation
The following three steps will be repeated until none of them apply.
In these, x, y, and z must be terms.
(Ix) will be replaced by x
((Kx)y) will be replaced by x
(((Sx)y)z) will be replaced by ((xz)(yz))
Input
A string or array, you do not have to parse the strings in the program.
The input is assumed to be a term.
If the simplification does not terminate, the program should not terminate.
Examples
(((SI)I)K) should evaluate to (KK) ((((SI)I)K) > ((IK)(IK)) > (K(IK)) > (KK))
The evaluation order is up to you.
This is code-golf. Shortest program in bytes wins.

Are the inputs strings we have to parse, or can we have them in a tree or similar?

They don't have to be parsed, you can have them in a tree.

And what do we do if the simplification does not terminate?

@xnor Then the program should not terminate.

Some example please.

Should we assume the input is a term (i.e. the behavior is unspecified if the input is not a term)? Is a non-strict evaluation order required so that ((KI)(((SI)I)((SI)I))) must terminate, or is such an expression allowed to diverge?

The input is assumed to be a term. That kind of expression is allowed to diverge.

It doesn't make much sense to me to say "If the simplification does not terminate" without specififying an exact algorithm required.  This is sort of the point Anders Kaseorg makes.  It would be best if we could have a unambiguous specification of when we must terminate.

@AdHocGarfHunter Execute the program as normal, if it is a diverging expression then the program will keep applying rules, and hence never terminating.

@nph The point is that ((KI)(((SI)I)((SI)I))) can either be reduced to I with one K step (leading to termination) or to ((KI)(((SI)I)((SI)I))) with one S step (leading to divergence), and you need to specify whether the former is required, the latter is required, or either are allowed. I suggest “either”. See https://en.wikipedia.org/wiki/Evaluation_strategy.

@AndersKaseorg Either is allowed.

Can I encode the terms S, K, I as 0, 1, 2 (or any three distinct numbers)? Also, as you mentioned "you do not have to parse the strings in the program", can I use a more "flat" representation e.g. [S, I, I, [S, I, I]] for (((SI)I)((SI)I)) for I/O (if I want the parsed result in this form)?

@Bubbler No, the input must be in terms of S, K, and I. And yes, you are allowed to have that "flat" representation.

There was a hardware SKI reduction Machine, SKIM made in about 1980.

Can we consider the result of SIIK to be a function like _ => K that takes an ignored argument and returns K instead of (K, K)?

@user Outputting a function would give you no way to distinguish between terms like I and ((SK)K), which behave the same way as functions but are different formal terms according to the specification.

@AndersKaseorg Ah, that makes sense. Wish there were some way to do it without ambiguity

Wolfram Language, 63 bytes
#//.{{I,x_}->x,{{K,x_},y_}->x,{{{S,x_},y_},z_}->{{x,z},{y,z}}}&

Try it online!
God, I love pattern matching in Wolfram Language. Represents (xy) as {x,y} (a list of two elements).
Alternatively, if we represent (xy) with x>y, we can do it in 55 bytes.
#//.{I>x_->x,(K>x_)>y_->x,((S>x_)>y_)>z_->(x>z)>(y>z)}&

Try it online!

Basic -1. Alternatively, save more with // instead of >: 45 bytes

Seed, 5925 5909 5890 5871 bytes
112 [encoded data, 5867 characters]

Try it online!
Made possible thanks to Abigail's perl answer. Inspired by HighlyRadioactive's comment.
Last iteration was golfed with bx6.

What the... this is real...

Now, do this in Malbolge.

Challenge accepted, but let me finish my work first ;)

This is wrong for the same reason as user89655’s answer; namely, it fails to simplify, e.g., ((K(SS))S) to (SS). (In the rules, x, y, and z are terms; they don’t have to be single characters.)

@AndersKaseorg fixed; it hurt many bytes but should work correctly now.

C (gcc), 666 616 518 483 476 bytes
Who doesn't love classy, Arthur Whitney-styled code?
No regular expressions involved, only clever parsing and evaluation.
PS: Yes, obviously, a few bytes can be shaved off, but for the artistic style of the obfuscated code, I'll keep them. Also for the byte count :p. Also, this code utilizes undefined behaviour in hope that nothing will break (hopefully).
@ceilingcat insisted on golfing it down from 666 bytes, so here is the golfed version:
#define J putchar
#define H O->a
#define G H->a
#define K O->b
typedef struct x{struct x*a,*b;int q;}Y;Y*O;z=1;A(q){O=calloc(6,4);O->q=q;}h(Y*O){Y*u;O=H&&H->q==2?z=K:H&&G&&G->q==1?z=H->b:H&&G&&G->a&&!G->a->q?u=A(3),(u->a=A(3))->a=G->b,(u->b=A(3))->a=H->b,u->a->b=u->b->b=K,z=u:(O->q==3?H=h(H),K=h(K):0,O);}r(x){Y*O;x=getchar()-73;x=x+33?A(x?x!=10:2):!getchar(K=r(H=r(O=A(3))))+O;}q(Y*O){O&&J(O->q["SKI "],O->q-3||J(41,q(K),q(H),J(40)));}main(){Y*O=r();for(;z;O=h(O))z=0;q(O);}

Try it online!

Now, do this in Seed.

Rust Macros, 480 441 bytes
macro_rules!s{({I$($t:tt)+}$s:tt)=>{s![{$($t)+}$s]};({K$x:tt$y:tt$($t:tt)*}$s:tt)=>{s![{$x$($t)*}$s]};({S$x:tt$y:tt$z:tt$($t:tt)*}$s:tt)=>{s![{$x$z($y$z)$($t)*}$s]};({($($c:tt)*)$($t:tt)*}{$($r:tt)*})=>{s![{$($c)*}{{$($t)*}$($r)*}]};({$($c:tt)*}{{$($t:tt)*}$($s:tt)*})=>{s![{$($c)*$($t)*}{$($s)*}]};({$($c:tt)*}{})=>{concat!($(s![$c]),*)};(($($t:tt)*))=>{concat!("(",s!($($t)*),")")};($t:tt)=>{stringify!($t)};($($t:tt)*)=>{s![{$($t)*}{}]};}

Try it online!
The macro takes in tokens and spits out a string literal. Input is in a flattened, left-associative format as seen on Wikipedia. Make sure there is some whitespace between combinators when using it.
ungolfed:
macro_rules! ski {
    ({I $($t:tt)+} $s:tt) => {ski![ {$($t)+} $s]};
    ({K $x:tt $y:tt $($t:tt)*} $s:tt) => {ski![ {$x $($t)*}$s] };
    ({S $x:tt $y:tt $z:tt $($t:tt)*} $s:tt) => {ski![ {$x $z ($y $z) $($t)*} $s ]};
    ({($($c:tt)*) $($t:tt)+}{$($r:tt)*}) => {ski![ {$($c)+} {{$($t)*} $($r)*} ]};
    ({$($c:tt)*} { {$($t:tt)*} $($s:tt)* }) =>{ski![ { $($c)* $($t)* } {$($s)*} ]};
    ({$($c:tt)*} {}) => {concat!($(ski![$c]),*)};
    (($($t:tt)*)) => {concat!("(", ski!($($t)*), ")")};
    ( $t:tt) =>{stringify!($t)};
    ($($t:tt)*) => {ski![ {$($t)*} {}]};
}

Macros declared with macro_rules perform substitution based on rules similar to a regex-based substitution. The general strategy is here is an execution stack, where the instructions are being stored and executed, and a call stack, which is a stack of execution stacks and is used to traverse into functions created with ().
Rule number ten serves as the entry point to the macro, matching on all inputs and setting up the call and execution stacks in the form {instructions}{}. Note that matched pairs of brackets count as a single token, and closing brackets stop greedy matches.
Rule one implements the I combinator. It matches when the call stack is I followed by one or more instructions. It simply passes on all the matched instructions.
Rule two implements the K combinator. It behaves similarly to I but uses two arguments instead of one.
Rule three is the same but for S.
Rule four implements traversing into parentheses by pushing the instructions remaining on the execution stack after the parentheses onto the call stack, and replacing the call stack with the instructions in the parentheses.
Rule five catches an edge case by stopping infinite recursion when there are no instructions after the parentheses. was made redundant by an earlier bug fix and removed.
Rule six is when the execution stack can't be simplified and there are more instructions on the call stack, the instructions in the top execution stack on the call stack are concatenated on the bottom of the main execution stack.
Rule seven is when the execution stack can't be simplified and the call stack is empty. Here all the tokens are split, fed back into this macro for stringification, and concatenated.
Rule eight is where I say I lied because parenthesized groups need further evaluation because that strategy I had above evaluated these groups lazily. This rule simply feeds the instructions in the parentheses back into the original macro and concatenates parentheses around the results.
Rule nine is our terminal rule, where the tokens passed in are stringified and returned.
Assuming the recursion limit is removed and rustc gets unlimited memory this  is a proof of turing completeness for rust's macro system (not the only one- rust's macros are trivially ℒ-hard, a macro that binds an inputted $ can create and execute arbitrary macros). A playground link that lets you view the ungolfed macro's expansion steps is below.
Playground

APL (Dyalog Unicode), 127 124 bytes
Full program. No use of regex.
∊{0=≡⍵:⍵
1⌽')(',∇¨⍵}{0=d←|≡⍵:⍵
'I'≡⊃⍵:⊃⌽⍵
(2≤d)∧'K'≡⊃⊃⍵:⊃⌽⊃⍵
(3≤d)∧'S'≡⊃∊⍵:x y,⍥⊂¨⊃⌽(((s x)y)z)←⍵
∇¨⍵}⍣≡⍎⍕{3⍴''''⍵}¨@{⍵∊⎕A}⍞

Try it online!
The program has three distinct parts:

Input handling
Evaluation
Output formatting

Input handling
This part transforms the traditional SKI notation into a nest APL data structure.
      ⍎⍕{3⍴''''⍵}¨@{⍵∊⎕A}⍞

⍞ prompt for one line of input text
  E.g. "(((SI)I)K)"
@{…} at locations where:
 ⍵ the argument characters
 ∊ are members of
 ⎕A the uppercase Alphabet
{…}¨ replace each one by:
 3⍴ a cyclical reshape into length 3, of
 ''''⍵ the string consisting of a quote character (') and the argument character
  E.g. ["(","(","(","'S'","'I'",")","'I'",")","'K'",")"]
⍕ stringify (this forces the now nested array into a flat space-separated string)
  E.g. "((( 'S'  'I' ) 'I' ) 'K' )"
⍎ evaluate as APL code
  E.g. [["SI","I"],"K"]
Evaluation
This part simplifies the data structure according to the three given rules.
           {0=d←|≡⍵:⍵
'I'≡⊃⍵:⊃⌽⍵
(2≤d)∧'K'≡⊃⊃⍵:⊃⌽⊃⍵
(3≤d)∧'S'≡⊃∊⍵:x y,⍥⊂¨⊃⌽(((s x)y)z)←⍵
∇¨⍵}

0=…: if 0 equals
d← the variable d which is (assigned for later use)
|≡⍵ the absolute depth (maximum nesting level) of the argument:
 ⍵ return the argument as-is (this ensures the continuation of already evaluated parts)
'I'≡…: if "I" matches
⊃⍵ the first element of the argument
 ⊃⌽⍵ return the last element of the argument (lit. the first of the reversed; this implements (Ix) → x)
(2≤d)∧…: if 2 is less than or equal to the depth (d), AND
'K'≡⊃⊃⍵ if "K" matches the first element of the first element of the argument:
 ⊃⌽⊃⍵ return the last element of the first element of the argument (lit. the first of the reversed first; this implements ((Kx)y) → x)
(3≤d)∧…: if 3 is less than or equal to the depth (d), AND
'S'≡ if "S" matches
⊃∊⍵ the first element of the enlisted (flattened) argument:
 (((s x)y)z)←⍵ destructure the argument into individual variables
 ⊃⌽ pick the last element (lit. first of the reversed) from that (z)
 x y,⍥⊂¨ pair up each of x and y with that (this implements (((Sx)y)z) → ((xz)(yz)))
∇¨⍵ otherwise, call self on each element of the argument
Output Formatting
Here, we transform the data structure back into traditional SKI notation.
∊{0=≡⍵:⍵
1⌽')(',∇¨⍵}

0=≡⍵: if zero is equal to the depth of the argument (i.e. it is a single character)
 ⍵ return that as-is
∇¨⍵ otherwise, call self on each element of the argument
')(', prepend ")("
1⌽ cyclically rotate one character from the front to the rear.

perl -p, 135 bytes
1 while s/\((I)(?<T>[SKI]|\((?&T)(?&T)\))\)|\(\((K)((?&T))\)(?&T)\)|\(\(\((S)((?&T))\)((?&T))\)((?&T))\)/$1?$2:$3?$4:"(($6$8)($7$8))"/e

Try it online!
Just a regexp applying the three rules. Reads a string from STDIN, applies all the rules until there's nothing to apply, writes the result to STDOUT.
(?<T>[SKI]|\((?&T)(?&T)\)) is a recursive pattern recognizing a term. The rest of the pattern is just a mechanically translation of the given rules.

−1 byte: \(\(\( ↦ \({3}

Or −40 bytes.

Retina 0.8.2, 171 bytes
{T`()`<>
<<<S((\w|(<)|(?<-3>>))+)>((\w|(<)|(?<-6>>))+)>((\w|(<)|(?<-9>>))+>)
<<$1$7<$4$7>
<<K((\w|(<)|(?<-3>>))+)>(\w|(<)|(?<-5>>))+>
$1
<I((\w|(<)|(?<-3>>))+)>
$1
T`<>`()

Try it online! Explanation:
{`

Repeat the transformations until there are no more available.
T`()`<>
T`<>`()

Temporarily switch ()s with <>s to avoid having to quote numerous ()s.
<<<S((\w|(<)|(?<-3>>))+)>((\w|(<)|(?<-6>>))+)>((\w|(<)|(?<-9>>))+>)
<<$1$7<$4$7>

Process S operations. (The last capture includes the trailing > in order to avoid repeating it in the replacement.)
<<K((\w|(<)|(?<-3>>))+)>(\w|(<)|(?<-5>>))+>
$1

Process K operations.
<I((\w|(<)|(?<-3>>))+)>
$1

Process I operations.
The (\w|(<)|(?<-[N]>>))+ construct is an example of a .NET regex balancing group. It tries to match characters, but it's only allowed to match >s if it's already seen the same number of <s. (N needs to be replaced with the number of the (<) capturing group. As written it fails if the <>s aren't balanced correctly, but you can use conditional regex to check for that.)

Wolfram Language, 44 bytes
s[a_][b_][c_]:=b@c//a@c;k[a_][b_]:=a;i@a_:=a

This defines them as actual functions in Wolfram, so s[i][i][k] returns k[k], etc.
Try it online!

-6 bytes

05AB1E, 92 bytes
ΔDŒʒ„)(©S¢Ë}ʒÁ®Å?y®S¢O_~}©vy"(Iÿ)"y:}®ãvy`"((Kÿ)ÿ)"yθ:}®3ãvy`"(((Sÿ)ÿ)ÿ)"yĆ1.I`"((ÿÿ)(ÿÿ))":

05AB1E has no regex, so uses a brute-force approach using all valid substrings. Because of this, it's extremely slow for larger test cases.
Executes in the order (Ix) → ((Kx)y) → (((Sx)y)z).
Try it online or verify a few more test cases.
Explanation:
Δ                        # Continue until the result no longer changes:
 D                       #  Duplicate the current string
                         #  (will use the implicit input-string in the first iteration)
  Œ                      #  Take all its substrings
   ʒ                     #  Filter those substrings by:
    „)(                  #   Push ")("
       ©                 #   Store it in variable `®` (without popping)
        S                #   Convert it to a list of characters: [")","("]
         ¢               #   Count each in the substring
          Ë              #   Check that the counts are equal for both
   }ʒ                    #  After the filter: filter once more:
     Á                   #   Rotate the substring once towards the left
      ®                  #   Push string ")(" from variable `®`
       Å?                #   Check if the rotated substring starts with this
     y                   #   Push the substring again
      ®S¢                #   Count the [")","("] again
         O_              #   Check that the sum of both counts is 0
     ~                   #   Check if either of the two was truthy
    }©                   #  After the filter: store it in variable `®` (without popping)
 v                       #  Loop over each valid substring:
  y                      #   Push the substring
   "(Iÿ)"                #   Push this string, with the `ÿ` automatically filled with
                         #   the substring
  y                      #   Push the substring again
  :                      #   Replace all "(Ia)" with "a"
 }®                      #  After the loop: push the list of valid substrings again
   ã                     #  Take all pairs of valid substrings
    v                    #  Loop over these pairs:
     y`                  #   Pop and push the pair separated to the stack
       "((Kÿ)ÿ)"         #   Push this string, with the `ÿ` automatically filled again
     yθ                  #   Pop and push only the last substring of the pair: [a,b] → b
     :                   #   Replace all "((Kb)a)" with "b"
 }®                      #  After the loop: push the list of valid substrings again
   3ã                    #  Take all triplets of valid substrings this time
     v                   #  Loop each each triplet:
      y`                 #   Pop and push the triplet separated to the stack
        "(((Sÿ)ÿ)ÿ)"     #   Push this string, with the `ÿ` automatically filled again
      y                  #   Push the current triplet again
       Ć                 #   Enclose; append its own head: [a,b,c] → [a,b,c,a]
        1.I              #   Get the 0-based 1st permutation: [a,b,c,a] → [a,b,a,c]
           `             #   Pop and push the quartet separated to the stack
            "((ÿÿ)(ÿÿ))" #   Push this string, with the `ÿ` automatically filled again
      :                  #   Replace all "(((Sc)b)a)" with "((ca)(ba))"
                         # (after which the result is output implicitly)

Scala 3 (compile-time), 113 bytes
type A=AnyKind
type S[X[a<:A]<:[b<:A]=>>A]=[Y[z<:A]]=>>[Z<:A]=>>X[Z][Y[Z]]
type K[X<:A]=[Y<:A]=>>X
type I[X<:A]=X

Try it in Scastie
It works at compile time and it doesn't exactly return a value (you can check it with =:= or other mechanisms), but Dotty's type system is Turing-complete (Scala 2's too, actually).
Pretty straightforward - it uses higher-kinded types and curried type lambdas like functions.
Ungolfed (and modified slightly for clarity):
type S =
  [X <: [a <: AnyKind] =>> [b <: AnyKind] =>> AnyKind] =>> //X is a type lambda with 2 parameters (curried) and returning a type of any kind
  [Y[z <: AnyKind]] =>> //Y is a type lambda taking one parameter and returning a type of any kind
  [Z <: AnyKind] //Z is a type of any kind
  =>> X[Z][Y[Z]] //The result of Skyz, as defined in the question
type K = [X <: AnyKind] =>> [Y <: AnyKind] =>> X
type I = [X <: AnyKind] =>> X

SIIK or (((SI)I)K) would be written as S[I][I][K].

With match types, 200 bytes
final class S
final class K
final class I
type R[T]=T match{case(((S,x),y),z)=>R[((x,z),(y,z))]case((K,x),y)=>R[x]case(I,x)=>R[x]case(a,b)=>R[a]match{case`a`=>(a,R[b])case _=>R[(R[a],R[b])]}case T=>T}

Thanks to @HTNW on SO for helping me with this
Try it in Scastie
A term (xy) is represented as the tuple (x,y).

Using literal types, 164 bytes
type R[T]=T match{case((('S',x),y),z)=>R[((x,z),(y,z))]case(('K',x),y)=>R[x]case('I',x)=>R[x]case(a,b)=>R[a]match{case`a`=>(a,R[b])case _=>R[(R[a],R[b])]}case T=>T}

Try it in Scastie
This one uses literal-based singleton types (the Chars 'S', 'K', and 'I').

Slightly unethical version, 158 bytes
type R[T]=T match{case(((0,x),y),z)=>R[((x,z),(y,z))]case((1,x),y)=>R[x]case(2,x)=>R[x]case(a,b)=>R[a]match{case`a`=>(a,R[b])case _=>R[(R[a],R[b])]}case T=>T}

Same approach as above, but this time, S is the singleton type of 0, K is 1, and I is 2.
Try it in Scastie

KamilaLisp, 137 bytes
(defmacro f(x)(match x((a b c)(S a b c)[(tie a c b c)/ 2])((a b)(K a b)a)(a(I a)a)((a b)(a b)(tie(f a)(f b)))(x)))(def g $(iterate /= f))

Ungolfed:
;; SKI calculus implementation using KamilaLisp macros
(defmacro ski (x) (match x
    ((a b c) (S a b c) [(tie a c b c) / 2])
    ((a b)   (K a b)   a)
    ((a)     (I a)     a)
    ((a b)   (a b)     (tie (ski a) (ski b)))
    (x)
))

;; iterate /=  =>  fixed point
(def ski-red $(iterate /= ski))

;; an example expression
(println@ski-red '(S I I K))

Maude, 138 bytes
fmod F is
sort T .
ops S K I : -> T .
op __ : T T -> T .
vars x y z : T .
eq I x = x .
eq (K x)y = x x .
eq ((S x)y)z = (x z)(y z) .
endfm

Maude> red ((S I)I)K .
reduce in F : ((S I) I) K .
rewrites: 3 in 0ms cpu (0ms real) (~ rewrites/second)
result T: K K

Haskell, 83 bytes
data T=S|K|I|T:$T
e(x:$y)=e x!e y
e x=x
I!x=x
K:$x!_=x
S:$x:$y!z=x!z!(y!z)
x!y=x:$y

Try it online!