How can I shorten this python code?

12

2

Here is the code which I want to shorten.

n=input()
while n:
 s=raw_input()
 x,r,g,b=(int(x) for x in s.split())
 a=x/r%2
 c=x/g%2
 d=x/b%2
 r=((a*10+c)*10)+d
 if r==0:e="black"
 elif r==100:e="red"
 elif r==1:e="blue"
 elif r==10:e="green"
 elif r==101:e="magenta"
 elif r==11:e="cyan"
 elif r==110:e="yellow"
 else:e="white"
 print(e)
 n-=1

Input: 3

4643 5913 4827 9752
5583 5357 5120 9400
2025 5475 4339 8392

Output:

black
yellow
black

Ranvijay Singh

Posted 2017-10-15T18:44:11.337

Reputation: 131

2Mind explaining what exactly what this is for, and what you're doing? – Okx – 2017-10-15T18:47:43.413

This is off topic imo. There is no "winner" and tips are more general. – Christopher – 2017-10-15T19:04:27.677

8@Christopher2EZ4RTZ we had many questions like that one before. they are not off topic, this had been discussed for a long time – Uriel – 2017-10-15T19:05:03.907

13

For the close voters, golfing tips questions are perfectly on-topic here, as decided on meta

– caird coinheringaahing – 2017-10-15T19:07:24.927

1Can you give us the problem statement? – xnor – 2017-10-15T19:12:46.833

Does this even work? Doesn’t the input have to be made into an int? – Tim – 2017-10-15T23:29:42.563

@Tim Although the question doesn't state it, the code is in Python 2, where input() is equivalent to eval(input()) in Python 3. – totallyhuman – 2017-10-15T23:44:17.890

Answers

18

Instead of ((a*10+c)*10)+d we can use ((a*2+c)*2)+d to distinguish the colors.

 r=((a*2+c)*2)+d
 if r==0:e="black"
 elif r==4:e="red"
 elif r==1:e="blue"
 elif r==2:e="green"
 elif r==5:e="magenta"
 elif r==3:e="cyan"
 elif r==6:e="yellow"
 else:e="white"

Ah, but now we're just distinguishing between values from 0 to 7, so we can index into an array instead!

 r=a*4+c*2+d
 e=["black","blue","green","cyan","red","magenta","yellow","white"][r]
 # or even shorter:
 e="black blue green cyan red magenta yellow white".split()[r]

Combining with Uriel's changes we get down to 136 bytes (164 bytes saved).

exec'x,r,g,b=map(int,raw_input().split());print"black blue green cyan red magenta yellow white".split()[x/r%2*4+x/g%2*2+x/b%2];'*input()

Try it online!

Lynn

Posted 2017-10-15T18:44:11.337

Reputation: 55 648

@RanvijaySingh If you don't mind putting , (commas) between the integers, then you can reach 115 bytes

– Mr. Xcoder – 2017-10-15T19:51:53.990

5

For the repetition use an exec statement,

map(int, for the conversion of string input into numerals,

shorten calculating r with r=a*100+c*10+d, then put the calculations of each variable (a, c, d) instead of the variable,

and for the conditions use a dictionary with a get query.

Finally, mash everything into one line.

Final result (updating):

exec'x,r,g,b=map(int,raw_input().split());print({0:"black",100:"red",1:"blue",10:"green",101:"magenta",11:"cyan",110:"yellow"}.get((x/r%2)*100+(x/g%2)*10+x/b%2,"white"));'*input()

Bytes saved: 121.

Uriel

Posted 2017-10-15T18:44:11.337

Reputation: 11 708

Can you please add a tio link? Thanks! – Mr. Xcoder – 2017-10-15T18:57:40.643

1@Mr.Xcoder I don't know what type of input OP is expecting, so I can't give an example until he does – Uriel – 2017-10-15T18:58:45.830

1Btw you can save quite a few bytes using exec"..."*input() – Mr. Xcoder – 2017-10-15T18:59:30.640

@Mr.Xcoder right, thanks! updating – Uriel – 2017-10-15T18:59:56.640

@RanvijaySingh you're welcome. what is it for btw? – Uriel – 2017-10-15T19:04:29.057

1You have some redundant parentheses in there (around print, and (x/r%2)*100x/r%2*100 etc.) – Lynn – 2017-10-15T19:11:24.453

2@Lynn yea, you covered it better. I just applied golfing techniques - and I'm used to python 3 – Uriel – 2017-10-15T19:14:58.427