---
# System prepended metadata

title: 11840 - Moving books
tags: [array]

---

# 11840 - Moving books
>author: Utin
###### tags: `array`
---

## Brief
See the code below

## Solution 0

```c=
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int N, book[26], shelf[26];

void pile_over(int from, int to);
void pile_onto(int from, int to);
void move_over(int from, int to);
void move_onto(int from, int to);

void print();
void print_value(int a);

void clean(int a);
void connect(int from, int to);

int check(int a, int b);

int main() {
    char op[10];
    int from, to;

    scanf("%d", &N);
    for (int i = 0; i < N; i++) {
        book[i] = i;
        shelf[i] = i;
    }
    while (1) {
        scanf("%s", op);

        // exit
        if (!strcmp(op, "exit")) break;

        // pile
        else if (!strcmp(op, "pile")) {
            scanf("%d %s %d", &from, op, &to);
            if (from == to || check(from, to) || check(to, from)) continue;
            else if (!strcmp(op, "onto")) pile_onto(from, to);
            else if (!strcmp(op, "over")) pile_over(from, to);
        }

        // move
        else if (!strcmp(op, "move")) {
            scanf("%d %s %d", &from, op, &to);
            if (from == to || check(from, to) || check(to, from)) continue;
            else if (!strcmp(op, "onto")) move_onto(from, to);
            else if (!strcmp(op, "over")) move_over(from, to);
        }
    }

    // output
    print();
}

void pile_over(int from, int to) {
    connect(from, to);                    //connect from and to
}

void pile_onto(int from, int to) {
    clean(to);                            // clean to
    connect(from, to);                    // connect from and to
}

void move_over(int from, int to) {
    clean(from);                          // clean from
    while (to != book[to]) to = book[to]; // search the top book
    connect(from, to);                    // connect from and to
}

void move_onto(int from, int to) {
    clean(from);                          // clean from
    clean(to);                            // clean to
    connect(from, to);                    // connect from and to
}

void print() {
    for (int i = 0; i < N; i++) {
        printf("%d:", i);
        if (shelf[i] != -1) print_value(shelf[i]);
        printf("\n");
    }
}

void print_value(int a) {
    printf(" %d", a);
    if (a != book[a]) print_value(book[a]);
}

void clean(int a) {
    int curr = a;
    while (curr != book[curr]) {
        int tmp = curr;
        curr = book[curr];
        shelf[curr] = curr;
        book[tmp] = tmp;
    }
}

void connect(int from, int to) {
    book[to] = from;
    if (shelf[from] == -1) {
        for (int i = 0; i < N; i++) {
            if (book[i] == from && i != to) {
                book[i] = i;
                break;
            }
        }
    }
    else shelf[from] = -1;
}

int check(int a, int b) {
    while (a != book[a]) {
        a = book[a];
        if (a == b) return 1;
    }
    return 0;
}

// Utin
```

## Solution 1

```c=
#include <stdio.h>

typedef struct _book {
	int num;
	struct _book* next, * pre;
} Book;

Book shelf[25], book[25];

void init(int n);
void move_onto(int A, int B);
void move_over(int A, int B);
void pile_onto(int A, int B);
void pile_over(int A, int B);
void clean(int idx);
void connect(int A, int B);
void output(Book* book);
int err(int A, int B);

int main() {
    char op[5] = {0};
    int N, A, B;
    scanf("%d", &N);
    init(N);
    while (1) {
        scanf("%s", op);
        if (op[0] == 'e') break;
        else if (op[0] == 'm') {
            scanf("%d %s %d", &A, op, &B);
            if (err(A, B) || err(B, A)) continue;
            if (op[1] == 'n') move_onto(A, B);
            else move_over(A, B);
        }
        else {
            scanf("%d %s %d", &A, op, &B);
            if (err(A, B) || err(B, A)) continue;
            if (op[1] == 'n') pile_onto(A, B);
            else pile_over(A, B);
        }
    }
    for (int i = 0; i < N; i++) {
        printf("%d:", i);
        output(shelf[i].next);
        printf("\n");
    }
}

void init(int n) {
    for (int i = 0; i < n; i++) {
        shelf[i].next = &book[i];
        book[i].num = i;
        book[i].next = NULL;
        book[i].pre = &shelf[i];
    }
}

void move_onto(int A, int B) {
    clean(A);
    clean(B);
    connect(A, B);
}

void move_over(int A, int B) {
    clean(A);
    Book* curr = &book[B];
    while (curr->next) curr = curr->next;
    connect(A, curr->num);
}

void pile_onto(int A, int B) {
    clean(B);
    connect(A, B);
}
void pile_over(int A, int B) {
    Book* curr = &book[B];
    while (curr->next) curr = curr->next;
    connect(A, curr->num);
}

void clean(int idx) {
    Book* curr = &book[idx];
    while (curr->next) {
        curr = curr->next;
        curr->pre->next = NULL;
        shelf[curr->num].next = curr;
        curr->pre = &shelf[curr->num];
    }
}

void connect(int A, int B) {
    book[B].next = &book[A];
    book[A].pre->next = NULL;
    book[A].pre = &book[B];
}

void output(Book* book) {
    while (book) {
        printf(" %d", book->num);
        book = book->next;
    }
}

int err(int A, int B) {
    Book* curr = &book[A];
    while (curr) {
        if (curr->num == B) return 1;
        curr = curr->next;
    }
    return 0;
}

// Utin
```

## Reference