240321 TIL
2024-03-22 02:04:55

오늘 한 일

  • 플머스 기초 트레이닝 문제

Tiny tips on Kotlin Competitive Programming

플머스 기초 알고 문제 풀면서 깨우친 잔잔바리 팁들을 정리해보았다. 주로 선언형보단 함수형 표현식으로 데이터를 간결하게 다루는 방법들을 나름대로 정리해 보았으며출처는 내 머리, 같은 문제를 먼저 푼 분들의 코드, 그리고 챗지피티 이다. 좀 더 길어지면 부문별로 나누어 새로 업로드 해야겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Pair 로 만들면 개별 요소에만 다른 연산 가능
val (str, n) = readLine()!!.split(' ').let { it[0] to it[1].toInt() }

// map 도 걸 수 있음
print(readLine()!!.split(' ').joinToString(""))

// 문자열 내의 특정 범위 대체 (endIndex exclusive)
fun String.replaceRange(startIndex: Int, endIndex: Int, replacement: String): String

// fold: 초기값 및 컬렉션 각 요소에 대해 적용할 연산을 인자로 받아 순회하며 연산 수행 & 결과 반환
intArrayOf(1,2,3,4).fold(0) { sum, element -> sum + element } // 10

// reduce: 초기값은 컬렉션의 첫 번째 요소로, 두 번째 요소부터 순회하며 주어진 연산 적용 & 결과 반환
intArrayOf(1,2,3,4).reduce { sum, element -> sum + element } // 10

// partition: 조건 함수에 따라 컬렉션을 두 개의 리스트로 분리하여 Pair<List,List> 형태로 반환함
val numbers = listOf(1, 2, 3, 4, 5)
val (even, odd) = numbers.partition { it % 2 == 0 } // [2,4], [1,3,5]

// 각 partition된 List 에 각각 연산을 적용하고 싶다면 let {} 을 쓰자
numbers.partition{}.let { (first, second) -> ... }

// map
val map = mapOf<Int>('a' to 3, 'b' to 4, 'c' to 5)
map.keys.first() // 'a','b','c'
map.keys.last() // 3,4,5

// 빈도 정리용 groupingBy(), eachCount()
val diceResults = listOf(3, 4, 3, 5) // 주사위 결과 예시
val groupedResults = diceResults.groupingBy { it }.eachCount()
println(groupedResults) // 출력: {3=2, 4=1, 5=1}

// string array 포문을 함수형으로 돌고 스트링값 리턴하는 경우
myStrings.indices.joinToString("") { // ... }

// 함수형식 for loop
myArr.indices.map { }
((idx..myArr).lastIndex).map { }

// 함수형으로 첫 조건 만족시 loop 정지
(i..j).firstOrNull { condition } ?: -1 // 단일 값 반환
(i..j).takeWhile { condition } // 리스트 반환

// generateSequence() 로 규칙적인 range 시퀀스 생성 +ft. lazy evaluation
// 호출될 때 값을 즉시 생성하지 않고 필요시 생성됨 -> 메모리 사용 최소화 & 무한 생성 가능
generateSequence(초기값/식, {생성 조건식})
.takeWhile { 조건식 }
.map { }
.blahBlah { }


// 첫 조건식에 해당하는 인덱스 반환
arr.indexOfFirst { it>0 }

// 배열 혹은 리스트 여러개 잘라 더하기

// 1. flatMap(): collection 각 요소에 함수 적용 후, 결과로 나온 여러 리스트를 하나로 평탄화
val listOfLists = listOf(listOf(1, 2), listOf(3, 4), listOf(5, 6))
val flatMapResult = listOfLists.flatMap { it.map { it * 2 } }
// flatMapResult: [2, 4, 6, 8, 10, 12]

// 2. map{}.flatten(): 먼저 map{} 으로 컬렉션의 각 요소에 함수를 적용하고 그 결과로 나온 이중리스트를 flatten()으로 평탄화
// map{}, flatten() 따로 수행하므로 중간 리스트가 생성되어 성능에 안좋을 수 있음
val result = listOfLists.map { it.map { it * 2 } }.flatten()
// result: [2, 4, 6, 8, 10, 12]


// 하나의 리스트를 n 개씩 쪼개고 추가적인 변형을 하고 싶을때.
// chunked splits the collection into sublists of a given size.
val result = str_list.toList().chunked(n) { it[0] }


// Kotlin Regex
// \d: a digit, \\d+: one or more digits
// * (0 or more), + (1 or more), ? (0 or 1), and {n,m} (between n and m)
// [abc] matches any single character a, b, or c
// Ranges can be specified, like [a-z]
// anchors: ^: start, $: end
myString.trim().split("\s+".toRegex())

// email validation
val emailRegex =
"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$".toRegex()
val email = "example@test.com"
val isValidEmail = email.matches(emailRegex)

//zip 쓰기
str1.zip(str2).joinToString("") { (a, b) -> "$a$b" }

// 요소 뒤에 n개만 추가/제거 된다면? -> Stack
import java.util.*
stack.push(arr[i]) else stack.pop()


// 최소힙 Priority Queue 사용하기
import java.util.PriorityQueue
val pq = PriorityQueue<T>(compareBy {}) // pair.first 이런 식으로 복합 자료구조의 특정 요소로 비교 가능
pq.peek()
pq.poll() // 스택의 Pop()과 같음. 기존 pq에서 제거하면서 그 요소를 가져옴


// 실수에서 정수로
ceil(number).toInt() // 올림 후 정수 변환
floor(number).toInt() // 내림 후 정수 변환
round(number).toInt() // 반올림 후 정수 변환
Prev
2024-03-22 02:04:55
Next