코딩 테스트/Level 1

프로그래머스 / 공원 산책

컴닥 2023. 3. 24. 00:01
반응형

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

파이썬

def solution(park, routes):
    position = [0, 0]
    for i, row in enumerate(park):
        for j, each in enumerate(row):
            if each == 'S':
                position = [i, j]
    directions = {'E': (0, 1), 'W': (0, -1), 'N': (-1, 0), 'S': (1, 0)}
    for direction, distance in map(lambda x: x.split(), routes):
        prev_pos = position.copy()
        for _ in range(int(distance)):
            position[0] += directions[direction][0]
            position[1] += directions[direction][1]
            if not (0 <= position[0] < len(park) and 0 <= position[1] < len(park[0]) and park[position[0]][position[1]] != 'X'):
                position = prev_pos
                break
    return position
from itertools import chain


def solution(park, routes):
    position = [(start := tuple(chain(*park)).index('S')) // len(park[0]), start % len(park[0])]
    directions = {'E': (0, 1), 'W': (0, -1), 'N': (-1, 0), 'S': (1, 0)}
    for direction, distance in map(lambda x: x.split(), routes):
        prev_pos = position.copy()
        for _ in range(int(distance)):
            position[0] += directions[direction][0]
            position[1] += directions[direction][1]
            if not (0 <= position[0] < len(park) and 0 <= position[1] < len(park[0])
                    and park[position[0]][position[1]] != 'X'):
                position = prev_pos
                break
    return position

 

코틀린

class Solution {
    fun solution(park: Array<String>, routes: Array<String>): IntArray {
        var position = mutableListOf(0, 0)
        for (i in park.indices)
            for (j in park[i].indices)
                if (park[i][j] == 'S')
                    position = mutableListOf(i, j)
        val directions = mapOf('E' to (0 to 1), 'W' to (0 to -1), 'N' to (-1 to 0), 'S' to (1 to 0))
        for ((direction, distance) in routes.map { it[0] to it.drop(2).toInt() }) {
            val prevPos = position.toMutableList()
            for (each in 0 until distance) {
                position[0] += directions[direction]!!.first
                position[1] += directions[direction]!!.second
                if (!(0 <= position[0] && position[0] < park.size 
                                && 0 <= position[1] && position[1] < park[0].length
                                && park[position[0]][position[1]] != 'X')) {
                    position = prevPos
                    break
                }
            }
        }
        return position.toIntArray()
    }
}

함수형으로

class Solution {
    fun solution(park: Array<String>, routes: Array<String>): IntArray {
        val directions = mapOf('E' to (0 to 1), 'W' to (0 to -1), 'N' to (-1 to 0), 'S' to (1 to 0))
        val start = park.flatMap { it.map { each -> each } }.indexOf('S')
        return routes
                .map { it[0] to it.drop(2).toInt() }
                .fold(mutableListOf(start / park[0].length, start % park[0].length)) { pos, (direction, distance) ->
                    val prevPos = pos.toMutableList()
                    val nextPos = pos.toMutableList()
                    repeat(distance) {
                        nextPos[0] += directions[direction]!!.first
                        nextPos[1] += directions[direction]!!.second
                        if (!(0 <= nextPos[0] && nextPos[0] < park.size && 0 <= nextPos[1] && nextPos[1] < park[0].length && park[nextPos[0]][nextPos[1]] != 'X'))
                            return@fold prevPos
                    }
                    return@fold nextPos
                }.toIntArray()
    }
}

가독성을 고려하여..
!! 보다는 적절히 ?을 사용하고..

class Solution {
    private val directions = mapOf('E' to (0 to 1), 'W' to (0 to -1), 'N' to (-1 to 0), 'S' to (1 to 0))

    private fun findStart(park: Array<String>): MutableList<Int> {
        val start = park.flatMap { it.map { each -> each } }.indexOf('S')
        return mutableListOf(start / park[0].length, start % park[0].length)
    }

    private fun isValid(park: Array<String>, pos: List<Int>): Boolean {
        if (0 > pos[0] || pos[0] >= park.size
                || 0 > pos[1] || pos[1] >= park[0].length
                || park[pos[0]][pos[1]] == 'X')
            return false
        return true
    }

    private fun go(park: Array<String>, pos: MutableList<Int>, direction: Char, distance: Int): MutableList<Int> {
        val prevPos = pos.toMutableList()
        repeat(distance) {
            pos[0] += directions[direction]?.first ?: 0
            pos[1] += directions[direction]?.second ?: 0
            if (!isValid(park, pos))
                return prevPos
        }
        return pos
    }

    fun solution(park: Array<String>, routes: Array<String>): IntArray {
        return routes
                .map { it[0] to it.drop(2).toInt() }
                .fold(findStart(park)) { pos, (direction, distance) ->
                    go(park, pos, direction, distance)
                }
                .toIntArray()
    }
}

함수형으로 코딩하면 흐름을 파악하기 좋다. 

reduce (초기값을 위해 fold를 사용)가 이 코드의 주된 흐름이다.... 

반응형