Discussion
· Aug 5

Code Golf: Print every character your program doesn't have

Today we have an unusual code golf: build a program (using only printable ASCII characters, tabs and newlines) that prints out exactly the characters in the printable ASCII space (characters 32 to 126) that don't appear in your program's source code (in any order, however many times you want).

As usual, the goal is to produce the shortest code to do this.

My (admittedly not very good, but does the job!) entry:

Class ascii.ascii {

ClassMethod ascii()
{
    set x="!#$%&'()*+,-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdfghijklmnopqruvwyz{|}~"
}

}

Let's say the characters in the signature:

ClassMethod ascii(){}

do not count for program's source code.

Discussion (22)3
Log in or sign up to continue

Judging by this code, I probably did not fully understand the conditions of the task.
So:

  1. the source code of the method = " i=0,27,0:1:94 %code.Write($c(i+32))
    ", size = 42
  2. the following characters are not found in the source code of the method:
    !"#&'*-/568;<>?@ABCDEFGHIJKLMNOPQRSTUVXYZ[\]^_`abghjklmnpqsuvwxyz{|}~
  3. the method should print the characters from point 2
  4. I did not find it in the task conditions [CodeMode = objectgenerator]

Where did I go wrong?

The problem is, the specification for this task is simple unprecise, and according to my opinion, gives a faulty example. Your exmple code has just a Set command but the task talks about "print out" - hence, I expected to see either a Write "whatever" or at last a Quit "whatever" comand.
Also, if we talk about a method signature, I take in account the number of arguments (maybe their types) only and the return type but never their method keywords, as in the solution from Eduard, hence his solution is not only creative but valid too.
I think, a fair way to mesure the size of a solution is, if you take the size of the routine which will be executed, and that is the INT routine, which is directly (we neglect the possible compiler optimizations, that's the compilers and not the users credit) compiled into a executable. How I got that code (some generator or via a macro or whatever other method) is actually irrelevant.
A very good example for using or not using a method keyword is the "codemode=expression":

/// you save that "Quit " but have to write "codemode=expression"
/// which is not taken in account by the Implementation.Size
ClassMethod Test() [ codemode = expression]
{
 123
}

/// you have to write "Quit " and save the writing of "codemode..."
/// The Implementation.Size counts that "quit "
ClassMethod Test2()
{
 quit 123
}

Whatever you choose, the corresponding INT code is always "quit ..."

So the bottom line is, either you should define all constraints and conditions or accept each end every clever solution.

It shouldn't be invalid because there are no corresponding constraints.

At the beginning, I thought not to participate, because of the problematic specification and example, but now, as I see, I'm not the only one with questions without answers, hence I offer an 38 char solution too (including the hint to compiler flags) and a shorter version with 34 chars, a correkt result but with "a little bit" of side effect.

We need the source code, so the compiler flag for keeping the source must be on. The 38 char version does the job

ClassMethod ascii() [ ProcedureBlock = 0 ]
{
x	n i f i=32:1:126 w:$t(x)'[$c(i) *i
}

The 34-character version does the job too  has a side effect (leaving the variable i with the last value)

ClassMethod ascii() [ ProcedureBlock = 0 ]
{
y	f i=32:1:126 w:$t(y)'[$c(i) *i
}

OK, it seems that I did not understood the challenge! 😂

BUT, the instructions read as:

"...build a program (using only printable ASCII characters, tabs and newlines) that prints out...."

What's your concept of "prints out"?

I understand that the provided sample solution doe not printout anything, but the instructions also says:

"....exactly the characters in the printable ASCII space (characters 32 to 126) that don't appear in your program's source code..."

Again, my concept of source code include...well, all the code, including string constants in the source code, so the provided sample solution does not satisfy the conditions because it contains ALL the printable ASCII space!
Maybe it correct because sing it contains all the  printable ASCII space, it does not prints out anything?!

Yes Enrico, it is my understanding exactly : if your program code (i.e. the lines in the routine generated by the compiler) contains all printable ASCII characters, it should output an empty string. Of course it sounds silly to devise a very clever way to output an empty string, but after all, golf - from a practical point of view - is a silly sport isn't it ? 🤣

There are to valid ways to solve this code golf:

  • Create a program that contains all ASCII characters in the source code (so it does not have to print anything)
  • Create a program which prints ASCII characters not present in a source code

Both approaches are valid, sample solution uses approach 1.

"Print out" is any output the program produces so if you for example add 1/0 at the end it might save you a few characters.

I would like to draw your attention to a number of points:

  • this code will work correctly only when the compilation flag "k" is enabled, otherwise $TEXT will not return anything.

    k - Keep source. When this flag is set, source code of
    generated routines will be kept.

  • this code will not work correctly in Caché, because there the label name will be "zascii", non "ascii"
  • if you look at the generated INT code, you can see the "}" character at the end, which will return $t(ascii+1), which will lead to an incorrect result
    ascii() methodimpl {
     i=32:1:126 w:$t(ascii+1)'[$c(i) *}