fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5. #include <time.h>
  6.  
  7. #define LOG(...) printf(__VA_ARGS__);
  8.  
  9. typedef unsigned int uint;
  10. typedef uint64_t ulongint;
  11.  
  12. enum settings_list
  13. {
  14. MARKOVLVL = 3, //level of markov chain
  15. MAXTEXTSIZE = 10000, //maximal size of text
  16. AVERAGESENTENCESIZE = 7, //average size of sentence
  17. AVERAGELINESIZE = 15
  18. };
  19. /*
  20. ulongint hash_coefficients[13]={1,37,1369,50653,1874161,69343957,2565726409,94931877133,3512479453921,
  21. 129961739795077,4808584372417849,177917621779460413,6582952005840035281};*/
  22.  
  23.  
  24. ulongint hash_coefficients[13]={1, 31, 961, 29791, 923521, 28629151, 887503681, 27512614111, 852891037441,
  25. 26439622160671, 819628286980801, 25408476896404831, 787662783788549761};
  26. //int settings[sizeof(settings_list)];
  27.  
  28. char* delimeter_list[9] = {" ", "...", "?!", "?", ".", "!", ":", ";", ","};
  29. typedef struct suffix
  30. {
  31. char * text;
  32. struct suffix * next; //pointer to the next suffix
  33. uint suff_counter; //how many times this suffix appears
  34. uint eos_counter; //how many times this prefix was an end of sentence
  35. struct suffix * delimeter_list;
  36. } suffix;
  37.  
  38. void free_s_list(suffix ** suff)
  39. {
  40. if((*suff)->next == NULL)
  41. {
  42. free((*suff)->text);
  43. (*suff)->text = NULL;
  44. free((*suff));
  45. (*suff) = NULL;
  46. return;
  47. }
  48. else
  49. {
  50. free_s_list(&((*suff)->next));
  51. free_s_list(suff);
  52. }
  53. }
  54.  
  55.  
  56. typedef struct prefix
  57. {
  58. suffix * suffix_list;
  59. uint sl_size; //size of suffix list
  60. char * words[MARKOVLVL];
  61. uint counter; //how many times this prefix appears
  62. }prefix ;
  63.  
  64. char * get_delimeter(char * str)
  65. {
  66. char * tmp;
  67. for(int i = 1; i <= 8; i++)
  68. {
  69. tmp = strstr(str, delimeter_list[i]);
  70. if(tmp!=NULL && strlen(tmp) == strlen(delimeter_list[i]))
  71. return delimeter_list[i];
  72. }
  73. return delimeter_list[0]; //return space symbol
  74. }
  75.  
  76. int get_delimeter_index(char * str)
  77. {
  78. char * tmp;
  79. for(int i = 1; i <= 8; i++)
  80. {
  81. tmp = strstr(str, delimeter_list[i]);
  82. if(tmp!=NULL && strlen(tmp) == strlen(delimeter_list[i]))
  83. return i;
  84. }
  85. return 0; //return space symbol
  86. }
  87.  
  88. char * remove_delimeter(char * str)
  89. {
  90. int len = strlen(str);
  91. if(len == 0 || len == 1)
  92. return str;
  93. char * result;
  94. char * gd = get_delimeter(str);
  95. if(gd != NULL && strcmp(gd," ") != 0)
  96. {
  97. result = (char*) malloc(sizeof(char)*(len-strlen(gd)+1));
  98. strncpy(result, str, len-strlen(gd));
  99. /*for(int i = 0; i < len-strlen(gd); i++)
  100.   result[i] = str[i];*/
  101. result[len-strlen(gd)] = '\0';
  102. }
  103. else
  104. {
  105. if(str[0] == '\"' && str[len-1] == '\"')
  106. {
  107. result = (char*) malloc(sizeof(char)*(len-2+1));
  108. for(int i = 1; i < len-1; i++)
  109. result[i-1] = str[i];
  110. result[len-2] = '\0';
  111. }
  112. else if(str[0] == '\"')
  113. {
  114. result = (char*) malloc(sizeof(char)*(len-1+1));
  115. for(int i = 1; i <= len-1; i++)
  116. result[i-1] = str[i];
  117. result[len-1] = '\0';
  118. }
  119. else if(str[len-1] == '\"')
  120. {
  121. result = (char*) malloc(sizeof(char)*(len-1+1));
  122. for(int i = 0; i < len-1; i++)
  123. result[i] = str[i];
  124. result[len-1] = '\0';
  125. }
  126. else
  127. {
  128. result = (char*) malloc(sizeof(char)*(len+1));
  129. strcpy(result, str);
  130. result[len] = '\0';
  131. }
  132. }
  133. return result;
  134. }
  135.  
  136. uint is_eos_delimeter(char * delim)
  137. {
  138. if(strcmp(delim,"!") == 0 || strcmp(delim,"?") == 0 ||
  139. strcmp(delim,".") == 0 || strcmp(delim,"?!") == 0 ||
  140. strcmp(delim,"...") == 0)
  141. return 1;
  142. else return 0;
  143. }
  144.  
  145. char * lower(char * str) //locale-dependend function
  146. {
  147. if(str[0] <= 'Z' && str[0] >= 'A')
  148. str[0] += 'a'-'A';
  149. return str;
  150. }
  151.  
  152. char * higher(char * str) //locale-dependend function
  153. {
  154. if(str[0] <= 'z' && str[0] >= 'A')
  155. str[0] -= 'a'-'A';
  156. return str;
  157. }
  158.  
  159. prefix * create_prefix(char * pref[MARKOVLVL], char * suff)
  160. {
  161. LOG("IN CREATE_PREFIX FUNCTION\n");
  162. LOG("Allocating memory for result\n");
  163. prefix * result = (prefix*) malloc(sizeof(prefix));
  164. char * temp;
  165. temp = remove_delimeter(suff);
  166. LOG("Allocating memory for suffix_list\n");
  167. result->suffix_list = (suffix*) malloc(sizeof(suffix));
  168. result->suffix_list->next = NULL;
  169. LOG("Allocating memory for suffix_list->text\n");
  170. result->suffix_list->text = (char*) malloc(strlen(temp)+1);
  171. result->suffix_list->suff_counter = 1;
  172. LOG("Allocating memory for suffix_list->delimeter_list\n");
  173. result->suffix_list->delimeter_list = (suffix*) malloc(sizeof(suffix));
  174. result->suffix_list->delimeter_list->next = NULL;
  175. result->suffix_list->delimeter_list->text = get_delimeter(suff);
  176. result->suffix_list->delimeter_list->suff_counter = 1;
  177. if(is_eos_delimeter(result->suffix_list->delimeter_list->text) == 1)
  178. {
  179. result->suffix_list->delimeter_list->eos_counter = 1;
  180. result->suffix_list->eos_counter = 1;
  181. }
  182. //strcpy(result->suffix_list->text,lower(temp));
  183. strcpy(result->suffix_list->text,temp);
  184. /*if(is_eos_delimeter(get_delimeter(pref[MARKOVLVL-1])) == 0)
  185. {
  186. LOG("Copying LOWER suffix\n");
  187. strcpy(result->suffix_list->text,lower(temp));
  188. }
  189. else
  190. {
  191. LOG("Copying suffix\n");
  192. strcpy(result->suffix_list->text,temp);
  193. }*/
  194. //LOG("SUFFIX:%s\n TEMPORARY STRING:%s\n",suff,temp);
  195. LOG("Freeing temp memory\n");
  196. free(temp);
  197. for(int i = 0; i < MARKOVLVL; i++)
  198. {
  199. //temp = remove_delimeter(lower(pref[i]));
  200. temp = remove_delimeter(pref[i]);
  201. //LOG("SUFFIX:%s\n TEMPORARY STRING:%s\n",suff,temp);
  202. LOG("Allocating memory for result->words[%d]\n", i);
  203. result->words[i] = (char*) malloc(strlen(temp)+1);
  204. strcpy(result->words[i], temp);
  205. LOG("Freeing temp memory\n");
  206. free(temp);
  207. }
  208. //LOG("SUFFIX:%s\n",suff);
  209. result->counter = 1;
  210. result->sl_size = 1;
  211. LOG("Returning result\n");
  212. return result;
  213. }
  214.  
  215. void delete_prefix(prefix ** pref)
  216. {
  217. if((*pref)->suffix_list != NULL)
  218. free_s_list(&((*pref)->suffix_list));
  219. for(int i = 0; i < MARKOVLVL; i++)
  220. {
  221. if((*pref)->words[i] != NULL)
  222. free((*pref)->words[i]);
  223. }
  224. if((*pref) != NULL)
  225. free((*pref));
  226. }
  227.  
  228. void add_delimeter(suffix * suff, int delim_index)
  229. {
  230. char * delim = delimeter_list[delim_index];
  231. if(is_eos_delimeter(delim) == 1)
  232. suff->eos_counter += 1;
  233. suffix * dlist;
  234. dlist = suff->delimeter_list;
  235. if(dlist != NULL)
  236. {
  237. for(int i = 0; i < suff->suff_counter;)
  238. {
  239. if(strcmp(dlist->text, delim) == 0)
  240. {
  241. dlist->suff_counter +=1;
  242. return;
  243. }
  244. i += dlist->suff_counter;
  245. if(dlist->next == NULL)
  246. {
  247. dlist->next = (suffix*) malloc(sizeof(suffix));
  248. dlist = dlist->next;
  249. break;
  250. }
  251. }
  252. }
  253. else
  254. {
  255. dlist = (suffix*) malloc(sizeof(suffix));
  256. }
  257. dlist->next = NULL;
  258. suff->suff_counter += 1;
  259. dlist->suff_counter = 1;
  260. dlist->text = delim;
  261. }
  262.  
  263. void add_suffix(prefix * pref, char * suff, int delim_index, int is_pref_eos)
  264. {
  265. suffix * suf = pref->suffix_list;
  266. for(int i = 0; i < pref->sl_size;)
  267. {
  268. if(strcmp(suf->text, suff) == 0)
  269. {
  270. add_delimeter(suf, delim_index);
  271. suf->suff_counter += 1;
  272. pref->sl_size++;
  273. return;
  274. }
  275. i+=suf->suff_counter;
  276. if( suf->next == NULL)
  277. {
  278. suf->next =(suffix*) malloc(sizeof(suffix));
  279. suf = suf->next;
  280. break;
  281. }
  282. }
  283. pref->sl_size++;
  284. suf->next = NULL;
  285. suf->text = (char*) malloc(strlen(suff)+1);
  286. /*if(is_pref_eos == 1)
  287.   strcpy(suf->text, lower(suff));
  288.   else
  289.   strcpy(suf->text, suff);*/
  290. strcpy(suf->text, suff);
  291. suf->suff_counter = 1;
  292. pref->counter += 1;
  293. }
  294.  
  295. suffix * get_random_suffix(suffix * suffix_list, int sl_size)
  296. {
  297. if(suffix_list == NULL ||sl_size == 0)
  298. return NULL;
  299. int randint = rand() % sl_size;
  300. suffix * suf = suffix_list;
  301. for(int i = 0; i < sl_size;)
  302. {
  303. randint -= suf->suff_counter;
  304. if(randint < 0 || suf->next == NULL)
  305. break;
  306. }
  307. return suf;
  308. }
  309.  
  310. prefix empty_prefix = {NULL,0,{NULL,NULL,NULL},0};
  311.  
  312. typedef struct bt_node
  313. {
  314. struct bt_node * left;
  315. struct bt_node * right;
  316. //bt_node * parent;
  317. ulongint key;
  318. prefix * value;
  319. } bt_node;
  320.  
  321. bt_node * bt_add(bt_node * root, char * pref[MARKOVLVL], ulongint pref_hash, char * suff)
  322. {
  323. LOG("IN BT_ADD FUNCTION\n");
  324. if(root == NULL)
  325. {
  326. root = (bt_node*) malloc(sizeof(bt_node));
  327. root->left = NULL;
  328. root->right = NULL;
  329. //root->parent = NULL;
  330. root->key = pref_hash;
  331. LOG("Going to CREATE_PREFIX\n");
  332. root->value = create_prefix(pref, suff);
  333. }
  334. else if(pref_hash < root->key)
  335. {
  336. root->left = bt_add(root->left, pref, pref_hash, suff);
  337. }
  338. else if(pref_hash > root->key)
  339. {
  340. root->right = bt_add(root->right, pref, pref_hash, suff);
  341. }
  342. else if(pref_hash == root->key)
  343. {
  344. LOG("Going to ADD_SUFFIX\n");
  345. add_suffix(root->value, remove_delimeter(suff), get_delimeter_index(suff), is_eos_delimeter(get_delimeter(pref[MARKOVLVL-1])));
  346. }
  347. return root;
  348. }
  349.  
  350. bt_node * bt_search(bt_node * root, ulongint key)
  351. {
  352. if(root == NULL)
  353. return NULL;
  354. else if(key < root->key)
  355. return bt_search(root->left, key);
  356. else if(key > root->key)
  357. return bt_search(root->right,key);
  358. else if(key == root->key)
  359. return root;
  360. return NULL;
  361. }
  362.  
  363. void bt_delete(bt_node ** root)
  364. {
  365. if((*root)->left!=NULL)
  366. bt_delete(&((*root)->left));
  367. else if((*root)->right!=NULL)
  368. bt_delete(&((*root)->right));
  369. else
  370. free(*root);
  371. }
  372.  
  373. prefix * bt_get_random_prefix(bt_node * root, ulongint rnd)
  374. {
  375. if(rnd - rand() == 0 || (root->left == NULL && root->right == NULL))
  376. return root->value;
  377. //else if((root->key - rnd) == rnd || (root->key == rnd))
  378. // return root->value;
  379. else if(rnd - rand() > 0)
  380. return bt_get_random_prefix(root->right, rnd);
  381. else
  382. return bt_get_random_prefix(root->left, rnd);
  383. }
  384.  
  385. ulongint hash(char * str)
  386. {
  387. int numlen = strlen(str);
  388. ulongint result = 0;
  389. for(int i = 0; i < numlen; i++)
  390. result += (str[i] + 1)*hash_coefficients[i%13];
  391. return result;
  392. }
  393.  
  394. ulongint prefix_hash(char * pref[MARKOVLVL])
  395. {
  396. ulongint result = 0;
  397. for(int i = 0; i < MARKOVLVL; i++)
  398. result += hash(pref[i])*(i+2);
  399. return result;
  400. }
  401.  
  402. char * read_word(FILE * fd)
  403. {
  404. int max_size = 5, cur_size = 0;
  405. char * result =(char *) malloc(max_size*sizeof(char));
  406. char ch = fgetc(fd);
  407. while(ch != EOF && ch != '\n' && ch != ' ' && ch != '\t')
  408. {
  409. if(cur_size >= max_size)
  410. {
  411. max_size *= 2;
  412. result = (char * ) realloc(result, max_size*sizeof(char));
  413. }
  414. result[cur_size] = ch;
  415. cur_size++;
  416. ch = fgetc(fd);
  417. }
  418. if(cur_size == 0)
  419. {
  420. free(result);
  421. return NULL;
  422. }
  423. else
  424. {
  425. result = (char*) realloc(result, ((cur_size+1)*sizeof(char)));
  426. result[cur_size] = '\0';
  427. }
  428. return result;
  429. }
  430.  
  431. bt_node * generate_tree(FILE * fd)
  432. {
  433. bt_node * root = NULL;
  434. char * pref[MARKOVLVL];
  435. char * suf;
  436. char * temp;
  437. LOG("Initial fd reading\n");
  438. for(int i = 0; i < MARKOVLVL; i++)
  439. {
  440. pref[i] = read_word(fd);
  441. if(pref[i] == NULL)
  442. {
  443. LOG("Input file reading error. Exiting");
  444. exit(1);
  445. return NULL;
  446. }
  447. }
  448. while(1)
  449. {
  450. LOG("Reading suffix\n");
  451. suf = read_word(fd);
  452. LOG("Suffix is %s\n", suf);
  453. if(suf == NULL)
  454. {
  455. if(feof(fd))
  456. break;
  457. else
  458. continue;
  459. }
  460. LOG("Adding suffix to tree\n");
  461. root = bt_add(root, pref, prefix_hash(pref), suf);
  462. LOG("Suffix was succesfully added\n");
  463. LOG("Freeing pref[0] memory\n");
  464. free(pref[0]);
  465. for(int i = 0; i < MARKOVLVL-1; i++)
  466. {
  467. pref[i] = pref[i+1];
  468. }
  469. /*for(int i = 0; i < MARKOVLVL; i++)
  470. LOG("PREFIX[%d]: %s\n",i,pref[i]);*/
  471. LOG("Removing delimeter from suffix\n");
  472. temp = remove_delimeter(suf);
  473. pref[MARKOVLVL-1] = temp;
  474. LOG("Freeing suffix memory\n");
  475. free(suf);
  476. }
  477. for(int i = 0; i < MARKOVLVL; i++)
  478. if(pref[i] != NULL)
  479. free(pref[i]);
  480. free(suf);
  481. return root;
  482. }
  483.  
  484. void generate_text(bt_node * root, FILE * fd, uint text_size)
  485. {
  486. LOG("IN GENERATE_TEXT FUNCTION\n");
  487. if(root == NULL)
  488. return;
  489. char * pref[MARKOVLVL];
  490. LOG("Getting random prefix\n");
  491. prefix * cur_pref = bt_get_random_prefix(root, rand());
  492. for(int i = 0; i < MARKOVLVL; i++)
  493. {
  494. pref[i] = cur_pref->words[i];
  495. fprintf(fd, "%s ", pref[i]);
  496. }
  497. LOG("Getting random suffix\n");
  498. suffix * t_suf = get_random_suffix(cur_pref->suffix_list, cur_pref->sl_size);
  499. char * suf = t_suf->text;
  500. char * delim = (get_random_suffix(t_suf->delimeter_list, t_suf->suff_counter))->text;
  501. uint ls_counter = MARKOVLVL+1; //current line size counter
  502. uint txt_counter = MARKOVLVL+1; //current text size counter
  503. uint sent_counter = MARKOVLVL+1;
  504. fprintf(fd, "%s ", suf);
  505. uint eos_flag = 0;
  506. while(txt_counter < text_size && txt_counter < MAXTEXTSIZE)
  507. {
  508. if(ls_counter > AVERAGELINESIZE)
  509. {
  510. fprintf(fd, "\b\n");
  511. ls_counter = 1;
  512. }
  513. for(int i = 0; i < MARKOVLVL-1; i++)
  514. {
  515. pref[i] = pref[i+1];
  516. }
  517. pref[MARKOVLVL-1] = suf;
  518. LOG("Searching for prefix\n");
  519. cur_pref = (bt_search(root, prefix_hash(pref)))->value;
  520. LOG("Getting random suffix\n");
  521. t_suf = get_random_suffix(cur_pref->suffix_list, cur_pref->sl_size);
  522. suf = t_suf->text;
  523. if(sent_counter > AVERAGESENTENCESIZE)
  524. {
  525. delim = delimeter_list[rand()%5 +1];
  526. sent_counter = 0;
  527. eos_flag = 0;
  528. }
  529. else
  530. {
  531. delim = (get_random_suffix(t_suf->delimeter_list, t_suf->suff_counter))->text;
  532. if(is_eos_delimeter(delim) == 1)
  533. {
  534. sent_counter = 0;
  535. eos_flag = 0;
  536. }
  537. else
  538. eos_flag++;
  539. }/*
  540. if(eos_flag == 1)
  541. {
  542. if(strcmp(delim, " ") == 0)
  543. fprintf(fd, "%s ", higher(suf));
  544. else
  545. fprintf(fd, "%s%s ", higher(suf), delim);
  546. }
  547. else
  548. {*/
  549. if(strcmp(delim, " ") == 0)
  550. fprintf(fd, "%s ", suf);
  551. else
  552. fprintf(fd, "%s%s ", suf, delim);
  553. //}
  554. txt_counter++;
  555. ls_counter++;
  556. sent_counter++;
  557. }
  558.  
  559. }
  560.  
  561. int main(void)
  562. {
  563. /*settings[MARKOVLVL] = 3;
  564.   settings[HASHSIZE] = 10000;
  565.   settings[MAXTEXTSIZE] = 10000;
  566.   settings[AVERAGESENTENCESIZE] = 7;*/
  567. //char * somestr[MARKOVLVL] = {"some","shitty","string"};
  568. //prefix * pref = create_prefix(somestr, "wow");
  569. // add_suffix(pref, "wow");
  570. // add_suffix(pref, "notwow");
  571. // suffix* suff = pref->suffix_list;
  572. // while(suff != NULL)
  573. // {
  574. // LOG("%s\n",suff->text);
  575. // if(suff->next == NULL)
  576. // break;
  577. // else
  578. // suff = suff->next;
  579. // }
  580. // delete_prefix(&pref);
  581. srand(time(NULL));
  582. /*FILE * fd = fopen("C:\\Users\\sai\\Documents\\Visual Studio 2010\\Projects\\markov_chain\\markov_chain\\input_01.txt", "r");
  583.   FILE * fd1 = fopen("C:\\Users\\sai\\Documents\\Visual Studio 2010\\Projects\\markov_chain\\markov_chain\\output_01.txt", "w");
  584.   if(fd == NULL)
  585.   {
  586.   LOG("Couldn\'t open file");
  587.   getchar();
  588.   exit(1);
  589.   }*/
  590. LOG("Going to tree building\n");
  591. bt_node * root = generate_tree(stdin);
  592. LOG("Going to text generation\n");
  593. generate_text(root, stdout, 100);
  594. bt_delete(&root);
  595. /*char * str = (char *) malloc(7);
  596.   scanf("%s",str);
  597.   printf("%s\n",str);
  598.   str = lower(str);
  599.   printf("%s\n", str);
  600.   getchar();*/
  601. getchar();
  602. return 0;
  603. }
  604.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Not long after we moved to Paris, in the fall of 1995, my wife, Martha, and I saw, in the window of a shop on the rue Saint-Sulpice, a nineteenth-century engraving, done in the manner, though I'm now inclined to think not from the hand, of Daumier. It shows a train on its way from the Right Bank of Paris to the moon. The train has a steam locomotive and six cars, and it is chugging up a pretty steep track. The track is supported on two high, slender spires that seem to be anchored somewhere in the Fifth Arrondissement (you can see the Pantheon in silhouette nearby), and then the track just goes right up and touches the full moon up in the clouds. I suppose the two pillars are stronger than they look. The train is departing at twilight-presumably its an overnight trip-and among the crowd on the ground below, only a couple of top-hatted bourgeois watch the lunar ex-press go on its way with any interest, much less wonder. Every-body else in the crowd of thirteen or so people on the platform,

4
mostly moms and dads and kids, are running around and making conversation and comforting children and buying tickets for the next trip and doing all the things people still do on station plat-forms in Paris. The device on the ticket window, like the title of the cartoon, reads: "A Railroad: From Paris to the Moon."
The cartoon is, in part, a satire on the stock market of the time and on railway share manipulations. ("Industry," the caption be-gins, "knows no more obstacles.") But the image cast its spell on us, at least, because it seemed to represent two notions, or ro-mances, that had made us want to leave New York and come to Paris in the first place. One was the old nineteenth-century vi-sion of Paris as the naturally modern place, the place where the future was going to happen as surely as it would happen in New York. If a train were going to run to the moon, that train would originate from the Gare du Nord, with Parisian kids getting worn out while they waited.
But the image represented another, more intense association, and that is the idea that there is, for some Americans anyway, a direct path between the sublunary city and a celestial state. Americans, Henry James wrote, "are too apt to think that Paris is the celestial city," and even if we don't quite think that, some of us do think of it as the place where tickets are sold for the train to get you there. (Ben Franklin thought this, and so did Gertrude Stein, and so did Henry Miller. It's a roomy idea.) If this notion is pretty obviously unreal, and even hair-raisingly naive, it has at least the excuse of not being original. When they die, Wilde wrote, all good Americans go to Paris. Some of us have always tried to get there early and beat the crowds.
I've wanted to live in Paris since I was eight. I had a lot of pic-tures of the place in my head and even a Parisian object, what I suppose I'd have to call an icon, in my bedroom. Sometime in the mid-sixties my mother, who has a flair for the odd, ready-made present, found-I suppose in an Air France office in Philadelphia-a life-size cardboard three-dimensional cutout of

5
a Parisian policeman. He had on a blue uniform and red kepi and blue cape, and he wore a handlebar mustache and a smile. (The smile suggests how much Art, or at any rate Air France, improves on Life, or at any rate on Paris policemen.)
My younger brother and I called the policeman Pierre, and he kept watch over our room, which also had Beatle posters and a blindingly, numbingly, excruciatingly bright red shag rug. (I had been allowed to choose the color from a choice of swatches, but I have an inability to generalize and have always made bad, over-bright guesses on curtains and carpets and, as it turned out, the shape of future events.) Although we had never gone anywhere interesting but New York, my older sister had already, on the basis of deep, illicit late-night reading of Jane Austen and Mary Poppins, claimed London, and I had been given Paris, partly as a consolation prize, partly because it interested me. (New York, I think, was an open city, to be divided between us, like Danzig. Our four younger brothers and sisters were given lesser princi-palities. We actually expected them to live in Philadelphia.)
My first images of Paris had come from the book adaptation of The Red Balloon, the wonderful Albert Lamorisse movie about a small boy in the Parisian neighborhood of Menilmontant who gets a magic, slightly overeager balloon, which follows him every-where and is at last destroyed by evil boys with rocks. Curiously, it was neither a cozy nor a charming landscape. The Parisian grown-ups all treated Pascal, the boy, with a severity bordering on outright cruelty: His mother tosses the balloon right out of the Haussmannian apartment; the bus conductor shakes his head and finger and refuses to allow the balloon on the tram; the prin-cipal of the school locks him in a shed for bringing the balloon to class. The only genuine pleasure I recall that he finds in this un-smiling and rainy universe is when he leaves the balloon outside a tempting-looking bakery and goes in to buy a cake. The insou-ciance with which he does it-cake as a right, not a pleasure- impressed me a lot. A scowling gray universe relieved by pastry:

6  
This was my first impression of Paris, and of them all, it was not the farthest from the truth. To this set of images were added, soon after, the overbright streets of the Madeline books, covered with vines and the little girls neat in their rows, and black and white pictures of men in suits walking through the Palais Royale, taken from a Cartier-Bresson book on the coffee table.
Pierre, though, being made of cardboard, got pretty beat up, sharing a room with two young boys, or maybe he was just both smaller and more fragile than I recall. In any case, one summer evening my parents, in a completely atypical display of hygienic decisiveness, decided that he was too beat up to keep and that it was time for him to pass away, and they put him out on the Philadelphia street for the trashman to take away.
I wept all night. He would sit out with the trash cans and would not be there in the morning. (A little later I read about Captain Dreyfus and his degradation, and the two uniformed and mustachioed figures got mixed up, so perhaps he had been sent to supply intimations of the other, darker side of French life. They were certainly there to be intimated.) What made me sad just then was the new knowledge that things changed, and there was nothing you could do about it. In a way, that was a Parisian emotion too.
***
I saw the real-or anyway the physical-Paris for the first time in 1973, when I was in my early teens. I had arrived with my large, strange family, those five brothers and sisters, and a couple of hangers-on and boyfriends. There were eight of us in the back of a Citroen station wagon. I was the one with the bad adoles-cent mustache. My parents, college professors, were on sabbati-cal, at a time, just weeks before the oil crunch, when the great good wave that had lifted up college professors into the upper middle classes was still rising. At the time we all lived in Mon-treal, and my brothers and sisters went to a French private acad-

 7
emy there actually run by the French government. The corridors in the school were named after Parisian streets: The Champs-Elysees led the way to the principal's office, and you took the rue Royale to the cafeteria for lunch. I was the only one in an English-speaking school and became oddly, or maybe not so oddly, the only one to fall entirely in love with France. (You can never forget, I suppose, that the Champs-Elysees once led the way to the principals office.)
We came in through one of the portes of Paris, the doors that are now merely exits from the peripheral expressway but that still keep the names of the real gates of the old walled city. It was probably the portes d'Orleans. I saw a girl lean over to kiss a friend on a stopped motorbike on the cheek, twice, here and then there. The trees cast patterned light on the street. We went out for dinner and, for fifteen francs, had the best meal I had ever eaten, and most of all, nobody who lived there seemed to notice or care. The beauty and the braised trout alike were just part of life, the way we do things here.
We had spent the previous three days in London. Though the taxis were black and the buses red and Regent's Park green, the familiar street names seemed curiously to belong to another civ-ilization, as though the city had been occupied once by another and more vivid, imperial race and had then been turned over to the pallid, gray people on the streets, who ate sandwiches that turned up at the edges. Paris, on the other hand, looked exactly as it was supposed to look. It wore its heart on its sleeve, and the strange thing was that the heart it wore so openly was in other ways so closed-mysterious, uninviting.
We settled in for a long winter. While my parents taught, I spent most of my time going to the movies with my cousin Philippe. You are supposed to be in love with Paris and Philippe and I were both in love. I was in love with Jacqueline Bisset, and he was in love with Dominique Sanda. We went to the movies all the time, looking for them both. I remember finding a fifth-run

8   
movie theater someplace in the Nineteenth Arrondissement, deep in a poor Algerian neighborhood, just in order to see Jacqueline's brief, heart-searing part in The Life and Times of Judge Roy Bean.
Almost incidentally, in love with Jacqueline Bisset, I fell in love with Paris. Paris-and this is the tricky thing-though it is always and indubitably itself, is also in its nature a difficult city to love for itself alone. What truly makes Paris beautiful is the in-termingling of the monumental and the personal, the abstract and the footsore particular, it and you. A city of vast and imper-sonal set piece architecture, it is also a city of small and intricate, improvised experience. My favorite architectural detail in Paris is the little entrance up the rue de Seine, a tiny archway where, as I have since found out, you can push a poussette right through and get to the grand Institut de France. You aren't looking at it; and then you and the poussette are in it, right in the driveway where the academicians go. For a moment you are it. The Insti-tut belongs to you. Ten steps more and you are on the pont des Arts. The passage from the big to the little is what makes Paris beautiful, and you have to be prepared to be small-to live, to trudge, to have your head down in melancholy and then lift it up, sideways-to get it.
What is true for academicians is true for adolescents with a fixation on Jacqueline Bisset. I saw Paris out of the corner of my eye, on my way to the movies, and so a love for Paris came to be one of the strongest emotions I possess. In addition, my father's friend the literary critic and pioneer deconstructionist Eugenio Donato brought me to a seminar that Roland Barthes was giving that spring. I didn't understand a word. (A few years later I met one of the French students in the class, and found out that she hadn't understood a word either.) Then we went home, back to Montreal, where my brothers and sisters returned to that French academy, and I kept my French sharp by reading the sports pages every day about the Montreal Canadiens.

9
Two years after that first year in Paris, I used the tiny lever of my knowledge of the city to induce-I still won't say deceive-a girl a real girl, I had fallen in love with into running away to Paris with me. Martha, who became and, twenty-five years later, re-mains - and I write these words with a stunned disbelief, shared only by her mother-my wife, loved Paris as much as I did, even though many of the advertised attractions-the seminar with my friend Roland Barthes, for instance-that I had promised her were suspiciously missing from our trip. If she noticed this or was bothered by it, she hasn't mentioned it yet. We spent a happy week in the Hotel Welcome on the boulevard Saint-Germain. The hidden humanism of the classical style, the idea of the intellectual as magician and stylist, and sex in a hotel room: These were the things I took away from a childhood spent continually in a made-up Paris and an adolescence spent, fitfully, in the real one.
***
For a long time New York intervened. Then, in the late eighties, we began to think about Paris again. We sat on the deck of a rented house in Cape Cod and, listening to old Charles Trenet records, thought. . . why not? (This was neither a hard leap nor an interesting one, since the Trenet songs we were listening to had the theme of Paris pretty much to the exclusion of every other human concept.) We watched The Umbrellas of Cherbourg over and over. We visited Paris whenever we could, as often as we could. We weren't Francophiles because we didn't know any-thing about France, and still don't. We were just crazy about Paris.
When our son, Luke Auden, was born, in September 1994, we knew that we would have to go to Paris soon, or we wouldn't go at all. In five years, everybody told us, he would no longer be "portable." When we were in Paris, we had hung around the parks and gardens, watching the carousels turn and the children

10
play and thinking, This would be a nice place to be a child or have one. We also saw all the aspects of a New York childhood that looked less delightful. You would see the five-year-olds at a friend's house already lost in the American media, simultane-ously listening to a Walkman, playing with a Game Boy, and watching a video on the VCR. Perhaps, we thought-however foolishly, however "unrealistically"-we could protect him from some of that if he spent his first five years in Paris.
"You can't run away from (a) reality, (b) American culture, (c) yourself," our friends all said, compositely. "But you can run away," we said under our breaths, and we did. We thought we might stay for good, but we knew that we would certainly stay for the last five years of the century; "We'll stay till the millennium," we could say grandly, and mean it cautiously. The New Yorker, where I worked, was ready to hear what I had to say about Parisian scenes and, more important, was willing to keep sending non-Parisian subjects, from Groucho Marx to the Starr Report, my way too, which let us pay Parisian rates. Martha, for her part, had become a filmmaker, and she had the great portable occupa-tion of the late twentieth century, a screenplay to write (and rewrite and rewrite again). So we went.
The New Yorker has had lots of good writers in place in Paris, but it was James Thurber, whose blind eyes in a photograph on my desk stare at me every morning, whose writing moved me most. Thurber, though he hardly spoke a word of French, wrote once that the surface of manners in France seemed to him the most beautiful in the world, and he was right. The romance of Paris was my subject, and if it is a moony or even a loony one, it is at least the one I get, a little.
This was a hard romance to sustain in most of the last five years, when almost everybody else thought that Paris was going straight to hell. When we first started dreaming of coming to Paris, around 1989, long-termist, infrastructure-building Eu-rope, many people said, owned the future. One only had to com-

11
pare JFK and Charles de Gaulle airports, the one named after the vital young internationalist and the other after the old reac-tionary, to catch the irony JFK was decrepit, dangerous, and al-most unpoliced; you stumbled off your plane into, of all bizarre things, a linoleum staircase, with a sign above warning you of il-legal livery drivers (whose complexions, delicately, had been made neither black nor white but swarthy, like Barbary Coast pirates). You took a taxi over roads so potholed that the infra-structure was visibly rusted out, ruined. At Charles de Gaulle Airport, on the other hand, you came to a breathtakingly modern terminal, full of odd glass corridors and long, radiating, covered walkways, and exited onto a highway so up-to-date that regular announcements of upcoming traffic were posted along with the waiting time for a reservation at the Brasserie Lipp. No one will believe this now, but that is how it seemed then. (Popular mem-ory may be short, but it is nothing compared with the amnesia of experts.)
By 1995 all that had changed, and Paris and France seemed left out of the new all-American dispensation. London, of all places, had become the town where people went to see new art and taste new cooking. For the first time in modern history it was actually possible to live in Paris for comfort and bourgeois secu-rity and travel to London for food and sex. (My cousin Philippe had, like so many ambitious Frenchmen of his generation, actu-ally fled Paris for London, where he had made a small fortune in banking and was about to finance his own restaurant.)
The failure of the French model and the triumph of the Anglo-American one is by now a sorry, often repeated fact. For five years hardly anyone wrote about Paris and the French except in a tone of diagnosis: how sick they were, when they got so sick, why they denied that they were sick, and if there was any chance that they would ever get better. (No.) Many journalistic tours d'horizons have been written in the last few years-"Whither France?" and "Whether France ..." and "Weathering France,"

and "France: How It Withers" and "Withering France." We surf the waves of capitalism, from crest to trough and back again, but the funny thing is that no matter how often we ride the wave, no-body notices that it's wet. When we are on the crest, we believe that we have climbed a mountain through our own virtuous ef-forts, and when we are in the trough, we believe that we have fallen into a pit through our own vice.
Whatever else might be true, though, in the last five years of the century, as the world became, by popular report, more "glob-alized" than it had ever been before, France became more differ-ent. "They order these matters better in France," Sterne's opening line for his sentimental journey in France, had a new ring, now. For most of two centuries, after all, what had been so different about France was how central and cosmopolitan it was. Ameri-cans had been going to Paris for a couple of centuries to learn a universal diplomatic language and the central artistic culture and even the most influential manner of cooking. Yet in the time we were there Paris seemed to pass from the place where you learned how to do it to the place where you learned how not to do it-how not to do it in the ordinary American imperial way, the place where you learned how to do it, as the French like to say, autrement, otherly. From the kind of sympathy that labor unions get from their public to the length of time you take to eat lunch, the way it's done in Paris now is not the way it's done in Adelaide or Toronto or Los Angeles or Tempe or Hong Kong or any of the studs on the broad belt of the English-speaking imperium that now encircles the world, with New York as its buckle. Americans still learn about differences in Paris, but now we learn about them not because we are so much closer to the center of things but because we are so much farther away. The light of Paris still shows Americans things as they are (if not as they really are) by showing us how things can look different in a different light, but the light it shows them with now is more mys-terious and singular, a kind of moral moonlight, a little bit harder to see by.
compilation info
prog.cpp:24: error: integer constant is too large for ‘long’ type
prog.cpp:24: error: integer constant is too large for ‘long’ type
prog.cpp:25: error: integer constant is too large for ‘long’ type
prog.cpp:25: error: integer constant is too large for ‘long’ type
prog.cpp:25: error: integer constant is too large for ‘long’ type
prog.cpp:25: error: integer constant is too large for ‘long’ type
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp:28: warning: deprecated conversion from string constant to ‘char*’
prog.cpp: In function ‘void add_delimeter(suffix*, int)’:
prog.cpp:237: warning: comparison between signed and unsigned integer expressions
prog.cpp: In function ‘void add_suffix(prefix*, char*, int, int)’:
prog.cpp:266: warning: comparison between signed and unsigned integer expressions
stdout
Standard output is empty