Consider the following diagram representing a combinational digital circuit – each gate implements a Boolean function of its inputs and there are no cycles in the circuit. The numbers annotated on the gates represent the delay d through the gate, in nanoseconds. If the inputs of a gate are ready at time t, then the output is ready at time t+d. (a) How much time does such a circuit take to compute its primary outputs? For the example above, the maximum delay for E is 2+4+3=9, and for F is 2+4+2=8. Write a program to compute the delay of every primary output in a combinational circuit (defined as the earliest time when the output is ready), given the circuit representation and delay information of the individual gates.
Input: Circuit file (see example file circuit.txt for diagram above)
Input: Gate Delay file (see example file gate_delays.txt for diagram above)
Output: Output Delay file (see example file output_delays.txt for diagram above)
(b) Extend your program to answer the converse question: suppose we require the output to be ready at a specific time. When do we require each input to be ready so that the output timing requirement is met?
Input: Circuit file (see example file circuit.txt for diagram above)
Input: Required Output Delay file (see example file required_delays.txt for diagram above)
Output: Input Delay file (see example file input_delays.txt for the diagram and required_delays.txt file above                                                                                                    def read_circuit_file(circuit):
    circuit = {}
    with open(circuit, 'r') as file:
        for line in file:
            gate, output, inputs = line.split()
            circuit[output.strip()] = [gate.strip(), inputs.strip().split()]
    return circuit

def read_gate_delays(gate_delays):
    gate_delays = {}
    with open(gate_delays, 'r') as file:
        for line in file:
            gate, delay = line.split()
            gate_delays[gate.strip()] = int(delay)
    return gate_delays

def calculate_output_delays(circuit, gate_delays):
    output_delays = {}
    for output in circuit.keys():
        delay = compute_delay(output, circuit, gate_delays)
        output_delays[output] = delay
    return output_delays

def compute_delay(output, circuit, gate_delays):
    if output in gate_delays:
        return gate_delays[output]
    gate, inputs = circuit[output]
    max_input_delay = max(compute_delay(input, circuit, gate_delays) for input in inputs)
    return max_input_delay + gate_delays[gate]

def write_output_delays(output_delays, output_file):
    with open(output_file, 'w') as file:
        for output, delay in output_delays.items():
            file.write(output + ':' + str(delay) + '\n')

def read_required_output_delays(required_delays_file):
    required_delays = {}
    with open(required_delays_file, 'r') as file:
        for line in file:
            output, delay = line.split(':')
            required_delays[output.strip()] = int(delay)
    return required_delays

def calculate_input_delays(circuit, gate_delays, required_delays):
    input_delays = {}
    for output, required_delay in required_delays.items():
        input_delays[output] = compute_input_delays(output, circuit, gate_delays, required_delay)
    return input_delays

def compute_input_delays(output, circuit, gate_delays, required_delay):
    if output in gate_delays:
        return required_delay - gate_delays[output]
    gate, inputs = circuit[output]
    max_required_input_delay = max(compute_input_delays(input, circuit, gate_delays, required_delay) for input in inputs)
    return max_required_input_delay - gate_delays[gate]

def write_input_delays(input_delays, input_file):
    with open(input_file, 'w') as file:
        for output, delays in input_delays.items():
            file.write(output + ': ' + ', '.join([str(delay) for delay in delays]) + '\n')

change this according to given data .