Getting percent of height, vertical volume slider - actionscript-3

ok I am having a brain fart right now and can't think straight. I've done this many times before.
I am making a vertical volume slider. The top of my slider track is at -80 and the bottom is -16. So my volume handle can slide between -80 and -16 on the Y axis.
-48 is basically 50%. I can't for the life of me figure out this percentage right now, can someone give me a little math help. I took math in summer school all 3 years of high school for a reason :P

max = -80
min = -16
so total points in range = 64
so 50% of total = 64 / 2 = 32
Now starts moving up from -16. You get -48 when you move 32 (50%) points up.
So the percent for any value v (in positive) in range 16 to 80 is:
percent = (v - 16) / 64 * 100
For this example: (48 - 16) / 64 * 100 = 50

Negative numbers confuse me on this sort of thing, but that's what spreadsheets and trial & error are for.
If I read the question right, you know -48 is 50%, and you'd like to know the percentages for other inputs (e.g., -12, -60, etc)
Remove the bias so our range is 0 .. max
Divide that by the max to get the percentage
Take the absolute value
if v is your input value (-48), then p = Math.abs((v+16)/64) where "+16" is just subtracting your lower bound (-16), and "64" is the absolute value of the upper bound minus the lower bound.
Put another way,
var lower:int = -16;
var upper:int = -80;
var v:int = -32;
var p:Number = Math.abs((v - lower) / (Math.abs(upper - lower));
I haven't tested this - no compiler here.

Related

How to calculate the perimeter of a cuboid?

Given is the length, breadth, and height of a cuboid. Your task is to calculate its Perimeter.
Note: Formula for the perimeter of the cuboid is 4(Length + Breadth + Height)
Input
User Task:
Since this will be a functional problem, you don't have to take input. You just have to complete the function Perimeter() that takes integers L, B, and H as parameters.
Constraints:
1 <= L, B, H <= 100
Output
Return the length of the Cuboid.
The steps of this task are relatively simple.
Acquire the length, breadth, and width.
Verify that the values are within the required bounds.
Calculate the perimeter.
Provide either the calculated perimeter or the length, depending on how pedantic the person writing those requirements is.
Number four is probably the hardest part of this task, and you’ll want to contact the person writing the requirements to verify that Output: Return the length of the Cuboid is in fact a typo and that you should be returning the perimeter of the Cuboid.
In this example, I’m going to assume that this is a trick question and provide the length; however, if it is not a trick question and is instead a typo, you’ll want to replace the length variable (LE) with the perimeter variable (PE) on the output line (80).
10 IF NOT (LE < 1 OR LE > 100 OR BR < 1 OR BR > 100 OR WI < 1 OR WI > 100) THEN 60
20 INPUT "LENGTH, BREADTH, WIDTH"; LE, BR, WI
30 IF LE < 1 OR BR < 1 OR WI < 1 THEN PRINT "YOU HAVE ENTERED THE":PRINT "MICROVERSE. PLEASE ENSURE THAT":PRINT "ALL DIMENSIONS ARE AT LEAST 1":PRINT "UNIT."
40 IF LE > 100 OR BR > 100 OR WI > 100 THEN PRINT "YOU HAVE LEFT THE BOUNDS OF":PRINT "THE KNOWN UNIVERSE. PLEASE":PRINT "ENSURE THAT ALL DIMENSIONS ARE":PRINT "NO MORE THAN 100 UNITS."
50 GOTO 10
60 PE = LE + BR + WI
70 PE=PE*4
80 PRINT "THE CUBOID'S LENGTH IS:";LE
90 END
BASIC was never known for its readability, and even this short program is probably difficult to follow. Here is the same program in somewhat more readable form:
loop while (%length% < 1 or %length% > 100 or %breadth% < 1 or %breadth% > 100 or %width% < 1 or %width% > 100)
input "Length, Breadth, Width"; %length%, %breadth%, %width%
switch
case (%length% < 1 or %breadth% < 1 or %width% < 1)
wrap You have entered the microverse. Please ensure that all dimensions are at least 1 unit.
case (%length% > 100 or %breadth% > 100 or %width% > 100)
wrap You have left the bounds of the known universe. Please ensure that all dimensions are no more than 100 units.
endswitch
endloop
%perimeter% = %length% + %breadth% + %width%
%perimeter% *= 4
print "The cuboid's length is:";%length%
This uses SuperBASIC, not as a recommendation (unless, as is very unlikely, the BASIC you happen to be using is on a TRS-80 Color Computer) but simply because I’m familiar with that BASIC preprocessor. These two programs are somewhat equivalent, in that I wrote the more readable code and then used the script to translate it to BASIC.
You can see the steps I outlined above: input the dimensions of the cuboid; verify that the dimensions are within the required bounds; and either loop back to the input request if they are not or calculate the perimeter and print the length if they are.
Note that the loop uses the feature of most BASIC implementations that on first encountering a numeric variable the variable is set to zero, which is out of the bounds of the stated requirements. If your variant of BASIC does not do this, you’ll need to assign initial values, most likely with a DEFINT or a LET statement.

Wrapping around 360 degrees with SQL query

I am fairly new with using SQL and I would like to learn how to efficiently filter a data set of ecliptic coordinates (longitude, latitude) for regions of the sky. The data set is in the southern ecliptic hemisphere (from -90 to 0 and 0 to 360) as shown below (simulated in Python with some simple numpy arange commands).
I have figured out how to filter a specific patch of the sky in python with the following code:
x = (eclong + 360 - center) % 360
ind = x > 180
x[ind] = x[ind] - 360 #converts from 0 to 360 to -180 to +180
x = -x #reverses scale where east direction is on left
To allow data points to wrap around the South pole, I also have an additional required condition:
filtered_eclong = (x < 12/np.cos(eclat *np.pi/180)) & (-12/np.cos(eclat *np.pi/180) < x & eclat < 0)
12 degrees is how wide the patch of sky that I want to grab is and center is a variable for the central ecliptic longitude of my desired patch of sky. The last line in the query is a correction to include objects near the southern ecliptic pole. (Note: eclat = ecliptic latitude , eclong = ecliptic longitude, both in degrees) As an example of the results I would like to get, the patch of sky I want to filter is centered on a ecliptic longitude of 315.8 degrees, seen below:
I've saved the entire simulated southern hemisphere as a csv file and uploaded the eclong and eclat values as columns in a sql database. I would like to be able to recreate the same query I performed in my Python code above. This is the closest attempt I have:
select * from coords
where eclat < -6
and mod(abs(eclong-315.8+360),360)-360 < 180
and mod(abs(eclong-315.8),360) < 12/cos(radians(eclat));
which produces this result where the filtered Python result is shown in red and the filtered sql result is shown in blue:
As shown, my query doesn't include things that wrap around from 360 degrees to 0 degrees and I'm not quite sure how to include those missing points.
I think using some combination of THEN, ELSE or CASE statements would help:
select * from Catalog
where eclat < -6
CASE
WHEN mod(abs(eclong-315.8),360) < 12/cos(radians(eclat)) > 0 THEN 'I'm not sure what to do...'
WHEN mod(abs(eclong-315.8),360) < 12/cos(radians(eclat)) < 360 THEN 'I'm not sure what to do...'
into myDB.filename
Any SQL gurus out there?
Though I'm not familiar with ecliptic coordinates, it sounds like you're trying to reconcile the lack of negative numbers based on your title. If that's indeed what you're going for, who cares that there aren't any negative values—let's pretend there are!
To generalize, we'll need to ensure we can safely calculate ±180 degrees from any starting longitude. With this use case, starting from 11 degrees, we could rearrange the unhelpful values by subtracting 360 from anything greater than 11 + 180 and working with the result as a helper. This way, 359 degrees would instead show up as -1, and then you can do normal math. If your starting longitude is above 180, we'd need to get the lowest values above 360. In SQL, here's a (maybe inefficient, but straightforward) way I'd create a helper column:
CASE
WHEN center < 180 THEN CASE
WHEN eclong > center + 180 THEN eclong - 360
ELSE eclong
END
WHEN center > 180 THEN CASE
WHEN eclong < center - 180 THEN eclong + 360
ELSE eclong
END
ELSE eclong
END as friendly_eclong

GPS Latitude and longitude from hexadecimal value

I'm getting the following replies from a GPS to a microcontroller, rather than try parse the string and convert that to hex to send, I'd rather just use the hex value supplied to then send to my server but I'm having difficulty working out what format it's stored in.
Lat: 37 Deg 39 Min 48.84 Sec S (0xFF94DE3A)
Lon: 144 Deg 58 Min 10.30 Sec E (0x019C5B97)
(another example:)
Lat: 49 Deg 10 Min 21.49 Sec N (0x008BDE6C)
Lon: 123 Deg 4 Min 14.76 Sec W (0xFEA1EE9A)
I've tried answers to other questions with similar titles to no avail..
Lat in the first example looks like -7020998 dec since it's south, similar to Lon in the second example (-22942054) is also negative in the west.
I've tried dividing the numbers by the converted expected result (using degrees + minutes/60 + seconds/3600) I come up with a rough number,
ie:
0xFF94DE3A = -7020998 / -37.66357 = ~186413.502
0x019C5B97 = 27024279 / 144.96953 = ~186413.510
0x008BDE6C = 9166444 / 49.17264 = ~186413.501
0xFEA1EE9A = -22942054 / -123.07077 = ~186413.508
This looks close to 180000, but if I divide by that it doesn't look right (-7020998 / 180000 = -39.00554). What does 186413 relate to though? I feel like I'm missing something completely obvious..
Edit: I'm able to get it working using the below quick example (I know it's not pretty):
if ($GPSLatitude > 0x7FFFFFFF) // ensure correct signedness
$GPSLatitude-=0x100000000;
$GPSf = floatval($GPSLatitude) / 186413.51334561207757602506827277;
$GPSD = floor($GPSf);
$GPSt = abs($GPSf - $GPSD) * 60;
$GPSM = floor($GPSt);
$GPSS = floor(($GPSt - $GPSM) * 6000) / 100;
echo 'GPS Latitude: ' . $GPSD . ' Deg ' . $GPSM . ' Min ' . number_format($GPSS,2,'.','') . ' Sec';
The results match perfectly, but I know there's got to be a better way than dividing by that horrible number?
According to http://en.wikipedia.org/wiki/Geotagging, the GPS coordinates could be set even in rationals:
When stored in EXIF, the coordinates are represented as a series of
rational numbers in the GPS sub-IFD. Here is a hexadecimal dump of the
relevant section of the EXIF metadata (with big-endian byte order):
I am afraid, you have not all hex digits and you see only the upper part of the rational number. And the invisible divisor could be that magic number.
I am not insisting it is so, I only demonstrate there could be ANYTHING hidden in the format.
And you are counting in degrees, and the coord could simply be gaussian X,Y.
Anyway, what is the name of your GPS format?

How can I round an integer to the nearest 1000 in Pascal?

I've got a Integer variable in Pascal. Is there any possible function I can use that can round that value to the nearest 1000, for example:
RoundTo(variable, 1000);
Does anything of the sort exist? Or is there another method I should try using?
Thanks!
The general solution for this kind of problem is to scale before and after rounding, e.g.
y = 1000 * ROUND(x / 1000);
Use RoundTo(variable, 3).
The second parameter specifies the digits you want to round to. Since you want to round to 1000 = 103 you need to specifiy 3, not 1000.
The documentation for RoundTo says:
function RoundTo(const AValue: Extended; const ADigit: TRoundToEXRangeExtended): Extended;
Rounds a floating-point value to a specified digit or power of ten using "Banker's rounding".
ADigit indicates the power of ten to which you want AValue rounded. It can be any value from –37 to 37 (inclusive).
The following examples illustrate the use of RoundTo:
RoundTo(1234567, 3) = 1235000
(I left out parts not relevant to your question)
Side-note: RoundTo uses Banker's round, so RoundTo(500, 3) = 0 and RoundTo(1500, 3) = 2000.
x = 1000*(x/1000), or x = x - (x mod 1000)

Least amount of voters, given two halves

One of my former students sent me a message about this interview question he got while applying for a job as a Junior Developer.
There are two candidates running for president in a mock classroom election. Given the two percentages of voters, find out the least amount of possible voters in the classroom.
Examples:
Input: 50.00,50.00
Output: 2
Input: 25.00,75.00
Output: 4
Input: 53.23, 46.77
Output: 124 // The first value, 1138 was wrong. Thanks to Loïc for the correct value
Note: The sum of the input percentages are always 100.00%, two decimal places
The last example got me scratching my head. It was the first time I heard about this problem, and I'm kindof stumped on how to solve this.
EDIT: I called my student about the problem, and told me that he was not sure about the last value. He said, and I quote, "It was an absurdly large number output" :( sorry! I should've researched more before posting it online~ I'm guessing 9,797 is the output on the last example though..
You can compute these values by using the best rational approximations of the voter percentages. Wikipedia describes how to obtain these values from the continued fraction (which can be computed these using the euclidean algorithm). The desired result is the first approximation which is within 0.005% of the expected value.
Here's an example with 53.23%:
10000 = 1 * 5323 + 4677
5323 = 1 * 4677 + 646
4677 = 7 * 646 + 155
646 = 4 * 155 + 26
155 = 5 * 26 + 25
26 = 1 * 25 + 1
25 = 25* 1 + 0
Approximations:
1: 1 / 1
-> 1 = 100%
2: 1 / (1 + 1/1)
-> 1/2 = 50%
2.5: 1 / (1 + 1 / (1 + 1/6))
-> 7/1 = 53.75%
3: 1 / (1 + 1 / (1 + 1/7))
-> 8/15 = 53.33%
3.5: 1 / (1 + 1 / (1 + 1 / (7 + 1/3)))
-> 25/47 = 53.19%
4: 1 / (1 + 1 / (1 + 1 / (7 + 1/4)))
-> 33/62 = 53.23%
The reason we have extra values before the 3rd and 4th convergents is that their last terms (7 and 4 respectively) are greater than 1, so we must test the approximation with the last term decremented.
The desired result is the denominator of the first value which rounds to the desired value, which in this vase is 62.
Sample Ruby implementation available here (using the formulae from the Wikipedia page here, so it looks slightly different to the above example).
First you can notice that a trivial solution is to have 10.000 voters. Now let's try to find something lower than that.
For each value of N starting à 1
For Each value of i starting à 1
If i/N = 46.77
return N
Always choose the minimum of the two percentages to be faster.
Or faster :
For each value of N starting à 1
i = floor(N*46.77/100)
For j = i or i+1
If round(j/N) = 46.77 and round((N-j)/N) = 53.23
return N
For the third example :
605/1138 = .5316344464
(1138-605)/1138 = .4683655536
but
606/1138 = .5325131810
(1138-606)/1138 = .4674868190
It can't be 1138...
But 62 is working :
33/62 = .5322580645
(62-33)/62 = .4677419355
Rounded it's giving you the good values.
(After some extensive edits:)
If you only have 2 voters, then you can only generate the following percentages for candidates A and B:
0+100, 100+0, or 50+50
If you have 3 voters, then you have
0+100, 100+0, 33.33+66.67, 66.67+33.33 [notice the rounding]
So this is a fun problem about fractions.
If you can make 25% then you have to have at least 4 people (so you can do 1/4, since 1/2 and 1/3 won't cut it). You can do it with more (i.e. 2/8 = 25%) but the problem asks for the least.
However, more interesting fractions require numbers greater than 1 in the numerator:
2/5 = 40%
Since you can't get that with anything but a 2 or more in the numerator (1/x will never cut it).
You can compare at each step and increase either the numerator or denominator, which is much more efficient than iterating over the whole sample space for j and then incrementing i;
i.e. if you have a percentage of 3%, checking solutions all the way up in the fashion of 96/99, 97/99, 98/99 before even getting to x/100 is a waste of time. Instead, you can increment the numerator or denominator based on how well your current guess is doing (greater than or less than) like so
int max = 5000; //we only need to go half-way at most.
public int minVoters (double onePercentage) {
double checkPercentage = onePercentage;
if (onePercentage > 50.0)
checkPercentage = 100-onePercentage; //get the smaller percentage value
double i=1;
double j=1; //arguments of Math.round must be double or float
double temp = 0;
while (j<max || i<max-1) { //we can go all the way to 4999/5000 for the lesser value
temp = (i/j)*100;
temp = Math.round(temp);
temp = temp/100;
if (temp == checkPercentage)
return j;
else if (temp > checkPercentage) //we passed up our value and need to increase the denominator
j++;
else if (temp < checkPercentage) //we are too low and increase the numerator
i++;
}
return 0; //no such solution
}
Step-wise example for finding the denominator that can yield 55%
55/100 = 11/20
100-55 = 45 = 9/20 (checkPercentage will be 45.0)
1/1 100.0%
1/2 50.00%
1/3 33.33%
2/3 66.67%
2/4 50.00%
2/5 40.00%
3/5 60.00%
3/6 50.00%
3/7 42.86% (too low, increase numerator)
4/7 57.14% (too high, increase denominator)
4/8 50.00%
4/9 44.44%
5/9 55.56%
5/10 50.00%
5/11 45.45%
6/11 54.54%
6/12 50.00%
6/13 46.15%
6/14 42.86%
7/14 50.00%
7/15 46.67%
7/16 43.75%
8/16 50.00%
8/17 47.06%
8/19 42.11%
9/19 47.37%
9/20 45.00% <-bingo
The nice thing about this method is that it will only take (i+j) steps where i is the numerator and j is the denominator.
I cannot see the relevance of this question to a position as junior developer.
Then answer that jumped into my head was more of a brute-force approach. There can be at most 5001 unique answers because there 5001 unique numbers between 00.00 and 50.00 . Consequently, why not create and save a look-up table. Obviously, there won't be 5001 unique answer because some answers will be repeated. The point is, there are only 5001 valid fractions because we are rounding to two digits.
int[] minPossible = new int[5001];
int numSolutionsFound = 0;
N = 2;
while(numSolutionsFound < 5001) {
for(int i = 0 ; i <= N/2 ; i++) {
//compute i/N
//see if the corresponding table entry is set
//if not write N there and increment numSolutionsFound
}
N++;
}
//Save answer here
Now the solution is merely a table look up.
FWIW I realize the euclidean solution is "correct". But I'd NEVER come up with that mid interview. However, I'd know something like that was possible -- but I won't be able to whip it out on the spot.