## PARI/GP - 24 ##

<!-- language-all: lang-default -->

 1%1
 8
 2+3

PARI/GP ignores spaces between digits, so that `1 8 2`, for example is treated as `182`. The same could work for perl by replacing the spaces with underscores. I haven't exhausted the entire search space, so there may be better candidates.

A program can be fed to gp as `gp -q -f program.gp`, or interactively in the repl.

---

**Output**

 1%1 8 2+3 -> 4
 1%1 3+8 2 -> 83 # invalid
 1%1 3+2 8 -> 29
 1%8 2+3 1 -> 32
 1 8%1 3+2 -> 7
 1 2+8%1 3 -> 20
 1 2+3 1%8 -> 19
 1 2+3 8%1 -> 12
 1%1 8 3+2 -> 3
 1%1 2+8 3 -> 84 # invalid
 1%1 2+3 8 -> 39
 1 8%1 2+3 -> 9
 1 3+8%1 2 -> 21
 1 3+2 1%8 -> 18
 8 1%1 3+2 -> 5
 8 1%1 2+3 -> 12 # dup
 8+2 1%1 3 -> 16
 8+3 1%1 2 -> 15
 2 1%1 8+3 -> 6
 2+8 1%1 3 -> 5 # dup
 3+2 8 1%1 -> 3 # dup
 2 8+3 1%1 -> 28
 8 2+3 1%1 -> 82 # invalid
 1 3+2 8%1 -> 13
 2+3 1%8 1 -> 33
 3 1%8+2 1 -> 28 # dup
 8%1 3+2 1 -> 29 # dup
 1%8 3+2 1 -> 22
 2+3 8 1%1 -> 2
 3 8+2 1%1 -> 38
 8 3+2 1%1 -> 83 # invalid
 3+2 1%8 1 -> 24
 2 1%8+3 1 -> 36
 8%1 2+3 1 -> 39 # dup
 2+3 1%1 8 -> 15 # dup
 3+2 1%1 8 -> 6 # dup
 3 1%1 2+8 -> 15 # dup
 2 1%1 3+8 -> 16 # dup
 3+8 1%1 2 -> 12 # dup
 3 1%1 8+2 -> 15 # dup

All but 4 values are within the required range, with 12 duplicate entries.

---

**Update**

I've finished crunching, there are six distinct 23s, and only one 24 (as read by rows):

 23 1%1 6 2+3 [2, 3, 4, 5, 7, 8, 11, 12, 13, 14, 16, 17, 18, 19, 22, 24, 26, 27, 32, 33, 34, 36, 37]
 23 1 2%3+2*8 [2, 5, 7, 8, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 22, 23, 25, 26, 29, 31, 32, 37, 40]
 23 2 3%1+8 2 [2, 4, 6, 7, 10, 11, 12, 13, 14, 15, 16, 20, 21, 23, 24, 28, 29, 30, 31, 32, 33, 34, 40]
 23 4%6%5*7+6 [2, 4, 5, 6, 7, 8, 9, 12, 13, 19, 21, 23, 24, 26, 29, 31, 32, 33, 34, 37, 38, 39, 40]
 23 5%6%4*7+6 [2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 25, 26, 29, 31, 33, 34, 37, 38, 39, 40]
 23 5%6%4*8+6 [1, 3, 5, 6, 8, 9, 10, 12, 14, 15, 18, 22, 24, 25, 27, 29, 30, 32, 34, 36, 37, 39, 40]

 24 1%1 8 2+3 [2, 3, 4, 5, 6, 7, 9, 12, 13, 15, 16, 18, 19, 20, 21, 22, 24, 28, 29, 32, 33, 36, 38, 39]

The program I used for crunching is below. PARI/GP has limited string processing capabilities, so deal mainly with char arrays (a.k.a. `Vecsmall`). The operators tested are `+`, `-`, `*`, `\` (floor div), `%`, `;` (expression separator, essentially discards everything before it), and ` ` (space, as described above). The exponent operator `^` could also be added, but it becomes too slow to test exhaustively.

 perms = {[
 [1, 2, 3, 6, 5, 4, 7, 8, 9], [1, 2, 3, 6, 9, 8, 5, 4, 7], [1, 2, 3, 6, 9, 8, 7, 4, 5], [1, 2, 5, 4, 7, 8, 9, 6, 3],
 [1, 4, 5, 2, 3, 6, 9, 8, 7], [1, 4, 7, 8, 5, 2, 3, 6, 9], [1, 4, 7, 8, 9, 6, 3, 2, 5], [1, 4, 7, 8, 9, 6, 5, 2, 3],
 [3, 2, 1, 4, 5, 6, 9, 8, 7], [3, 2, 1, 4, 7, 8, 5, 6, 9], [3, 2, 1, 4, 7, 8, 9, 6, 5], [3, 6, 5, 2, 1, 4, 7, 8, 9],
 [3, 6, 9, 8, 5, 2, 1, 4, 7], [3, 6, 9, 8, 7, 4, 1, 2, 5], [5, 4, 1, 2, 3, 6, 9, 8, 7], [5, 6, 3, 2, 1, 4, 7, 8, 9],
 [5, 8, 7, 4, 1, 2, 3, 6, 9], [5, 8, 9, 6, 3, 2, 1, 4, 7], [7, 4, 1, 2, 3, 6, 5, 8, 9], [7, 8, 5, 4, 1, 2, 3, 6, 9],
 [9, 8, 7, 4, 5, 6, 3, 2, 1], [7, 4, 5, 8, 9, 6, 3, 2, 1], [5, 4, 7, 8, 9, 6, 3, 2, 1], [3, 6, 9, 8, 7, 4, 5, 2, 1],
 [7, 8, 9, 6, 3, 2, 5, 4, 1], [9, 6, 3, 2, 5, 8, 7, 4, 1], [5, 2, 3, 6, 9, 8, 7, 4, 1], [3, 2, 5, 6, 9, 8, 7, 4, 1],
 [7, 8, 9, 6, 5, 4, 1, 2, 3], [9, 6, 5, 8, 7, 4, 1, 2, 3], [5, 6, 9, 8, 7, 4, 1, 2, 3], [9, 8, 7, 4, 1, 2, 5, 6, 3],
 [7, 4, 1, 2, 5, 8, 9, 6, 3], [5, 2, 1, 4, 7, 8, 9, 6, 3], [7, 8, 9, 6, 3, 2, 1, 4, 5], [9, 8, 7, 4, 1, 2, 3, 6, 5],
 [9, 6, 3, 2, 1, 4, 7, 8, 5], [7, 4, 1, 2, 3, 6, 9, 8, 5], [9, 8, 5, 6, 3, 2, 1, 4, 7], [9, 6, 3, 2, 1, 4, 5, 8, 7]
 ]}

 ops = Vecsmall("+-*\\%; ")

 ms = 1

 for(c = 48, 57, {
 for(d = c, 57,
 for(f = d, 57,
 for(g = c, 57,
 for(e = 48, 57,
 print1(Strchr([c,d,e,f,g,13]));
 for(h = 1, #ops,
 for(i = 1, #ops,
 for(j = 1, #ops,
 for(k = 1, #ops,
 a = Vecsmall([c, ops[h], d, ops[i], e, ops[j], f, ops[k], g]);
 s = Set();
 for(m = 1, #perms,
 v = Strchr(vecextract(a, perms[m]));
 iferr(b = eval(v), E, b = 0);
 if(b >= 1 && b <= 40, s = setunion(s, [b]))
 );
 if(#s >= ms, ms = min(23, #s); print(#s, " ", Strchr(a), " ", s));
 )
 )
 )
 )
 )
 )
 )
 )
 })