Skip to content

Instantly share code, notes, and snippets.

@brhoades
Last active August 29, 2015 14:25
Show Gist options
  • Save brhoades/68a3903947c5f6b77e29 to your computer and use it in GitHub Desktop.
Save brhoades/68a3903947c5f6b77e29 to your computer and use it in GitHub Desktop.
Find longest palindrome substring, Microsoft Coding Competition 2014 https://github.com/Tomdarling/Microsoft-Competition/tree/master/bin/palindromePhrases
require 'awesome_print'
matchstr = /[[:punct:]]|[[:space:]]|[^[:ascii:]]/
class String
def palindrome?
self == self.reverse
end
end
class Array
# This returns all combinations of each slice. each_slice normally returns:
# ["A","B","C","D"] => ["A","B"], ["C","D"]
# but here:
# ["A","B","C","D"] => ["A","B"], ["B",C"], ["C","D"]
def each_slice_exhaustive( size )
Enumerator.new do |enum|
last = []
if size == self.size
enum.yield self.join('')
end
self.each do |c|
if last.size < size
last << c
next
end
last << c
enum.yield last.join('') #eh, speeds things up to do it now, also fixes shallow copy problems
last.shift
end
end
end
end
def arrayFind( contents )
contents.each do |l|
print "\nString #", contents.index(l) + 1, ":\n"
found = false
l.size.downto(2) do |i|
break if found
if i != l.size
print "\b"*6
end
print (100-(i.to_f/l.size*100)).round(1), "%"
l.chars.each_slice_exhaustive(i).each do |slice|
if slice.palindrome?
$palindromes << slice
found = true
break
end
end
end
end
end
def sliceFind( contents )
contents.each do |l|
found = false
l.size.downto(2) do |i|
break if found
# create string slices of size i from index j
0.upto(l.size-i) do |j|
w = l.slice(j,i)
if w.palindrome?
found = true
$palindromes << w
break
end
end
end
end
end
contents = []
original = []
File.open(ARGV[0], 'r') do |f|
f.each_line do |line|
contents << line.gsub( matchstr, '' ).downcase
original << line
end
end
$palindromes = []
if ARGV[1] == "array"
print "Array find: \n"
arrayFind( contents )
else
print "Slice find: \n"
sliceFind( contents )
end
$palindromes.map { |p| print p, "\n" }
print "\n"
# Now relate our palindrome to the source text
$palindromes.each do |p|
match = []
palini = 0
# go through source string until, ignoring removed characters, we find our palindrome
# where the longest is aabaa
original[$palindromes.index p].chars.each do |o|
if o =~ matchstr
match << o if palini > 0
next
end
if p[palini] == o.downcase
matching = true
palini += 1
match << o
else
matching = false
match = []
palini = 0
end
if palini == p.length
print match.join(''), "\n"
break
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment