Advertisement
vkazar

Untitled

Nov 1st, 2023
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 4.57 KB | None | 0 0
  1. package sprint4.final
  2.  
  3. import java.io.BufferedReader
  4. import java.io.InputStreamReader
  5. import java.util.*
  6.  
  7. infix fun Int.myMod(m: Int) = this - (this.toDouble() / m).toInt()
  8.  
  9. class MyHashTable {
  10.     private val capacity = 100003
  11.     private val innerArray: MutableList<Bucket?> = MutableList(capacity) { null }
  12.  
  13.     operator fun set(key: Int, value: Int) {
  14.         innerArray[getIndex(key)] = Bucket(value, key)
  15.     }
  16.  
  17.     operator fun get(key: Int) = innerGet(key)?.value
  18.  
  19.     fun delete(key: Int) = innerGet(key)?.delete()
  20.  
  21.     private fun innerGet(key: Int): Bucket? = innerArray[getIndex(key)]?.takeIf { !it.deleted }
  22.  
  23.     private fun getIndex(key: Int): Int {
  24.  
  25.         var step = 0
  26.         var deletedIndexPotentialToInsert: Int? = null
  27.         var rounds = 0
  28.  
  29.         while (true) {
  30.             val secondHash = (key / 2)
  31.                 .let {
  32.                     it + if (key % 2 == it % 2) {
  33.                         1
  34.                     } else {
  35.                         0
  36.                     }
  37.                 }
  38.             // Ищем следующий подходящий индекс
  39.             val candidateIndex: Int = (key.mod(capacity) + (secondHash * step).mod(capacity)) % capacity
  40. //            val candidateIndex: Int = (key.mod(capacity) + step) % capacity
  41.  
  42.             if (step != 0 && candidateIndex == key.mod(capacity) && ++rounds == 5) {
  43.                 throw Error(
  44.                     """
  45.                    step: $step
  46.                    rounds: $rounds
  47.                    total: ${innerArray.count { it != null }}
  48.                    deleted: ${innerArray.count { it?.deleted == true }}
  49.                    active: ${innerArray.count { it?.deleted == false }}
  50.                    empty: ${innerArray.count { it == null }}
  51.                    key: $key
  52.                    candidateIndex: $candidateIndex
  53.                    deletedIndexPotentialToInsert: $deletedIndexPotentialToInsert
  54.                    keyExists: ${innerArray.find { it?.key == key } ?: "none"}
  55.                """.trimIndent()
  56.                 )
  57.             }
  58.  
  59.  
  60.             // Если элемент по этому индексу свободен, то значит он подходит для вставки,
  61.             // а искомого элемента для возврата или удаления нет
  62.             // Но при этом для экономии возвращаем найденный удалённый, если такой есть
  63.             val candidateBucket = innerArray[candidateIndex]
  64.                 ?: return deletedIndexPotentialToInsert ?: candidateIndex
  65.  
  66.             // В данной ветке мы ещё не нашли нужный индекс
  67.             // Если текущий удалён, и он первый удалённый, то запоминаем его индекс
  68.             if (candidateBucket.deleted && deletedIndexPotentialToInsert == null) deletedIndexPotentialToInsert =
  69.                 candidateIndex
  70.  
  71.             // Если текущий удалён или ключ не совпадает...
  72.             if (candidateBucket.deleted || candidateBucket.key != key) {
  73.                 // ...то уходим на следующую итерацию
  74.                 ++step
  75.                 continue
  76.             }
  77.  
  78.             //Нашли интересующий нас индекс
  79.             return candidateIndex
  80.         }
  81.     }
  82.  
  83.     private class Bucket constructor(val value: Int, val key: Int) {
  84.         var deleted = false
  85.             private set
  86.  
  87.         fun delete(): Int {
  88.             deleted = true
  89.             //При удалении для упрощения синтаксиса возвращаем удалённый элемент
  90.             return value
  91.         }
  92.     }
  93. }
  94.  
  95. fun main() {
  96.     val buffer = BufferedReader(InputStreamReader(System.`in`))
  97.     val sb = StringBuilder()
  98.     val hashTable = MyHashTable()
  99.     repeat(buffer.readLine().toInt()) {
  100.         val tokenizer = StringTokenizer(buffer.readLine())
  101.         when (tokenizer.nextToken()) {
  102.             "get" -> hashTable[tokenizer.nextToken().toInt()].nullSafeToString()
  103.             "put" -> {
  104.                 hashTable[tokenizer.nextToken().toInt()] = tokenizer.nextToken().toInt()
  105.                 null
  106.             }
  107.             "delete" -> hashTable.delete(tokenizer.nextToken().toInt()).nullSafeToString()
  108.             else -> throw Error("unknown command")
  109.         }
  110.             ?.let { sb.appendLine(it) }
  111.     }
  112.     println(sb)
  113. }
  114.  
  115. fun Int?.nullSafeToString() = this?.toString() ?: "None"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement