Skip to content

Instantly share code, notes, and snippets.

View yongjhih's full-sized avatar
🏠
Working from home

Andrew Chen yongjhih

🏠
Working from home
View GitHub Profile
class Solution {
val cache: MutableMap<Int, Int> = mutableMapOf()
fun climbStairs(n: Int): Int {
if (n <= 0) return 0
if (n == 1) return 1
if (n == 2) return 2
if (cache[n] != null) return cache[n]!!
val res = climbStairs(n-1) + climbStairs(n-2)
cache[n] = res
class Solution {
fun findKthLargest(nums: IntArray, k: Int): Int {
return findKthSmallestInPlace(nums.toList(), nums.indices, nums.size - k)!!
}
fun findKthSmallestInPlace(nums: MutableList<Int>, range: IntRange, i: Int): Int? {
if (nums.isEmpty()) return null
if (nums.size == 1) return nums.first()
if (range.toList().isEmpty()) return null
fun CharSequence.indicesOf(pattern: String): Sequence<Int> = sequence {
var startIndex = 0
while (true) {
startIndex = indexOf(pattern, startIndex)
if (startIndex < 0) break
yield(startIndex)
startIndex += pattern.length
}
}
fun CharSequence.replacePatternsSorted(patterns: Iterable<String>, onReplace: (CharSequence) -> CharSequence): CharSequence =
replacePatterns(patterns.sortedByDescending { it.length }, onReplace)
fun CharSequence.replacePatterns(patterns: Iterable<Regex>, onReplace: (CharSequence) -> CharSequence): CharSequence {
val patternsIterator = patterns.iterator()
if (!patternsIterator.hasNext()) return this
val matches = patternsIterator.next().findAll(this)
val nextPatterns = patternsIterator.asSequence().toList()
if (!matches.iterator().hasNext()) return replacePatterns(nextPatterns, onReplace)
fun Context.outputStreamOrThrow(fileName: String, type: String = Environment.DIRECTORY_DOWNLOADS) =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentResolver.run {
openOutputStream(insert(
MediaStore.Downloads.EXTERNAL_CONTENT_URI,
ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(MediaStore.MediaColumns.RELATIVE_PATH, type)
}
)!!)!!
@yongjhih
yongjhih / InterceptedInterceptor.kt
Last active October 13, 2022 18:02
Retrofit Annotation
class InterceptedInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response =
try {
val invocation = chain.request().tag<Invocation>()
val annotation = invocation?.method()?.annotation<Intercepted>()
(annotation?.value?.java?.constructors?.first()
?.newInstance(invocation.arguments()) as Interceptor?)?.intercept(chain)
} catch (e: Throwable) { null } ?: chain.proceed(chain.request())
}
@yongjhih
yongjhih / CallCallAdapterFactory.kt
Created October 11, 2022 09:09
For exception handling
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
open class CallCallAdapterFactory(private val onResponse: (Call<*>, Response<*>) -> Unit) : CallAdapter.Factory() {
override fun get(returnType: Type, annotations: Array<out Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
@UiThread
fun View.fadeIn(
duration: Long = 250,
fromAlpha: Float? = null,
onAnimation: AlphaAnimation.() -> Unit = {},
) {
clearAnimation()
val oldAlpha = alpha
alpha = 1f
startAnimation(AlphaAnimation(fromAlpha ?: oldAlpha, 1f).apply {
@RequiresPermission(ACCESS_NETWORK_STATE)
fun ConnectivityManager.getNetworkConnectedFlow(): Flow<Boolean> = callbackFlow {
trySend(isConnected)
val networkStatusCallback = object : ConnectivityManager.NetworkCallback() {
override fun onUnavailable() {
trySend(false)
}
override fun onAvailable(network: Network) {
/**
* Since the onScrollStateChanged(RecyclerView.SCROLL_STATE_IDLE) is not reliable,
* We should check the recyclerView.scrollState after fling instead
*
* ref. https://stackoverflow.com/questions/8140623/android-onscrollstatechanged-scroll-state-idle-sometimes-doesnt-fire
*/
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
scrollStateFlow.tryEmit(newState)
}