[퀴즈] 가위 바위 보에서 서로 비기는 경우 구하기 0 32 11,814

by 마농 경우의수 connect by [2013.07.24 18:03:31]


[퀴즈] 가위 바위 보에서 서로 비기는 경우 구하기


[문제]
가위 바위 보 게임의 참가자 테이블 T1 과 코드테이블 T2 가 있을 때
다음 결과를 도출하는 SQL 을 작성하세요.
가위 바위 보 게임 참가자 3명이 게임을 했을 때
조합 가능한 모든 경우 중 비기는 경우를 구하는 문제입니다.
코드테이블은 변동 없습니다. 참가자는 늘어날 수 있습니다.
참가자가 늘어나는 경우까지 고려하여 SQL 을 작성해 주세요.


[샘플]
WITH t1 AS
(
SELECT 1 id, 'AA' nm FROM dual
UNION ALL SELECT 2, 'BB' FROM dual
UNION ALL SELECT 3, 'CC' FROM dual
--UNION ALL SELECT 4, 'DD' FROM dual
)
, t2 AS
(
SELECT 1 cd, '가위' v FROM dual
UNION ALL SELECT 2, '바위' FROM dual
UNION ALL SELECT 3, '보' FROM dual
)
SELECT * FROM t1, t2;


[원본]
게임참가자 테이블 코드 테이블
ID NM CD V
1 AA 1 가위
2 BB 2 바위
3 CC 3
[결과]
P
AA가위-BB가위-CC가위
AA가위-BB바위-CC보
AA가위-BB보-CC바위
AA바위-BB가위-CC보
AA바위-BB바위-CC바위
AA바위-BB보-CC가위
AA보-BB가위-CC바위
AA보-BB바위-CC가위
AA보-BB보-CC보


[정답] 아래부분 마우스 드래그하세요

SELECT p
  FROM (SELECT SUBSTR(SYS_CONNECT_BY_PATH(nm||v, '-'), 2) p
          FROM t1, t2
         WHERE CONNECT_BY_ISLEAF = 1
         START WITH id = 1
         CONNECT BY PRIOR id + 1 = id
        ) t3
     , t2
 WHERE INSTR(p, v) > 0
 GROUP BY p
 HAVING COUNT(*) IN (1, 3)
 ORDER BY p
;

by 아발란체 [2013.07.25 11:08:55]

세 사람이 가위바위보를 하면.

가위=1, 바위=2, 보=3이라고 했을 때
아래처럼 경우가 나올 수 있는거 같은데(27 = 3 * 3 * 3)

이 조합에서 비긴 사람만 본다면,
3사람이 다 비겨야 비겼다고 볼 수 있나요?
2사람만 같아도 비긴 결과가 있다고 볼 수 있나요?

결과셋을 보면 더 헤갈리고.. ㅡ ㅅ ㅡ)/
비겼다고 하는게 같은 것을 낸 사람 아닌가용?


1.1.1
1.1.2
1.1.3
1.2.1
1.2.2
1.2.3
1.3.1
1.3.2
1.3.3

2.1.1
2.1.2
2.1.3
2.2.1
2.2.2
2.2.3
2.3.1
2.3.2
2.3.3

3.1.1
3.1.2
3.1.3
3.2.1
3.2.2
3.2.3
3.3.1
3.3.2
3.3.3


by 손님 [2013.07.25 11:18:56]
2사람만 같아도 비긴 결과죠
실제로 가위바위보할때도 그렇잖아요 ㅎㅎ

by 손님 [2013.07.25 11:23:49]

1.1.1 --비김
1.1.2
1.1.3
1.2.1
1.2.2
1.2.3 --비김
1.3.1
1.3.2 --비김
1.3.3

2.1.1
2.1.2
2.1.3
2.2.1
2.2.2 --비김
2.2.3
2.3.1
2.3.2
2.3.3

3.1.1
3.1.2
3.1.3
3.2.1
3.2.2
3.2.3
3.3.1
3.3.2
3.3.3 ---비김


by DIIIN [2013.07.25 11:18:31]
두 사람이 같으면 비길수가 없지요

by DIIIN [2013.07.25 11:19:29]
1.2.3 이면 비긴거죠 1.1.1 도 비긴거구요

by 손님 [2013.07.25 11:21:43]
그렇네요 ㅋㅋㅋ
잘못생각했어요
1번 가위 2번 가위 3번 보 일때는 비긴게아닌게되니

1,2,3 이 모두 다를경우도 비긴상태

by 아발란체 [2013.07.25 11:20:52]

아하..... ㅡ ㅅ ㅡ) 감사합니다.

이 닭대가뤼...


by 용근님 [2013.07.25 11:21:35]
문제는 이해했어도 못짜고 있음 ㅎㅎㅎㅎㅎㅎㅎㅎㅎ 생각의 전환 차이가 필요해보임

by 우리집아찌 [2013.07.25 11:34:08]
어려워요... 인원 추가되도 되야하공..

by DIIIN [2013.07.25 11:37:27]
문제는 참가자가 늘어난다는거죠 이론적으로는 모두 같을 때와 3명 이상이 모두 다르면 되는데... 프로그램 설치 중이라 해볼 수가 없네요

by 용근님 [2013.07.25 13:09:40]

-- 넘어려워요 상주셔야 돼요 ㅎㅎ

SELECT 가위바위보
  FROM (
    SELECT 가위바위보
, DECODE ( LENGTH ( 가위바위보 ), LENGTH ( REPLACE ( 가위바위보, '가위', '' ) ), 'X', 'O' ) 가위
, DECODE ( LENGTH ( 가위바위보 ), LENGTH ( REPLACE ( 가위바위보, '바위', '' ) ), 'X', 'O' ) 바위
, DECODE ( LENGTH ( 가위바위보 ), LENGTH ( REPLACE ( 가위바위보, '보'  , '' ) ), 'X', 'O' ) 보
  FROM (
  SELECT SUBSTR ( SYS_CONNECT_BY_PATH ( a.nm || b.v, '-' ), 2 ) 가위바위보
   , level lv
   , cnt
    FROM ( SELECT t1.*
    , count(*) over() cnt    
FROM t1
)  a
   , t2 b
   START WITH id = 1
  CONNECT BY PRIOR a.id >= level
AND PRIOR a.id < a.id
    ) WHERE lv = 3
)
WHERE NVL ( DECODE ( REGEXP_COUNT ( 가위||바위||보, '[O]' ), 3, '비김' )
   , DECODE ( REGEXP_COUNT ( 가위||바위||보, '[O]' ), 1, '비김' )
  ) = '비김'


by 우리집아찌 [2013.07.25 13:20:06]
반 포기상태인데.. 상주시면 도전해야겠네요.. ㅎㅎ

by 용근님 [2013.07.25 13:29:19]
-- 조금 수정 

SELECT 가위바위보
 FROM (
	 SELECT 가위바위보
  , CASE WHEN REGEXP_COUNT ( 가위바위보, '가' ) >= 1 THEN 'O' ELSE 'X' END 가위
  , CASE WHEN REGEXP_COUNT ( 가위바위보, '바' ) >= 1 THEN 'O' ELSE 'X' END 바위
  , CASE WHEN REGEXP_COUNT ( 가위바위보, '보' ) >= 1 THEN 'O' ELSE 'X' END 보
 FROM (
 SELECT SUBSTR ( SYS_CONNECT_BY_PATH ( a.nm || b.v, '-' ), 2 ) 가위바위보
, level lv
	 , cnt
	FROM ( SELECT t1.*
	 , count(*) over() cnt 
	 FROM t1
	 ) a
	, t2 b
 START WITH id = 1
 CONNECT BY PRIOR a.id < a.id
	) WHERE lv = cnt
)
WHERE DECODE ( REGEXP_COUNT ( 가위||바위||보, '[O]' ), 3, '비김', 1, '비김' ) = '비김'

by sdalf [2013.07.25 13:36:38]
4명이상일경우엔 3row만 나오는게 맞나요? 

select result
from 
(
    select  m.*
    ,(select count(distinct REGEXP_SUBSTR(t_result, '[^-]+', 1, level)) from dual connect by level<=REGEXP_COUNT(t_result,'-')+1) series_count
    from 
    (
        select id,v,nm,cd
        ,level lv
        ,SUBSTR(SYS_CONNECT_BY_PATH(nm||v,'-'),2) result
        ,SUBSTR(SYS_CONNECT_BY_PATH(cd,'-'),2) t_result
        ,count(distinct nm) over() nm_cnt
        from 
        (
            SELECT * 
            FROM t1,t2 
        )
        CONNECT BY PRIOR id < id
    ) m
    where lv = nm_cnt
)
where series_count in (1,nm_cnt)
order by result

by 용근님 [2013.07.25 13:40:25]

전 39건이 나오는군요


by DIIIN [2013.07.25 13:42:32]
4명이면 3명일 때보다 더 많지요 3명일 때 비기는 경우는 9가지군요

by sdalf [2013.07.25 13:44:31]
4명일때 비기는 경우는

가위 가위 가위 가위
바위 바위 바위 바위
보 보 보 보 

외의 경우는 없을듯한데요? 

by 윤 [2013.07.25 13:54:46]
가위 바위 보 가위
가위 바위 보 보
가위 바위 보 바위
가위 보 바위 가위
가위 보 바위 보
가위 보 바위 바위

바위 가위 보 가위
바위 가위 보 보
바위 가위 보 바위

보 가위 바위 가위
보 가위 바위 보
보 가위 바위 바위

등등.....

이것도 비기는거에 속하지 않을까요?

by 아린 [2013.07.25 13:50:26]
3명 9건 / 4명 39건  나오네요..

SELECT p
  FROM (SELECT SUBSTR(SYS_CONNECT_BY_PATH(nm||v, '-'),2) p
             , SUBSTR(SYS_CONNECT_BY_PATH(v, '-'),2) gn
          FROM t1, t2
         WHERE LEVEL = 4 --(인원수 ) 
         START WITH id = 1 
         CONNECT BY PRIOR id + 1  = id
        )
      , (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 10) d
 WHERE d.lv <= REGEXP_COUNT(gn, '-') +1
 GROUP BY p
 HAVING COUNT(DISTINCT REGEXP_SUBSTR(gn, '[^-]+', 1, lv)) IN (1, 3)

by sdalf [2013.07.25 13:59:02]
아 그렇네요. 4명이 모두 달라야지만 비기는거라 생각했는데 아니군요. ㅎㅎ

가위,바위,보가 한번씩만나와도 비기는거네요.


-- 수정본..
SELECT RESULT
FROM 
(
    SELECT  M.*
    ,(SELECT COUNT(DISTINCT REGEXP_SUBSTR(T_RESULT, '[^-]+', 1, LEVEL)) FROM DUAL CONNECT BY LEVEL<=REGEXP_COUNT(T_RESULT,'-')+1) SERIES_COUNT
    FROM 
    (
        SELECT ID,V,NM,CD
        ,LEVEL LV
        ,SUBSTR(SYS_CONNECT_BY_PATH(NM||V,'-'),2) RESULT
        ,SUBSTR(SYS_CONNECT_BY_PATH(CD,'-'),2) T_RESULT
        ,COUNT(DISTINCT NM) OVER() NM_CNT
        FROM T1,T2 
        CONNECT BY PRIOR ID < ID
    ) M
    WHERE LV = NM_CNT
)
WHERE SERIES_COUNT IN (1,3)
ORDER BY RESULT

by 윤 [2013.07.25 13:59:58]
필요했던 퀴즈가 눈앞에 현실로 +_+ 감사함니다

by 마농 [2013.07.25 15:24:05]

와우... 답글이 많이 달렸네요..
퀴즈에 관심 가져주셔서 감사합니다.
위에 정답 올렸습니다. 확인해 보세요.


정답 설명
이번 퀴즈에서 원하는 답은 다음과 같습니다.
[모든 경우의 수 구하기]
1. t1, t2 를 Cross Join 하고
2. Start With id = 1 Connect by Prior id+1 = id 를 이용한 계층 구조 전개
3. Connect_by_isLeaf 를 이용한 조건절 주기
4. Sys_Connect_by_Path 를 이용한 정보 조회
[비기는 경우 구하기]
5. Instr 을 이용한 조인
6. Count(*) In (1, 3) 을 이용한 조건 처리


답글을 살펴보니 1,2,4,6 까지 생각하신 분은 몇분 계시네요.
안타깝게도 3번과 5번을 생각하신 분은 없네요.
대신 별도 인원카운트를 구하거나, 정규식등을 이용해 주셨네요.


by 용근님 [2013.07.25 15:27:33]
결과값만 맞춘걸로 상품 주시면 안되요? ㅋㅋㅋㅋ

by 신이만든짝퉁 [2013.07.25 18:06:10]
select path1
  from (
        select substr(path1,2) path1
             , substr(path2,2) path2
          from (
                select level lvl
                     , sys_connect_by_path(data, '-') path1
                     , sys_connect_by_path(cd, '-') path2
                  from (
                        select nm||v data
                             , id
                             , cd
                          from t1
                             , t2
                       )
                connect by prior id < id  and level <= (select count(*) from t1)
               )
         where lvl = (select count(*) from t1)
       )
 where (regexp_count(path2, '1') <> 0 and  regexp_count(path2, '2') <> 0 and regexp_count(path2, '3') <> 0)
    or regexp_count(path2, '1') >= (select count(*) from t1)
    or regexp_count(path2, '2') >= (select count(*) from t1)
    or regexp_count(path2, '3') >= (select count(*) from t1)
order by path1   

아~~
저는 너무 복잡하게 풀었군요.
그래도 답은 맞았습니다. ;;

by DIIIN [2013.07.25 18:12:56]
난해한 계층쿼리~

by 우리집아찌 [2013.07.25 18:48:12]

내일 봐야지.. 오늘 엄청 바뿌넹..

by 권pro [2013.09.03 14:42:25]
될때까지풀겠습니다 !

by 가자미 [2013.09.14 01:26:52]
SELECT  AA.nm || AA.v || '-' || BB.nm || BB.v|| '-' || CC.nm || CC.v
FROM    ( SELECT  * FROM    T1, T2 WHERE   NM = 'AA' ) AA
        , ( SELECT  * FROM    T1, T2 WHERE   NM = 'BB' ) BB
        , ( SELECT  * FROM    T1, T2 WHERE   NM = 'CC' ) CC
WHERE  (AA.cd = BB.cd
AND    BB.cd = CC.cd)
or    (AA.cd <> BB.cd
AND     BB.cd <> CC.cd
AND     AA.cd <> cc.cd
)
order by AA.cd, BB.cd, CC.cd
;

by v상이v [2013.11.04 16:16:46]
SELECT P
 FROM (
    SELECT SUBSTR(SYS_CONNECT_BY_PATH(nm||v, '-'), 2) p
        ,DECODE(INSTR(SYS_CONNECT_BY_PATH(V, '-'),'-가위'),0,0,1) A
        ,DECODE(INSTR(SYS_CONNECT_BY_PATH(V, '-'),'-바위'),0,0,1) B
        ,DECODE(INSTR(SYS_CONNECT_BY_PATH(V, '-'),'-보'),0,0,1) C
     FROM t1, t2
     WHERE CONNECT_BY_ISLEAF = 1
     START WITH id = 1
     CONNECT BY PRIOR id + 1 = id
     )
 WHERE A+B+C != 2

by 샤프하나 [2014.05.21 17:34:52]

SELECT PATH
FROM (
    SELECT LEVEL LV, NM, V, SYS_CONNECT_BY_PATH(NM||V,'-') AS PATH
          ,CONNECT_BY_ISLEAF  AS CHK
    FROM (
      SELECT *
      FROM  T1,T2      
    )
    START WITH ID = 1
    CONNECT BY ID = PRIOR ID + 1
)
WHERE CHK = 1
AND (    (INSTR(PATH,'가위') > 0 AND INSTR(PATH,'바위') > 0 AND INSTR(PATH,'보') > 0)
      OR (INSTR(PATH,'가위') > 0 AND INSTR(PATH,'바위') <= 0 AND INSTR(PATH,'보') <= 0)
      OR (INSTR(PATH,'가위') <= 0 AND INSTR(PATH,'바위') > 0 AND INSTR(PATH,'보') <= 0)
      OR (INSTR(PATH,'가위') <= 0 AND INSTR(PATH,'바위') <= 0 AND INSTR(PATH,'보') > 0)  )
;
안보고 풀어봤는데 이게 바로 실력차이구나라는걸 느끼게 해주네요.
많이 배우고 갑니다.


by terry0515 [2016.01.20 16:32:54]

아직 정답은 안보고 작성해봤네요..

사람이 추가된다면?? -> 동적쿼리로..변경하면-_-;;;

 

WITH t1 AS
(
SELECT 1 id, 'AA' nm
UNION ALL SELECT 2, 'BB'
UNION ALL SELECT 3, 'CC'
--UNION ALL SELECT 4, 'DD'
)
, t2 AS
(
SELECT 1 cd, '가위' v
UNION ALL SELECT 2, '바위'
UNION ALL SELECT 3, '보'
)

select *
from
(SELECT * FROM t1 full outer join t2 on 1 =1 where t1.id = 1
) a    
     cross apply (SELECT * FROM t1 full outer join t2 on 1 =1 where t1.id = 2) b
     cross apply (SELECT * FROM t1 full outer join t2 on 1 =1 where t1.id = 3) c
where (  
          ( a.v = b.v and b.v = c.v )
       Or ( a.v <> b.v and b.v <> c.v and c.v <> a.v )
      )
    


by 선복 [2016.01.27 20:37:35]

우와 정말 쿼리문이 너무 아름다워요... 어떻게 이렇게 간단한 SQL문이 완벽한 답을 출력해 내는지.... 대단하십니다!!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입