#07

// slistdemo1.c --- single-linked list demonstration
#include <stdio.h>
#include <stdlib.h>
struct node { double data; struct node *next; };
typedef struct node *nodep;

nodep node_new(double d, nodep n) {
  nodep p = (nodep)malloc(sizeof(struct node));
  p->data = d; p->next = n; return p;
}
void plist(nodep p) {
  while(p != NULL) { printf(" %g", p->data); p = p->next; }
  printf("\n");
}
nodep mklist(int n, char *a[]) {
  nodep p = NULL;
  for(int i = n-1; i >= 0; --i) { p = node_new(atof(a[i]), p); }
  return p;
}
int main(int argc, char *argv[]) {
  nodep p = mklist(argc-1, argv+1); plist(p);
  p->next->next = p->next->next->next; plist(p);
  p->next->next = node_new(1.0, p->next->next); plist(p);
  return 0;
}
void plist(nodep p) {
  if(p == NULL) { printf("\n"); return; }
  printf(" %g", p->data); plist(p->next);
}
nodep mklist(int n, char *a[]) {
  if(n == 0) { return NULL; }
  return node_new(atof(*a), mklist(n-1, a+1));
}
// listeditor.c --- single-linked list editor
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct node { double data; struct node *next; };
typedef struct node *nodep;

nodep node_new(double d, nodep n) {
  nodep p = (nodep)malloc(sizeof(struct node));
  p->data = d; p->next = n; return p;
}
nodep mklist(int n, char *a[]) {
  if(n == 0) { return NULL; }
  return node_new(atof(*a), mklist(n-1, a+1));
}
void plist(nodep p) {
  if(p == NULL) { printf("\n"); return; }
  printf(" %g", p->data); plist(p->next);
}
void nconc(nodep p, nodep q) {
  while(p != NULL && p->next != NULL) { p = p->next; }
  if(p != NULL) { p->next = q; }
}
void delnode(nodep p, int n) {
  while(--n > 0 && p != NULL) { p = p->next; }
  if(p != NULL && p->next != NULL) { p->next = p->next->next; }
}
nodep addlist(nodep x, nodep y) {
  if(x == NULL) { return y; }
  if(y == NULL) { return x; }
  return node_new(x->data+y->data, addlist(x->next, y->next));
}
bool getl(char s[], int lim) {
  int c, i = 0;
  for(c = getchar(); c != EOF && c != '\n'; c = getchar()) {
    s[i++] = c; if(i+1 >= lim) { break; }
  }
  s[i] = '\0'; return c != EOF;
}
int parse(char *a[], char *s) {
  int i, k = 0, len = strlen(s);
  for(i = 0; i < len; ++i) {
    if(s[i] == ' ') { s[i] = '\0'; }
    if(s[i] != '\0' && (i == 0 || s[i-1] == '\0')) { a[k++] = s+i; }
  }
  return k;
}
int main(int argc, char *argv[]) {
  char buf[200], *cmd[20];
  nodep list = NULL;
  while(true) {
    printf("> "); if(!getl(buf, 200)) { break; }
    int k = parse(cmd, buf);
    if(k > 0 && strcmp(cmd[0], "q") == 0) {
      break;
    } else if(k > 0 && strcmp(cmd[0], "e") == 0) { // enter list
      list = mklist(k-1, cmd+1);
    } else if(k > 0 && strcmp(cmd[0], "a") == 0) { // append list
      nconc(list, mklist(k-1, cmd+1));
    } else if(k > 1 && strcmp(cmd[0], "add") == 0) { // add list
      list = addlist(list, mklist(k-1, cmd+1));
    } else if(k > 1 && strcmp(cmd[0], "d") == 0) { // delete item
      delnode(list, atoi(cmd[1]));
    } else {
      plist(list);
    }
  }
  return 0;
}
// istack.h --- int type stack interface
#include <stdbool.h>
struct istack;
typedef struct istack *istackp;
istackp istack_new(int size); // allocate new stack
bool istack_isempty(istackp p); // test if the stack is empty
void istack_push(istackp p, int v); // push a value
int istack_pop(istackp p);      // pop a value and return it
int istack_top(istackp p);      // peek the topmost value
// iqueue.h --- int type queue interface
#include <stdbool.h>
struct iqueue;
typedef struct iqueue *iqueuep;
iqueuep iqueue_new(int size);
bool iqueue_isempty(iqueuep p);
bool iqueue_isfull(iqueuep p);
void iqueue_enq(iqueuep p, int v);
int iqueue_deq(iqueuep p);
// factdemo.c --- two fact function for gdb exercise.
#include <stdio.h>
#include <stdlib.h>
int fact1(int n) {
  int i, r = 1;
  for(i = 1; i <= n; ++i) {
    r *= i;
  }
  return r;
}
int fact2(int n) {
  if(n <= 0) { return 1; }
  int r = fact2(n-1);
  return n * r;
}
int main(int argc, char *argv[]) {
  int n = atoi(argv[1]);
  printf("fact1(%d) == %d\n", n, fact1(n));
  printf("fact2(%d) == %d\n", n, fact2(n));
  return 0;
}