programming challenges 2012 crypt kicker - andstudy/forge GitHub Wiki

๋ฌธํ˜„์ง„

๋‹น๋ถ€ ์‚ฌํ•ญ

  • ์ด ์ฝ”๋“œ๋Š” ๋‹จ์ˆœํžˆ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ’€์–ด๋‚ด๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ ์ž…๋‹ˆ๋‹ค. ์ถ”๊ฐ€๋กœ ์ˆ˜์ • ํ•  ์˜ˆ์ • ์ž…๋‹ˆ๋‹ค.
  • ํŒŒ์ด์ฌ 2.7 ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ•˜์˜€์œผ๋ฉฐ ํŒŒ์ดํ† ๋‹‰์— ๊ฑธ๋งž์ง€ ์•Š๋Š” ์ฝ”๋“œ ์ž…๋‹ˆ๋‹ค. C++์ฒ˜๋Ÿผ ์งœ๋†จ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ๋„ ์•„๋‹Œ์ง€..
  • ์–‘ํ•ด๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์†Œ์Šค์ฝ”๋“œ

#-*-coding:utf-8 -*-

mapping = dict()
""" rd ๋Š” ๋ ˆํผ๋Ÿฐ์Šค ์‚ฌ์ „์ด๋‹ค. ํ‰๋ฌธ ๋‹จ์–ด๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ """
rd = [ 'dick', 'jane', 'spot', 'puff', 'and', 'yertle']
""" ed๋Š” ์•”ํ˜ธ ์‚ฌ์ „์ด๋‹ค. ์•”ํ˜ธํ™”๋œ ๋‹จ์–ด๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค """
ed = ['bjvg', 'hxsn', 'qymm', 'rqat', 'xsb', 'pnetfn']
ed_ = ['bjvg', 'xsb', 'hxsn', 'xsb', 'qymm', 'xsb', 'rqat', 'xsb', 'pnetfn']

def decodewords(mappingdict, word):
    tempstr = ""
    for char in word:
        tempstr = tempstr + mappingdict[char]
    
    return tempstr
    
def copydictionary(tempdict, mappingdict):
    """ ๋‘ ๊ฐœ์˜ ์‚ฌ์ „์„ ํ•ฉ์นจ """
    for key in tempdict.keys():
        mappingdict[key] = tempdict[key]
    return mappingdict
        
def wordmapping(mappingdict, plaintext, cryptogram):
    """ ๋‘ ๊ฐœ์˜ ๋‹จ์–ด๋ฅผ ๋ฐ›์•„์„œ ๋งคํ•‘ ํ…Œ์ด๋ธ”์— ์ ์šฉ ํ•œ๋‹ค.
    1) ๋‹จ์–ด๋ผ๋ฆฌ ๋งคํ•‘ ํ…Œ์ด๋ธ”์— ์ถฉ๋Œ ์—†์ด ์ ์šฉ ๊ฐ€๋Šฅํ•จ
        ๋งคํ•‘ํ…Œ์ด๋ธ”์— ์ž„์‹œํ…Œ์ด๋ธ”์„ ๋ฎ์–ด์”Œ
        True๋ฐ˜ํ™˜
    2) ๋‹จ์–ด๋ผ๋ฆฌ ๋งคํ•‘ ํ…Œ์ด๋ธ”์— ์ถฉ๋Œ ์žˆ์–ด์„œ ์ ์šฉ ๋ถˆ๊ฐ€๋Šฅํ•จ
        ๊ธฐ์กด ๋งคํ•‘ํ…Œ์ด๋ธ”์€ ๊ทธ๋Œ€๋กœ.
        False๋ฐ˜ํ™˜ 
    3) ๋‘ ๋ฌธ์ž์˜ ๊ธธ์ด๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋ฌด์กฐ๊ฑด False๋ฐ˜
    """
    
    if len(plaintext) != len(cryptogram):
        return False
    
    tempmappingdict = mappingdict.copy()
    
    for i in range(len(cryptogram)):
        char = cryptogram[i]
        chkresult = checkintegrity(tempmappingdict, char, plaintext[i])
        if  chkresult == False:
            return False
        else:
            tempmappingdict[char] = plaintext[cryptogram.index(char)]
    mappingdict = copydictionary(tempmappingdict, mappingdict)
    return True

def checkintegrity(mappingdict, indexchar, mappingchar):
    """ 
    indexchar => ์•”ํ˜ธํ™”๋œ๊ธ€์ž 
    mappingchar => ํ‰๋ฌธ
    
    1) ๋งคํ•‘ ํ…Œ์ด๋ธ”์— ์ด๋ฏธ ํ•ด๋‹น ํ‚ค ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ
    1-1) ์ด๋ฏธ ์žˆ๋Š” ํ‚ค ๊ฐ’๊ณผ ์ƒˆ๋กœ ๋“ค์–ด์˜จ ํ‚ค ๊ฐ’์ด ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ
    1-1-1) ์ด๋ฏธ ์žˆ๋Š” ํ‚ค์™€ ์ƒˆ๋กœ ๋“ค์–ด์˜จ ํ‚ค ๊ฐ’์ด ์ผ์น˜ ํ•˜๋Š” ๊ฒฝ์šฐ true๋ฐ˜ํ™˜ 
    1-1-2) ์ด๋ฏธ ์žˆ๋Š” ํ‚ค์™€ ์ƒˆ๋กœ ๋“ค์–ด์˜จ ํ‚ค ๊ฐ’์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ false๋ฐ˜ํ™˜ 
    
    2) ๋งคํ•‘ ํ…Œ์ด๋ธ”์— ํ•ด๋‹น ํ‚ค ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
    2-1) ๊ทธ๋Œ€๋กœ ๋งคํ•‘ ํ…Œ์ด๋ธ”์— ์ž…๋ ฅํ•˜๊ณ  true ๋ฐ˜ํ™˜
    
    ์˜ˆ) indexchar = qymm
        mappingchar = dick
        mappingdict = {}
        
    """
     
    tempkeys = mappingdict.keys()
    
    if indexchar in tempkeys:
        if mappingdict[indexchar] == mappingchar:
            return True
        else:
            return False
    else:
        mappingdict[indexchar] = mappingchar
        return True

def decode(edword):
                
    if len(ed) == 0:
        wordmapping(mapping, rd[0], edword)
        print 'touch end -- ed is empty'
        print mapping
        return True

    
    for rdword in rd:
        print '--On Test %s, %s' % (edword, rdword)
        if wordmapping(mapping, rdword, edword) == True:
            rd.remove(rdword)
            newedword = ed.pop()
            result = decode(newedword)
            if result == False:
                ed.append(newedword)
                rd.append(rdword)
            else:
                return True
    
    return False

def main():
    """ ๊ฐ๊ฐ์˜ 4๊ฐœ์˜ ๊ธ€์ž๋ฅผ ๊ฐ€์ง„ dictionary๋ฅผ ๊ฐ€์ง.
    ๋ชจ๋“  ์•”ํ˜ธํ™” ๋ฌธ์žฅ์„ ํ•˜๋‚˜์”ฉ ๋นผ์„œ ํ•ด๋…ํ•จ
 
    ํ‰๋ฌธ์‚ฌ์ „ = [ 'dick', 'jane', 'spot'] ์•”ํ˜ธ์‚ฌ์ „ = [ 'bjvg', 'rqat', 'hxsn']
    
    ์œ„์™€ ๊ฐ™์ด ๊ฐ€์ •ํ•˜๋ฉด, 'bjvg'๋Š” 'dick','jane', 'spot' ์„ธ ๊ฐœ์ค‘์— ํ•˜๋‚˜์ž„. 
    
    1) 'bjvg'๋ฅผ 'dick'์™€ ๋งค์นญ ์‹œํ‚ด
    1-1) 'bjvg'๋ฅผ 'dick'์— ๋งค์นญ ์‹œํ‚ค๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์Œ.
    1-1-1) 'rqat'๋ฅผ 'jane'์— ๋งค์นญ ์‹œ์ผœ๋ด„
    ...
    1-2) 'bjvg'๋ฅผ 'dick'์— ๋งค์นญ ์‹œ์ผฐ๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ.
    1-2-1) 'bjvg'๋ฅผ 'jane'์— ๋งค์นญ ์‹œ์ผœ๋ด„
    ...
    ๊ณ„์† ์•”ํ˜ธ์‚ฌ์ „์— ๋‹จ์–ด๋ฅผ ๋ฒˆ์—ญ ์‹œํ‚ค๋Š”๋ฐ ๋” ์ด์ƒ ํ•ด๋…ํ•  ๋‹จ์–ด๊ฐ€ ์—†์œผ๋ฉด ๋.
    
    decode ํ•จ์ˆ˜๋Š” ์ž๊ธฐ๊ฐ€ ํ•ด๋…ํ•œ ๋‹จ์–ด๋ฅผ ์ถœ๋ ฅํ•˜๋ฏ€๋กœ ๊ฒฐ๊ตญ retval์€ ํ•ด๋…ํ•œ ์ „์ฒด ๋ฌธ์ž์—ด์„ ๋ฐ˜
    """
    strresult = "*"
    retval = None
    print '-------------------------'
    print ed
    print rd
    print '-------------------------'

    edword = ed.pop()
    retval = decode(edword)
        
    if retval == False:
        print strresult
    else:
        for edword in ed_:
            print decodewords(mapping,edword)
main()

ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค

#-*-coding:utf-8 -*-
import no12CryptKicker as cryptkicker
import unittest

class testUnit (unittest.TestCase):
    
    def setup_testdict1(self):
        self.testdict1 = {'b': 'd', 'v': 'c', 'g': 'k', 'j': 'i'}
        pass
    
    def setup_testdict2(self):
        self.testdict2 = {'h': 'j', 'x': 'a', 's': 'n', 'n': 'e'}
        pass
    
    def teardown_testdict1(self):
        self.testdict1 = dict()
        pass
    
    def teardown_testdict2(self):
        self.testdict2 = dict()
        pass
    
    def test_func_wordmapping(self):
        testemptydict = dict()
        self.assertTrue(cryptkicker.wordmapping(testemptydict, 'dick', 'bjvg'))
        self.assertDictEqual(testemptydict, {'b':'d', 'j':'i', 'v':'c', 'g':'k'})
        
    def test_func_wordmapping2(self):
        """qymm์— dick๋ฅผ ๋„ฃ์œผ๋ฉด ์ •์ƒ์ ์œผ๋กœ false๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š”์ง€ ๊ฒ€์‚ฌ """
        testemptydict = dict()
        self.assertFalse(cryptkicker.wordmapping(testemptydict, 'dick', 'qymm'))
        
    def test_func_wordmapping3(self):
        """๊ธธ์ด๊ฐ€ ๋‹ค๋ฅธ ๋ฌธ์ž์—ด์„๋„ฃ์–ด์„œ ์ œ๋Œ€๋กœ ํŒ๋ณ„ ํ•˜๋Š”์ง€ ํ™•์ธ"""
        testemptydict = dict()
        self.assertFalse(cryptkicker.wordmapping(testemptydict, 'dick', 'xsb'))
    
    def test_func_wordmappingWithCopy(self):
        self.setup_testdict2()
        self.assertTrue(cryptkicker.wordmapping(self.testdict2, 'dick', 'bjvg'))
        self.assertDictEqual(self.testdict2, {'b': 'd', 'v': 'c', 'g': 'k', 'j': 'i','h': 'j', 'x': 'a', 's': 'n', 'n': 'e'})
        
        testemptydict = dict()
        self.assertTrue(cryptkicker.wordmapping(testemptydict, 'puff', 'qymm'))
        self.assertDictEqual(testemptydict, {'q':'p', 'y':'u', 'm':'f'})

        
    def test_func_checkintegrity(self):
        testemptydict = dict()
        self.assertTrue(cryptkicker.checkintegrity(testemptydict, 'b', 'd'))
        self.assertTrue(cryptkicker.checkintegrity(testemptydict, 'j', 'i'))
        self.assertTrue(cryptkicker.checkintegrity(testemptydict, 'v', 'c'))
        self.assertTrue(cryptkicker.checkintegrity(testemptydict, 'g', 'k'))
        
        testemptydict = dict()
        self.assertTrue(cryptkicker.checkintegrity(testemptydict, 'm', 'c'))
        self.assertFalse(cryptkicker.checkintegrity(testemptydict, 'm', 'k'))
    
    def test_func_copydictionary(self):
        self.setup_testdict1()
        self.setup_testdict2()
        self.assertDictEqual(cryptkicker.copydictionary(self.testdict1, self.testdict2), \
                             {'b': 'd', 'v': 'c', 'g': 'k', 'j': 'i','h': 'j', 'x': 'a', 's': 'n', 'n': 'e'})
                
if __name__ == "__main__":
    suite = unittest.TestLoader().loadTestsFromTestCase(testUnit)
    unittest.TextTestRunner(verbosity=2).run(suite)

์ด์žฌ์ •

#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <list>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;

#ifndef NULL
#define NULL '\0'
#endif

typedef struct _sRsvWord
{
	bool reserve;
	string str;
	
	_sRsvWord() {}
	_sRsvWord(const string st) : str(st), reserve(false)
	{
	}
	bool operator==(const _sRsvWord &rhs)
		{ return str == rhs.str; }
} sRsvWord;

typedef map<int, list<sRsvWord> > Dict; //string length, string list
typedef Dict::iterator DictItor;
Dict g_Dictionary; 

typedef list< list<string> > CryptList;
typedef CryptList::iterator CryptItor;
CryptList g_CryptStrings;


// ์‚ฌ์ „๋กœ๋”ฉ
bool Input(char *fileName)
{
	FILE *fp = fopen(fileName, "r");
	if (!fp) return false;

	char line[ 256];
	char *next = fgets(line, sizeof(line), fp);
	if (!next)
	{
		fclose(fp);
		return false;
	}

	const int size = atoi(next);
	int cnt = 0;
	while (next && size > cnt++)
	{
		next = fgets(line, sizeof(line), fp);
		const int len = strlen(line)-1;
		line[ len] = NULL; // ๊ฐœํ–‰๋ฌธ์ž ์ œ๊ฑฐ
		DictItor it = g_Dictionary.find(len);
		if (g_Dictionary.end() == it)
			g_Dictionary.insert( Dict::value_type(len, list<sRsvWord>()) );
		g_Dictionary[ len].push_back( sRsvWord(line) );
	}

	// ์•”ํ˜ธํ™”๋œ ์ŠคํŠธ๋ง ๋กœ๋”ฉ
	while (next)
	{
		next = fgets(line, sizeof(line), fp);
		const int len = strlen(line)-1;
		line[ len] = NULL; // ๊ฐœํ–‰๋ฌธ์ž ์ œ๊ฑฐ
		list<string> cryptStrings;
		char *p = strtok(line, " ");
		while (p)
		{
			cryptStrings.push_back(p);
			p = strtok(NULL, " ");
		}
		g_CryptStrings.push_back( cryptStrings );
	}	
	
	fclose(fp);
	return true;
}


char g_MatchTable[ 26];

string GetMatchString(string &cryptString)
{
	string str = cryptString;
	const int len = cryptString.length();
	for (int i=0; i < len; ++i)
		str[ i] = g_MatchTable[ 'z'-cryptString[ i]];
	return str;
}

void SetMatchString(string &cryptString, string &matchString)
{
	const int len = cryptString.length();
	for (int i=0; i < len; ++i)
	{
		g_MatchTable[ 'z'-cryptString[ i]] = matchString[ i];
	}
}

string GetDictionaryString( string &findString )
{
	const int len = findString.length();
	DictItor it = g_Dictionary.find(len);
	if (g_Dictionary.end() == it)
		return "";

	list<sRsvWord>::iterator i = find(it->second.begin(), it->second.end(), findString);
	if (it->second.end() == i)
		return "";
	return i->str;
}

// '*' ํ‘œ์‹œ๋ฅผ ์ œ์™ธํ•œ ์ŠคํŠธ๋ง์„ ๋น„๊ตํ•ด์„œ ๋ฆฌํ„ดํ•œ๋‹ค.
list<sRsvWord>::iterator GetNextDictionaryString( list<sRsvWord>::iterator beginItor, 
												 const list<sRsvWord>::iterator endItor, string &findString )
{
	list<sRsvWord>::iterator it = beginItor;
	while (endItor != it)
	{
		if (it->reserve)
		{
			++it;
			continue;
		}

		const int len = it->str.length();
		if (len != findString.length())
			break;

		int i=0;
		for (i=0; i < len; ++i)
		{
			if (findString[ i] == '*') 
				continue;
			if (it->str[ i] != findString[ i])
				break;
		}
		if (i==len) // ์ผ์น˜
			return it;
		++it;
	}
	return endItor;
}

// cryptString์„ ์‚ฌ์ „์—์žˆ๋Š” ๋‹จ์–ด๋กœ ์˜ˆ์•ฝ์‹œํ‚จ๋‹ค.
string ReserveTable( string &reserveString, string &cryptString, string &matchString )
{
	string str;
	list<sRsvWord>::iterator ritor;
	const int len = cryptString.length();
	DictItor it = g_Dictionary.find(len);
	if (g_Dictionary.end() == it)
		return "";

	if (reserveString.empty())
	{
		ritor = GetNextDictionaryString(it->second.begin(), it->second.end(), matchString);
	}
	else
	{
		list<sRsvWord>::iterator i = find(it->second.begin(), it->second.end(), reserveString);
		if (it->second.end() != i)
			i->reserve = false; // ์˜ˆ์•ฝ๋œ ๋‹จ์–ด ๋ณต๊ตฌ

		ritor = GetNextDictionaryString(++i, it->second.end(), matchString );
	}

	if (it->second.end() != ritor)
	{
		SetMatchString(cryptString, ritor->str);
		ritor->reserve = true;
		str = ritor->str;
	}

	return str;
}

// ํ…Œ์ด๋ธ” ์ƒ์„ฑ
bool MakeTable(list<string>::iterator crypStringItor, list<string>::iterator cryptEndItor )
{
	if (crypStringItor == cryptEndItor)
		return true;

	string cryptString = *crypStringItor;
	string matchString = GetMatchString(cryptString);
	string dictString = GetDictionaryString(matchString);
	if (dictString.empty())
	{
		string reseveString;
		while (1)
		{
			reseveString = ReserveTable( reseveString, cryptString, matchString );
			if (reseveString.empty())
				return false;
			if (MakeTable(++crypStringItor, cryptEndItor))
				return true;
		}
	}
	else
	{
		return MakeTable(++crypStringItor, cryptEndItor);
	}

	return true;
}

// ์•”ํ˜ธ๋ฌธ์œผ๋กœ ๋งค์นญํ…Œ์ด๋ธ”์„ ์ด์šฉํ•ด์„œ ๊ธ€์ž๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
void PrintCryptString(list<string>::iterator beginIt, list<string>::iterator endIt)
{
	list<string>::iterator it = beginIt;
	if (it == endIt)
		return;

	string matchString = GetMatchString(*beginIt);
	printf( "%s ", matchString.c_str() );
	PrintCryptString(++it, endIt);
}

void DecryptLine(list<string> &cryptStrings)
{
	for (int i=0; i < sizeof(g_MatchTable); ++i)
		g_MatchTable[ i] = '*';

	list<string>::iterator it = cryptStrings.begin();
	MakeTable(cryptStrings.begin(), cryptStrings.end() );

	PrintCryptString(cryptStrings.begin(), cryptStrings.end());
	printf( "\n" );

}

// ๋ณตํ˜ธํ™”
void Decrypt()
{
	CryptItor it = g_CryptStrings.begin();
	while (g_CryptStrings.end() != it)
		DecryptLine(*it++);
}

int main(int argc, char* argv[])
{
	if (argc < 2)
		return 0;

	Input(argv[1]);
	Decrypt();

	return 0;
}
โš ๏ธ **GitHub.com Fallback** โš ๏ธ