Let N be the 1 5 0 0 -digit string of decimal digits linked here .
Consider all substrings of N with length strictly greater than 1 . Let P be the number of these substrings that are palindromes (read the same forwards and backwards), and let L be the largest palindromic substring (converted to an integer). Compute the remainder when P + L is divided by 1 0 0 0 .
EDIT: The number is:
845339512654353013973726529001291079167398839841139949030851696390946980101698124639149591440119733604468880607555560607206064491347909369911515301019367711551352591990261320383329288164577799740443242050242319267457621744807851983932903020081029321152325175250685866007841518940360280269649423980138752509028919270696197406591840726262868909999601238346887569491166411930108771076009573412594100219771074212035289275491573364890832367256854827355325731308226389028814609823679403212837077171147035094962722853937529780881806452156815760851836710785281112178566572142070924792670573967021943625926183861042230278394450084283686782710687142035589512463860007382666540574865786548090984873591052303316826223089810233823833877818493413413377572125316440837829248059997597530413074225936022537356928726861032836482495816729317138037356704312711814039586229918016418907376961773423879993723686730471541871754763457516922397978666764180907493617108196535775671577122375548642715864362660363698285254692252450789495296857844775409285832067120397741225920809730915094640238325092213217491635025536097960140990339793121105117908393671593840606430927286507282838120710540761234699189422511628632095218354056738982111107254470000373451953905544838296347383706816543780729267523585541214385956448406268928721934984154648198940685892036868554606054558448653750977153318569536525693630516086917674823412432181461884413411201293004004992015882876179775802939973661220145456423636324708339384632070192417332964444202
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
The way you handled the problem is really admirable.
I used for loops based on the start and end. Good approach!
Just curious, what was your runtime? I brute-forced it as well and ended up with a horrible runtime of about 3 minutes. Was yours much better?
Log in to reply
2.105 seconds
Log in to reply
How do you find runtime?
Log in to reply
@Lokesh Sharma – import time and then time.clock() at the beginning. To find elapsed time at any point call time.clock() again, which will return the time since the first call to it.
Log in to reply
@Daniel Chiu – Thanks. It worked. Mine was 6.7 seconds.
Log in to reply
@Lokesh Sharma – On re-examining my code I found the problem and managed to get it down to about 110 ms. Nice work!
Log in to reply
@Carl Denton – Whoa! 3 minutes to 110 ms. Would you mind pasting your re-examined code here?
Log in to reply
@Lokesh Sharma – Sure. I did it in Java.
public class Palindrome
{
public static void main(String[] args)
{
long startTime = System.currentTimeMillis();
String input = args[0];
int count = 0;
String longest = "0";
for (int subLength = 2; subLength <=
input.length() ; subLength++)
for(int pos = 0; pos <= input.length() -
subLength; pos++)
{
if (isPalindrome(input.substring(
pos, pos + subLength)))
{
count++;
if(Long.parseLong(input.substring(pos, pos +
subLength)) > Long.parseLong(longest))
{
longest =
input.substring(pos, pos + subLength);
}
}
}
System.out.println("Count: " + count);
System.out.println("Longest: " + longest);
System.out.println("Remainder: " +
(Long.parseLong(longest) + count) % 1000);
long endTime =
System.currentTimeMillis();
long timeElapsed = endTime - startTime;
System.out.println("Runtime: " +
timeElapsed + " ms");
}
public static boolean isPalindrome(String s)
{
boolean palindrome = true;
for (int i = 0; i < s.length()/2; i++)
{
if (s.charAt(i) == s.charAt(s.length() -
1 - i))
continue;
else
{
palindrome = false;
break;
}
}
return palindrome;
}
}
Log in to reply
@Carl Denton – Sorry, it's a bit lengthy with the margins of the comments. The problem was that in the isPalindrome(String s) method, I had previously been simply adding to the new string character by character using a "+=" operator. With strings, this creates a whole new string object, so for each character of the string I had been simply creating an entirely new object, which takes a lot of time. I revised to the above code and the runtime went to down to about 110 ms. I knew creating strings took time, but I was surprised at just how much of a difference it made!
Log in to reply
@Carl Denton – Hi guys,
Why is no one preferring parallel processing? Instead of going for normal loop processing, palindromes of different lengths can be found in parallel. I actually used, Java's StringBuffer reverse, which itself is heavy and along with it, I loaded the program with an ArrayList for adding palindromes. Again iterated over the ArrayList to compute the final result. Worst possible way to solve it. But the thing is, mine took about 0.65 seconds the first time itself. Started 1499 threads. I am pretty sure this could even be reduced to very less, a well informed guess gives me about 150 ms, 100 to actually solve and 50 is the thread overhead. But, if the length of the string is increased, it'd overcome the thread overhead. Is there any particular reason that no one has used Threads or parallel processing?
+1 for compact & self explained code. took 7.108s on my computer.
This takes under 1 sec on my machine... haven't tested exactly how much :D
import sys
import csv
f=open("data.txt",'r')
reader=csv.reader(f)
b=f.readline()
P=0
longest=""
startLongest=0
endLongest=0
longestLength=0
def checkLength(j,k,tempLength):
global longest,startLongest,endLongest,longestLength
if tempLength>longestLength:
startLongest=j
endLongest=k
longest=b[j:k+1]
longestLength=tempLength
def check1(b):
global P
for i in range (1,1499):
j=i-1
k=i+1
tempLength=1
while j>=0 and k<=1499:
if b[j]==b[k]:
tempLength=tempLength+2
checkLength(j,k,tempLength)
P=P+1
j=j-1
k=k+1
else:
break
def check2(b):
global P
for i in range (0,1500):
j=i
k=i+1
tempLength=0
while j>=0 and k<=1499:
if b[j]==b[k]:
tempLength=tempLength+2
checkLength(j,k,tempLength)
P=P+1
j=j-1
k=k+1
else:
break
check1(b)
check2(b)
print P+int(longest)%1000
Lucky you, the longest palindrome is also the largest because there is only the longest palindrome!
Log in to reply
I convert to an integer, so that shouldn't be a problem, right?
First, we must define a Python function to check whether a number is a palindrome. We need to recognize that for a given string n u m , if it's a palindrome with an even number of digits, n u m [ : ( l e n ( n u m ) / / 2 ) ] must be the same as n u m [ ( l e n ( n u m ) / / 2 ) : ] [ : : − 1 ] , i.e. the first half of the string is the same as the second half reversed. We also recognize that for a palindrome with an odd number of digits, we apply the same logic but simply ignore the middle digit, i.e. replace the second expression with n u m [ ( l e n ( n u m ) / / 2 + 1 ) : ] [ : : − 1 ] (the syntax ::-1 means to reverse the string). Note that since any multiple of two mod two is zero and any odd number mod two is one, we end up with this definition:
def isPalindrome(num):
return [(len(num) // 2 + len(num) % 2):][::-1]
Next, we take our string, string , and split it into substrings, using Python's concise generator syntax to find a start and end and then slice the string:
substrs = [string[start:end] for start in range(0, len(string) - 2) for end in range(start + 2, len(string) + 1)]
Finally, we write a loop to find P and L, initializing them both to zero:
for substr in substrs:
if isPalindrome(substr):
P += 1
if int(substr) > L:
L = int(substr)
We top it off by printing the value P + L , mod 1000.
Forgot to mention, it takes 9 seconds to run on my system.
My Python solution
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Python solution:
#Creating the palindrome function
def is_palindrome(s):
return s == s[::-1]
#Opening the file and storing characters into a variable
f = open('Number_Palindromes.txt', 'r')
chars = [line for line in f][0]
#Defining variables for the loop
total = 0
largest = 0
#Loop through the starting index and substring length
for i in range(len(chars)):
for substr_len in range(2, len(chars) - i + 1):
#Calls palindrome function
s = chars[i:i + substr_len]
if is_palindrome(s):
total += 1
#Checks to see if it is the largest palindrome
if int(s) > largest:
largest = int(s)
#Print the answer and close the file
print (largest + total) % 1000
f.close()
My solution it takes around 2 secs on my computer
string="845339512654353013973726529001291079167398839841139949030851696390946980101698124639149591440119733604468880607555560607206064491347909369911515301019367711551352591990261320383329288164577799740443242050242319267457621744807851983932903020081029321152325175250685866007841518940360280269649423980138752509028919270696197406591840726262868909999601238346887569491166411930108771076009573412594100219771074212035289275491573364890832367256854827355325731308226389028814609823679403212837077171147035094962722853937529780881806452156815760851836710785281112178566572142070924792670573967021943625926183861042230278394450084283686782710687142035589512463860007382666540574865786548090984873591052303316826223089810233823833877818493413413377572125316440837829248059997597530413074225936022537356928726861032836482495816729317138037356704312711814039586229918016418907376961773423879993723686730471541871754763457516922397978666764180907493617108196535775671577122375548642715864362660363698285254692252450789495296857844775409285832067120397741225920809730915094640238325092213217491635025536097960140990339793121105117908393671593840606430927286507282838120710540761234699189422511628632095218354056738982111107254470000373451953905544838296347383706816543780729267523585541214385956448406268928721934984154648198940685892036868554606054558448653750977153318569536525693630516086917674823412432181461884413411201293004004992015882876179775802939973661220145456423636324708339384632070192417332964444202"
ln = len(string) - 1 N = 0 Lstart = 0 Ldistance = 0 for i in range(ln): #search for a end end = ln while end > i : if string[i] == string[end]: #Got an end #To check if it is symetric ni = i ne = end while ni < ne: if string[ni] != string[ne]: break ni += 1 ne -= 1 if ne <= ni: #Got a symetric N += 1 distance = end - i + 1 if distance > Ldistance: Ldistance = distance Lstart = i end -= 1 s = int(string[Lstart:Lstart + Ldistance]) + N print( s % 1000 )
My solution uses Hash algorithm and runtime is less than 0.1s. The input string can be written as s 1 s 2 . . . s i . . . s j . . . s n .
Let's consider substring X = s i . . . s j . X will be a palindrome if value of X is equal to value of reverse string of X (both in decimal).
Hash value of forward string X is defined as: H 1 = ( s i . 1 0 i + s i + 1 . 1 0 i + 1 + . . . + s j . 1 0 j ) % B A S E
and Hash value of reverse string of X is H 2 = ( s j . 1 0 n − j + 1 + s i + 1 . 1 0 n − j + 2 + . . . + s i . 1 0 n − i + 1 ) % B A S E
where B A S E is a big prime number, for example 1 0 0 0 0 0 0 0 0 9 .
We can conclude that X = = r e v e r v e ( X ) if H 1 . 1 0 n − i = = H 2 . 1 0 j − 1 . The probability that above condition becomes wrong is too small, because B A S E is a big prime number.
The complexity of calculating Hash value for each substring X can be O ( 1 ) by using three arrays in preprocessing step: P[i] is the power of 1 0 , a[i] is the Hash value of substring s 1 . . . s i and b[i] is the Hash value (in reverse) of substring s [ i ] . . . s [ n ] .
Here is my code in short (sorry because I don't know how to insert code in the post):
n = length of(s);
ans = 0;
FOR(i,1,n) FOR(j,i+1,n) {
sum1 = (a[j]-a[i-1]+MOD)*POW[n-i]; sum1 %= MOD;
sum2 = (b[i]-b[j+1]+MOD)*POW[j-1]; sum2 %= MOD;
if(sum1 == sum2) {
string tmp = "";
FOR(k,i,j) tmp += s[k];
cout << tmp << endl; /// it's too easy to find the longest palindrome
ans++;
}
} cout << ans << endl;
Simple brute force solution...
with open("big_number.txt") as problem:
number = problem.read()
palindromes = []
i = 0
for digit in number:
candidate = digit
for c in number[i+1:]:
candidate += c
if candidate == candidate[::-1]:
palindromes.append(int(candidate))
i+=1
print((max(palindromes)+len(palindromes))%1000)
import java.util.Stack;
public class NumericalPalindromes {
public static void main(String[] args) {
// TODO Auto-generated method stub
String bigStr = "845339512654353013973726529001291079167398839841139949030851696390946980101698124639149591440119733604468880607555560607206064491347909369911515301019367711551352591990261320383329288164577799740443242050242319267457621744807851983932903020081029321152325175250685866007841518940360280269649423980138752509028919270696197406591840726262868909999601238346887569491166411930108771076009573412594100219771074212035289275491573364890832367256854827355325731308226389028814609823679403212837077171147035094962722853937529780881806452156815760851836710785281112178566572142070924792670573967021943625926183861042230278394450084283686782710687142035589512463860007382666540574865786548090984873591052303316826223089810233823833877818493413413377572125316440837829248059997597530413074225936022537356928726861032836482495816729317138037356704312711814039586229918016418907376961773423879993723686730471541871754763457516922397978666764180907493617108196535775671577122375548642715864362660363698285254692252450789495296857844775409285832067120397741225920809730915094640238325092213217491635025536097960140990339793121105117908393671593840606430927286507282838120710540761234699189422511628632095218354056738982111107254470000373451953905544838296347383706816543780729267523585541214385956448406268928721934984154648198940685892036868554606054558448653750977153318569536525693630516086917674823412432181461884413411201293004004992015882876179775802939973661220145456423636324708339384632070192417332964444202";
Stack<Character> stack = new Stack<Character>();
int count = 0, maxLength = 0;
for(int i=0;i<bigStr.length();i++) {
Character c = Character.valueOf(bigStr.charAt(i));
Character c1 = null;
if(i!=bigStr.length()-1)
c1 = Character.valueOf(bigStr.charAt(i+1));
boolean isEven = false;
boolean isOdd = false;
if(!stack.isEmpty() && stack.peek().charValue() == c.charValue()) {
isEven = true;
}
if(!stack.isEmpty() && c1!=null && c1.charValue() == stack.peek().charValue()) {
isOdd = true;
}
if(isEven) {
count ++;
Stack<Character> tmpStack = new Stack<Character>();
int j = i+1;
int length = 2;
while(true) {
tmpStack.push(stack.pop());
if(j>=bigStr.length()) break;
if(stack.isEmpty()) break;
if(bigStr.charAt(j) != stack.peek().charValue())
break;
length += 2;
count ++;
j++;
}
while(!tmpStack.isEmpty()) {
stack.push(tmpStack.pop());
}
if (length > maxLength) {
int beginIndex = i - (j-1-i);
beginIndex--;
String palindromeString = bigStr.substring(beginIndex, j);
System.out.println(palindromeString);
maxLength = length;
}
}
if(isOdd) {
count ++;
Stack<Character> tmpStack = new Stack<Character>();
int j = i+2;
int length = 3;
while(true) {
tmpStack.push(stack.pop());
if(j>=bigStr.length()) break;
if(stack.isEmpty()) break;
if(bigStr.charAt(j) != stack.peek().charValue())
break;
length += 2;
count ++;
j++;
}
while(!tmpStack.isEmpty()) {
stack.push(tmpStack.pop());
}
if (length > maxLength) {
maxLength = length;
int beginIndex = i - (j-1-i);
String palindromeString = bigStr.substring(beginIndex, j);
System.out.println(palindromeString);
}
}
stack.push(Character.valueOf(bigStr.charAt(i)));
}
System.out.println("Count: " + count);
}
}
I'm just starting to learn Python, so forgive me for any beginner mistakes I might have made. Constructive criticism or suggestions are welcome.
list=[]
num='whatever the number is, paste it here'
for startpoint in range(0,1499):
for endpoint in range(startpoint+1, 1500):
sub=num[startpoint:endpoint+1]
reverse=sub[::-1]
if(sub==reverse):
list.append(int(sub))
print(max(list)+len(list))
The output is 3 2 4 2 0 5 0 2 7 5 5 .
Python Sol:
s = open('Number_Palindromes.txt', 'r')
s = s.read()
def isPalindrome(num):
if num == num[::-1]:
return True
return False
def Pal(l):
pals = []
for i in range(len(s) - (l - 1)):
if isPalindrome(s[i: i + l]):
pals.append(s[i: i + l])
return pals
bestLen = 0
for leng in range(2, 1501):
if len(Pal(leng)) > 0:
bestLen = leng
print Pal(bestLen) # This is P
allPals = []
for leng in range(2, 100):
for i in Pal(leng):
allPals.append(i)
print len(allPals) # This is L
guys can y tell wats wrong in dis code ?? :)
int max;
int pallcheck(char a[2000]){
int i=0,j;
while (a[i]>0) {
i++;
}
j=--i;
while (j) {
if (a[i-j]!=a[j]) {
return 0;
}
j--;
}
if (atoi(a)>max) {
max=atoi(a);
}
if (atoi(a)){ return 1;}
else return 0;
}
int main(){
int i,j,k=0,c=0,flag;
char a[2000]={"845339512654353013973726529001291079167398839841139949030851696390946980101698124639149591440119733604468880607555560607206064491347909369911515301019367711551352591990261320383329288164577799740443242050242319267457621744807851983932903020081029321152325175250685866007841518940360280269649423980138752509028919270696197406591840726262868909999601238346887569491166411930108771076009573412594100219771074212035289275491573364890832367256854827355325731308226389028814609823679403212837077171147035094962722853937529780881806452156815760851836710785281112178566572142070924792670573967021943625926183861042230278394450084283686782710687142035589512463860007382666540574865786548090984873591052303316826223089810233823833877818493413413377572125316440837829248059997597530413074225936022537356928726861032836482495816729317138037356704312711814039586229918016418907376961773423879993723686730471541871754763457516922397978666764180907493617108196535775671577122375548642715864362660363698285254692252450789495296857844775409285832067120397741225920809730915094640238325092213217491635025536097960140990339793121105117908393671593840606430927286507282838120710540761234699189422511628632095218354056738982111107254470000373451953905544838296347383706816543780729267523585541214385956448406268928721934984154648198940685892036868554606054558448653750977153318569536525693630516086917674823412432181461884413411201293004004992015882876179775802939973661220145456423636324708339384632070192417332964444202"};
char temp;
while (a[k]>0) {
k++;
}
printf(" k=%d\n ",k);
for (i=0; i<k-1; i++) {
for (j=i+1; j<k; j++) {
flag=1;
if (a[i]==a[j]&&a[i]!='0') {
temp=a[j+1];
a[j+1]=0;
if (pallcheck(&a[i])) {
c++;
}
a[j+1]=temp;
}
}
}
printf(" \nc=%d max=%d\n ",c,max);
printf("%d",((c+max)%1000));
}
Log in to reply
got it
code is corrcet should have taken double but took int :P
Problem Loading...
Note Loading...
Set Loading...
I used a brute-force strategy. I loop over all possible values of the index of the first digit of a substring, and then over all possible values of the length of the substring to grab all possible substrings. Then, I check whether each substring is a palindrome, and whether the integer value is larger than the current largest. Finally, I print P and L to check, along with the desired P + L .
Python:
This prints out 3 3 2 3 2 4 2 0 5 0 2 4 2 3 3 2 4 2 0 5 0 2 7 5 5 .