File size: 3,427 Bytes
eeef81e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python3

from typing import Any, Union


class Animal:
    def __init__(self, name: str) -> None:
        self.name = name

    def set_order(self, order: int) -> None:
        self.order = order

    def peek_order(self) -> int:
        return self.order

    def __str__(self) -> str:
        return f"{self.name}"


class Node:
    def __init__(self, data: Any):
        self.data = data
        self.next_node = None


class LinkedList:
    def __init__(self) -> None:
        self.head = None
        self.tail = None

    def __str__(self) -> str:
        current = self.head
        string = f""
        while current.next_node is not None:
            string += f"{current.data} -> "
            current = current.next_node
        return string + "END"

    def is_empty(self) -> bool:
        if self.head is None:
            return True
        else:
            return False

    def insert(self, item: Any) -> None:
        if self.is_empty():
            self.head = Node(item)
            self.tail = self.head
        else:
            new_node = Node(item)
            self.tail.next_node = new_node
            self.tail = self.tail.next_node

    def remove(self) -> Any:
        if self.head is None:
            raise ("Empty LinkedList!")
        else:
            data = self.head.data
            self.head = self.head.next_node
            return data

    def peak(self):
        return self.head.data


class Dog(Animal):
    def __init__(self, name: str):
        super().__init__(name)


class Cat(Animal):
    def __init__(self, name: str):
        super().__init__(name)


class AnimalQueue:
    def __init__(self) -> None:
        self.dogs = LinkedList()
        self.cats = LinkedList()
        self.order = 0

    def enqueue(self, animal: Union[Dog, Cat]) -> None:
        if not isinstance(animal, (Dog, Cat)):
            raise Exception("Expected Dog or Cat!")
        else:
            animal.set_order(self.order)
            self.order += 1
            if isinstance(animal, Dog):
                self.dogs.insert(animal)
            elif isinstance(animal, Cat):
                self.cats.insert(animal)

    def dequeAny(self) -> Union[Dog, Cat]:
        if self.dogs.is_empty():
            return self.dequeCat()
        elif self.cats.is_empty():
            return self.dequeDog()

        if self.dogs.head.data.peek_order() > self.cats.head.data.peek_order():
            return self.dequeCat()
        else:
            return self.dequeDog()

    def print_cats(self) -> str:
        string = ""
        cat = self.cats.head
        while cat is not None:
            string += f"{cat.data.name} {cat.data.peek_order()} | "
            cat = cat.next_node
        return string

    def dequeDog(self) -> Dog:
        return self.dogs.remove()

    def dequeCat(self) -> Cat:
        return self.cats.remove()


def main():
    q = AnimalQueue()
    dogs = [Dog("d1"), Dog("d2"), Dog("d3")]
    cats = [Cat("c1"), Cat("c2"), Cat("c3")]
    both = []
    while cats != []:
        both.append(cats.pop())
        both.append(dogs.pop())
    [q.enqueue(animal) for animal in both]

    string = ""
    for anim in both:
        string += f"{anim.name} {anim.order} | "
    print(string)
    # print(q.print_cats())
    get = q.dequeDog()
    print(get.order,get.name)
    get = q.dequeAny()
    print(get.order,get.name)


if __name__ == "__main__":
    main()