본문 바로가기
Algorithms/simulation

7 Problem A : Bit_ImageMap1

by OKOK 2019. 11. 13.

가로 세로 각각 256개의 bit로 이루어진 imagemap이 있음

이 imagemap 내에 0~14 사이의 정수 4096개를 저장하는 encode() 함수를 설계

변환된 imagemap 이미지는 노이즈에 의해 0 또는 1로 변경 될 수 있고,

90, 180, 270도 회전 가능, 가로 또는 세로 방향으로 대칭 변경 가능하다

이 imagemap 데이터를 분석하여, 최초 저장된 4096개 정수를 반환하는 decode() 함수를 작성

 

- encode : data[4096]을 입력 받아 4개 비트에 저장하는데, 각 모서리는 0을 그리고 나머지 3개는 정상 비트를 입력

 - 패턴찾기에 사용할 0과 1을 넣음

- 노이즈, 회전, 플립

- decode : 먼저 패턴을 찾는다 압축한 좌표로 패턴을 찾아서 회전을 했는지 플립을 했는지 찾아냄

 - 반대로 수행한 다음에

 - 다시 원래 data 배열에 정상값을 넣는다 

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <memory.h>

extern void encode(unsigned char imagemap[256][32], unsigned char data[4096]);
extern void decode(unsigned char data[4096], unsigned char imagemap[256][32]);

static void setpixel(unsigned char imagemap[256][32], int x, int y, int pixel)
{
	unsigned char mask = 0x80 >> (x % 8);

	if (pixel == 0) imagemap[y][x / 8] &= ~mask;
	else imagemap[y][x / 8] |= mask;
}

static int getpixel(unsigned char imagemap[256][32], int x, int y)
{
	unsigned char mask = 0x80 >> (x % 8);

	if ((imagemap[y][x / 8] & mask) == 0) return 0;
	else return 1;
}

static void noise(unsigned char imagemap[256][32])
{
	for (register int y = 0; y < 256; y += 2)
		for (register int x = 0; x < 256; x += 2)
		{
			setpixel(imagemap, x + rand() % 2, y + rand() % 2, 0);
			setpixel(imagemap, x + rand() % 2, y + rand() % 2, 1);
		}
}

static void rotate(unsigned char imagemap[256][32], int angle)
{
	static unsigned char buffer[256][32];

	if (angle != 0)
	{
		switch (angle)
		{
		case 1: // 90
			for (register int y = 0; y < 256; y++)
				for (register int x = 0; x < 256; x++)
					setpixel(buffer, x, y, getpixel(imagemap, y, 255 - x));
			break;
		case 2: // 180
			for (register int y = 0; y < 256; y++)
				for (register int x = 0; x < 256; x++)
					setpixel(buffer, x, y, getpixel(imagemap, 255 - x, 255 - y));
			break;
		case 3: // 270
			for (register int y = 0; y < 256; y++)
				for (register int x = 0; x < 256; x++)
					setpixel(buffer, x, y, getpixel(imagemap, 255 - y, x));
			break;
		}

		for (register int y = 0; y < 256; y++)
			for (register int x = 0; x < 256; x++)
				setpixel(imagemap, x, y, getpixel(buffer, x, y));
	}
}

static void flip(unsigned char imagemap[256][32], int mode)
{
	static unsigned char buffer[256][32];

	if (mode != 0)
	{
		switch (mode)
		{
		case 1: // horizontal
			for (register int x = 0; x < 256; x++)
				for (register int y = 0; y < 256; y++)
					setpixel(buffer, x, y, getpixel(imagemap, x, 255 - y));
			break;
		case 2: // vertical
			for (register int y = 0; y < 256; y++)
				for (register int x = 0; x < 256; x++)
					setpixel(buffer, x, y, getpixel(imagemap, 255 - x, y));
			break;
		}

		for (register int y = 0; y < 256; y++)
			for (register int x = 0; x < 256; x++)
				setpixel(imagemap, x, y, getpixel(buffer, x, y));
	}
}

int main(void)
{
	static const int TCSIZE = 1;

	static unsigned char data[TCSIZE][4096] = { 0 };
	static unsigned char org[TCSIZE][4096] = { 0 };
	static unsigned char result[TCSIZE][4096] = { 0 };
	static unsigned char imagemap[TCSIZE][256][32] = { 0 };

	srand(3); // The seed will be changed.

	for (register int TC = 0; TC < TCSIZE; TC++)
		for (register int c = 0; c < 4096; c++)
			org[TC][c] = data[TC][c] = rand() % 15;

	int PERFORMANCE = 10000;

	time_t start = clock();
	for (register int TC = 0; TC < TCSIZE; TC++)
		encode(imagemap[TC], data[TC]);
	PERFORMANCE -= (clock() - start) / (CLOCKS_PER_SEC / 1000);

	for (register int TC = 0; TC < TCSIZE; TC++)
	{
		noise(imagemap[TC]);
		rotate(imagemap[TC], rand() % 4);
		flip(imagemap[TC], rand() % 3);
	}

	start = clock();
	for (register int TC = 0; TC < TCSIZE; TC++)
		decode(result[TC], imagemap[TC]);
	PERFORMANCE -= (clock() - start) / (CLOCKS_PER_SEC / 1000);

	int PASS = 0;

	for (register int TC = 0; TC < TCSIZE; TC++)
		if (memcmp(org[TC], result[TC], 4096) == 0) PASS++;

	printf("SCORE: %d\n", PASS * 10000 + PERFORMANCE);

	return 0;
}

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

#include <stdio.h>
void set(unsigned char imagemap[256][32], int x, int y, int pixel)
{
	unsigned char mask = 0x80 >> (x % 8);

	if (pixel == 0) imagemap[y][x / 8] &= ~mask;
	else imagemap[y][x / 8] |= mask;
}

int get(unsigned char imagemap[256][32], int x, int y)
{
	unsigned char mask = 0x80 >> (x % 8);

	if ((imagemap[y][x / 8] & mask) == 0) return 0;
	else return 1;
}

void myrotate(unsigned char imagemap[256][32], int angle)
{
	static unsigned char buffer[256][32];

	if (angle != 0)
	{
		switch (angle)
		{
		case 1: // 90
			for (register int y = 0; y < 256; y++)
				for (register int x = 0; x < 256; x++)
					set(buffer, x, y, get(imagemap, y, 255 - x));
			break;
		case 2: // 180
			for (register int y = 0; y < 256; y++)
				for (register int x = 0; x < 256; x++)
					set(buffer, x, y, get(imagemap, 255 - x, 255 - y));
			break;
		case 3: // 270
			for (register int y = 0; y < 256; y++)
				for (register int x = 0; x < 256; x++)
					set(buffer, x, y, get(imagemap, 255 - y, x));
			break;
		}

		for (register int y = 0; y < 256; y++)
			for (register int x = 0; x < 256; x++)
				set(imagemap, x, y, get(buffer, x, y));
	}
}

void myflip(unsigned char imagemap[256][32])
{
	static unsigned char buffer[256][32];

	for (register int y = 0; y < 256; y++)
		for (register int x = 0; x < 256; x++)
			set(buffer, x, y, get(imagemap, 255 - x, y));

	for (register int y = 0; y < 256; y++)
		for (register int x = 0; x < 256; x++)
			set(imagemap, x, y, get(buffer, x, y));
}

int search(unsigned char imagemap[256][32])
{
	int cnt[8] = { 0 }, pattern = 0, i, j, k;
	int dy[8] = { 0, 129,193,64,0,129,193,64 }, dx[8] = { 64, 0, 129,193,129,193,64,0 };
	
	/*
	for (i = 0; i < 64; i += 2){
		for (j = 0; j < 64; j += 2) {
			for (k = 0; k < 8; k++) {
				cnt[k] += get(imagemap, j + dx[k], i + dy[k]);
			}
		}
	}
	*/
	// 찾을 때 전체 검사가 아닌 띄엄띄엄 검사
	for (i = 0; i < 64; i += 2) {
		for (j = 0; j < 64; j += 2) {
			cnt[0] += get(imagemap, j + 64, i);
			cnt[1] += get(imagemap, j, i + 129);
			cnt[2] += get(imagemap, j + 129, i + 193);
			cnt[3] += get(imagemap, j + 193, i + 64);
			cnt[4] += get(imagemap, j + 129, i);
			cnt[5] += get(imagemap, j + 193, i + 129);
			cnt[6] += get(imagemap, j + 64, i + 193);
			cnt[7] += get(imagemap, j, i + 64);
		}
	}
	for (i = 1; i < 8; i++) if (cnt[pattern] < cnt[i]) pattern = i;
	return pattern;
}

void output(unsigned char imagemap[256][32])
{
	for (int i = 0; i < 256; i += 2) {
		for (int j = 0; j < 256; j += 2) {
			printf("%d", get(imagemap, j + j / 128, i + i / 128));
		}
		printf("\n");
	}
	printf("\n");
}

void output2(unsigned char imagemap[256][32])
{
	for (int i = 0; i < 256; i += 1) {
		for (int j = 0; j < 256; j += 1) {
			printf("%d", get(imagemap, j, i));
		}
		printf("\n");
	}
	printf("\n");
}

void encode(unsigned char imagemap[256][32], unsigned char data[4096])
{
	int i, j, r, c, bit, y = 0, x = 0;
	for (i = 0; i < 4096; i++) {
		for (j = 3; j >= 0; j--) {
			bit = (data[i] >> j) & 1;
			for (r = 0; r < 2; r++) {
				for (c = 0; c < 2; c++) {
					set(imagemap, x + c, y + r, bit);
				}
			}
			set(imagemap, x + x / 128, y + y / 128, 0); // 0으로 설정해서 3개는 정상, 1개는 내가 사용 패턴 찾기에
			x += 2;
			if (x >= 256) x = 0, y += 2;
		}
	}
	// 패턴찾기에 사용할 1
	for (i = 0; i < 64; i += 2) { 
		for (j = 64; j < 128; j += 2) {
			set(imagemap, j, i, 1);
		}
	}
	output(imagemap);
	//output2(imagemap);
}

void decode(unsigned char data[4096], unsigned char imagemap[256][32])
{
	output(imagemap);
	//output2(imagemap);
	int pattern = search(imagemap);
	if (pattern >= 4) myflip(imagemap);
	myrotate(imagemap, pattern % 4);

	int i, j, r, c, k = 0, cnt;
	for (i = 0; i < 256; i += 2) {
		for (j = 0; j < 256; j += 2) {
			cnt = 0;
			for (r = 0; r < 2; r++) {
				for (c = 0; c < 2; c++) {
					cnt += get(imagemap, j + c, i + r);
				}
			}
			cnt -= get(imagemap, j + j / 128, i + i / 128);
			data[k / 4] = data[k / 4] * 2 + cnt / 2;
			k++;
		}
	}
}

 

 

'Algorithms > simulation' 카테고리의 다른 글

5 Problem C : 루빅의 사각형  (0) 2019.11.13
7 Problem B : Bit_ImageMap2  (0) 2019.11.13
6 Problem B : 개미마을4  (0) 2019.11.12
6 Problem A : 개미마을3  (0) 2019.11.12
5 Problem A : 지하철  (0) 2019.11.08

댓글