JS - Unity - Multiples of a Number from a Number - javascript

I have a yield WaitForSeconds, transform.position.y=transform.position.y+1; cycle which constantly adds numbers.
At the bottom I will have 52 of these:
function Update () {
if (transform.position.y ? == 1) {
print ("Part2")
}
if (transform.position.y ? == 2) {
print ("Part3")
}
if (transform.position.y ? == 3) {
print ("Part4")
}
etc...
How do I set it so that to get it to say 'Part2', the transform.position.y has to be either 2, 54, 106, etc.. (onwards forever).
Much would be appreciated

Something like this?
if ( transform.position.y == 2 || transform.position.y == 54 || transform.position.y == 106 ) {
print ("Part2");
}

You can just use the mod operator (% in Javascript) which returns the division remainder of two integers.
For example:
7 % 2 = 1
So transform.position.y % 52 will do exactly what you want:
0 % 52 = 0
1 % 52 = 1
2 % 52 = 2
...
51 & 52 = 51
52 % 52 = 0
53 % 52 = 1
54 % 52 = 2
and so on...
To have it go from 1-52 instead of 0-51, you can just add one to the result.
All together:
function Update() {
var part : int = transform.position.y % 52 + 1;
print( "Part" + part.ToString() );
}

Related

Efficient way to end the recursion?

I'm trying to define a recursive function that returns X if the given input's square sum leads to 1, which works fine. However, if the input doesn't lead to 1 then it keeps looping and I cannot find a way to exit it.
For instance, input of integer 7, 10, 13 leads to 1, but input of 2, 3, 4, 5, 6, 11 does not. If I try
x === 4 || x === 0
, it ends the recursion for the input that does not lead to 1 but for some inputs it takes multiple recursion calls to reach to 4 and that's not efficient. Later on, I want to use the return values for other calculations.
function recursion(x) {
if (x === 0) {
return;
}
if (x === 1) {
return x;
}
x = squareSum(x);
return recursion(x);
}
Here is the squareSum function.
function sqaureSum(n){
let sumTotal;
if (n < 10){
sumTotal = Math.pow(n, 2);
return sumTotal;
}
sumTotal = Math.pow(n % 10, 2) + squareSum(Math.floor(n / 10));
return sumTotal;
}
You need to track the numbers you've already seen, stopping when you reach 1 or when you reach a number you've already seen.
We can add a default parameter with a list of already-seen numbers, and then in a recursive call, add the current number to that list. This version just returns a boolean, true if the number eventually reaches 1 and false if we hit some other cycle. And we find the numbers among the first hundred positive integers, which do reduce to 1:
const squareSum = (n) =>
(n) < 10 ? n * n : (n % 10) ** 2 + squareSum (Math .floor ( n / 10))
const repeatedSquareSum = (n, seen = []) =>
n <= 1
? true
: seen .includes (n)
? false
: repeatedSquareSum (squareSum (n), [...seen, n])
console .log (Array .from ({length: 100}, (n, i) => i + 1) .filter (n => repeatedSquareSum(n)))
You wanted to return the original number in the positive case. That's odd, but not much more difficult:
const repeatedSquareSum = (n, seen = []) =>
n <= 1
? seen [0] || n
: seen .includes (n)
? false
: repeatedSquareSum (squareSum (n), [...seen, n])
(The || n bit is just because we haven't yet added anything to seen in the cases of 0 and 1.)
You also could return the array of numbers visited in the false case, by returning seen instead of false in that case, or if you just want to see the repeating cycle of numbers, you could return [...seen .slice (seen.indexOf (n)), n].
Other notes have pointed out that there is only one cycle of repeating values, outside of 0 -> 0 and 1 -> 1. And that is 4 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20 -> 4. This somewhat surprising result is proven in a fairly readable formal mathematical paper. Using that information, we can choose to write an even simpler version:
const repeatedSquareSum = (n) =>
n <= 1
? true
: n == 4
? false
: repeatedSquareSum (squareSum (n))
Update
A followup question in the comments (next time, please start a new question) asked how to count the number of steps until we reach a target number such as 20. We can add a default parameter with the count, and track until we reach that number or enter a loop. The only complexity is that if the target is in the list of numbers that cycle endlessly, we need to not stop when we enter the loop but only when we hit the target number.
Here we build this on the last version above for simplicity, but we could also do so atop the earlier, more complex versions:
const squareSum = (n) =>
(n) < 10 ? n * n : (n % 10) ** 2 + squareSum (Math .floor ( n / 10))
const squareSumToTarget = (target) => (n, count = 0) =>
n <= 1 || (![4, 16, 37, 58, 89, 145, 42, 20] .includes (target) && n == 4)
? Infinity
: n == target
? count
: squareSumToTarget (target) (squareSum (n), count + 1)
const squareSumTo20 = squareSumToTarget (20)
console .log (squareSumTo20 (445566)) //=> 3 (445566 -> 154 -> 42 -> 20)
console .log (squareSumTo20 (44)) //=> Infinity (44 -> 32 -> 13 -> 10 -> 1 -> 1 -> 1 -> ...)
console .log (squareSumTo20 (4)) //=> 7 (4 -> 16 -> 37 -> 58 -> 89 -> 145 -> 42 -> 20)
console .log (squareSumToTarget (17) (79)) //=> Infinity (79 -> 130 -> 10 -> 1 -> 1 -> 1 -> ...)
console .log (squareSumToTarget (36) (5) )
//=> Infinity (36 -> 45 -> 41 -> 17 -> 50 -> 25 -> 29 -> 85 -> 89 -> 145 -> 42 -> 20 -> 4 -> 16 -> 37 -> 58 -> 89 ...)
// ^----------------------------------------------'
because of sumTotal = Math.pow(n % 10, 2) + squareSum(n / 10);
when you calculate n / 10 it's can be a float, and you should convert your numbers to int
for checking float numbers log x inside recursion
function recursion(x) {
console.log(x) // <-- HERE
...
}
Math.floor, Math.ceil, Math.round can help you
and for
if (x === 0) {
return;
}
inside recursion add a value ( 0 or 1 ).
it's return undefiend and it convert to NaN
Searching a few minuts, I found this util information. Summarizing, you can check if the number you get, in some point is equal to any of these numbers: 4, 16, 37, 58, 89, 145, 42, 20:
const loopNumbers = new Set([4, 16, 37, 58, 89, 145, 42, 20]);
...
if(loopNumbers.has(x)) {
// It does not lead to 1
}

javascript program to convert binary to decimal and back

I have tried this
function binToDec(num) {
let dec = 0;
for(let i = 0; i < num.length; i++) {
if(num[num.length - (i + 1)] === '1') {
dec += 2 ** i;
}
}
return dec;
}
console.log(binToDec('1010'));
this code is not mine and it works but i want to know how it converts the binary number to decimal and it will be very helpful is you could tell me another way to do it.
I have also tried this
function binToDec(num) {
let bin = parseInt(num, 2);
return bin;
}
console.log(binToDec(1010));
I know this also work but i am not looking for this answer.
thank you for your help.
I just starts with the last character of the string and adds the value of this position to the result.
string dec
------ -------
1010 0
0 0
1 0 + 2
0 2
1 2 + 8
------ ------
10
function binToDec(num) {
let dec = 0;
for (let i = 0; i < num.length; i++) {
if (num[num.length - (i + 1)] === '1') {
dec += 2 ** i;
}
}
return dec;
}
console.log(binToDec('1010')); // 10
Another way is to start with the left side of the sting and
multiply the converted value by the base (2) and
add the value of the string.
The result is now the converted number. This works for all bases, as long as the value at the index is converted to a number.
function binToDec(num) {
let dec = 0;
for (let i = 0; i < num.length; i++) {
dec *= 2;
dec += +num[i];
}
return dec;
}
console.log(binToDec('1101')); // 13
Explanation
Think of how base 10 works.
909 = 900 + 9
= (9 * 100) + (0 * 10) + (9 * 1)
= (9 * 10**2) + (0 * 10**1) + (9 * 10**0)
As you can see, a natural number in base 10 can be seen as a sum where each term is in the form of:
digit * base**digit_position
This is true for any base:
base 2 : 0b101 = (0b1 * 2**2) + (0b0 * 2**1) + (0b1 * 2**0)
base 16 : 0xF0F = (0xF * 16**2) + (0x0 * 16**1) + (0xF * 16**0)
Therefore, here is a possible abstraction of a natural number:
function natural_number (base, digits) {
var sum = 0;
for (var i = 0; i < digits.length; i++) {
digit = digits[i];
digit_position = digits.length - (i + 1);
sum += digit * base**digit_position;
}
return sum;
}
> | natural_number(2, [1, 0, 1]) // 1 * 2**2 + 1 * 2**0
< | 5
> | natural_number(10, [1, 0, 1]) // 1 * 10**2 + 1 * 10**0
< | 101
> | natural_number(16, [1, 0, 1]) // 1 * 16**2 + 1 * 16**0
< | 257
Your own function takes only binary numbers (base 2). In this case digit can be either 0 or 1, that's all. We know that it's useless to multiply something by 0 or 1, so the addition can be replaced with:
if (digit === 1) {
sum += 2**digit_position;
}
Which is the equivalent of:
if (num[num.length - (i + 1)] === '1') {
dec += 2 ** i;
}
Do you get it? :-)
Alternative
You don't feel confortable with the exponentiation operator (**)? There is a workaround. Did you ever notice that multiplying a number by 10 is nothing more than shifting its digits one time to the left?
909 * 10 = 9090
Actually, shifting a number to the left boils down to multiplying this number by its base:
number *= base
This is true for any base:
base 2 : 0b11 * 2 = 0b110
base 16 : 0xBEE * 16 + 0xF = 0xBEE0 + 0xF = 0xBEEF
Based on this, we can build an algorithm to convert an array of digits into a number. A trace of execution with [9,0,9] in base 10 as input would look like this:
init | 0 | n = 0
add 9 | 9 | n += 9
shift | 90 | n *= 10
add 0 | 90 | n += 0
shift | 900 | n *= 10
add 9 | 909 | n += 9
Here is a possible implementation:
function natural_number (base, digits) {
var n = 0;
for (var i = 0; i < digits.length; i++) {
n += digits[i];
if (i + 1 < digits.length) {
n *= base;
}
}
return n;
}
Of course this function works the same as before, and there is a good reason for that. Indeed, unroll the for loop that computes [9,0,9] in base 10, you get this:
return ((0 + 9) * 10 + 0) * 10 + 9;
Then expand this expression:
((0 + 9) * 10 + 0) * 10 + 9
= (0 + 9) * 10 * 10 + 0 * 10 + 9
= 9 * 10 * 10 + 0 * 10 + 9
= 9 * 10**2 + 0 * 10**1 + 9 * 10**0
Do you recognize the equation discussed earlier? :-)
Bonus
Reverse function:
function explode_natural_number (base, number) {
var remainder, exploded = [];
while (number) {
remainder = number % base;
exploded.unshift(remainder);
number = (number - remainder) / base;
}
return exploded.length ? exploded : [0];
}
> | explode_natural_number(2, 5)
< | [1, 0, 1]
> | explode_natural_number(3, 5) // base 3 (5 = 1 * 3**1 + 2 * 3**0) :-)
< | [1, 2]
> | explode_natural_number(16, natural_number(16, [11, 14, 14, 15])) // 0xBEEF
< | [11, 14, 14, 15]
String to number and number to string:
function parse_natural_number (number, base) {
var ZERO = 48, A = 65; // ASCII codes
return natural_number(base, number.split("").map(function (digit) {
return digit.toUpperCase().charCodeAt(0);
}).map(function (code) {
return code - (code < A ? ZERO : A - 10);
}));
}
function stringify_natural_number (number, base) {
var ZERO = 48, A = 65; // ASCII codes
return String.fromCharCode.apply(
String, explode_natural_number(base, number).map(function (digit) {
return digit + (digit < 10 ? ZERO : A - 10);
})
);
}
> | stringify_natural_number(parse_natural_number("48879", 10), 16)
< | "BEEF"
> | parse_natural_number("10", 8)
< | 8
More levels of abstraction for convenience:
function bin_to_dec (number) {
return parse_natural_number(number, 2);
}
function oct_to_dec (number) {
return parse_natural_number(number, 8);
}
function dec_to_dec (number) {
return parse_natural_number(number, 10);
}
function hex_to_dec (number) {
return parse_natural_number(number, 16);
}
function num_to_dec (number) {
switch (number[0] + number[1]) {
case "0b" : return bin_to_dec(number.slice(2));
case "0x" : return hex_to_dec(number.slice(2));
default : switch (number[0]) {
case "0" : return oct_to_dec(number.slice(1));
default : return dec_to_dec(number);
}
}
}
> | oct_to_dec("10")
< | 8
> | num_to_dec("010")
< | 8
> | 010 // :-)
< | 8
function dec_to_bin (number) {
return stringify_natural_number(number, 2);
}
> | dec_to_bin(8)
< | "1000"

Javascript round down whole number

Im trying round down a whole number, but I cant seem to find a javascript function for this.
I have tried math.floor but this does not do the trick. The number must always be rounded down, not sure if there's an javascript function for this?
Example:
29 -> 20
4456 -> 4450
111 -> 110
9 -> 9//the number cant be 0
....
Math.floor(344);//returns 344 (it must be 340)
You can round to the nearest place by utilizing the power of 10.
function ceil10(n, e) {
var m = Math.pow(10, e - 1);
return Math.ceil(n / m) * m || n;
}
function floor10(n, e) {
var m = Math.pow(10, e - 1);
return Math.floor(n / m) * m || n;
}
function roundNearestLog(n) {
var e = Math.ceil(Math.log(n + 1) / Math.LN10),
m = Math.pow(10, e - 1);
return Math.floor(n / m) < 5 ? floor10(n, e) : ceil10(n, e);
}
console.log('ceil 3 =', ceil10(344, 3)); // 400
console.log('ceil 2 =', ceil10(344, 2)); // 350
console.log('ceil 1 =', ceil10(344, 1)); // 344
console.log('ceil 0 =', ceil10(344, 0)); // 344
console.log('-------------');
console.log('floor 0 =', floor10(344, 0)); // 344
console.log('floor 1 =', floor10(344, 1)); // 344
console.log('floor 2 =', floor10(344, 2)); // 340 <-- What you want
console.log('floor 3 =', floor10(344, 3)); // 300
console.log('-------------');
console.log('near 3 =', roundNearestLog(3)); // 3
console.log('near 34 =', roundNearestLog(34)); // 30
console.log('near 344 =', roundNearestLog(344)); // 300
console.log('-------------');
console.log('near 6 =', roundNearestLog(6)); // 6
console.log('near 67 =', roundNearestLog(67)); // 70
console.log('near 677 =', roundNearestLog(677)); // 700
.as-console-wrapper { top: 0; max-height: 100% !important; }
You can still use Math.floor, and simply shift the answer by an order of magnitude:
const moreFloor = n => Math.floor (n / 10) * 10 || n;
// (or if you prefer...)
function moreFloor (n) {
return Math.floor (n / 10) * 10 || n;
}
Just to clarify, the || n at the end of the expression is due to the particular requirement in the question to not round down any number less than ten. If readers want moreFloor(9) === 0, you can omit that part.
Well, that's weird, but here's my answer.
function roundDown(numberToRound) {
//Check if the number would've rounded to 0
if (numberToRound < 10) return numberToRound;
//Return the number minus the difference to the nearest multiple of 10
return numberToRound - (numberToRound % 10);
}
You could subtract the remainder part of 10 and check if the value is zero.
function down(v) {
return v - v % 10 || v;
}
console.log(down(111));
console.log(down(30));
console.log(down(9));
console.log(down(0));

JavaScript - Project Euler #5 -- efficiency

This is for Project Euler, problem #5.
The task is to find the smallest number evenly divisible by numbers 1-20. My code seems to work on 1-18, but at 19 my browser starts timing out. This leads me to believe my code is just inefficient.
How can I mitigate this?
function divisible(a){
counter = 0;
result = 2;
while (counter < a){
for (var x = 0; x <= a; x ++){
if (result % x === 0){
counter ++;
}
}
if (counter != a){
counter = 0;
result ++;
}
}
return result;
}
divisible(20)
Basically, you want the least common multiple of 1,...,20.
I would implement lcm by using gcd, which can be implemented using the fast Euclidean algorithm.
function gcd(a, b) {
return b === 0 ? a : gcd(b, a%b); // Euclidean algorithm
}
function lcm(a, b) {
return a * b / gcd(a, b);
}
function divisible(a){
var result = 1;
for(var i=2; i<=a; ++i)
result = lcm(result, i);
return result;
}
divisible(20); // 232792560
Yup, inefficient. You would need to change the algorithm. The most efficient I can think of is to factorise all the numbers from 2 to 20 (with factors and counts: e.g. 18 is 3 * 3 * 2, or twice 3 and once 2, for final { 3: 2, 2: 1 }); then find the maximum for each factor, and multiply them together.
An abbreviated example: the least number that is divisible by 18 and 16:
18: { 3: 2, 2: 1 }
16: { 2: 4 }
maximums of factor repetitions: { 3: 2, 2: 4 }
result: 3^2 * 2^4 = 144
Factorising numbers from 2 to 20 is easy; if you don't know how to do it, there are many possible algorithms, you can see the Wikipedia article on integer factorisation for ideas.
another option with brute force and modulo rest-classification
this problem can be solved with a simple common modulo rest class characteristics.
look at the numbers from 1 to 20 and divide it into two groups and find some unique common attributes between them.
1 2 3 4 5 6 7 8 9 10
we are building a division with the same reminder members
1 divides all
2 divide 4,8 -->>8 important
3 divide 6,9 but 6 doesnt divide 9 evenly--> 6,9
5 divide 10-->> 10 important
that leaves us with 6,7,8,9,10 to check if there is any number from 1 that can divide this with rest 0.
the trick is if 2,4,8 divides a number let say 16 with the same reminder then we don't have to check if 2,4 divides 16, we check only 8.
11 12 13 14 15 16 17 18 19 20
here we can do the same from about with factors of the numbers from above and we will be left with
11 12 13 14 15 16 17 18 19 20
NB: we know that the last number that has to divide the number is 20,
so that means either the solution will be a number ending with 0 or is
one of the factors of 20, so we build factors of 20 and check if 11 12
13 14 15 16 17 18 19 can divide it then we are done.
int start = 20;
while (start % 11 != 0 || start % 12 != 0 | start % 13 != 0 || start % 14 != 0 ||
start % 15 != 0 || start % 16 != 0 || start % 17 != 0 || start % 18 != 0 || start % 19 != 0 )
{
start += 20;
}
console.log(start)
The same idea applies analogue to the first deduction I made to make the
problem seems smaller.
//smallest number divisible by all numbers from 1 to 10
int a = 10;
while (a % 6 != 0 || a % 7 != 0 | a % 8 != 0 || a % 9 != 0 )
{
a += 10;
}
console.log(a)
//smallest number divisible by all numbers from 1 to 5
int i = 5;
while (i % 3 != 0 || i % 4 != 0)
{
i += 5;
}
console.log(i)

Normalising the remaining decimal of a number?

I have a counter that goes up by 0.33 on each iteration. What's the best way of normalising the output such that the remaining decimal is either .33, .66 or .99 depending on its logical iteration?
On the left is my counter after each iteration, and on the right shows how I would like it normalised:
iteration / decimal / normalised
0 > .33 > .33
1 > .66 > .66
2 > .99 > .99
3 > 1.32 > 1.33
4 > 1.65 > 1.66
5 > 1.98 > 1.99
6 > 2.31 > 2.33
7 > 2.64 > 2.66
8 > 2.97 > 2.99
...
170 > 56.1 > 56.99
171 > 56.43 > 57.33
172 > 56.76 > 57.66
173 > 57.09 > 57.99
Note that, further down the line of iterations, 56.1 is 170 iterations of .33 (56.1 / .33 = 170), therefore its logical ending is .99, because it is the last in the series of 3 (170 % 3 = 2).
Here is a fiddle that summarises the iteration logic.
var increment = 1/3;
var start = 0;
while(true) {
start += increment;
alert(start);
}
Unless you need amazing precision into thousands of iterations the above code should solve your problem.
Otherwise I suggest to use integers for exact precision.
var increment = 1;
var start = 0;
while(true) {
start += increment;
alert(start/3);
}
I think this will be a okay
function CreateSeries()
{
for(int i=0;i<4;i++)
{
document.write(i + .33);
document.write(i + .66);
document.write(i + .99);
}
}
Perhaps I did not explain the logical iterations particularly well in my initial question, but I have found that the simplest way to normalise the numbers in the desired way is to use the following:
function normalise(input){
var output = ( Math.floor((input / .33) / 3)) + ((((input / .33) % 3) + 1) * .33 );
return Number(output.toFixed(2));
}
This has the desired results:
iteration : output
0 : 0.33
1 : 0.66
2 : 0.99
3 : 1.33
4 : 1.66
5 : 1.99
6 : 2.33
7 : 2.66
8 : 2.99
9 : 3.33
10 : 3.66
...
100 : 33.66
101 : 33.99
102 : 34.33
103 : 34.66
104 : 34.99
105 : 35.32
...
165 : 55.33
166 : 55.66
167 : 55.99
168 : 56.33
169 : 56.66
170 : 56.99
An example of the method in action.

Categories