Advertisement
Guest User

Untitled

a guest
Mar 26th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.40 KB | None | 0 0
  1. import loglevel from 'loglevel';
  2. import { gaussian, randomBetweenMinAndMax } from './random-utils';
  3.  
  4. interface IPeriodEntry {
  5. calories: number;
  6. workout: boolean;
  7. }
  8. interface ISimEntry {
  9. correctnessFactor: number;
  10. period: IPeriodEntry[];
  11. }
  12.  
  13. interface IConfig {
  14. periodLength: number;
  15. fastingDays: number;
  16. targetWorkoutDays: number;
  17. simulationCount: number;
  18. dailyTargetCalories: number;
  19. }
  20.  
  21. const selectPeriodDays = (
  22. targetDays: number,
  23. periodLength: number
  24. ): number[] => {
  25. const realizedTarget = Math.floor(gaussian(targetDays, targetDays)());
  26. if (realizedTarget < 1) {
  27. return [];
  28. } else {
  29. return Array(realizedTarget)
  30. .fill(false)
  31. .map(() => randomBetweenMinAndMax(1, periodLength) - 1);
  32. }
  33. };
  34.  
  35. const generatePeriodWorkouts = (config: IConfig): number[] =>
  36. selectPeriodDays(config.targetWorkoutDays, config.periodLength);
  37. const generatePeriodFastingDays = (config: IConfig): number[] =>
  38. selectPeriodDays(config.fastingDays, config.periodLength);
  39.  
  40. const generatePeriodCalories = (config: IConfig): number[] => {
  41. // make a standard gaussian variable.
  42. const standardDistribution = gaussian(
  43. config.dailyTargetCalories,
  44. config.dailyTargetCalories
  45. );
  46.  
  47. return Array(config.periodLength)
  48. .fill(0)
  49. .map(() => Math.floor(standardDistribution()));
  50. };
  51.  
  52. const sumPeriodCalories = (week: IPeriodEntry[]): number =>
  53. week.reduce((acc, current) => acc + current.calories, 0);
  54.  
  55. const sumPeriodWorkouts = (week: IPeriodEntry[]): number =>
  56. week.reduce((acc, current) => {
  57. if (current.workout) {
  58. return acc + 1;
  59. } else {
  60. return acc;
  61. }
  62. }, 0);
  63.  
  64. const mergeFastingAndWorkouts = (
  65. calories: number[],
  66. fastingDays: number[],
  67. workoutDays: number[]
  68. ): IPeriodEntry[] => {
  69. return calories.map(
  70. (caloriesInstance: number, index: number): IPeriodEntry => {
  71. const calIntstanceFastAdjusted = fastingDays.includes(index)
  72. ? 0
  73. : caloriesInstance;
  74. const workout = workoutDays.includes(index);
  75. return { calories: calIntstanceFastAdjusted, workout };
  76. }
  77. );
  78. };
  79.  
  80. const generatePeriodWithMetadata = (
  81. config: IConfig,
  82. periodTarget: number
  83. ): ISimEntry => {
  84. const periodCalories = generatePeriodCalories(config);
  85. const fastingDays = generatePeriodFastingDays(config);
  86. const periodWorkouts = generatePeriodWorkouts(config);
  87. const period = mergeFastingAndWorkouts(
  88. periodCalories,
  89. fastingDays,
  90. periodWorkouts
  91. );
  92. const workoutDiff = Math.abs(
  93. config.targetWorkoutDays - sumPeriodWorkouts(period)
  94. );
  95. const calorieDiff = Math.abs(periodTarget - sumPeriodCalories(period));
  96. return {
  97. correctnessFactor: workoutDiff + calorieDiff,
  98. period
  99. };
  100. };
  101.  
  102. const generatePeriodSimulations = (config: IConfig): ISimEntry[] => {
  103. const periodTarget = config.dailyTargetCalories * config.periodLength;
  104. const periods = [];
  105.  
  106. for (let i = 0; i < config.simulationCount; i++) {
  107. periods.push(generatePeriodWithMetadata(config, periodTarget));
  108. }
  109. return periods;
  110. };
  111.  
  112. const main = (config: IConfig) => {
  113. const sims = generatePeriodSimulations(config);
  114. const result = sims.reduce(
  115. (p: ISimEntry, c: ISimEntry): ISimEntry => {
  116. if (p.correctnessFactor < c.correctnessFactor) {
  117. return p;
  118. } else {
  119. return c;
  120. }
  121. }
  122. );
  123. loglevel.error(JSON.stringify(result, null, 2));
  124. };
  125. main({
  126. dailyTargetCalories: 1800,
  127. fastingDays: 2,
  128. periodLength: 7,
  129. simulationCount: 10000,
  130. targetWorkoutDays: 5
  131. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement