5
\$\begingroup\$

Write a program rotates some Cartesian coordinates through an angle about the origin (0.0,0.0). The angle and coordinates will be read from a single line of stdin in the following format:

angle x1,y1 x2,y2 x3,y3 ...

eg.

3.14159265358979 1.0,0.0 0.0,1.0 1.0,1.0 0.0,0.0  

The results should be printed to stdout in the following format:

x1',y1' x2',y2' x3',y3' ...

eg.

-1.0,-3.23108510433268e-15 -3.23108510433268e-15,-1.0 -1.0,-1.0 -0.0,-0.0
\$\endgroup\$
3
  • \$\begingroup\$ Am I allowed a leading space in the output? \$\endgroup\$
    – J B
    Commented Mar 4, 2011 at 20:13
  • \$\begingroup\$ @JB yes that is fine \$\endgroup\$
    – david4dev
    Commented Mar 4, 2011 at 20:41
  • \$\begingroup\$ Can J unary minus signs (_) be used for output? For input? \$\endgroup\$
    – J B
    Commented Mar 5, 2011 at 0:04

6 Answers 6

5
\$\begingroup\$

Perl, 112 80 78

s/\S*//;$c=cos$&;$s=sin$&;s/([^ ,]*),(\S*)/($1*$c-$2*$s).",".($1*$s+$2*$c)/ge

Run on command-line as perl -pe 'code here', p option counted in code size.

For reference, here's my previous approach. But regexes are too damn powerful.

split/[ ,]/,<>;$_='A;Y,print$x*cos($a)-$y*sin$a,",",$x*sin($a)+$y*cos$a,$"whileX';s/[AXY]/\$\l$&=shift\@_/g;eval
\$\endgroup\$
3
\$\begingroup\$

C (124 Characters)

main(){double t,x,y,c,s;scanf("%lf",&t);c=cos(t);s=sin(t);while(~scanf("%lf,%lf",&x,&y))printf("%lf,%lf ",c*x-s*y,s*x+c*y);}
\$\endgroup\$
4
  • \$\begingroup\$ this doesn't compile. \$\endgroup\$
    – david4dev
    Commented Mar 4, 2011 at 14:44
  • \$\begingroup\$ @david4dev wild guess: link with -lm \$\endgroup\$
    – J B
    Commented Mar 4, 2011 at 14:46
  • \$\begingroup\$ @david4dev ideone.com/nuhLz \$\endgroup\$
    – fR0DDY
    Commented Mar 4, 2011 at 14:46
  • \$\begingroup\$ It compiles and runs OK with -lm. \$\endgroup\$
    – david4dev
    Commented Mar 4, 2011 at 14:48
3
\$\begingroup\$

Python (157)

from math import*;f=float
i=raw_input().split();a=f(i[0])
c=cos(a);s=sin(a)
def p((x,y)):print"%f,%f"%(c*x-s*y,s*x+c*y),
for l in i[1:]:p(map(f,l.split(',')))
\$\endgroup\$
2
\$\begingroup\$

J, 58 (with one bug)

c=:charsub
(r.@{.*}.)&.(".@('-_,j'&c :.('j,_-'&c))@stdin)_

Sample run (note I've replaced the origin test case with some negative input, as that was actually a pain to get right with J's representation of negatives):

echo -n '3.14159265358979 1.0,0.0 0.0,1.0 1.0,1.0 -1.0,-1.0' | jconsole rotate.ijs
-1,3.23109e-15 -3.23109e-15,-1 -1,-1 1,1   

There is one family of input that will not render exactly as asked (though calling it wrong would be debatable). Which one exactly is left as an exercise to the reader :-)

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

APL (Dyalog Extended), 51 bytes

x←⎕⋄g←{(¯1 2⍴1↓x)×⍤1⊢⍵○⊃x}⋄∊⍉↑(⊂-/g⌽⍳2)⍪⊂',',¨+/g⍳2

Try it online!

Reduced by a lot with dzaima's help at The APL Orchard. Apparently there's still room to save a few bytes, which I'll be golfing later.

Explanation

x←⎕⋄g←{(¯1 2⍴1↓x)×⍤1⊢⍵○⊃x}⋄∊⍉↑(⊂-/g⌽⍳2)⍪⊂',',¨+/g⍳2
x←⎕                                                 store input as x
   ⋄g←{                  }                          define function g:
                       ⊃x                           first element of x
                     ⍵○                             take sine & cosine of it based on argument
                 ×⍤1⊢                               multiply with each row of
       (¯1 2⍴1↓x)                                   the points reshaped into pairs
                          ⋄                         finally,
                                              +/g⍳2 x sin theta + y cos theta
                                        ⊂',',¨      prepend comma to each
                                       ⍪            joined with
                              (⊂-/g⌽⍳2)             x cos theta - y sin theta
                            ⍉↑                      convert to matrix and transpose
                           ∊                        and enlist the elements                                               
\$\endgroup\$
1
\$\begingroup\$

Wolfram Mathematica, 35 bytes

 RotationTransform@#[[1]]/@#~Drop~1&

OP's test case:

 RotationTransform@#[[1]]/@#~Drop~1&@{3.14159265358979,{1.0,0.0},{0.0,1.0},{1.0,1.0},{0.0,0.0}}

{{-1., 3.23109*10^-15}, {-3.23109*10^-15, -1.}, {-1., -1.}, {0., 0.}}

If we instead use exact values, we can get an exact output:

 RotationTransform@#[[1]]/@#~Drop~1&@{Pi,{1,0},{0,1},{1,1},{0,0}}

{{-1, 0}, {0, -1}, {-1, -1}, {0, 0}}

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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