50023. Combination Lock

I'm a slow walker, but I never walk backwards.

Problem Description

Read problems statements in Mandarin ChineseMorris AI 翻譯:
實作 號碼鎖 (Combination lock) 的結構。例如於行李箱上使用的號碼鎖,號碼鎖沒有永久的密碼,當它用什麼密碼鎖住,下一次就必須用什麼密碼打開。現在請實作一個密碼範圍為 0 到 9999 號碼鎖。

Implement a combination lock. A combination lock has a combination of 4 digits, like 0256. A combination lock only opens when the correct combination is entered. You must implement the following functions.

  • void init(Lock *lock);
    Initialize a combination lock. Initially the lock is unlocked.
  • int lock(Lock *lock, int combination);
    To lock an unlocked lock.
    • If the lock is already locked then do nothing and return -1 as error.
    • If the lock is unlocked then lock it with the combination and return the combination if it is valid. A valid combination is an integer from 0 to 9999. After that the lock is locked. If the combination is not valid return 10000 as error.
  • int unlock(Lock *lock, int combination);
    To unlock a locked lock.
    • If the lock is already unlocked then do nothing and return -1 as error.
    • If the lock is locked then unlock it with the combination. If the combination is correct then unlock the lock and return 0. If the combination is incorrect then the lock remains locked and return 1 as error.
  • int isLocked(Lock *lock);
    Return 1 if the lock is locked, 0 if unlocked.

Subtasks

  • 10pt. Implement init and isLocked.
  • 30pt. Implement init, lock, and isLocked. The combination for lock is always valid.
  • 10pt. Implement init, lock, and isLocked. The combination for lock may be invalid.
  • 50pt. Implement init, lock, unlock, and isLocked.

locker.h

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef _LOCKER_H
#define _LOCKER_H
 
/*
    define structure Lock
*/
 
void init(Lock *lock);
int lock(Lock *lock, int combination);
int unlock(Lock *lock, int combination);
int isLocked(Lock *lock);
#endif

main.c

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
42
43
44
45
46
47
48
49
#include "locker.h"
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
 
void test_specall() {
#define UNLOCK 0
#define LOCKED 1
#define OPERROR -1
#define PEERROR 10000
    int n, cmds, cmd, lid, combination;
    scanf("%d", &n);
    Lock *locker[32];
    for (int i = 0; i < n; i++)
        locker[i] = (Lock *) malloc(sizeof(Lock));
    for (int i = 0; i < n; i++)
        init(locker[i]);
    scanf("%d", &cmds);
    for (int i = 0; i < cmds; i++) {
        scanf("%d %d", &cmd, &lid);
        if (cmd == 1) {
            int ret = isLocked(locker[lid]);
            printf("isLocked %d %s\n", lid, ret == OPERROR ? "NOTHING HAPPENED" :
                ((ret == LOCKED) ? "LOCKED" : (ret == UNLOCK ? "UNLOCK" : "INVALID VALUE")));
        } else if (cmd == 2) {
            scanf("%d", &combination);
            int ret = lock(locker[lid], combination);
            if (ret == OPERROR)
                printf("lock %d %s\n", lid, "NOTHING HAPPENED");
            else if (ret == PEERROR)
                printf("lock %d %s\n", lid, "INVALID COMBINATION");
            else
                printf("lock %d new pwd: %d\n", lid, ret);
        } else if (cmd == 3) {
            scanf("%d", &combination);
            int ret = unlock(locker[lid], combination);
            printf("unlock %d %s\n", lid, ret == OPERROR ? "NOTHING HAPPENED" :
                ((ret == LOCKED) ? "LOCKED" : (ret == UNLOCK ? "UNLOCK" : "INVALID VALUE")));
        } else {
            assert(0);
        }
    }
}
int main() {
    test_specall();
    return 0;
}

Sample Input

3 12
2 0 9999
3 1 1234
1 0
1 2
3 0 1234
3 0 10000
2 0 514
3 0 9999
2 0 514
3 0 9999
1 0
1 1

Sample Output

lock 0 new pwd: 9999
unlock 1 NOTHING HAPPENED
isLocked 0 LOCKED
isLocked 2 UNLOCK
unlock 0 LOCKED
unlock 0 LOCKED
lock 0 NOTHING HAPPENED
unlock 0 UNLOCK
lock 0 new pwd: 514
unlock 0 LOCKED
isLocked 0 LOCKED
isLocked 1 UNLOCK

Discussion