diff --git a/README.md b/README.md
index 8c5cb43bb6dcd1afd945beaf7482ad3e2c5b64e2..86be9a3e5f9f5bd5d76b036ada6bf450bbc3abb6 100644
--- a/README.md
+++ b/README.md
@@ -1,74 +1,77 @@
 
-Operating system Assignment 4
-===================
+# Operating system Assignment 4
+
+## TA Info & Assignment URL
 
-TA Info & Assignment URL
 ---
 
 - TA Mail: ckai22@ajou.ac.kr
-- TA gitlab: http://git.ajou.ac.kr/ckai22
+- TA gitlab: <http://git.ajou.ac.kr/ckai22>
+
+## File Info
 
-File Info
 ---
+
 - **main.c**: Implements input and output
 - **alloc.h**: Implements meta structure
 - **alloc.c**: Implements malloc, free, and realloc
-- **Makefile**: compiles the 
+- **Makefile**: compiles the
 - **input** directory: saves the input file
 
-TEST
+## TEST
+
 ---
-##### Test proceeds as follows.
-- - - 
-1.	Input File name to the main function parameter.
-2.	Read File (File IO)
-3.	Interpret commands in File
-4.	Output to stdout
-
-##### **Command structure in File**
-- - -
-"Number of command lines" "Fit"<br>
-"Command" "Contents"<br>
-"Command" "Contents"<br>
-...<br>
-
-##### **Fit type (case sensitive)**
-- - -
-F: first fit<br>
-B: Best fit<br>
-W: worst fit<br>
-
-##### **Command type**
-- - -
-**s** String: String The command to put the value into<br>
-**f** n: nth allocation area free<br>
-**r** n m: reallocation with m bytes in the nth allocation area<br>
-**e** n: Allocate space without contents to n bytes<br>
-
-##### **Output**
-- - -
-“Free" "size" "content (if command is m only)"<br>
-"Free" "size" "content (if command is m only)"<br>
-...<br>
-
-##### **Example**
-- - -
-E1)<br>
-**Input**<br>
-3 F<br>
-m Think like a man of action and act like man of thought.<br>
-m Courage is very important. Like a muscle, it is strengthened by use.<br>
-m Life is the art of drawing sufficient conclusions from insufficient premises.<br>
-**Output**<br>
-0 56 Think like a man of action and act like man of thought.<br>
-0 72 Courage is very important. Like a muscle, it is strengthened by use.<br>
-0 80 Life is the art of drawing sufficient conclusions from insufficient premises.<br>
-<br>
-E2)<br>
-**Input**<br>
-2 F<br>
-m Think like a man of action and act like man of thought.<br>
-f 0<br>
-**Output**<br>
-1 56
 
+### **Test proceeds as follows**
+
+1. Input File name to the main function parameter.
+2. Read File (File IO)
+3. Interpret commands in File
+4. Output to stdout
+
+### **Command structure in File**
+
+"Number of command lines" "Fit"  
+"Command" "Contents"  
+"Command" "Contents"  
+...
+
+### **Fit type (case sensitive)**
+
+F: first fit  
+B: Best fit  
+W: worst fit  
+
+### **Command type**
+
+**s** String: String The command to put the value into  
+**f** n: nth allocation area free  
+**r** n m: reallocation with m bytes in the nth allocation area  
+**e** n: Allocate space without contents to n bytes  
+
+### **Output**
+
+“Free" "size" "content (if command is m only)"  
+"Free" "size" "content (if command is m only)"  
+...  
+
+### **Example**
+
+E1)  
+**Input**  
+3 F  
+m Think like a man of action and act like man of thought.  
+m Courage is very important. Like a muscle, it is strengthened by use.  
+m Life is the art of drawing sufficient conclusions from insufficient premises.  
+**Output**
+0 56 Think like a man of action and act like man of thought.  
+0 72 Courage is very important. Like a muscle, it is strengthened by use.  
+0 80 Life is the art of drawing sufficient conclusions from insufficient premises.  
+
+E2)  
+**Input**  
+2 F  
+m Think like a man of action and act like man of thought.  
+f 0  
+**Output**  
+1 56  
\ No newline at end of file
diff --git a/alloc.c b/alloc.c
index 931b9fd59da6368f6a48cfa9f681133f918b162b..d6528bb6138a13b2265b362839d8a8eab7b9f0a7 100644
--- a/alloc.c
+++ b/alloc.c
@@ -1 +1,207 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
 #include "alloc.h"
+#define align(n) (((n+3)/4)*4)
+meta *base;
+meta *last;
+
+void *m_find(size_t size)
+{
+  if(!base) return 0;
+  //else if(base==last) return base+1;
+
+  meta *cur=base, *ans=0;
+  size_t max=0, min=SIZE_T_MAX;
+  bool find=false;
+
+  do
+  {
+    switch(fit_type)
+    {
+      case FIRST_FIT:
+        if(cur->free && cur->size>=size) find=true;
+        break;
+
+      case BEST_FIT:
+        if(cur->free && cur->size>=size && cur->size<min)
+        {
+          ans=cur;
+          min=ans->size;
+        }
+        break;
+
+      case WORST_FIT:
+        if(cur->free && cur->size>=size && cur->size>max)
+        {
+          ans=cur;
+          max=ans->size;
+        }
+        break;
+    }
+    if(!find) cur=cur->next;
+  } while(cur && !find);
+  
+  if(find) ans=cur;
+  
+  return !ans?ans:ans+1;
+}
+
+void *m_merge(meta *cur1, meta *cur2)
+{
+  cur1->next=cur2->next;
+  cur1->size+=(cur2->size+META_SIZE);
+  if(cur2->next && cur2->next->free)
+    m_merge(cur1, cur2->next);
+  else if(cur1->prev && cur1->prev->free)
+    cur1=(m_merge(cur1->prev, cur1)-META_SIZE);
+  return cur1+1;
+}
+
+void *m_split(meta *cur, size_t size)
+{
+  if(cur->size<=size) return cur+1;
+
+  size_t size_sum=size+META_SIZE;
+  meta *new_meta=(void *)cur+size_sum;
+  new_meta->prev=cur;
+  new_meta->next=cur->next;
+  new_meta->free=true;
+  new_meta->size=cur->size-size_sum;
+
+  cur->size=size;
+  cur->next=new_meta;
+  return cur+1;
+}
+
+void *m_malloc(size_t size)
+{
+  size=align(size);
+  size_t size_sum=size+META_SIZE;
+  void *result;
+
+  if(!base)
+  {
+    //if(sbrk(0)==-1) return;
+    base=sbrk(0);
+    sbrk((int)size_sum);
+    base->free=true;
+    base->size=size;
+    last=base;
+  }
+  
+  result=m_find(size);
+  
+  //if no result
+  if(!result)
+  {
+    if(last->free && (last->size < size))
+      size_sum=size-last->size;
+    meta *result_meta=last;
+    last=sbrk((int)size_sum);
+    last->prev=result_meta;
+    last->free=true;
+    last->size=size;
+    result_meta->next=last;
+    result=result_meta+1;
+    
+    //realloc for the merging case
+    if(last->free && (last->size < size))
+      result=m_realloc(result, size);
+    else
+      result=last+1;
+  }
+  result=m_split(result-META_SIZE, size);
+  
+  return result;
+}
+
+void *m_realloc(void *ptr, size_t size)
+{
+  size=align(size);
+  void *cur=ptr;
+  meta *cur_meta=cur-META_SIZE;
+
+  if(cur_meta->size==size) return ptr;
+  //TODO: case when extra size is sufficient
+  if(cur_meta->size>size)
+    cur=m_split(cur_meta, size);
+  else if(cur_meta->next && cur_meta->next->free && cur_meta->size+cur_meta->next->size+META_SIZE > size)
+  {
+    m_free(ptr);
+    cur=m_merge(cur_meta, cur_meta->next);
+    cur_meta=cur-META_SIZE;
+    if(cur_meta->size+META_SIZE > size)
+      cur=m_split(cur_meta, size);
+  }
+  //nothing to merge or split
+  else
+  {
+    cur=m_malloc(size);
+    cur_meta=cur-META_SIZE;
+    memcpy(cur, ptr, size);
+    cur_meta->free=false;
+    m_free(ptr);
+  }
+  
+  return cur;
+}
+
+void m_free(void *ptr)
+{
+  //if(!ptr) return 0;
+
+  meta *cur=ptr-META_SIZE;
+  cur->free=true;
+  
+  if(cur->prev && cur->prev->free)
+    cur=m_merge(cur->prev,cur);
+  else if(cur->next && cur->next->free)
+    cur=m_merge(cur,cur->next);
+  
+  //release memory on the last block
+  if(cur->prev && cur==last)
+  {
+    last=last->prev;
+    last->next=NULL;
+  }
+  
+  //back to origin state if there are no blocks
+  else if(!cur->prev && cur==last)
+    base=last=NULL;
+  //return 1;
+}
+
+void *m_travel(int idx)
+{
+  if(!base) return 0;
+  meta *cur=base;
+  for(int i=0;cur && i<idx;i++)
+    cur=cur->next;
+
+  if(!cur) return 0;
+  else return cur+1;
+}
+
+void print_mem(void)
+{
+  /*
+  if(!base)
+  {
+    fprintf(stdout, "No memory allocated!\n");
+    return;
+  }
+  */
+
+  meta *cur=base;
+  while(cur)
+  {
+    fprintf(stdout, "%d %zu", cur->free, cur->size);
+    if(!cur->free) fprintf(stdout, " %s", (char *)(cur+1));
+    fprintf(stdout, "\n");
+    cur=cur->next;
+  }
+
+  return;
+}
diff --git a/alloc.h b/alloc.h
index 3245f55c3496bc75c70c04625ca3dcb7dd5d0afd..acba4047f19a05f25d3f7d1ac2fb52cfac946ed9 100644
--- a/alloc.h
+++ b/alloc.h
@@ -1,8 +1,28 @@
+#include <stdio.h>
+#include <stdbool.h>
 #ifndef _ALLOC_H_
 #define _ALLOC_H_
+#define FIRST_FIT 'F'
+#define BEST_FIT 'B'
+#define WORST_FIT 'W'
+#define META_SIZE sizeof(struct meta_struct)
 
 typedef struct meta_struct {
-
+  struct meta_struct *prev;
+  struct meta_struct *next;
+  bool free;
+  size_t size;
 } meta;
 
+extern int fit_type;
+
+void *m_find(size_t size);
+void *m_merge(meta *cur1, meta *cur2);
+void *m_split(meta *cur, size_t size);
+void *m_malloc(size_t size);
+void *m_realloc(void *ptr, size_t size);
+void m_free(void *ptr);
+void *m_travel(int idx);
+void print_mem(void);
+
 #endif
diff --git a/main.c b/main.c
index b5fba0682b01a1005462aa24bf4ac2f21227e156..646319f2097ae46d238378875c98e9fd290b3d2e 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,71 @@
+#include <stdio.h>
+#include <string.h>
 #include "alloc.h"
+#define BUF_MAX 1000
+#define FILE_PATH "test1.txt"
+#define STRING 's'
+#define FREE 'f'
+#define REALLOC 'r'
+#define ALLOC 'e'
+char buf[BUF_MAX+10];
+void *ptr;
+int fit_type;
 
 int main()
 {
+  FILE *fp=fopen(FILE_PATH, "rt");
+  if(!fp)
+  {
+    printf("Cannot open file!\n");
+    return 0;
+  }
+
+  char cmd;
+  int cmd_num, idx;
+  size_t size_alloc;
+  fscanf(fp, "%d %c\n", &cmd_num, &fit_type);
+  for(int i=0;i<cmd_num;i++)
+  {
+    fscanf(fp, "%c ", &cmd);
+    switch(cmd)
+    {
+      case STRING:
+        fgets(buf, BUF_MAX, fp);
+        size_alloc=strlen(buf);
+        buf[size_alloc-1]='\0';
+        ptr=m_malloc(size_alloc);
+        strcpy(ptr, buf);
+        meta *tmp=ptr-META_SIZE;
+        tmp->free=false;
+        //(meta *)(ptr-META_SIZE)->free=false;
+        break;
+
+      case FREE:
+        fscanf(fp, "%d\n", &idx);
+        ptr=m_travel(idx);
+        
+        if(!ptr){}
+         //fprintf(stdout, "No allocation on block %d\n", idx);
+        else m_free(ptr);
+        break;
+
+      case REALLOC:
+        fscanf(fp, "%d %zd\n", &idx, &size_alloc);
+        ptr=m_realloc(m_travel(idx), size_alloc);
+        break;
+
+      case ALLOC:
+        fscanf(fp, "%zd\n", &size_alloc);
+        ptr=m_malloc(size_alloc);
+        break;
+
+      default:
+        fprintf(stdout, "Wrong command\n");
+    }
+  }
+
+  print_mem();
+
+  fclose(fp);
   return 0;
 }