Created
April 16, 2025 15:06
-
-
Save hikaMaeng/8605f42a60983737a0d58d6b4596f016 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example | |
//fun Int.collatz():List<Int> = collatz1(listOf()) | |
//private tailrec fun Int.collatz1(acc:List<Int>):List<Int> | |
//= when { | |
// this == 1->acc + this | |
// this % 2 == 0->(this / 2).collatz1(acc + this) | |
// else->(this * 3 + 1).collatz1(acc + this) | |
//} | |
fun Int.collatz2():List<Int> = collatz2(this, listOf()) | |
private tailrec fun collatz2(v:Int, acc:List<Int>):List<Int> | |
= when { | |
v == 1->acc + v | |
v % 2 == 0->collatz2(v / 2, acc + v) | |
else->collatz2(v * 3 + 1, acc + v) | |
} | |
fun q5_1(){ | |
println(13.collatz2()) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example | |
import org.example.Direction.Down | |
import org.example.Direction.Up | |
data class Elevator(val floor:Int) | |
//sealed interface Direction | |
//data object Up : Direction | |
//data object Down : Direction | |
enum class Direction { | |
Up, Down | |
} | |
fun List<Direction>.fold(acc:Elevator, block:(Elevator, Direction)->Elevator): Elevator | |
= fold2(this, acc, block, 0) | |
private tailrec fun <ITEM, ACC> fold2( | |
list:List<ITEM>, acc:ACC, block:(ACC, ITEM)->ACC, cursor:Int | |
): ACC | |
= if (cursor == list.size) acc else fold2(list, block(acc, list[cursor]), block, cursor + 1) | |
fun q5_2(){ | |
val list = listOf(Up, Up, Down, Up, Down, Down, Up, Up, Up, Down) | |
val elevator = list.fold(Elevator(0)) { acc, direction -> | |
when (direction) { | |
Up -> Elevator(acc.floor + 1) | |
Down -> Elevator(acc.floor - 1) | |
} | |
} | |
println("Elevator is at floor ${elevator.floor} == 2") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example | |
sealed class JsonCompactor( | |
val original: String, | |
cursor: Int, | |
val compacted:StringBuilder, | |
){ | |
companion object{ | |
tailrec fun compactJson(target:JsonCompactor):JsonCompactor { | |
val nextCursor = target.cursor | |
return if(nextCursor < target.original.length) compactJson(target.compact(target.original[nextCursor])) else target | |
} | |
} | |
val cursor = cursor + 1 | |
protected abstract fun compact(c:Char):JsonCompactor | |
} | |
class OutQuotes(original:String, cursor:Int, compacted:StringBuilder):JsonCompactor(original, cursor, compacted){ | |
override fun compact(c:Char):JsonCompactor = when(c){ | |
'"' -> InQuotes(original, cursor, compacted.apply{append(c)}) | |
' ', '\t', '\r', '\n' -> OutQuotes(original, cursor, compacted) | |
else -> OutQuotes(original, cursor, compacted.apply{append(c)}) | |
} | |
} | |
class InQuotes(original:String, cursor:Int, compacted:StringBuilder):JsonCompactor(original, cursor, compacted){ | |
override fun compact(c:Char):JsonCompactor = when(c){ | |
'"' -> OutQuotes(original, cursor, compacted.apply{append(c)}) | |
'\\' -> Escaped(original, cursor, compacted.apply{append(c)}) | |
else -> InQuotes(original, cursor, compacted.apply{append(c)}) | |
} | |
} | |
class Escaped(original:String, cursor:Int, compacted:StringBuilder):JsonCompactor(original, cursor, compacted){ | |
override fun compact(c:Char):JsonCompactor | |
= InQuotes(original, cursor, compacted.apply{append(c)}) | |
} | |
fun String.compactJson():String | |
= StringBuilder().also{JsonCompactor.compactJson(OutQuotes(this, -1, it))}.toString() | |
enum class Type{OUT_QUOTES, IN_QUOTES, ESCAPED} | |
fun String.compactJson2():String | |
= fold(StringBuilder() to Type.OUT_QUOTES){(builder, type), c-> | |
when(type) { | |
Type.OUT_QUOTES->builder.apply { | |
if(c !in " \t\r\n") append(c) | |
} to if(c == '"') Type.IN_QUOTES else type | |
Type.IN_QUOTES->builder.append(c) to when(c) { | |
'"'->Type.OUT_QUOTES | |
'\\'->Type.ESCAPED | |
else->type | |
} | |
Type.ESCAPED->builder.append(c) to Type.IN_QUOTES | |
} | |
}.first.toString() | |
fun q5_3(){ | |
println("q5_3") | |
val json = """{ "my greetings" : "hello world! \"How arg you>\"" }""" | |
val compact = """{"my greetings":"hello world! \"How arg you>\""}""" | |
println("${json.compactJson()} == $compact ? ${json.compactJson() == compact}") | |
println("${json.compactJson2()} == $compact ? ${json.compactJson2() == compact}") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example | |
/** | |
* algebra : 대수 - 구체적인 수의 연산과 성질 덧셈, 뺄샘, 곱셈, 나눗셈 연산 - 구상수 자연수, 정수, 유리수, 실수 ->방정식, 유도식, 인수분해 | |
* abstract algebra : 추상 대수는 연산의 성질만 일치한다면 어떤 구상수가 와도 연산은 성립해 | |
* 불린대수 추상대수 구상대수: true, false안중요. 0,1대체해도 상관없음. 부정, 앤드, 오알 이라는 연산의 교환분배법칙 및 항등원 | |
* | |
* 추상대수론에는 일반화된 연산의 성질 -> 집합론 | |
* | |
* ZSF집합론 : 원소가 집합에 속해있고 교집합 차집합... 원소에 관심이 많다. 집합에 원소가 속했있다에 관심 | |
* 추상대수집합론 : 원소란 이항연산으로 정의된다 - (A, A)->A A를 집합 +(자연수, 자연수) -> 자연수 자연수를 덧셈이항연산의 집합으로 볼래 | |
* {0,1,2,3} "% 4" | |
* 1. 가장 원시적인 추상대수집합은 (A, A)->A 라는 이항연산이 있음. A->A = f(A, A):A | |
* 2. 이항연산이 결합법칙을 성립시킨다 f(f(a, b), c) = f(a, f(b, c)) -> 연산을 합성시킬 수 있다 -> 연산만 합성을 반복시켜 연산 가능성만 | |
* 나타내도 실제 게산 결과와 일치하는게 성립 = 참조투명성 = 함수합성이 여러 계산을 합친 계산으로 만들어지고 실제 계산은 안해 | |
* 추상대수학은 계산결과에 관심이 없다. 연산과 연산의 성질에 관심이 있다. | |
* 추상대수의 모든 연산에서 가장 중요한것 - 결합성이 확보되야 최소조건이 달성됨 | |
* 이항연산이 결합성을 만족하는 성질이 잇을 때 ----> 반군 세미그룹 | |
* 반군의 이항연산이 항등원을 갖고 있다면 --> 모노이드 | |
* 모노이드의 이항연산이 역원을 갖고 있다면 --> 군 그룹 | |
* 군 혹은 모노이드 까지의 이항연산은 일반적으로 곱이라 부른다. | |
* 보통 군을 곱이라는 연산 하나를 갖고 잇는 집합이라 | |
* 이항연산이 교환법칙마져 만족하면 ->아벨군 | |
* 군체환론 group(곱연산 하나) ring(곱연산과덧셈연산이 분배법칙을 성립시킬때) field(환의 연산이 역원을 성립시킬떄) | |
*/ | |
interface Monoid<T> { | |
val id: T | |
fun combine(a: T, b: T): T | |
fun lawAssociativity(a: T, b: T, c: T): Boolean = combine(a, combine(b, c)) == combine(combine(a, b), c) | |
} | |
fun <T> List<T>.fold(monoid:Monoid<T>):T = this.fold(monoid.id) { acc, item -> monoid.combine(acc, item) } | |
fun q5_4(){ | |
val intPlusMonoid = object : Monoid<Int> { | |
override val id = 0 | |
override fun combine(a: Int, b: Int) = a + b | |
} | |
println(listOf(1,2,3).fold(intPlusMonoid)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example | |
import org.example.ElevatorState.Closed | |
import org.example.ElevatorState.Opened | |
import kotlin.math.abs | |
sealed interface ElevatorState { | |
enum class Direction { UP, DOWN, NONE } | |
val direction: Direction | |
val floor:Int | |
val objects:Set<Int> | |
data class Closed(override val direction:Direction, override val floor:Int, override val objects:Set<Int>): ElevatorState | |
data class Opened(override val direction:Direction, override val floor:Int, override val objects:Set<Int>): ElevatorState | |
} | |
sealed interface ElevatorCommand:(ElevatorState)->ElevatorState{ | |
fun handle(state:ElevatorState):List<ElevatorEvent> | |
data object Close:ElevatorCommand{ | |
override fun invoke(state: ElevatorState): ElevatorState = when (state) { | |
is Closed -> state | |
is Opened -> Closed(state.direction, state.floor, state.objects) | |
} | |
override fun handle(state: ElevatorState): List<ElevatorEvent> = when (state) { | |
is Closed -> listOf() | |
is Opened -> listOf(ElevatorEvent.Closed(true)) | |
} | |
} | |
data class Call(val floor:Int, val direction: ElevatorState.Direction):ElevatorCommand{ | |
override fun invoke(state: ElevatorState): ElevatorState = when (state) { | |
is Closed -> if(state.floor == floor && (state.direction == direction || state.direction == ElevatorState.Direction.NONE)) | |
Opened(state.direction, floor, state.objects) else state.copy(objects = state.objects + floor) | |
is Opened -> state.copy(objects = state.objects + floor) | |
} | |
override fun handle(state: ElevatorState): List<ElevatorEvent> = when (state) { | |
is Closed -> if(state.floor == floor && (state.direction == direction || state.direction == ElevatorState.Direction.NONE)){ | |
listOf(ElevatorEvent.Opened(false), ElevatorEvent.FloorChanged(state.floor, floor)) | |
} else listOf(ElevatorEvent.ObjectsAdded(floor)) | |
is Opened -> listOf(ElevatorEvent.ObjectsAdded(floor)) | |
} | |
} | |
data class Move(val floor:Int):ElevatorCommand{ | |
override fun invoke(state: ElevatorState): ElevatorState = when (state) { | |
is Closed -> if (state.floor == floor) Opened(state.direction, floor, state.objects) else state.copy(objects = state.objects + floor) | |
is Opened -> if (state.floor == floor) state else state.copy(objects = state.objects + floor) | |
} | |
override fun handle(state: ElevatorState): List<ElevatorEvent> = when (state) { | |
is Closed -> if (state.floor == floor) listOf(ElevatorEvent.Opened(false), ElevatorEvent.FloorChanged(state.floor, floor)) | |
else listOf(ElevatorEvent.ObjectsAdded(floor)) | |
is Opened -> if (state.floor == floor) listOf() else listOf(ElevatorEvent.ObjectsAdded(floor)) | |
} | |
} | |
data object Step:ElevatorCommand{ | |
override fun handle(state: ElevatorState): List<ElevatorEvent> = listOf() | |
override fun invoke(state: ElevatorState): ElevatorState = when (state) { | |
is Opened -> state // 문이 열려 있으면 이동 불가 | |
is Closed -> { | |
if(state.objects.isEmpty()) state.copy(direction = ElevatorState.Direction.NONE) | |
else { | |
val current = state.floor | |
val objects = state.objects | |
val dir = when(state.direction) { | |
ElevatorState.Direction.NONE-> { | |
val next = objects.minByOrNull {abs(it - current)}!! | |
if(next > current) ElevatorState.Direction.UP else ElevatorState.Direction.DOWN | |
} | |
else->state.direction | |
} | |
val floor = when(dir) { | |
ElevatorState.Direction.UP->state.floor + 1 | |
ElevatorState.Direction.DOWN->state.floor - 1 | |
ElevatorState.Direction.NONE->state.floor | |
} | |
if(floor in objects) { | |
val remaining = objects - floor | |
Opened(when { | |
remaining.isEmpty() -> ElevatorState.Direction.NONE | |
dir == ElevatorState.Direction.UP -> if(remaining.any { it > floor }) ElevatorState.Direction.UP else ElevatorState.Direction.DOWN | |
dir == ElevatorState.Direction.DOWN -> if(remaining.any { it < floor }) ElevatorState.Direction.DOWN else ElevatorState.Direction.UP | |
else -> ElevatorState.Direction.NONE | |
}, floor, remaining) | |
}else state.copy(dir, floor, objects) | |
} | |
} | |
} | |
} | |
} | |
fun q6_1() { | |
var state: ElevatorState = ElevatorState.Closed( | |
direction = ElevatorState.Direction.NONE, | |
floor = 3, | |
objects = emptySet() | |
) | |
val scenario: List<Pair<String, ElevatorCommand>> = listOf( | |
"콜: 5층에서 아래로" to ElevatorCommand.Call(5, ElevatorState.Direction.DOWN), | |
"스텝 실행" to ElevatorCommand.Step, | |
"콜: 2층에서 위로" to ElevatorCommand.Call(2, ElevatorState.Direction.UP), | |
"스텝 실행" to ElevatorCommand.Step, | |
"문 닫기" to ElevatorCommand.Close, | |
"이동: 1층으로 Move" to ElevatorCommand.Move(1), | |
"스텝 실행" to ElevatorCommand.Step, | |
"스텝 실행" to ElevatorCommand.Step, | |
"스텝 실행" to ElevatorCommand.Step, | |
"스텝 실행" to ElevatorCommand.Step, | |
"문 닫기" to ElevatorCommand.Close, | |
"이동: 3층으로 Move" to ElevatorCommand.Move(3), | |
"스텝 실행" to ElevatorCommand.Step, | |
"문 닫기" to ElevatorCommand.Close, | |
"스텝 실행" to ElevatorCommand.Step, | |
"스텝 실행" to ElevatorCommand.Step, | |
"문 닫기" to ElevatorCommand.Close, | |
) | |
scenario.forEachIndexed { index, (label, cmd) -> | |
println("[$index] $label, $cmd") | |
state = cmd(state) | |
println(" → 전이상태: $state") | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example | |
import kotlin.collections.fold | |
sealed interface ElevatorEvent:(ElevatorState)->ElevatorState{ | |
data object Idle : ElevatorEvent{ | |
override fun invoke(e:ElevatorState): ElevatorState = e | |
} | |
data class Opened(val isOpened:Boolean):ElevatorEvent{ | |
override fun invoke(e:ElevatorState): ElevatorState = ElevatorState.Opened(e.direction, e.floor, e.objects) | |
} | |
data class Closed(val isOpened:Boolean):ElevatorEvent{ | |
override fun invoke(e:ElevatorState): ElevatorState = ElevatorState.Closed(e.direction, e.floor, e.objects) | |
} | |
data class FloorChanged(val from: Int, val to: Int) : ElevatorEvent{ | |
override fun invoke(e:ElevatorState): ElevatorState = when (e) { | |
is ElevatorState.Closed -> e.copy(floor = to) | |
is ElevatorState.Opened -> e.copy(floor = to) | |
} | |
} | |
data class ObjectsAdded(val floor: Int) : ElevatorEvent{ | |
override fun invoke(e:ElevatorState): ElevatorState = when (e) { | |
is ElevatorState.Closed -> e.copy(objects = e.objects + floor) | |
is ElevatorState.Opened -> e.copy(objects = e.objects + floor) | |
} | |
} | |
data class ObjectsRemoved(val floor: Int) : ElevatorEvent{ | |
override fun invoke(e:ElevatorState): ElevatorState = when (e) { | |
is ElevatorState.Closed -> e.copy(objects = e.objects - floor) | |
is ElevatorState.Opened -> e.copy(objects = e.objects - floor) | |
} | |
} | |
} | |
//[e,e,e,e]->s | |
//s +[e,e,e,e,e,e,e,e,e,e,e,e] -> s | |
//[e,e,e,e] == s + [e,e,e,e,e] ->s + [e,e,e] -> s | |
fun List<ElevatorEvent>.replay(snapshot:ElevatorState):ElevatorState | |
= fold(snapshot){acc, event->event(acc)} | |
fun ElevatorState.handle(vararg command:ElevatorCommand):List<ElevatorEvent> | |
= command.fold(listOf<List<ElevatorEvent>>()){acc, command-> | |
acc + command.handle(acc.flatten().replay(this)) | |
acc | |
}.flatten() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment