커피를 한 잔 밖에 마시지 않은 어느 비오는 날의 삽질. 메모리 제한이 2MB인 수업 과제에서 필요한 정수 배열의 크기를 10,000,000이 아닌 1,000,000으로 잘못 봐서 시작된 삽질이다. unsigned short는 2bytes, 백만 개면 딱 2MB다. 메모리 제한을 넘지 않게 하려면 배열 크기를 줄일 필요가 있었는데, 과제에서 요구하는 배열에 저장되는 정수는 어떤 경우에도 1500을 넘지 않으니 bit는 12개만 있으면 충분했다.
unsigned short 3개마다 12bits 4개가 들어갈 수 있으니 index 번호 변환은 간편하게 /4*3 해주면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 unsigned short arr[10000000 /4 *3 ];void store (int index, unsigned short value) { int chunk_num = (index/4 )*3 ; switch (index%4 ) { case 0 : arr[chunk_num] = (value << 4 ) | (arr[chunk_num] & 0x000F ); break ; case 1 : arr[chunk_num] = (arr[chunk_num] & 0xFFF0 ) | (value >> 8 ); arr[chunk_num+1 ] = ((value & 0x00FF ) << 8 ) | (arr[chunk_num+1 ] & 0x00FF ); break ; case 2 : arr[chunk_num+1 ] = (arr[chunk_num+1 ] & 0xFF00 ) | (value >> 4 ); arr[chunk_num+2 ] = ((value & 0x000F ) << 12 ) | (arr[chunk_num+2 ] & 0x0FFF ); break ; case 3 : arr[chunk_num+2 ] = (arr[chunk_num+2 ] & 0xF000 ) | (value); break ; } } unsigned short load (int index) { int chunk_num = (index/4 )*3 ; unsigned short value; switch (index%4 ) { case 0 : value = (arr[chunk_num] >> 4 ); break ; case 1 : value = ((arr[chunk_num] & 0x000F ) << 8 ) | (arr[chunk_num+1 ] >> 8 ); break ; case 2 : value = ((arr[chunk_num+1 ] & 0x00FF ) << 4 ) | ((arr[chunk_num+2 ] & 0xF000 ) >> 12 ); break ; case 3 : value = (arr[chunk_num+2 ] & 0x0FFF ); break ; } return value; }
원래는 배열은 물론이고 10,000,000이란 숫자도 필요없는 다른 알고리즘으로 답을 찾고 있었는데, 놓친 케이스가 뭔지 도저히 찾을 수가 없어서 이런식으로 요행을 노려봤다. 어쨌거나 삽질한 게 아까워서 기록.