text:
Solve a Solitaire Chess Puzzle
Recently, I was introduced to a puzzle game known as Solitaire Chess. I'll summarize the rules here:

The board is a 4x4 checkerboard.
All pieces are the same color (no teams) and all pieces can capture any other piece.
Every move must be a capture. No moving to empty squares.
There must be exactly one piece remaining at the end.
All pieces move exactly like they do in chess, with one modification: the pawn can capture in any diagonal direction (which technically makes it a ferz). For the benefit of those who may not know, I have included movement diagrams.
None of the other rules of chess (such as check, castling, etc.) apply here. It's all about captures.

King (K)
K * . . | * K * . | * * * .
* * . . | * * * . | * K * .
. . . . | . . . . | * * * .
. . . . | . . . . | . . . .

Queen (Q)
Q * * * | * Q * * | * * * .
* * . . | * * * . | * Q * *
* . * . | . * . * | * * * .
* . . * | . * . . | . * . *

Rook (R)
R * * * | * R * * | . * . .
* . . . | . * . . | * R * *
* . . . | . * . . | . * . .
* . . . | . * . . | . * . .

Bishop (B)
B . . . | . B . . | * . * .
. * . . | * . * . | . B . .
. . * . | . . . * | * . * .
. . . * | . . . . | . . . *

Knight (N)
N . . . | . N . . | . . . *
. . * . | . . . * | . N . .
. * . . | * . * . | . . . *
. . . . | . . . . | * . * .

Pawn (P)
P . . . | . P . . | * . * .
. * . . | * . * . | . P . .
. . . . | . . . . | * . * .
. . . . | . . . . | . . . .

Input/output
For reference, the sample puzzle from the Solitaire Chess webpage will be used:
. . . .
. B . .
R P . .
. . . N

The solution is to take the pawn with the knight, then take the knight with the rook, and finally take the bishop with the rook.
Input
Input must be in one of three forms; you are free to pick the one that is most convenient for you.

A string of characters such as .....B..RP.....N, with or without newlines. The character representing a blank space may be any character that isn't one of KQRBNP.
A list of lists (or a flattened list) where the elements are either characters or numbers, like so: [['.', '.', '.', '.'], ['.', 'B', '.', '.'], ['R', 'P', '.', '.'], ['.', '.', '.', 'N']] or [[0, 0, 0, 0], [0, 4, 0, 0], [3, 6, 0, 0], [0, 0, 0, 5]]. For the former, the character that represents a blank space may be anything that isn't one of KQRBNP. For the latter, I've given pieces the number that corresponds to their rank in my earlier list of moves (1 is a king, 4 is a bishop, 6 is a pawn, etc.). You are free to change the numbering.
A list of coordinates where each element has the form [x, y, 'c'], like so: [[1, 2, 'B'], [0, 1, 'R'], [1, 1, 'P'], [3, 0, 'N']].

If you pick one of the list-based input formats, the separators and delimiters may be any reasonable and understandable characters.
Output
Output must be a sequence of moves or a sequence of board states. Some puzzles have more than one solution; you may output one or all of them. If you choose to output a sequence of board states, each board must be in one of the three input formats, with a reasonable separator (such as newlines) between them.
If you choose to output a sequence of moves, they must be expressed as a list of pairs of coordinate pairs, like so: [[[3,0], [1,1]], [[0,1], [1,1]], [[1,1], [1,2]]]. [0,0] represents the bottom left corner, and again, separating and delimiting characters may be any reasonable choice.
If a given board cannot be solved, output any falsy value (0, empty string, etc.). If a given board has fewer than two pieces, behavior is undefined.
Test Cases
Note: outputs are only given as a list of pairs of coordinates since the other formats should be fairly easy to check for correctness (and I didn't feel like typing out all the possible output formats). Also, for the puzzles that have more than one solution, only one possibility is provided.
Input 1:
. . . N
. . . .
. R . .
. . B .

...N.....R....B.

[['.', '.', '.', 'N'], ['.', '.', '.', '.'], ['.', 'R', '.', '.'], ['.', '.', 'B', '.']]

[[0, 0, 0, 5], [0, 0, 0, 0], [0, 3, 0, 0], [0, 0, 4, 0]]

[[3, 3, 'N'], [1, 1, 'R'], [2, 0, 'B']]

Output 1:
[[[2,0], [1,1]], [[1,1], [3,3]]]

Input 2:
. . . .
. B . .
R P . .
. . . N

.....B..RP.....N

[['.', '.', '.', '.'], ['.', 'B', '.', '.'], ['R', 'P', '.', '.'], ['.', '.', '.', 'N']]

[[0, 0, 0, 0], [0, 4, 0, 0], [3, 6, 0, 0], [0, 0, 0, 5]]

[[1, 2, 'B'], [0, 1, 'R'], [1, 1, 'P'], [3, 0, 'N']]

Output 2:
[[[3,0], [1,1]], [[0,1], [1,1]], [[1,1], [1,2]]]

Input 3:
. N R .
B . . .
N . . B
. . P .

.NR.B...N..B..P.

[['.', 'N', 'R', '.'], ['B', '.', '.', '.'], ['N', '.', '.', 'B'], ['.', '.', 'P', '.']]

[[0, 5, 3, 0], [4, 0, 0, 0], [5, 0, 0, 4], [0, 0, 6, 0]]

[[1, 3, 'N'], [2, 3, 'R'], [0, 2, 'B'], [0, 1, 'N'], [3, 1, 'B'], [2, 0, 'P']]

Output 3:
[[[2,0], [3,1]], [[0,1], [1,3]], [[0,2], [1,3]], [[2,3], [1,3]], [[3,1], [1,3]]]

Input 4:
. . . N
. . . R
R B B .
N P P .

...N...RRBB.NPP.

[['.', '.', '.', 'N'], ['.', '.', '.', 'R'], ['R', 'B', 'B', '.'], ['N', 'P', 'P', '.']]

[[0, 0, 0, 5], [0, 0, 0, 3], [3, 4, 4, 0], [5, 6, 6, 0]]

[[3, 3, 'N'], [3, 2, 'R'], [0, 1, 'R'], [1, 1, 'B'], [2, 1, 'B'], [0, 0, 'N'], [1, 0, 'P'], [2, 0, 'P']]

Output 4:
[[[2,1], [3,2]], [[1,1], [3,3]], [[3,2], [1,0]], [[3,3], [0,0]], [[0,1], [0,0]], [[0,0], [1,0]], [[1,0], [2,0]]]

Input 5:
P . . .
. R . .
R . R .
. R . .

P....R..R.R..R..

[['P', '.', '.', '.'], ['.', 'R', '.', '.'], ['R', '.', 'R', '.'], ['.', 'R', '.', '.']]

[[6, 0, 0, 0], [0, 3, 0, 0], [3, 0, 3, 0], [0, 3, 0, 0]]

[[0, 3, 'P'], [1, 2, 'R'], [0, 1, 'R'], [2, 1, 'R'], [1, 0, 'R']]

Output 5:
[[[0,3], [1,2]], [[1,2], [2,1]], [[2,1], [1,0]], [[1,0], [0,1]]]

Input 6:
. P . N
K . . .
. . B .
. . R Q

.P.NK.....B...RQ

[['.', 'P', '.', 'N'], ['K', '.', '.', '.'], ['.', '.', 'B', '.'], ['.', '.', 'R', 'Q']]

[[0, 6, 0, 5], [1, 0, 0, 0], [0, 0, 4, 0], [0, 0, 3, 2]]

[[1, 3, 'P'], [3, 3, 'N'], [0, 2, 'K'], [2, 1, 'B'], [2, 0, 'R'], [3, 0, 'Q']]

Output 6:
[[[3,0], [2,0]], [[2,0], [2,1]], [[3,3], [2,1]], [[2,1], [1,3]], [[0,2], [1,3]]]

there is a little mistake in output 1, it should be [[[2,0], [1,1]], [[1,1], [3,3]]]

Also, as an additional note, the king is really a Mann (can be captured, but has the same move rules) (Fairy chess nomenclature is fun)

@Damien: Good spot! Thanks.

Is it OK to include the piece symbol in the output? Such as: [["R", [2, 0], [1, 1]], ["N", [1, 1], [3, 3]]]

@Arnauld: Yes, that would be okay. Somewhat strange though since you're listing the piece that's captured, not the capturing piece.

You're right. Actually, I'm now showing both the capturing and captured pieces. Hope that's okay too. ;)

@Arnauld: That would definitely be better.

Haskell, 226 195 191 188 bytes
Returns a list of all solutions. Each solution is a list of moves.
Returns an empty list if there is no solution.
Saved 4 bytes Thanks to Lynn.
Try it online
m"P"=[2]
m"N"=[5]
m"K"=[1,2]
m"R"=[1,4,9]
m"B"=[2,8,18]
m _=m"B"++m"R"
l%x=[z|z<-l,fst z/=x]
f[_]=[[]]
f l=[(i,j):r|(i@(s,t),a)<-l,(j@(u,v),_)<-l,(s-u)^2+(t-v)^2`elem`m a,r<-f$(j,a):l%i%j]

Usage:
main = do
    print $ f [((3, 3), "N"), ((1, 1), "R")]
    putStrLn""
    mapM_ print $ f [((3, 3), "N"), ((1, 1), "R"), ((2, 0), "B")]
    putStrLn""
    mapM_ print $ f [((1, 2), "B"), ((0, 1), "R"), ((1, 1), "P"), ((3, 0), "N")]
    putStrLn""
    mapM_ print $ f [((1, 3), "P"), ((3, 3), "N"), ((0, 2), "K"), ((2, 1), "B"), ((2, 0), "R"), ((3, 0), "Q")]

Output:
[]

[((2,0),(1,1)),((1,1),(3,3))]

[((3,0),(1,1)),((0,1),(1,1)),((1,1),(1,2))]

[((1,3),(0,2)),((3,3),(2,1)),((2,1),(0,2)),((3,0),(2,0)),((2,0),(0,2))]
[((1,3),(0,2)),((3,3),(2,1)),((3,0),(2,1)),((2,1),(2,0)),((2,0),(0,2))]
[((1,3),(0,2)),((3,3),(2,1)),((3,0),(2,0)),((2,0),(0,2)),((2,1),(0,2))]
[((1,3),(0,2)),((3,3),(2,1)),((3,0),(2,0)),((2,1),(0,2)),((2,0),(0,2))]
[((1,3),(0,2)),((2,0),(2,1)),((3,0),(2,1)),((3,3),(2,1)),((2,1),(0,2))]
[((1,3),(0,2)),((3,0),(2,1)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(0,2))]
[((1,3),(0,2)),((3,0),(2,0)),((2,0),(0,2)),((3,3),(2,1)),((2,1),(0,2))]
[((1,3),(0,2)),((3,0),(2,0)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(0,2))]
[((1,3),(0,2)),((3,0),(2,0)),((3,3),(2,1)),((2,1),(0,2)),((2,0),(0,2))]
[((1,3),(0,2)),((3,0),(2,0)),((3,3),(2,1)),((2,0),(0,2)),((2,1),(0,2))]
[((3,3),(2,1)),((2,1),(1,3)),((3,0),(2,0)),((2,0),(0,2)),((0,2),(1,3))]
[((3,3),(2,1)),((2,1),(0,2)),((1,3),(0,2)),((3,0),(2,0)),((2,0),(0,2))]
[((3,3),(2,1)),((2,1),(0,2)),((3,0),(2,0)),((2,0),(0,2)),((0,2),(1,3))]
[((3,3),(2,1)),((2,1),(0,2)),((3,0),(2,0)),((2,0),(0,2)),((1,3),(0,2))]
[((3,3),(2,1)),((2,1),(0,2)),((3,0),(2,0)),((1,3),(0,2)),((2,0),(0,2))]
[((3,3),(2,1)),((1,3),(0,2)),((2,1),(0,2)),((3,0),(2,0)),((2,0),(0,2))]
[((3,3),(2,1)),((1,3),(0,2)),((3,0),(2,1)),((2,1),(2,0)),((2,0),(0,2))]
[((3,3),(2,1)),((1,3),(0,2)),((3,0),(2,0)),((2,0),(0,2)),((2,1),(0,2))]
[((3,3),(2,1)),((1,3),(0,2)),((3,0),(2,0)),((2,1),(0,2)),((2,0),(0,2))]
[((3,3),(2,1)),((3,0),(2,1)),((2,1),(2,0)),((2,0),(0,2)),((0,2),(1,3))]
[((3,3),(2,1)),((3,0),(2,1)),((2,1),(2,0)),((2,0),(0,2)),((1,3),(0,2))]
[((3,3),(2,1)),((3,0),(2,1)),((2,1),(2,0)),((1,3),(0,2)),((2,0),(0,2))]
[((3,3),(2,1)),((3,0),(2,1)),((1,3),(0,2)),((2,1),(2,0)),((2,0),(0,2))]
[((3,3),(2,1)),((3,0),(2,0)),((2,0),(0,2)),((0,2),(1,3)),((2,1),(1,3))]
[((3,3),(2,1)),((3,0),(2,0)),((2,0),(0,2)),((2,1),(0,2)),((1,3),(0,2))]
[((3,3),(2,1)),((3,0),(2,0)),((2,0),(0,2)),((2,1),(1,3)),((0,2),(1,3))]
[((3,3),(2,1)),((3,0),(2,0)),((2,0),(0,2)),((1,3),(0,2)),((2,1),(0,2))]
[((3,3),(2,1)),((3,0),(2,0)),((2,1),(1,3)),((2,0),(0,2)),((0,2),(1,3))]
[((3,3),(2,1)),((3,0),(2,0)),((2,1),(0,2)),((2,0),(0,2)),((0,2),(1,3))]
[((3,3),(2,1)),((3,0),(2,0)),((2,1),(0,2)),((2,0),(0,2)),((1,3),(0,2))]
[((3,3),(2,1)),((3,0),(2,0)),((2,1),(0,2)),((1,3),(0,2)),((2,0),(0,2))]
[((3,3),(2,1)),((3,0),(2,0)),((1,3),(0,2)),((2,0),(0,2)),((2,1),(0,2))]
[((3,3),(2,1)),((3,0),(2,0)),((1,3),(0,2)),((2,1),(0,2)),((2,0),(0,2))]
[((0,2),(1,3)),((2,1),(3,0)),((2,0),(3,0)),((3,0),(3,3)),((3,3),(1,3))]
[((0,2),(1,3)),((2,0),(2,1)),((3,0),(2,1)),((3,3),(2,1)),((2,1),(1,3))]
[((0,2),(1,3)),((3,0),(2,1)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(1,3))]
[((0,2),(1,3)),((3,0),(2,0)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(1,3))]
[((2,1),(3,0)),((0,2),(1,3)),((2,0),(3,0)),((3,0),(3,3)),((3,3),(1,3))]
[((2,1),(3,0)),((2,0),(3,0)),((3,0),(3,3)),((3,3),(1,3)),((0,2),(1,3))]
[((2,1),(3,0)),((2,0),(3,0)),((3,0),(3,3)),((0,2),(1,3)),((3,3),(1,3))]
[((2,1),(3,0)),((2,0),(3,0)),((0,2),(1,3)),((3,0),(3,3)),((3,3),(1,3))]
[((2,0),(2,1)),((1,3),(0,2)),((3,0),(2,1)),((3,3),(2,1)),((2,1),(0,2))]
[((2,0),(2,1)),((0,2),(1,3)),((3,0),(2,1)),((3,3),(2,1)),((2,1),(1,3))]
[((2,0),(2,1)),((3,0),(2,1)),((1,3),(0,2)),((3,3),(2,1)),((2,1),(0,2))]
[((2,0),(2,1)),((3,0),(2,1)),((3,3),(2,1)),((2,1),(1,3)),((0,2),(1,3))]
[((2,0),(2,1)),((3,0),(2,1)),((3,3),(2,1)),((2,1),(0,2)),((1,3),(0,2))]
[((2,0),(2,1)),((3,0),(2,1)),((3,3),(2,1)),((1,3),(0,2)),((2,1),(0,2))]
[((2,0),(2,1)),((3,0),(2,1)),((3,3),(2,1)),((0,2),(1,3)),((2,1),(1,3))]
[((2,0),(2,1)),((3,0),(2,1)),((0,2),(1,3)),((3,3),(2,1)),((2,1),(1,3))]
[((3,0),(3,3)),((3,3),(1,3)),((1,3),(0,2)),((0,2),(2,0)),((2,0),(2,1))]
[((3,0),(2,1)),((2,1),(2,0)),((2,0),(0,2)),((0,2),(1,3)),((1,3),(3,3))]
[((3,0),(2,1)),((1,3),(0,2)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(0,2))]
[((3,0),(2,1)),((0,2),(1,3)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(1,3))]
[((3,0),(2,1)),((2,0),(2,1)),((1,3),(0,2)),((3,3),(2,1)),((2,1),(0,2))]
[((3,0),(2,1)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(1,3)),((0,2),(1,3))]
[((3,0),(2,1)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(0,2)),((1,3),(0,2))]
[((3,0),(2,1)),((2,0),(2,1)),((3,3),(2,1)),((1,3),(0,2)),((2,1),(0,2))]
[((3,0),(2,1)),((2,0),(2,1)),((3,3),(2,1)),((0,2),(1,3)),((2,1),(1,3))]
[((3,0),(2,1)),((2,0),(2,1)),((0,2),(1,3)),((3,3),(2,1)),((2,1),(1,3))]
[((3,0),(2,0)),((2,0),(0,2)),((0,2),(1,3)),((3,3),(2,1)),((2,1),(1,3))]
[((3,0),(2,0)),((2,0),(0,2)),((1,3),(0,2)),((3,3),(2,1)),((2,1),(0,2))]
[((3,0),(2,0)),((2,0),(0,2)),((3,3),(2,1)),((2,1),(0,2)),((1,3),(0,2))]
[((3,0),(2,0)),((2,0),(0,2)),((3,3),(2,1)),((2,1),(1,3)),((0,2),(1,3))]
[((3,0),(2,0)),((2,0),(0,2)),((3,3),(2,1)),((0,2),(1,3)),((2,1),(1,3))]
[((3,0),(2,0)),((2,0),(0,2)),((3,3),(2,1)),((1,3),(0,2)),((2,1),(0,2))]
[((3,0),(2,0)),((2,0),(2,1)),((1,3),(0,2)),((3,3),(2,1)),((2,1),(0,2))]
[((3,0),(2,0)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(1,3)),((0,2),(1,3))]
[((3,0),(2,0)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(0,2)),((1,3),(0,2))]
[((3,0),(2,0)),((2,0),(2,1)),((3,3),(2,1)),((1,3),(0,2)),((2,1),(0,2))]
[((3,0),(2,0)),((2,0),(2,1)),((3,3),(2,1)),((0,2),(1,3)),((2,1),(1,3))]
[((3,0),(2,0)),((2,0),(2,1)),((0,2),(1,3)),((3,3),(2,1)),((2,1),(1,3))]
[((3,0),(2,0)),((1,3),(0,2)),((2,0),(0,2)),((3,3),(2,1)),((2,1),(0,2))]
[((3,0),(2,0)),((1,3),(0,2)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(0,2))]
[((3,0),(2,0)),((1,3),(0,2)),((3,3),(2,1)),((2,1),(0,2)),((2,0),(0,2))]
[((3,0),(2,0)),((1,3),(0,2)),((3,3),(2,1)),((2,0),(0,2)),((2,1),(0,2))]
[((3,0),(2,0)),((3,3),(2,1)),((2,1),(1,3)),((2,0),(0,2)),((0,2),(1,3))]
[((3,0),(2,0)),((3,3),(2,1)),((2,1),(0,2)),((2,0),(0,2)),((0,2),(1,3))]
[((3,0),(2,0)),((3,3),(2,1)),((2,1),(0,2)),((2,0),(0,2)),((1,3),(0,2))]
[((3,0),(2,0)),((3,3),(2,1)),((2,1),(0,2)),((1,3),(0,2)),((2,0),(0,2))]
[((3,0),(2,0)),((3,3),(2,1)),((2,0),(0,2)),((0,2),(1,3)),((2,1),(1,3))]
[((3,0),(2,0)),((3,3),(2,1)),((2,0),(0,2)),((2,1),(0,2)),((1,3),(0,2))]
[((3,0),(2,0)),((3,3),(2,1)),((2,0),(0,2)),((2,1),(1,3)),((0,2),(1,3))]
[((3,0),(2,0)),((3,3),(2,1)),((2,0),(0,2)),((1,3),(0,2)),((2,1),(0,2))]
[((3,0),(2,0)),((3,3),(2,1)),((1,3),(0,2)),((2,1),(0,2)),((2,0),(0,2))]
[((3,0),(2,0)),((3,3),(2,1)),((1,3),(0,2)),((2,0),(0,2)),((2,1),(0,2))]
[((3,0),(2,0)),((0,2),(1,3)),((2,0),(2,1)),((3,3),(2,1)),((2,1),(1,3))]

Beautiful solution! Inlining ! saves a few bytes: f l=[(i,j):r|(i@(s,t),a)<-l,(j@(u,v),_)<-l%i,r<-f$(j,a):l%i%j,(s-u)^2+(t-v)^2`elem`m a]

Nice! What does the output look like?

[[((2,0),(1,1)),((1,1),(3,3))]]. A list of solutions, where a solution is a list of moves, where a move is ((x1,y1),(x2,y2)).

m"P"=[1]
Shouldn't it be 2?

Yes, of course! Thanks

Javascript (ES6), 372 361 358 bytes
It (still) needs some optimizing. But here is a first 2nd 3rd attempt.
b=>{for(n=-4,b=[...b];n<36;b.splice(n+=8,0,0,0,0,0));l=[];(M=(P,u,Z,z,L)=>{for(P=u=n;u--;)
for((z=[640,164928,641,259,899,898]["PNBRQK".indexOf(b[u])])&&P++,L=1,s=z&1;z>>=1;L++)for(Z
=u;z&1&!((Z+=L)&n)&&(b[Z]<'A'||!(M(l.push([b[Z],[u&3,31-u>>3],b[u],[Z&3,31-Z>>3]]),b[Z]=b[u
],b[u]='.'),b[u]=b[Z],b[Z]=l.pop()[0]))&&s||(L=-L,Z=u,L<0););P-37||console.log(l)})()}

Output format:
// Puzzle #1
[["B", [2, 0], "R", [1, 1]], ["B", [1, 1], "N", [3, 3]]]

Example:

let F =
b=>{for(n=-4,b=[...b];n<36;b.splice(n+=8,0,0,0,0,0));l=[];(M=(P,u,Z,z,L)=>{for(P=u=n;u--;)for((z=[640,164928,641,259,899,898]["PNBRQK".indexOf(b[u])])&&P++,L=1,s=z&1;z>>=1;L++)for(Z=u;z&1&!((Z+=L)&n)&&(b[Z]<'A'||!(M(l.push([b[Z],[u&3,31-u>>3],b[u],[Z&3,31-Z>>3]]),b[Z]=b[u],b[u]='.'),b[u]=b[Z],b[Z]=l.pop()[0]))&&s||(L=-L,Z=u,L<0););P-37||console.log(l)})()}

console.log("Puzzle #1");
F("...N.....R....B.");
console.log("Puzzle #2");
F(".....B..RP.....N");

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


text:
Output the nth rational number according to the Stern-Brocot sequence
The Stern-Brocot sequence is a Fibonnaci-like sequence which can be constructed as follows:

Initialise the sequence with s(1) = s(2) = 1
Set counter n = 1
Append s(n) + s(n+1) to the sequence
Append s(n+1) to the sequence
Increment n, return to step 3

This is equivalent to:

Amongst other properties, the Stern-Brocot sequence can be used to generate every possible positive rational number. Every rational number will be generated exactly once, and it will always appear in its simplest terms; for example, 1/3 is the 4th rational number in the sequence, but the equivalent numbers 2/6, 3/9 etc won't appear at all.
We can define the nth rational number as r(n) = s(n) / s(n+1), where s(n) is the nth Stern-Brocot number, as described above.
Your challenge is to write a program or function which will output the nth rational number generated using the Stern-Brocot sequence.

The algorithms described above are 1-indexed; if your entry is 0-indexed, please state in your answer
The algorithms described are for illustrative purposes only, the output can be derived in any way you like (other than hard-coding)
Input can be via STDIN, function parameters, or any other reasonable input mechanism
Ouptut can be to STDOUT, console, function return value, or any other reasonable output stream
Output must be as a string in the form a/b, where a and b are the relevant entries in the Stern-Brocot sequence. Evaluating the fraction before output is not permissable. For example, for input 12, output should be 2/5, not 0.4.
Standard loopholes are disallowed

This is code-golf, so shortest answer in bytes will win.
Test cases
The test cases here are 1-indexed.
n    r(n)
--  ------
1    1/1
2    1/2
3    2/1
4    1/3
5    3/2
6    2/3
7    3/1
8    1/4
9    4/3
10   3/5
11   5/2
12   2/5
13   5/3
14   3/4
15   4/1
16   1/5
17   5/4
18   4/7
19   7/3
20   3/8
50   7/12
100  7/19
1000 11/39

OEIS entry: A002487

Excellent Numberphile video discussing the sequence: Infinite Fractions

Can the output use Trues instead of 1s?

@Loovjo No, True/2 isn't a valid fraction (as far as I'm concerned). As an aside, True isn't always 1 - some languages use -1 instead to avoid potential mistakes when applying bitwise operators. [citation needed]

related

@Sok citation

@Sok but in Python, True is equivalent to 1 and True/2 would be 1/2.

Are equivalent representations (like -2/-1 == 2/1 or 4/2 == 2/1) acceptable?

@LeakyNun That may be the case, but True is not the same in every language. This would open the door to different representations coming from different languages. In my opinion, the output from every language should be consistent, so I'm not allowing True in the place of 1

@Mego No, as the fractions should be generated using some variation of the Stern-Brocot sequence. Negative numbers don't feature in that sequence, and as noted in the question, every rational number generated will be in its simplest terms.

Jelly, 14 bytes
3ẋḶŒpḄċ
’Ç”/⁸Ç

Try it online!
Ooh, looks like I can beat the accepted answer by @Dennis, and in the same language at that. This works using a formula from OEIS: the number of ways to express (the number minus 1) in hyperbinary (i.e. binary with 0, 1, 2 as digits). Unlike most Jelly programs (which work either as a full program or a function), this one works only as a full program (because it sends part of the output to stdout, and returns the rest; when used as a full program the return value is sent to stdout implicitly, so all the output is in the same place, but this wouldn't work for a function submission).
This version of the program is very inefficient. You can create a much faster program that works for all input up to 2ⁿ via placing n just after the ẋ on the first line; the program has O(n × 3ⁿ) performance, so keeping n small is fairly important here. The program as written sets n equal to the input, which is clearly large enough, but also clearly too large in almost all cases (but hey, it saves bytes).
Explanation
As usual in my Jelly explanations, text in braces (e.g. {the input}) shows something that automatically filled in by Jelly due to missing operands in the original program.
Helper function (calculates the nth denominator, i.e. the n+1th numerator):
3ẋḶŒpḄċ
3ẋ       3, repeated a number of times equal to {the argument}
  Ḷ      Map 3 to [0, 1, 2]
   Œp    Take the cartesian product of that list
     Ḅ   Convert binary (or in this case hyperbinary) to a number
      ċ  Count number of occurrences of {the argument} in the resulting list

The first five bytes are basically just generating all possible hyperbinary numbers up to a given length, e.g. with input 3, the output of Ḷ is [[0,1,2],[0,1,2],[0,1,2]] so the cartesian product is [[0,0,0],[0,0,1],[0,0,2],[0,1,0],…,[2,2,1],[2,2,2]]. Ḅ basically just multiplies the last entry by 1, the penultimate entry by 2, the antepenultimate entry by 4, etc., and then adds; although this is normally used to convert binary to decimal, it can handle the digit 2 just fine, and thus works for hyperbinary too. Then we count the number of times the input appears in the resulting list, in order to get an appropriate entry in the sequence. (Luckily, the numerator and denominator follow the same sequence).
Main program (asks for the numerator and denominator, and formats the output):
’Ç”/⁸Ç
’Ç      Helper function (Ç), run on {the input} minus 1 (‘)
  ”/    {Output that to stdout}; start again with the constant '/'
    ⁸Ç  {Output that to stdout}; then run the helper function (Ç) on the input (⁸)

Somehow I keep writing programs that take almost as many bytes to handle I/O as they do to solve the actual problem…

Good grief, you weren't kidding about it being inefficient - on TIO 12 takes 20s to complete, and 13 times out completely! Accepted, even though I can't verify all the test cases.

Haskell, 78 77 65 58 bytes
Shamelessly stealing the optimized approach gives us:
(s#t)0=show s++'/':show t
(s#t)n=t#(s+t-2*mod s t)$n-1
1#1

Thanks to @nimi for golfing a few bytes using an infix function!
(Still) uses 0-based indexing.

The old approach:
s=(!!)(1:1:f 0)
f n=s n+s(n+1):s(n+1):(f$n+1)
r n=show(s n)++'/':(show.s$n+1)

Damn the output format... And indexing operators. EDIT: And precedence.
Fun fact: if heterogenous lists were a thing, the last line could be:
r n=show>>=[s!!n,'/',s!!(n+1)]

Using a guard to bind s!!n should be one byte shorter: f n|x<-s!!n=x:x+x+1:f$n+1

@Laikoni s!!n+1 is not (s!!n)+1 but s!!(n+1) which is why I can't do that :/

Indeed, that should have been obvious. Its just ... so many s!!n in there!

Sadly, even using g=s!! isn't shorter...

You can use ++'/':(show.s$n+1) in r to save a byte.

Switch to an an infix function: (s#t)0=show..., (s#t)n=t#(s+t-2*mod s t)$n-1, r=1#1. You can even omit r, i.e. the last line is just 1#1.

@nimi Thanks, I wasn't aware I can omit the r= at the bottom.

CJam (20 bytes)
1_{_@_2$%2*-+}ri*'/\

Online demo. Note that this is 0-indexed. To make it 1-indexed, replace the initial 1_ by T1.
Dissection
This uses the characterisation due to Moshe Newman that

the fraction a(n+1)/a(n+2) can be generated from the previous fraction a(n)/a(n+1) = x by 1/(2*floor(x) + 1 - x)

If x = s/t then we get
  1 / (2 * floor(s/t) + 1 - s/t)
= t / (2 * t * floor(s/t) + t - s)
= t / (2 * (s - s%t) + t - s)
= t / (s + t - 2 * (s % t))

Now, if we assume that s and t are coprime then
  gcd(t, s + t - 2 * (s % t))
= gcd(t, s - 2 * (s % t))
= gcd(t, -(s % t))
= 1

So a(n+2) = a(n) + a(n+1) - 2 * (a(n) % a(n+1)) works perfectly.
1_           e# s=1, t=1
{            e# Loop...
  _@_2$%2*-+ e#   s, t = t, s + t - 2 * (s % t)
}
ri*          e# ...n times
'/\          e# Separate s and t with a /

Love the methodology here, awesome answer!

If you scroll further down the OEIS entry you'll find that Mike Stay already submitted that formula.

Jelly, 16 bytes
L‘Hị⁸Sṭ
1Ç¡ṫ-j”/

Try it online! or verify all test cases.
How it works
1Ç¡ṫ-j”/  Main link. Argument: n

1         Set the return value to 1.
 Ç¡       Apply the helper link n times.
   ṫ-     Tail -1; extract the last two items.
     j”/  Join, separating by a slash.

L‘Hị⁸Sṭ   Helper link. Argument: A (array)

L         Get the length of A.
 ‘        Add 1 to compute the next index.
  H       Halve.
   ị⁸     Retrieve the item(s) of A at those indices.
          If the index in non-integer, ị floors and ceils the index, then retrieves
          the items at both indices.
    S     Compute the sum of the retrieved item(s).
     ṭ    Tack; append the result to A.

05AB1E, 34 33 25 23 bytes
XX‚¹GÂ2£DO¸s¦ìì¨}R2£'/ý

Explanation
XX‚                        # push [1,1]
   ¹G           }          # input-1 times do
     Â                     # bifurcate
      2£                   # take first 2 elements of reversed list
        DO¸                # duplicate and sum 1st copy, s(n)+s(n+1)
           s¦              # cut away the first element of 2nd copy, s(n)
             ìì            # prepend both to list
               ¨           # remove last item in list
                 R2£       # reverse and take the first 2 elements
                    '/ý    # format output
                           # implicitly print

Try it online
Saved 2 bytes thanks to Adnan.

Does this also work?: XX‚¹GÂ2£DO¸s¦ìì¨}R2£'/ý.

@Adnan Indeed. I forgot that ý can format a list. Nice.

Python 2, 85 81 bytes
x,s=input(),[1,1]
for i in range(x):s+=s[i]+s[i+1],s[i+1]
print`s[x-1]`+"/"+`s[x]`

This submission is 1-indexed.
Using a recursive function, 85 bytes:
s=lambda x:int(x<1)or x%2 and s(x/2)or s(-~x/2)+s(~-x/2)
lambda x:`s(x)`+"/"+`s(x+1)`

If an output like True/2 is acceptable, here's one at 81 bytes:
s=lambda x:x<1 or x%2 and s(x/2)or s(-~x/2)+s(~-x/2)
lambda x:`s(x)`+"/"+`s(x+1)`

MATL, 20 bytes
FT+"@:qtPXnosV47]xhh

This uses the characterization in terms of binomial coefficients given in the OEIS page.
The algorithm works in theory for all numbers, but in practice it is limited by MATL's numerical precision, and so it doesn't work for large entries. The result is accurate for inputs up to 20 at least.
Try it online!
Explanation
FT+      % Implicitly take input n. Add [0 1] element-wise. Gives [n n+1]
"        % For each k in [n n+1]
  @:q    %   Push range [0 1 ... k-1]
  tP     %   Duplicate and flip: push [k-1 ... 1 0]
  Xn     %   Binomial coefficient, element-wise. Gives an array
  os     %   Number of odd entries in that array
  V      %   Convert from number to string
  47     %   Push 47, which is ASCII for '\'
]        % End for each
x        % Remove second 47
hh       % Concatenate horizontally twice. Automatically transforms 47 into '\'
         % Implicitly display

C (GCC), 79 bytes
Uses 0-based indexing.
s(n){return!n?:n%2?s(n/2):s(-~n/2)+s(~-n/2);}r(n){printf("%d/%d",s(n),s(n+1));}

Ideone

x?:y is a gcc extension.

JavaScript (ES6), 43 bytes
f=(i,n=0,d=1)=>i?f(i-1,d,n+d-n%d*2):n+'/'+d

1-indexed; change to n=1 for 0-indexed. The linked OEIS page has a useful recurrence relation for each term in terms of the previous two terms; I merely reinterpreted it as a recurrence for each fraction in terms of the previous fraction. Unfortunately we don't have inline TeX so you'll just have to paste it onto another site to find out how this formats:
$$ \frac{a}{b} \Rightarrow \frac{b}{a + b - 2(a \bmod b)} $$

m4, 131 bytes
define(s,`ifelse($1,1,1,eval($1%2),0,`s(eval($1/2))',`eval(s(eval(($1-1)/2))+s(eval(($1+1)/2)))')')define(r,`s($1)/s(eval($1+1))')

Defines a macro r such that r(n) evaluates according to the spec. Not really golfed at all, I just coded the formula.

124 bytes

Python 2, 66 bytes
f=lambda n:1/n or f(n/2)+n%2*f(-~n/2)
lambda n:`f(n)`+'/'+`f(n+1)`

Uses the recursive formula.

Actually, 18 bytes
11,`│;a%τ@-+`nk'/j

Try it online!
This solution uses Peter's formula and is likewise 0-indexed. Thanks to Leaky Nun for a byte.
Explanation:
11,`│;a%τ@-+`nk'/j
11                  push 1, 1
  ,`│;a%τ@-+`n      do the following n times (where n is the input):
                      stack: [t s]
    │                 duplicate the entire stack ([t s t s])
     ;                dupe t ([t t s t s])
      a               invert the stack ([s t s t t])
       %              s % t ([s%t s t t])
        τ             multiply by 2 ([2*(s%t) s t t])
         @-           subtract from s ([s-2*(s%t) s t])
           +          add to t ([t+s-2*(s%t) t])
                      in effect, this is s,t = t,s+t-2*(s%t)
              k'/j  push as a list, join with "/"

A controversial byte off

@LeakyNun I'll hold off on that improvement until there's clarification from the OP.

MATL, 32 30 bytes
1i:"tt@TF-)sw@)v]tGq)V47bG)Vhh

This uses a direct approach: generates enough members of the sequence, picks the two desired ones and formats the output.
Try it online!

R, 93 bytes
f=function(n)ifelse(n<3,1,ifelse(n%%2,f(n/2-1/2)+f(n/2+1/2),f(n/2)))
g=function(n)f(n)/f(n+1)

Literally the simplest implementation. Working on golfing it a bit.

Ruby, 49 bytes
This is 0-indexed and uses Peter Taylor's formula. Golfing suggestions welcome.
->n{s=t=1;n.times{s,t=t,s+t-2*(s%t)};"#{s}/#{t}"}

Maple
0: do 1/(1+floor(%)-frac(%))od;

Uses % which is the ditto operator reevaluating the last expression.

Welcome to Code Golf, nice first answer!

><>, 34+2 = 36 bytes
After seeing Peter Taylor's excellent answer, I re-wrote my test answer (which was an embarrassing 82 bytes, using very clumsy recursion).
&01\$n"/"on;
&?!\:@}:{:@+@%2*-&1-:

It expects the input to be present on the stack, so +2 bytes for the -v flag. Try it online!

Octave, 90 bytes
function f(i)S=[1 1];for(j=1:i/2)S=[S S(j)+S(j+1) (j+1)];end;printf("%d/%d",S(i),S(i+1));end

C#, 91 90 bytes
n=>{Func<int,int>s=_=>_;s=m=>1==m?m:s(m/2)+(0==m%2?0:s(m/2+1));return$"{s(n)}/{s(n+1)}";};

Casts to Func<int, string>.
This is the recursive implementation.
Ungolfed:
n =>
{
    Func<int,int> s = _ => _; // s needs to be set to use recursively. _=>_ is the same byte count as null and looks cooler.
    s = m =>
        1 == m ? m               // s(1) = 1
        : s(m/2) + (0 == m%2 ? 0 // s(m) = s(m/2) for even
        : s(m/2+1));             // s(m) = s(m/2) + s(m/2+1) for odd
    return $"{s(n)}/{s(n+1)}";
};

Edit: -1 byte. Turns out C# doesn't need a space between return and $ for interpolated strings.

Python 2, 59 bytes
s,t=1,1;exec"s,t=t,s+t-2*(s%t);"*input();print'%d/%d'%(s,t)

Uses Peter's formula and is similarly 0-indexed.
Try it online

J, 29 bytes
([,'/',])&":&([:+/2|]!&i.-)>:

Usage
Large values of n require a suffix of x which denotes the use of extended integers.
   f =: ([,'/',])&":&([:+/2|]!&i.-)>:
   f 1
1/1
   f 10
3/5
   f 50
7/12
   f 100x
7/19
   f 1000x
11/39

100 counts as a "large value"?

@dcsohl In this method, the binomial coefficients are computed, and for n = 100, the largest one computed is C(72, 28) = 75553695443676829680 > 2^64 and will require extended integers to avoid floating point values.

Mathematica, 108 106 101 bytes
(s={1,1};n=1;a=AppendTo;t=ToString;Do[a[s,s[[n]]+s[[++n]]];a[s,s[[n]]],#];t@s[[n-1]]<>"/"<>t@s[[n]])&

R, 84 bytes
function(n,K=c(1,1)){for(i in 1:n)K=c(K,K[i]+K[i+1],K[i+1])
paste0(K[i],"/",K[i+1])}

Try it online!
The older R implementation doesn't follow the specs, returning a floating point rather than a string, so here's one that does.

APL (Dyalog Unicode), 56 bytes (SBCS)
{1(⍵{s←⍺⊃⍵⋄t←⍵[n←⍺+1]⋄⍺=⍺⍺:,/⍕¨s'/'t⋄n∇⍵,(s+t),t})1 1}

Try it online!
Inner operator:
{                 ⍝ ⍺ is counter, ⍺⍺ is input, ⍵ is sequence
 s ← ⍺ ⊃ ⍵       ⍝ s is the ⍺th element of ⍵ (1-indexed), i.e. s(n)
⋄t ← ⍵[n←⍺+1]     ⍝ t is s(n+1). Also create variable n that holds ⍺+1
⋄⍺ = ⍺⍺:          ⍝ If counter equals the n we want to reach
  s ÷ t           ⍝ Return s(n) / s(n+1)
⋄n ∇ ⍵,(s+t),t   ⍝ Otherwise, call itself again with counter incremented
                 ⍝ and the new terms added to the sequence
                 ⍝ ∇ is self reference and , is concatenate
}

The outer function just calls the inner one with 1 as the initial value of the counter, 1 1 as the initial sequence, and its right argument as the left operand of the inner operator (n).

PARI/GP, 33 bytes
f(n)=if(n,(1+f(n\2)^q=n%2*2-1)^q)

Attempt This Online!

source: Stack Exchange

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

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

sort: votes


text:
Golf me a card dealer
Frank has been working IT his whole life. Each day he responds to tickets, organizes equipment, and reports to his boss. One day, near the closing time on friday, Frank is doing his final inventory and sorting come cables in the supply closet. Suddenly, the door closes and locks from the outside! Such audacity! Frank shakes the door to try and let anyone know that he's stuck in the closet. Blast, nobody comes to his aid. With no cellphone, and no internet connection, Frank settles in with his laptop. After countless games of solitaire, frank decides to make his own card game....
Challenge:
In this case, you are frank (but not really). Your challenge is to create a dealer that can deal hands of cards, that could be dealt realistically. Your program needs to do 2 things: deal hands of cards according to an input, and take all the hands and reshuffle them. You must do this in the least ammount of bytes possible.
Rules:
Possible cards include all classic numbers and faces (a,2,3,4,5,6,7,8,9,10,j,q,k) and all suits (c,s,h,d), and two jokers (0j).
If a card is dealt, it cannot be dealt again until the program is given the reshuffle command, or it runs out of cards.
valid inputs are 'd' to deal a hand of 6 cards, and 'r' to reshuffle. NOTE that you can only deal out 9 hands before you run out of cards. Your program can either:
Automatically reshuffle,
Or give a 'X' to indicate that the dealer is out of cards.
your program needs to be able to take multiple commands over its running span.
All possible hands need to be able to be dealt in every order. Though, your program does NOT have to be random.
Examples:
We deal twice, the first hand yields the 2 of hearts, a 4 of spades, 9 of clubs, a joker, an ace of spades, and a 6 of diamonds. The second hand yields the 3 of hearts, the 10 of diamonds, the 10 of clubs, the king of clubs, the ace of diamonds, and the queen of spades. this is VALID because this is possible in real life.

d
  2h4s9c0jas6d
  d
  3h10d10ckcadqs

We deal twice, the first hand yields a mass of 5 cards (indicated by the dashes) and a 6 of hearts. The second hand deals another mass of 5 cards (again, the dashes) and another 6 of hearts. This is INVALID because it cannot happen in real life.

d
  -----6h
  d
  6h-----

we deal once, reset, and deal again. some of the cards from the first and the second deal match. this is VALID because cardstacks are renewed when shuffled.

d
  123456
  r
d
  456789

Scoring:
As with any golf, the lowest byte count wins! Good luck!

how many jokers?

@Rod 2, as standard. that way all 9 hands will have the same number of cards, as the deck will be 54 cards total.

Can programs take a list of commands [d,d,r,d,d...], and output each of the deals that way?

@NathanMerrill sure, so long as it CAN take multiple commands.

Is it OK to display T instead of 10?

@Arnauld no, 10 is 10 as 5 is 5.

@Rod 9 6-card hands is 54 cards, so I'm assuming that means 2.

Can we distinguish between the jokers, e.g., 0j and 1j, so that every card is unique?

@TimmyD sure. that's fine.

Pyth - 42 41 bytes
Will need to restructure this.
VcQ\rj<c9.S++M*+md"jqka"}2T"cshd"m"0j"2lN

Try it online here.
Stops giving cards after 9 deals.

Javascript (ES6), 189 bytes
i=>{for(n=52,d=['0j','0j'];n;d[n+1]='123456789JQKA'[--n>>2]+(n<4?0:'')+'cdhs'[n&3]);i.forEach(c=>{c!='r'&&n-54||(d.sort((a,b)=>Math.random()-.5),n=0);c=='d'&&console.log(d.slice(n,n+=6))})}

Demo:

let F =
i=>{for(n=52,d=['0j','0j'];n;d[n+1]='123456789JQKA'[--n>>2]+(n<4?0:'')+'cdhs'[n&3]);i.forEach(c=>{c!='r'&&n-54||(d.sort((a,b)=>Math.random()-.5),n=0);c=='d'&&console.log(d.slice(n,n+=6))})}

F([..."rddrdddddd"]);

Python 3, 184 192 179 bytes
d=lambda:[(v+s,'10'+s)[v=='1']for v in'123456789JQKA'for s in'SCHD']+['0J']*2
_=0;c=d()
while 1:
 if input()<'r'*(len(c)>5):[print(c.pop())for i in'_'*6]
 else:c=d();del c[_];_+=1

Edit: jokers
Edit 2: switched from using random and shuffling the list to cycling through the list and deleting 1 index from it incrementally.
Try it

The print in the list comprehension works only in Python 3, not in Python 2 - for me at last. Also you're missing the jokers.

05AB1E, 56 bytes
Automatically reshuffles.
9L>"ajqk"Sì"cshd"â€J„0jD‚ì©UvXg>y'rQ~i®U}y'dQiX.r6ô¬,¦˜U

Explanation
Generate the list of cards:
9L>"ajqk"Sì                     # list of card values, excluding jokers
           "cshd"â€J            # cartesian product with suits to generate all cards except jokers
                    „0jD‚ì      # add the jokers
                          ©U    # store in register and X

The actual function:
v                             # for each in input
         i  }                 # if
 Xg>                          # we're out of cards
        ~                     # or
    y'rQ                      # it's an explicit reshuffle
          ®U                  # get full list of cards from register and store in X
                              # then
             y'dQi            # if it's a draw
                  X.r         # shuffle current list of cards
                     6ô¬,     # print a list of 6 cards
                         ¦˜U  # save the rest of the cards in X

Try it online

PHP, 342 bytes
Update of @hd-s version.
$c=explode(",","2,3,4,5,6,7,8,9,T,J,Q,K,A");$a=["h"=>$c,"d"=>$c,"s"=>$c,"c"=>$c,"0"=>["J","J"]];$b=$a;$f=0;foreach(explode(",",$argv[1])as$g){if($g=='d'&&$f<54){$f+=6;for($i=0;$i<6;$i++){$s=array_keys($a)[rand(0,4)];$l=rand(1,count($a[$s])-1);if(isset($a[$s][$l])){echo$a[$s][$l].$s;unset($a[$s][$l])}else{$i--}}echo PHP_EOL}else{$f=0;$a=$b}}

Please test before qualifying. PHP 5.3+
Changes:

All variables renamed to be 1 byte long
The card array is just reset at the end
All cards dealt check shortened
Couple of spaces removed

Total bytes saved: 69

PowerShell v2+, 174 158 bytes
$a=(2..10+[char[]]'ajqk'|%{$i=$_;[char[]]'cshd'|%{"$i$_"}})+'0j'+'1j';$x=,0
for(){switch(read-host){'d'{$a|?{$_-notin$x}|Random -c 6|%{$x+=$_;$_}}'r'{$x=,0}}}

Creates an array of the number and suit combinations, plus two jokers (note they're unique), stores that into $a. This forms our full deck. Sets array $x equal to [0]. This represents the cards that we've already dealt. Then enters an infinite for loop. Performs a read-host to get the d or r (other behavior is undefined).
For dealing, pipes $a a Where-Object to pull out the items that are -notin$x (i.e., the cards we haven't dealt yet). Those are piped to Get-Random with a -count of 6, which will randomly select 6 distinct elements. We store those newly-dealt cards into $x, and the card is placed $_ onto the pipeline, which will get flushed when the next read-host happens and output one-per-line thanks to the default behavior of Write-Output. If the user attempts to deal when $a = $x (i.e., all cards have been dealt), then the Get-Random will be selecting from nothing, and so nothing will be output.
For the reshuffling, we just set $x back to ,0 as the original array.
Note you'll need to ctrl-c or otherwise force quit the program.
Example execution
PS C:\Tools\Scripts\golfing> .\golf-card-dealer.ps1
d
8c
5h
as
ah
1j
ac
d
5d
2h
8s
6h
2c
qs
d
8h
6d
10c
10h
6s
4h
d
js
9h
4c
6c
qd
kd
d
3d
jc
8d
2s
3h
4d
d
kh
jd
3c
0j
jh
10d
d
9s
7s
ks
kc
qc
9d
d
5s
9c
7c
4s
10s
7d
d
7h
5c
3s
qh
2d
ad
d
d
d
r
d
3c
qs
2s
kd
2h
qc
d
ks
2d
5s
qd
kc
js

PS C:\Tools\Scripts\golfing>

so, If I'm understanding correctly, (d)ealing after the deck is out doesn't return any cards? That's valid, I'm just curious.

@tuskiomi Yep, that's right.

PHP, 411 bytes
This will generate a random outcome for each play (each deal(d)) and then once it's used all the cards, it will reshuffle the deck, clearing the play space.
To run, input comma separated commands: php card_dealer_golf.php d,d,d,d,r
$c=explode(",","a,2,3,4,5,6,7,8,9,10,j,q,k");$a=["h"=>$c,"d"=>$c,"s"=>$c,"c"=>$c,"0"=>["J","J"]];$cd=0;foreach(explode(",",$argv[1]) as $cmd){if($cd>=54){$cmd="r";}if($cmd=='d'){$cd+=6;for($i=0;$i<6;$i++){$s=array_keys($a)[rand(0,4)];$l=rand(1,count($a[$s])-1);if(isset($a[$s][$l])){echo$a[$s][$l].$s;unset($a[$s][$l]);}else{$i--;}}echo PHP_EOL;}else{$cd=0;$a=["h"=>$c,"d"=>$c,"s"=>$c,"c"=>$c,"0"=>["J","J"]];}}

Output:
$ php card_dealer_golf.php d,d,d,d,r
10djs5cjh2h3h
3cJ06d2d7d3s
9s6s7h4d6c4s
10c4c3d7c8h6h

Ungolfed version
$cards = explode(",","a,2,3,4,5,6,7,8,9,10,j,q,k");
$a = [
        "h" => $cards,
        "d" => $cards,
        "s" => $cards,
        "c" => $cards,
        "0" => ["J","J"]
    ];
$cd=0;
foreach(explode(",",$argv[1]) as $cmd) {
        if($cd>=54) {$cmd = "r";}
        if($cmd=='d'){
                $cd+=6; //+6 cards dealt
                for($i=0;$i<6;$i++){
                    $suit = array_keys($a)[rand(0,4)]; //get random suit
                    $l=rand(1,count($a[$suit])-1); //get random card from suit
                    if(isset($a[$suit][$l])){ //if the card is still in the deck
                        echo $a[$suit][$l].$suit; //output it
                        unset($a[$suit][$l]); //remove from deck
                    }else{
                        $i--; //card not in deck, decrease the cards dealt in this round to be regenered
                    }
                }
                echo PHP_EOL;
        }else{
                //reshuffle logic. reset deck and amount of cards dealth
                $cd=0;
                $a = [
                        "h" => $cards,
                        "d" => $cards,
                        "s" => $cards,
                        "c" => $cards,
                        "0" => ["J","J"]
                ];
        }
}


text:
Given a list of Tetris moves, return the number of completed lines
Description
We consider a slightly simplified version of Tetris where each move consists of:

rotating the piece clockwise, 0 to 3 times
positioning the piece at a given column
fast drop

The goal is to determine the number of completed lines, given a list of such Tetris moves.
Completed rows are removed as pieces are dropped, following standard Tetris rules.
Playfield
The playfield is 10-column wide. There's no Game Over and it is assumed that there's always enough space and time to perform the above actions, no matter the configuration of the playfield. The height of the playfield doesn't really matter here, but you can use the standard 22 rows as an upper limit.
Shapes of Tetrominoes

Input / Output
Input
A comma separated list of Tetris moves encoded with 3 characters. The first two character describe the Tetromino shape to use and the last one describes the position where it's dropped.

Tetromino: I, O, T, L, J, Z or S, in the same order as above.
Number of clockwise rotations: 0 to 3
Column: 0 to 9. This is the column in which the top-left corner of the piece (marked with an x on the above picture) is located after the rotation 1

It is assumed that all moves in the provided list are valid. There's no need to check for invalid entries such as I07 (horizontal I shape put too far on the right).
1 You are free to either implement a real rotation algorithm or to hardcode all the different shapes, as long as the x is located in the column given by the third character of the move.
Output
Number of completed lines.
Example

O00,T24 will generate the first position and O00,T24,S02,T01,L00,Z03,O07,L06,I05 will generate the second position.
Therefore, the following sequence will generate a Tetris and should return 4:
O00,T24,S02,T01,L00,Z03,O07,L06,I05,I19

Test cases
1) "O00,T24,S02,T01,L00,Z03,O07,L06,I05,I19" -> 4
2) "S00,J03,L27,Z16,Z18,I10,T22,I01,I05,O01,L27,O05,S13" -> 5
3) "I01,T30,J18,L15,J37,I01,S15,L07,O03,O03,L00,Z00,T38,T01,S06,L18,L14" -> 4
4) "S14,T00,I13,I06,I05,I19,L20,J26,O07,Z14,Z10,Z12,O01,L27,L04,I03,S07,I01,T25,J23,J27,O01,
    I10,I10" -> 8
5) "O00,T24,L32,T16,L04,Z11,O06,L03,I18,J30,L23,Z07,I19,T05,T18,L30,I01,I01,I05,T02" -> 8

Test page
You can use this JSFiddle to test a move list.

What axis are the pieces rotated about?

(Voting to close as unclear until the rotation gets clarified.) This is a nice challenge, but it could've used some time in the Sandbox.

@tuskiomi - It doesn't matter because the top left corner is the reference for the position of the piece. But I will try to update my question to illustrate this.

If you complete a line on top of an uncompleted line, do you delete that line immediately so that you can drop pieces into the uncompleted line?

@Neil - Yes. All completed lines are immediately removed.

@Arnauld I suggest you take a look at the super rotation system, and edit the image a teency bit. http://tetris.wikia.com/wiki/SRS

@tuskiomi - I'm a bit concerned about that. My fear is that going into rotation details will make the question appear more complicated than it actually is. The only rule is that the 3rd character in the move represents the column where the x goes. The implementation is left at the reader initiative. Please let me know if that makes sense.

So, we can treat these as 25 (15 if you don't count duplicates) different shapes, then?

@tuskiomi - Yes, exactly. The first two characters of the move essentially describe the shape to use, and the 3rd one the position where it's dropped.

what should we do in the case of an impossible piece?, eg: overlapping or off the edge?

Sounds like you're implementing a Keyblox macro evaluator.

Can you add some more test cases? 4 seems a little light. Also it would be good if you could clarify that lines must be removed in the question — until I saw your comment I'd assumed that was another element you'd removed to simplify it.

@Dave - I've added a JSFiddle to test the move lists. Hopefully that should also help clarify the puzzle.

Can solutions take input as an array rather than a comma-separated string?

@Jordan - Yes. An array of strings such as [ "O00", "T24", "S02", ... ] would be fine.

This is the best PCG question I've seen for a long time.  What a great idea!   Best in the subjective sense of interesting and practical and not too big yet not too small.

Just scrolled down memory lane. This is still my favorite challenge ever. Wish I could upvote again!

PHP, 405 399 378 372 368 360 354 347 331 330 328 319 309 300 bytes
(with Dave´s block mapping)
<?$f=[~0];L:for($y=0;$f[++$d+$y]|$s;$s>>=4)$y-=1022<$f[$d+$y]=$f[$d]|$s%16<<$x;$c-=$y;if(list($p,$r,$x)=$argv[++$z])for($s=I==$p?$r&1?4369:15:hexdec(decoct(O==$p?27:ord(base64_decode('M1ozWjqaF1kemR6ZPJMPyTnSJ0s')[ord($p)/4%5*4+$r])));;$d--)for($y=4;$y--;)if ($f[$d+$y]>>$x&$s>>$y*4&15)goto L;echo$c;

program, takes moves as separate arguments, prints result
breakdown to function:
takes moves as array, returns result
function t($a)
{
    $f=[~$z=0];             // init field $f (no need to init $z in golfed version)
    L:                      // jump label
                            // A: paint previous piece at line $d+1:
#   if($s)paint($f,$s,$d+1,$x);
    for($y=0;               // $y = working line offset and temporary score
        $f[++$d-$y]|$s;$s>>=4)// next field line; while field or piece have pixels ...
        $s>>=4)                 // next piece line
        $y+=1022<               // 3: decrease temp counter if updated line is full
            $f[$d-$y]=$f[$d]    // 2: use $y to copy over dropped lines
                |$s%16<<$x;     // 1: set pixels in working line
    $c+=$y;                         // add temp score to global score
#   paint($f);var_dump($c);
    if(list($p,$r,$x)=$a[$z++])// B: next piece: $p=name; $r=rotation, $x=column
#   {echo"$z:$p$r-$x
";
        for(                // C: create base 16 value:
            $s=I==$p
                ? $r&1?4369:15  // I shape (rotated:0x1111, not rotated:0xf)
                : hexdec(decoct(    // 5: convert from base 8 to base 16
                    O==$p ? 27  // O shape (rotation irrelevant: 033)
                    : ord(          // 4: cast char to byte
                                    // 0: 4 bytes for each remaining tetromino
                        base64_decode('M1ozWjqaF1kemR6ZPJMPyTnSJ0s')[
                            ord($p)/4%5 // 1: map STZJL to 01234
                            *4      // 2: tetromino offset
                            +$r]    // 3: rotation offset
            )));;$d--
        )
            for($y=4;$y--;) // D: loop $y through piece lines
                if ($f[$d+$y]>>$x & $s>>$y*4 & 15) // if collision ...
                    goto L;         // goto Label: paint piece, tetris, next piece
#   }
    return$c;               // return score
}

for reference: the old mapping
            hexdec(decoct(          // 3. map from base 8 to base 16
                                    // 0. dword values - from high to low: rotation 3,2,1,0
                [0x991e991e,0xc90f933c,0x4b27d239,0x1b1b1b1b,0,0x5a335a33,0x59179a3a]
                [ord($m[0])/2%9]    // 1. map ZJLO.ST to 0123.56 -> fetch wanted tetromino
                >>8*$m[1]&255       // 2. the $m[1]th byte -> rotated piece
            ))

testing
see my other PHP answer
want to watch?
remove the # from the function source and add this:
function paint($f,$s=0,$d=0,$x=0){echo'
';for($y=count($f)+5;$y--;$g=0)if(($t=(($z=$y-$d)==$z&3)*($s>>4*$z&15)<<$x)|$r=$f[$y]|0){$z=$t?" $r|$t=<b".(1022<($z=$t|$r)?' style=color:green':'').">$z":" $r";for($b=1;$b<513;$b*=2)$z=($t&$b?''.($r&$b?2:1).'':($r&$b?1:'.')).$z;printf("%02d $z\n",$y);}echo'
';}

some golfing steps
Rev. 5: A big leap (399-21=378) came by simply moving the column shift
from a separate loop to the two existing loops.
Rev. 8: Switching from array to base 16 for the piece ($s) did not give much,
but made way for some more golfing.
Rev. 17: crunched the values with base64_encode(pack('V*',<values>))
and used byte indexing instead of unpack to save 16 bytes
Rev. 25 to 29: inspired by Dave´s code: new hashing (-2), new loop design (-9), goto (-10)
no pre-shift though; that would cost 17 bytes.
more potential
With /2%9, I could save 15 bytes (only 14 bytes with /4%5)
by putting binary data into a file b and then indexing file(b)[0].
Do I want that?
UTF-8 characters would cost a lot for the transformation.
on the hashing
I used ZJLO.ST /2%9 -> 0123.56;
but T.ZJLOS /3%7 -> 0.23456 is as good.
one byte longer: O.STJLZ %13/2 -> 0.23456
and three more: OSTZJ.L %17%12%9 -> 01234.6
I could not find a short hash (max. 5 bytes) that leaves no gap;
but Dave found STZJL /4%5 -> 01234, dropping the O from the list. wtg!
btw: TIJSL.ZO (%12%8) -> 01234.67 leaves room for the I shape
(and a fictional A, M or Y shape). %28%8 and %84%8, do the same (but with E instead of A).

Nice; I like the combined painting+line detection, and the break 2 is much cleaner than what I had to do in C! You might be able to save some bytes by using array_diff (set completed lines to a fixed value instead of using unset then replace array_values with array_diff), but I can't tell from the docs if that would flatten repeated values (e.g. array_diff([1,2,2,3],[1]) -> [2,2,3] or just [2,3])

@Dave: array_diff does not remove duplicate values; and I already have the fixed value (1023); but it does not reindex the array. Great idea, but it would cost a byte.

wow that was a loud whoosh as you flew past me! Looks like I've got some catching up to do!

Congrats on reaching 300! I'll implement your latest suggested change (hadn't thought to simplify the rotation check now that I don't need /10 all over the place), but otherwise I think I'm done. I'm surprised at how directly competitive PHP and C turned out to be. This was fun — hope the OP accepts your answer!

@Dave & Titus - I wish I could accept both answers. You guys did a great job. Congrats anyway to Titus for reaching 300. And I think that's actually 299 since you have a useless space after a if.

@Arnauld - Good eye. You´re right, it´s actually 299 (and the -15 still in my hands). Wow I think this is my first accepted answer. Thanks! :) Not easy when questions are flooded with Lua, Haskell, Pyth and consorts.

C, 401 392 383 378 374 351 335 324 320 318 316 305 bytes
d[99]={'3Z3Z',983177049,513351321,1016270793,970073931,~0},*L=d+5,V,s;char c;main(x){B:for(c=0;c[++L]|V;V>>=4)c-=(L[c]=*L|(V&15)<<x)>1022;s-=c;if(scanf("%c%1d%d,",&c,&V,&x)>2)for(V=c^79?d[c/4%5]>>24-V*8:27,V=c^73?V/64%4<<8|V/8%8<<4|V%8:V&32?15:4369;;--L)for(c=4;c--;)if(L[c]>>x&V>>c*4&15)goto B;return s;}

Takes comma-separated input on stdin, returns the score in the exit status.
Requires char to be signed (which is the default for GCC) and requires '3Z3Z' to be interpreted as 861549402 (which is the case for GCC on little endian machines, at least).

Usage example:
echo "O00,T24,S02,T01,L00,Z03,O07,L06,I05,I19" | ./tetris; echo "$?";

High-level explanation:
All shapes except the line can fit in a 3x3 grid with one corner missing:
6 7 -
3 4 5
0 1 2

That means it's easy to store them in a byte each. For example:
- - -         0 0 -
- # -   -->   0 1 0   -->   0b00010111
# # #         1 1 1

(we align each piece to the bottom-left of the box to make dropping it easier)
Since we get at least 4 bytes to an int, this means we can store all 4 rotations of each piece in a single integer, with a special case for the line. We can also fit each row of the game grid into an int (only needs 10 bits), and the currently falling piece into a long (4 lines = 40 bits).

Breakdown:
d[99]={             // General memory
  '3Z3Z',           //  Shape of "S" piece (multi-char literal, value = 861549402)
  983177049,        //  Shape of "T" piece
  513351321,        //  Shape of "Z" piece
  1016270793,       //  Shape of "J" piece
  970073931,        //  Shape of "L" piece
  ~0                //  Bottom of game grid (solid row)
},                  //  Rest of array stores lines in the game
*L=d+5,             // Working line pointer (start >= base of grid)
V,                  // Current piece after expansion (also stores rotation)
s;                  // Current score (global to initialise as 0)
char c;             // Input shape identifier (also counts deleted lines)
main(x){            // "x" used to store x location
  B:                                // Loop label; jumps here when piece hits floor
  for(c=0;c[++L]|V;V>>=4)           // Paint latest piece & delete completed lines
    c-=(L[c]=*L|(V&15)<<x)>1022;
  s-=c;                             // Increment score
  if(scanf("%c%1d%d,",&c,&V,&x)>2)  // Load next command
    for(V=c^79?                     // Identify piece & rotation
          d[c/4%5]>>24-V*8          //  Not "O": load from data
        :27,                        //  Else "O": always 27
        V=c^73?                     // If not "I" (line):
          V/64%4<<8|V/8%8<<4|V%8    //  expand shape to 16-bits
        :                           // Else we are a line:
          V&32?                     //  "I" coincides with "J"; use this to check
               15:4369;             //  horizontal/vertical
        ;--L)                       // Loop from top-to-bottom of grid
      for(c=4;c--;)                 //  Loop through rows of piece
        if(L[c]>>x&V>>c*4&15)       //   If collides with existing piece:
          goto B;                   //    Exit loops
  return s;                         // Return score in exit status
}

-4, -1 thanks to @Titus, and -23, -11 with inspiration from their answer

Nice one! Could you just do s+=(d[A-x]=d[A]) without using x?

Unfortunately x is needed to keep track of how many rows to collapse in the current step (each row A is set to the value of row A-x as the loop progresses)

D'oh! My bad. Sorry for such a silly suggestion. :)

The possibilities of C still surprise me somtimes

The %12 idea is brilliant. But I lost some ... what does 1[*v] do?

@Titus it's an abuse of C's array indexing. Put simply, 1[a] and a[1] do the same thing (or more precisely, a[b] translates to *(a+b)). It's abused like this as a way of avoiding brackets. In this case, 1[*v] == (*v)[1], i.e. the second letter of the command, i.e. the rotation.

So if that line was partially de-obfuscated, it would read: A=d[(command[0]+1)%12]>>((51-command[1])*8);

Can you get rid of the I placeholder? If so, try /2%9 as hash instead of %12. %12%8 if not.

Nice hashing. I love the x[++L]|W part. Adopted both from you. I wonder if I can squeeze another 3 bytes out of mine without using the external file.

"whoosh" again :D Can you find another 7 or 8 bytes somewhere?

Can you gain anything from masking default V with 255 and then using  65609 for rotated I before base conversion? I guess not, but I like the idea. 2) Is there a reason why you use long V? int would save a byte, char V would render %4 obsolete.

... and you could put that declaration to the head ... so, if char is applicable, it would save 5 bytes.

@Titus Heh, it was only a matter of time! I'm not sure I can get another 7 bytes out but I'll give it a shot. As for your comment, I don't need V to be long, but I do need W to be long (uses 40 bits). Combining both assignments inside the loop saves the need to declare and assign each, saving some bytes.

@Titus I was intrigued by your comment "no pre-shift though; that would cost 17 bytes" and wondered if I could save anything by using your shift-while-painting idea. In the end it freed up 11 bytes! (both directly and because it let me re-order things to finally get rid of the last {})

Very nice again! still, PHP´s built-ins help me stay ahead of you in spite of all the $s I need. Only wish I had been faster with some more algorithm ideas. Good coop, anyway.

I see two more bytes in your value construction. Try
V=c^73?V^79?(V=<byte>)/64%4<<8...:51:x&1?4369:15

298 bytes

Ruby, 474 443 428 379 + 48 = 427 bytes
-1 thanks to @Titus
This can definitely be golfed more.
Reads a binary dictionary of pieces (see below) from STDIN or a filename and takes a move list as an argument, e.g. $ cat pieces | ruby script.rb O00,T24,S02,....
q=$*.pop
z=$<.read.unpack('S*')
b=c=g=i=0
x=10
u=1023
r=->n{n&2**x-1>0?n:r[n>>x]}
y=->n{n>0?[n&u]+y[n>>x]:[]}
l=->c,n{z.find{|m|m>>x==c<<2|n.to_i}||l[c,n-2]}
q.scan(/(\w)(\d)(\d)/){n=l["IOTLJSZ".index($1),$2.to_i]
v=(n&1|(n&6)<<9|(n&56)<<17|(n&960)<<24)<<$3.to_i
(y[b].size+1).times{t=b<<40
t&v>0&&break
g=t|v
v<<=x}
b=0
a=y[r[g]]
a.grep_v(u){|o|b|=o<<x*i
i+=1}
c+=a.count u}
p c

Binary piece data (xxd format)
0000000: c003 4b04 d810 d814 b820 9c24 d029 5a2c  ..K...... .$.)Z,
0000010: 7830 9634 e039 ca3c 3841 d444 c849 4e4c  x0.4.9.<8A.D.INL
0000020: 9861 9869 5c64 5c6c f050 f058 9a54 9a5c  .a.i\d\l.P.X.T.\

See it on repl.it (with hard-coded arguments, dictionary): https://repl.it/Cqft/2
Ungolfed & explanation
# Move list from ARGV
q = $*.pop

# Read piece dictionary; pieces are 16-bit integers: 3 for letter,
# 2 for rotation, 10 for shape (and 1 wasted)
z = $<.read.unpack('S*')

# Empty board and various counters
b = c = g = i = 0
x = 10 # Magic numbers
u = 1023

# A function to remove empty lines
r = ->n{ n & 2**x - 1 > 0 ? n : r[n >> x] }

# A function to split the board into lines
y = ->n{ n > 0 ? [n & u] + y[n >> x] : [] }

# A function to lookup a piece by letter and rotation index
l = ->c,n{ z.find {|m| m >> x == c << 2 | n.to_i } || l[c, n-2] }

# Read the move list
q.scan(/(\w)(\d)(\d)/) {
  # Look up the piece
  n = l["IOTLJSZ".index($1), $2.to_i]

  # Convert the 10-bit piece to a 40-bit piece (4 rows of 10 columns)
  v = (n & 1 |
        (n & 6) << 9 |
        (n & 56) << 17 |
        (n & 960) << 24
      ) << $3.to_i # Shift by the appropriate number of columns

  # Drop the piece onto the board
  (y[b].size + 1).times {
    t = b << 40
    t & v > 0 && break
    g = t | v
    v <<= x
  }

  # Clear completed rows
  b = 0
  a = y[r[g]]
  a.grep_v(u) {|o|
    b |= o << x * i
    i += 1
  }

  c += a.count u # Count cleared rows
}
p c

1 byte: m >> 10 could be m >> x

@Titus Good eye. Thanks!

No need to explicitly require \ds in the regular expression: /(\w)(\d)(\d)/ → /(\w)(.)(.)/

PHP, 454 435 427 420 414 bytes
bit fields for pieces and map; but no special case for the I shape as Dave´s golfing.
<?$t=[I=>[15,4369],O=>[51],T=>[114,562,39,305],L=>[113,802,71,275],J=>[116,547,23,785],Z=>[54,561],S=>[99,306]];foreach($argv as$z=>$m)if($z){$s=$t[$m[0]][$m[1]%count($t[$m[0]])];for($d=$i=0;$i<4;$i++)for($k=0;$k<4;$k++)if($s>>4*$k&1<<$i){for($y=0;$y++<count($f);)if($f[$y-1]&1<<$m[2]+$i)$d=max($d,$y-$k);$k=3;}for($k=$d;$s;$k++,$s>>=4)if(1022<$f[$k]|=$s%16<<$m[2]){$c++;unset($f[$k]);}$f=array_values($f);}echo$c;

takes arguments from command line, prints result
ungolfed as function
takes arguments as array, returns result
function t($a)
{
    // bitwise description of the stones and rotations
    $t=[I=>[15,4369],O=>[51],T=>[114,562,39,305],L=>[113,802,71,275],J=>[116,547,23,785],Z=>[54,561],S=>[99,306]];
    foreach($a as$m)
    {
        $s=$t[$m[0]][$m[1]%count($t[$m[0]])];   // $s=stone
        // find dropping space
        for($d=$i=0;$i<4;$i++)
            // a) lowest pixel of stone in column i
            for($k=0;$k<4;$k++)
                if($s>>4*$k&1<<$i)
                {
                    // b) top pixel of field in column x+i
                    for($y=0;$y++<count($f);)
                        if($f[$y-1]&1<<$m[2]+$i)$d=max($d,$y-$k);
                    $k=3; // one byte shorter than `break;`
                }
        // do drop
        for($k=$d;$s;$k++,$s>>=4)
            if(1022<$f[$k]|=$s%16<<$m[2])   // add block pixels to line pixels ... if full,
            {$c++;unset($f[$k]);}           // tetris
        $f=array_values($f);
    }
    return$c;
}

tests (on function)
$data=[
    "O00,T24,S02,T01,L00,Z03,O07,L06,I05,I19"=>4,
    "S00,J03,L27,Z16,Z18,I10,T22,I01,I05,O01,L27,O05,S13" => 5,
    "I01,T30,J18,L15,J37,I01,S15,L07,O03,O03,L00,Z00,T38,T01,S06,L18,L14" => 4,
    "S14,T00,I13,I06,I05,I19,L20,J26,O07,Z14,Z10,Z12,O01,L27,L04,I03,S07,I01,T25,J23,J27,O01,I10,I10" => 8,
    // additional example for the two last tetrominoes:
    'O00,T24,L32,T16,L04,Z11,O06,L03,I18,J30,L23,Z07,I19,T05,T18,L30,I01,I01,I05,T02' => 8,
];
function out($a){if(is_object($a)){foreach($a as$v)$r[]=$v;return'{'.implode(',',$r).'}';}if(!is_array($a))return$a;$r=[];foreach($a as$v)$r[]=out($v);return'['.join(',',$r).']';}
function cmp($a,$b){if(is_numeric($a)&&is_numeric($b))return 1e-2<abs($a-$b);if(is_array($a)&&is_array($b)&&count($a)==count($b)){foreach($a as $v){$w = array_shift($b);if(cmp($v,$w))return true;}return false;}return strcmp($a,$b);}
function test($x,$e,$y){static $h='

input	output	expected	ok?
';echo"$h
",out($x),'	',out($y),'	',out($e),'	',cmp($e,$y)?'N':'Y',"
";$h='';}
foreach($data as $v=>$e)
{
    $x=explode(',',$v);
    test($x,$e,t($x));
}

427? You're on!

@Jordan: and those 427 include the <? overhead :)


text:
Extendable Train Swapping Problem
Extended Train Swapping Problem
Part 1: Normal Train Swapping Problem
In the 1996 CCC (Canadian Computing Competition), the first Stage 2 problem was a Train Swapping Problem. You can visit the link here. Essentially, you have a bunch of numbered trains, and you want to find out how many train swaps you need to get them in order, and each train swap operation allows you to swap two adjacent trains. Since train carriages can run either way, nobody cares about the fact that the train carriages face the other way when swapped. This is pretty easy; all you need to do is:

 Find the number of steps to bubble-sort it; it's the most efficient sorting algorithm when you can only make adjacent element swaps

So, I made a harder one.
Part 2: How this challenge works
Essentially, you can now swap more than just adjacent trains. With a longer rotating platform, you can swap the position of multiple trains. For example, with a rotating platform of length 4, you can swap both the inner and outer pairs at the same time, so 1 2 3 4 becomes 4 3 2 1. Here are some examples for different rotating platform sizes:
Length 2:
1 2 3 4 5
  ---
1 3 2 4 5

Length 3:
1 2 3 4 5
  -----
1 4 3 2 5

Length 4:
1 2 3 4 5
-------
4 3 2 1 5

Essentially, you're just inverting a sublist of the entire train. To clarify, in each move, you can only swap exactly N trains.
Part 3: Specifications
Input
Your input must take in two things: the length of the rotating platform, and the order of the train carriages. You may also require the number of train carriages if you wish. The order of the train carriages is given by an ordered list of numbers (each number representing a train carriage), so you can read the input as space-separated integers, newline-separated integers, an array, etc.
Output
You must output the optimal (minimum) number of swaps needed to get the carriages all into the order 1 2 3 ... N. If there is no solution, output -1, No solution, or some other consistent message. You may not output to stderr.
Scoring
This is a code-golf challenge, so scoring is in bytes. The solution with the lowest number of bytes as of September 1st, 2016 will be the accepted one.
Examples
Problem 1
Input
4
2
1 3 2 4

Output
1

Explanation
This is pretty trivial; with a rotating platform of length 2, it's the same as the normal train swapping problem. Swap the 2 and the 3.
Problem 2
Input
4
3
1 3 2 4

Output
No solution (or an equivalent consistent message).

Problem 3
Input
9
3
1 4 5 6 3 8 7 2 9

Output
4

Explanation
1 4 5 6 3 8 7 2 9
          -----
1 4 5 6 3 2 7 8 9
      -----
1 4 5 2 3 6 7 8 9
    -----
1 4 3 2 5 6 7 8 9
  -----
1 2 3 4 5 6 7 8 9

Standard loopholes apply
Good luck!
EDIT 1: Made the input format more flexible. Thanks to @Mego!
EDIT 2: Clarified that a rotating platform of length 4 swaps both the inner and outer pairs. Thanks to @TimmyD!
EDIT 3: Clarified that you must make permutations of length N exactly, not at most. Thanks to @Zgarb!

Having such a strict input format is not a good idea. Any input format, so long as only the list of train carriages (and optionally the length of this list) and the length of the platform is transmitted, should be acceptable.

@Mego Okay, I will make the change.

@TimmyD Yes. I will clarify this in the challenge.

Does a length-N platform flip exactly N trains, or at most N trains?

@Zgarb Oh. I forgot to consider that. It's exactly N trains. I will clarify this in the challenge.

A question can only have 5 tags. I removed [tag:array-manipulation] because it's so generic as to be virtually useless, and I think the question is better served by the more specific tags I added.

I swear a variant of this was a GCJ problem once. But it had arbirtarily sized platforms, I think.

Related: https://en.wikipedia.org/wiki/Pancake_sorting.

Is terminating and printing nothing acceptable for the "no solution" case ?

@TonHospel Sorry for the late reply, yes it is acceptable, as long as there is no sort of error message.

Perl, 120 bytes
Includes +6 for -Xapi (- and space are counted too because both the -i and the $' in the code make it impossible to combine the options with -e)
Run with the input on STDIN and the platform length after the -i option, e.g.
perl -Xapi3 trains.pl <<< "1 4 5 6 3 8 7 2 9"

Prints -2 if there is no solution
trains.pl:
1until$_=$n++*$z{pack"W*",@F}||-!grep!$z{$_}++&&/.{$^I}(??{!\$z{$`.reverse($&).$'}})$/s,keys%z,pack"W*",1..@F;$_--

if N <= 9 then you can gain 5 more bytes:
1until$_=$n++*$z{join"",@F}||-!grep!$z{$_}++&&/.{$^I}(??{!\$z{$`.reverse($&).$'}})$/,keys%z,join"",1..@F;$_--

Good job; as far as I've tested, this works! +1 & accept


text:
Find the Frobenius!
Intro:
A Frobenius number is a number which cannot be made from numbers in a set.
For example, 43 is the Frobenius number of the set {6, 9, 20}, because you cannot get 43 from those numbers, and it is the largest number which cannot be made.
42 is not a Frobenius number of the set {6, 9, 20}, because it can be made from 4 6's and 2 9's (4*6 + 2*9 = 42).
Task and Specs:
Your task is, when given a list of numbers as input, find the Frobenius number.
You are guaranteed that there will always be at least two numbers in the input (if there's only 1 number in the input, the result will be infinite).
You are also guaranteed that all numbers are positive.
You only need to calculate up to and including 2^32 - 1.
Examples:

6, 9, 20 = 43
4, 7 = 17
10, 12 = Infinity or whatever value cannot be made last

You are NOT allowed to use built-ins (I'm looking at you, Mathematica).

Mathematica, 15 bytes, ... Oh, uh, nevermind.

I think this is a dupe of this challenge, which was also done in the SO days.


text:
The IHIH Pyramid
I find it fascinating how the letters "H" and "I" are very similar. "H" is a horizontal stroke surrounded by two vertical strokes; "I" is a vertical stroke surrounded by two horizontal strokes (depending on your font). I bet this could be nested... You know what that reminds me of? Fractals!!!
Let's define the "IHIH" pyramid as follows: The first iteration is this ASCII representation of the letter "I":
---
 |
---

The next iteration has a vertical stroke on either side.
|   |
|---|
| | |
|---|
|   |

If you view the "I" in the middle as a single horizontal stroke, then this second iteration is basically an "H". The third iteration adds a horizontal stroke on the top and bottom
-------
 |   |
 |---|
 | | |
 |---|
 |   |
-------

Again, if you view the "H" in the middle as a single vertical stroke, then this iteration is basically an "I". This pattern continues, alternating between "H"s and "I"s on every iteration. For reference, here are the first 6 iterations:
1:
---
 |
---

2:
|   |
|---|
| | |
|---|
|   |

3:
-------
 |   |
 |---|
 | | |
 |---|
 |   |
-------

4:
|       |
|-------|
| |   | |
| |---| |
| | | | |
| |---| |
| |   | |
|-------|
|       |

5:
-----------
 |       |
 |-------|
 | |   | |
 | |---| |
 | | | | |
 | |---| |
 | |   | |
 |-------|
 |       |
-----------

6:
|           |
|-----------|
| |       | |
| |-------| |
| | |   | | |
| | |---| | |
| | | | | | |
| | |---| | |
| | |   | | |
| |-------| |
| |       | |
|-----------|
|           |

The Challenge:
Write a program or function that outputs the N'th iteration of the IHIH pyramid, and an optional trailing newline. Your input will be a single positive integer in whatever reasonable format you want. You do not have to handle invalid inputs, e.g. non-integers, numbers smaller than 1, etc. Your program must at the very least produce the right output for inputs up to 20. Since this is code-golf, standard loopholes are not allowed and the shortest answer in bytes wins!

Is it acceptable if I return an arrow of strings one fror each row?

Didn't quite meeting the challenge criteria, but did something cool by accident... Try it online!

Pyth, 50 40 31 25 bytes

j@s.u,J+*\-K+2lheN+jR*2;eN*\-KjR"||"+*dK+J*dKQ]]\|
LXR"|-")CbjyW%Q2uy+K*\-+2lhG+jR*2;GKQ]\|
juCGQuC+K*@"-|"H+3yH+jR*2;GKQ\|
j@CBujR*@"-|"H2CjR*2;GQ\|

Test suite.
Explanation
This is a recursive algorithm.
In each iteration, we perform three actions:

prepend and append a space to each line
transpose the array
prepend and append to each line either "-" or "|" depending on the number of iteration.

After the iterations, the odd-numbered outputs will be transposed. Therefore, we transpose them.
j@CBujR*@"-|"H2CjR*2;GQ\|   input: Q
j@CBujR*@"-|"H2CjR*2;GQ\|Q  implicit filling of arguments

    u                 Q\|   for Q times, starting with "|", G as current output,
                            H as number of iterations:

                jR*2;G          prepend and append a space to each line
                                (using each line as separator, join [" "," "])
               C                transpose
     jR*      2                 prepend and append the following to each line:
        @"-|"H                      the H-th element of the string "-|" (modular indexing)

 @CB                     Q  select the Q-th element from [output,
                            transposed output] (modular indexing)
j                           join by newlines

I love the transponation idea.

Python, 165 145 133 123 bytes
A recursive solution:
def i(e):
 d="|";a=e*2;x=d+" "*(a-1)+d
 if e<1:return d
 if e%2:d,x=[" ","-"*(a+1)]
 return[x]+[d+z+d for z in i(e-1)]+[x]

Called with print ("\n".join(i(int(sys.argv[1])))), where the parameter is the iteration number of the IHIH pyramid.
Thanks to @DJMcMayhem for saving 20 bytes. Taking the idea behind those suggestions further saved another 12 bytes. Thanks to @Maltysen for suggestions that trimmed some more bytes.
The function sets the delimiter d to "|" and the intervening spaces to " " (for odd-numbered iterations), deals with returning in the degenerate case, then resets the delimiter to " " and the intervening spaces to "-" for even-numbered iterations. The function returns a list of strings for each line of the IHIH, having embedded the result of a recursive call to the function in the right place within the list.

Nice answer, and welcome to the site! You do not need to join the lines, a list of strings is fine. A couple tips: change lines 2 and 3 to if e<1:return'|' (no newline between them) then remove the "else" and remove the extra indentation.

you can take out the space after return. Also, you can merge the lines without ifs with semicolons, and save on the indentation

I've edited your answer. Please feel free to revert my edits if you don't like them.

Cheddar, 186 177 165 154 148 131 bytes
(n,b?,c?,q?,g=s->(n-=1)<0?s:g((q=(c=s.lines[0].len)%4>2?b='|'+" "*c+"|":b='-'*(c+2))+"\n"+s.sub(/^|$/gm,q?'|':' ')+"\n"+b))->g("|")

Uses recursion. Will add explanation once done golfing.
Try it online!
Explanation
This one is a bit complex too keep track off all the variables I'm using but I'll try to keep it simple:
(
 n,    // Input
 b?,   // Stores row to add to top/bottom
 c?,   // Width of string
 q?,   // false if I-ifying. true if not
 g=
   s->          // Main logic, s is generated string
    (n-=1)<0 ? s :   // Decrease input each iteration. Stop when 0
    g(               // Recurse with....
      (
        q= (         // Set `q` true if h-ifying. false if I-ifying
         c=s.lines[0].len    // Set `c` to width of string
        ) % 4>2 ?
        b='|'+" "*c+"|" :    // Set `b` to top/bottom row adding
        b='-'*(c+2)          // `*` is repeat, c is from before
      ) + "\n" +
        s.sub(/^|$/gm,       // Add the following to beginning/end of each line
          q?'|':' '          // if H-ifying, add `|`s if I-ifying add spaces
        ) + "\n" + b         // Add bottom row, generated from before
    )
) -> g("|")     // Middle item is `|`

This was a pain to golf but its 55 bytes shorter than original.

Python 2, 93 bytes
Leaky Nun saved 7 bytes.
r=range(input()+1)
r=r[:0:-1]+r
for y in r:print''.join('| -'[[x%2,y%2+1][x&-2<y]]for x in r)

Closed form :o :o

Ahh, of course: at first I needed int(x/2.) because I was taking range(-n,n+1) but now I can just use those. Thank you!

I specified Python 2 in the header because simply saying "Python" usually means the code works under either Python 2 or Python 3, which is not the case here.

Matricks, 80 62 bytes
An iterative solution (Recursion in Matricks is hard...)
Run with python matricks.py ihih.txt [[]] <input> --asciiprint

k124;FiQ%2:v;b[m124:Q*2+3:1;];a{z:Q*2+1;};:b;v[m45:1:Q*2+3;];u{zQ*2+1:;};;:1:n;;
k124;FiQ%2:v;b[m124:Q*2+3:2;];B1;:b;v[m45:2:Q*2+3;];V1;;:1:n;;

Explanation:
k124;                 # Set the matrix to '|'
F...:1:n;;            # Repeat input times, (Q is iteration variable)
  iQ%2:...:...;       # if statement, check if Q is odd or even
                      # Q is even,
    b;                # Make space to the left
    v[m45:2:Q*2+3;];  # Set the top 2 rows to '-'s
    V1;               # Rotate the matrix up 1 unit, moving the topmost row to the bottom
                      # Q is odd,
    v;                # Make space above
    b[m124:Q*2+3:2;]; # Set the 2 left columns to '|'s
    B1;               # Rotate the matrix left 1 unit, moving the leftmost row to the right

Wow, iterative! I'm impressed.

@ConorO'Brien Matricks was built for dynamic matrix resizing, so it's not THAT impressive, but thanks anyway!

JavaScript (ES6), 92 90 bytes

f=
(n,[h,c,v]=n&1?`-- `:` ||`)=>n?(c+=h.repeat(n+n-1)+c)+`
${f(n-1).replace(/^|$/gm,v)}
`+c:v
;
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>

Recursive solution works by taking the previous iteration, adding the v character to the sides, then adding the c character to the corners and the h character along the top and bottom. The set of characters simply alternates each iteration. Edit: Saved 2 bytes by returning v when n=0.

Dyalog APL, 52 43 bytes
{v=⊃⍵:h⍪⍨h⍪s,⍵,s⋄v,⍨v,s⍪⍵⍪s}⍣⎕⍪⊃v h s←'|- '

v h s←'|- ' assigns the three characters to three names (vertical, horizontal, space)
⊃ the first one, i.e. |
⍪ make into 1×1 table
{...}⍣⎕ get input and apply the braced function that many times
 v=⊃⍵: if the top-left character of the argument is a vertical, then:
  h⍪⍨ horizontals below
  h⍪ horizontals above
  s, spaces to the left of
  ⍵,s the argument with spaces to the right
 ⋄ else:
  v,⍨ verticals to the right of
  v, verticals to the left of
  s⍪ spaces above
  ⍵⍪s the argument with spaces below
TryAPL online!

Brachylog, 84 bytes
,[[["|"]]:?:1]i:1:zi:ca~@nw
hh~m["-|":B]:ramggL," "ggS,?:Sz:ca:Srz:caz:Lz:ca:Lrz:ca.

Try it online!
A port of my answer in Pyth.

C, 110 bytes
#define R(A,B,C)for(A=n,B=1;A<=n;putchar(C),A-=B|=-!A)
f(n,y,x,w,v){R(y,w,10)R(x,v,"| -"[x/2*2<y?y%2+1:x%2]);}

Invoke as f(n). For 111 bytes, I could do:
f(n,y,x,w,v){for(y=n,w=1;y<=n;y-=w|=-!y,puts(""))for(x=n,v=1;x<=n;x-=v|=-!x)putchar("| -"[x/2*2<y?y%2+1:x%2]);}

i.e., the #define saves exactly one byte.

APL (Dyalog Classic), 34 bytes
'- |'[2+∘.(≤-(1+=)×2|⌈)⍨(⌽,0,⊢)⍳⎕]

Try it online!
(uses ⎕io←1)
⍳⎕ is 1 2 ... N
(⌽,0,⊢) is a train that turns it into -N ... -1 0 1 ... N
∘.( )⍨ executes the parentheses for every pair of coordinates ⍺ ⍵
the train (≤-(1+=)×2|⌈) or its dfn equivalent {(⍺≤⍵)-(1+⍺=⍵)×2|⍺⌈⍵} produces a matrix like:
 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1
  0  1  0  0  0  0  0  0  0  1  0
  0  1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1  1  0
  0  1  0  1  0  0  0  1  0  1  0
  0  1  0  1 ¯1 ¯1 ¯1  1  0  1  0
  0  1  0  1  0  1  0  1  0  1  0
  0  1  0  1 ¯1 ¯1 ¯1  1  0  1  0
  0  1  0  1  0  0  0  1  0  1  0
  0  1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1  1  0
  0  1  0  0  0  0  0  0  0  1  0
 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1 ¯1

'- |'[2+   ] makes these valid indices in ⎕IO=1 and picks the corresponding characters

A rare occurrence where a full program and dfn have the same bytecount.

Dyalog APL, 34 bytes
{⍉⍣⍵{b,b,⍨⍉s,⍵,⊃s b←' -|'~⊃⍵}⍣⍵⍪'|'}

{...}⍣⍵⍪'|' Apply function in braces ⍵ times starting with 1x1 matrix of character |. The result of each application is the argument for the next application.
s b←' -|'~⊃⍵ s is space and b is the bar not in the top left corner of the argument (' -|'~'-' removes horizontal bar and leaves space and vertical bar)
s,⍵,⊃s b add space to left and right (⊃ picks s from vector s b)
b,b,⍨⍉ transpose and add b to left and right
For odd numbers this leaves the result transposed, so a final transpose is required.
⍉⍣⍵ Transpose ⍵ times (once would be enough, but shorter to code this way)
TryAPL online

Welcome to PPCG!

Thanks! Trying to join the party now, lots of fun solving these :)

Cheddar, 107 bytes
(n,g=n->n?(f->f(f(g(n-1)," ").turn(1),n%2?"-":"|"))((a,b)->a.map(i->b+i+b)):["|"])->(n%2?g(n).turn(1):g(n))

Try it online!

Cheddar, 85 bytes
(n,r=(-n|>n).map(v->abs v))->r.map(y->r.map(x->"| -"[(x&-2)<y?y%2+1:x%2]).fuse).vfuse

My first Cheddar answer. Try it online!
If I try to write r=(-n|>n).map(v->abs v).map, and then r(y->r(x->…)), the interpreter crashes. ;-;

You can make v->abs v into (abs) (e.g. r.map((abs))) which will return a function which has the behavior of the abs function. e.g. (+)(1,2) -> 3. (^)(2,6) -> 64. Also big wow on outgolfing me by almost 50%

No, I tried that: Runtime Error: `abs` has no behavior for types `Number` and `Number`  (because map receives both the element and its index, presumably.)

ah :/ i was just about to fix that bug today >_>

MATLAB, 168 163 bytes
This is probably not the cleverest way to do it: Expanding a string on all sides in n steps:
function s=g(n);s='|';for m=1:n;if mod(m,2);a=45;b=a;c=0;else a='|';b=0;c=a;end;s=[a repmat(b,1,2*m-1);repmat(c,2*m-1,1) s];s(:,end+1)=s(:,1);s(end+1,:)=s(1,:);end

Usage: Save as g.m (do I have to add that to the byte count?) and call e.g. g(15).
Ungolfed:
function s=g(n)

% // Initialize s
s = '|';

for m=1:n
   % // Decide if odd or even number and which symbol to add where
   if mod(m,2)
      a=45;b=a;c=0; % // char(45) is '-' and char(0) is ' ' (thx to Luis Mendo)
   else
      a='|';b=0;c=a;
   end
      % // Add symbols at top and left to s
      s = [a repmat(b,1,2*m-1);repmat(c,2*m-1,1) s];
      % // Add symbols at right and bottom to s
      s(:,end+1) = s(:,1);
      s(end+1,:) = s(1,:);
end

You can replace ' ' by 0 (Matlab treats char 0 as a space) and '-'  by 45. File name doesn't have to be included in byte count

Ruby, 81 78 77 bytes
This is based on Lynn's Python answer. Golfing suggestions welcome.
Edit: 3 bytes thanks to Lynn. Corrections and golfing 1 byte thanks to Jordan.
->n{r=(-n..n).map &:abs;r.map{|y|puts r.map{|x|"| -"[x&-2<y ?y%2+1:x%2]}*""}}

Ungolfing:
def f(n)
  r = -n..n            # Range from -n to n (inclusive)
  r = r.map{|i|i.abs}  # Turns every element of r positive
  r.each do |y|
    s = ""             # a line of the fractal
    r.each do |x|      # build up the fractal based on x and y
      if x/2*2 < y
        s += " -"[y%2]
      else
        s += "| "[x%2]
      end
    end
    puts s             # print the line
  end
end

Can you .map(&:abs)?

@Lynn Well spotted. Any other suggestions?

The first * isn't doing anything. You can use *"" instead of .join. Also, using p surrounds each line with quotation marks (it calls inspect on its arguments), which might disqualify you.

Also, you can remove the parentheses around &:abs (map &:abs). You might be able to do something with Array#product instead of nested maps, but it'll make line breaks tricky.

@Jordan Your first four hints work, but r.product(r).map (however that works) is longer and does not appear to allow line breaks very easily.

Actually, 48 45 44 bytes
This is an attempt to port my Ruby answer to Actually. This is way too long and golfing suggestions are very much appreciated. Try it online!
u;±ux♂A╗╜`╝╜";2@%2╛%u╛(2±&<I'-' '|++E"£MΣ.`M

Here is a 46-byte version which separates out the nested functions so that we can define "| -" in fewer bytes. Try it online!
u;±ux♂A╗╜`;2@%2╛%u╛(2±&<I"| -"E`#"╝╜%r£MΣ."%£M

Ungolfing:
First algorithm
u         Increment implicit input.
;±u       Duplicate, negate, increment. Stack: [-n n+1]
x♂A       Range [-n, n+1). Abs(x) over the range.
╗         Save list to register 0. Let's call it res.
╜         Push res so we can iterate over it.
  `         Start function (with y from map() at the end)
  ╝         Save y to register 1.
  ╜         Push res so we can iterate over it.
    "         Start function as string (with x from map() at the end)
    ;         Duplicate x.
    2@%       x mod 2.
    2╛%u      y mod 2 + 1.
    ╛(2±&<I   If x&-2 < y, then y%2+1, else x%2.
    '-' '|++  Push "| -" (We're inside a string right now,
                          so we need to push each char individually)
    E         Grab index of "| -"
    "£        End string and turn into function.
  M         Map over res.
  Σ.        sum() (into a string) and print.
  `         End function.
M         Map over res.

Second algorithm
u;±ux♂A╗╜                  Create res as before.
`;2@%2╛%u╛(2±&<I"| -"E`#   The inner function from the first algorithm put into a list.
                             The only change to the function is the definition of "| -".
"╝╜  £MΣ."                 Most of the outer function from the first algorithm as a string.
   %r      %               %-formats the list into the outer function.
            £M             Turns the string into a function, maps over res.

u;±ux♂A╗╜\;2@%2╛%u╛(2±&<I"| -"E`#"╝╜%r£Mεj."%£M` is longer than what you currently have (by 2 bytes), but you might find some inspiration for ways to make it shorter that I'm not seeing.

Canvas, 19 18 17 14 bytes
|╶［ ｅ↷ｌ|＊ｅ｝╶［↷

Try it here!
If I were allowed to output every other output rotated 90°, the last 4 characters could be removed.
Explanation (some characters have been changed to look ~monospace):
|               push "|" - the canvas
 ╶[       }     repeat input times
    e             encase the canvas in spaces horizontally
     ↷            rotate the canvas 90°
      l|*         push "-" repeated the canvas height times vertically
         e        and encase the canvas if two of those horizontally
           ╶[   repeat input times
             ↷    rotate the canvas 90°

I'd lose 6 bytes if they loosened that restriction too :P.

@MagicOctopusUrn wellp, make that -5 bytes for me :p (could your answer benefit from a transpose loop as well?)

my implementation is a transpose loop :D.

05AB1E, 29 28 bytes
„|-S¹>∍ƶćsvy‚˜.Bζ}¹Fζ}»R.∞.∊

Try it online!
-1 thanks to Dzaima...
This is an iterative solution.

Essentially This is made by creating the following pattern:
['|','--','|||',...]

Then, pairwise, transposing each element together and adding the padding.
By transposing after each iteration, we end up creating a single corner of the pattern.
Then, we can use 05AB1E's reflection commands.

„|-S                         # Push ['|','-']
    ¹>∍                      # Extended to input length.
       ƶ                     # Each element multiplied by its index.
        ćs                   # Extract head of list, swap remainder to top.
          v      }           # For each element in the '|-' list...
           y‚˜               # Wrap current 2D array with new entry, flatten.
              .Bζ            # Pad and transpose, leaving it transposed for the next addition.
                 }           # End loop.
                  ¹Fζ}       # Transpose N times.
                      »R     # Bring it all together into a newline string, reverse.
                        .∞.∊ # Mirror horizontally, then vertically with overlap.

Stax, 22 bytes
âeò↕\┐▄┤╚╬8φ8Δ☺Pä≤δ₧ßƒ

Run and debug it
Unpacked, ungolfed, and commented, it looks like this.
'|          string literal "|"
{           begin block to repeat
  . |G      push " |", then jump to trailing `}` below
  '-z2lG    push ["-",[]], then jump to trailing `}` below again
}N          repeat block according to number specified in input
m           output each row in grid

}           goto target - `G` from above jumps to here
  i@        modularly index into pair using iteration index
  ~         push to input stack
  {;|Sm     surround each row with the extracted element
  M         transpose grid

Run this one

Mathematica, 158 164 bytes
f[n_]:=Print/@StringJoin/@Map[{{{"|","|", },{ , , }},{{"|", ,"-"},{ ,"-","-"}}}[[##]]&@@#&,Table[{1+i~Mod~2, 1+j~Mod~2, 2+Sign[Abs[i]-Abs[j]]}, {i,-n,n}, {j,-n,n}],{2}]

Mathematically calculates the correct symbol at the coordinates (i,j), where both run from -n to n. Human formatted:
f[n_]:=Print/@
 StringJoin/@
  Map[
   {{{"|","|", },{ , , }},{{"|", ,"-"},{ ,"-","-"}}[[##]]&@@#&,
   Table[{1+i~Mod~2,1+j~Mod~2,2+Sign[Abs[i]-Abs[j]]},{i,-n,n},{j,-n,n}],
   {2}]

PHP, 166 bytes
golfed more than 100 bytes off my first approach
and it´s still the longest answer here.
function i($n){for($m=['|'];$k++<$n;){array_unshift($m,$m[]=str_repeat(' -'[$f=$k&1],2*$k-1));foreach($m as$i=>&$r)$r=($c='||- '[2*$f+($i&&$i<2*$k)]).$r.$c;}return$m;}

breakdown
function h($n)
{
    for($m=['|'];$k++<$n;)
    {
        array_unshift($m,$m[]=str_repeat(' -'[$f=$k&1],2*$k-1));
        foreach($m as$i=>&$r)
            $r=($c='||- '[2*$f+($i&&$i<2*$k)]).$r.$c;
    }
    return$m;
}

ungolfed
function ihih($n)
{
    $m=['|'];                   // iteration 0
    for($k=1;$k<=$n;$k++)       // loop $k from 1 to $n
    {
        $f=$k&1;                        // flag for odd iterations
        // add lines:
        $r=str_repeat(' -'[$f],2*$k-1); // new line: ' ' for even, '-' for odd iterations
        $m[]=$r;                                // append
        array_unshift($m,$r);                   // prepend
        // add columns:
        foreach($m as$i=>&$r)           // for each line
        {
            $c='| '[$f];                        // '|' for even, ' ' for odd iterations
            if($f && (!$i || $i==2*$k)) $c='-'; // '-' in corners for odd iterations
            $r=$c.$r.$c;                        // prepend and append character
        }
    }
    return $m;
}

Perl 5, 150 bytes
sub h{my$i=pop;my$c=$i%2?$":'|';return(map{"$c$_$c"}h($i-1)),$i%2?'-'x($i*2+1):$c.$"x($i*2-1).$c if$i;()}say for reverse(@q=h<>),$q[0]=~s/---/ | /r,@q

Try it online!

Haskell, 110 bytes
f 0=["|"]
f n|odd n=g ' '!n$'-'|1>0=g '|'$id!n$' '
g c=map$(c:).(++[c])
(g!n)c|p<-g.f$n-1=(:p)<>pure$c<$head p

Try it online!
Explanation/Ungolfed
The helper function g takes a character and a list of strings, it then pre- and appends that character to each string:
g c = map (\s-> [c] ++ s ++ [c])

Next the operator (!) takes a function (g), a number (n) and a character (c). It then computes the output for n-1, applies the function g to it and adds a string of the same width consisting of cs to the beginning and end:
(g ! n) c | prev <- g $ f (n-1), ln <- [c | _ <- head p]
          = [ln] ++ prev ++ [ln]

With these we'r ready to generate the outputs recursively, first we need to cover the base case:
f 0 = ["|"]

And then the recursion:
-- for odd n: the previous output needs a space at the end and beginning and then a string of '-' characters at the top and bottom
f n | odd n     = (g ' ' ! n) '-'
-- for even n: the previous output needs a line of spaces at the top and bottom and then each line needs to be enclosed with '|' characters
    | otherwise = g '|' $ (id ! n ) ' '

J, 37 bytes
f=:{&' |-'@*@(-:@=+<-2&|@>.)"{~@:|@i:

TIO