• + 0 comments

    Answer in typescript

    function strangeCounter(t: number): number {
        /*
            idea 1: counting 1 by 1 util get result. 
            correct but too many loop, tooooooo slow with large input
        */
    
        /*
            idea 2: we knew value reset when it value reach 1, i need to find the time at that moment
            larger than and nearest the time we need to find out. then just minus max_time by the diff
            of max_time with time, we will get value.
            
            explain: 
                calling time is t1 and t2, value is v1 and v2. Each reset have many couple of t1:v1->t2:v2
                we can see t2-t1 always equal v1-v2. 
                
                t2 - t1 = v1 - v2
                
                we knew v2 = 1, t1 = t, we need find v1 as result. the missing piece is t2.
                t2 can be easy calc by fomula:
                
                t2 = <old t2> + 3 * Math.pow(2,<reset>)
            eg: with sample t=4, we have
                
                t1 = 4
                v1 = ?
                t2 = ?
                v2 = 1
                
                by calc t2
                
                reset = 0
                t2 = <old t2> + 3 * Math.pow(2,<reset>)
                   = 3
                
                reset = 1
                t2 = <old t2> + 3 * Math.pow(2,<reset>)
                   = 3 + 6
                   = 9 (enough, it larger than t1)
                
                now we have 3/4 parameter, just doing fomula
                
                    t2 - t1 = v1 - v2
                =>  v1 = t2 - t1 + v2
                =>  v1 = 9 - 4 + 1
                =>  v1 = 6
                
        */
    
        var reset = 0;
        var time_max = 0;
    
        while (true) {
            // calc time_max at reset.
            time_max = time_max + (3 * Math.pow(2, reset));
    
            // inc reset, check time_max is enough?
            reset++;
            if (time_max >= t) break;
        }
        
        // we got the time_max, now do the minus to get value
        return time_max + 1 - t;
    }