// 2025-2026 Богданович Давид Когут Прихожденко (кдб.дійсність.укр)

взяти визначення мавка;

простір мавка {
  внутрішня дія змішати_кд(
    значення: кд
  ) -> природне {
    змінна змішане: природне = 5381;
    змінна п: природне = 0;

    поки п < значення.розмір {
      змішане = (змішане * 33) + природне(значення.дані[п]);

      п += 1;
    }

    вернути змішане;
  }

  внутрішня дія розширити_призначення(
    М: *Машина,
    призначення: *Призначення,
    нова_вмісткість: природне
  ) {
    якщо нова_вмісткість == 0 {
      нова_вмісткість = призначення.вмісткість * 2;
    } інакше якщо нова_вмісткість <= призначення.вмісткість {
      вернути;
    }

    змінна нові_дані = виділити<*Призначене>(М, нова_вмісткість);

    змінна п: природне = 0;

    поки п < нова_вмісткість {
      нові_дані[п] = пусто як *Призначене;

      п += 1;
    }

    п = 0;

    поки п < призначення.вмісткість {
      змінна поточне_призначене = призначення.дані[п];

      поки поточне_призначене != пусто {
        змінна нова_позиція = змішати_кд(поточне_призначене.назва.значення) % нова_вмісткість;

        змінна наступний = поточне_призначене.наступний;

        поточне_призначене.наступний = нові_дані[нова_позиція];

        нові_дані[нова_позиція] = поточне_призначене;

        поточне_призначене = наступний;
      }

      п += 1;
    }

    звільнити(М, призначення.дані);

    призначення.дані = нові_дані;
    призначення.вмісткість = нова_вмісткість;
  }

  дія призначити(
    М: *Машина,
    призначення: *Призначення,
    назва: *ПредметТексту,
    значення: Значення
  ) {
    якщо призначення.вмісткість == 0 {
      призначення.дані = виділити<*Призначене>(М, 1);
      призначення.вмісткість = 1;
      призначення.дані[0] = пусто як *Призначене;
    } інакше якщо ((р64(призначення.розмір) / р64(призначення.вмісткість)) > 0.7) {
       розширити_призначення(М, призначення, 0);
    }

    змінна позиція = змішати_кд(назва.значення) % призначення.вмісткість;

    змінна призначене = призначення.дані[позиція];

    поки призначене != пусто {
      якщо порівняти_тексти(М, призначене.назва, назва) {
        призначене.назва = назва;
        призначене.значення = значення;

        вернути;
      }

      призначене = призначене.наступний;
    }

    змінна нова_призначене = виділити<Призначене>(М, 1);
    нова_призначене.назва = назва;
    нова_призначене.значення = значення;
    нова_призначене.наступний = призначення.дані[позиція];
    призначення.дані[позиція] = нова_призначене;

    призначення.розмір += 1;
  }

  дія знайти_призначене(
    М: *Машина,
    призначення: Призначення,
    назва: *ПредметТексту,
    вихід: *Значення
  ) -> логічне {
    якщо призначення.вмісткість == 0 {
      вернути ні;
    }

    змінна позиція = змішати_кд(назва.значення) % призначення.вмісткість;

    змінна призначене = призначення.дані[позиція];

    поки призначене != пусто {
      якщо порівняти_тексти(М, призначене.назва, назва) {
        вихід::вміст = призначене.значення;

        вернути так;
      }

      призначене = призначене.наступний;
    }

    вернути ні;
  }

  дія перебрати_призначення(
    М: *Машина,
    призначення: Призначення,
    дія_перебору: (М: *Машина, призначення: Призначення, назва: *ПредметТексту, значення: Значення, аргумент: адреса) -> логічне,
    аргумент: адреса
  ) -> логічне {
    змінна п: природне = 0;

    поки п < призначення.вмісткість {
      змінна призначене = призначення.дані[п];

      поки призначене != пусто {
        якщо не дія_перебору(М, призначення, призначене.назва, призначене.значення, аргумент) {
          вернути ні;
        }

        призначене = призначене.наступний;
      }

      п += 1;
    }

    вернути так;
  }
}