Advertisement
Artyom_Kopan

BFS

Jun 2nd, 2022
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.16 KB | None | 0 0
  1. package final
  2.  
  3. import kotlinx.coroutines.Dispatchers
  4. import kotlinx.coroutines.runBlocking
  5. import kotlinx.coroutines.withContext
  6. import java.util.LinkedList
  7. import java.util.Queue
  8.  
  9. const val NOT_FOUND = -1
  10. const val HITLER = "https://en.wikipedia.org/wiki/Adolf_Hitler"
  11.  
  12. // результат == true <=> найден гитлер
  13. fun processRefs(articles: Queue<Pair<String, Int>>, ref: String, priority: Int): Boolean {
  14.     val wikipediaPages = searchRefs(getHtmlDocument(ref))
  15.     for (page in wikipediaPages) {
  16.         if (page == HITLER) {
  17.             return true
  18.         }
  19.         articles.add(Pair(page, priority + 1))
  20.     }
  21.     return false
  22. }
  23.  
  24. // возвращает число шагов, за которые можно найти Гитлера, начиная со страницы startArticle
  25. fun bfs(startArticle: String, searchDepth: Int, threadsCount: Int): Int = runBlocking {
  26.     // first = ссылка, second = число шагов, за которое до неё можно дойти
  27.     val articles: Queue<Pair<String, Int>> = LinkedList()
  28.     articles.add(Pair(startArticle, 0))
  29.  
  30.     while (articles.isNotEmpty() && articles.peek().second < searchDepth) {
  31.         val firstRefs = (1..threadsCount).mapNotNull { articles.poll() }
  32.         var isContinue = false
  33.         for (element in firstRefs) {
  34.             if (element.first == HITLER) {
  35.                 return@runBlocking element.second
  36.             }
  37.             if (element.second == searchDepth) {
  38.                 isContinue = true
  39.                 break
  40.             }
  41.         }
  42.         if (isContinue) {
  43.             continue
  44.         }
  45.  
  46.         val flags = BooleanArray(firstRefs.size) { false }
  47.         for (i in firstRefs.indices) {
  48.             flags[i] = withContext(Dispatchers.Default) {
  49.                 processRefs(
  50.                     articles,
  51.                     firstRefs[i].first,
  52.                     firstRefs[i].second
  53.                 )
  54.             }
  55.         }
  56.  
  57.         for (i in firstRefs.indices) {
  58.             if (flags[i]) {
  59.                 return@runBlocking firstRefs[i].second + 1
  60.             }
  61.         }
  62.     }
  63.  
  64.     return@runBlocking NOT_FOUND
  65. }
  66.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement