1
\$\begingroup\$

I stumbled upon this kata; the aim is to count how many epoqs it takes for n forward-counters and m backward-counters to all be equal.

In the beginning, all the planets start with 0.

There are two types of planets: forward-counting planets, and backward-counting planets. Every second, the display number on each forward-counting planet will increase by one, and the display number for each backward-counting planet will decrease by one.

Each planet has it's own special number, let's call it the planet's x, for now. It is the highest number that the planet can display. The lowest is 0.

Instead of becoming negative, the display number for a backward-counting planet would wrap to it's x.

Instead of becoming greater than x, the display number for a forward-counting planet would wrap back to 0.

This code works and seem 'clean' but times out when the amount of counters gets too large. How can I optimize this code?

class Counter:
    def __init__(self, name):
        self.name = name
        self.modulo = name + 1

class ForwardCounter(Counter):
    def __init__(self, name):
        super().__init__(name)
        
    def count(self, epoq):
        return (self.name + epoq) % self.modulo
    
class BackwardCounter(Counter):
    def __init__(self, name):
        super().__init__(name)

    def count(self, epoq):
        return (self.name - epoq) % self.modulo

def unifier(retrograde,prograde):
    counters = [BackwardCounter(x) for x in retrograde]
    counters += [ForwardCounter(x) for x in prograde]
    
    epoq = 1
    while True:
        first = counter[0].count(epoq)
        if all(first == rest.count(epoq) for rest in counter[1:]):
            break
        epoq += 1
    return epoq

Tests:

test.assert_equals(unifier([25,8], [24,7]), 1402)
test.assert_equals(unifier([1,2,3,4], [6,7,8,9,10]), 27720)
\$\endgroup\$
  • 5
    \$\begingroup\$ Thou shalt not bruteforce. Study the underlying math; it is not that complicated. \$\endgroup\$ – vnp Sep 30 at 16:41
  • 1
    \$\begingroup\$ I still haven't found the algorithm. On the plus side, I studied modular arithmetic. ;) \$\endgroup\$ – Sy Ker Oct 3 at 8:50
  • 1
    \$\begingroup\$ Your code as posted doesn't work. NameError: name 'counter' is not defined \$\endgroup\$ – Peilonrayz Oct 3 at 10:33
  • 1
    \$\begingroup\$ Your code doesn't pass the kata's test case - unifier([6,9], [2,4,7]) doesn't output anything when it's meant to output 840. \$\endgroup\$ – Peilonrayz Oct 3 at 10:44
  • \$\begingroup\$ Did you really have to close the question? I guess I'll reopen, thanks. \$\endgroup\$ – Sy Ker Oct 3 at 15:47

Browse other questions tagged or ask your own question.