I need to reduce the length of this code in Python 3 as much as possible (even if it will be less readable):

a,b,x,y=[int(i) for i in input().split()]
while 1: 
 if y<b:r='S';y+=1
 if y>b:r='N';y-=1 
 if x<a:r+='E';x+=1
 if x>a:r+='W';x-=1

It's a map: you are on (x,y) and you need to go to (a,b). S for South, N for North, NE for North East and so on. After each turn I must tell where to go using print.

Update: This is what I've got now, but is there any way to shorten it further?

while 1:c,d=(y>b)-(y<b),(x>a)-(x<a);print((' NS'[c]+' WE'[d]).strip());y-=c;x-=d
  • 2
    \$\begingroup\$ This never terminates. Is that OK? \$\endgroup\$
    – xnor
    Commented May 7, 2015 at 19:08
  • \$\begingroup\$ Yes. In fact, it will automatically end when x=a and y=b \$\endgroup\$
    – xaxa
    Commented May 7, 2015 at 19:11
  • \$\begingroup\$ How strict is the form of the input? For example if you are allowed to take input as "[4,5,1,2]" you could change the first line to a much shorter a,b,x,y=input() \$\endgroup\$
    – KSab
    Commented May 8, 2015 at 13:13
  • \$\begingroup\$ it's really too bad they got rid of cmp() in python 3, this is a perfect use case. \$\endgroup\$ Commented May 9, 2015 at 11:35

4 Answers 4


Python 3, 107

while 1:print('SN'[b>y][:B]+'WE'[a>x][:A]);A-=1;B-=1

A different strategy to generate the directions, tracking each coordinate's absolute displacement to the goal rather than the actual location.

For the horizontal direction, finds the absolute displacement A=abs(a-x) and direction character 'WE'[a>x]. Simulates going towards the goal by decrementing A and printing the direction character as long as we haven't already reached the goal coordinate (A>0). Does the same for vertical.


Theres a shorter way to strip():

(' NS'[c]+' WE'[d]).strip()
c%2*' NS'[c]+d%2*' WE'[d]

saves two characters.


There's a shorter way to take the initial input:

a,b,x,y=[int(i) for i in input().split()]

Thanks to @DenDenDo, for pointing out that you can do tuple unpacking assignment on map objects.

  • 3
    \$\begingroup\$ You dont even need list(), simply a,b,x,y=map(int,input().split()) \$\endgroup\$
    – DenDenDo
    Commented May 7, 2015 at 19:27

In Python 2, you could use cmp, which returns -1, 0, or 1. Use this result to get the correct letter.

while 1:c=cmp(y,b);d=cmp(x,a);print((' SN'[c]+' WE'[d]).strip());y-=c;x-=d

Martin Büttner suggested saving the cmp results to variables, and isaacg noted that now the whole loop can be on one line.

Unfortunately, Python 3 doesn't have cmp, but using (y>b)-(y<b) for cmp(y,b) is still shorter than the original.

  • \$\begingroup\$ Thank you but how do you use the function cmp ? \$\endgroup\$
    – xaxa
    Commented May 7, 2015 at 19:55
  • \$\begingroup\$ "cmp(x,y): Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y." From the Python documentation. link \$\endgroup\$
    – Bonsaigin
    Commented May 7, 2015 at 20:23
  • \$\begingroup\$ @Bonsaigin That's a Python 2 documentation link. \$\endgroup\$
    – isaacg
    Commented May 7, 2015 at 20:34
  • \$\begingroup\$ I decided to fix up the answer to make it relevant and undelete it, as it was an important part in reducing the size of the original. \$\endgroup\$ Commented May 9, 2015 at 11:42
  • \$\begingroup\$ cc: @isaacg see above comment \$\endgroup\$ Commented May 9, 2015 at 11:43

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.