Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Exercise: Palindromes and Isograms
Index -> General Programming
Goto page Previous  1, 2
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
btiffin




PostPosted: Sat May 10, 2008 1:48 am   Post subject: Re: Exercise: Palindromes and Isograms

Update to the REBOL version. I was so excited about getting a chance to use alter that I skipped the obvious, and I added tabs to the delimters this time. alter is short for alternate, it scans a series! and either inserts or removes the value. Its use is normally limited to handling flags, so I thought this would be another use, but unique is more appropriate.
REBOL:
#!rebol -c
rebol []
line: ask "? "
words: parse/all line " ^-"
probe words
foreach word words [
    mod: uppercase trim/all copy word
    if equal? mod reverse copy mod [print ["Palindrome:" word]]
    if equal? length? unique mod length? mod [print ["Isogram:" word]]
]

wtd; Your exercises are cutting into my breaks! Smile
Sponsor
Sponsor
Sponsor
sponsor
Saad




PostPosted: Sat May 10, 2008 11:50 am   Post subject: Re: Exercise: Palindromes and Isograms

rizzix wrote:
Saad Shouldn't you account for single-quoted strings?


Correct again. However I realised a better way of doing it with help from regular expressions

Was done with GHC version 6.8.2

Compiled via
code:
ghc <name> -package regex-compat-0.71.0.1

Haskell:
import List (sort, group)
import Char (toLower, isAlpha)
import Text.Regex

main = getLine >>= \input -> mapM_ putStrLn $ filter (\word -> isPalindrome word || isIsograph word) $ separateWords [] $ fixString input
    where
        fixString string = subRegex (mkRegex "( *\\\\*(\'|\") *)") string "~"
       
        separateWords :: [String] -> String -> [String]
        separateWords allWords "" = allWords
        separateWords allWords (' ':rest) = separateWords allWords rest
        separateWords allWords ('~':rest) = let (word, _:remainder) = span (\char -> char /= '~') rest in separateWords (allWords ++ [word]) remainder
        separateWords allWords string = let (word, remainder) = span (\char -> char /= ' ' && char /= '~') string in separateWords (allWords ++ [word]) remainder
       
        isPalindrome :: String -> Bool
        isPalindrome string = let word = map toLower $ filter isAlpha string in word == reverse word

        isIsograph :: String -> Bool
        isIsograph string = all (\letters -> length letters == 1) $ group $ sort $ map toLower $ filter isAlpha string


Basically I replace all the quotation types with a ~ and then its simple string manipulation
rizzix




PostPosted: Sat May 10, 2008 2:10 pm   Post subject: RE:Exercise: Palindromes and Isograms

what if the word was 'abc ~ def'
Saad




PostPosted: Sat May 10, 2008 2:22 pm   Post subject: Re: RE:Exercise: Palindromes and Isograms

rizzix @ Sat May 10, 2008 2:10 pm wrote:
what if the word was 'abc ~ def'


It was done assuming that the words entered would be valid words.

However another version based on the same idea but with support of characters like ~ (although wtd could make what he wants more clear if he wants that kind of support or not)
Haskell:
import List (sort, group)
import Char (toLower, isAlpha)

main = getLine >>= \input -> mapM_ putStrLn $ filter (\word -> isPalindrome word || isIsograph word) $ separate input
    where
        separate :: String -> [String]
        separate line = separateWords [] line
            where
                separateWords :: [String] -> String -> [String]

                separateWords allWords "" = allWords
                separateWords allWords (' ':rest) = separateWords allWords rest
                   
                separateWords allWords ('\\':'\'':rest) = let (word, _:_:remainder) = span (\char -> char /= '\\') rest in separateWords (allWords ++ [word]) remainder
                separateWords allWords ('\\':'\"':rest) = let (word, _:_:remainder) = span (\char -> char /= '\\') rest in separateWords (allWords ++ [word]) remainder
                separateWords allWords ('\'':rest) = let (word, _:remainder) = span (\char -> char /= '\'') rest in separateWords (allWords ++ [word]) remainder
                separateWords allWords ('\"':rest) = let (word, _:remainder) = span (\char -> char /= '\"') rest in separateWords (allWords ++ [word]) remainder

                separateWords allWords string = let (word, remainder) = span (\char -> char /= ' ') string in separateWords (allWords ++ [word]) remainder
               
        isPalindrome :: String -> Bool
        isPalindrome string = let word = map toLower $ filter (\x -> x /= ' ') string in word == reverse word
   
        isIsograph :: String -> Bool
        isIsograph string = all (\letters -> length letters == 1) $ group $ sort $ map toLower string
rizzix




PostPosted: Sat May 10, 2008 2:39 pm   Post subject: Re: Exercise: Palindromes and Isograms

Here's another approach to this, using Parser Combinators.

Scala:
import scala.util.parsing.combinator.lexical._;
import scala.util.parsing.input.CharArrayReader.EofCh

object Test extends Application {
    case class Word(str : String)
   
    def isIsoPalin(s : List[Char]) =  s == s.reverse || s.removeDuplicates == s
   
    object Lexer extends Lexical {
        type Token = Word
       
        val sq = '\''; val dq = '"'; val bs = '\\'
       
        def whitespace = ' '?
       
        def token = (
            sq ~ ((bs ~ sq | chrExcept(sq, EofCh))+) ~ sq ^^ {case _ ~ xs ~ _ => Word(deflate(xs))}
          | dq ~ ((bs ~ dq | chrExcept(dq, EofCh))+) ~ dq ^^ {case _ ~ xs ~ _ => Word(deflate(xs))}
          | rep(' ') ~ (chrExcept(' ', EofCh)+)           ^^ {case _ ~ xs     => Word(xs mkString "")}
        );
       
        private def deflate(xs : List[Any]) : String = xs match {
            case (bs ~ c) :: ys => c.toString + deflate(ys)
            case y :: ys => y + deflate(ys)
            case _ => ""
        }
    }
   
    var scanner = new Lexer.Scanner(readLine)
   
    while (!scanner.atEnd) {
        scanner.first match {case Word(str) => if (isIsoPalin(str.toList.filter {_ != ' '} )) println(str)}
        scanner = scanner.rest
    }
}


Edit: fixed some bugs, cleaned up code.
Display posts from previous:   
   Index -> General Programming
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 2 of 2  [ 20 Posts ]
Goto page Previous  1, 2
Jump to:   


Style:  
Search: