On the web is lot of conversion tables between foot height and shoe size. Like here http://www.shoesize.com/men/sizechart/ I would like to ask if there is a math function between those two params. Fuction should looks like:
function getShoeSize(height in cm){
...type magic here...
return shoeSize; //size in EU format
}
I don't think there is an easy mathematical way of doing it (I am sure it is possible, but it would probably be unreadable for the average developer).
What I suggest you can do, and which is easy to build. Is that you make an array of the shoe sizes (example of all sizes can be found on http://www.shoesizingcharts.com/ and many more sites). And use that array to convert cm to euro size.
The array could look something like:
var shoeSizeMap = [
{ cm: 20.8, euroSize: '35' },
{ cm: 21.3, euroSize: '35' },
{ cm: 21.6, euroSize: '35/36' },
... etc
]
And use a function to find it like:
function findEuroSizeByCm(cm) {
var result = shoeSizeMap.find(function(shoeSize) {
return shoeSize.cm == cm;
});
return result ? result.euroSize : 'unknown size';
}
findEuroSizeByCm(20.8); // returns 35
ps. be aware that I typed in the example the numbers as 'floats' you might want to compare as strings if your data-source is supplying strings as well (just change cm: 20.8 to cm: '20.8').
It is clear that dependence is not very smooth:
So you can find closest cm size in array with binary search and check if neighbour size is closer (for example, for 26.5 cm binary search can find tabular value 26 as lesser value, but 26.7 is closer, so 42.5 size would fit better). Or use binary search implementation that finds upper value.
Edit: Due to very small array it is simpler to use linear search. Pseudocode:
idx = 0
while (CmSize[idx] < Foot_len) && (idx < CmSize.Length)
idx++
return EUSize[idx]
Related
I'm working on the stonewall exercise of codility. Getting 100% on the correctness tests, but failing all of the performance tests. I'm having trouble envisiging why my solution may be fine for smaller inputs but is going so wrong for larger inputs. Is anyone able to offer feedback about what might be wrong with my solution? I've found this one quite challenging. Taken me a few days of revisiting just to get to this stage! Thanks in advance.
The problem
You are going to build a stone wall. The wall should be straight and N
meters long, and its thickness should be constant; however, it should
have different heights in different places. The height of the wall is
specified by an array H of N positive integers. H[I] is the height of
the wall from I to I+1 meters to the right of its left end. In
particular, H[0] is the height of the wall's left end and H[N−1] is
the height of the wall's right end.
The wall should be built of cuboid stone blocks (that is, all sides of
such blocks are rectangular). Your task is to compute the minimum
number of blocks needed to build the wall.
Write a function:
function solution(H);
that, given an array H of N positive integers specifying the height of
the wall, returns the minimum number of blocks needed to build it.
For example, given array H containing N = 9 integers: H[0] = 8
H[1] = 8 H[2] = 5 H[3] = 7 H[4] = 9 H[5] = 8 H[6] = 7
H[7] = 4 H[8] = 8
the function should return 7. The figure shows one possible
arrangement of seven blocks.
Write an efficient algorithm for the following assumptions:
N is an integer within the range [1..100,000];
each element of array H is an integer within the range [1..1,000,000,000].
My solution
function solution(H) {
let stones = 0
let absoluteMinimum = Infinity;
let prevStones = []
for (let i = 0; i < H.length; i++) {
if (H[i] < absoluteMinimum) {
stones ++
absoluteMinimum = H[i]
prevStones = [H[i]]
} else if (prevStones.includes(H[i])) {
while (prevStones.includes(H[i])) {
prevStones.pop()
}
prevStones.push(H[i])
} else if (H[i] != H[i-1]) {
prevStones.push(H[i])
stones ++
}
}
return stones
}
Here is the summary of my attempt including test results.
https://app.codility.com/demo/results/training2V8Y42-AUQ/
Following #Teemu's comment, and noting that the code simply is searching prevStones for the existence of a specific height, suggest creating another array that holds the counts of the heights in prevStonesCount.
Eg, if setting prevStones = [ 8 ] then set prevStonesCount[ 8 ] = 1, as there is one stone in the prevStones array of height 8.
Now, rather than having to perform prevStones.includes( 8 ), simply check if 0 < prevStonesCount[ 8 ]. (That is, .includes() searches the entire prevStones array for a height of 8, whereas prevStonesCount[ 8 ] in one step indicates whether any stones of height 8 are in the prevStones array.)
Thus, anytime performing a prevStones.push( x ) or prevStones.pop( x ), make the corresponding adjustment of prevStonesCount[ x ] += 1 or prevStonesCount[ x ] -= 1, respectively.
Note also that within the first if where prevStones = [H[i]], that the prevStones array is essentially cleared and set to an initial value. This means that the prevStonesCount array will also need to be cleared, and then set prevStonesCount[ H[i] ] = 1.
What's the best way to calculate the size needed to fit an array of pixels into an image as close as possible to a rectangle/square shape without losing or adding unnecessary pixels?
Using an image of 100 pixels as an example, the best size to fit all pixels would be 10x10, because 10*10 is 100, that is, it adds the least amount of extra pixels (in this case 0). 100x1 also fits all pixels, but it sure is much less rectangular than 10x10.
And in order to fit 101 pixels the best size is 8x13, although 8*13 is 104, it's the only multiplication that doesn't lose any pixels, adds few extra pixels (3), and has the most rectangular shape.
So far I have been able to solve this problem with the following rules:
Dividing width by height must result in a value greater than 0.5 and
less than 1.5. (This will ensure that only the most rectangular values are kept).
Multiplying width by height must result in a value greater than or
equal to the number of pixels.
By applying these rules I end up with a variety of possibilities, the best one being the one that, when multiplied, most closely approximates the number of pixels.
Here's what my code looks like currently:
function loopPixels(pixels, callback) {
for (let x = 2; x < pixels; x++) {
for (let y = 2; y < pixels; y++) {
callback(x, y);
}
}
}
function getRectangle(pixels) {
let result = {extraPixels: pixels};
loopPixels(pixels, (left, right) => {
let half = (left/right);
let total = (left*right);
if (Math.round(half) == 1 && total >= pixels) {
if (total-pixels < result.extraPixels) {
result = {size: [left, right], extraPixels: total-pixels};
}
}
})
return result;
}
getRectangle(101) // must return [[8, 13], 3] (width, height and additional pixels)
What it does is keep a variable holding the smallest result of (width*height)-pixels, which is the difference between the found values and the number of pixels.
Although it works fine for small amounts of pixels, with huge values (which would likely return 1000x1000 sizes), it's ultra slow.
Is there a specific reason for such slowness? and would it be possible to get the same result without using nested for loops?
The following code can be made more efficient but it is very descriptive. It takes a pixel count (n) and a k value which denotes the best k matches.
Lets try 68M pixels for some resonable aspect ratios.
function getReasonableDimensions(n,k){
var max = ~~Math.sqrt(n);
return Array.from({length: max}, (_,i,a) => [n%(max-i),max-i])
.sort((a,b) => a[0] - b[0])
.slice(0,k)
.map(t => [Math.floor(n/t[1]), t[1]]);
}
var res = getReasonableDimensions(68000000,10)
console.log(JSON.stringify(res));
I'm trying to make an animation recorder that records x,y positions into an array and allow the animation to be recalled. I specifically have p5.js in mind as the graphics lib, but any should work. since this is just array work.
in p5.js to return the value of Sin() or Cos() you can pass them an angle, that angle can be ever incrementing since 2PI == 4PI (in terms of the direction the rotation is facing) etc. I'm looking to replicate this kind of function but to return the data stored in an array.
so for example you've got an array like the following
let demo = ['297', '298', '299', '300']
It would be easy to loop over the array once since it has 4 items, but I'd like to write a function where if we passed in 4, it would return index 0, '297' or if we fed in 11, it would return '300' or if we fed in 22 it would return '299'
this way the function could continually be fed in an ever increasing value that moves up each frame we could return the values of the array in a loop.
let survey = 0;
let demo = ['297', '298', '299', '300']
//a rendering loop
function draw(){
survey ++
let xPos = getPosition(survey) //this getPosition function is the one in question
ellipse(xPos,100,50)
}
I feel like this is some modulo math, but I cant quite get it sorted.
thanks for taking a look!
The solution to your problem is the modulus (%) operator. This operator will return the remainder of the division.
E.g. 11 % 4 = 3
const positions = [297, 298, 299, 300];
function getPosition(positions, i) {
return positions[i % positions.length];
}
console.log(getPosition(positions, 4)); // 297
console.log(getPosition(positions, 11)); // 300
console.log(getPosition(positions, 22)); // 299
I need to create a rowchart in dc.js with inputs from multiple columns in a csv. So i need to map a column to each row and each columns total number to the row value.
There may be an obvious solution to this but i cant seem to find any examples.
many thanks
S
update:
Here's a quick sketch. Apologies for the standard
Row chart;
column1 ----------------- 64 (total of column 1)
column2 ------- 35 (total of column 2)
column3 ------------ 45 (total of column 3)
Interesting problem! It sounds somewhat similar to a pivot, requested for crossfilter here. A solution comes to mind using "fake groups" and "fake dimensions", however there are a couple of caveats:
it will reflect filters on other dimensions
but, you will not be able to click on the rows in the chart in order to filter anything else (because what records would it select?)
The fake group constructor looks like this:
function regroup(dim, cols) {
var _groupAll = dim.groupAll().reduce(
function(p, v) { // add
cols.forEach(function(c) {
p[c] += v[c];
});
return p;
},
function(p, v) { // remove
cols.forEach(function(c) {
p[c] -= v[c];
});
return p;
},
function() { // init
var p = {};
cols.forEach(function(c) {
p[c] = 0;
});
return p;
});
return {
all: function() {
// or _.pairs, anything to turn the object into an array
return d3.map(_groupAll.value()).entries();
}
};
}
What it is doing is reducing all the requested rows to an object, and then turning the object into the array format dc.js expects group.all to return.
You can pass any arbitrary dimension to this constructor - it doesn't matter what it's indexed on because you can't filter on these rows... but you probably want it to have its own dimension so it's affected by all other dimension filters. Also give this constructor an array of columns you want turned into groups, and use the result as your "group".
E.g.
var dim = ndx.dimension(function(r) { return r.a; });
var sidewaysGroup = regroup(dim, ['a', 'b', 'c', 'd']);
Full example here: https://jsfiddle.net/gordonwoodhull/j4nLt5xf/5/
(Notice how clicking on the rows in the chart results in badness, because, what is it supposed to filter?)
Are you looking for stacked row charts? For example, this chart has each row represent a category and each color represents a sub-category:
Unfortunately, this feature is not yet supported at DC.js. The feature request is at https://github.com/dc-js/dc.js/issues/397. If you are willing to wade into some non-library code, you could check out the examples referenced in that issue log.
Alternatively, you could use a stackable bar chart. This link seems to have a good description of how this works: http://www.solinea.com/blog/coloring-dcjs-stacked-bar-charts
I have a grid with 4 doughtnut charts on each column for different periods of time: last 90 days, last 60 days, last 7 days and today.
The problem with today is that it doesn't always show data, especially in the morning. Is there a way to force ChartJS to show the chart even if it doesn't have any data?
Here's an example: http://jsfiddle.net/6xV78/219/
var pieData = [
{
value: 0,
color:"#3F9F3F"
},
{
value : 0,
color : "#222"
}
];
I found a quick work-around, not sure how "good" or "valid" way it is but it's working for me. If the values are null/zero I replaced them with -1 to retain the looks of the chart and then use the custom tooltip function to override the output.
{
...
data: [earned == 0 ? -1 : earned, pending == 0 ? -1 : pending]
...
},
options: {
tooltip: {
callbacks: {
label: function (tooltipItem, data) {
const value = data['datasets'][0]['data'][tooltipItem['index']];
return '$' + (value == -1 ? 0 : value);
}
}
}
}
Obviously I have 2 slices and when both are 0 the chart is displayed with 2 equal halves both showing $0 income (both earned and pending).
*Do note that this will still take 1 into account when others aren't null so you need to take care of that on your end. I added a method to verify if ALL values are null and that's the only case I display it like this.
A pie chart with all values equal to zero is ill-defined. Because the angle (and the area) of each slice is proportionate to the ratio of the slice's respective value over the sum of all values. If all values are equal to zero, then their sum is zero. Division by zero should be rightfully avoided by the library (hopefully by design), resulting in the no-pie-chart case you encounter. It should be the programmer's responsibility to detect the all-zeros case before populating the chart, if such a case has a possibility of occurring. Then the programmer could either display a "No data yet. What are you doing up so early? Go to sleep." message, if all values are zero. Or, maybe, if they terribly need to keep the looks consistent (having a chart there all the time), they could show a special all-black no-data pie chart with the following dummy data:
var pieNoData = [
{
value: 1,
color: "#000000"
}
];
There is no shame in disclosing that no data exists yet, though.