#WEEKLY Challenge #2 Submission
h
MrEconomical (2199)

easy

golf?

In my old solution, I tried to balance efficiency as well as golfing which I quickly realized was not a good idea, which is why I have created a new golfed solution using ESMIN which focuses only on golfing and not efficiency (77 characters). You can run this golfed solution here: bennyboy.tech/ESMin/interpreter3.html?eval=true&input=20&code=A%3D0%3BR%3D1%2B%E2%A9%A4%E2%81%BD%C3%AF%E2%93%A1%24%2B(_%C3%9F)%EA%9D%88%3B%E2%A9%A4(2*R)%E2%93%9C%7BD%3D%C9%B1.abs(R-%24)%2CA%3D!A%E2%8B%8E(%24%E2%89%94(%24%C3%9F)%E1%B4%99)%E2%85%8BD%3CA%5B0%5D)%3F%5BD%2C%24%5D%3AA%7D%3BA%5B1%5D (Markdown is weird just copy paste the entire link)

Description of OLD SOLUTION

All jokes aside, this was a very interesting weekly challenge and I am pretty proud of how my solution works, in addition to it being golfed and completely unintelligable.

We can break this problem down into two parts: adding up the number of digits and then finding the closest palindrome to that number.

The first part of the problem is easy; you can simply group the numbers from 0 to n by # digits, such as those that have 1 digit, those that have 2 digits, and then add them all up. You can do this by iterating from 0 to the floor of the log base 10 of the number and then multiplying the corresponding number 10 ** i + 1, i.e. 10 one digit numbers (0 - 9), 91 two digit numbers (10 - 99) and so on. Then, we need to add the "extra" bit we got rid of when taking the floor of the log. This is simple, just take the number of digits and multiply by the numbers between the last power of 10 and n: (n - 10 ** i) * (i + 1).

The code that performs part 1 of the problem:

L=Math;a=r=0;n=L.abs(+prompt());d=0|L.log10(n);for(o=0;o<d;o++)r+=9*10**o+1;r+=(n-10**o+1)*(o+1)

The second part of the problem is also rather simple. Once we have the sum of digits, we can generate the closest palindrome. Consider the number abcde. We can generate a palindrome by repeating half of the number, such as abcba or edcde. It is always much better to repeat the first half of the number for generating a palindrome close to our number as we do not overwrite the larger front digits. However, we must also check the cases in which there are zeroes in the number or a 9 in the middle. For example, consider the number 10999: here, the best course of action is not repeating the front to produce 10901 but rather 11011. In order to account for these cases, we can simply increment and decrement the middle digit by 1 if 9 or 0 and handle the carry operations as needed.

Code for finding closest palindrome:

s=r.toString();l=s.length;f=+s.slice(0,0|l/2);m=l%2?s.slice(0|l/2,0|l/2+1):"";c=s=>s.split("").reverse().join("");[""+f+m+c(""+f),+m==9?""+(f+1)+0+c(""+(f+1)):0,+m==0?""+(f-1)+9+c(""+(f-1)):0].forEach(p=>{x=L.abs(r-+p);a=x<a[0]||!a?[x,+p]:a})

For negative numbers as an input, all you need to do is take the absolute value as the problem is symmetric on both sides of 0.

You are viewing a single comment. View All
AmazingMech2418 (692)

Nice job! Yours actually seems to work quite a bit like mine, just yours is 357 characters while mine is 500...

AmazingMech2418 (692)

Update: Mine is now 357 characters as well...