TIL

Coding Test

프로그래머스 코딩테스트 17일차 문제풀이 완료

  • 숨어있는 숫자의 덧셈 (2)
  • 안전지대
  • 삼각형의 완성조건 (2)
  • 외계어 사전

안전지대 문제

링크: https://school.programmers.co.kr/learn/courses/30/lessons/120866

2차원 배열의 board에 지뢰가 존재하는 곳에 1이, 없으면 0이라는 값이 존재한다고 했을때, 해당 board를 입력하면 안전지대의 수를 출력하는 함수를 완성해야한다. 이때 지뢰가 있으면 주변 1곳씩은 위험지대로 간주한다.

아래처럼 문제를 풀긴 했지만 테스트가 정말 딱 하나가 실패했다.

function solution(land) {
// 지뢰가 어디있는가?
let mineSpot = land.flat().indexOf(1)
// 지뢰가 있는곳을 모두 파악한다. 
let mineList = []
let obj ={}
let col = 0
let row = 0
while(mineSpot != -1){
  mineList.push(mineSpot)
  mineSpot = land.flat().indexOf(1, mineSpot+1);
}
// 위험지역 선정하기. 지뢰지역의 주변 1칸씩이 모두 위험 지역이 된다.

for (let e of mineList){
    col = Math.floor(e / land.length )
   row = e % land[0].length

  // col이 첫번째인 경우
  if (col === 0){
    // row 가 2번째에서 4번째 사이에 있는 경우
   (1 <=row && row < land.length-2 ) ?  [
land[col].splice(row-1,3,1,1,1),
     land[col+1].splice(row-1,3,1,1,1),
   ]
    //row가 맨 끝에 있는 경우
  : row === land.length-1 ?
     [land[col].splice(row-1,2,1,1), land[col+1].splice(row-1,2,1,1)]
  // row가 맨 처음에 있는 경우
  :
   [land[col].splice(row,2,1,1),land[col+1].splice(row,2,1,1)]
  
  }
  // col 이 2번째와 끝에서 2번째사이에 있는 경우
  else if ( 1<= col && col <= land.length-2){
    // row 가 2번째에서 4번째 사이에 있는 경우
  (1 <= row && row < land[0].length -2 ) ? 
    [ land[col-1].splice(row-1,3,1,1,1),
  land[col].splice(row-1,3,1,1,1),
  land[col+1].splice(row-1,3,1,1,1)]
    //row가 맨 끝에 있는 경우
  : row === land[0].length-1 ?
    [  land[col-1].splice(row-1,2,1,1),
  land[col].splice(row-1,2,1,1),
  land[col+1].splice(row-1,2,1,1)]
      // row가 맨 처음에 있는 경우
  :   [land[col-1].splice(row,2,1,1),
  land[col].splice(row,2,1,1),
  land[col+1].splice(row,2,1,1)] 
   }
  // col이 맨 끝일 경우
  else{
    (1 <= row && row < land[0].length - 2) ? [ land[col-1].splice(row-1,3,1,1,1),
  land[col].splice(row-1,3,1,1,1)]
  : row === land[0].length - 1 ? [ land[col-1].splice(row-1,2,1,1),
  land[col].splice(row-1,2,1,1)]
  :    
    [land[col-1].splice(row,2,1,1),
  land[col].splice(row,2,1,1)]
  }  
}

    return  land.flat().filter((e) => e === 0).length
}

뭐가 문제였는가?

처음에 입출력 예시를 자세히 안보고 그냥 5x5 형태인 board라고 생각했는데 nxn 형태였다. 그말은 즉슨 1x1의 board 일 경우에도 생각을 해야하는데 코드 후반부의 splice는 보다시피 지뢰가 board 가운데에 위치한 경우에는 3개 적게는 2개의 값을 교체하는 방식으로 이루어져있다.

만약 1x1 형태의 경우라면 이런 splice의 값들이 전부 null로 나오기 때문에 런타임 에러가 발생한것!

어떻게 해결했는가?

결국 1x1 형태의 경우를 따로 작성했음

if (land[0].length===1) {
    return land[0][0] === 1? 0 : 1
} 

만약 2차원 배열의 첫번째 인덱스의 length가 1이라면(해당 board는 정사각형 배열이므로 하나의 인덱스 길이만 비교해도 문제 없다고 생각함) 단 하나의 값을 보고 안전지대의 수를 경우에 따라 리턴하게 설정함

코딩 테스트를 하면서 예외의 경우를 항상 고려해야 한다고 느꼈다. 정말 이 하나의 예외때문에 오답이 되어버리다니..

JavaScript

.splice() : 대상 배열에 요소를 추가하거나 삭제하거나 교체한다. 대상배열의 원본이 변경되므로 사용에 주의할 것

  • 요소 추가
let list = [1,2,3,4,5]

list.splice(2,0,"추가된 요소") // 시작 인덱스, 제거 개수, 대채 요소내용 순서로 작성한다.


console.log(list) // [1,2,"추가된 요소",3,4,5]
  • 요소 제거
let list = [1,2,3,4,5]

list.splice(1,1) //1번 인덱스를 시작으로 하나 제거해줘

console.log(list) // [1,3,4,5]
  • 요소 교체
let list = [1,2,3,4,5]

list.splice(1,1,"이") //1번 인덱스 제거하고 맨 마지막에 적힌 내용으로 교체한다!

console.log(list) // [1,"이",3,4,5]
  • 요소 추가 및 삭제
let list = [1,2,3,4,5]

list.splice(0,0,"이","삼","사") // 0개 제거하고 0번 인덱스자리에 내용을 추가한다.

console.log(list)

unshift() : 새로운 요소를 대상 배열의 맨 앞에 추가하고 새로운 배열 길이를 반환한다. 대상 배열 원본이 변경된다.

let list = [1,2,3,4,5]

list.unshift("하이")

console.log(list) //  ["하이",1,2,3,4,5]

Array.from() : 유사 배열을 실제 배열로 반환한다.


const arraylike = {
  0: 'ham',
  1: 'bur',
  2: 'ger',
  length: 3
}


console.log(arraylike.constructor === Array) // false
console.log(arraylike.constructor === Object) // true


Array.from(arraylike).forEach(item => console.log(item)) // "ham","bur","ger"

Array.isArray() : 배열 데이터인지 확인한다.

const array =['ham','bur','ger']
const arraylike = {
  0: 'ham',
  1: 'bur',
  2: 'ger',
  length: 3
}

console.log(Array.isArray(array)) // true
console.log(Array.isArray(arraylike)) // false

Object

Object.assign() : 하나 이상의 출처 객체로부터 대상 객체로 속성을 복사하고 대상 객체를 반환한다.

const target = { a: 1, b: 2 }
const source1 = { b: 3, c: 4 }
const source2 = { c: 5, d: 6 }
const result = Object.assign(target, source1, source2)

console.log(target) // { a: 1, b: 3, c: 5, d: 6 }
console.log(result) // { a: 1, b: 3, c: 5, d: 6 }

만약 원본 객체가 수정되는 것을 원하지 않으면 요소에 빈 객체를 추가해주면 된다.

const target = { a: 1, b: 2 }
const source1 = { b: 3, c: 4 }
const source2 = { c: 5, d: 6 }
const result = Object.assign({}, target, source1, source2)

console.log(target) // { a: 1, b: 2 }
console.log(result) // { a: 1, b: 3, c: 5, d: 6 }

아니면 전개 연산자를 사용해도 된다.

const target = { a: 1, b: 2 }
const source1 = { b: 3, c: 4 }
const source2 = { c: 5, d: 6 }
const result = {
  ...target,
  ...source1,
  ...source2
}

console.log(target) // { a: 1, b: 2 }
console.log(result) // { a: 1, b: 3, c: 5, d: 6 }

Object.entries() : 주어진 객체의 각 속성과 값으로 하나의 배열을 만들어서 요소로 추가한 2차원 배열을 반환한다.

const jyc = {
  name: 'jyc',
  age: 28,
  favfood: 'hamburger',
  email: 'jyc4648@gmail.com'
}

console.log(Object.entries(jyc))
/* 
[
	["name", "jyc"],
    ["age","28"],
    ["favfood","hamburger"],
    ["email","jyc4648@gmail.com"]
    
]
}*/

Object.keys() : 주어진 객체의 속성 이름을 나열한 배열을 반환한다.

const jyc = {
  name: 'jyc',
  age: 28,
  favfood: 'hamburger',
  email: 'jyc4648@gmail.com'
}

console.log(Object.keys(jyc)) //["name","age","favfood","email"]

Object.values() : 주어진 객체의 속성 값을 나열한 배열을 반환한다.

const jyc = {
  name: 'jyc',
  age: 28,
  favfood: 'hamburger',
  email: 'jyc4648@gmail.com'
}

console.log(Object.values(jyc)) //["jyc",28,"hamburger","jyc4648@gmail.com"]

Object.freeze(), Object.isFrozen() : 주어진 객체를 변경하지 못하게 동결시기고, 동결의 여부를 확인하는 메소드

const jyc = {
  name: 'jyc',
  age: 28,
  favfood: 'hamburger',
  email: 'jyc4648@gmail.com'
}

console.log(jyc) /* 
	{"name":"jyc"
    "age":"28"
    "favfood":"hamburger"
    "email":"jyc4648@gmail.com"}
    */

console.log(Object.isFrozen(jyc)) //false

Object.freeze(jyc) // 동결

jyc.age = 22

console.log(jyc) /* 
	{"name":"jyc"
    "age":"28"
    "favfood":"hamburger"
    "email":"jyc4648@gmail.com"}
    */ 
console.log(Object.isFrozen(jyc)) // true

Object.seal(), Object.isSealed(): 주어진 객체를 변경할 수 없도록 밀봉하거나, 밀봉 여부를 확인한다. 동결과 다른점은 밀봉후에도 속성값은 변경 가능하다.

수정은 가능하지만 추가는 안됨

const jyc = {
  name: 'jyc',
  age: 28,
  favfood: 'hamburger',
  email: 'jyc4648@gmail.com'
}

console.log(jyc) /* 
	{"name":"jyc"
    "age":"28"
    "favfood":"hamburger"
    "email":"jyc4648@gmail.com"}
    */

console.log(Object.isSealed(jyc)) //false

Object.seal(jyc) // 밀봉!

jyc.age = 22 //값이 수정되는것은 가능하다!

console.log(jyc) /* 
	{"name":"jyc"
    "age":"22"
    "favfood":"hamburger"
    "email":"jyc4648@gmail.com"}
    */ 
console.log(Object.isSealed(jyc)) // true

Object.defineProperty() : 주어진 객체에 속성을 추가하거나, 특성을 변경한다. 다른 사용자가 데이터를 가져오려고 할때 감시의 용도로 사용할 수 있다.

속성:기본값설명
enumerable: false속성의 열거 가능 여부
configurable: false속성의 수정(이미 존재할 때), 삭제 가능 여부
writable: false속성의 값 변경 가능 여부
value: undefined속성의 값
get: undefined속성의 Getter
set: undefined속성의 Setter

Object.defineProperties() : 주어진 객체에 여러 속성을 추가하거나 ,특성을 변경한다.

const user = {}
Object.defineProperties(user, {
  name: {
    enumerable: true,
    value: 'jyc'
  },
  age: {
    enumerable: true,
    value: 28
  },
  email: {
    enumerable: true,
    configurable: true,
    writable: true,
    value: []
  },
  address: {
    value: '전남'
  }
})

console.log(user)
for (const key in user) {
  console.log(key)
}
// 'name'
// 'age'
// 'email'

Json

JSON(JavaScript Object Notation)는 데이터 전달을 위한 표준 데이터 포맷

  • 문자,숫자, 불린,null,객체,배열만 사용
  • 문자는 큰 따옴표만 사용
  • 후행 쉼표 사용 불가
  • .json 확장자 사용

.stringify() : JavaScript 데이터를 json 문자로 변환

console.log(JSON.stringify('Hello world!')) // '"Hello world!"'
console.log(JSON.stringify(123)) // '123'
console.log(JSON.stringify(false)) // 'false'
console.log(JSON.stringify(null)) // 'null'
console.log(JSON.stringify({ name: 'Heropy', age: 85 })) // '{"name":"Heropy","age":85}'
// console.log(JSON.stringify({ name: 'Heropy', age: 85 }, null, 2))
console.log(JSON.stringify([1, 2, 3])) // '[1,2,3]'

.parse() : JSON 문자를 분석해서 javascript 데이터로 변환한다.

console.log(JSON.parse('"Hello world!"')) // "Hello world!"
// console.log(JSON.parse('Hello world!'))
// console.log(JSON.parse("Hello world!"))
console.log(JSON.parse('123')) // 123
console.log(JSON.parse('false')) // false
console.log(JSON.parse('null')) // null
console.log(JSON.parse('{"name":"Heropy","age":85}')) // { name: 'Heropy', age: 85 }
console.log(JSON.parse('[1,2,3]')) // [1, 2, 3]

모듈

이해 가능한, 보다 작은 단위로 나눠진것
자바스크립트에서 파악하면 모듈은 특정 데이터들의 집합이다.

내보내기(exports)

기본 내보내기 (Default exports)

  • 이름 지정할 필요가 없다.
  • 모듈당 단 1번만 가능하다

이름 내보내기 (Named exports)

  • 이름을 무조건 지어야한다
  • 모듈당 n번 사용가능!
profile
개발자 꿈나무

0개의 댓글