Which Lua function is better to use? - performance

I took two ways to round numbers to decimals. First function just rounds the number:
function round(num)
local under = math.floor(num)
local over = math.floor(num) + 1
local underV = -(under - num)
local overV = over - num
if overV > underV then
return under
else
return over
end
end
The next two functions use this function to round a number to decimals:
function roundf(num, dec)
return round(num * (1 * dec)) / (1 * dec)
end
function roundf_alt(num, dec)
local r = math.exp(1 * math.log(dec));
return round(r * num) / r;
end

Why not simply
function round(num)
return num >= 0 and math.floor(num+0.5) or math.ceil(num-0.5)
end
Instead of math.floor(num) + 1 you can simply use math.ceil(num) btw.
Why do you multiply with 1 multiple times?
There are many things to consider when rounding numbers. Please do some research on how to handle special cases.

Related

using while loop the page keep loading over and over (codewars problem)

heyy guys i m trying to solve Factorial decomposition (codewars task )
well some numbers work with me untill i reach number 23 the page keep looping over and over someone help me please
function decomp(n) {
let c =[]
let sum =1
for(let i=n;i>=1;i--){
sum*=i
}
let k= 2
while(k<=sum){
if(sum%k!==0){
k++}
while(sum%k==0){
c.push(k)
sum = sum/k
}
}
return c.join('*')
}
the function works good until i reach the number 23 the keep loading over and over , the tasks is about the function is decomp(n) and should return the decomposition of n! into its prime factors in increasing order of the primes, as a string.
factorial can be a very big number (4000! has 12674 digits, n can go from 300 to 4000).
In Fortran - as in any other language - the returned string is not permitted to contain any redundant trailing whitespace: you can use dynamically allocated character strings.
example
n = 12; decomp(12) -> "2^10 * 3^5 * 5^2 * 7 * 11"
since 12! is divisible by 2 ten times, by 3 five times, by 5 two times and by 7 and 11 only once.
n = 22; decomp(22) -> "2^19 * 3^9 * 5^4 * 7^3 * 11^2 * 13 * 17 * 19"
n = 25; decomp(25) -> 2^22 * 3^10 * 5^6 * 7^3 * 11^2 * 13 * 17 * 19 * 23
23! cannot be exactly expressed in double-precision floating-point format, which JavaScript uses for its numbers.
However, you don't need to compute n!. You just need to factorize each number and concat their factorization.
Actually, you don't even need to factorize each number. Note that given n and p, there are (n/p) numbers no greater than n that are multiples of p, (n/(p*p)) that are multiples of p*p, etc.
function *primes(n) {
// Sieve of Eratosthenes
const isPrime = Array(n + 1).fill(true);
isPrime[0] = isPrime[1] = false;
for (let i = 2; i <= n; i++) {
if (isPrime[i]) {
yield i;
for (let j = i * i; j <= n; j += i)
isPrime[j] = false;
}
}
}
function decomp(n) {
let s = n + '! =';
for (const p of primes(n)) {
let m = n, c = 0;
// There are (n/p) numbers no greater than n that are multiples of p
// There are (n/(p*p)) numbers no greater than n that are multiples of p*p
// ...
while (m = ((m / p) | 0)) {
c += m;
}
s += (p == 2 ? ' ' : ' * ') + p + (c == 1 ? '' : '^' + c);
}
return s;
}
console.log(decomp(12))
console.log(decomp(22))
console.log(decomp(23))
console.log(decomp(24))
console.log(decomp(25))

Perform index-wise matrix operation in julia

I want to perform index-wise operation on a matrix. I know that you can write a regular function and perform it on each entry of the matrix e.g.
function foo(x::Int64)
return x * 2
end
myArray = [1 2 3; 4 5 6]
foo.(myArray)
how would I go about doing something like x * x.elementCol + x.elementrow? essentially the following code in parallel:
function goo(x::Array{Int64,2})
for j = 1:size(x,2)
for i = 1:size(x,1)
x[i,j] = (x[i,j] * j) + i
end
end
return x
end
You can write:
x .= x .* indices(x, 2)' .+ indices(x, 1)

Does d3.js have reverse ease functions?

With d3.js we can achieve eased time out of normalized time t, typically in the range [0,1]
For example:
d3.easeCubic(0.25) = 0.0625
How can we reverse that, how can we find x given known y ?
d3.easeCubic(X) = 0.0625,
X ???
The answer here is cubic root, but still.
The problem is in reusability, ease function can change to d3.easeExpIn, or `d3.easeCircleOut, or any other, do you need to invent reverse functions on your own, or are they hidden anywhere ?
Firstly, your math is wrong. d3.easeCubic(0.25) will give you 0.0625:
var easy = d3.easeCubic(0.25);
console.log(easy);
<script src="https://d3js.org/d3.v4.min.js"></script>
Now, back to your question:
How can we reverse that, how can we find x given known y?
There is no native solution, but we can create our own function to find X given a known Y. The problem, of course, is that we have to invert the math for each specific easing... But, since you asked about d3.easeCubic, which is the same of d3.easeCubicInOut, let's try to create an inverted function for that particular easing.
First step, let's have a look at the source code:
export function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
You can easily see that this is the correct function, giving us the same value as the first snippet:
function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
console.log(cubicInOut(0.25))
Now, let's try to invert it.
The math here is somehow complicated, but for values less than 1, here is the function:
function inverseEaseCubic(t){
return Math.cbrt(t * 2) / 2;
}
And here is the demo. We pass 0.0625 to the function, and it returns 0.25:
function inverseEaseCubic(t){
return Math.cbrt(t * 2) / 2;
}
console.log(inverseEaseCubic(0.0625))
If you want to deal with numbers bigger than 1, this is the complete function:
function InverseEaseCubic(t){
return t <= 1 ? Math.cbrt(t * 2) / 2 : (Math.cbrt(2 * t - 2) + 2) / 2;
}
PS: In his comment, #altocumulus just reminded us that, sometimes, it's even impossible to find the value. Here is a very simple example. Suppose this function:
function exponentiation(a){
return a*a;
}
Now imagine that, when called with an unknown argument, the function returned 4. What's the argument? Can we find out? Impossible to determine, because second degree equations, like this one, have 2 roots:
console.log(exponentiation(2))//returns 4
console.log(exponentiation(-2))//also returns 4
I used the #Gerardo Furtado answer but the inverse function didn't work well so I wrote another
function cubicInOut(t) {
return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
}
function inverseEaseCubic(x) {
return x < .5 ? Math.cbrt(x / 4) : (2 - Math.cbrt(2 - 2 * x)) / 2;
}
console.log(inverseEaseCubic(cubicInOut(1)) === 1);
console.log(inverseEaseCubic(cubicInOut(0.6)) === 0.6);
console.log(inverseEaseCubic(cubicInOut(0.4)) === 0.4);
console.log(inverseEaseCubic(cubicInOut(0.1)) === 0.1);
console.log(inverseEaseCubic(cubicInOut(0)) === 0);

Exponentiation program

I am trying to do a fast exponentiation. But the result does not seem to produce the correct result. Any help would be appreciated.
EDIT: Manage to solve it thanks for all the help.
if (content[i] == '1')
s1 = (int)(po1 * (Math.pow(po1, 2)));
else
s1 = po1 * po1;
final_result *= temp;
Check out this Exponation by squaring
You probably want to bit-shift right and square your base each time you encounter a 1 bit in the exponent
int pow(int base, int e)
{
int retVal = 1;
while (e)
{
if (e % 2 == 1)//i.e. last bit of exponent is 1
retVal *= base;
e >>= 1; //bitshift exponent to the right.
base *= base; // square base since we shifted 1 bit in our exponent
}
return retVal ;
}
A good way of thinking about it is that your exponent is being broken down: say, 6^7 (exponent in bits is 1, 1, 1) = 6^1 * 6^2 * 6^4 = 6 * 36 * 36^2 = 6 * 36 * 1296. Your base is always squaring itself.
temp = (int)(g1 * (Math.pow(g1, 2)));
This basically just boils down to g13. I'm not familiar with this algorithm but this can't be right.
Also, as a side note, don't ever call Math.pow(<var>, 2), just write <var> * <var>.
There are several problems with your code, starting with the fact that you are reading the exp string in the wrong direction, adding extra multiplications by the base, and not considering the rank of the 1 when raising the powers of 2.
Here is a python quick sketch of what you are trying to achieve:
a = int(raw_input("base"))
b = "{0:b}".format(int(raw_input("exp")))
res = 1
for index, i in enumerate(b[::-1]):
if i == '1':
res *= a**(2**index)
print res
Alternatively, you could square a at every iteration instead:
for index, i in enumerate(b[::-1]):
if i == '1':
res *= a
a *= a

How do I find the Excel column name that corresponds to a given integer? [duplicate]

This question already has answers here:
How to convert a column number (e.g. 127) into an Excel column (e.g. AA)
(60 answers)
Closed 9 years ago.
How would you determine the column name (e.g. "AQ" or "BH") of the nth column in Excel?
Edit: A language-agnostic algorithm to determine this is the main goal here.
I once wrote this function to perform that exact task:
public static string Column(int column)
{
column--;
if (column >= 0 && column < 26)
return ((char)('A' + column)).ToString();
else if (column > 25)
return Column(column / 26) + Column(column % 26 + 1);
else
throw new Exception("Invalid Column #" + (column + 1).ToString());
}
Here is the cleanest correct solution I could come up with (in Java, but feel free to use your favorite language):
String getNthColumnName(int n) {
String name = "";
while (n > 0) {
n--;
name = (char)('A' + n%26) + name;
n /= 26;
}
return name;
}
But please do let me know of if you find a mistake in this code, thank you.
A language agnostic algorithm would be as follows:
function getNthColumnName(int n) {
let curPower = 1
while curPower < n {
set curPower = curPower * 26
}
let result = ""
while n > 0 {
let temp = n / curPower
let result = result + char(temp)
set n = n - (curPower * temp)
set curPower = curPower / 26
}
return result
This algorithm also takes into account if Excel gets upgraded again to handle more than 16k columns. If you really wanted to go overboard, you could pass in an additional value and replace the instances of 26 with another number to accomodate alternate alphabets
Thanks, Joseph Sturtevant! Your code works perfectly - I needed it in vbscript, so figured I'd share my version:
Function ColumnLetter(ByVal intColumnNumber)
Dim sResult
intColumnNumber = intColumnNumber - 1
If (intColumnNumber >= 0 And intColumnNumber < 26) Then
sResult = Chr(65 + intColumnNumber)
ElseIf (intColumnNumber >= 26) Then
sResult = ColumnLetter(CLng(intColumnNumber \ 26)) _
& ColumnLetter(CLng(intColumnNumber Mod 26 + 1))
Else
err.Raise 8, "Column()", "Invalid Column #" & CStr(intColumnNumber + 1)
End If
ColumnLetter = sResult
End Function
Joseph's code is good but, if you don't want or need to use a VBA function, try this.
Assuming that the value of n is in cell A2
Use this function:
=MID(ADDRESS(1,A2),2,LEN(ADDRESS(1,A2))-3)
IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
This works 2 letter columns (up until column ZZ). You'd have to nest another if statement for 3 letter columns.
The formula above fails on columns AY, AZ and each of the following nY and nZ columns. The corrected formula is:
=IF(COLUMN()>26,CHAR(ROUNDDOWN((COLUMN()-1)/26,0)+64)&CHAR(MOD((COLUMN()-1),26)+65),CHAR(COLUMN()+64)
Ruby one-liner:
def column_name_for(some_int)
some_int.to_s(26).split('').map {|c| (c.to_i(26) + 64).chr }.join # 703 => "AAA"
end
It converts the integer to base26 then splits it and does some math to convert each character from ascii. Finally joins 'em all back together. No division, modulus, or recursion.
Fun.
FROM wcm:
If you don't want to use VBA, you can use this
replace colnr with the number you want
=MID(ADDRESS(1,colnr),2,LEN(ADDRESS(1,colnr))-3)
Please be aware of the fact that this formula is volatile because of the usage of the ADDRESS function. Volatile functions are functions that are recalculated by excel after EVERY change.
Normally excel recalculates formula's only when their dependent references changes.
It could be a performance killer, to use this formula.
And here is a conversion from the VBScript version to SQL Server 2000+.
CREATE FUNCTION [dbo].[GetExcelColRef]
(
#col_seq_no int
)
RETURNS varchar(5)
AS
BEGIN
declare #Result varchar(5)
set #Result = ''
set #col_seq_no = #col_seq_no - 1
If (#col_seq_no >= 0 And #col_seq_no < 26)
BEGIN
set #Result = char(65 + #col_seq_no)
END
ELSE
BEGIN
set #Result = [dbo].[GetExcelColRef] (#col_seq_no / 26) + '' + [dbo].[GetExcelColRef] ((#col_seq_no % 26) + 1)
END
Return #Result
END
GO
This works fine in MS Excel 2003-2010. Should work for previous versions supporting the Cells(...).Address function:
For the 28th column - taking columnNumber=28; Cells(1, columnNumber).Address returns "$AB$1".
Doing a split on the $ sign returns the array: ["","AB","1"]
So Split(Cells(1, columnNumber).Address, "$")(1) gives you the column name "AB".
UPDATE:
Taken from How to convert Excel column numbers into alphabetical characters
' The following VBA function is just one way to convert column number
' values into their equivalent alphabetical characters:
Function ConvertToLetter(iCol As Integer) As String
Dim iAlpha As Integer
Dim iRemainder As Integer
iAlpha = Int(iCol / 27)
iRemainder = iCol - (iAlpha * 26)
If iAlpha > 0 Then
ConvertToLetter = Chr(iAlpha + 64)
End If
If iRemainder > 0 Then
ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64)
End If
End Function
APPLIES TO: Microsoft Office Excel 2007 SE / 2002 SE / 2000 SE / 97 SE
I suppose you need VBA code:
Public Function GetColumnAddress(nCol As Integer) As String
Dim r As Range
Set r = Range("A1").Columns(nCol)
GetColumnAddress = r.Address
End Function
This does what you want in VBA
Function GetNthExcelColName(n As Integer) As String
Dim s As String
s = Cells(1, n).Address
GetNthExcelColName = Mid(s, 2, InStr(2, s, "$") - 2)
End Function
This seems to work in vb.net
Public Function Column(ByVal pColumn As Integer) As String
pColumn -= 1
If pColumn >= 0 AndAlso pColumn < 26 Then
Return ChrW(Asc("A"c) + pColumn).ToString
ElseIf (pColumn > 25) Then
Return Column(CInt(math.Floor(pColumn / 26))) + Column((pColumn Mod 26) + 1)
Else
stop
Throw New ArgumentException("Invalid column #" + (pColumn + 1).ToString)
End If
End Function
I took Joseph's and tested it to BH, then fed it 980-1000 and it looked good.
In VBA, assuming lCol is the column number:
function ColNum2Letter(lCol as long) as string
ColNum2Letter = Split(Cells(1, lCol).Address, "$")(0)
end function
All these code samples that these good people have posted look fine.
There is one thing to be aware of. Starting with Office 2007, Excel actually has up to 16,384 columns. That translates to XFD (the old max of 256 colums was IV). You will have to modify these methods somewhat to make them work for three characters.
Shouldn't be that hard...
Here's Gary Waters solution
Function ConvertNumberToColumnLetter2(ByVal colNum As Long) As String
Dim i As Long, x As Long
For i = 6 To 0 Step -1
x = (1 - 26 ^ (i + 1)) / (-25) - 1 ‘ Geometric Series formula
If colNum > x Then
ConvertNumberToColumnLetter2 = ConvertNumberToColumnLetter2 & Chr(((colNum - x - 1)\ 26 ^ i) Mod 26 + 65)
End If
Next i
End Function
via http://www.dailydoseofexcel.com/archives/2004/05/21/column-numbers-to-letters/
Considering the comment of wcm (top value = xfd), you can calculate it like this;
function IntToExcel(n: Integer); string;
begin
Result := '';
for i := 2 down to 0 do
begin
if ((n div 26^i)) > 0) or (i = 0) then
Result := Result + Char(Ord('A')+(n div (26^i)) - IIF(i>0;1;0));
n := n mod (26^i);
end;
end;
There are 26 characters in the alphabet and we have a number system just like hex or binary, just with an unusual character set (A..Z), representing positionally the powers of 26: (26^2)(26^1)(26^0).
FYI T-SQL to give the Excel column name given an ordinal (zero-based), as a single statement.
Anything below 0 or above 16,383 (max columns in Excel2010) returns NULL.
; WITH TestData AS ( -- Major change points
SELECT -1 AS FieldOrdinal
UNION ALL
SELECT 0
UNION ALL
SELECT 25
UNION ALL
SELECT 26
UNION ALL
SELECT 701
UNION ALL
SELECT 702
UNION ALL
SELECT 703
UNION ALL
SELECT 16383
UNION ALL
SELECT 16384
)
SELECT
FieldOrdinal
, CASE
WHEN FieldOrdinal < 0 THEN NULL
WHEN FieldOrdinal < 26 THEN ''
WHEN FieldOrdinal < 702 THEN CHAR (65 + FieldOrdinal / 26 - 1)
WHEN FieldOrdinal < 16384 THEN CHAR (65 + FieldOrdinal / 676 - 1)
+ CHAR (65 + (FieldOrdinal / 26) - (FieldOrdinal / 676) * 26 - 1)
ELSE NULL
END
+ CHAR (65 + FieldOrdinal % 26)
FROM TestData
ORDER BY FieldOrdinal
I currently use this, but I have a feeling that it can be optimized.
private String GetNthExcelColName(int n)
{
String firstLetter = "";
//if number is under 26, it has a single letter name
// otherwise, it is 'A' for 27-52, 'B' for 53-78, etc
if(n > 26)
{
//the Converts to double and back to int are just so Floor() can be used
Double value = Convert.ToDouble((n-1) / 26);
int firstLetterVal = Convert.ToInt32(Math.Floor(value))-1;
firstLetter = Convert.ToChar(firstLetterValue + 65).ToString();
}
//second letter repeats
int secondLetterValue = (n-1) % 26;
String secondLetter = Convert.ToChar(secondLetterValue+65).ToString();
return firstLetter + secondLetter;
}
=CHAR(64+COLUMN())

Resources