Algorithm/Programmers SQL

[MySQL] 프로그래머스 특정 형질을 가지는 대장균 찾기

제우제우 2024. 8. 26. 18:25

https://school.programmers.co.kr/learn/courses/30/lessons/301646

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

코딩테스트 연습 > SELECT > 특정 형질을 가지는 대장균 찾기

문제 분석 

문제 난이도 LEVEL1 

 

문제에서 주어진 테이블(ECOLI_DATA)에는 INTEGER 타입의 GENOTYPE 컬럼이 있다. 

개체의 형질이라고 한다  :(

 

문제의 조건은 2번 형질을 보유하지 않으면서 1번이나 3번 형질을 보유하고 있는 대장균 개체의 수 (COUNT)를 출력하는

SQL 작성이다.

 

핵심: n번 형질이란 GENOTYPE 컬럼을 이진수로 변환하고 뒤에서 n번째를 의미한다. 

 

EX) GENOTYPE 15 

13를 이진수로 변환하면 1101 이다. 

 

1101에서 1번 형질은 1 / 2번 형질은 0 / 3번 형질은 1 / 4번 형질은 1 

 

문제의 조건은 2번 형질 보유하지 않고 1번이나 3번 형질을 보유하는 게 조건이니까

2번 형질이 0이고 1번 3번 형질 모두 1이니 숫자 13은 count에 들어가야 한다.

 

나는 이진수 변환은 BIN() 함수를 

BIN() 함수를 사용해서 변환한 이진수의 N번째 형질 파악은 SUBSTRING(), LENGTH() 함수를 사용해서 풀었다. 

 

SQL 작성하고 실행했는데 계속 틀려서 당황했는데 

SELECT 결과가 COUNT(*)여서 틀렸던 것이다. AS를 사용해서 꼭 COUNT라고 별칭을 주자 

 

정답 코드

SELECT COUNT(*) AS COUNT
FROM ECOLI_DATA
WHERE 
BIN(GENOTYPE) = 1  OR
BIN(GENOTYPE) = 01 OR
( 
  LENGTH(BIN(GENOTYPE)) >= 3 AND 
  SUBSTRING(BIN(GENOTYPE), LENGTH(BIN(GENOTYPE)) -1, 1) != 1 AND
  (SUBSTRING(BIN(GENOTYPE), LENGTH(BIN(GENOTYPE)) -2, 1) = 1 OR SUBSTRING(BIN(GENOTYPE), LENGTH(BIN(GENOTYPE)), 1) = 1 ) 
)

 

SQL를 처음 풀어서 이렇게 푸는 게 맞나 싶었는데 일단 통과는 되었다.

 

비트연산 활용 

SELECT COUNT(*) AS COUNT
FROM ECOLI_DATA
WHERE
GENOTYPE & 2 = 0 AND
(GENOTYPE & 4 = 4 OR GENOTYPE & 1 = 1)

 

이렇게 간단한 문제풀이가..

 

간단한 설명 

이진수 뒤에서 3번째 숫자가 1인지 파악하는 방법은 GENOTYPE & 4 이다. 

& 연산(AND)을 하면 GENOTYPE은 이진수로 먼저 변환된다. 4 또한 이진수로 변환되어 100 이다.

 

GENOTYPE이 3,4,13 인 케이스를 예시로 두겠다.  

3: 11 

4: 100

13: 1101

이진수(GENOTYPE) 011(3) 100(4) 1101(13)
4(100) 100  
100 0100
결과  0 100 = 4  100 = 4

 

정확하게 뒤에서 3번째 자리에 1이 있어야 4로 결과가 나온다. 

  1. 특정 형질을 가지는 대장균 찾기