7
\$\begingroup\$

(Previously on "Print the __ without using __" ... this one and this one)

The game of Hearts has a popular scoring variant called "Shooting the Moon," whereby instead of trying to not acquire penalty cards (and thus penalty points), as is the usual gameplay strategy, if you acquire all of the penalty cards you actually score the best that round. We're going to apply that same logic to some code golf.

The ASCII printable characters (plus space) are, in order

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

Let's divide these into three groups:

Alphanumeric:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Symbolic (or non-alphanumeric)

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

and the space character.

Your task is to use the alphanumeric characters to print the symbolic characters (in any order), with the following restrictions:

  • The program/function should take no input and output to STDOUT (or equivalent).
  • You can use a symbolic character in your source code for a penalty of +5 per unique character.
  • Using the same character more than once does not increase your penalty (e.g., you can use [ 25 times and only get one +5 penalty)
  • Whitespace (including tabs and newlines) in the output or the source code is completely optional. Leading, trailing, inline - no penalties or bonuses. They still count for bytes in source code as usual.
  • If you manage to use all 32 symbolic characters in your code, you get a bonus of -100 points for Shooting the Moon instead of any penalties.
  • If you manage to use all 32 symbolic and all 62 alphanumeric characters in your code, you instead get a bonus of -250 points for Shooting the Sun instead of any penalties.
  • Characters inside literal strings, literal characters, or comments do not count for the bonus or the penalty. (E.g., a Foo program of something like "!#$%..." would be allowed, but would not get the bonus or penalty points for the characters inside the literal).
  • Literal string or comment delimiters do count, however, so something like // !#$*... would count the initial / for penalty/bonus calculations.
  • Yes, this rules out languages like Whitespace or the like, where everything not whitespace is treated as a comment. Bummer.
  • Scoring is bytes of code + penalty(ies) + bonus(es), lowest score wins. Negative scores are possible.

Example scores:

50 bytes code + (5 unique symbolic characters)*5 penalty each = 75 points

200 bytes code + (32 unique symbolic characters)*0 penalty each + (-250 bonus for shooting the sun) = -50 points

\$\endgroup\$
  • 2
    \$\begingroup\$ According to my calculations, there are 62 alphanumeric characters 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz and 33 non-alphanumeric !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ (note the space at the end). Is this correct? \$\endgroup\$ – ETHproductions Sep 28 '15 at 16:13
  • \$\begingroup\$ What about no-ops and unexecuted code? \$\endgroup\$ – Dennis Sep 28 '15 at 16:24
  • \$\begingroup\$ @Dennis As I told Kevin W, "Does it compile/run/execute/whatever? If yes, totally legit. I fully expected flavors of reflection, quines reading the source code, etc., to try and work around the restrictions, and if, in this instance, it means gobbledy-gook code that could be reached but isn't, works for me." ... I didn't explicitly call this out in the question, as I didn't want to overtly suggest that as the only method of doing this. \$\endgroup\$ – AdmBorkBork Sep 28 '15 at 16:26
  • \$\begingroup\$ Does the output have to consist only of the symbolic characters? \$\endgroup\$ – Luke Sep 28 '15 at 17:20
  • 1
    \$\begingroup\$ Can we output duplicates? \$\endgroup\$ – slebetman Sep 29 '15 at 3:50

14 Answers 14

13
\$\begingroup\$

GolfScript, -153

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

Prints

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

Score:

  • 97 bytes of source code: +97
  • Shooting the Sun: -250

Try it online.

How it works

Since the code block (lambda, anonymous function)

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

does not contain any syntax errors, it will be pushed on the stack and printed verbatim if left on it. The linefeed is required to end the comment that # started.

Finally, ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 is an undefined token; it does nothing.

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

C++, 310

Well, I started this without realizing that @ and backticks are totally disallowed in C++ source. Posting it even though it's a very poor entry as it stands, in case anybody knows a way out. Is there a compiler that would allow these characters in symbol names?

#include<IOSTREAM>
int main(int bgjkpqvwxyzBCDFGHJKLNPQUVWXYZ$){\
for(char _='!';_<127;++_){_==48?_=58:_==65||_==98-1.?_+=26:!~_^_&_*_%3,""[0];std::cout<<_;}}//
  • 160 bytes
  • 5 * 30 unique symbolic characters = 150 point penalty

Edit: -90

Leaving the above because it's a little more interesting than the following, which uses an unused #define to sneak in the missing symbols.

#include<IOSTREAM>
#define bgjkpqvwxyzBCDFGHJKLNPQUVWXYZ !"#$%&'*,-./@[\]^`~
int main(){for(char _=33;_<127;++_){_==48?_=58:_==65||_==97?_+=26:_;std::cout<<_;}}
  • 160 bytes
  • Shooting the sun, -250 points
\$\endgroup\$
  • \$\begingroup\$ Ooof. I'm not aware of a compiler that allows backtick. Have a +1, instead. \$\endgroup\$ – AdmBorkBork Sep 28 '15 at 20:43
  • \$\begingroup\$ +1 much appreciated! It was still fun even though it crashed and burned before making it to the moon. \$\endgroup\$ – Luke Sep 28 '15 at 20:44
  • 1
    \$\begingroup\$ GCC doesn't mind a #define with backtick in the definition. But it doesn't like the upper-case IOSTREAM. \$\endgroup\$ – Peter Taylor Sep 28 '15 at 22:09
  • \$\begingroup\$ @PeterTaylor, not even on a Windows platform? \$\endgroup\$ – kay Sep 29 '15 at 11:38
  • \$\begingroup\$ Didn't even think about #define. If that counts I can rethink everything here. \$\endgroup\$ – Luke Sep 29 '15 at 12:31
9
\$\begingroup\$

CJam, -66

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

Prints every symbol exactly once, without any extraneous whitespace.

Score:

  • 34 bytes of source code: +34
  • Shooting the Moon: -100

Try it online.

How it works

Since the code block (lambda, anonymous function) {'"#$%&()*.+,-/:!;<=>?@[\]^_`|~} does not contain any syntax errors, it will be pushed on the stack and printed verbatim if left on it.

Since " only appears in the character literal '", we also push an emoty string as "", which won't affect the output.

\$\endgroup\$
  • 1
    \$\begingroup\$ Doesn't that count as a string literal? \$\endgroup\$ – OrangeDog Sep 29 '15 at 12:26
  • \$\begingroup\$ The last two bytes are a string literal. The rest in a block, which is CJam's closest equivalent to a lambda or anonymous function. \$\endgroup\$ – Dennis Sep 29 '15 at 15:45
5
\$\begingroup\$

Ruby, -148

p %w{!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ 123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnoqrstuvxyz}[0]

Results in:

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

Produces an array, takes the special characters and inspects them.

102 (bytes) + 0 (penalty) - 250 (shot the sun) = -148 points

\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! Pretty dang slick answer. \$\endgroup\$ – AdmBorkBork Sep 28 '15 at 20:59
  • 1
    \$\begingroup\$ Since p wraps the output of a string in quotes, you can leave the " out of your code to save a byte. In fact, since it also escapes various other characters, you can leave out `` as well. \$\endgroup\$ – iamnotmaynard Sep 28 '15 at 21:19
  • \$\begingroup\$ @iamnotmaynard not if I want to use all the special characters inside my code :/ I was just thinking about that. Leaving out the " or \ prevents me from using all the specials inside the code and shooting the sun. \$\endgroup\$ – PotatoOmeletteSandwich Sep 28 '15 at 21:21
  • \$\begingroup\$ Oh yeah... of course. That's the whole point, isn't it. \$\endgroup\$ – iamnotmaynard Sep 28 '15 at 21:28
  • 7
    \$\begingroup\$ Hm, I'd argue that %w{...} is still a type of string literal and "Characters inside literal strings, literal characters, or comments do not count for the bonus or the penalty." \$\endgroup\$ – Martin Ender Sep 28 '15 at 21:41
4
\$\begingroup\$

Befunge-93, -125

Since having code that is never reached is OK, this is deemed an allowed answer.

p>g1g:,"}"`#@_g1+00p           #
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
23456789ABCDEFGHIJKLMNOPQRSTUVWX
YZabcdefhijklmnoqrstuvwxyz

it's 125 - 250, so -125. I tried to avoid reading the characters in string mode as that seems to violate the rules, but I don't see any violation here. I just read what every character is in the 1st row until it's ascii value is >125. I had to change it a bit to have it run properly in the interpreter

\$\endgroup\$
  • \$\begingroup\$ Does the -151 version compile/run/execute/whatever? If yes, totally legit. I fully expected flavors of reflection, quines reading the source code, etc., to try and work around the restrictions, and if, in this instance, it means gobbledy-gook code that could be reached but isn't, works for me. \$\endgroup\$ – AdmBorkBork Sep 28 '15 at 16:24
3
\$\begingroup\$

STATA, -120

#d 01256789ABCDEFGHIJKLMNOPQRSTUVWXYZbefgjklmnopqstuvwxyz`!$%&*+,-./:<=>?@[\]^_{|}~'
di "'`!#$%&()*+,-./:;<=>?@[\]^_{|}~"char(34);

Abuses the standard STATA interpreter. The #d command (short for #delimit) changes the delimiter to ; unless whatever follows the command is "cr". But the spec only specifies what happens when what follows is ";" or "cr".

Score:

  • 130 bytes of source code: +130

  • Shooting the Sun: -250

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

Beam, -34 -47

Now that I've fixed my initial misunderstanding, now to try and get some points back:)

'''''>`+++++++)--'''''>`@+@+@+vabcdefghi
/+++)++@+@+@+@+@+@\012^   _?Ps)klmopqrtw
+3456789ABv+@+@`<'''++++++++++<!"#$%&*,.
|CDEFGIJKL(     ^Z\''''>`+++++)+\=@[]{}~
\+`<'''''@<MNOQRSTUVWXYH@+@+@+@+/:;xyzj

Using the same logic for scoring as the Befunge-93 answer. 216 Bytes - 250 Shooting the Sun. Now to see if I can compact it a bit more and improve my logic.

Brief explanation:
enter image description here

var ITERS_PER_SEC = 100000;
var TIMEOUT_SECS = 50;
var ERROR_INTERRUPT = "Interrupted by user";
var ERROR_TIMEOUT = "Maximum iterations exceeded";
var ERROR_LOSTINSPACE = "Beam is lost in space";
var code, store, beam, ip_x, ip_y, dir, input_ptr, mem;
var input, timeout, width, iterations, running;
function clear_output() {
document.getElementById("output").value = "";
document.getElementById("stderr").innerHTML = "";
}
function stop() {
running = false;
document.getElementById("run").disabled = false;
document.getElementById("stop").disabled = true;
document.getElementById("clear").disabled = false;
document.getElementById("timeout").disabled = false;
}
function interrupt() {
error(ERROR_INTERRUPT);
}
function error(msg) {
document.getElementById("stderr").innerHTML = msg;
stop();
}
function run() {
clear_output();
document.getElementById("run").disabled = true;
document.getElementById("stop").disabled = false;
document.getElementById("clear").disabled = true;
document.getElementById("input").disabled = false;
document.getElementById("timeout").disabled = false;
code = document.getElementById("code").value;
input = document.getElementById("input").value;
timeout = document.getElementById("timeout").checked;   	
code = code.split("\n");
width = 0;
for (var i = 0; i < code.length; ++i){
	if (code[i].length > width){ 
		width = code[i].length;
	}
}
console.log(code);
console.log(width);   	
running = true;
dir = 0;
ip_x = 0;
ip_y = 0;
input_ptr = 0;
beam = 0;
store = 0;
mem = [];   	
input = input.split("").map(function (s) {
		return s.charCodeAt(0);
	});	
iterations = 0;
beam_iter();
}
function beam_iter() {
while (running) {
	var inst; 
	try {
		inst = code[ip_y][ip_x];
	}
	catch(err) {
		inst = "";
	}
	switch (inst) {
		case ">":
			dir = 0;
			break;
		case "<":
			dir = 1;
			break;
		case "^":
			dir = 2;
			break;
		case "v":
			dir = 3;
			break;
		case "+":
			++beam;
			break;
		case "-":
			--beam;
			break;
		case "@":
			document.getElementById("output").value += String.fromCharCode(beam);
			break;
		case ":":
			document.getElementById("output").value += beam;
			break;
		case "/":
			dir ^= 2;
			break;
		case "\\":
			dir ^= 3;
			break;
		case "!":
			if (beam != 0) {
				dir ^= 1;
			}
			break;
		case "?":
			if (beam == 0) {
				dir ^= 1;
			}
			break;
		case "_":
			switch (dir) {
			case 2:
				dir = 3;
				break;
			case 3:
				dir = 2;
				break;
			}
			break;
		case "|":
			switch (dir) {
			case 0:
				dir = 1;
				break;
			case 1:
				dir = 0;
				break;
			}
			break;
		case "H":
			stop();
			break;
		case "S":
			store = beam;
			break;
		case "L":
			beam = store;
			break;
		case "s":
			mem[beam] = store;
			break;
		case "g":
			store = mem[beam];
			break;
		case "P":
			mem[store] = beam;
			break;
		case "p":
			beam = mem[store];
			break;
		case "u":
			if (beam != store) {
				dir = 2;
			}
			break;
		case "n":
			if (beam != store) {
				dir = 3;
			}
			break;
		case "`":
			--store;
			break;
		case "'":
			++store;
			break;
		case ")":
			if (store != 0) {
				dir = 1;
			}
			break;
		case "(":
			if (store != 0) {
				dir = 0;
			}
			break;
		case "r":
			if (input_ptr >= input.length) {
				beam = 0;
			} else {
				beam = input[input_ptr];
				++input_ptr;
			}
			break;
		}
	// Move instruction pointer
	switch (dir) {
		case 0:
			ip_x++;
			break;
		case 1:
			ip_x--;
			break;
		case 2:
			ip_y--;
			break;
		case 3:
			ip_y++;
			break;
	}
	if (running && (ip_x < 0 || ip_y < 0 || ip_x >= width || ip_y >= code.length)) {
		error(ERROR_LOSTINSPACE);
	}
	++iterations;
	if (iterations > ITERS_PER_SEC * TIMEOUT_SECS) {
		error(ERROR_TIMEOUT);
	}
}
}
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;">Code:<br><textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">'''''>`+++++++)--'''''>`@+@+@+vabcdefghi
/+++)++@+@+@+@+@+@\012^   _?Ps)klmopqrtw
+3456789ABv+@+@`<'''++++++++++<!"#$%&*,.
|CDEFGIJKL(     ^Z\''''>`+++++)+\=@[]{}~
\+`<'''''@<MNOQRSTUVWXYH@+@+@+@+/:;xyzj
</textarea><p>Timeout:<input id="timeout" type="checkbox" checked="checked">&nbsp;<br><br><input id="run" type="button" value="Run" onclick="run()"><input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="disabled"><input id="clear" type="button" value="Clear" onclick="clear_output()">&nbsp; <span id="stderr" style="color:red"></span></p>Output:<br><textarea id="output" rows="6" style="overflow:scroll;width:90%;">        </textarea><br>Input:<br><textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;"></textarea></div>

\$\endgroup\$
  • \$\begingroup\$ Running this in your provided snippet, I get lots of extraneous characters in addition to just the symbolic characters. \$\endgroup\$ – AdmBorkBork Sep 28 '15 at 21:37
  • \$\begingroup\$ @TimmyD Whoops sorry, misread the question. Will delete and fix. \$\endgroup\$ – MickyT Sep 28 '15 at 21:39
  • \$\begingroup\$ @TimmyD Think I have got it right this time \$\endgroup\$ – MickyT Sep 28 '15 at 23:42
  • \$\begingroup\$ Awesome! But for me, it prints !"# and then errors out with Maximum iterations exceeded. \$\endgroup\$ – ETHproductions Sep 30 '15 at 13:35
  • \$\begingroup\$ @ETHproductions, Thanks. There was a bug in the snippet that caused the _ and | to reflect the wrong way. I had fixed up the snippet else where, but forgot to do this one. \$\endgroup\$ – MickyT Sep 30 '15 at 17:54
2
\$\begingroup\$

PHP, 154 - 250 = -96

Requires error reporting to be off. I hope I'm not breaking the rules by adding the dead code between $a=33 and ;$a<65.

<?php #
Z:for($a=33,$ABCDEFGHIJKLMNOPQRSTUVWXYdgijklmnqstuvwxyz_=@``.[!-0/~9%8^3|0&0].''."";$a<65;$a++){echo chr($a+10*($a>47)+26*($a>54)+26*($a>60));}\b;
\$\endgroup\$
2
\$\begingroup\$

Tcl, 135-250 = -115

set {123456789ABCDEFGHIJKLMNOPQRSTUVXYZbcdhkmqwyz!"#$%&'()*+,-./:;<=>?@[\]^`|~} 0
puts [join [regexp -inline -all {\W+} [info vars]]]_

Explanation: Create a variable named {123456789ABCDEFGHIJKLMNOPQRSTUVXYZbcdhkmqwyz!"#$%&'()*+,-./:;<=>?@[\]^|~} (basically the entire ASCII sequence minus some alphanumeric characters already in the source) then get the list of all variables in scope (info vars) and use regexp to filter out the non-symbols form the resulting list. I believe a variable name qualifies as something that's not a string literal. This is possible because Tcl allows almost any byte sequence for variable and function names (including symbols and even non-printing characters).

Note: Strictly speaking, it's a string literal, which is why it's quoted in {} (tcl has two ways of quoting strings: {} and ""). But in tcl, everything is a string literal including the entire program. Tcl is a string-based language after all. So I'm interpreting the "string literal" specification as: "string literal" when used as data.

\$\endgroup\$
  • \$\begingroup\$ +1 nice approach using the variable name. And yes, "string literal" is meaning what you've got for your interpretation -- set x="foo" and the like. \$\endgroup\$ – AdmBorkBork Sep 29 '15 at 12:28
2
\$\begingroup\$

Ruby, -126

Nothing in string literals or comments. The output ain't pretty since it's p-ing an array of strings, but it's all there.

p @bdefgjkoqstuvwyz_BCDHJKLMPQSTUWXYZ=[*32..47,*58..64,*91..96,*123..126].map!{|x|x.chr};+-~0?"":(``%nil<$\>''^ARGF/IO&ENV)#

Score:

  • Bytes: +124
  • Shot the sun: -250
\$\endgroup\$
2
\$\begingroup\$

FORTH, -118

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

Forth names are only delimited by whitespace, so the name is just all the shoot the sun characters minus : ." and ;

  • Code: 132
  • Shoot the sun: -250
\$\endgroup\$
1
\$\begingroup\$

Batch, -143 bytes

@echo !"#$%%&'()*+,-./:;<=>?@[\]^_`{|}~
@goto :a
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZbdfijklmnpqrsuvwxyz
:a
  • 107 bytes of source code: +107
  • Shooting the Sun: -250

I didn't think this would beat anyone. After all it's batch!

\$\endgroup\$
  • \$\begingroup\$ Do :012345...z fit the rule? \$\endgroup\$ – l4m2 Jun 7 '18 at 15:42
1
\$\begingroup\$

Haskell, -135

main=putStr$!do{(x,y)<-"!:[{"`zip`"/@`~";[x..y]}
veRbOsE#%&*+/:>?@\^|~_0123456789ABCDFGHIJKLMNPQTUVWXYZcfghjklqw'=0

Score:

  • 115 bytes
  • -250 shooting the sun bonus

After re-reading I think dead code was ok so this version is shorter. The main function is borrowed from @xnor's answer to this question. It basically takes the endpoints and zips them pairwise to transforms them into ranges, being equal to

putStr(concatMap (\(x,y)->[x..y]) [('!','/'),(':','@'),('[','`'),('{','~')])

The other line just defines an unused operator #%&*+/:>?@\^|~ with long parameter names.

(),;[]`{}"'_ are the special characters that can't be used in operator names but _ and ' can be used variable names. The others are all used in the first line.

Try it online!

\$\endgroup\$
0
\$\begingroup\$

MS-SQL, 133 bytes - 250 bonus = -117

create TABLE[!"#$%&'()*+,-./:;<=>?@[\]]^_`{|}~](DdfGgHiJkPpQqUuVvWXYZz0123456789 xml)
SELECT NAME FROM sys.objects where name LIKE'!%'

Uses a system view specific to MS SQL, so not guaranteed to work on other platforms.

Creates a table with a name consisting of the 32 symbols in order. This is normally invalid for a SQL identifier, but we can make it work by surrounding it by brackets. This name is then retrieved from system view sys.objects (assuming that no other tables start with !).

Alphanumerics not used elsewhere make up the (unused) xml field name.

Make sure to clean up the table when you are done! (not included in score):

DROP TABLE[!"#$%&'()*+,-./:;<=>?@[\]]^_`{|}~]
\$\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.