문제 링크
문제 해설
리눅스의 파일 권한과 관련된 문제. 관련 지식이 있다면 어렵지 않게 풀 수 있다.
우선 각 권한을 2진수로 바꿔보자.
\begin{align*}
000 &\to 권한 없음\\
001 &\to 실행 가능\\
010 &\to 수정 가능\\
011 &\to 실행 및 수정 가능\\
100 &\to 읽기 가능\\
101 &\to 읽기 및 실행 가능\\
110 &\to 읽기 및 수정 가능\\
111 &\to 읽기, 수정, 실행 모두 가능
\end{align*}
여기서 \(2^2\)에 해당하는 비트는 읽기 권한을, \(2^1\)에 해당하는 비트는 수정 권한을, \(2^0\)에 해당하는 비트는 실행 권한을 나타낸다는 것을 알 수 있다.
유저의 권한그룹이 갖는 권한과 유저가 수행하려는 작업에 해당하는 숫자를 AND 연산해서 그 결과가 수행하려는 작업에 해당하는 숫자라면 해당 작업을 수행할 수 있다는 뜻이 된다.
이제 구현을 해보자.
각 유저는 유저의 이름에 해당하는 그룹에 포함되고, 추가적으로 입력으로 주어지는 그룹이 더 있다면 해당 그룹에도 포함된다.
val userGroup = HashMap<String, Set<String>>()
repeat(u) {
StringTokenizer(readLine()).apply {
val user = nextToken()
val group = HashSet<String>().apply { add(user) }
if (hasMoreTokens()) StringTokenizer(nextToken(), ",").apply { while (hasMoreTokens()) group.add(nextToken()) }
userGroup[user] = group
}
}
각 파일의 정보를 Map에 저장해준다. 이 때 각 파일별로 부여된 권한과 소유자, 소유 그룹에 대한 정보를 갖는 File 클래스도 작성해준다.
val files = HashMap<String, File>()
repeat(f) { _ ->
StringTokenizer(readLine()).apply { files[nextToken()] = File(nextToken().run { IntArray(3) { get(it) - '0' } }, nextToken(), nextToken()) }
}
private class File(val mode: IntArray, val owner: String, val group: String)
마지막으로 파일에 수행하려는 작업의 성공 여부를 판별해주면 된다.
작업을 하려는 유저가 소유자라면 mode
의 0번째 요소, 소유자가 아니지만 소유그룹에 포함된다면 1번째 요소, 둘 다 아니라면 2번째 요소를 가져와서 수행하려는 작업에 해당하는 숫자와 AND 연산을 해서 성공 여부를 판별해주면 된다.
repeat(readLine().toInt()) {
StringTokenizer(readLine()).apply {
val user = nextToken()
val fileName = nextToken()
val command = nextToken()
val file = files[fileName]!!
val mode = file.mode.let { if (file.owner == user) it[0] else if (userGroup[user]!!.contains(file.group)) it[1] else it[2] }
val success = when (command) {
"R" -> mode and 4 == 4
"W" -> mode and 2 == 2
"X" -> mode and 1 == 1
else -> false
}
bw.write(if (success) "1\n" else "0\n")
}
}
Code
import java.util.StringTokenizer
fun main() = with(System.`in`.bufferedReader()) {
val bw = System.out.bufferedWriter()
val (u, f) = readLine().split(' ').map { it.toInt() }
val userGroup = HashMap<String, Set<String>>()
repeat(u) {
StringTokenizer(readLine()).apply {
val user = nextToken()
val group = HashSet<String>().apply { add(user) }
if (hasMoreTokens()) StringTokenizer(nextToken(), ",").apply { while (hasMoreTokens()) group.add(nextToken()) }
userGroup[user] = group
}
}
val files = HashMap<String, File>()
repeat(f) { _ ->
StringTokenizer(readLine()).apply { files[nextToken()] = File(nextToken().run { IntArray(3) { get(it) - '0' } }, nextToken(), nextToken()) }
}
repeat(readLine().toInt()) {
StringTokenizer(readLine()).apply {
val user = nextToken()
val fileName = nextToken()
val command = nextToken()
val file = files[fileName]!!
val mode = file.mode.let { if (file.owner == user) it[0] else if (userGroup[user]!!.contains(file.group)) it[1] else it[2] }
val success = when (command) {
"R" -> mode and 4 == 4
"W" -> mode and 2 == 2
"X" -> mode and 1 == 1
else -> false
}
bw.write(if (success) "1\n" else "0\n")
}
}
bw.close()
}
private class File(val mode: IntArray, val owner: String, val group: String)
'Algorithm > BOJ' 카테고리의 다른 글
[Kotlin] 백준 13199 : 치킨 먹고 싶다 (0) | 2024.03.25 |
---|---|
[Kotlin] 백준 3107 : IPv6 (0) | 2024.02.20 |
[Kotlin] 백준 11082 : 소수를 분수로 (0) | 2023.12.11 |
[Kotlin] 백준 1850 : 최대공약수 (2) | 2023.11.11 |
[Kotlin] 백준 30036 : INK (0) | 2023.10.25 |
댓글