IE 지원에 대한 생각

개인적으로 뭔가를 만들 때 난 브라우저 하나하나에 대해 따로 신경쓰지 않는다. 그나마 신경 쓰는 정도라면 X-UA-Compatible 관련 meta 태그를 넣어주는 것, 그리고 PrefixFree라는 JS 라이브러리를 가져다 쓰는 것 정도다. IE에 어떤 JS 함수가 없다거나 CSS를 지원 안한다거나 해서 그걸 신경써서 분기점을 만들거나 하지 않는다.

예를 들어서 HTML, CSS, JS를 이미지 파일이라고 치고 웹브라우저를 이미지 뷰어라고 생각해보자. 음원파일과 음원 재생기라고 봐도 상관 없다. 디자이너가 이미지를 뽑을 때, 프로듀서가 음원 파일을 뽑을 때 특정 이미지 뷰어, 음원 재생기가 그 파일을 읽지 못할 때를 대비하여 파일 헤더에 분기점을 넣는다던지 하는 행동을 할까? 보통은 그런 이미지 뷰어, 음원 재생기가 업데이트 될 때까지 기다리거나 그냥 버리고 다른 프로그램을 쓴다. (물론 모든 뷰어에서 안열린다면 그 파일을 뽑아낸 프로그램의 버그일것이다.)

하지만 대부분의 웹 디자이너/프로그래머들은 이런 행위를 한다. 심지어 브라우저들도 웹 표준에 맞지 않는 파일을 읽어들인다. 웹프라우저가 표준에서 살짝 벗어난 파일을 읽는 것은 잘 한 행동이라고 생각하지만 IE를 고려해서 분기점을 만들거나 CSS hack을 사용하면 안된다고 생각한다. 계속 구버전의 IE에서도 정삭 동작하도록 웹 어플리케이션을 만든다면 멍청한 사용자들은 자신들의 브라우저가 괜찮은 줄 알고 업그레이드를 하지 않는다. 2000년대 중반에 여러 포털사이트에서 IE6을 그만쓰자면서 IE8 업그레이드 링크를 뿌리고 IE8로 업그레이드를 하면 추첨을 통해 상품을 주는 등의 이벤트를 진행했다. 하지만 소용이 없었고 Google Chrome의 등장으로 IE의 사용자가 줄었다. 차라리 IE8로 업그레이드를 하면 혜택을 주는 것보다 IE6 지원을 끊어버렸으면 좋았을것이다.

예전엔 Firefox에서 돌아가지 않는 웹사이트를 보면 사용자들은 Firefox보다 IE가 좋다며 Firefox를 비난했지만(대부분의 문제는 ActiveX였다.) 요즘은 Chrome에서 안돌아가는 사이트를 보면 IE만 지원하는 사이트를 비난한다. 이정도의 생각을 할 정도로 사용자가 달라졌는데 아직도 IE의 표준 미지원에 대해 고민을 하면 안된다고 생각한다. 사용자느 얼마든지 브라우저를 바꿀 준비가 되어있다.

한국의 일부 높은 사람들은 구버전의 IE에 대한 지원을 끊으면 사용자가 급격하게 줄어서 매출에 영향이 올 것이라고 생각한다. 하지만 내 생각은 그 반대다. IE에 대한 지원을 할 인력으로 최신 웹 기술을 이용하여 사이트를 만들면 IE를 쓰지 않는 사용자가 유입되어 오히려 사용자가 늘것이다.

자연수 찾기 문제

면접관이 자연수 하나를 생각할테니 그 수를 질문을 통해 맞춰보라고 합니다. 단, 질문에 대한 답은 예/아니오밖에 존재할 수 없으며 면접관은 거짓말을 하지 않습니다.
최소한의 질문으로 수를 맞추려면 어떤 전략을 짜야 할까요?

생각한 수가 X가 맞냐는 질문을 해서 맞다는 답이 나왔을 경우 최종적으로 수를 맞췄다고 인정합니다. 예를 들면

Q: 수가 1이 맞나요?

A: No

Q: 수가 2가 맞나요?

A: Yes

위와 같은 대화에선 2번만에 수를 맞춘 것입니다.

풀이 가리기

저는 이런 방법으로 풀었습니다.

  • 바이너리 서치가 가장 빠를 것 같지만 수의 범위가 제한이 없으니 1의 자리부터 거꾸로 해나가면 된다.
  • 언제 끝날지는 모르니 중간중간 계산을 해서 그 수가 맞는 지 확인을 해봐야 한다.

제가 생각한 시나리오는 다음과 같습니다.

Q: 생각한 수를 2진수로 변환했을 때 맨 오른쪽 자릿수가 1입니까?

A: Yes

Q: 그러면 생각한 수가 1입니까?

A: No

Q: 생각한 수를 2진법으로 변환했을 때 오른쪽에서 2번째 자릿수가 1입니까?

A: Yes

Q: 그러면 생각한 수가 3입니까?

A: Yes

그래서 다음과 같은 소스가 나왔습니다.

def is_number(orig, guess):
    if orig == guess:
        return True
    return False


def is_number_nth_field_one(orig, n):
    num = orig / (2 ** (n - 1))
    if num % 2:
        return True
    return False


def guess_number(num):
    count = 0
    n = 1
    guessing = 0
    correct = False
    while not correct:
        count += 1
        if is_number_nth_field_one(num, n):
            guessing += 2 ** (n - 1)
		count += 1
		if is_number(num, guessing):
			correct = True
        n += 1
    return count

if __name__ == '__main__':
    total = 0
    for i in xrange(1, 1000001):
        count = guess_number(i)
        total += count
        print "guess %d, count: %d, total: %d" % (i, count, total)

    print "Total: %d" % total

위의 방법으로 1부터 1000000까지의 수를 모두 돌려보면 총 37902890번의 질문을 합니다.
하지만 뭔가 더 질문의 수를 줄일 수 있을 것 같았습니다.
잘 살펴보면 알겠지만, 쓸모 없는 질문이 있습니다. N번째 자릿수를 물어봤을 때 0이었다면 생각한 수를 확인하는 과정에서 아까 아니라고 한 수를 또 물어봅니다. 다음과 같은 대화가 오가는거죠.

Q: 생각한 수를 2진수로 변환했을 때 맨 오른쪽 자릿수가 1입니까?

A: Yes

Q: 그러면 생각한 수가 1입니까?

A: No

Q: 생각한 수를 2진법으로 변환했을 때 오른쪽에서 2번째 자릿수가 1입니까?

A: No

Q: 그러면 생각한 수가 1입니까?

A: No

그래서 자릿수가 0일 땐 질문을 하지 않고 바로 다음 자리수로 넘어가게 했습니다.

def is_number(orig, guess):
    if orig == guess:
        return True
    return False


def is_number_nth_field_one(orig, n):
    num = orig / (2 ** (n - 1))
    if num % 2:
        return True
    return False


def guess_number(num):
    count = 0
    n = 1
    guessing = 0
    correct = False
    while not correct:
        count += 1
        if is_number_nth_field_one(num, n):
            guessing += 2 ** (n - 1)
			count += 1
			if is_number(num, guessing):
				correct = True
        n += 1
    return count

if __name__ == '__main__':
    total = 0
    for i in xrange(1, 1000001):
        count = guess_number(i)
        total += count
        print "guess %d, count: %d, total: %d" % (i, count, total)

    print "Total: %d" % total

아까랑 아주 살짝 다르죠. 이번에는 총 28836444번 질문을 했습니다. 아까보다 훨씬 줄었죠.

이것보다 더 좋은 해법이 있는지는 모르겠습니다. 더 좋은 답이 있다면 알려주세요.