101
\$\begingroup\$

Choose any five characters your language supports. There are 5! = 5×4×3×2×1 = 120 ways these can be arranged into a 5-character string that contains each character once; 120 permutations.

Choose your characters such that, when each of the 120 strings is run in your language, the 120 outputs produced will be as many unique integers from 1 to 120 (inclusive) as possible.

That is, for each of the 120 permutations of your 5 characters that produce runnable code that outputs a single number, you want the set of all those numbers to match as close as possible to the set of integers from 1 through 120.

So, ideally, your first permutation would output 1, the next 2, the next 3, all the way up to 120. But that ideal is likely impossible for most languages and characters.

The 5-character strings may be run as:

  • a program with no input
  • a function with no arguments
  • a REPL command

Different strings can be run in different ways if desired

For the output to count, it must be a single integer output in a normal way, such as:

  • being printed to stdout
  • returned by the function
  • the result of the REPL expression

The code should terminate normally (which may involve erroring out as long as the number has been output first). Code that does not run at all is fine, just the (nonexistent) output doesn't count. The numbers output should be in decimal unless a different base is the norm for your language.

The submission that generates the most distinct numbers from 1 through 120 wins. The earlier submission wins in case of a tie.

Notes

  • Your 5 characters do not all need to be different, but of course having duplicate characters reduces the effective number of permutations.
  • Float outputs such as 32.0 count as well as plain 32. (But 32.01 would not.)
  • Leading zeroes such as 032 count as well as plain 32.
  • Valid outputs should be deterministic and time invariant.
  • We are dealing with characters, not bytes.

Example

The characters 123+* are a reasonable first choice for Python's (or many language's) REPL. The resulting 120 permutations and outputs are:

123+* n/a
123*+ n/a
12+3* n/a
12+*3 n/a
12*3+ n/a
12*+3 36
132+* n/a
132*+ n/a
13+2* n/a
13+*2 n/a
13*2+ n/a
13*+2 26
1+23* n/a
1+2*3 7
1+32* n/a
1+3*2 7
1+*23 n/a
1+*32 n/a
1*23+ n/a
1*2+3 5
1*32+ n/a
1*3+2 5
1*+23 23
1*+32 32
213+* n/a
213*+ n/a
21+3* n/a
21+*3 n/a
21*3+ n/a
21*+3 63
231+* n/a
231*+ n/a
23+1* n/a
23+*1 n/a
23*1+ n/a
23*+1 23
2+13* n/a
2+1*3 5
2+31* n/a
2+3*1 5
2+*13 n/a
2+*31 n/a
2*13+ n/a
2*1+3 5
2*31+ n/a
2*3+1 7
2*+13 26
2*+31 62
312+* n/a
312*+ n/a
31+2* n/a
31+*2 n/a
31*2+ n/a
31*+2 62
321+* n/a
321*+ n/a
32+1* n/a
32+*1 n/a
32*1+ n/a
32*+1 32
3+12* n/a
3+1*2 5
3+21* n/a
3+2*1 5
3+*12 n/a
3+*21 n/a
3*12+ n/a
3*1+2 5
3*21+ n/a
3*2+1 7
3*+12 36
3*+21 63
+123* n/a
+12*3 36
+132* n/a
+13*2 26
+1*23 23
+1*32 32
+213* n/a
+21*3 63
+231* n/a
+23*1 23
+2*13 26
+2*31 62
+312* n/a
+31*2 62
+321* n/a
+32*1 32
+3*12 36
+3*21 63
+*123 n/a
+*132 n/a
+*213 n/a
+*231 n/a
+*312 n/a
+*321 n/a
*123+ n/a
*12+3 n/a
*132+ n/a
*13+2 n/a
*1+23 n/a
*1+32 n/a
*213+ n/a
*21+3 n/a
*231+ n/a
*23+1 n/a
*2+13 n/a
*2+31 n/a
*312+ n/a
*31+2 n/a
*321+ n/a
*32+1 n/a
*3+12 n/a
*3+21 n/a
*+123 n/a
*+132 n/a
*+213 n/a
*+231 n/a
*+312 n/a
*+321 n/a

There are 36 numbers generated, all luckily within 1 to 120:

36, 26, 7, 7, 5, 5, 23, 32, 63, 23, 5, 5, 5, 7, 26, 62, 62, 32, 5, 5, 5, 7, 36, 63, 36, 26, 23, 32, 63, 23, 26, 62, 62, 32, 36, 63

However, only 8 of them are unique:

36, 26, 7, 5, 23, 32, 63, 62

So such a submission would only score 8 out of a maximal 120.

\$\endgroup\$
  • 21
    \$\begingroup\$ I wanna do this challenge but it seems IMPOSSIBLE in c-like languages!!! \$\endgroup\$ – Mukul Kumar Dec 9 '16 at 8:57
  • 3
    \$\begingroup\$ @MukulKumar I believe there are REPLs in C-like language as well (e.g. gdb can be used - to a degree - as a REPL for C) so that the approach demonstrated for Python would still be an option. \$\endgroup\$ – Martin Ender Dec 9 '16 at 9:02
  • 1
    \$\begingroup\$ Related (fixed link). \$\endgroup\$ – Fatalize Dec 9 '16 at 13:02
  • 3
    \$\begingroup\$ @ETH No to the true thing. Thats like allowing another base. \$\endgroup\$ – Calvin's Hobbies Dec 9 '16 at 22:06
  • 3
    \$\begingroup\$ @OldBunny2800 Valid outputs should be deterministic and time invariant. \$\endgroup\$ – Dennis Dec 13 '16 at 1:21

32 Answers 32

41
\$\begingroup\$

Python3, 21 27 values

Characters: 3479%

Unique numbers: [1,2,3,4,5,6,7,8,9,11,12,19,20,21,24,29,34,35,36,37,39,43,46,47,49,73,74]

As it was requested, here are the permutations that fell in the range [1, 120]. Try it online!

347%9   5
349%7   6
34%79   34
34%97   34
374%9   5
379%4   3
37%49   37
37%94   37
394%7   2
397%4   1
39%47   39
39%74   39
3%479   3
3%497   3
3%749   3
3%794   3
3%947   3
3%974   3
437%9   5
439%7   5
43%79   43
43%97   43
473%9   5
479%3   2
47%39   8
47%93   47
493%7   3
497%3   2
49%37   12
49%73   49
4%379   4
4%397   4
4%739   4
4%793   4
4%937   4
4%973   4
734%9   5
739%4   3
73%49   24
73%94   73
743%9   5
749%3   2
74%39   35
74%93   74
793%4   1
794%3   2
79%34   11
79%43   36
7%349   7
7%394   7
7%439   7
7%493   7
7%934   7
7%943   7
934%7   3
937%4   1
93%47   46
93%74   19
943%7   5
947%3   2
94%37   20
94%73   21
973%4   1
974%3   2
97%34   29
97%43   11
9%347   9
9%374   9
9%437   9
9%473   9
9%734   9
9%743   9
\$\endgroup\$
  • 2
    \$\begingroup\$ Wouldn't you get better results in Python 2, where / is integer division? \$\endgroup\$ – Neil Dec 9 '16 at 10:16
  • \$\begingroup\$ @Kade Me as well. The largest I tried was something in the lines of "0123456789*-+&|%^0123456789" \$\endgroup\$ – Yytsi Dec 9 '16 at 13:37
  • \$\begingroup\$ There is 2 more alternative to this resulting the same number of values: 5679% and 5789% \$\endgroup\$ – Gábor Fekete Dec 9 '16 at 14:31
  • \$\begingroup\$ FYI - This (or the 5679% and 5789% ones) are likely the optimal for PowerShell as well. \$\endgroup\$ – AdmBorkBork Dec 9 '16 at 19:36
  • \$\begingroup\$ I got this answer (along with 5679% and 5798%) as well through an exhaustive search on all combinations of 0123456789+-*/&|^#% with replacement. I agree that these are likely optimal. \$\endgroup\$ – JaredL Dec 9 '16 at 20:12
34
\$\begingroup\$

05AB1E, 27 38 41 numbers

4·>Ìn

Generates the unique numbers:

[4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 25, 27, 32, 33, 34, 35, 36, 37, 38, 49, 50, 52, 54, 64, 65, 66, 67, 72, 73, 74, 81, 83, 98, 100, 101, 102]

Uses the constant 4 with the operations +1, +2, *2 and ^2.

\$\endgroup\$
  • \$\begingroup\$ Haven't tested, but would using - instead of + yield a wider variety of results based on its non-commutative property? \$\endgroup\$ – Osable Dec 9 '16 at 10:22
  • \$\begingroup\$ @Osable: I have tested with - as well, but never gotten over 30 unique numbers. One issue is that you get negative values as well which fall outside the range. Maybe with some other operators replaced it might be better, but I haven't found an improvement thus far. \$\endgroup\$ – Emigna Dec 9 '16 at 10:25
  • \$\begingroup\$ Right, I skipped the part (although in bold style) saying that output must be in range [1,120]. My bad \$\endgroup\$ – Osable Dec 9 '16 at 10:28
  • \$\begingroup\$ I tried for awhile and capped at like ~35 on everything else. \$\endgroup\$ – Magic Octopus Urn Dec 9 '16 at 17:44
32
\$\begingroup\$

Python, 18 numbers

237#-

Produces as valid results:

1, 2, 3, 4, 5, 7, 16, 23, 24, 25, 27, 32, 35, 37, 69, 71, 72, 73

EDIT: I can attest that TuukkaX's solution is optimal for Python. I ran the following code bruteforcing all possible combinations of 5 printable ASCII characters:

from itertools import permutations,combinations_with_replacement

def perms(chars):
  result=set()
  for permut in permutations(chars):
    try:
      current=eval(''.join(permut))
      assert str(int(current))==str(current)
      result.add(int(current))
    except:
      pass
  return sum([1 for x in result if 1<=x<=120])

best=1
for c in combinations_with_replacement(' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~',5):
    string=''.join(c)
    r=perms(string)
    if r>=best:
        best=r
        print(r,string,end='\n')

The results (after running for almost 7 hours) showed that the optimal solution is in fact 27 different numbers, produced by three different solutions all using four numbers and mod (%): %3479, %5679 and %5789.

\$\endgroup\$
  • 25
    \$\begingroup\$ @TùxCräftîñg Actually it isn't, a set is an unordered collection. \$\endgroup\$ – Leo Dec 9 '16 at 10:05
  • 2
    \$\begingroup\$ @TùxCräftîñg https://repl.it/El9V/0 of course sets use an internal sorting to keep track of elements, the point is that you can't rely on this sorting, as items are not necessarily sorted in the order you would expect them to be \$\endgroup\$ – Leo Dec 9 '16 at 11:17
  • 1
    \$\begingroup\$ @TuukkaX I see that this is unexpected behaviour and causes more problems than it solves, so I edited it out. Sorry for the inconvenience :) \$\endgroup\$ – Leo Dec 9 '16 at 11:20
  • 1
    \$\begingroup\$ @hBy2Py If you don't do any other operation on the set between the two iterations I think you can assume that the two iterations will follow the same order. In the general case, though, the rule is that sets are unordered collections, so you should never rely on them having any kind of order. \$\endgroup\$ – Leo Dec 9 '16 at 18:05
  • 3
    \$\begingroup\$ @Leo Got it: sets are nitroglycerin. Reasonably stable unless you bump them. \$\endgroup\$ – hBy2Py Dec 9 '16 at 18:07
23
\$\begingroup\$

Java 8, 2 4 numbers

n->12  // returns 12
n->21  // returns 21
n1->2  // returns 2
n2->1  // returns 1

Weren't expecting a Java answer, were you?

This is a lambda that can only be arranged one of two ways (and with any two different digits!) for a total of two unique numbers. Everything else isn't a valid lambda.

Actually improved the answer, thanks to some help from comments! Didn't see that 0 wasn't valid, and forgot that variables could, y'know, be more than one character. We've got 4!

An even worse solution

()->1

But, on the bright side, two unique answers in Java!

\$\endgroup\$
  • 2
    \$\begingroup\$ Does Java have a REPL? Maybe you can use more symbols this way \$\endgroup\$ – Arturo Torres Sánchez Dec 9 '16 at 16:40
  • \$\begingroup\$ I have no idea. I'm inclined to say no. Besides, my answer would basically become a copypaste of the other REPL answers then :P \$\endgroup\$ – Xanderhall Dec 9 '16 at 17:20
  • 3
    \$\begingroup\$ Java 9 will have a vanilla REPL!! But for now we're stuck with 3rd party stuff. \$\endgroup\$ – NonlinearFruit Dec 9 '16 at 18:12
  • 17
    \$\begingroup\$ I think you can do better with n->12. This gives you four distinct answers that are all within the range: n->12, n->21, n1->2, n2->1. \$\endgroup\$ – user62131 Dec 9 '16 at 22:21
  • 2
    \$\begingroup\$ Java 9 and its REPL are available in an early access version today. In fact, I've submitted answers to other questions on here using it. \$\endgroup\$ – David Conrad Dec 10 '16 at 6:04
18
\$\begingroup\$

Jelly, 26 30 32 numbers

‘’3²Ḥ

This (and its anagrams) are full programs, that take no input, and produce output on standard output.

The outputs from the 120 programs are, in the order Jelly generates them if you ask it to generate permutations of the program:

018 036 06 03 09 03 18 116 116 117 125 135 06 03 14 15 13 22 19 13 24
28 33 42 018 036 06 03 09 03 -132 -164 -120 -119 -149 -137 26 43 18 17 
33 24 -19 13 -216 -210 53 44 18 36 30 31 49 63 18 36 10 9 25 17 18 19
18 17 18 18 36 48 36 26 36 36 06 03 14 15 13 22 06 03 -18 -17 -13 -24
06 07 06 05 06 06 03 12 03 -14 03 03 09 03 14 18 03 12 09 03 -116 -110 
23 14 09 015 09 05 09 09 03 12 03 -14 03 03

If you just take the unique outputs in numerical order, you get:

-216 -210 -164 -149 -137 -132 -120 -119 -116 -110 -24 -19 -18 -17 -14 -13
03 05 06 07 09 10 12 13 14 15 17 018 19 22 23 24 25 26 28 30 31 33 036 42
43 44 48 49 53 63 116 117 125 135

Many of these are too small, and 135 is too large, but there are still 32 that are in range.

The basic idea is to use mostly monadic instructions (in a program with only monads and nilads, these each just transform the previous output), and ones that allow the value to diverge quickly. The exception is with 3, which is a nilad (the constant value 3). If it appears at the start of the program, all the operations will be done from 3. If it appears in the middle, it splits the program into two halves, each of which outputs an integer (and as they each print to standard output, the results end up getting concatenated, thus giving us "concatenate" as an additional operation to generate numbers).

The operations we have here, in the context the program generates them in, are: increment; decrement; constant 3; square; and double. Increment and decrement are unfortunately opposites, and decrement has an unfortunate tendency to produce a -1 or -2 in the first section (thus leading to a negative number overall), but this still gave a greater spread of outputs than the other things I tried. In particular, we get a pretty good spread of both the first and second halves of the number (note that the first half can be the null string, if 3 is the first character in the program).

\$\endgroup\$
  • \$\begingroup\$ @TuukkaX it does, I implemented both the monadic Œ¿ and the dyadic œ¿ (see near the bottom of the Wiki's atoms page), but they are both 2-byte dyads which will reduce the code permutations that do what you want, plus you'd need all of your inputs to be lists (12 is not a list). \$\endgroup\$ – Jonathan Allan Dec 9 '16 at 13:13
16
\$\begingroup\$

JavaScript, 27 numbers

Very similar to TuukkaX's answer, with another set of digits.

5789%

The 27 distinct values are:

589 %   7 -> 1
987 %   5 -> 2
978 %   5 -> 3
879 %   5 -> 4
985 %   7 -> 5
958 %   7 -> 6
975 %   8 -> 7
 95 %  87 -> 8
  9 % 875 -> 9
 97 %  85 -> 12
 89 %  75 -> 14
 95 %  78 -> 17
 78 %  59 -> 19
 79 %  58 -> 21
 98 %  75 -> 23
 87 %  59 -> 28
 89 %  57 -> 32
 97 %  58 -> 39
 98 %  57 -> 41
 57 %  98 -> 57
 58 %  97 -> 58
 59 %  87 -> 59
 75 %  98 -> 75
 78 %  95 -> 78
 79 %  85 -> 79
 85 %  97 -> 85
 87 %  95 -> 87
\$\endgroup\$
  • \$\begingroup\$ would using bitwise not, ~, help at all? It's a unary operation which may be useful. \$\endgroup\$ – JollyJoker Dec 9 '16 at 13:52
  • 1
    \$\begingroup\$ @JollyJoker Well, the best I can find so far with ~ is 257&~, which produces 11 distinct values. \$\endgroup\$ – Arnauld Dec 9 '16 at 14:25
  • \$\begingroup\$ I'm a bit surprised, but I guess my intuition isn't very good here. \$\endgroup\$ – JollyJoker Dec 9 '16 at 14:56
15
\$\begingroup\$

Brachylog, 26 numbers

3+*^-

This outputs the following numbers: [2,3,4,5,6,7,8,9,10,16,17,18,19,20,25,26,30,31,32,35,36,37,48,49,63,64]

Explanation

  • 3 is the integer 3, obviously.
  • + is increment
  • * is double
  • ^ is square
  • - is decrement

There are a lot of situations where the program simply errors: for example *+^3- errors because it asks “Take 0, double it, increment, square, the result of that square is 3, decrement” which is obviously wrong.

Any program that ends with 3 will either output 3 or not work.

Any program that starts with *3 will loop infinitely because of a bug (Brachylog is attempting to find a list of sublists which product result in 3 which is not possible).

\$\endgroup\$
  • 1
    \$\begingroup\$ Nice answer and Idk anything about the golfing but in math side you can get any number up to 121 by just adding or subbing first five power of 3. 1,3,9,27 and 81. Hope that helps. \$\endgroup\$ – shyos Dec 9 '16 at 15:11
11
\$\begingroup\$

Vim, 16 numbers

i1234

print

1, 2, 3, 4, 12, 13, 14, 21, 23, 24, 31, 32, 34, 41, 42, 43
\$\endgroup\$
  • 1
    \$\begingroup\$ @ymbirtt Where did the 3 and the 4 go? You need all length-5 permutations. \$\endgroup\$ – Kade Dec 9 '16 at 15:53
  • \$\begingroup\$ i1234 prints "1234", is this some kind of script or keypresses? If it's keypresses it doesn't work. \$\endgroup\$ – Captain Man Dec 9 '16 at 17:30
  • \$\begingroup\$ Expanding on @Captain Man's point, the obvious way to run the permutations as a script would be with :norm. That doesn't print any numbers in the 1-120 range, though. Did you have another method in mind? \$\endgroup\$ – Simon Dec 9 '16 at 17:35
  • \$\begingroup\$ You can put them in the online interpreter for V which is more or less backwards compatible with Vim \$\endgroup\$ – nmjcman101 Dec 9 '16 at 19:24
  • 4
    \$\begingroup\$ @nmjcman101 In this case it fall to in the hole of "mostly" since 12i34 in V result in 12 occurence of 34 where as if you type it in vim it just give you 34 (i guess V assume a final esc) \$\endgroup\$ – Sefa Dec 12 '16 at 9:13
11
\$\begingroup\$

IA-32 machine code, 8 numbers

Hexadecimal byte values:

2c 40 48 b0 c3

The code is run as a function returning the value in al.

Valid permutations:

b0 2c c3 xx xx => 2c (mov al, 2c)

b0 40 c3 xx xx => 40 (mov al, 40)

b0 48 c3 xx xx => 48 (mov al, 48)

b0 2c 40 c3 48 => 2d (mov al, 2c; inc eax)

b0 2c 48 c3 40 => 2b (mov al, 2c; dec eax)

b0 40 48 c3 2c => 3f (mov al, 40; dec eax)

b0 48 40 c3 2c => 49 (mov al, 48; inc eax)

b0 48 2c 40 c3 => 8 (mov al, 48; sub al, 40)

I did a brute-force search, with the following constraints:

  • The first byte is b0 - to initialize the al register
  • The last byte is c3 - return; following bytes are discarded
  • Possible opcode bytes are:
    • 0x04 - add
    • 0x0c - or
    • 0x24 - and
    • 0x2c - sub
    • 0x34 - xor
    • 0xd4 - aad
    • 0x40 - inc
    • 0x48 - dec

This leaves only 3 changeable bytes with a maximum of 15 possible results. Of these, a maximum of 9 can be distinct (in fact, this happens for only one set of bytes!). One of the values is out of range, so this leaves 8 values. There is another set of bytes

34 40 48 b0 c3

which also gives 8 distinct values - the programs are the same, except for sub replaced by xor, which makes two of the possible outputs identical.

All other sets of bytes give 7 or fewer possible results.

\$\endgroup\$
10
\$\begingroup\$

Jelly, 33 numbers

Ḥ23+c

double(left);
2 literal 2;
3 literal 3;
+ add(left, right); and
c choose(left, right), i.e. number of ways to choose right objects from a collection of left objects.

Numbers yielded with an example program:

 1 +32Ḥc   18 3Ḥc2+    45 2+3Ḥc
 2 c3Ḥ+2   20 2+Ḥc3    47 23c+Ḥ
 3 c2Ḥ+3   21 2Ḥ+3c    48 c+23Ḥ
 4 +2Ḥc3   22 3Ḥc+2    53 2c+Ḥ3
 5 2+3cḤ   23 23cḤ+    56 3Ḥ+2c
 6 3c+2Ḥ   24 cḤ+23    63 c+2Ḥ3
 8 2c+3Ḥ   30 3+c2Ḥ    65 32c+Ḥ
 9 3c2+Ḥ   32 32cḤ+    66 c+32Ḥ
12 +3cḤ2   33 cḤ+32    72 3c+Ḥ2
13 +2cḤ3   36 3+Ḥc2    82 c+3Ḥ2
15 +3Ḥc2   42 cḤ3+2   120 3+2Ḥc

I tried to choose easy to parse ones, but some are rare and slightly strange to parse, for example 23 is:

23cḤ+: (23 c (2 * 23)) + 23 = (23 c 46) + 23 = 0 + 23 = 23

...and 72 and 13 use implicit printing:

3c+Ḥ2: z = (3 c 0) + (3 * 2); print(z); z = 2; print(z)
       z =    1    +    6   ; print(z); z = 2; print(z)

+2cḤ3: z = (0 + 2) c (2 * 0); print(z); z = 3; print(z)
       z =    2    c    0   ; print(z); z = 3; print(z)
       z =         1        ; print(z); z = 3; print(z)

Note that Ḥ34+c also produces 33 unique values in [1,120].

\$\endgroup\$
10
\$\begingroup\$

Brain-Flak 1

(())#

Brain-Flak requires balanced braces, so a 5 character program is only valid if one of the characters starts a comment. That leaves us with 4 characters to work with. Of those, 2 have to be ( and ) otherwise nothing would get pushed onto the stack. Those have to go first and 4th with the comment last ((..)#). Now we can put (), {}, <>, or [] inside. {}, <>, and [] each evaluate to 0, but () is 1. That means that (())# is the only 5 character string that produces a valid Brain-Flak program.

Try it Online!

If the question were instead "what are the 6 most powerful characters", the answer would be (){}[] as Brain-Flak is turing complete using only this subset.

\$\endgroup\$
  • \$\begingroup\$ A poorly documented feature: the @ij debug flag pauses the program and allows the user to input brain-flak code to be run where the @ij flag appeared in the code. Pretty powerful but unfortunately requires user input and so is not useful here. \$\endgroup\$ – 0 ' Dec 15 '16 at 7:24
  • \$\begingroup\$ Slight correction: (){}[] would score 0. You forgot the permutations rule ;) \$\endgroup\$ – CalculatorFeline Jun 18 '17 at 3:15
8
\$\begingroup\$

Hexagony, 13 numbers

)24!@

These are the 13 printable numbers with one possible program for each of them:

)!@24 1
2!@)4 2
2)!@4 3
4!@)2 4
4)!@2 5
)2!@4 12
)4!@2 14
24!@) 24
24)!@ 25
2)4!@ 34
42!@) 42
42)!@ 43
4)2!@ 52

The programs should be fairly self-explanatory. @ terminates the program, ! prints the current value, ) increments it, 2 and 4 append themselves to the current value (where the initial value is 0). The actual hexagonal layout of the source code is irrelevant here, the programs can simply be read from left to right.

This should be optimal, although instead of 2 and 4 you can pick any pair digits x and y such that 2 ≤ x ≤ y-2.

The above solution was found by (almost exhaustive) brute force, requiring one ! (otherwise it wouldn't print anything), one @ (otherwise the program won't terminate), and filling the remaining three characters with any (repeated) combination from the following set of characters:

#[]\/_|<>)!0123456789$

I can't see how any of the other commands could possibly generate more variety.

\$\endgroup\$
  • \$\begingroup\$ I was going to post a Labyrinth answer as well, but the exact same set of solutions appears to be optimal there as well (with effectively the same semantics, too). \$\endgroup\$ – Martin Ender Dec 9 '16 at 10:52
7
\$\begingroup\$

Perl, 27 numbers

3479%

Perl doesn't have a built-in REPL, so you can use re.pl from Devel::REPL.

Results:

%9743 -> N/A
9%743 -> 9
97%43 -> 11
974%3 -> 2
9743% -> N/A
%7943 -> N/A
7%943 -> 7
79%43 -> 36
794%3 -> 2
7943% -> N/A
%7493 -> N/A
7%493 -> 7
74%93 -> 74
749%3 -> 2
7493% -> N/A
%7439 -> N/A
7%439 -> 7
74%39 -> 35
743%9 -> 5
7439% -> N/A
%9473 -> N/A
9%473 -> 9
94%73 -> 21
947%3 -> 2
9473% -> N/A
%4973 -> N/A
4%973 -> 4
49%73 -> 49
497%3 -> 2
4973% -> N/A
%4793 -> N/A
4%793 -> 4
47%93 -> 47
479%3 -> 2
4793% -> N/A
%4739 -> N/A
4%739 -> 4
47%39 -> 8
473%9 -> 5
4739% -> N/A
%9437 -> N/A
9%437 -> 9
94%37 -> 20
943%7 -> 5
9437% -> N/A
%4937 -> N/A
4%937 -> 4
49%37 -> 12
493%7 -> 3
4937% -> N/A
%4397 -> N/A
4%397 -> 4
43%97 -> 43
439%7 -> 5
4397% -> N/A
%4379 -> N/A
4%379 -> 4
43%79 -> 43
437%9 -> 5
4379% -> N/A
%9734 -> N/A
9%734 -> 9
97%34 -> 29
973%4 -> 1
9734% -> N/A
%7934 -> N/A
7%934 -> 7
79%34 -> 11
793%4 -> 1
7934% -> N/A
%7394 -> N/A
7%394 -> 7
73%94 -> 73
739%4 -> 3
7394% -> N/A
%7349 -> N/A
7%349 -> 7
73%49 -> 24
734%9 -> 5
7349% -> N/A
%9374 -> N/A
9%374 -> 9
93%74 -> 19
937%4 -> 1
9374% -> N/A
%3974 -> N/A
3%974 -> 3
39%74 -> 39
397%4 -> 1
3974% -> N/A
%3794 -> N/A
3%794 -> 3
37%94 -> 37
379%4 -> 3
3794% -> N/A
%3749 -> N/A
3%749 -> 3
37%49 -> 37
374%9 -> 5
3749% -> N/A
%9347 -> N/A
9%347 -> 9
93%47 -> 46
934%7 -> 3
9347% -> N/A
%3947 -> N/A
3%947 -> 3
39%47 -> 39
394%7 -> 2
3947% -> N/A
%3497 -> N/A
3%497 -> 3
34%97 -> 34
349%7 -> 6
3497% -> N/A
%3479 -> N/A
3%479 -> 3
34%79 -> 34
347%9 -> 5
3479% -> N/A

Brute-forced using the following program:

use strict;
use warnings 'all';
use 5.010;

use Algorithm::Combinatorics qw(combinations);
use Algorithm::Permute;
use Scalar::Util::Numeric qw(isint);

my @chars = ( 0..9, qw(+ - * / . ; ' " \ @ $ # ! % ^ & ( ) { } =) );
my $iter  = combinations(\@chars, 5);
my $max   = 0;
my @best;

while (my $combo = $iter->next) {
    my $count = count_valid([@$combo]);

    if ($count > $max) {
        $max  = $count;
        @best = @$combo;
    }
}

say "$max -> @best";

sub count_valid {
    my ($chars) = @_;

    my $iter = Algorithm::Permute->new($chars);
    my %results;

    while (my @perm = $iter->next) {
        no warnings;
        my $val = eval join '', @perm;
        use warnings 'all';

        $results{$val} = 1 if isint($val) && $val > 0 && $val <= 120;
    }

    return scalar keys %results;
}
\$\endgroup\$
  • \$\begingroup\$ Perl actually does have something very close to a built-in REPL. Try running perl -de 1 some time. This technically opens the debugger on an empty program, but the debugger has a REPL-alike built in. Unfortunately, you need to write p at the start of each line to get it to actually print the result. \$\endgroup\$ – user62131 Dec 9 '16 at 22:23
  • \$\begingroup\$ @ais523 That's why I didn't mention it; you can't just type the string itself and get output, which is one of the requirements. \$\endgroup\$ – ThisSuitIsBlackNot Dec 11 '16 at 16:24
7
\$\begingroup\$

R, 15 18 numbers

Not a huge number but it may be the best that can be done with R. I searched all combinations of digits 0..9, operators + - * / ^ and the comment char #, and the following eight all output 18 unique integers between 1 and 120.

-#146
-#157
-#237
-#238
-#256
-#267
-#278
-#378
-#467
-#568

As an example, let's take -#146. Here are the 18 integers we can get:

1#-46      = 1
6-4#1      = 2
4-1#6      = 3
4#-16      = 4
6-1#4      = 5
6#-14      = 6
14-6#      = 8
16-4#      = 12
14#-6      = 14
16#-4      = 16
41-6#      = 35
41#-6      = 41
46-1#      = 45
46#-1      = 46
61-4#      = 57
61#-4      = 61
64-1#      = 63
64#-1      = 64

If you're curious about the (ugly) code used to test all the possible combinations, here it is. It outputs the number of unique integers between 1 and 120 for each character combination of length 5 to a file called "datafile" in the current working directory.

allchars = c("1","2","3","4","5","6","7","8","9","0","+","-","*","/","^")
apply(gtools::combinations(n=15, r=5, v=allchars, repeats.allowed=TRUE),
      1,
      function(chars) {
        x = apply(apply(e1071::permutations(length(chars)), 
                        1,
                        function(i) chars[i]
                        ),
                  2,
                  paste, collapse=""
            )
        u = unique(x)
        o = as.numeric(unlist(sapply(u, function(i) eval(try(parse(t=i),TRUE)))))

        f = factor(unique(o[o<=120 & o>=1 & o%%1==0]))
        write(paste(nlevels(f), paste(chars, collapse="")), "datafile", append=TRUE)
      }
)
\$\endgroup\$
  • \$\begingroup\$ You say it's ugly code... I think it's beautiful! The many uses of apply never cease to amaze me! \$\endgroup\$ – Sumner18 Apr 9 at 16:43
6
\$\begingroup\$

Octave, 18

This was found using a bruteforce search on the symbols *+-/0123456789:;<\^|~%. But it took way too long to compute...

-139%

Possible outputs:

1, 2, 3, 4, 6, 8, 9,13,16,19,22,31,38,39,88,91,92,93
\$\endgroup\$
5
\$\begingroup\$

Octave, 15 numbers

Not much to brag about, but this is the best I can get in Octave:

124+%

It gives the numbers:

1    2    3    4    5    6   12   14   16   21   24   25   41   42   43

I got 16 too, but it seems it's identical to Sefa's answer...

1234%

1    2    3    4   12   13   14   21   23   24   31   32   34   41   42   43
\$\endgroup\$
  • \$\begingroup\$ According to my tests, the optimal choice from 0123456789+-*.% for octave is 139-%, which produces an array of 18: 1 2 3 4 6 8 9 13 16 19 22 31 38 39 88 91 92 93. So you can gain another 3 numbers :) \$\endgroup\$ – user4768 Dec 9 '16 at 15:48
  • 2
    \$\begingroup\$ very crude brute-force that I used to get the 18-number solution: pastebin.com/umckG0VS \$\endgroup\$ – user4768 Dec 9 '16 at 15:55
  • 2
    \$\begingroup\$ I found that solution too, but that was after seeing the python submission and it's essentially the same thing. Nice job bothering to make a brute force script. 😊 \$\endgroup\$ – Stewie Griffin Dec 9 '16 at 16:35
4
\$\begingroup\$

PHP, 15 numbers

1230\r

Uses the fact that php prints anything outside its tags verbatim (without using this you can do exactly 1 number with something like <?=1;). Also uses an actual carriage return character rather than \r.

Creates (sorted, removed leading 0s):

 1 1 2 2 3 3 10 10 12 12 12 12 13 13 13 13 20 20 21 21 21 21 23 23 23 23 30 30 31 31 31 31 32 32 32 32 102 102 103 103 120 120 123 123 123  123  130  130  132  132  132  132  201  201  203  203  210  210  213  213  213  213  230  230  231  231  231  231  301  301  302  302  310  310  312  312  312  312  320  320  321  321  321  321  1023  1023  1032  1032  1203  1203  1230  1230  1302  1302  1320  1320  2013  2013  2031  2031  2103  2103  2130  2130  2301  2301  2310  2310  3012  3012  3021  3021  3102  3102  3120  3120  3201  3201  3210  3210

of which the valid unique numbers are:

1 2 3 10 12 13 20 21 23 30 31 32 102 103 120
\$\endgroup\$
  • 3
    \$\begingroup\$ That doesn't really print those numbers though. 12\r30 prints 12\r30, the terminal just overwrites the first two characters. \$\endgroup\$ – Dennis Dec 9 '16 at 16:13
  • \$\begingroup\$ @Dennis That's like saying that in any challenge that requires the technique of control characters to overwrite text, the output isn't what's seen at the end, but the sum of the written bytes. Since \r isn't printable, the output of 12\r30 is 30. \$\endgroup\$ – cat Dec 9 '16 at 22:28
  • 3
    \$\begingroup\$ @cat We've actually discussed this on meta; using control characters is only allowed if the challenge is related to ASCII art. \$\endgroup\$ – Dennis Dec 9 '16 at 22:30
4
\$\begingroup\$

Cubix, 7 numbers

"2)@O

Outputs these numbers:

")O2@ ->  1
")2O@ ->  2
"2)O@ ->  3
2"O@) -> 41
)"O@2 -> 50
2"O)@ -> 64
2")O@ -> 65

Any valid Cubix program for this challenge has to have an O to output an integer, and an @ to terminate the program (Cubix has never even heard of "errors"). This gives us 3 chars to play around with to generate the most outputs. Furthermore, because of the way Cubix arranges code on a cube, the first char will be useless unless one of the others is a directional char.

The most efficient way I have found to generate multiple numbers is to use " to push a string of char-codes to the stack. With careful rearrangement, we can fit several chars in the last spot and simply output their char-codes. By using ) to increment the top item, we can create extra outputs from several of these arrangements.

There are two basic program types in use here. The first is this:

"2)O@

which expands to

  "
2 ) O @
  .

The resulting program pushes 2 to the stack, increments it with ), outputs with O, and terminates with @.

The second is this:

2")O@

which expands to

  2
" ) O @
  .

The resulting program pushes the char-codes of ), O, and @, increments the last one with ), outputs with O, and terminates with @.

\$\endgroup\$
3
\$\begingroup\$

><>, 6 numbers

Gained 2 numbers thanks to Teal Pelican

1ln";

Produces the unique numbers [1, 4, 5, 49, 59, 108]

We need n to print a number.
We need ; to terminate.

That leaves us only 3 chars to work with.

A few different combinations of value & operator together with " confirmed to produce 6 unique values, but I haven't found anything better than that.

\$\endgroup\$
  • \$\begingroup\$ I've been trying to work this out but doesn't this only produce 4 numbers? as the range is 1-120 not 0-120? \$\endgroup\$ – Teal pelican Dec 9 '16 at 16:00
  • \$\begingroup\$ @Tealpelican: Correct. I realized this on the way home from work and was just about to fix it. \$\endgroup\$ – Emigna Dec 9 '16 at 16:14
  • \$\begingroup\$ I've had a little look into some more fish programs like the quines and hello world etc and had an idea. Something using the characters like this; 1n;+" would generate 6+ from a quick calculation (using the loop feature and strings to our advantage) - might be worth checking with different values for 1 and operations. \$\endgroup\$ – Teal pelican Dec 9 '16 at 16:24
  • \$\begingroup\$ @Tealpelican: That's a good idea. \$\endgroup\$ – Emigna Dec 9 '16 at 16:27
3
\$\begingroup\$

Groovy, 10 Numbers

Man JVM solutions are BAD for this... Who knew?

1200+

Results in:

[3, 10, 12, 17, 21, 30, 66, 80, 102, 120]

Wait, what? How the hell does it make 17 you ask?

20+10 is 30.
0120+ is invalid.
2+001 is 3.
201+0 is 201.
2+100 is 102.
0+012 is 10.
21+00 is 21.
02+01 is 3.
0210+ is invalid.
10+20 is 30.
200+1 is 201.
0+210 is 210.
1200+ is invalid.
0201+ is invalid.
+0021 is 17.
1+002 is 3.
210+0 is 210.
100+2 is 102.
010+2 is 10.
00+12 is 12.
20+01 is 21.
01+20 is 21.
0+120 is 120.
+0120 is 80.
0+021 is 17.
+1020 is 1020.
0012+ is invalid.
02+10 is 12.
102+0 is 102.
012+0 is 10.
+2100 is 2100.
12+00 is 12.
00+21 is 21.
+2001 is 2001.
+0210 is 136.
+1200 is 1200.
1020+ is invalid.
0102+ is invalid.
2001+ is invalid.
001+2 is 3.
+0012 is 10.
2+010 is 10.
0021+ is invalid.
10+02 is 12.
2100+ is invalid.
+0201 is 129.
2010+ is invalid.
020+1 is 17.
1002+ is invalid.
+2010 is 2010.
1+020 is 17.
1+200 is 201.
01+02 is 3.
+1002 is 1002.
120+0 is 120.
0+102 is 102.
+0102 is 66.
002+1 is 3.
0+201 is 201.
021+0 is 17.

Trade secret, in Groovy/Java integers preceded with a 0 are octals. Code I used for testing Groovy answers incase someone wants to beat me:

("1200+" as List).permutations().collect{
    it.join()
}.collect {
    print "$it is "
    x=-1;
    try {
        x=Eval.me(it);
        println "$x."
    } catch(Exception e) {
        println "invalid."
    }
    x<=120?x:-1;
}.unique().sort();​
\$\endgroup\$
  • \$\begingroup\$ I guess the same answer would also work for Java. \$\endgroup\$ – Paŭlo Ebermann Dec 11 '16 at 13:53
3
\$\begingroup\$

MATL, 15 numbers

0123%

% is the comment operator, so it will "cut" in all possible places once, helping to create all possible combinations of the given digits and subsets of them:

1
2
3
10
12
13
20
21
23
30
31
32
102
103
120
\$\endgroup\$
3
\$\begingroup\$

J , 16 Numbers

1234]

Nothing fancy, just tested 1234 with all the 1-character verbs that were reasonable. ] selects its right argument.

The unique numbers produced are

0 4 3 34 43 2 24 42 23 32 234 243 324 342 423 432 1 14 41 13 31 134 143 314 341 413 431 12 21 124 142 214 241 412 421 123 132 213 231 312 321 1234 1243 1324 1342 1423 1432 2134 2143 2314 2341 2413 2431 3124 3142 3214 3241 3412 3421 4123 4132 4213 4231 4312 4321

of which 16:

4 3 34 43 2 24 42 23 32 1 14 41 13 31 12 21

Are in the range [1,120].

Tested with

# (#~e.&(>:i.120)) ~. (". :: 0:)"1 (A.~ i.@!@#) '1234]'
\$\endgroup\$
3
\$\begingroup\$

Japt, 41 numbers

Pretty much just trial and error so there may be a better solution. Uses integers 3 & 4 and the Japt shortcuts for squaring, adding 1 & multiplying by 2. All 120 programmes output an integer >0 but only 78 are <=120 and only 41 of those are unique.

34²ÄÑ

Generates the numbers:

1,3,4,5,6,7,8,9,13,14,17,20,21,26,27,29,30,31,32,33,34,35,36,37,38,39,42,43,44,45,47,56,59,68,69,72,73,86,87,92,93

View the list of numbers or the collection of valid programmes


Explanation

A few things to note about Japt that are relevant here are:

  1. If a programme doesn't start with (in this case) one of the digits then the first input variable U, which defaults to 0, is automatically inserted at the beginning,
  2. If either or both of the digits immediately follow one of the shortcuts for a mathematical operation then they are appended to it (e.g. 3Ä4 = 3+14 = 17 and, similarly, 4Ѳ = 4*2**2 = 16), and,
  3. If one of the digits immediately follows the ² then the ² and everything before it are, essentially, ignored.

Explanations for a few of the programmes (producing 1, 3, 37 and 93, respectively):

²Ñ34Ä  :Square 0, multiply by 234 and add 1
4ÄѲ3  :Add 1 multiplied by 2 squared to 4, ignore that and return the 3
3²Ä4Ñ  :Square 3 and add 14 multiplied by 2
4Ñ3IJ  :Multiply 4 by 23 and add 1 squared
\$\endgroup\$
2
\$\begingroup\$

Befunge, 11 numbers

Befunge is a bit limited because it only supports single digit literals. So the best I could come up with was 11 numbers, assuming the calculation must leave us with one and only one number on the stack.

Best characters: 358*%

Generated numbers: (just one example of each)

58*3% => 1
358*% => 3
38*5% => 4
538*% => 5
35*8% => 7
835*% => 8
385%* => 9
583%* => 10
358%* => 15
53%8* => 16
35%8* => 24
\$\endgroup\$
2
\$\begingroup\$

Python, 16 numbers

1234#

Uses # to comment out all unnecessary numbers.

\$\endgroup\$
2
\$\begingroup\$

dc, 19 numbers

*3zO+

Output is on top of stack, and errors (including stack underflow) are ignored. The valid permutations are:

+O3*z:   1
+O*3z:   2
+Oz3*:   3
O*z3+:   4
O*3z+:   5
+O3z*:   6
+z3*O:  10
3*zO+:  11
3*Oz+:  12
Oz3*+:  13
O3z*+:  16
+3Oz*:  20
3Oz*+:  23
+zO3*:  30
O3*z+:  31
Oz+3*:  33
3Oz+*:  36
Oz3+*:  40
O3z+*:  50
TOTAL COUNT = 19 numbers

Here's the Python program I used to show those results:

#!/usr/bin/python

import sys
import itertools
import subprocess

if len(sys.argv[1]) != 5:
    print("Invalid input")
    sys.exit(1)

devnull = open("/dev/null", 'w');

r = dict()
for s in itertools.permutations(sys.argv[1]):
    p = "".join(s)
    try:
        e = (subprocess.check_output(['dc', '-e', p, '-e', 'p'], stderr=devnull))
        e = int(e)
        if 0 < e <= 120:
            r[e] = p
    except e:
        pass

for i in sorted(r):
    print("%5s: %3d" % (r[i], i))

print("TOTAL COUNT = %d numbers" % len(r))

Two other strings which give the same score of 19 are 32d+* and *4zO+.

\$\endgroup\$
2
\$\begingroup\$

Smalltalk, 26 numbers

1235r

Explanation: 12r35 is a notation for using radix 12, and is thus 3*12+5.
This can be verified in Squeak:

((Array streamContents: [:s |
    '1235r'  permutationsDo: [:each | 
        | eval |
        eval := [Compiler evaluate: each] ifError: [nil].
        (eval isInteger and: [eval >=1 and: [eval <= 120]]) ifTrue: [s nextPut: each copy -> eval]]])
  collect: #value as: Set) sorted

gives:

#(1 2 3 5 28 31 33 37 38 41 42 47 55 58 63 66 67 68 71 76 82 86 105 107 108 116)

If we replace last line with:

    sorted: #value ascending)

we then get the expressions:

'235r1' -> 1
'253r1' -> 1
'325r1' -> 1
'352r1' -> 1
'523r1' -> 1
'532r1' -> 1
'135r2' -> 2
'153r2' -> 2
'315r2' -> 2
'351r2' -> 2
'531r2' -> 2
'513r2' -> 2
'125r3' -> 3
'152r3' -> 3
'215r3' -> 3
'251r3' -> 3
'521r3' -> 3
'512r3' -> 3
'123r5' -> 5
'132r5' -> 5
'213r5' -> 5
'231r5' -> 5
'321r5' -> 5
'312r5' -> 5
'23r15' -> 28
'25r13' -> 28
'13r25' -> 31
'15r23' -> 33
'32r15' -> 37
'35r12' -> 37
'5r123' -> 38
'12r35' -> 41
'5r132' -> 42
'15r32' -> 47
'52r13' -> 55
'53r12' -> 55
'5r213' -> 58
'12r53' -> 63
'5r231' -> 66
'13r52' -> 67
'31r25' -> 67
'21r35' -> 68
'35r21' -> 71
'25r31' -> 76
'5r312' -> 82
'5r321' -> 86
'51r23' -> 105
'53r21' -> 107
'21r53' -> 108
'23r51' -> 116

I wanted to cheat and define a method r in Integer as

Integer>>r
    ^self \\ 120 + 1

Unfortunately, the compiler chops on 1235r because it recognizes an unfinished number with radix rather than a message r sent to 1235...
I could easily change the compiler too, but it's a bit too much of a cheat to my taste.

\$\endgroup\$
1
\$\begingroup\$

Mathematica, 16 numbers

;1234

Not very interesting, but I can't seem to find anything better using arithmetic. The only thing that might work is using ! for factorial or double factorial, but this is so prone to generating massive numbers that it's impossible to brute force.

The 16 numbers (in range) that can be generated from the above 5 characters are:

1, 2, 3, 4, 12, 13, 14, 21, 23, 24, 31, 32, 34, 41, 42, 43
\$\endgroup\$
  • \$\begingroup\$ Why not ;6789 ? \$\endgroup\$ – David G. Stork Apr 10 at 3:49
1
\$\begingroup\$

Runic Enchantments, 19 numbers

234p@

Essentially 3 literals, the pow operator, and a "print the entire stack and terminate" command. 234p@ prints 812 (3^4 conxatenated with a 2). Full permutation list, note that @ has been replaced by ak@ in order to generate a newline between each result and a > has been added to insure that each line executes independently. Note also that the outputs are not in the same order as the programs that generated them (as some programs may terminate more quickly).

Many permutations print nothing (eg. @234p or p234@), but 19 do result in output within the allowable range.

Numbers possible (and one possible program that results in it; . indicates that those positions may be any of the remaining characters as it isn't executed):

2@...        2
3@...        3
4@...        4
23p@.        8
32p@.        9
42p@.       16
32@..       23
42@..       24
23@..       32
43@..       34
24@..       42
34@..       43
23p4@       48
32p4@       49
43p@.       64
34p@.       81
423p@       84
432p@       94
\$\endgroup\$
1
\$\begingroup\$

TI-BASIC, 12 numbers

23+4!

There is most likely a better combination, but I wasn't able to find it.

All \$24\$ valid permutations are as follows:

23+4!   -> 47
24+3!   -> 30
2+4!3   -> 74
2+3!4   -> 26
2!4+3   -> 11
2!+43   -> 45
2!+34   -> 36
2!3+4   -> 10
32+4!   -> 56
34+2!   -> 36
3+4!2   -> 51
3+2!4   -> 11
3!4+2   -> 26
3!+42   -> 48
3!+24   -> 30
3!2+4   -> 16
43+2!   -> 45
42+3!   -> 48
4+2!3   -> 10
4+3!2   -> 16
4!2+3   -> 51
4!+23   -> 47
4!+32   -> 56
4!3+2   -> 74

Of which there are \$12\$ unique values:

\$10,11,16,26,30,36,45,47,48,51,56,74\$

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.