U E D R , A S I H C RSS

Power Of Cryptography/조현태

No older revisions available

No older revisions available



소감

숫자가 지대 크다. 감당이 안된다..ㅠ.ㅜ
사실 하라면 못할것도 없지만, 입력 형식과 출력 형식등을 새로 짜내고, 덧셈및 곱셈연산을 다시짜주면 간단히(?)해결된다.
하지만 지금은 일해야 하기때문에 시간이 부족한 관계로..
임시로 뒤에 두 숫자는 해결하지 못하는 소스를 짜두었다.
내일이나 모레 수정 및 보완해서 두개 다 풀수 있도록 만들겠다.

// 값을 입력받을때, 두 값의 입력순서를 바꿔 놓았는데, 그편이 좀더 안정적이라는 단순한 이유때문..
회사에서 이런짓 하면 짤리려나?ㅎㅎㅎ

두번째 소스.. 숫자가 커도 저장하고 연산할 수 있을...듯 하다..;;ㅁ;; ㅎㅎㅎ MAX_LONG의 값을 10으로 줄이고 테스트를 해서 2개 이상의 경우에도 돌아가는 것은 알겠는데... 3번째 4번째 예제의 수가 원체 커야지 말이다. 연산의 결과가 좀처럼 안나온다. 곱하기 루틴에서 계속 더하고 있는듯..;;ㅁ;;
음.. 다른방법을 찾아야 하나.^^;

소스

~cpp 
#include <iostream>

using namespace std;
const int TRUE=1;
const int FALSE=0;

unsigned __int64 such_target_number(unsigned __int64 mokpyo, unsigned __int64 gaesu)
{
	unsigned __int64 min_answer=1, max_answer=mokpyo+1;
	while (min_answer+1!=max_answer)
	{
		unsigned __int64 temp_target=(min_answer+max_answer)/2;
		unsigned __int64 temp_result=1;
		for (register unsigned __int64 i=0; i<gaesu; ++i)
			temp_result*=temp_target;
		if (temp_result>mokpyo)
			max_answer=temp_target;
		else if (temp_result<mokpyo)
			min_answer=temp_target;
		else
			return temp_target;
	}
	return FALSE;
}

void main()
{
	cout << "결과값에 1을 입력할경우 프로그램이 끝납니다.\n";
	while (1)
	{
		unsigned __int64 intput_number=0;
		cout << "제곱한 결과값을 입력해주세요. >>";
		while (intput_number<1)
			scanf("%I64d",intput_number);
		if (1==intput_number)
			break;
		unsigned __int64 gob_gaesu=0;
		cout << "제곱한 회수를 입력해주세요. >>";
		while (intput_number<gob_gaesu || gob_gaesu<1)
			scanf("%I64d",gob_gaesu);
		unsigned __int64 answer=such_target_number(intput_number,gob_gaesu);
		if (FALSE==answer)
			cout << "잘못된 값을 입력하였습니다.\n";
		else
			cout << "결과값은 " <<answer << " 입니다.\n";
	}
	cout << "이용해주셔서 감사합니다.\n";
}

두번째 소스

~cpp 
#include <iostream>
#include <conio.h>

using namespace std;
const int TRUE=1;
const int FALSE=0;
const int ENTER=13;
const unsigned __int64 MAX_LONG=1000000000000000000;

class save_number{
private:
	unsigned __int64 number;
	save_number *next;
	save_number *prv;
public:
	save_number(int input_number, save_number *who_next)
	{
		number=input_number;
		next=who_next;
		prv=NULL;
		if (NULL!=who_next)
			who_next->link(this);
	}
	save_number(save_number *input_number, save_number *who_next)
	{
		number=0;
		next=who_next;
		prv=NULL;
		if (NULL!=who_next)
			who_next->link(this);
		plus_number(input_number);
	}
	~save_number()
	{
		if (prv!=NULL)
			delete prv;
	}
	void link(save_number *new_prv)
	{
		prv=new_prv;
	}
	save_number *get_prv()
	{
		return prv;
	}
	save_number *get_next()
	{
		return next;
	}
	void ollim()
	{
		if (prv!=NULL)
		{
			prv->number_input(number/MAX_LONG);
			number%=MAX_LONG;
		}
		else
		{
			prv=new save_number(number/MAX_LONG,this);
			number%=MAX_LONG;
		}
	}
	void plus_ollim()
	{
		if (prv!=NULL)
		{
			prv->plus_number_unsigned(number/MAX_LONG);
			number%=MAX_LONG;
		}
		else
		{
			prv=new save_number(number/MAX_LONG,this);
			number%=MAX_LONG;
		}
	}
	int number_input(int input_number)
	{
		if (input_number>9 || input_number<0)
			return FALSE;
		number*=10;
		number+=input_number;
		if (number>=MAX_LONG)
			ollim();
		return TRUE;
	}

	unsigned __int64 call_number(int where_number)
	{
		if (0==where_number)
			return number;
		if (prv==NULL)
			return MAX_LONG;
		return prv->call_number(where_number-1);
	}
	void plus_number_unsigned(unsigned __int64 plus_input_number)
	{
		number+=plus_input_number;
		if (number>=MAX_LONG)
			plus_ollim();
	}
	int plus_number(int plus_input_number)
	{
		if (plus_input_number<0)
			return FALSE;
		plus_number_unsigned( plus_input_number);
		return TRUE;
	}
	void plus_number(save_number *plus_target)
	{
		save_number *target=this;
		register int i=0;
		unsigned __int64 get_number;
		while (1)
		{
			get_number=plus_target->call_number(i);
			if (MAX_LONG==get_number)
				break;
			this->plus_number_unsigned(get_number);
			if (target->get_prv()==NULL)
				break;
			target=target->get_prv();
			++i;
		}
		while (1)
		{
			++i;
			get_number=plus_target->call_number(i);
			if (MAX_LONG==get_number)
				break;
			target=new save_number(get_number,target);
		}
	}
	int compare_number(unsigned __int64 target_number)
	{
		if (number<target_number)
			return 1;
		if (number>target_number)
			return -1;
		return 0;
	}
	int compare_number(save_number *target_number)
	{
		register int i=0;
		unsigned __int64 this_number=0;
		unsigned __int64 taget_get_number=0;
		while (this_number!=MAX_LONG)
		{
			if (taget_get_number==MAX_LONG)
				return -1;
			this_number=call_number(i);
			taget_get_number=target_number->call_number(i);
			++i;
		}
		if (taget_get_number!=MAX_LONG)
			return 1;
		while (1)
		{
			this_number=call_number(i);
			taget_get_number=target_number->call_number(i);
			if (this_number==taget_get_number && 0==i)
				return 0;
			this_number%=MAX_LONG; taget_get_number%=MAX_LONG;
			if (this_number<taget_get_number)
				return 1;
			if (this_number>taget_get_number)
				return -1;
			--i;
		}
	}
	int nanugi_2()
	{
		if (NULL!=prv)
		{
			if (1==prv->nanugi_2())
				number+=MAX_LONG;
			if (0==prv->call_number(0))
			{
				delete prv;
				prv=NULL;
			}
		}
		if (1==number%2)
		{
			number/=2;
			return 1;
		}
		number/=2;
		return 0;
	}
};

void print_number(save_number *target)
{
	save_number *temp_number=target;
	while(NULL!=temp_number->get_prv())
		temp_number=temp_number->get_prv();
	while (NULL!=temp_number)
	{
		cout << temp_number->call_number(0);
		temp_number=temp_number->get_next();
	}
}

save_number *such_target_number(save_number *mokpyo, save_number *gaesu)
{
	save_number *min_answer, *max_answer, *temp;
	int result_compare;
	min_answer=new save_number(1,NULL);
	max_answer=new save_number(mokpyo,NULL);max_answer->plus_number(1);
	temp=new save_number(min_answer,NULL);temp->plus_number(1);
	result_compare=temp->compare_number(max_answer);
	delete temp;
	while (0!=result_compare)
	{
		save_number *temp_target, *temp_result;
		temp_target=new save_number(min_answer,NULL);
		temp_target->plus_number(max_answer);temp_target->nanugi_2();
		temp_result=new save_number(1,NULL);
		save_number *i=new save_number(0,NULL);
		while(0!=i->compare_number(gaesu))
		{
			save_number *j=new save_number(1,NULL);
			save_number *temp_plus=new save_number(temp_result,NULL);
			while (0!=j->compare_number(temp_target))
			{
				temp_result->plus_number(temp_plus);
				j->plus_number(1);
			}
			delete j;
			delete temp_plus;
			i->plus_number(1);
		}
		delete i;
		int result_compare_second=temp_result->compare_number(mokpyo);
		if (-1==result_compare_second)
		{
			delete max_answer;
			max_answer=new save_number(temp_target,NULL);
		}
		else if (1==result_compare_second)
		{
			delete min_answer;
			min_answer=new save_number(temp_target,NULL);
		}
		else
		{
			delete min_answer;delete max_answer;delete temp_result;
			return temp_target;
		}
		temp=new save_number(min_answer,NULL);temp->plus_number(1);
		result_compare=temp->compare_number(max_answer);
		delete temp;
	}
	return NULL;
}

void main()
{
	save_number *intput_number, *gob_gaesu;
	intput_number=new save_number(0,NULL);
	gob_gaesu=new save_number(0,NULL);
	char temp=0;
	cout << "제곱한 결과값을 입력해주세요. >>";
	while (ENTER!=temp)
	{
		temp=getch();
		if (47<temp && 58>temp)
		{
			intput_number->number_input(temp-48);
			cout << temp;
		}
	}
	temp=0; cout << "\n";
	cout << "제곱한 회수를 입력해주세요. >>";
	while (ENTER!=temp)
	{
		temp=getch();
		if (47<temp && 58>temp)
		{
			gob_gaesu->number_input(temp-48);
			cout << temp;
		}
	}
	cout << "\n";
	save_number *answer=such_target_number(intput_number,gob_gaesu);
	if (NULL==answer)
		cout << "잘못된 값을 입력하였습니다.\n";
	else
	{
		cout << "결과값은 ";
		print_number(answer);
		cout << " 입니다.\n";
		delete answer;
	}
	cout << "이용해주셔서 감사합니다.\n";
}

나에게 할말

int 형을 64비트로 했군. -_-. 생각해보자. 파이썬처럼 거의 무한대자리까지 연산하려면 어떻게 해야할까??? - 영호
└간단하게 파이썬이랑 결합하면 되요오오~~>ㅃ<;;; ㅎㅎㅎㅎ
필요할때마다 malloc으로 할당하고 포인터로 넘겨서 연산하는 방법이 있습니다만....(귀찮다...귀찮다..귀찮다..윽.. 이게 아니잖아!!) -조현태
└음... 그거 내가 고등학교때 짜다가 포기했던 방법이네 ㅋㅋㅋ 나중에 가니 꽤나 복잡해져서...
암튼 요즈음 방법으로는... __int64 를 만드는 방법으로... assembly를 이용하면 엄청 간단해지더군 -_-...
한번 공부하고 만들어봐... C언어에서 인라인 어셈 써서 함수 만들어두 좋구. 아래 참고. - 영호

~cpp 
-----------c언어 소스-------
 2982:                     __int64 a,b;
 2983:
 2984:                     a = 0xffffffffffffffff;
 2985:                     b = a-1;
----------디셈블리소스------
 00415183   mov         dword ptr [a],0FFFFFFFFh
 0041518A   mov         dword ptr [ebp-4],0FFFFFFFFh
 00415191   mov         eax,dword ptr [a]
 00415194   sub         eax,1
 00415197   mov         ecx,dword ptr [ebp-4]
 0041519A   sbb         ecx,0
 0041519D   mov         dword ptr [b],eax
 004151A0   mov         dword ptr [ebp-0Ch],ecx
;;ㅁ;; 음.. 영호선배는 넘흐 마니 알고이쩡..>ㅃ<;; C언어 소스 봐도 모르게떠용..ㅎㅎ 64비트형의 인트형의 변수를 두개 지정하고 a에다가 최대값을..(아마 부호가 있기 때문에 -1저장됬을듯한..)넣고 b에는 a-1을.. 그럼 -2가 저장..;; 음.. 이게 아니라 혹시 b가 포인터라서 메모리 한칸 앞쪽을 잡아주는 건가요? 음.. 그러면 할당되지않은 메모리를 건드는 사태가..;;ㅁ;; 이것도 아닌가.. 연구를..;;ㅁ;; - 조현태

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:24:01
Processing time 0.0528 sec