Developing Formula/Pattern To Determine Position - javascript

I'll try to ask as clearly as possible, but please comment if some part is not clear to you.
I'm trying to develop a formula to determine the position of an element based on that element's value in a sequence. More specifically, I am using JavaScript to split a string of this nature: c-c c-c-c c into an array and iterate over that array using an interval of 2i to extract the c values. For example, let's say my string is as previously posted (6 c values in length). I wish to place these c values in the following manner where the number refers to the value of i in my loop (I prepended an extra 0 to make it symmetrical due to the 10):
00 ## 02
##
06 ## 04
##
08 ## 10
I'm trying to find a pattern/formula using the value of i which will result in the above positioning. For simplicity's sake, let's assume an x,y coordinate system such that the position of the c value at 00 is (0,0), 02 is (1,0), 04 is (1,1), 06 is (0,1), 08 is (0,2), and 10 is (1,2).
Can anyone help in developing a pattern/formula/algorithm to determine the positioning using i values? I'm trying not to have to write (in this example) six different if statements.

Using your x,y coordinate system:
y = Math.floor(i / 2);
x = y % 2 == 0 ? i % 2 : (i + 1) % 2;
Or if you want it more concise (but very unclear):
y = Math.floor(i / 2);
x = (i + y % 2) % 2;
The above code is based on the assumption that the code is something like this:
for (var i = 0; i < theString.length / 2; i++) {
var character = theString.charAt(2 * i);
// work out the coordinates
}
If the code is more like this:
for (var i = 0; i < theString.length; i += 2) {
var character = theString.charAt(i);
// work out the coordinates
}
Then we need to do modify it a bit to be like this:
j = i / 2;
y = Math.floor(j / 2);
x = y % 2 == 0 ? j % 2 : (j + 1) % 2;
Or if you want it more concise (but very unclear):
j = i / 2;
y = Math.floor(j / 2);
x = (j + y % 2) % 2;

Related

Modular arithmetic does not work in Threshold signature (TSS) implementation

I was implementing threshold signatures protocol described in this paper and I run into a case where it fails and I don't understand reasons why. In the end, u and x should be the same, but they are not. I would appreciate any advice that will help me to find the bug.
This is JS code, it can be executed in browser console
/// TSS 2-of-2 case
// Field modulus, secp2561k
n = 115792089237316195423570985008687907852837564279074904382605163141518161494337n
// party 1 Polynomial coeff of degree 1
coeff_1 = 103808273981011494448342588544071102049904991793672697167547228275701563388858n
// coeff_1 = 10380827398101149444834258854407110204990499179367269716754722827570156338885n // Working coeff
// party 1 Polynomial coeff of degree 1
coeff_2 = 49961718147812071312795198333632033669565055597187655909241672498689891015278n
// coeff_2 = 4996171814781207131279519833363203366956505559718765590924167249868989101527n // Working coeff
// Party 1 secret
u_1 = 6989964936015280241594720270850184250394589151026058230978623558313385587815n
// Party 2 secret
u_2 = 91492373973552717359377053249757253672786176158857596037729237022345023720795n
// Party 1 Shamir points
y1_x = 1n
y1_1 = (y1_x * coeff_1 + u_1) % n
// 110798238917026774689937308814921286300299580944698755398525851834014948976673n
y1_2 = (y1_x * coeff_2 + u_2) % n
// 25662002884048593248601266574701379489513667476970347564365746379516753241736n
// Party 2 Shamir points
y2_x = 2n
y2_1 = (y2_x * coeff_1 + u_1) % n
// 98814423660722073714708912350304480497367008459296548183467916968198350871194n
y2_2 = (y2_x * coeff_2 + u_2) % n
// 75623721031860664561396464908333413159078723074158003473607418878206644257014n
// Party 1 point (y1_x, y1)
y1 = (y1_1 + y1_2) % n
// Party 2 point (y1_x, y1)
y2 = (y2_1 + y2_2) % n
// Common secret
u = (u_1 + u_2) % n
// Same secret, that went though Shamir schema
x = (y1*2n - y2) % n
// Checking calculations, should be 0
u - x
```
Your code is almost correct, just missing the final modulus at the end. Change the last line to
(u - x) % n;
The (u -x) is exactly n.
115792089237316195423570985008687907852837564279074904382605163141518161494337

lagrange algorithm in Javascript

I wrote a javascript version of Lagrange algorithm, but it kept going wrong when I run it, I don't know what went wrong.
I use this to calculate time.
When I pass a cSeconds as a variable, sometimes it returns a minus value which is obviously wrong...
function LagrangeForCat(cSeconds){
var y = [2592000,7776000,15552000,31104000,93312000,155520000,279936000,404352000,528768000,622080000,715392000,870912000,995328000,1119744000,1244160000,1368576000,1492992000,1617408000,1741824000,1866240000,1990656000,2115072000,2239488000,2363904000,2488320000,2612736000,2737152000,2861568000,2985984000,3110400000,3234816000,3359232000,3483648000,3608064000];
var x = [604800,1209600,1814400,2592000,5184000,7776000,15552000,23328000,31104000,46656000,62208000,93312000,124416000,155520000,186624000,217728000,248832000,279936000,311040000,342144000,373248000,404352000,435456000,466560000,497664000,528768000,559872000,590976000,622080000,653184000,684288000,715392000,746496000,777600000];
var l = 0.0;
for (var j = 0; j < 34; j++) {
var s = 1.0;
for (var i = 0; i < 34; i++) {
if (i != j)
s = s * ((cSeconds - x[i]) / (x[j] - x[i]));
}
l = l + s * y[j];
}
var result = l / (24 * 60 * 60);
var Days = Math.floor(result);
//get float seconds data
var littleData = String(result).split(".")[1];
var floatData = parseFloat("0."+littleData);
var second = floatData *60*60*24;
var hours = Math.floor(second/(60*60));
var minutes = Math.floor(second % 3600/60);
var seconds = Math.floor(second % 3600) % 60;
var returnData = {days:Days,hours: hours + ':' + minutes + ':' + seconds}
return returnData;
}
I don't believe the issue is with your code but with the data set.
I tried a few things, for instance if you have cSeconds = one of the x values, then you get the correct result (I could check that it was equal to the matching y value).
I put all the data in open office and drew the graph it was like the square root function but more extreme (the 'straight' part look very straight) then I remembered that when you interpolate you usually get a polynomial that crosses the points you want but can be very wild outside between the point.
To test my theory I modified the algorithm to control at which x/y index to start and tried for all the values:
for (let i = 0; i < 35; ++i) {
LagrangeForCat(63119321, i, 34)
}
Together with a console.log inside LagrangeForCat it gives me the interpolated y value if I use all the x/y arrays (i=0), if I ignore the first x/y point (i=1), the first two (i=2), ...
00-34 -6850462776.278063
01-34 549996977.0003194
02-34 718950902.7592317
03-34 723883771.1443908
04-34 723161627.795225
05-34 721857113.1756063
06-34 721134873.0889213
07-34 720845478.4754647
08-34 720897871.7910147
09-34 721241470.2886044
10-34 722280314.1033486
11-34 750141284.0070543
12-34 750141262.289736
13-34 750141431.2562406
14-34 750141089.6980047
15-34 750141668.8768387
16-34 750142353.3267975
17-34 750141039.138794
18-34 750141836.251831
19-34 750138039.6240234
20-34 750141696.7529297
21-34 750141120.300293
22-34 750141960.4248047
23-34 750140874.0966797
24-34 750141337.5
25-34 750141237.4694824
26-34 750141289.2150879
27-34 750141282.5408936
28-34 750141284.2094421
29-34 750141283.987999
30-34 750141284.0002298
31-34 750141284.0000689
32-34 750141283.9999985
33-34 3608064000
34-34 0
Exclude 33-34 and 34-34 (there's just not enough data to interpolate).
For the example x=63119321 you'd expect y to be between 715392000 and 870912000 you can see that if you ignore the first 2-3 values the interpolation is "believable", if you ignore more values you interpolate based off the very straight part of the curve (see how consistent the interpolation is from 11-34 onward).
I use to work on a project where interpolation was needed, to avoid those pathological cases we opted for linear interpolation trading accuracy for security (and we could generate all the x/y points we wanted). In your case I'd try to use a smaller set, for instance only two values smaller than cSeconds and two greater like this:
function LagrangeForCat(cSeconds) {
var x = [...];
var y = [...];
let begin = 0,
end = 34
for (let i = 0; i < 34; ++i) {
if (cSeconds < x[i]) {
begin = (i < 3) ? 0 : i - 2
end = (i > (x.length - 1)) ? x.length : i + 1
break
}
}
let result = 0.0;
for (let i = begin; i < end; ++i) {
let term = y[i] / (24 * 60 * 60)
for (let j = begin; j < end; ++j) {
if (i != j)
term *= (cSeconds - x[j]) / (x[i] - x[j]);
}
result += term
}
var Days = Math.floor(result);
// I didn't change the rest of the function didn't even looked at it
}
If you find this answer useful please consider marking it as answered it'd be much appreciated.

How do I solve this ? Javascript

Here is the problem:
Declare a variable called x and assign it a value that equals the remainder of 20 divided by 3. Next, divide and assign 1 to that variable and display the result in an alert box. The result should be 2.
Here is my code:
var x = 20 / 3;
alert(x / 1);
I am brand new to Javascript. I am coming up with 6.66. The answer should be 2. What am I doing wrong?
You need this:
the remainder of 20 divided by 3
You're dividing. The remainder (or modulo) operator in JavaScript is the percentage symbol (%).
So your code should look like this instead:
var x = 20 % 3;
alert(x / 1);
Further reading:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators
https://www.w3schools.com/js/js_arithmetic.asp
Well there is % in JS for remainder. / is the division sign.
var x = 20 % 3; console.log(x / 1);

What is the reverse of the Modulo operator

I have hard time wrapping my head around how to get this to work so I came to ask the help of the brilliant minds in here.
The thing is, I want to reverse the process of the below equation so that I get X from the given Y and Z.
Z = [ ( X * 30 ) % Y ]
For the use-case, a user inputs number Y and then presses ENTER, the system get's the current server time and then multiplies that by 30. The user will then be given the remainder of the server time in format HHMMssxxx, (hmm, xxx here is the millisecond.. I don't know the format letter for millisecond.. hehe..), divided by Y - that is (X*30) % Y where X is the current server time converted to int.
How can I do this in reverse?
The catch is, X should not be greater than 2359999 -> (23:59:59.999) the maximum time value for a 24-hour clock.
Supposedly I have Z = 32, Y = 400, how can I find X?
I know that it's possible to have multiple answers. Here's what I came up so far but I think this is not very optimal in terms of performance.
function getTimeIDx(rem, codeIndexer) {
var times = [];
for(var i = 0; i < 2400000; i++) {
if((i * 30) % codeIndexer == rem) {
var str = i.toString(),
l = str.length;
if(l < 9)
str = '000000000'.substr(0, 9 - l) + str;
str = str.substr(0, 2) + ':' + str.substr(2, 2) + ':' + str.substr(4, 2) + '.' + str.substr(6);
if(/^(?:[0-1]?\d|2[0-3]):(?:[0-5]?\d):(?:[0-5]+\d)/.test(str))
times.push(str);
}
}
return times;
}
Is there some way to do this more efficiently? Is there something like a inverse modulo?
EDIT:
Updated code to check if the string is a valid time.
You cannot reverse it. Modulo is the remainder from a division operation.
Simplifying your equation. Z = Y % 2
Z is 0 for half of the values and 1 for the rest.
You can not solve for the dividend with just the remainder and the divisor.
Lets fill it into the equation:
32 = ( X * 30 ) % 400
Then this means that X * 30 is a multiple of 400 plus 32:
32
432
832
...
Now we could divide that by 30 to get x. That could be done in js like this:
function* reverse(Z, Y) {
for(let n = 0; ; n++)
yield (Z + Y * n) / 30;
}
Usable as:
for(let X of reverse(32, 400))
console.log(X);
Note that this loop will run forever as there are infinite results. Try it

Javascript Brainteaser - Reverse Number Determining

Lets say I have a list of numbers in the following form(Ignore the | they are there for formating help).
00|00|xx
00|xx|00
xx|00|00
etc.
Rules: XX can be any number between 1 and 50. No XX values can be identical.
Now I select a random set of numbers(no duplicates) from a list qualifying the above format, and randomly add and subtract them. For example
000011 - 002400 - 230000 = -232389
How can I determine the original numbers and if they were added or subtracted solely from -232389? I'm stumped.
Thanks!
EDIT:
I was looking for a function so I ended up having to make one. Its just a proof of concept function so variables names are ugly http://jsfiddle.net/jPW8A/.
There are bugs in the following implementation, and it fails to work in a dozen of scenarios. Check the selected answer below.
function reverse_add_subtract(num){
var nums = [];
while(num != 0){
var str = num.toString(),
L = Math.abs(num).toString().length,
MA = str.match(/^(-?[0-9]?[0-9])([0-9][0-9])([0-9][0-9])*$/);
if(MA){
var num1 = MA[1],
num2 = MA[2];
}else{
var num1 = num,
num2 = 0;
}
if(L%2)L++;
if( num2 > 50){
if(num < 0) num1--;
else num1++;
}
nums.push(num1);
var add = parseInt(num1 + Array(--L).join(0),10);
num = (num-add);
}
return nums;
}
reverse_add_subtract(-122436);
First note that each xx group is constrained from [1, 50). This implies that each associated pair in the number that is in the range [50, 99) is really 100 - xx and this means that it "borrowed from" the group to the left. (It also means that there is only one set of normalized numbers and one solution, if any.)
So given the input 23|23|89 (the initial xx spots from -232389), normalize it -- that is, starting from the right, if the value is >= 50, get 100 - value and carry the 100 rightward (must balance). Example: (23 * 100) + 89 = 2300 * 89 = 2400 - 11 = 2389. And example that shows that it doesn't matter if it's negative as the only things that change is the signs: (-23 * 100) - 89 = -2300 - 89 = -2400 + 11 = -2389
(Notes: Remember, 1 is added to the 23 group to make it 24: the sign of the groups is not actually considered in this step, the math is just to show an example that it's okay to do! It may be possible to use this step to determine the sign and avoid extra math below, but this solution just tries to find the candidate numbers at this step. If there are any repeats of the number groups after this step then there is no solution; otherwise a solution exists.)
The candidate numbers after the normalization are then 23|24|11 (let's say this is aa|bb|cc, for below). All the xx values are now known and it is just a matter of finding the combination such that e * (aa * 10000) + f * (bb * 100) + g * (cc * 1) = -232389. The values aa, bb, cc are known from above and e, f, and g will be either 1 or -1, respectively.
Solution Warning: A method of finding the addition or subtraction given the determined numbers (determined above) is provided below the horizontal separator. Take a break and reflect on the above sections before deciding if the extra "hints" are required.
This can then be solved by utilizing the fact that all the xx groups are not dependent after the normalization. (At each step, try to make the input number for the next step approach zero.)
Example:
-232389 + (23 * 10000) = -2389 (e is -1 because that undoes the + we just did)
-2389 + (24 * 100) = 11 (likewise, f is -1)
11 - (11 * 1) = 0 (0 = win! g is 1 and solution is (-1 * 23 * 10000) + (-1 * 24 * 100) + (1 * 11 * 1) = -232389)
Happy homeworking.
First, your math is wrong. Your leading zeros are converting the first two numbers to octal. If that is the intent, the rest of this post doesn't exactly apply but may be able to be adapted.
11-2400-230000 = -232389
Now the last number is easy, it's always the first two digits, 23 in this case. Remove that:
-232389 + 230000 = -2389
Your 2nd number is the next 100 below this, -2400 in this case. And your final number is simply:
-2389 + 2400 = 11
Aww! Someone posted an answer saying "brute force it" that I was about to respond to with:
function find(num){for(var i=1;i<50;i++){for(var o1=0;o1<2;o1++){for(var j=1;j<50;j++){for(var o2=0;o2<2;o2++){for(var k=1;k<50;k++){var eq;if(eval(eq=(i+(o1?'+':'-')+j+'00'+(o2?'+':'-')+k+'0000'))==num){ return eq; }}}}}}}
they deleted it... :(
It was going to go in the comment, but here's a cleaner format:
function find(num){
for(var i=1;i<50;i++){
for(var o1=0;o1<2;o1++){
for(var j=1;j<50;j++){
for(var o2=0;o2<2;o2++){
for(var k=1;k<50;k++){
var eq;
if(eval(eq=(i+(o1?'+':'-')+j+'00'+(o2?'+':'-')+k+'0000'))==num){ return eq; }
}
}
}
}
}
}

Categories

Resources