You're in a dark room. The only light comes from the LEDs on an old digital alarm clock with four seven-segment displays. The time is displayed in 24-hour format, HH:MM (no seconds), and the leading digit is blank if not used. How much time passes between the room's darkest state and its lightest?

18 hours and 56 minutes (from 1:11 to 20:08). We also consider 18 hours and 57 minutes as a correct answer, but technically speaking the interval extends from the last moment of 1:11 to the first moment of 20:08.

Assignment

A seven-segment display is an electronic device for displaying decimal digits (and sometimes letters). The display consists of seven bar-shaped segments arranged in the shape of the number 8. Each segment can be turned on or off individually. With this, all numbers can be formed in a reasonable legible way, as are the letters A, b, C, d, E and F, for example for the representation of hexadecimal numbers1. Sometimes there is also an eighth segment that represents a decimal point used for the display of non-integer numbers, but we will not consider this option here.

Each of the individual segments is identified by a letter. The top segment is A, the right segments are B and C, the bottom segment is D, the left segments are E and F, and the middle segment is G. This allows us to write, for example, that the digit 5 can be displayed by lighting up the segments A, F, G, C and D. The order in which the letters of the segments are listed makes no difference.

seven-segment display
Representation of the hexadecimal digits on a seven-segment display.
seven-segment display
Letters for the individual segments of a seven-segment display.

Define a class Display that can be used to represent seven-segment displays. When creating a new display (Display), a string (str) must be passed containing the uppercase letters of the segments that must light up on the display. If the string contains a character that is not used to identify a segment, or if the same letter occurs multiple times in the string, an AssertionError must be raised with the message invalid segments. Displays (Display) are immutable.

If a display (Display) is passed to the built-in function len, the brightness of the display must be returned as a number (int) that indicates how many segments of the display are lit.

If a display (Display) is passed to the built-in function repr, a string representation (str) must be returned that reads as a Python expression to create a new display (Display) with the same segments lighting up as on the display passed to the function repr. The letters of the segments must be listed in alphabetical order.

If a display (Display) is passed to the built-in function str, a string representation (str) must be returned that consists of five lines. When all segments light up, the representation looks like the digit 8:

 -- 
|  |
 -- 
|  |
 -- 

Each line of this representation contains four characters (so possibly there are spaces at the end of a line). The characters of segments that are not lit must be replaced by spaces.

For two displays (Display) $$d$$ and $$e$$, the following built-in Python operators must return a new display (Display):

operator result
$$d$$ & $$e$$ a display (Display) on which only the segments light up that are lit on $$d$$ and on $$e$$
$$d$$ - $$e$$ a display (Display) on which only the segments light up that are lit on $$d$$, but not on $$e$$
$$d$$ | $$e$$ a display (Display) on which only the segments light up that are lit on $$d$$ or on $$e$$, or on both
$$d$$ ^ $$e$$ a display (Display) on which only the segments light up that are lit on $$d$$ or on $$e$$, but not on both
~$$d$$ a display (Display) on which only the segments light up that are not lit on $$d$$

Example

Note

This interactive session can be used directly as a docstring. Note however that some lines end with spaces that are important for running doctests. In case you use an IDE that is configured to automatically remove whitespace at the end of lines, you'll have to disable this functionality.

>>> three = Display('GBADC')
>>> three
Display('ABCDG')
>>> print(three)
 -- 
   |
 -- 
   |
 -- 
>>> len(three)
5
>>> four = Display('FBGC')
>>> four
Display('BCFG')
>>> print(four)
    
|  |
 -- 
   |
    
>>> len(four)
4
>>> three & four
Display('BCG')
>>> three - four
Display('AD')
>>> three | four
Display('ABCDFG')
>>> three ^ four
Display('ADF')
>>> ~four
Display('ADE')