# 2020q3 Homework1 (quiz1)
###### tags: `sysprog2020`
* [add entry](https://hackmd.io/vdkBR0toQ_WIBYo0JtXpcw?both#add-entry)
* [AA1](https://hackmd.io/vdkBR0toQ_WIBYo0JtXpcw?both#AA1)
* [AA2](https://hackmd.io/vdkBR0toQ_WIBYo0JtXpcw?both#AA2)
* [swap pair](https://hackmd.io/vdkBR0toQ_WIBYo0JtXpcw?both#swap_pair)
* [BB1](https://hackmd.io/vdkBR0toQ_WIBYo0JtXpcw?both#BB1)
* [BB2](https://hackmd.io/vdkBR0toQ_WIBYo0JtXpcw?both#BB2)
# node structure
```c
typedef struct __node {
int value;
struct __node *next;
} node_t;
```
```graphviz
digraph {
label="node_t";
node[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">value</td>
<td port="next" border="1" bgcolor='#AAAAAA'>next</td>
</tr>
</table>
>];
node1, node2
node1:next->node2:value
{rank=same; node1 node2}
}
```
# add entry
### Target : Append a new element to list
```c
void add_entry(node_t **head, int new_value)
{
node_t **indirect = head;
node_t *new_node = malloc(sizeof(node_t));
new_node->value = new_value;
new_node->next = NULL;
AA1;
while (*indirect)
indirect = &(*indirect)->next;
AA2;
}
```
### analysis
Create a new element
```graphviz
digraph B {
node[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">value</td>
<td port="next" border="1" bgcolor='#AAAAAA'>next</td>
</tr>
</table>
>];
n_0,n_1,n_2,n_new
n_0:next->n_1:value
n_1:next->n_2:value
{rank=same; n_0 n_1, n_2, n_new}
}
```
find last element
```graphviz
digraph B {
node[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">value</td>
<td port="next" border="1" bgcolor='#AAAAAA'>next</td>
</tr>
</table>
>];
n_0,n_1,n_2,n_new
n_0:next->n_1:value
n_1:next->n_2:value
n_headpp[fontsize=12,shape=rect,label="indirect (node_t**)"]
n_headp[fontsize=12,shape=rect,label="*indirect (node_t*)"]
n_headpp->n_headp
n_headp->n_0:value[label="start"]
n_headp->n_0:next[label="after loop 0"]
n_headp->n_1:next[label="after loop 1"]
n_headp->n_2:next[label="after loop 2, *indirect==null"]
{rank=same; n_0 n_1, n_2, n_new}
}
```
### AA1
AA1 is not easy, I found answer by looking options
```c
assert(new_node); // check memory is allocated
```
### AA2
Since original code has create a new node and loop through list to find last node, AA2 should be insert the new node.
```c
*indirect = new_node;
```
# swap_pair
### Target : swap every two node
```c
node_t *swap_pair(node_t *head)
{
for (node_t **node = &head; *node && (*node)->next; BB1) {
node_t *tmp = *node;
BB2;
tmp->next = (*node)->next;
(*node)->next = tmp;
}
return head;
}
```
### breakdown
```c
node_t *swap_pair(node_t *head)
{
for (node_t **node = &head; // initialize
*node && (*node)->next; // check there are two nodes to swap
BB1) { // next
```
#### before:
```graphviz
digraph{
n_first[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">first</td>
<td port="next" border="1" bgcolor='#AAAAAA'>*second</td>
</tr>
</table>
>]
n_second[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">second</td>
<td port="next" border="1" bgcolor='#AAAAAA'>*third</td>
</tr>
</table>
>]
n_third[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">third</td>
<td port="next" border="1" bgcolor='#AAAAAA'>*next</td>
</tr>
</table>
>]
n_node[shape=rect,fontsize=12,label="*node"];
n_node->n_first:value;
n_first:next->n_second:value;
n_second:next->n_third:value;
{rank=same;n_node n_first n_second, n_third}
}
```
```c
node_t *tmp = *node; // cache the first node
BB2;
tmp->next = (*node)->next;/* ∵ the next of fisrt node shouble be
* the next of seconde node
* ∴ (*node) is a pointer to seconde node
*/
(*node)->next = tmp; // assign pointer to first node to second.next
```
#### after:
```graphviz
digraph{
n_first[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">first</td>
<td port="next" border="1" bgcolor='#AAAAAA'>*third</td>
</tr>
</table>
>]
n_second[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">second</td>
<td port="next" border="1" bgcolor='#AAAAAA'>*first</td>
</tr>
</table>
>]
n_third[shape=none label=<
<table border="0" cellspacing="0">
<tr>
<td port="value" border="1">third</td>
<td port="next" border="1" bgcolor='#AAAAAA'>*next</td>
</tr>
</table>
>]
n_first:next->n_third:value;
n_second:next->n_first:value;
n_node[shape=rect,fontsize=12,label="*node"];
n_node->n_second:value;
{rank=same;n_node n_first n_second, n_third}
}
```
### BB2
The missing part should be changing \*node (node_t\*) from 'pointer to first node' to 'pointer to second node'
```c
*node=(*node)->next
```
### BB1
And it need to go through next pair, which is set \*node (node_t\*) to 'pointer to third node', and \*node is a 'pointer to second node' after above operation.
```c
node=&(*node)->next->next
```
```c
}
return head;
}
```
### without return
simply change type of head from node_t* to node_t**
```c
void swap_pair(node_t **head)
{
for (node_t **node = head;
*node && (*node)->next;
node=&(*node)->next->next) {
node_t *tmp = *node;
*node = (*node)->next;
tmp->next = (*node)->next;
(*node)->next = tmp;
}
}
```
### test
<iframe width="800px" height="800px" src="https://godbolt.org/e#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAM1QDsCBlZAQwBtMQBGAFlICsupVs1qhkAUgBMAISnTSAZ0ztkBPHUqZa6AMKpWAVwC2tLgHZSW9ABk8tTADljAI0zEQ3ABykADqgWE6rR6hibmvv6BdLb2Tkau7l6KypiqQQwEzMQEIcamnBZKKmp0GVkEMY4ubh7eCpnZuWEFig0VdlXxNV4AlIqoBsTIHADkUgDMdsiGWADU4uM69fioAHQIC9jiAAwAgju7BACePphYVLP1xAaqswD6d7QYmPNmsnuzn7N2BLMAbmwDJgFu9dl9LgRrrcHk85gAqewADwIIIO4jMABFZrDMHcUeNQQccXjZnCFAB3Zg%2BO4%2BZh4YgQYm/OEITDMdA9NFvA7gmjEWaM54kuEI57zcZYqQANlZ7JBpJx80kUulAtFWB6AFpNkj8dJsc8FhjpRB1ZgtTrMMjteNsLqeq9QeDwUzSQQjD5xVizaiPs7PmavWqcRbbbrfWD/bN3T4bXarb8jcHnqH48iI1Hkxq47qgzGM190ca/Z9iJgCINaLNZegI0W0XsDn9UHh0JdKdTafTJIKsMKWWyOVynV8%2BQLXSLFUma/LA9LVaaQzmE/KcUaTWbU7rl8iHeiR/6JzGgz6CTyo3OJVnzTu9ef/THb0HFynbwX/S/s5bkXmPe/XsW%2ByYk2LZtj4xA/Kw9S9riBBwsQnLciWszkggeDsBACH7vezrgT8VAQFIkhSAArD44gkbIkgkegpCkeRJHGiROi0ERpBkMQcYAoYmDsbenJnsh4LEEanHfneyH1o2wF7D8sxGHStAQIhB4Gn2vy0CR%2B6cJI4wkaQ2IGKwrA%2BJC9aCZGnyurQ3DabpvBKlKmnmap1njHZ4zjAZ0o2S5OHWcRbw6eMkjecqtDucBFkukKGmcB5nBhU5gXGtFXzWdsHnbEltDxVFhLIRO/JJhSVI0nSDI%2BdsAmqXh9BQQQmE1Q2lmzMVV6lZ2FVNXWyGdeV3aEcqWFpZ8dUEA1PUWUWIx9KwIAjCRIykKYIzbMtqALTochyJcAxDC8EycMtBALetPR9AA1iAJHZfNIzcMtq3raQm0jMtCggNlp1rbNpBwLAMCICgqAeuhbjkJQaBg%2Bw7jAJw2yhVQ6EEG4n0QM4Z3Lc4dhZEcC3HaQ0NGFoBAAPK0Kw%2BO/aQWAKaI7BY7T9KpGofyYJ9NNWqkBio0zPzKEzrB4M4xB43oWAEydEFGFLfQ0PQTBsBwPD8IIwiiCgO0yEIIufZAfSoKZQSc5qZPjB9KRpBoEBWE0%2BSWNolRxAkgh%2BAEJTBPoeRu5EnvO9U7iJUUrPpG09uCCH1u0GU2QB10QetOUEfB208eu5wfQKPtwxcHNC1LStTNvYinhSpqUrcLMwDIMgswI6skgCrghAkEq4yJbMegw247eZ132vSCdWMXaQ123UIC2PaQstSuMqxmB3BTbJ5Uor2Y2zeM9G0LR9X2kD953/UDEBIAMBA%2BLzkMQNDPjg4nZyt4nCuMCwjOq%2BSYs%2BHLk%2BLU9xcLSOihQgCBZil3LpXautd67bEbsPX6o8aw1GUr/aestxhSkblKTwnhJAAE4pRzwIfg0K29Xq70UPvQ%2Bs0ro3TugtC2RcaZvXgedfOIxJD/2YRQ6ho92bEACBobgQA%3D"></iframe>
# reverse
### Target : reverse link all node
```c
node_t *reverse(node_t *head)
{
node_t *cursor = NULL;
while (head) {
node_t *next = head->next; // cache next
CCC; // link head to cursor and re assign cursor
head = next; // process next
}
return cursor;
}
```
### CCC
```c
head->next = cursor;
cursor = head;
```
### without return
```c
void reverse(node_t **headp)
{
node_t **cursor = headp;
node_t *head = *headp;
*cursor=NULL;
while (head) {
node_t *next = head->next; // cache next
head->next = *cursor;
*cursor = head;
head = next; // process next
}
}
```
# Fisher–Yates shuffle
The algorithm it self is not hard,
but it turns out pretty tricky to do with linked list.
```c
void FisherYatesShuffle(node_t **head)
{
int n = 0;
for (node_t *c = *head; c; ++n, c = c->next)
;
for (int i = n; i > 1; --i, head = &(*head)->next) {
node_t **target = head;
for (int s = rand() % i; s; --s, target = &(*target)->next)
;
swapNodes(head, target);
}
}
```
The swap node is much more complex than I thought, it take about 2 hours to do this, it is easier to think step by step in paper.
```c
void swapNodes(node_t **head, node_t **target)
{
if (head == target)
return;
```
swap pointer to node(next pointer of previous node)
```c
node_t *k = *head;
*head = *target;
*target = k;
```
swap next pointer of node
```c
k = (*target)->next;
(*target)->next = (*head)->next;
(*head)->next = k;
}
```