fork download
  1. // Программа разменивает сумму советскими копейками
  2. // Используется "жадный" алгоритм - отнимается по максимуму наибольший,
  3. // что для произвольного набора монет может приводить к неразмененному остатку
  4. // Copyleft Alexey Kuzminov (с) 2016
  5.  
  6. // количество копеек + падеж от копейки
  7. // ВНИМАНИЕ: требуется сортировка по убыванию и наличие 1 копейки в списке
  8. let coins = [
  9. (50, "копеек")
  10. (20, "копеек")
  11. (10, "копеек")
  12. (5, "копеек")
  13. (3, "копейки")
  14. (2, "копейки")
  15. //(1, "копейке") // !!! закомментирована для демонстрации эффекта неразмена
  16. ]
  17.  
  18. // рекурсивный пробег по списку, откусывая по одному элементу с начала
  19. // возвращает количество монет, которыми разменивается сумма монетами списка
  20. let rec exchange_tail (sum: int byref) list =
  21. match list with
  22. | head :: tail ->
  23. let (value, text) = head // просто парсим кортеж
  24. let count = sum / value
  25. sum <- sum - count * value
  26. if count > 0 then printfn " %d по %d %s" count value text
  27. count + exchange_tail &sum tail
  28. | [] -> 0
  29.  
  30. // функция размена
  31. let exchange sum =
  32. let mutable total = sum
  33. printfn "\nРазмен суммы %d:" total
  34. printfn "Итого монет %d" (exchange_tail &total coins)
  35. if (total > 0) then printfn "Осталось неразменена сумма %d" total
  36.  
  37. // для проверки
  38. exchange 14
  39. exchange 98
  40.  
Success #stdin #stdout 0.08s 24496KB
stdin
Standard input is empty
stdout
Размен суммы 14:
  1 по 10 копеек
  1 по 3 копейки
Итого монет 2
Осталось неразменена сумма 1

Размен суммы 98:
  1 по 50 копеек
  2 по 20 копеек
  1 по 5 копеек
  1 по 3 копейки
Итого монет 5