본문 바로가기
GAS

[GAS] 중복없는 로또번호 만들기

by 일등미노왕국 2023. 4. 17.

https://www.youtube.com/watch?v=dX3krhu1PqM&list=PLxmyPu_Id2smCXbzw2IgsRpizPIaR8G-i&index=5 

 

앱스 스크립트로 로또번호를 생성하는 코드이다.

기존에 본인이 했던 VBA로 만드는 코드에서는 Colection을 통해서 중복된 수가 나오면 중복된 수가 없을 때 까지 무한반복해서 로또 번호를 추출하곤 했다.

 

이 코드에서는 1부터 45까지 배열을 만든 후 이것을 복사하여 번호가 추출이 되면 그 번호를 빼곤 다시 추출하여 중복되는 수가 애초에 발생하지 않도록 하고 있다.

 

EXCEL AND VBA님은 이것을 위해 JSON.stringify로 배열을 String화 한 후 다시 JSON.parse를 통해 배열의 사본을 위해 복사하는 코드를 만들었지만,

let values = JSON.parse( JSON.stringify(machine)) ;

 

배열의 사본을 만드는 것은 이방법보다 더 쉬운 방법이 있다. 바로

let tmp =   machine.slice();

이 한줄이다.

 

자그럼 복제를 안하면 어찌 될까?  

splice 함수는 slice 함수와는 다르게 도마뱀 코리를 자르듯 배열에서 슬라이싱 된 만큼 기존 배열의 값도 변경하게 만든다.

그렇기에 횟수가 반복진행될 수록 45개의 숫자는 한번씩만 사용되고 더이상 재활용이 되지 않는다.

 

그렇기 때문에 배열을 복제해야 하는 것이다.

 

더보기
function Lotto() {
  let sht = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0],   // sht 시트선언
      iCnt = sht.getRange("c2").getValue(),                         // 횟수 선언 
      rows=[],                                                      // 6개의 로또 번호를 담을 배열
      row,                                                          // 하나의 로또 번호들을 담을 변수      
      machine = get_From_A_to_B(1,45);                              // 1부터 45번까지 차례로 담기 위한 변수

  // 변수 선언하기 콤마(,)로 연결하면 쭉 이어서 선언할수 있음 / 단 마지막은 세미콜론(;)으로 마루리해야함

      for(let i=1 ; i <= iCnt ; i++){
        row = [];      
        
        let tmp =   machine.slice();                                // machine 배열의 사본(복제)

        for(let c=1; c<= 6 ; c++){
          
          row.push(tmp.splice(parseInt( Math.random()*tmp.length), 1)[0]  );
                   // splice는 tmp 배열에서 무작위로 하나씩 row배열로 넣은 후 tmp 배열에서 삭제함
                   // 이렇기 때문에 중복수가 발생하지 않음.
        }

        rows.push(row);                                            // 전체출력해할 배열에 담음
      }

  sht.getRange(6,2,100,6).clearContent();                          // 기존 영역 삭제 
  sht.getRange(6,2, rows.length, rows[0].length).setValues(rows);  // 완성된 로또 번호를 셀에 출력

  
}

function get_From_A_to_B(i,j) {
  
  let result = [];

  for (let m=i; m<=j ; m++){
    result.push(m);                                                 // 1부터 45까지의 번호를 result 배열에 
                                                                    // 순서대로 담아라    
  }
    return result;
}

아직은 눈에 많이 익숙하지 않아서 오타도 많고 갑자기 공부할 양도 많이 늘었지만, 결국 우리는 또 이녀석을 정복하게 될것이다. 늘 그랬듯

 

https://docs.google.com/spreadsheets/d/1UJEOae4DDJkcm0DcVxdn2aAXrJpTM0HKUFTEDJbavqE/edit?usp=sharing

 

댓글