Finding Palindromes

is there any way to have an applescript find all palindromes in a givin wordlist?

Try this (no garuntees it will work perfectly though)

set the listToCheck to {"these", "are", "some", "example", "palindromes", "ere", "able was I ere I saw Elba", " A nut for a jar of tuna"}
set palindromelist to {}

repeat with currentItem in the listToCheck
	set charCount to (count of the currentItem)
	set frontChar to 1
	set endChar to charCount
	repeat
		if (item frontChar of currentItem as text) is space then set frontChar to frontChar + 1
		if (item endChar of currentItem as text) is space then set endChar to endChar - 1
		set stillpalindrome to my checkword(currentItem, frontChar, endChar)
		if stillpalindrome and (frontChar is greater than charCount / 2) then
			copy currentItem as text to end of palindromelist
			exit repeat
		else if not stillpalindrome then
			exit repeat
		end if
		set frontChar to frontChar + 1
		set endChar to endChar - 1
	end repeat
end repeat
return palindromelist

on checkword(currentItem, frontChar, endChar)
	if (item frontChar of currentItem) is (item endChar of currentItem) then
		return true
	else
		return false
	end if
end checkword

Ben

Here’s an easier example, using AppleScript’s ability to reverse a list

set the listToCheck to {"these", "are", "some", "example", "palindromes", "ere", "able was I ere I saw Elba", " A nut for a jar of tuna"}
set palindromelist to {}

repeat with eachItem in listToCheck
	set forwardstring to (words of eachItem) as string
	set reversedstring to (reverse of (characters of forwardstring)) as string
	if forwardstring = reversedstring then
		-- we have a panindrome!
		copy eachItem as string to end of palindromelist
	end if
end repeat
return palindromelist

It also relies on AppleScript’s text item delimiters to eliminate the spaces between words. Make sure to set the TIDs to an empty string before this code if you set the TIDs elsewhere in your script.

Here’s my attempt:

set the list_to_check to {"A man, a plan, a canal, Panama.", "these", "are", "some", "example", "palindromes", "ere", "able was I ere I saw Elba", "A nut for a jar of tuna"}
set palindrome_list to {}

repeat with this_item in the list_to_check
	set this_item to contents of this_item
	if (my check_palindrome(this_item)) = true then set end of palindrome_list to this_item
end repeat
return palindrome_list

on check_palindrome(the_string)
	set the_string to (words of the_string) as string
	set check_count to (round of ((count of the_string) / 2) rounding down)
	repeat with i from 1 to check_count
		if (character i of the_string) is not (character (i * -1) of the_string) then return false
	end repeat
	return true
end check_palindrome

Jon

Camelot jumped in as I was working this out. That’s a more elegant solution than the one I came up with but at least we were both on the same track with the “words as string” method to get just the letters.

Jon

Wow - very elegant.

Excellent! :slight_smile: Here’s a modification that also ignores apostrophes:

set the listToCheck to {"these", "are", "some", "example", "palindromes", "ere", "able was I ere I saw Elba", " A nut for a jar of tuna", "One man's name? No!"}
set palindromelist to {}

-- A precaution to ensure that 'characters ... as string' goes as expected
set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to ""

ignoring white space and punctuation
	repeat with eachItem in listToCheck
		set forwardstring to eachItem as string
		set reversedstring to (reverse of (characters of forwardstring)) as string
		if forwardstring = reversedstring then
			-- we have a palindrome!
			set end of palindromelist to forwardstring
		end if
	end repeat
end ignoring

set AppleScript's text item delimiters to ASTID

return palindromelist

any way to set the words imputed to a text file? say words dictianary file?

If, by “words dictianary file” you mean Microsoft Word’s Dictionary file, then no. This file is not a regular text file - more a binary database file of words.

However, Mac OS X (like most Unix systems) ships with a common word file at /usr/share/dict/words.

It would be simple to read this file via AppleScript and use this as the input to the palindrome finder…

set wordlist to paragraphs of (read file “Macintosh HD:usr:share:dict:words”)

this

set listToCheck to paragraphs of (read file "Crazy Go Nuts:usr:share:dict:words")
set palindromelist to {}

repeat with eachItem in listToCheck
	set forwardstring to (words of eachItem) as string
	set reversedstring to (reverse of (characters of forwardstring)) as string
	if forwardstring = reversedstring then
		-- we have a panindrome
		copy eachItem as string to end of palindromelist
	end if
end repeat
return palindromelist

got none
crazy go nuts is my hd name

Try this (the other dictionary was wrong)

--initialization
set the Dictionary to "The Stranger:usr:share:dict:web2" as alias
set palindromeFile to "The Stranger:Users:benjaminhulley:Desktop:palindrome.txt"
set AppleScript's text item delimiters to ""
set startRead to 0
set endRead to 2 ^ 12
set endReached to false
set EOFMarker to get eof of the dictionary
set firstRun to true

repeat until endReached = true
	set listToCheck to paragraphs of (read the dictionary from startRead to endRead)
	set palindromelist to my processWords(listToCheck)
	set startRead to endRead
	set endRead to endRead + 2 ^ 12
	if endRead is greater than or equal to EOFMarker then
		set endRead to EOFMarker
		set endReached to true
	end if
	if (firstRun is true) then
		set appendData to false
		set firstRun to false
	else
		set appendData to true
	end if
	set AppleScript's text item delimiters to return
	if palindromelist is not {} then
		set palindromelist to ((palindromelist as text) & return)
		my writeToFile(palindromelist, palindromeFile, appendData)
	end if
	set AppleScript's text item delimiters to ""
end repeat

on processWords(listToCheck)
	set palindromelist to {}
	repeat with eachItem in listToCheck
		if ((count of eachItem) is greater than 1) then
			set forwardstring to (words of eachItem) as string
			set reversedstring to (reverse of (characters of forwardstring)) as string
			if forwardstring = reversedstring then
				-- we have a palindrome! 
				copy eachItem as string to the end of palindromelist
			end if
		end if
	end repeat
	return palindromelist
end processWords

on writeToFile(thisData, targetFile, appendData)
	try
		set the targetFile to the targetFile as text
		set the openTargetFile to open for access file targetFile with write permission
		if appendData is false then set eof of the openTargetFile to 0
		write thisData to the openTargetFile starting at eof
		close access the openTargetFile
		return true
	on error
		try
			close access file targetFile
		end try
		return false
	end try
end writeToFile

Ben