algorithm / knowledge

숫자를 아스키 7-세그먼트로 그리기

paul 2025.11.10 685words (3m)

숫자를 전자시계처럼 생긴 모양으로 터미널에 찍는 문제다. 0부터 9까지의 모양을 어딘가에 담아둬야 하는데, 자료구조를 크게 만들지 않고 문자열 두 뭉치로 끝냈다.

python
p = " -  | |   "
q = ['0700700000',
     '4222466244',
     '7700000700',
     '4262224242',
     '0700700700']

조각 팔레트

p 는 한 칸에 들어갈 수 있는 조각들을 겹쳐서 담아둔 문자열이다. 여기서 세 글자씩 잘라 쓴다.

시작 위치 잘라낸 것
0 - 가로 막대
2 | 오른쪽 세로선만
4 | | 양쪽 세로선
6 | 왼쪽 세로선만
7 (공백 셋) 빈 칸

조각이 다섯 종류인데 배열 다섯 개를 만들지 않고, 겹치는 부분을 공유하도록 한 줄에 밀어넣었다. | | || 가 같은 영역을 나눠 쓴다.

글꼴

q 는 다섯 줄이고 각 줄이 열 글자다. q[줄][숫자] 가 그 숫자의 그 줄에 어떤 조각이 오는지를 p 의 시작 위치로 가리킨다.

첫 줄 '0700700000' 을 보면 숫자 1과 숫자 4 자리만 7 이다. 1과 4는 맨 윗 가로 막대가 없다. 나머지는 0 이라 막대가 있다.

둘째 줄 '4222466244' 는 위쪽 세로선이다. 0은 4 라 양쪽 다 있고, 1과 2와 3은 2 라 오른쪽만, 5와 6은 6 이라 왼쪽만 있다.

10x5짜리 표를 문자열 다섯 개로 적은 셈이다.

조립

python
for idx, l in enumerate(q):
    s = []
    for d in str(n):
        a, b, c = p[int(l[int(d)]):][:3]
        s.append(a + b * scale + c)

    l = ''.join(s)
    print((l + '\n') * (row if idx % 2 else 1), end='')

l[int(d)] 로 이 숫자의 이 줄이 쓸 시작 위치를 얻고, p[시작:][:3] 으로 세 글자를 떼어낸다. 그걸 a, b, c 로 풀어놓는다.

가운데 bscale 번 반복한다. 가로 막대는 - 가 늘어나 길어지고, 세로선 두 개짜리는 가운데 공백이 늘어나 넓어진다. 양끝은 그대로 두므로 모양이 안 깨진다.

python
row, col = 2, 2
scale = (col - 1) * 3 + 1

세로 크기는 다르게 처리한다. q 의 홀수 번째 줄이 세로선 줄이므로 idx % 2 로 골라 그 줄만 row 번 출력한다. 가로 막대 줄은 여러 번 찍으면 막대가 여러 개가 되므로 한 번만 찍는다.

결과

text
       ----  ----        ----  ----  ----  ----  ----  ---- 
     |     |     ||    ||     |          ||    ||    ||    |
     |     |     ||    ||     |          ||    ||    ||    |
       ----  ----  ----  ----  ----        ----  ----       
     ||          |     |     ||    |     ||    |     ||    |
     ||          |     |     ||    |     ||    |     ||    |
       ----  ----        ----  ----        ----  ----  ----

1234567890row=2, col=2 로 찍은 것이다.

숫자 사이 간격이 없어서 붙어 보인다. 각 자리를 만들 때 뒤에 공백을 하나 더 붙이면 될 것 같은데 지금은 그대로다.