상세 컨텐츠

본문 제목

어이없이 쉬운 별 삼각형 맹글깅

자바스크립트

by e7e 2023. 7. 22. 12:04

본문

요즘에도 마니 그러한지는 정확하게 난 알 수 없지만(안 그런 것 같당 느낌이당) 한때는 코딩테스트

의외로 뜬금없이 예상치 않은 순간에 불쑥 해보라는 질문에  초보자들 또는 로직이 약한 개발자의

머릿속을 대체 여긴 어디얌 몇시얌?  시공간 구분 능력을 상실케 맹그는 질문이  바로

별 삼각형을 출력하는 프로그램을  후다닥 맹글어 보시옹 질문이었당.

 

개인적인 생각이지만 아마 아직도 현직에서 개발자로 일하면서도 별삼각형을 못 맹그는 개발자가

분명 꽤 있지 않을까 싶당. 외워서 했다면 당연 시간이 흐르면 기억이 흐리니 할 수 없을 거시당.

지금 바로  한번 해보면 어떨까싶당. (자신을 주기적으로 돌아보는 시간은  마니 피로하당!)

 

역시 항상 그렇지는 않지만, 별삼각형 그리기는 말 그대로 거저 거저 그냥 쉽당.

 

별삼각형 그리기는 그냥 글자로 하면 폰트에 영향을 받아 삼각형 모양이 쪼메 찌그러질 수 있는뎅,

전각문자, 반각문자란게 있어서 그 넓이가 다르기 때문이당. 

그래서 정확히 같은 사이즈의 네모를 리턴해주는 함수 fRetDiv를 맹글어서 글자를 넘긴당.

그럼 글자가 들어있는 네모또는 비어있는(보이지 않는) div태그로 만든 네모를 리턴해 준당.

 

로직을 외우기보다는 흐름의 잔상(연상)을 기억에 남기는 거시 좋당.

오른쪽 반쪽짜리 삼각형을 맹글고, 다음엔 왼쪽 반쪽짜리 삼각형을 만들어 보면, 저절로

트리모양 삼각형을 만드는 산수가 보이게 된당.

핵심은 줄단위로 빈칸을 갯수에 맞춰 잘 넣고, 줄 마다 들어가야 할 별의 갯수가 1,3,5,7,9....

식으로 즉 줄넘버를 N이라 하면 2N-1개가 들어감을 인지하는 순간 그저 코딩이 귀찮아진당.

 

너무도 쉽고 쉬운 문제로 잼나게 DIV에 비디오라도 넣어볼까 생각했지만, 본질을 흐릴수도

있다는 생각에 그저 랜덤한 색깔정도 넣는 거스로 그냥 정했당.(역시 내맘이당.)

 

일부러 합칠 수도 있는 함수를 각각 분리해 놓았으니, 이해하는 데는 에너지 소비가 거의 없당.

아래 소스를 오므라이스에 뿌리듯 카피.붙여넣기로 실행결과와 소스라인을 누느로 잘 맞춰보장!

 

starTriangle.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>E7E 메롱</title>
    <style>
        * {
            margin:0; padding: 0;
            box-sizing: border-box;
            text-align: left;
        }
        #wrapper {
            margin:15px auto;
            width:600px;
            text-align: center;
 /*레이아웃체크용      border: 1px solid blue; */
        }
        .commonNemo {
            width:15px;
            height:15px;
            text-align: center;
        }
        .viewNemo {
            display:inline-block;
            border:1px solid black;
            font-weight: bolder;
            line-height: 110%;
            font-size: 1.2em;
        }
        .blankNemo {
            display:inline-block;
            border:1px solid white;
            backface-visibility: hidden;
        }
        .oneB {
            display: inline-block;
            padding-left: 80px;
            width:49%;
            height:230px;
            border: 1px solid blue;
            border-radius: 25%;
        }
        .oneA {
            margin:0 auto;
            padding-left: 16%;
            width:80%;
            height:230px;
            border: 1px solid blue;
            border-radius: 15%;
        }
        #sndRow {
            width:100%;
        }
        h1 {
            background-color: orange;
        }
        #disp {
            position: relative;
            margin:0 auto;
            top:30px;
            left:-200px;
            width:1000px;
            height:340px; 
            border: 1px solid black;
            text-align: center;
            padding-top: 50px;
        }
    </style>
</head>
<body>
<div id="wrapper">
    <h1>&copy; E7E 어이없당 삼각형</h1><br>
    <input type=button value="◣맹글기" onclick="f1Triangle()">
    <input type=button value="◢맹글기" onclick="f2Triangle()">
    <input type=button value="▲맹글기" onclick="f3Triangle()">
    <input type=button value="▲돌려붙이깅" onclick="fRotTri()">
    &nbsp;&nbsp;배경블랙<input type="checkbox" onclick="fBackBlack(this)"><br><br>
    <div id="fstRow">
        <div class="oneB"></div>
        <div class="oneB"></div>
    </div>
    <div id="sndRow">
        <div class="oneA"></div>
    </div>
    <div id="disp">
    </div>
</div>
<script>
//전역
const myWrapper = document.querySelector("#wrapper");
const myFstRow = document.querySelector("#fstRow");
const mySndRow = document.querySelector("#sndRow");
const myDisp = document.querySelector("#disp");
const myOneA = document.querySelector(".oneA");

//rgba로 색깔 랜덤하게 돌려주는 함수!
function fRetColor(){
    let vRed = Math.round(Math.random()*255);
    let vGreen = Math.round(Math.random()*255);
    let vBlue = Math.round(Math.random()*255);
    let vAlpha = "0." + Math.round(Math.random()*9);
    if(vAlpha == "0.0") vAlpha = "1";
    return `rgba(${vRed},${vGreen},${vBlue},${vAlpha})`;
}

//안 빈 네모 색깔 화려하겡, 동적바인딩 개념 자브시옹
let timer=null;
function fNemoColor(){
    // 동적 바인딩! - 찾아놓은 거시 아니공, 할때 마다 다시 찾음!
    let viewNemos = document.querySelectorAll(".viewNemo")
    for(let i=0; i<viewNemos.length; i++){
        viewNemos[i].style.backgroundColor= fRetColor();
    }
    timer=setTimeout(fNemoColor,200);
}

// 네모난 div를 리턴해주는 함수
function fRetDiv(p_char){     
    let nemoDiv = document.createElement("div");
    if(p_char){ // * 들어있는 네모
        nemoDiv.setAttribute("class","viewNemo commonNemo");
        nemoDiv.style.backgroundColor = fRetColor();
        nemoDiv.innerHTML = p_char;
    }else {   // 비어있는 네모
        nemoDiv.setAttribute("class","blankNemo commonNemo");
    }
    return nemoDiv;
}

// 삼각형 그리깅
var v_maxLine = 10; // 몇줄짜링?
// 오른쪽 반쪽 삼각형
function f1Triangle(){
    let posDiv = myFstRow.children[0]; 
    posDiv.innerHTML = "";
    for(let i=1; i<=v_maxLine; i++){
        for(let k=1; k<=i; k++){
            posDiv.appendChild(fRetDiv("*"));
        }
        posDiv.innerHTML += "<br>";
    }
    if(!timer) fNemoColor();
}

//왼쪽 반쪽 삼각형
function f2Triangle(){
    let posDiv = myFstRow.children[1]; 
    posDiv.innerHTML = "";
    for(let i=1; i<=v_maxLine; i++){
        //공백(스페이스바)네모
        for(let j=1; j<=v_maxLine-i; j++){
            posDiv.appendChild(fRetDiv(""));
        }
        // 별네모
        for(let k=1; k<=i; k++){
            posDiv.appendChild(fRetDiv("*"));
        }
        posDiv.innerHTML += "<br>";
    }
    if(!timer) fNemoColor();
}

// 완성된 트리 삼각형
function f3Triangle(){
    let posDiv = mySndRow.children[0]; 
    posDiv.innerHTML = "";
    for(let i=1; i<=v_maxLine; i++){
        for(let j=1; j<=v_maxLine-i; j++){
            posDiv.appendChild(fRetDiv(""));
        }
        for(let k=1; k<=(i*2)-1; k++){
            posDiv.appendChild(fRetDiv("*"));
        }
        posDiv.innerHTML += "<br>";
    }
    if(!timer) fNemoColor();
}

// 복사해서 회전된 삼각형 3개 맹글깅
let rotState=false;
function fRotTri(){
    if(myOneA.innerHTML==""){
        alert("복사할 Node가 비어있어용 쏘링!");
        return;
    }
    myDisp.innerHTML="";
    let rotGak=0;
    for(let i=1; i<=3; i++){
        rotGak += 90;
        let cloneOneA = myOneA.cloneNode(true);
        cloneOneA.style.padding=0;
        cloneOneA.style.display="inline-block";
        cloneOneA.style.width="300px";
        cloneOneA.style.transform=`rotate(${rotGak}deg)`;
        myDisp.appendChild(cloneOneA);
    }
    //console.log("체킁",myWrapper.getBoundingClientRect().height)
    if(!rotState){
        myWrapper.style.height = myWrapper.getBoundingClientRect().height + 50 +"px";
        rotState=!0;
    }
}

// 배경 까맣게 맹글어서 비어있는 네모 보이겡(삼각형그리기 로직체크용)
function fBackBlack(pThis){
    if(pThis.checked){
        for(let i=0; i<myFstRow.children.length; i++){
            myFstRow.children[i].style.backgroundColor="black";
        }
        mySndRow.children[0].style.backgroundColor="black";
    }else {
        for(let i=0; i<myFstRow.children.length; i++){
            myFstRow.children[i].style.backgroundColor="white";
        }
        mySndRow.children[0].style.backgroundColor="white";
    }
}
</script>
</body>
</html>

내 브라우져는 나에게 아래 그림과 같은 잔상을 남겨주었당.

배경을 블랙으로 체크하면, 빈 네모칸(글자로 치면 스페이스)이 보여서 로직자체가 누네 들어와 버린당.

항상 자신의 아이디어를 추가하여 재창조 작업을 즐기장. 그 순간 당신은 이미 최고당!

 

 

별인지 인공위성인지 모를 외롭고 히미함에 지친 멍청한 빛 1개와 천 쪼가리 모양 달이

짙은 어둠의 무게가 버거워 먹구름 뒤에 숨지 않아도 은폐 엄폐가 절로 일어나던 그날 밤

어둠을 담아 똑 또오옥 똑 똑 또오똑 또오똑 아주 똑똑하게 누군가 문을 Knock Knock 한당.

 

머징?  이미 침대라 넘 귀찮당.. 지쳐서 가겠징!

또도독 또도독 또오로로 또오로로  똑똑똑 또오똑 또오똑 또오겠다는 드시 마구 더 두드린당.

 

어둡고, 불안하지만 할 수 없당.  문을 연당. 허억

"문을 열었넹!~~"  악귀가 문밖에서 정갈하지 못한 긴 머리카락과 내리 깐 눈과

오래된 피인지, 새로 산 케찹인지 모를 뻘건 침 흘림을 하고 갸웃한 고개를 누나페 드리민당.

아우 무서! 무서!

 

"너엉~~ 근데 여기 천국인데 괜찮겠엉?  드러와 드러와! "   악귀는 머엉...............

"난 천국 교향악단 지휘자 천소음이라 해 방가 방가~~"

그날이후 악귀는 천국교향악단 소속의 악기가 되어 악귀소리를 내어야만 했당.

 

악기얌 악귀얌 악귀얌 악기얌 내 욕망 주껭! 오래 오래 잘살앙!~~

 

악귀의 악기소리는 인간계에 요따구로 귀에 들렸다고 한당.

"Knock Knock Knockin' On Heaven's Door!"

 

https://www.youtube.com/watch?v=_0DkuuhvaeQ 

 

관련글 더보기