0

I was just trying to solve this problem on Codeforces: Check whether it's posible to split a number w (1 ≤ w ≤ 100) into a sum of 2 even numbers

I solved the problem and started to look others solutions for the problem. The I found that solution:

w=int(input())
print("YNEOS"[(w%2)|(w<=2)::2])

it took half of time to solve the problem then mine. Unfortunately I am not getting how it is working and why it is faster than mine. My solution is :

n = int(input())
if (n-2)%2==0 and n > 2:
    print("YES")
else:
    print("NO")

I am a beginner in python. So it will be very helpful for me it i get a proper explanation.

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • questions should be self-contained because people don't want to click on an external link, and that also avoids issues when the external link rots – phuclv May 07 '19 at 01:50

1 Answers1

1

The :: part is called slicing. The general syntax is start:stop[:step] which will make a new array or string from the original one, beginning from index start to before stop every step (default = 1). It's essentially a syntactic sugar for slice(start, stop, step) which returns a slice object. If stop is omitted then all the elements till the end of the string will be extracted

You may want to read An Informal Introduction to Python for more information about slicing


Now (w%2)|(w<=2) calculates the start index. | is the bitwise-OR operator. w<=2 is a bool expression, but in Python "Booleans are a subtype of integers", so True and False will be converted to 1 and 0 respectively

  • If w is an odd number then w % 2 == 1. Regardless of the remaining part, (w%2)|(w<=2) will always be 1 in this case and the expression becomes "YNEOS"[1::2] which takes every second letter in the string starting from index 1. The result is the string NO
  • If w is an even number then w % 2 == 0. According to the problem description 1 ≤ w ≤ 100 the only valid even numbers belong to the range [2, 100]
    • If w == 2 then w <= 2 returns 1 and the output is NO like above
    • If w > 2 then both the sides of (w%2)|(w<=2) is 0, and "YNEOS"[0::2] takes the 1st, 3rd and 5th letters which is YES

Realizing that the expression always returns 0 or 1 we'll have an alternative more readable solution that uses direct addressing instead of slicing

w=int(input())
print(['YES', 'NO'][(w % 2) | (w <= 2)])

Btw, you have a redundant subtraction: (n-2)%2==0 is exactly the same as n % 2 == 0

phuclv
  • 37,963
  • 15
  • 156
  • 475