# StackOverflow 챌린지 #14 ‘Signal from Noise’ 도전 가이드와 팁

---

# # 📌 서론 – 왜 이번 챌린지가 주목받는가?

2024년 9월, **StackOverflow 프로그래밍 챌린지**가 새로운 미션을 공개했습니다. 바로 *Signal from Noise* 라는 이름의 문제인데, 이름만 들어도 “시끄러운 데이터 속에서 유의미한 신호를 찾아라”는 의미가 담겨 있습니다.

프로그래밍 입문자부터 중급 개발자까지 모두가 즐길 수 있는 설계와, 알고리즘 사고를 키워줄 수 있는 구조가 특징이죠.

하지만 처음 접하는 사람들은

- 문제 설명이 길어 보인다

- 어떤 접근법이 맞는지 감이 잡히지 않는다

와 같은 고민에 빠지기 쉽습니다.

이 글에서는 **초보자도 이해하기 쉬운** 단계별 해설과, 실제 구현에 바로 적용할 수 있는 팁을 제공해 **Signal from Noise** 를 성공적으로 풀어내는 방법을 소개합니다.

---

# # 🧩 본론

## # 1️⃣ 문제 이해하기 – 핵심은 “노이즈 제거”

> **문제 요약**

> - 입력: 여러 줄에 걸친 문자열(‘0’과 ‘1’만 포함)

> - 목표: 각 열(column)마다 가장 많이 등장하는 비트(0 또는 1)를 찾아 새로운 문자열을 만든다.

> - 최종 출력: 만든 문자열을 2진수로 해석한 뒤 10진수 값 출력

이때 “노이즈”는 각 열에 섞여 있는 드물게 등장하는 비트를 의미합니다. 가장 많이 등장하는 비트를 **시그널**이라고 부르며, 이를 추출하면 문제를 해결할 수 있습니다.

## # 2️⃣ 알고리즘 설계 – 카운팅만 하면 된다

1. **입력 읽기** – 전체 라인을 배열에 저장합니다.

2. **열 길이 파악** – 모든 라인의 길이는 동일하므로 첫 번째 라인의 길이를 기준으로 합니다.

3. **열별 0·1 카운트** – `int[] zeroCnt`, `int[] oneCnt` 배열을 만들고, 각 라인을 순회하면서 해당 열의 비트를 카운트합니다.

4. **시그널 문자열 생성** – 각 열에서 `oneCnt[i] > zeroCnt[i]`이면 ‘1’, 아니면 ‘0’으로 결과 문자열을 채웁니다.

5. **10진수 변환** – `Integer.parseInt(signal, 2)`(Java) 혹은 `int(signal, 2)`(Python) 등으로 변환 후 출력합니다.

이 알고리즘은 **O(N·M)** (N: 라인 수, M: 열 길이) 시간 복잡도로, 입력이 커져도 충분히 빠릅니다.

## # 3️⃣ 구현 예시 – Python & Java 두 가지 버전

### # Python (초보자에게 친숙)

```
python

import sys

lines = [line.strip() for line in sys.stdin if line.strip()]

cols = len(lines[0])

zero_cnt = [0] * cols

one_cnt  = [0] * cols

for line in lines:

    for i, ch in enumerate(line):

        if ch == '0':

            zero_cnt[i] += 1

        else:

            one_cnt[i]  += 1

signal = ''.join('1' if one_cnt[i] > zero_cnt[i] else '0' for i in range(cols))

result = int(signal, 2)

print(result)

```

### # Java (타입 안정성을 선호하는 경우)

```
java

import java.io.*;

import java.util.*;

public class SignalFromNoise {

    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        List<String> lines = new ArrayList<>();

        String line;

        while ((line = br.readLine()) != null && !line.isBlank()) {

            lines.add(line.trim());

        }

        int cols = lines.get(0).length();

        int[] zeroCnt = new int[cols];

        int[] oneCnt  = new int[cols];

        for (String s : lines) {

            for (int i = 0; i < cols; i++) {

                if (s.charAt(i) == '0') zeroCnt[i]++;

                else oneCnt[i]++;

            }

        }

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < cols; i++) {

            sb.append(oneCnt[i] > zeroCnt[i] ? '1' : '0');

        }

        int result = Integer.parseInt(sb.toString(), 2);

        System.out.println(result);

    }

}

```

두 예시 모두 **Signal from Noise** 를 풀기 위한 핵심 로직을 그대로 보여줍니다.

## # 4️⃣ 추가 팁 – 테스트와 디버깅을 쉽게 하는 방법

| 팁 | 설명 |

|---|---|

| **샘플 입력 파일 만들기** | 작은 크기의 파일(`sample.txt`)에 직접 데이터를 넣고, `cat sample.txt \| python solution.py` 형태로 실행해 보세요. |

| **열 단위 출력 확인** | 카운트 배열을 출력해 보면 어느 열이 ‘0’이 많은지 한눈에 파악할 수 있습니다. |

| **예외 상황 처리** | 입력이 비어 있거나 열 길이가 서로 다른 경우, `ValueError` 혹은 `ArrayIndexOutOfBoundsException`이 발생합니다. 미리 검증 로직을 추가하면 점수를 잃지 않습니다. |

| **시간·메모리 제한 확인** | StackOverflow 챌린지는 일반적으로 2초, 256 MB 제한이 있습니다. 위 O(N·M) 알고리즘은 충분히 통과합니다. |

---

# # 🚀 결론 – 지금 바로 도전해 보세요!

*Signal from Noise* 는 **StackOverflow 프로그래밍 챌린지** 중에서도 난이도가 낮은 편이지만, 데이터 처리와 비트 연산을 연습하기에 최적화된 문제입니다. 위에서 제시한 단계별 접근법과 구현 예시를 그대로 따라 하면 금방 풀 수 있을 겁니다.

> **행동 유도**

> 1. 오늘 바로 문제 페이지(https://reddit.com/r/programming/comments/1phzkhg/stackoverflow_programming_challenge_14_signal/)에 접속하세요.

> 2. 제공된 샘플 입력을 복사해 로컬 환경에 저장하고, 위 코드 중 하나를 실행해 보세요.

> 3. 자신만의 추가 테스트 케이스를 만들어 **Signal from Noise** 를 완전히 정복한 뒤, StackOverflow에 정답을 제출해 포인트를 획득하세요!

프로그래밍 실력을 단계적으로 높이고 싶다면, 이번 챌린지를 시작점으로 삼아 **프로그래밍 문제 풀이** 습관을 길러보세요. 다음 주에도 새로운 **Signal from Noise** 와 비슷한 유형의 문제가 등장할 테니, 오늘 배운 방법을 꾸준히 복습하는 것이 중요합니다.

함께 성장하는 개발자가 되길 바랍니다! 🎉
