01011011101111011111... 시퀀스에 대한 인터뷰 질문입니다. 코드 품질의 척도로서의 미적분은 어떻습니까?

목차


  • Solution #1: Generators
  • Solution #2: Why should I care about powers of two and binary representations of digits?
  • Solution #3: Simplest possible
  • About Time Complexity of Solution #1
  • Calculus as a metric of code quality?

  • 머리말



    인터뷰에서 이 작업에 대해 들은 것은 오래 전 일입니다. 자랑스럽지 않은 알고리즘으로 해결했습니다. 그러나 이 작업은 내 머리 속에 있으며 시간이 지남에 따라 그것에 대해 생각하고 해결하는 더 나은 방법을 찾습니다.
    이 기사의 제목이나 다른 해결 방법에서 2의 거듭제곱을 볼 수 있다면 우리와 공유하고 의견을 남겨주세요. 어떤 생각이든 유용할 수 있습니다.

    솔루션으로 이동해 보겠습니다.

    솔루션 #1: 생성기

    I found it very fast because this way was preferred by my interviewer. Mostly it's not about solution of the task. You just need to know how generators work and that's it.
    I think this is O(N^2) classical problem (or not?). I can show you the algo on TypeScript lang. It's like JavaScript but with types.

    export function* strangeZeroOneSequence(length: number): Generator<number> {
      for (let counter = 0; counter < length; counter++) {
        let iterator = 0;
        yield iterator;
    
        while (iterator <= counter) {
          yield 1;
          iterator++;
        }
      }
    }
    

    Computer programming it's constantly about test cases

    describe("Check strangeZeroOneSequence", () => {
      it("01 sequence", () => {
        const generator = strangeZeroOneSequence(1);
        const array = [...generator];
        expect(array).toStrictEqual([0, 1]);
      });
      it("01011011101111 sequence", () => {
        const generator = strangeZeroOneSequence(4);
        const array = [...generator];
        console.warn(array);
        expect(array.join("")).toBe("01011011101111");
      });
    });
    

    Ok, you can play with it by yourself and leave any comments about it.
    I want to stop now with it, and you can look at the complexity estimation of this algo in the bottom of this article. I move to the solution #2.

    솔루션 #2: 왜 2의 거듭제곱과 숫자의 이진 표현에 신경을 써야 합니까?

    Because it's one direct way to solve it. Let's remember about powers of two in table view, but let's skip first power 2^0=1

    Binary 2^x Decimal
    10 2^1 2
    100 2^2 4
    1000 2^3 8
    10000 2^4 16
    100000 2^5 32

    And etc.

    Column "Binary" is exactly the pattern, but inverted by somehow. We need replace first 1 from the left to 0 and every next 0 to 1 . How can we do this, but without any loops? Is there any way?

    In the binary system, each digit represents an increasing power of 2, with the rightmost digit representing 20, the next representing 21, then 22, and so on. The value of a binary number is the sum of the powers of 2 represented by each "1" digit. For example, the binary number 100101 is converted to decimal form as follows wiki link




    1000...0 <- 처음부터 1, 끝까지 0으로 보이는 모든 이진수, 정확한 2의 거듭제곱과 같을 때2^n
    2^n2^(n-1)2^(n-1)...2^22^12^0

    1
    0
    0
    ...
    0
    0
    0


    십진법을 찾기 위해 2^0에서 2^n까지 2의 모든 거듭제곱을 합할 수 있습니다. 여기서 이진 표현은 1입니다.

    루프 없이 이진수의 모든 항목을 0에서 1로 반전시키는 방법은 무엇입니까? 바이너리에서도 작동하기 때문에 수학을 사용합시다!

    2^n2^(n-1)2^(n-1)...2^22^12^0

    1
    1
    1
    ...
    1
    1
    1

    1
    0
    0
    ...
    0
    0
    0

    0
    1
    1
    ...
    1
    1
    1

    (row 1) => 전체 세트(row 2) => 첫 번째 항은 1이고 나머지는 0입니다.(row 3) = (row 1) - (row 2) =>는 우리의 시퀀스입니다!

    해결책은 다음과 같습니다.

    export const strangeZeroOneSequence = (length: number): string => {
      let [result, chunk] = ['', 0];
      // One single loop till the end O(N)
      for (let i = 0; i < length; i++) {
        chunk += Math.pow(2, i);
        // Just binary data casting, that's O(1)
        result += `0${chunk.toString(2)}`;
      }
      return result;
    };
    
    
    


    테스트 케이스:

    describe("Check strangeZeroOneSequence", () => {
      it("01 sequence", () => {
        const result = strangeZeroOneSequence(1);
        expect(result).toBe("01");
      });
      it("01011 sequence", () => {
        const result = strangeZeroOneSequence(2);
        expect(result).toBe("01011");
      });
      it("010110111 sequence", () => {
        const result = strangeZeroOneSequence(3);
        expect(result).toBe("010110111");
      });
      it("01011011101111 sequence", () => {
        const result = strangeZeroOneSequence(4);
        expect(result).toBe("01011011101111");
      });
    });
    
    


    복잡성은 확실히 O(N) 입니다. 보시다시피, 때때로 숫자의 이진 형식이 보이는 것보다 더 대표적입니다.

    해결 방법 #3: 가장 간단함

    I could start from this, but who's gonna read me if I create an article with just 10 lines of code? =)

    export function strangeZeroOneSequence(length: number): string {
      let [result, sequence] = ['', '01'];
      for (let i = 0; i < length; i++) {
        result += sequence;
        sequence += '1';
      }
      return result;
    }
    

    You can use test cases from
    Some of you already knew the answer from the beginning. Not anytime you have a simple and expressive solution.

    Probably you have yours solution - would you share it?


    솔루션 #1의 시간 복잡도에 대하여

    Is it O(N^2) , or could we estimate it a little better? Yes we can and no, we shouldn't! Estimation O(N^2) is good enough.
    You need to move to real math if you want to make a more precise estimation.
    And I can give you just a little notch to open this shade for you. How can we estimate the time-complexity of this algo but with more accuracy than O(N^2) ?
    Let's make 2 sequences and then graphically visualize it.

    n -> gap of zeros in the sequence
    b -> count of algo iteration that we save per every run

    So we can make a plot, where n , b on x , y axes. Just two dimensional Decart system.

    You can find data and graph here on desmos



    따라서 두 번째 그룹을 활성화하면 함수 공간의 모든 점마다 동작을 예측하는 수학 함수를 볼 수 있습니다.



    그리고 이것이 정확한 기능이라는 미적분학 증거가 있습니다.f(x) 와 역도함수F(x) 부터 시작합시다. 시간 공간에서 이 함수의 작업을 찾으려면 0과 99 사이의 F(x)의 한정적분이어야 합니다(범위 n 또는 t , 실행 시간 공간)



    이것이 정확히 일치하는 것을 알 수 있습니다. 적분 값 = b = 5049의 최신 값

    그리고 기능은 규모에 상관없이 두 공간(불연속 및 연속)에서 일치합니다!



    코드 품질의 척도로서의 미적분?

    It's very interesting and beautiful when you can find the the exact math function that express work that the program function has done. You can think about every function on your code as a pices of work that it has to be done. Then you can think about optimization and bottle necs in the algo, based on the math! There are so many ways of optimizations math functions!
    Probably there is the whole area of analysis of computer program functions spaces. Do you know tools that can automatically analyze your program functions space and create some reports about it?
    In case of pure functions we have input space map to output space of the program function. You can find correlation between input space and output space based on type signatures.
    And test cases of your project can make this job, it can be very interesting report. Just think about it as a tool that can find every function, every method in your code, run it and calc statistics about complexity of the algo per every line of the code. And detected correlation between input space and output space can provide an infinity possible ways for optimization of any kind programs!
    Probably
    interpolation 기술은 우리에게 기회를 줄 수 있습니다

    얼마나 많은 작업이 필요한가!


    저와 함께하세요:

    Github

    좋은 웹페이지 즐겨찾기