Automated meetings schedule planner - javascript

I work in an event organizing company, our main business is organizing “speed dating” meetings between buyers (retailers and distributors) and manufacturers of food and beverages. We have people that create a schedule for events and I would like to somehow automate this process.
I would ask for help with logic for a web app that would schedule the meetings.
There are 10 different companies on each side.
The meetings should be only if one side chose a company from the other side.
Each meeting is 15 minutes.
The whole event should we 2-2,5 hours long.
Any suggestions on how to create a great schedule automatically?
P.S. I am sorry if my question is not clear, this is my first Stack Overflow question.

I don't have a JavaScript solution, but this can be solved with mathematical optimization tools.
Let's start with some data:
---- 11 SET b buyers
buyer1 , buyer2 , buyer3 , buyer4 , buyer5 , buyer6 , buyer7 , buyer8 , buyer9 , buyer10
---- 11 SET s sellers
seller1 , seller2 , seller3 , seller4 , seller5 , seller6 , seller7 , seller8 , seller9
seller10
---- 11 SET r rounds
round1, round2, round3, round4, round5, round6, round7, round8
---- 11 PARAMETER wantMeeting a meeting has been requested
seller1 seller2 seller3 seller4 seller5 seller6 seller7 seller8 seller9
buyer1 1 1
buyer2 1 1
buyer3 1 1
buyer4 1 1
buyer5 1 1 1
buyer6 1 1 1
buyer7 1 1 1 1
buyer8 1 1
buyer9 1 1 1
buyer10 1 1
+ seller10
buyer8 1
Introduce binary variables:
x(b,s,r) = 1 if buyer b meets seller s in round r
0 otherwise
We only consider the cases where wantMeeting=1. Implicitly, when wantMeeting=0, we assume x(b,s,r)=0.
Constraints:
Meeting is requested:
sum(r, x(b,s,r)) = 1 for all b,s with wantMeeting(b,s)=1
Buyer can only have one meeting per round
sum(s|wantMeeting(b,s)=1, x(b,s,r)) <= 1 for all b,r
Seller can only have one meeting per round
sum(b|wantMeeting(b,s)=1, x(b,s,r)) <= 1 for all s,r
Here | is the mathematic notation for "such that".
I have also added some constraints, and an objective to minimize the number of rounds needed. The resulting Mixed Integer Programming model gives as result:
---- 42 VARIABLE x.L meetings
round1 round2 round3 round4
buyer1 .seller1 1
buyer1 .seller9 1
buyer2 .seller5 1
buyer2 .seller7 1
buyer3 .seller3 1
buyer3 .seller4 1
buyer4 .seller1 1
buyer4 .seller3 1
buyer5 .seller2 1
buyer5 .seller4 1
buyer5 .seller6 1
buyer6 .seller5 1
buyer6 .seller6 1
buyer6 .seller9 1
buyer7 .seller1 1
buyer7 .seller2 1
buyer7 .seller5 1
buyer7 .seller6 1
buyer8 .seller3 1
buyer8 .seller8 1
buyer8 .seller10 1
buyer9 .seller2 1
buyer9 .seller5 1
buyer9 .seller6 1
buyer10.seller7 1
buyer10.seller9 1
---- 42 VARIABLE round.L round is used
round1 1, round2 1, round3 1, round4 1
---- 42 VARIABLE numRounds.L = 4 number of rounds needed
I did not have a capacity per round (say n tables are available). This is not very difficult to add. More details are here.
For some more examples of these type of models see:
Scheduling Business Dinners
Speed Dating Scheduling
I probably would solve this on a server, but if you insist on a JavaScript solution, there is a JavaScript port of the GLPK Mixed Integer Programming Solver (link). You may also look into Constraint Programming Solvers (there are a few available in JavaScript).

Related

Scraping Javascript-Rendered Content in R from a Webpage without Unique URL

I want to scrape historical results of South African LOTTO draws (especially Total Pool Size, Total Sales, etc.) from the South African National Lottery website. By default one sees links to results for the last ten draws, or one can select a date range to pull up a larger set of links to draws (which will still display only ten per page).
Hovering in the browser over a link e.g. 'LOTTO DRAW 2012' we see javascript:void(); so it is clear that the draw results will be rendered using Javascript. Reading advice on an R Web Scraping Cheat Sheet, I realized that I needed to open Google Chrome Developer tools, then open Network tab, and then click the link to the draw 'LOTTO DRAW 2012'. When I did so, I could see that this url is being called with an initiator
When I right-click on the initiator and select 'Copy Response', I can see the data I need inside a 'drawDetails' object in what appears to be JSON code.
{"code":200,"message":"OK","data":{"drawDetails":{"drawNumber":"2012","drawDate":"2020\/04\/11","nextDrawDate":"2020\/04\/15","ball1":"48","ball2":"6","ball3":"43","ball4":"41","ball5":"25","ball6":"45","bonusBall":"38","div1Winners":"1","div1Payout":"10546013.8","div2Winners":"0","div2Payout":"0","div3Winners":"28","div3Payout":"7676.4","div4Winners":"62","div4Payout":"2751.4","div5Winners":"1389","div5Payout":"206.3","div6Winners":"1872","div6Payout":"133","div7Winners":"28003","div7Payout":"50","div8Winners":"20651","div8Payout":"20","rolloverAmount":"0","rolloverNumber":"0","totalPrizePool":"13280236.5","totalSales":"11610950","estimatedJackpot":"2000000","guaranteedJackpot":"0","drawMachine":"RNG2","ballSet":"RNG","status":"published","winners":52006,"millionairs":1,"gpwinners":"52006","wcwinners":"0","ncwinners":"0","ecwinners":"0","mpwinners":"0","lpwinners":"0","fswinners":"0","kznwinners":"0","nwwinners":"0"},"totalWinnerRecord":{"lottoMillionairs":28716702,"lottoWinners":337285646,"ithubaMillionairs":135763,"ithubaWinners":305615802}},"videoData":[{"id":"1049","listid":"1","parentid":"1","videosource":"youtube","videoid":"chHfFxVi9QI","imageurl":"","title":"LOTTO, LOTTO PLUS 1 AND LOTTO PLUS 2 DRAW 2012 (11 APRIL 2020)","description":"","custom_imageurl":"","custom_title":"","custom_description":"","specialparams":"","lastupdate":"0000-00-00 00:00:00","allowupdates":"1","status":"0","isvideo":"1","link":"https:\/\/www.youtube.com\/watch?v=chHfFxVi9QI","ordering":"10001","publisheddate":"2020-04-11 20:06:17","duration":"182","rating_average":"0","rating_max":"0","rating_min":"0","rating_numRaters":"0","statistics_favoriteCount":"0","statistics_viewCount":"329","keywords":"","startsecond":"0","endsecond":"0","likes":"6","dislikes":"0","commentcount":"0","channel_username":"","channel_title":"","channel_subscribers":"9880","channel_subscribed":"0","channel_location":"","channel_commentcount":"0","channel_viewcount":"0","channel_videocount":"1061","channel_description":"","channel_totaluploadviews":"0","alias":"lotto-lotto-plus-1-and-lotto-plus-2-draw-2012-11-april-2020","rawdata":"","datalink":"https:\/\/www.googleapis.com\/youtube\/v3\/videos?id=chHfFxVi9QI&part=id,snippet,contentDetails,statistics&key=AIzaSyC1Xvk2GUdb_N3UiFtjsgZ-uMviJ_8MFZI"}]}
It is a POST type request, and so I tried to follow this answer, but cannot find onclick values indicating the data submitted with the form. Moreover, the request URL for 'LOTTO DRAW 2012' is identical to that for 'LOTTO DRAW 2011', so there is no unique identifier for the particular draw being passed with the URL itself. Thus it is not clear to me how the unique request for the results of a particular draw is made.
Hence, the smaller question is, given a particular LOTTO draw number or draw date, how does one find out the unique identifier that is used to make the POST request for the data pertaining to that draw specifically?
The larger question is, if one is able to obtain such unique identifiers for all the historical draws, how can one generate the JSON drawDetails object for all the historical draws in turn, or otherwise complete the scraping operation?
You are right - the contents on the page are updated by javascript via an ajax request. The server returns a json string in response to an http POST request. With POST requests, the server's response is determined not only by the url you request, but by the body of the message you send to the server. In this case, your body is a simple form with 3 fields: gameName, which is always LOTTO, isAjax which is always true, and drawNumber, which is the field you want to vary.
If you are using httr, you specify these fields as a named list in the body parameter of the POST function.
Once you have the response for each draw, you will want to parse the json into an R-friendly format such as a list or data frame using a library such as jsonlite. From looking at the structure of this particular json, it makes most sense to extract the component $data$drawDetailsand make that a one-row dataframe. This will allow you to bind several draws together into a single data frame.
Here is a function that does all that for you:
lotto_details <- function(draw_numbers)
{
do.call("rbind", lapply(draw_numbers, function(x)
{
res <- httr::POST(paste0("https://www.nationallottery.co.za/index.php",
"?task=results.redirectPageURL&",
"Itemid=265&option=com_weaver&",
"controller=lotto-history"),
body = list(gameName = "LOTTO", drawNumber = x, isAjax = "true"))
as.data.frame(jsonlite::fromJSON(httr::content(res, "text"))$data$drawDetails)
}))
}
Which you use like this:
lotto_details(2009:2012)
#> drawNumber drawDate nextDrawDate ball1 ball2 ball3 ball4 ball5 ball6
#> 1 2009 2020/04/01 2020/04/04 51 15 7 32 42 45
#> 2 2010 2020/04/04 2020/04/08 43 4 21 24 10 3
#> 3 2011 2020/04/08 2020/04/11 42 43 8 18 2 29
#> 4 2012 2020/04/11 2020/04/15 48 6 43 41 25 45
#> bonusBall div1Winners div1Payout div2Winners div2Payout div3Winners
#> 1 1 0 0 0 0 21
#> 2 22 0 0 0 0 31
#> 3 34 0 0 0 0 21
#> 4 38 1 10546013.8 0 0 28
#> div3Payout div4Winners div4Payout div5Winners div5Payout div6Winners
#> 1 8455.3 60 2348.7 1252 189 1786
#> 2 6004.3 71 2080.6 1808 137.3 2352
#> 3 8584.5 60 2384.6 1405 171.1 2079
#> 4 7676.4 62 2751.4 1389 206.3 1872
#> div6Payout div7Winners div7Payout div8Winners div8Payout rolloverAmount
#> 1 115.2 24664 50 19711 20 3809758.17
#> 2 91.7 35790 50 25981 20 5966533.86
#> 3 100.5 27674 50 21895 20 8055430.87
#> 4 133 28003 50 20651 20 0
#> rolloverNumber totalPrizePool totalSales estimatedJackpot
#> 1 2 6198036.67 9879655 6000000
#> 2 3 9073426.56 11696905 8000000
#> 3 4 10649716.37 10406895 10000000
#> 4 0 13280236.5 11610950 2000000
#> guaranteedJackpot drawMachine ballSet status winners millionairs
#> 1 0 RNG2 RNG published 47494 0
#> 2 0 RNG2 RNG published 66033 0
#> 3 0 RNG2 RNG published 53134 0
#> 4 0 RNG2 RNG published 52006 1
#> gpwinners wcwinners ncwinners ecwinners mpwinners lpwinners fswinners
#> 1 47494 0 0 0 0 0 0
#> 2 66033 0 0 0 0 0 0
#> 3 53134 0 0 0 0 0 0
#> 4 52006 0 0 0 0 0 0
#> kznwinners nwwinners
#> 1 0 0
#> 2 0 0
#> 3 0 0
#> 4 0 0
Created on 2020-04-13 by the reprex package (v0.3.0)
The question already has a satisfactory answer (see above) that I've accepted. I simultaneously arrived at a nearly identical solution; I add it here only because it explicitly covers the full range of available draw numbers and will automatically detect the most recent draw number so that the code can be run 'as is' in the future, provided the National Lottery website design remains the same.
theurl <- "https://www.nationallottery.co.za/index.php?task=results.redirectPageURL&Itemid=265&option=com_weaver&controller=lotto-history"
x <- rvest::html_text(xml2::read_html(theurl))
preceding_string <- "LOTTO, LOTTO PLUS 1 AND LOTTO PLUS 2 DRAW "
drawnums <- as.integer(vapply(gregexpr(preceding_string, x)[[1]] + nchar(preceding_string),
function(k) substr(x, start = k, stop = k + 3), NA_character_))
drawnumrange <- 1506:max(drawnums)
response <- lapply(drawnumrange, function(d) httr::POST(url = theurl,
body = list(gameName = "LOTTO", drawNumber = as.character(d), isAjax =
"true"), encode = "form"))
jsondat <- lapply(response, function(r) jsonlite::parse_json(r)$data$drawDetails)
lottotable <- as.data.frame(do.call(rbind, jsondat))
numericcols <- c(1, 4:32, 36:37)
lottotable[numericcols] <- sapply(lottotable[numericcols], as.numeric)
xlsx::write.xlsx2(lottotable[1:37], "lottotable.xlsx", row.names = FALSE)

Getting an array index from percentage?

I am building out an Angular2 Slider component and the current setup is that the value of the slider is a percentage (based off where the slider handle is from 0% - 100%). I have an array of n items and want the slider to grab the appropriate index from the array based off the percentage (where the handle is at).
Here is my current drag event (fired when user is dragging slider handle):
handleDrag(evt, ui) {
let maxWidth = $('#slideBar').width() - 15;
let position = $('#slideHandle').css('left');
position = position.replace('px', '');
let percent = (+position / +maxWidth) * 100;
this.year = percent;
}
The percentage is working correctly but am wondering how I should structure the algorithem to fetch the array index by percentage. So, if i'm at 50%, I want to fetch the array index 73 if the array length is 146.
Is there an easier way of doing this with JavaScript? I have done a similar component where I did a table approach but would like to figure out a way to do this without adding 'helper html elements' to the page.
Your approach sounds fine, so getting the index would could be achieved by using the .length property of your array as follows:
var actualndex = Math.floor((array.length-1) * percentage);
// Where percentage is a value between 0 and 1
This should return an index between 0 and array.length-1 depending on the percentage value.
TL;DR
This answer didn't work for me. I did some experimenting and found that Math.round is better than Math.floor in this situation, but using Math.floor with some additional logic is even better still. For best results, try:
var index = Math.min(Math.floor(array.length * percentage), (array.length-1));
Intro
I know this question seems to be answered, but I'm posting another answer because using the selected answer gave me unexpected results, and I want to save others from running into the same problem.
First of all, I want to clarify that if you only need an approximation, not a precise result, the selected answer will mostly work, especially for a larger array.
However, for smaller arrays, it frequently does not return the expected result. For example, with an array size of 2, it always returns the first element (index 0) unless the percentage is exactly 100%. Even 99% will return the 1st element (Math.floor((2-1) * 0.99) == 0). In fact, 100% is the ONLY value that will yield the last index (no matter the size of the array).
Expected Results
By "expected" results, I mean, that if an array has N elements, each element is represented by 1/Nth of the values from 0.0 to 1.0. An array of 5 elements would be break down like this:
Given Percentage
Expected Index
[0.00%, 20.00%)
0
[20.00%, 40.00%)
1
[40.00%, 60.00%)
2
[60.00%, 80.00%)
3
[80.00%, 100.00%]
4
Algorithms
I looked at 3 different algorithms with various array sizes:
var indexFloor = Math.floor((array.length-1) * percentage);
var indexRound = Math.round((array.length-1) * percentage);
var indexCustom = Math.min(Math.floor(array.length * percentage), (array.length-1));
Results
All 3 algorithms tend to the same results as the array gets larger, but the 3rd one always gives the results that I would expect.
Take a look at the results from arrays of sizes 2 and 5 (incorrect results in BOLD) (Prettier version):
Percentage
Floor(Size 2)
Round(Size 2)
Custom(Size 2)
Floor(Size 5)
Round(Size 5)
Custom(Size 5)
0.00%
0
0
0
0
0
0
5.00%
0
0
0
0
0
0
10.00%
0
0
0
0
0
0
15.00%
0
0
0
0
1
0
20.00%
0
0
0
0
1
1
25.00%
0
0
0
1
1
1
30.00%
0
0
0
1
1
1
35.00%
0
0
0
1
1
1
40.00%
0
0
0
1
2
2
45.00%
0
0
0
1
2
2
50.00%
0
1
1
2
2
2
55.00%
0
1
1
2
2
2
60.00%
0
1
1
2
2
3
65.00%
0
1
1
2
3
3
70.00%
0
1
1
2
3
3
75.00%
0
1
1
3
3
3
80.00%
0
1
1
3
3
4
85.00%
0
1
1
3
3
4
90.00%
0
1
1
3
4
4
95.00%
0
1
1
3
4
4
100.00%
1
1
1
4
4
4
For size 2, both Round and the custom algorithm produce the expected results. However, for size 5, only the custom algorithm does. Specifically, the Round method has 85% selecting the 3rd element (I would expect 80% and over to be the last element) and 15% selecting 2nd element (I would expect that to require 20%).
We see similar results with slightly larger table sizes (Incorrect Results in bold) (Prettier Version):
Percentage
Floor(Size 8)
Round(Size 8)
Custom(Size 8)
Floor(Size 10)
Round(Size 10)
Custom(Size 10)
0.00%
0
0
0
0
0
0
5.00%
0
0
0
0
0
0
10.00%
0
1
0
0
1
1
15.00%
1
1
1
1
1
1
20.00%
1
1
1
1
2
2
25.00%
1
2
2
2
2
2
30.00%
2
2
2
2
3
3
35.00%
2
2
2
3
3
3
40.00%
2
3
3
3
4
4
45.00%
3
3
3
4
4
4
50.00%
3
4
4
4
5
5
55.00%
3
4
4
4
5
5
60.00%
4
4
4
5
5
6
65.00%
4
5
5
5
6
6
70.00%
4
5
5
6
6
7
75.00%
5
5
6
6
7
7
80.00%
5
6
6
7
7
8
85.00%
5
6
6
7
8
8
90.00%
6
6
7
8
8
9
95.00%
6
7
7
8
9
9
100.00%
7
7
7
9
9
9
The Round and Custom methods are very similar (especially for the size 10 array). They are, in fact, identical up until 60%, which the Round method yields index 5, but the custom method correctly classifies that as index 6. From then on, the Round algorithm is off by one.
Conclusion
The original algorithm's use of Math.floor was correct, but the method used to ensure the result was a valid array index skewed the results because there are there are N elements, not N-1 elements. But when we use N, a percentage value of 100% yields a value that is outside of the valid range of 0 to N-1.
However, by definition, 100% should return the last index of the array, and this can be enforced with a simple call to Math.min. The result is this algorithm for determining an array index using a percentage:
var index = Math.min(Math.floor(array.length * percentage), (array.length-1));
Backup
Complete table of all the tested array sizes and percentages
Excel document I made for testing

Can I represent large integers in Node 6 for only exponentiation without a dependency?

I am working on a kata that asks for the last digit of a[0] ^ (a[1] ^ (a[2] ^ ... (a[n-1] ^ a[n]))). When computing the answer, eventually Math.pow exceeds Number.MAX_SAFE_INTEGER, causing modexp below to return erroneous results.
#user2357112 says that JS needs a library for arbitrary-precision integers, which is all well and good, but nothing in the kata indicates that such a library is available in the remote environment, or even that I need one.
Since the kata and SO point in different directions on this matter, I want to learn if I can feasibly represent big integers ONLY for the purposes of solving this kata without writing an entire library.
My in-progress code is below, and it passes many tests before printing incorrect results. Some code was omitted to avoid spoilers.
TL;DR: If I cannot use a library, what can I do to feasibly represent large integers for the use case indicated by Math.pow()?
function modexp(b, e) {
let c = 1
while(e) {
if (e & 1)
c = c * b % 10
e >>= 1
b = b * b % 10
}
return c;
}
function lastDigit(as) {
if (!as || !as.length) return 1;
let e = as.slice(1).reverse().reduce((p,c) => Math.pow(c,p));
return modexp(as[0], Number(e));
}
This is obviously an X-Y problem. You don't need large integers.
You need to go back to elementary school math.
What's multiplication? Well let's take one example:
WARNING: SPOILERS! Don't read the following if you want to figure it out yourself!
1 2
x 2 3
------
3 6 last digit 6
2 4
------
2 7 6 notice how last digit is only involved
in ONE multiplication operation?
Hmm.. there seems to be a pattern. Let's see if that pattern holds. Let's multiply 12 x 23 x 23 by only doing the last digit:
1 2
x 2 3
------
6 calculate ONLY last digit
x 2 3
------
8 answer is: last digit is 8
Let's check our answer:
1 2
x 2 3
------
3 6
2 4
------
2 7 6
x 2 3
------
8 2 8
5 5 2
-------
6 3 4 8 last digit is INDEED 8
So it seems that you can find the last digit by only calculating the last digit. Let's try to implement a powLastDigit() function.
WARNING: SPOILERS! DON'T READ THE CODE IF YOU WANT TO WRITE IT YOURSELF!
function powLastDigit (number,power) {
var x = number;
for (var y=1; y<power; y++) {
x = ((x%10)*(number%10))%10; // we only care about last digit!
}
return x;
}
Let's check if we are right:
> powLastDigit(3,7)
7
> Math.pow(3,7)
2187
> powLastDigit(5,8)
5
> Math.pow(5,8)
390625
> powLastDigit(7,12)
1
> Math.pow(7,12)
13841287201
OK. Looks like it's working. Now you can use this function to solve your problem. It has no issues with very large exponents because it doesn't deal with large numbers:
> powLastDigit(2323,123456789)
3
Optimization
The above code is slow because it uses a loop. It's possible to speed it up by using Math.pow() instead. I'll leave that as a homework problem.
I use bit array to represent a positive integer;
[0,0,1,1] // bit array of 12 (MSB=rightmost)
This structure is used to manipulate the overall exponent, E
a[1] ^ (a[2] .. (a[n-1] ^ a[n])) // E
(!)There is a relation between LSD(a[0]) and the overall exponent E as below
//LSD(a[0]) LSD(LSD(a[0]) ^ E) for
// [E/4R0, E/4R1, E/4R2, E/4R3]
//--------- ----------------------------
// 0 [0, 0, 0, 0]
// 1 [1, 1, 1, 1]
// 2 [6, 2, 4, 8]
// 3 [1, 3, 9, 7]
// 4 [6, 4, 6, 4]
// 5 [5, 5, 5, 5]
// 6 [6, 6, 6, 6]
// 7 [1, 7, 9, 3]
// 8 [6, 8, 4, 2]
// 9 [1, 9, 1, 9]
For example, find least significant digit of (2 ^ (2 ^ 3)),
// LSD(a[0]) is 2
// E is 8
// implies E mod 4 is 0
// LSD(LSD(a[0]) ^ E)
// for E/4R0 is 6 (ans)
To determine E mod 4,
E[0] + E[1] * 2 // the two LSBs
To summarize, I create a data structure, bit array, to store large integers,
mainly for the intermediate value of exponent-part. The bit array is dynamic length obtaining max. 9007199254740991 bits, if all bits are set, the value in decimal is 2 ^ (9007199254740991 + 1) - 1. This bit array will never be converted back to decimal(safe). The only interesting information of overall exponent, E, is its two least significant bits, they are the remainder of E/4
which can be applied to the above relation(!).
Obviously, Math.pow will not work for bit array, so I handcraft a simple exp() for it. This is trivial since the fact that
//exponentiation == lots of multiplications == lots of additions
//it is not difficult to implement addition on bit array
This is the fiddle demonstrating above idea ONLY. It is intended to be slow if the E is really large. FYI
LSD.find([3,4,5,6]) // my Nightly hanged ~3s to find lsd
You may optimize the Bits.exp by means of childprocesses, web workers, debounce function, simd etc. Good luck.
You don't really need a bigint library to solve this kata.
You are only interested in the last digit of the result, and fortunately there is a property of powers that helps us with this. We effectively want to compute a power in modulus 10. Yes, modular exponentiation does help us a bit here, but the problem is that the exponent is very large as well - too large to compute, and too large to run a loop with that many iterations. But we don't need to, all we are interested in is the modulus of the result.
And there is a pattern! Let's take 4x as an example:
x 4^x (4^x)%10
--------------------------
0 4^0 = 1 1
1 4^1 = 4 4
2 4^2 = 16 6
3 4^3 = 64 4
4 4^4 = 256 6
5 4^5 = 1024 4
… …
20 4^20 = ??? 6 sic!
21 4^21 = ??? 4
… …
You will be able to find these patterns for all numbers in all modular bases. They all share the same characteristic: there's a threshold below which the remainder is irregular, and then they form a repeating sequence. To get a number in this sequence, we only need to perform a modulo operation on the exponent!
For the example above ((4^x)%10), we use a lookup table 0 → 6, 1 → 4 and compute x % 2; the threshold is 1. In JavaScript code, it might look like this:
x < 1 ? 1 : [6, 4][x % 2];
Of course, x is a very large number formed by the repeated exponentiation of the rest of the input, but we do not need to compute it as whole - we only want to know
whether it is smaller than a relatively small number (trivial)
what the remainder after division by q is - just a recursive call to the function we're implementing!

Javascript - return array of values that totals next number up

I am trying to work out the best way to achieve the following:
A score might require a total of 25 'items' AS A MINIMUM
currently that person might have 15.8 'items'
I have a number of items required to reach that score (9.2)
So to get that score the minimum a person must have is 10 'items' in x weeks (to be 25.8 and over the 25 threshold).
Assuming they have 4 weeks to do it that gives 2.5 needed per week.
What I am struggling with is how to output an array of 'whole items' that will make 10.
e.g.
2
3
2
3
I want the items to be as evenly distributed as possible.
so
1
2
3
4
would be useless
I am just trying to work out the best way to do this.
I was thinking of:
finding nearest whole number ROUNDED UP (3 in this example)
Then outputting that number
Then on the next pass gathering the 'remainder' (-0.5) and then rounding the number.
But it doesn't quite work for all cases.
Can anyone help me get my head around it without writing hundreds of lines of code.
As a further example say 17 were needed in 5 weeks that would be
4
3
3
4
3
Thanks in advance.
You could do it some way like this:
function myFunction(total, weeks) {
var n = 0;
var temp = 0;
var arr = [];
while (n < total) {
temp = n;
n += total / weeks;
arr.push(Math.floor(n) - Math.floor(temp));
}
return arr;
}
myFunction(10, 4); //[2, 3, 2, 3]
myFunction(17, 5); //[3, 3, 4, 3, 4]
In this code, total / weeks will be the average number you'll want to add to n to get from 0 to total in exactly weeks iterations.
Now the difference between the original value of n (which is stored in temp) and the new value of n is pushed to the array. That will give you the rounded numbers you'll need to add up to the entered total.

printing quantity of sales per page not overall quantity of sales

So Iam making a birt report on enclipse my goal is to output on each page amount of sales of a given person, not overall amount of sales of that person.
Consider this table(consider we only have 1 person):
personID sales date
------- ----- -----
111 10 2010-02-02
111 15 2010-02-03
111 5 2010-03-03
111 7 2010-04-03
111 8 2011-01-01
111 9 2013-01-01
111 20 2014-01-01
111 25 2014-03-02
The scenario on each page:
It shows 3 results(which I want)
but below each page its showing 99 sales (which I don't want)
What I want is that:
on 1st page it shows 30 sales (for 3 rows)
on 2nd page it shows 24 sales(for 3 rows)
and last page it shows 45(for 2 remaining rows)
what I did is that (i dont know if its right approach):
DENSE_RANK() OVER (ORDER BY sales) AS Row,
convert(integer,ROW_NUMBER() over(order by sales)/4) as page
which turned my table into
personID sales date Row page
------- ----- ----- ---- ----
111 10 2010-02-02 1 0
111 15 2010-02-03 2 0
111 5 2010-03-03 3 0
111 7 2010-04-03 4 1
111 8 2011-01-01 5 1
111 9 2013-01-01 6 1
111 20 2014-01-01 7 1
111 25 2014-03-02 8 2
As you can see there's another issue which is:
the 1st 3 rows got page(0)
but row 4-5-6-7 got page 1 which is wrong it should have been row 4-5-6 page 1
and row 7-8 page 2
I am also working on eclipse using JavaScript
<method name="onPageEnd"><![CDATA[var sales = this.getInstancesByElementName("sales");
var tmp=0;
if( sales != null )
{
for(var i=0; i< sales.length; i++ )
{
for(var j=0;j<3;j++)
{
//Instance of DataItemInstance
var sales = sales[i];
tmp+=parseInt(sales.getValue());
}
}
}
Once your query results are correct, you should compute SUM(sales) based on the page.
This can be done either with SQL (Oracle SQL syntax)
with x as
(
your_query_here
)
select x.*,
sum(sales) over (partition by page) -- IIRC
from x
or with BIRT, if you create a GROUP (called "page" for example) in your (layout) table, and an aggregate column binding based on this group.
Now to the query itself:
I don't think that the DB actually shows the results you state with your query.
Probably "Row" is defined in your query as
DENSE_RANK() OVER (ORDER BY "date" AS "Row"
I often use something like this for "matrix reports in SQL" and the like (asssuming you want 3 rows/page). This is a puire SQL solution:
with
y as (
select ...,
ROW_NUMBER() over(order by "sales") partition by ("personID") - 1 as "Row"
-- Note: Row is zero-based: 0,1,2,...
),
x as (
select y.*,
MOD(y."Row", 3) + 1 as "RowOnPage"
trunc(y."Row"/3) + 1 as "Page"
from y
)
select x.*,
sum("sales") over (partition by "personId", "Page") as SumSalesPerPersonAndPage
-- IIRC
from x
This is probably not quite correct (because I don't know how you intend to handle the different persons), but you get the idea...
For creating reports, it is a great advantage to know analytic functions.
I usually test my queries outside of BIRT (eg with SQL*Developer).

Categories