Guest User

Untitled

a guest
Jul 22nd, 2018
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.80 KB | None | 0 0
  1. use std::borrow::Borrow;
  2.  
  3. fn product_with_mask<I, F>(probabilities: 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. probabilities.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 res = (0u64..(1 << len))
  45. .filter(|x| x.count_ones() >= necessary as u32)
  46. .map(|mask| product_with_mask(probs.clone(), mask))
  47. .sum();
  48.  
  49. res
  50. }
  51.  
  52. fn count_lucky_hunt_with_names<I, P>(probs: I, necessary: usize) -> f64
  53. where
  54. I: IntoIterator<Item = P>,
  55. P: Borrow<(&'static str, f64)>,
  56. <I as IntoIterator>::IntoIter: ExactSizeIterator + Clone,
  57. {
  58. count_lucky_hunt(probs.into_iter().map(|p| p.borrow().1), necessary)
  59. }
  60.  
  61. #[test]
  62. fn with_names() {
  63. let probs = [("bear", 0.5), ("tiger", 0.5), ("lion", 0.5)];
  64. assert_eq!(count_lucky_hunt_with_names(&probs, 2), 0.5);
  65. }
  66.  
  67. #[test]
  68. fn some_variants() {
  69. let probs = [0.1, 0.5];
  70. assert_eq!(count_lucky_hunt(&probs, 1), 0.55);
  71. assert_eq!(count_lucky_hunt(&probs, 2), 0.05);
  72. assert_eq!(count_lucky_hunt(&probs, 3), 0.00);
  73. }
  74.  
  75. #[test]
  76. #[should_panic]
  77. fn too_big() {
  78. let big = vec![0.5; SIZE_LIMIT + 1];
  79. count_lucky_hunt(&big, 4);
  80. }
Add Comment
Please, Sign In to add comment