Advertisement
Guest User

Untitled

a guest
May 26th, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Нужно найти путь из  start -> end
  2. // На вход подается функция  fetchTicket(from): Promise<string[]> - возвращает достижимые вершины
  3. // Нельзя использовать async/await и генераторы
  4. // Пример данных
  5. const paths = {
  6.   'A': ['B'],
  7.   'B': ['C'],
  8.   'C': ['D', 'A'],
  9.   'D': ['B'],
  10. }
  11.  
  12. // Функция полученния данных
  13. function fetchTicket(from) {
  14.   return new Promise((resolve) => resolve(paths[from]));
  15. }
  16.  
  17. // Цикл на промисах
  18. function loop(promise, step) {
  19.   return promise.
  20.     then(step)
  21.     .then((stepResult) => {
  22.       return !stepResult.done ? loop(Promise.resolve(stepResult.state), step) : stepResult.state;
  23.     })
  24. }
  25.  
  26. function bfsPromise (fetchData, start, end) {
  27.   const q = [start];
  28.   const visited = {};
  29.   const parent = [];
  30.   parent[start] = null;
  31.  
  32.   const startState = {
  33.     q,
  34.     visited,
  35.     fetchData,
  36.     parent,
  37.     end,
  38.     start,
  39.   };
  40.  
  41.   // Шаг одного цикла
  42.   const step = (state) => {
  43.     if (state.q.length === 0) {
  44.       return {
  45.         done: true,
  46.         state,
  47.       }
  48.     }
  49.    
  50.     const current = state.q.pop();
  51.  
  52.     return fetchData(current)
  53.       .then((nodes) => {
  54.         nodes.forEach((node) => {
  55.           if (node === state.end || visited[node]) {
  56.             if (node === state.end) {
  57.               state.parent[node] = current;
  58.               state.q = [];
  59.             }
  60.            
  61.             return;
  62.           }
  63.          
  64.           visited[node] = true;
  65.           state.parent[node] = current;
  66.           state.q.push(node);
  67.         });
  68.      
  69.         return {
  70.           done: false,
  71.           state,
  72.         }
  73.       });
  74.   }
  75.  
  76.   return loop(Promise.resolve(startState), step);
  77. }
  78.  
  79. function buildPath(statePromise) {
  80.   return statePromise.then((state) => {
  81.     state.q = null;
  82.     state.visited = null;
  83.     const result = [];
  84.    
  85.     let node = state.end;
  86.     let path = [node];
  87.     let isContainStart = false;
  88.    
  89.     while(state.parent[node]) {
  90.       node = state.parent[node];
  91.      
  92.       isContainStart = node === state.start;
  93.       path.push(node);
  94.     }
  95.    
  96.     if (!isContainStart) {
  97.       return 'no way';
  98.     }
  99.    
  100.     // Очень долгая операция
  101.     return path.reverse();
  102.   });
  103. }
  104.  
  105. // Функция решения
  106. function solve (start, end, fetchFlights) {
  107.   if (start === end) {
  108.     return Promise.resolve([start]);
  109.   }
  110.  
  111.   return buildPath(bfsPromise(fetchFlights, start, end));
  112. }
  113.  
  114. // пример работы
  115. solve('A', 'C', fetchTicket).then(console.log);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement