Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

The title says it all. Your goal is to write a program that forms a w×h rectangle of characters that can be rotated and re-run to output the number of 90° Counter-Clockwise (CCW) rotations that have been done.

For example, if the 3×2 program

abc
def

solved the problem, it would initially output 0, and successive rotations of 90° CCW

cf    fed    da
be    cba    eb
ad           fc

would output 1, 2, and 3 respectively.

Using comments makes this a trivial task is most languages. In Ruby for example, it can be done in a 7×7 rectangle:

###p###
### ###
###1###
p 0#2 p
###3###
### ###
###p###

The challenge is to do this without any sort of comments.

Scoring

Your score is w*h, the area of your rectangle. Newlines are excluded. In other words, code-golf, newlines not counted.

The score for the Ruby example is 49 (though of course it is invalid since it has comments).

Notes

  • Your code must really be rectangular with no missing characters at the end of lines.
  • If you wish you may output other legal "mod 90°" values instead of 0 1 2 3. So 8 is fine instead of 0, and -1 is fine instead of 3, etc.
  • The output may go to the console or into a file.
  • Standard loopholes apply.

I hope this, my first question, really intrigues some people. Enjoy!

share|improve this question
    
To be more specific about what a comment is, is a comment any unevaluated code? Unparsed code? –  isaacg yesterday
    
I mean that none of your language's traditional "comment characters" should appear in any of the 4 rotated versions. So for C++, two slashes next to each other should never appear, though one may be used alone. Likewise with /*. I hope that clarifies it. –  Calvin's Hobbies yesterday
    
What about languages that do not have comment characters? –  isaacg yesterday
    
So code like echo 0;exit;e in bash is allowed? –  user23013 yesterday
    
If there is no way to comment then you needn't worry. @user23013 That bash is fine. –  Calvin's Hobbies yesterday
show 4 more comments

8 Answers

Ruby, 9×8 (72)

  3 ;p  
 p|p =p 
p || p=p
 ;p|p|p;
;p=p ||0
 ;p   p;
2 ||p =p
  00; p 
     1  

A bit longer than the other solution, but at least this solution doesn't depend on any implicit printing or rule abuse. For all four rotations, the full code is parsed and other than some short-circuiting, all of it is executed. Surprisingly, there's absolutely no symmetry in the code

This solution relies on the fact that it's still possible to call the p function (which is used to print the numbers) even if a variable with the same name has already been defined. For example, something like p p calls the function p with the variable p as argument (thus, printing the value of p).

Explanation for some of the common expressions used in the code:

  • p: As mentioned above, this is either a function call or a variable. When the variable is not defined, this calls the function p without arguments, which does nothing and returns nil.
  • p p: Prints the variable p.
  • p|x: When p is the function, this is identical to nil|x, which returns true/false depending on the value of x. If p is an integer, it's bitwise or. Either way, this statement has no side effect.
  • p=p||x: Effectively the same as p||=x (conditional assignment) with the advantage of being syntactically valid and a no-op when reversed.

Symmetric version (9×10 = 90)

    p    

  0 * 0  
  00100  
  0||2* p
p *0||0  
  00300  
  0 * 0  

    p    

This is the shortest symmetric solution (C2 when ignoring the numbers to print) I could come up with.

Test script

Here's a test script to verify the code above (the # at the line ends have been added so that the whitespace doesn't get stripped and are removed before execution):

rotate=->s{s.split($/).map{|i|i.chars.reverse}.transpose.map(&:join).join($/)}

s=<<EOD.gsub(?#,"")
  3 ;p  #
 p|p =p #
p || p=p#
 ;p|p|p;#
;p=p ||0#
 ;p   p;#
2 ||p =p#
  00; p #
     1  #
EOD


puts ">>> 0°"
eval s
puts ">>> 90°"
eval rotate[s]
puts ">>> 180°"
eval rotate[rotate[s]]
puts ">>> 270°"
eval rotate[rotate[rotate[s]]]
share|improve this answer
5  
It may not be the shortest but this is exactly the kind of obfuscated brilliance I was looking for :D –  Calvin's Hobbies 23 hours ago
add comment

Pyth, 9 characters (3x3)

0 1

3 2

In pyth, everything is printed by default, unless it is preceded by a space. Lines after the first line are for user input, and are not evaluated in this program.

Another way to get 9 characters:

"0"
3 1
"2"

Pyth 1.0.5, 4 characters

While recent changes to pyth have made 2 digit numbers harder to generate (A change that I am considering reverting), older versions of Pyth have easy two digit number generation, which, combined with the implicit printing and the fact that all lines but the first are ignored, gives the following solution:

32
41

Prints 32,21,14,43.

share|improve this answer
    
Well, that's just fun. +1 –  TheRare yesterday
    
Shucks, I was hoping it wasn't that easy. You are missing 3 characters on your middle line but I'm guessing that's due to the auto-formatting here. –  Calvin's Hobbies yesterday
    
@Calvin'sHobbies Sorry, I see. It chomped my trailing spaces. –  isaacg yesterday
    
@Quincunx Oh, I missed that part of the scoring. Thanks for the fixes. –  isaacg 23 hours ago
add comment

GolfScript, 4 (2x2)

43
12

Prints 4312 which is 0 (mod 4). The rotations print 3241 (1 mod 4), 2134 (2 mod 4), and 1423 (3 mod 4).

Prompted by:

If you wish you may output other legal "mod 90°" values instead of 0 1 2 3. So 8 is fine instead of 0, and -1 is fine instead of 3, etc.

There are actually many sets of numbers for which this works. I found these with this Python program:

def f(a,b,c,d):
    return int("%i%i%i%i"%(a,b,c,d))
for a in range(10):
    for b in range(10):
        for c in range(10):
            for d in range(10):
                candidate = f(a,b,c,d) % 4 == 0
                candidate &= f(b,d,a,c) % 4 == 1
                candidate &= f(d,c,b,a) % 4 == 2
                candidate &= f(c,a,d,b) % 4 == 3
                if candidate:
                    print("%i, %i, %i, %i"%(a,b,c,d))
share|improve this answer
2  
Very clever. I honestly thought that extra rule was innocuous. –  Calvin's Hobbies 23 hours ago
    
Don't forget to count the newline as a character. –  isaacg 23 hours ago
1  
@Everybody Note that this is not the smallest possible program. A 2x1 is possible, and it is the smallest possible. So get to work! –  Quincunx 23 hours ago
    
An equivalent python program: x=[print("%i, %i, %i, %i"%(a,b,c,d))for a,b,c,d in __import__('itertools').product(*(range(10),)*4)if int("%i%i%i%i"%(a,b,c,d))%4==0and int("%i%i%i%i"%(b,d,a,c))%4==1and int("%i%i%i%i"%(d,c,b,a))% 4==2and int("%i%i%i%i"%(c,a,d,b))%4==3]. One liner ftw! –  Quincunx 22 hours ago
    
@isaacg Your score is w*h, the area of your rectangle. Newlines are excluded. In other words, code-golf, newlines not counted. –  undergroundmonorail 21 hours ago
show 1 more comment

GolfScript, 9 (3x3)

0}1
} }
3}2

Sort of abusing the rules. The } happens to end the program if there is no matching {, and the contents of the stack are printed at program end.

share|improve this answer
    
Don't forget to count the newline as a character. –  isaacg 23 hours ago
    
@isaacg Your score is w*h, the area of your rectangle. Newlines are excluded. In other words, code-golf, newlines not counted. –  undergroundmonorail 21 hours ago
    
I didn't know that } can be unbalanced. Nice trick. –  Peter Taylor 16 hours ago
add comment

BASIC, 64

Won't win, but here it is anyway. (Tested in Chipmunk Basic)

?0:END:?
:::::::1
D:::::::
N::::::E
E::::::N
:::::::D
3:::::::
?:DNE:2?

Note: ? is shorthand for PRINT in various dialects of BASIC. Although there are lots of syntax errors in the code, the END statement in the first line prevents them from being seen by the interpreter.

share|improve this answer
1  
Actually, your scores are 64 and 16, respectively. Newlines don't count. Also, why not split the answer? –  Quincunx 23 hours ago
    
Oh, missed that bit. I would have split the answers if they weren't occupying joint last place. There doesn't seem to be much point otherwise :-) –  squeamish ossifrage 23 hours ago
    
You're not last anymore :-) –  Quincunx 23 hours ago
add comment

Befunge, 16

0.@1
@@@.
.@@@
[email protected]

Explanation: Digits from 0 to 9 push the corresponding number onto the stack, . pops a value from the stack and prints it as an integer, and @ ends the program.

(tested here)

share|improve this answer
add comment

Aheui, 8

바몽희뷸
뷷희몽반

Since Aheui does not have a letter that pushes 1 onto the stack, I decided to print 0, 5, 2, and 3.

Explanation: 바 and 반 push 0 and 2, respectively, onto the stack and moves the cursor right by one character. 뷸 and 뷷 push 5 and 3, respectively, onto the stack and moves the cursor down by two characters. 몽 pops and prints the number in the stack and moves the cursor up by one character. 희 terminates the program.

share|improve this answer
add comment

JavaScript, 4

03
12

When you execute this program (or a rotation of this program) in a javaScript console, only the last line is evaluated and echoed in the console.

So:

12 modulo 4 == 0
01 modulo 4 == 1
30 modulo 4 == 2
23 modulo 4 == 3

Here are all the similar 2x2 programs that work too:

03
12

03
16

03
52

03
56

03
92

03
96

07
12

07
16

07
52

07
56

07
92

07
96

43
12

43
16

43
52

43
56

43
92

43
96

47
12

47
16

47
52

47
56

47
92

47
96

83
12

83
16

83
52

83
56

83
92

83
96

87
12

87
16

87
52

87
56

87
92

87
96

In other terms,

ab
cd

where a is in [0,4,8], b is in [3,7], c is in [1,5,9], and d is in [2,6]

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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