Guest User

Untitled

a guest
Jul 21st, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.86 KB | None | 0 0
  1. use std::borrow::Borrow;
  2.  
  3. fn product_with_mask<I, F>(arr: I, mask: u64) -> f64
  4. where
  5. I: IntoIterator<Item = F>,
  6. F: Borrow<f64>,
  7. {
  8. #[inline]
  9. fn adjust(f: f64, bit: u64) -> f64 {
  10. if bit == 0 {
  11. 1.0 - f
  12. } else {
  13. f
  14. }
  15. }
  16.  
  17. arr.into_iter()
  18. .enumerate()
  19. .map(|(i, x)| adjust(*x.borrow(), mask & (1 << i)))
  20. .product()
  21. }
  22.  
  23. const SIZE_LIMIT: usize = 63;
  24.  
  25. fn count_lucky_hunt<I, F>(probs: I, necessary: usize) -> f64
  26. where
  27. I: IntoIterator<Item = F>,
  28. F: Borrow<f64>,
  29. <I as IntoIterator>::IntoIter: ExactSizeIterator + Clone,
  30. {
  31. use std::iter::ExactSizeIterator;
  32.  
  33. let probs = probs.into_iter();
  34. let len = probs.len();
  35.  
  36. if len > SIZE_LIMIT {
  37. panic!("cannot count result for len > {}", SIZE_LIMIT);
  38. }
  39.  
  40. if necessary > len {
  41. return 0.0;
  42. }
  43.  
  44. let mut res = 0.0;
  45.  
  46. for killed in necessary..=len {
  47. for killed_mask in (0u64..(1 << len)).filter(|x| x.count_ones() == killed as u32) {
  48. res += product_with_mask(probs.clone(), killed_mask);
  49. }
  50. }
  51.  
  52. res
  53. }
  54.  
  55. fn count_lucky_hunt_with_names<I, P>(probs: I, necessary: usize) -> f64
  56. where
  57. I: IntoIterator<Item = P>,
  58. P: Borrow<(&'static str, f64)>,
  59. <I as IntoIterator>::IntoIter: ExactSizeIterator + Clone,
  60. {
  61. count_lucky_hunt(probs.into_iter().map(|p| p.borrow().1), necessary)
  62. }
  63.  
  64. #[test]
  65. fn with_names() {
  66. let probs = [("медведь", 0.5), ("тигр", 0.5), ("лев", 0.5)];
  67. assert_eq!(count_lucky_hunt_with_names(&probs, 2), 0.5);
  68. }
  69.  
  70. #[test]
  71. fn some_variants() {
  72. let probs = [0.1, 0.5];
  73. assert_eq!(count_lucky_hunt(&probs, 1), 0.55);
  74. assert_eq!(count_lucky_hunt(&probs, 2), 0.05);
  75. assert_eq!(count_lucky_hunt(&probs, 3), 0.00);
  76. }
  77.  
  78. #[test]
  79. #[should_panic]
  80. fn too_big() {
  81. let big = vec![0.5; SIZE_LIMIT + 1];
  82. count_lucky_hunt(&big, 4);
  83. }
Add Comment
Please, Sign In to add comment