<aside> ⚠️ 5달을 깎은 끝에 얻은 결론이지만, 과정을 설명하기에는 너무 길어 결과만 남겼습니다.

</aside>

가능한가?

결론부터 말하자면, 이 방법으로 519개까지는 무조건 4000번 미만으로 정렬할 수 있습니다.

아이디어

이는 몇 가지 간단한 아이디어에서 시작합니다.

각 스택의 끝에서 끝으로 자유롭게 이동할 수 있다

스택 A의 top, 스택 A의 bottom, 스택 B의 top, 스택 B의 bottom, 이렇게 총 4가지 위치에서는 서로 다른 곳으로 이동할 수 있습니다.

시작 위치, 끝 위치 A top A bottom B top B bottom
A top - ra pb pb + rb
A bottom rra - rra + pb rra + pb + rb
B top pa pa + ra - rb
B bottom rrb + pa rrb + pa + ra rrb -

그러므로 3분할 병합정렬, 퀵정렬이 가능합니다.

병합정렬, 퀵정렬, 18가지 방향, 다양한 방법

a + b + c = N개를 정렬하면서 이동하는 방법을 크게 병합정렬과 퀵정렬로 나눌 수 있습니다.

각 위치는 스택 A, B의 top, bottom일 수도 있고 top이면서 bottom일 수도 있습니다.

방향이 같아도 여러가지 방법이 있지만, 어떤 방법이 가장 효율적일지는 미리 알 수 없습니다.

개수와 방향에 따라 효율적인 정렬 방법/개수가 다르다

예를 들어 스택 A의 top에서 스택 A의 top으로 정렬하면서 이동하는 경우 아래 두 가지 방법이 있을 수 있습니다.

두번째 방법(#2)은 rr을 활용했습니다.

Untitled

Untitled

제가 찾은 방법은 6가지인데, 실제로 같은 방향이라도 개수에 따라 효율적인 방법이 달랐습니다.

방법

(ㄱ) - 우선 무차별 대입으로 몇 개까지는 항상 최적의 경로로 정렬되도록 하드코딩할 수 있습니다.

// 중략
	"\\2\\2\\2\\2\\5\\13\\5\\10\\5\\10\\1\\1\\1\\1\\6\\6\\6\\6",
		// 9 8 7 6 5 4 2 3 1을 a의 top/bottom에서 a의 top/bottom으로 이동하려면
		// pb pb pb pb ss rrr ss rr ss rr pa pa pa pa ra ra ra ra
	"\\2\\2\\2\\2\\2\\5\\11\\13\\1\\1\\1\\6\\10\\1\\1\\6\\6\\6",
		// 9 8 7 6 5 4 3 1 2을 a의 top/bottom에서 a의 top/bottom으로 이동하려면
		// pb pb pb pb pb ss rra rrr pa pa pa ra rr pa pa ra ra ra
	"\\2\\2\\2\\2\\2\\3\\13\\13\\5\\1\\1\\1\\10\\1\\1\\6\\6\\6\\6",
		// 9 8 7 6 5 4 3 2 1을 a의 top/bottom에서 a의 top/bottom으로 이동하려면
		// pb pb pb pb pb sa rrr rrr ss pa pa pa rr pa pa ra ra ra ra
// 후략

(ㄴ) - 다음으로는 무차별 대입과 DP를 통해 개수와 방향에 따라 어떤 방법으로, 어디로 몇 개를 보내는 게 효율적일지도 몇 개까지는 하드코딩할 수 있습니다.

{
	// 5000개를 정렬할 때 방향별로 어떤 방법을 써야 몇번만에 정렬이 완료될지
{{{1690, 2193, 1117}, 55845}, ps_solve_tst_merge_no_rotate_solve},
{{{1857, 2431, 712}, 53514}, ps_solve_txt_merge_twist_solve},
{{{1427, 519, 3054}, 57664}, ps_solve_tsb_merge_solve},
{{{1188, 1968, 1844}, 54224}, ps_solve_txb_merge_straightforward_solve},
{{{1631, 766, 2603}, 55779}, ps_solve_tot_merge_no_rotate_solve},
{{{878, 2358, 1764}, 53452}, ps_solve_tos_merge_solve},
{{{2849, 570, 1581}, 57387}, ps_solve_tob_merge_solve},
{{{1968, 712, 2320}, 54505}, ps_solve_sss_merge_solve},
{{{2088, 712, 2200}, 53565}, ps_solve_sxs_merge_straightforward_solve},
{{{736, 2355, 1909}, 54176}, ps_solve_sot_quick_solve},
{{{386, 2297, 2317}, 53784}, ps_solve_sob_quick_solve},
{{{519, 1427, 3054}, 57664}, ps_solve_bst_quick_solve},
{{{1256, 700, 3044}, 56586}, ps_solve_bxt_merge_twist_solve},
{{{2963, 1493, 544}, 58996}, ps_solve_bsb_merge_solve},
{{{296, 1415, 3289}, 56158}, ps_solve_bxb_quick_twist_solve},
{{{602, 1808, 2590}, 57387}, ps_solve_bot_merge_no_rotate_solve},
{{{599, 2335, 2066}, 55613}, ps_solve_bos_merge_solve},
{{{386, 1390, 3224}, 59369}, ps_solve_bob_merge_solve},
},

이제 런타임에서는 이렇게 정해진 방법대로 정렬하면 됩니다.

일정 개수 (ㄱ) 이하는 하드코딩된 최적의 경로로, 또 일정 개수 (ㄴ) 이하는 최적의 개수/방법으로, 그 이상은 (ㄴ)의 마지막 비율대로…

마무리

저는 블랙홀이 부족해서 이 방법을 고안만 하고 구현은 아직 못 했습니다.

아마 이 방법대로 구현한다면 세계 1등일지도…?

생각하는 즐거움을 박탈하고 싶지 않아 최소한의 정보만 남겼습니다. 여러분도 한 번 생각해보세요!

그리고 혹시 더 빠르게 정렬할 방법을 찾으셨다면 댓글 남겨주시면 감사하겠습니다. 🙏🏻