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:
Classascii.ascii {
ClassMethodascii()
{
setx="!#$%&'()*+,-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdfghijklmnopqruvwyz{|}~"
}
}Let's say the characters in the signature:
ClassMethodascii(){}do not count for program's source code.
Comments
42 characters so far.
42 characters, but I don't like that code in a class....it's like cheating
43 characters, without feeling cheating 馃槀
it's like cheating
Reflective programming is not cheating!
Alas, I'm well behind : 54 characters (according to %Dictionary.MethodDefinition Implementation.Size).
Please, enlighten me 馃槄
ClassMethodascii() [ CodeMode = objectgenerator ]
{
f i=0,83,0,33,29,2,3:1:94,2d%code.Write($c(i+32))
}Well, in that case you might as well do this (down to 41):
ClassMethodascii() [ CodeMode = objectgenerator ]
{
f i=0,27,0:1:94d%code.Write($c(i+32))
}ah, yes, thanks, comments are indeed part of the source code 馃榿
Judging by this code, I probably did not fully understand the conditions of the task. So:
- the source code of the method = "聽f聽i=0,27,0:1:94聽d聽%code.Write($c(i+32)) ", size = 42
- the following characters are not found in the source code of the method:
!"#&'*-/568;<>?@ABCDEFGHIJKLMNOPQRSTUVXYZ[\]^_`abghjklmnpqsuvwxyz{|}~ - the method should print the characters from point 2
- I did not find it in the task conditions [CodeMode = objectgenerator]
I agree that
[ CodeMode = objectgenerator ]is certainly outside of this code golf conditions (method signature should not be changed), but it's still a creative example.
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.SizeClassMethod Test() [ codemode = expression]
{
123
}
/// you have to write "Quit " and save the writing of "codemode..."/// The Implementation.Size counts that "quit "ClassMethod Test2()
{
quit123
}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.
38 characters for me. :)
(but the solution is dependent on compilation flags - not sure if that invalidates it)
I am very interested how compilation flags help you with this.
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.
This is old enough to post a spoiler now - I got down to 35 with the *i trick; what's the 34-character solution?
Spoiler
Classascii.ascii
{
ClassMethodascii()
{
f i=32:1:126{w:$t(+6)'[$c(i) *i}
}
}
We need the source code, so the compiler flag for keeping the source must be on. The 38 char version does the job
ClassMethodascii() [ ProcedureBlock = 0 ]
{
x n i f i=32:1:126w:$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)
ClassMethodascii() [ ProcedureBlock = 0 ]
{
y f i=32:1:126w:$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.
Using the second approach : edited down to 39 characters
ClassMethodascii()
{
f i=32:1:126w:$t(ascii+1)'[$c(i) *i
}*iis a great idea.
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 { 聽f聽i=32:1:126聽w:$t(ascii+1)'[$c(i)聽*i聽}
size = 59 (does not depend on the "k" flag)
ClassMethod ascii()
{
f i=32:1:126 w:^oddDEF($this,"m","ascii",30,1)'[$c(i) *i
}size = 76 (+without the "for" loop)
ClassMethod ascii()
{
w $tr(##class(%Net.SMTP).#PrintableAscii,^oddDEF($this,"m","ascii",30,1))
}