Code Challenge problem: Cute girl decoder – Solution

Following my Code Challenge problem Cute girl decoder, here is the solution:

Solution

It seems very easy to solve this problem by replacing the substring such as j by gi, dz by d, k by khong.

But, there is a trick at “With words, she usually use”, that means k should be replace by khong only if it’s a word that is normally separated by these characters: [space] , . ; ? !

You could find an implementation below in Objective-C, my thank to Nghia Luong for the code contribution.

-(NSString*)cuteGirlTranslatorFromString:(NSString*)str {
    NSDictionary *wordsDict = @{@"k" :@"khong",
        @"ko"  :@"khong",
        @"ng"  :@"nguoi",
        @"hok" :@"khong",
        @"ntn" :@"nhu the nao",
        @"kq"  :@"ket qua",
        @"n"   :@"nhieu",
        @"dc"  :@"duoc"
    };

    NSDictionary *charsDict = @{
        @"j"  : @"gi", 
        @"w"  : @"qu",
        @"f"  : @"ph",
        @"dz" : @"d",
        @"z"  : @"d"
    };

    NSString *specialCharacterString = @"!~`@#$%^&*-+();:={}[],.<>?\\/\"\'";
    NSCharacterSet *specialCharacterSet = [NSCharacterSet characterSetWithCharactersInString:specialCharacterString];

    NSArray *components = [str componentsSeparatedByString:@" "];
    NSString *finalString = [[NSString alloc] init];
    
    for (NSString *eachOne in components) {
        NSString *specialChar = nil;
        NSRange specialCharRange = [eachOne rangeOfCharacterFromSet:specialCharacterSet options:NSCaseInsensitiveSearch];
        NSRange charRange;
        charRange = NSMakeRange(0, eachOne.length);
        if (specialCharRange.length) {
            specialChar = [eachOne substringWithRange:specialCharRange];
            charRange = NSMakeRange(0, specialCharRange.location);
        }
        NSString *restChar = [eachOne substringWithRange:charRange];
        for (NSString *keyString in wordsDict.allKeys) {
            if ([restChar isEqualToString:keyString]) {
                restChar = [wordsDict objectForKey:keyString];
            }
        }
        for (NSString *keyString in charsDict.allKeys) {
            if ([restChar rangeOfString:keyString].location != NSNotFound) {
                restChar = [restChar stringByReplacingOccurrencesOfString:keyString withString:[charsDict objectForKey:keyString]];
            }
        }

        // add special char
        if (specialCharRange.length) {
            restChar = [restChar stringByAppendingString:specialChar];
        }
        restChar = [restChar stringByAppendingString:@" "];
        finalString = [finalString stringByAppendingString:restChar];
    }

    return str;
}

// AND IMPELMENT:
NSString *inputString = @"blah blah"; // the message here
// Output is
[self cuteGirlTranslatorFromString:inputString];

It looks good but in my opinion, we could make it better with the open design.

Better design

Let see my implementation below as I think it could be better design to extend the implementation in the future. But please try to find some area we can improve 🙂

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Solution.CuteGirlDecoder
{
    internal interface IDecoder
    {
        string DecodeString( string message );
    }

    public class WordDecoder : IDecoder
    {
        private string _shortWord, _fullWord;

        public WordDecoder( string shortWord, string fullWord )
        {
            _shortWord = shortWord;
            _fullWord = fullWord;
        }

        public string DecodeString( string message )
        {
            StringBuilder str = new StringBuilder( message );
            int index = 0;
            List<char> separaters = new List<char> { '.', ' ', ';', ',', '?' };

            while ( ( index = str.ToString().IndexOf( _shortWord, index ) ) > 0 )
            {
                if ( ( index == 0 || separaters.Contains( str[ index - 1 ] ) && separaters.Contains( str[ index + _shortWord.Length ] ) ) )
                {
                    str = str.Remove( index, _shortWord.Length );
                    str = str.Insert( index, _fullWord );
                }
                index++;
            }

            return str.ToString();
        }
    }

    public class SubStringDecoder : IDecoder
    {
        private string _shortWord, _fullWord;

        public SubStringDecoder( string shortWord, string fullWord )
        {
            _shortWord = shortWord;
            _fullWord = fullWord;
        }

        public string DecodeString( string message )
        {
            return message.Replace( _shortWord, _fullWord );
        }
    }

    internal class Solution
    {
        public static void Main( string[] args )
        {
            List<IDecoder> decoders = new List<IDecoder>();
            decoders.Add( new WordDecoder( "k", "khong" ) );
            decoders.Add( new WordDecoder( "ko", "khong" ) );
            decoders.Add( new WordDecoder( "ng", "nguoi" ) );
            decoders.Add( new WordDecoder( "n", "nhieu" ) );
            decoders.Add( new WordDecoder( "dc", "duoc" ) );
            decoders.Add( new WordDecoder( "hok", "khong" ) );
            decoders.Add( new WordDecoder( "ntn", "nhu the nao" ) );
            decoders.Add( new WordDecoder( "kq", "ket qua" ) );

            decoders.Add( new SubStringDecoder( "j", "gi" ) );
            decoders.Add( new SubStringDecoder( "w", "qu" ) );
            decoders.Add( new SubStringDecoder( "f", "ph" ) );
            decoders.Add( new SubStringDecoder( "dz", "d" ) );
            decoders.Add( new SubStringDecoder( "z", "d" ) );

            string message = "blah blah"; // message here

            foreach ( IDecoder decoder in decoders )
            {
                message = decoder.DecodeString( message );
            }

            // Output: message
        }
    }
}

And the decoded message would be:

chan qua. em mun an nhieu ga quay cho doi gio duoc khong day? Anh co phai la nguoi iu cua em khong day, neu a la nguoi ieu cua em thi phai dua em di an ga quay chu, anh ma hem dua em di em gian a lien doa. The gio anh mun nhu the nao? ket qua ha? ok, neu ma anh khong dua iem di an ga ran thi nguoi dung den gap em lam gii nua, em khong yeu anh nua dau, iu gi ma co moi viec dua di an ga quay cung khong duoc thi yeu lam gi day, chan anh vagi dan ra ay. Ngay hom sau em noi gi a, em van noi la: chan qua. em mun an nhieu ga quay cho doi gio duoc khong day? Anh co phai la nguoi iu cua em khong day, neu a la nguoi ieu cua em thi phai dua em di an ga quay chu, anh ma hem dua em di em gian a lien doa. The gio anh mun nhu the nao? ket qua ha? ok, neu ma anh khong dua iem di an ga ran thi nguoi dung den gap em lam gii nua, em khong yeu anh nua dau, iu gi ma co moi viec dua di an ga quay cung khong duoc thi yeu lam gi day, chan anh vagi dan ra ay. Ngay hom sau nua em noi gi a, em noi day ne: chan qua. em mun an nhieu ga quay cho doi gio duoc khong day? Anh co phai la nguoi iu cua em khong day, neu a la nguoi ieu cua em thi phai dua em di an ga quay chu, anh ma hem dua em di em gian a lien doa. The gio anh mun nhu the nao? ket qua ha? ok, neu ma anh khong dua iem di an ga ran thi nguoi dung den gap em lam gii nua, em khong yeu anh nua dau, iu gi ma co moi viec dua di an ga quay cung khong duoc thi yeu lam gi day, chan anh vagi dan ra ay.

Go further

The idea of Skype plugin just came to make this problem more fun. But do you want to make it go live? I didn’t build it yet, but if you like this idea, I would like to code and share in the next post.

Do you want to see the new Skype plugin? Throw me at least 50 likes 🙂