-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrss.xml
More file actions
799 lines (709 loc) · 187 KB
/
rss.xml
File metadata and controls
799 lines (709 loc) · 187 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>http://www.infectmac.com/</title><link>http://www.infectmac.com/</link><description>a blog of fun</description><lastBuildDate>Sun, 27 May 2012 01:11:34 GMT</lastBuildDate><generator>PyRSS2Gen-1.0.0</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>have you tried turning it on and off again: libxpc</title><link>http://www.infectmac.com/posts/2011-12-20-6-3-have-you-tried-turning-it-on-and-off-again:-libxpc.html</link><description><p>There was a weird hang we were seeing in <a href="http://itunes.apple.com/us/app/float-reader/id447992005?ls=1&amp;mt=8">Float</a>. It would occur anytime a text field became the first responder. The issue could be reproduced with our development build as well as the live app store build. The hang had the following frames at the top of the callstack for the main thread:</p>
<div class="codehilite"><pre><span class="mi">0</span> <span class="n">libsystem_kernel</span><span class="o">.</span><span class="n">dylib</span> <span class="n">mach_msg_trap</span> <span class="p">(</span><span class="n">in</span> <span class="n">libsystem_kernel</span><span class="o">.</span><span class="n">dylib</span><span class="p">)</span> <span class="o">+</span> <span class="mi">20</span>
<span class="mi">1</span> <span class="n">libsystem_kernel</span><span class="o">.</span><span class="n">dylib</span> <span class="n">mach_msg</span> <span class="p">(</span><span class="n">in</span> <span class="n">libsystem_kernel</span><span class="o">.</span><span class="n">dylib</span><span class="p">)</span> <span class="o">+</span> <span class="mi">50</span>
<span class="mi">2</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span> <span class="n">_xpc_connection_check_in</span> <span class="p">(</span><span class="n">in</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span><span class="p">)</span> <span class="o">+</span> <span class="mi">152</span>
<span class="mi">3</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span> <span class="n">_xpc_connection_init</span> <span class="p">(</span><span class="n">in</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1032</span>
<span class="mi">4</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span> <span class="n">_xpc_connection_wakeup2</span> <span class="p">(</span><span class="n">in</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span><span class="p">)</span> <span class="o">+</span> <span class="mi">774</span>
<span class="mi">5</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span> <span class="n">_xpc_connection_wakeup</span> <span class="p">(</span><span class="n">in</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span><span class="p">)</span> <span class="o">+</span> <span class="mi">62</span>
<span class="mi">6</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span> <span class="n">_xpc_connection_send_registration</span> <span class="p">(</span><span class="n">in</span> <span class="n">libxpc</span><span class="o">.</span><span class="n">dylib</span><span class="p">)</span> <span class="o">+</span> <span class="mi">24</span>
<span class="c1">#If you are reading this... reboot your iOS device. Your problems will probably go away.</span>
</pre></div>
<p>Google didn't return useful results for some the various <code>_xpc*</code> function names. Although the libxpc keyword seemed to be associated with "hang." I went and grabbed another 4S. Fortunately, the issue did not repro. From what I could tell libxpc is related to remote debugging. However, it never shutdown properly and was left running to break as it pleased. After a quick reboot of the device we were back to normal.</p>
<p>Seeing as Google was pretty sparse on this issue I hope this will save others some time.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2011-12-20-6-3-have-you-tried-turning-it-on-and-off-again:-libxpc.html</guid><pubDate>Tue, 20 Dec 2011 06:03:00 GMT</pubDate></item><item><title>good tools</title><link>http://www.infectmac.com/posts/2011-2-14-3-39-good-tools.html</link><description><p>I recently moved to doing BlackBerry development at work which required me to go through setting up a new environment. I had successfully setup iPhone and Android environments by simply following the directions on their web sites. Not surprisingly, Apple has the easiest development environment to get setup. Google had a few more steps but made up for it with good <a href="http://developer.android.com/sdk/index.html">documentation</a>. To get started on Blackberry development I installed a bunch of software from this <a href="http://us.blackberry.com/developers/javaappdev/devtools.jsp">page</a>: Eclipse for Blackberry Development, Blackberry Java Development Environment (JDE), Torch Simulator, MDS Simulator. Ok good to go. I was able to build our <a href="http://appworld.blackberry.com/webstore/content/9656?lang=en">product</a> and run it on a simulator. Next I started playing around with the app. Setting breakpoints and getting an idea of how things were plugged together. I wanted to try out the voice search feature and thought the simulator would use the PC mic but it was not working. I figured it should be easy to load the app on a device and eliminate the simulator as the cause of the problem. The JDE comes with a tool called JavaLoader for placing builds on the device. I plugged the device into the computer and ran the tool. It dumped info to the terminal of what it was doing and left me with an error message: HRESULT: 80040154. With a quick search I found that error code meant the a COM class could not be instantiated. I figured I probably did not install the software which allowed for communication with the device over USB. But what was it? With COM to create an object you pass in a GUID and bam you have yourself an instance of some class (an oversimplification but good enough for this). Underneath the hood the program is really digging through the Windows registry looking for that GUID. If I could find that GUID I could easily find what I was missing with a quick web search. To find the GUID I fired up <a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx">procmon</a> and reran the JavaLoader program. Procmon is magic in a box. It shows all the different events taking place with the file system and registry for the whole system or a particular process. It helped me find the GUID in question as seen in the picture below:</p>
<p><img alt="procmon" src="static/img/procmon.png" /></p>
<p>I searched for <code>BA3D0120-E617-4F66-ADCA-585CC2FB86DB</code> and found a <a href="http://stackoverflow.com/questions/1585314/where-can-i-find-a-list-of-well-known-com-object-guids">stackoverflow</a> entry indicating that Blackberry Desktop Manager needed to be installed. Once I installed it everything work as expected. Lesson today: Good tools make life better.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2011-2-14-3-39-good-tools.html</guid><pubDate>Mon, 14 Feb 2011 03:39:00 GMT</pubDate></item><item><title>objective c blocks</title><link>http://www.infectmac.com/posts/2011-2-7-9-32-objective-c-blocks.html</link><description><p>Objective-C features anonymous functions via what they call blocks. I was a little fuzzy on the memory management rules of blocks at first. The basic rules are: the block structure is stack allocated and blocks retain Objective-C objects they reference until the block is deallocated. In order to keep the block around beyond the lifetime of a stack frame the block must be copied to the heap All of the objects directly referenced within the block will be retained. When the block is released those objects will also be released. Keep in mind the retained objects may have weak references to other objects that may end up getting freed before one would expect. For example, an objects delegate is typically not retained. A simple mistake would be to perform an asynchronous action which causes a view to update but has the possibility of the delegate being released before that action has the opportunity to complete With the Flickr app I spoke of <a href="posts/2011-1-31-8-28-the-great-uitableview-race.html">previously</a> I messed up on both rules. First, my block referenced <code>tableView</code> whose delegate was the view controller. With the code below it will likely fail if the user backs away before all the thumbnails finish loading.</p>
<div class="codehilite"><pre><span class="o">-</span> <span class="p">(</span><span class="n">UITableViewCell</span> <span class="o">*</span><span class="p">)</span><span class="nl">tableView:</span><span class="p">(</span><span class="n">UITableView</span> <span class="o">*</span><span class="p">)</span><span class="n">tableView</span> <span class="nl">cellForRowAtIndexPath:</span><span class="p">(</span><span class="n">NSIndexPath</span> <span class="o">*</span><span class="p">)</span><span class="n">indexPath</span> <span class="p">{</span>
<span class="p">...</span><span class="n">code</span> <span class="n">to</span> <span class="n">dequeue</span> <span class="n">and</span> <span class="n">setup</span> <span class="n">a</span> <span class="n">UITableViewCell</span> <span class="n">removed</span><span class="p">...</span>
<span class="c1">//retrieve our Core Data representation of the photo</span>
<span class="n">Photo</span><span class="o">*</span> <span class="n">photo</span> <span class="o">=</span> <span class="p">[</span><span class="n">Photo</span> <span class="nl">photoWithFlickrData:</span><span class="n">pictObj</span> <span class="nl">inManagedObjectContext:</span><span class="n">context</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="n">photo</span><span class="p">.</span><span class="n">thumbnail</span><span class="p">)</span> <span class="p">{</span>
<span class="n">cell</span><span class="p">.</span><span class="n">imageView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIImage</span> <span class="nl">imageWithData:</span><span class="n">photo</span><span class="p">.</span><span class="n">thumbnail</span><span class="p">];</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="c1">//Photo objects uses Grand Central Dispatch to make a request to </span>
<span class="c1">//Flickr servers for photo downloads.</span>
<span class="p">[</span><span class="n">photo</span> <span class="nl">thumbnailWithBlock:</span><span class="o">^</span><span class="p">(</span><span class="n">NSData</span><span class="o">*</span> <span class="n">image</span><span class="p">)</span> <span class="p">{</span>
<span class="n">cell</span><span class="p">.</span><span class="n">imageView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIImage</span> <span class="nl">imageWithData:</span><span class="n">image</span><span class="p">];</span>
<span class="p">[</span><span class="n">tableView</span> <span class="nl">reloadRowsAtIndexPaths:</span><span class="p">[</span><span class="n">NSArray</span> <span class="nl">arrayWithObject:</span><span class="n">indexPath</span><span class="p">]</span> <span class="nl">withRowAnimation:</span><span class="n">UITableViewRowAnimationNone</span><span class="p">];</span>
<span class="p">}];</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">cell</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>Once the user backs away from the table’s view controller it will be released. It is possible the queue will still be downloading thumbnails. Once a thumbnail is downloaded the block passed to thumbnailWithBlock will be called and attempt to update the table only to have the program crash. Instead of sending the reload message to <code>tableView</code> I send the reload message to <code>self.tableView</code>. In this case self is the view controller for the table view and since it is now reference in the block it will be retained for later use. After using Grand Central Dispatch (GCD) to perform the image fetching I wanted to see how it could be done with <code>NSURLConnection</code>. <code>NSURLConnection</code> handles all of the networking on a separate thread. It notifies the UI thread via various delegate methods of the download progress. I simply changed the <code>thumbnailWithBlock</code> on the Photo object to use <code>NSURLConnection</code> and store a pointer to the block object for use later. When the download finished I called the block with the downloaded data but the program crashed. The reason was I had failed to copy the block to the heap and was getting the <code>EXC_BAD_ACCESS</code> error. The fix was to send a copy message to the block and be sure to release it after using it with the downloaded data. Once I figured that all out I wondered how GCD handled blocks. It must copy them or else it would be getting <code>EXC_BAD_ACCESS</code> errors. Me being curious I went and looked and sure enough they <a href="http://libdispatch.macosforge.org/trac/browser/trunk/src/queue.c#L692">copy</a> the blocks before using them.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2011-2-7-9-32-objective-c-blocks.html</guid><pubDate>Mon, 07 Feb 2011 09:32:00 GMT</pubDate></item><item><title>phantom mapkit polylines</title><link>http://www.infectmac.com/posts/2011-2-3-1-49-phantom-mapkit-polylines.html</link><description><p>I was toying around with MapKit today and I am pretty sure I found a bug. MapKit renders an extra line along the equator if a polyline's point has a latitude of zero or an extra line along the prime meridian if its longitude is zero AND if the line width is less than or equal to 1.0. The code snippet to reproduce the issue can be found here:</p>
<div class="codehilite"><pre><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">viewWillAppear:</span><span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="n">animated</span>
<span class="p">{</span>
<span class="p">[</span><span class="n">super</span> <span class="nl">viewWillAppear:</span><span class="n">animated</span><span class="p">];</span>
<span class="n">CLLocationCoordinate2D</span> <span class="n">points</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="n">points</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">latitude</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">points</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">longitude</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">points</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">latitude</span> <span class="o">=</span> <span class="o">-</span><span class="mi">6</span><span class="p">;</span>
<span class="n">points</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">longitude</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">MKPolyline</span><span class="o">*</span> <span class="n">polyline</span> <span class="o">=</span> <span class="p">[</span><span class="n">MKPolyline</span> <span class="nl">polylineWithCoordinates:</span><span class="n">points</span> <span class="nl">count:</span><span class="mi">2</span><span class="p">];</span>
<span class="p">[</span><span class="n">mapView</span> <span class="nl">addOverlay:</span><span class="n">polyline</span><span class="p">];</span>
<span class="p">[</span><span class="n">mapView</span> <span class="nl">setRegion:</span><span class="n">MKCoordinateRegionMake</span><span class="p">(</span><span class="n">CLLocationCoordinate2DMake</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">MKCoordinateSpanMake</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">))];</span>
<span class="p">}</span>
<span class="o">-</span> <span class="p">(</span><span class="n">MKOverlayView</span><span class="o">*</span><span class="p">)</span><span class="nl">mapView:</span><span class="p">(</span><span class="n">MKMapView</span> <span class="o">*</span><span class="p">)</span><span class="n">mapView</span> <span class="nl">viewForOverlay:</span><span class="p">(</span><span class="kt">id</span> <span class="o">&lt;</span><span class="n">MKOverlay</span><span class="o">&gt;</span><span class="p">)</span><span class="n">overlay</span>
<span class="p">{</span>
<span class="n">MKPolylineView</span><span class="o">*</span> <span class="n">polylineView</span> <span class="o">=</span> <span class="p">[[</span><span class="n">MKPolylineView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithPolyline:</span><span class="n">overlay</span><span class="p">];</span>
<span class="n">polylineView</span><span class="p">.</span><span class="n">lineWidth</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">polylineView</span><span class="p">.</span><span class="n">strokeColor</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIColor</span> <span class="n">redColor</span><span class="p">];</span>
<span class="k">return</span> <span class="p">[</span><span class="n">polylineView</span> <span class="n">autorelease</span><span class="p">];</span>
<span class="p">}</span>
</pre></div>
<p>And also a screenshot of the result:</p>
<p><img alt="phantom" src="static/img/phantom-lines.png" /></p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2011-2-3-1-49-phantom-mapkit-polylines.html</guid><pubDate>Thu, 03 Feb 2011 01:49:00 GMT</pubDate></item><item><title>the great uitableview race</title><link>http://www.infectmac.com/posts/2011-1-31-8-28-the-great-uitableview-race.html</link><description><p>For the iTunes U course on iOS programming I followed along with the homework assignments. The last assignment was a Flickr app that shows photos at popular geotagged locations. I had an issue with UITableViewCell reuse and background threads populating the thumbnail image that I thought was worth sharing. On iOS in order to improve performance some of the different libraries like UIKit and MapKit have the ability to reuse UI elements once they are no longer on screen. When reuse occurs it is up to the developer to provide new data for the UI element. My problem was that two or more asynchronous operations could change the same table cell. One solution would be to stop reusing table cells but that is not ideal. As long as I can identify which image should be shown in the cell at a given time I can make sure the correct asynchronous operation updates the cell. Since UITableViewCell derives from UIView it has the tag property which is a NSInteger. The UITableView represents an array of data from Flickr. Before making the asynchronous call I set the cell’s tag to the index in that array it currently represents. Then in the callback function I only update the cell if its tag matches the index for which the asynchronous call was made. Without this change in place it is possible to scroll through the list rapidly and see the thumbnail change two or three times for a cell while the remaining thumbnail downloads finish. But the last update could be the wrong thumbnail. The code itself is simple and can be found here: </p>
<div class="codehilite"><pre><span class="o">-</span> <span class="p">(</span><span class="n">UITableViewCell</span> <span class="o">*</span><span class="p">)</span><span class="nl">tableView:</span><span class="p">(</span><span class="n">UITableView</span> <span class="o">*</span><span class="p">)</span><span class="n">tableView</span> <span class="nl">cellForRowAtIndexPath:</span><span class="p">(</span><span class="n">NSIndexPath</span> <span class="o">*</span><span class="p">)</span><span class="n">indexPath</span> <span class="p">{</span>
<span class="k">static</span> <span class="n">NSString</span> <span class="o">*</span><span class="n">CellIdentifier</span> <span class="o">=</span> <span class="s">@&quot;Cell&quot;</span><span class="p">;</span>
<span class="n">UITableViewCell</span> <span class="o">*</span><span class="n">cell</span> <span class="o">=</span> <span class="p">[</span><span class="n">tableView</span> <span class="nl">dequeueReusableCellWithIdentifier:</span><span class="n">CellIdentifier</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="n">cell</span> <span class="o">==</span> <span class="nb">nil</span><span class="p">)</span> <span class="p">{</span>
<span class="n">cell</span> <span class="o">=</span> <span class="p">[[[</span><span class="n">UITableViewCell</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithStyle:</span><span class="n">UITableViewCellStyleSubtitle</span> <span class="nl">reuseIdentifier:</span><span class="n">CellIdentifier</span><span class="p">]</span> <span class="n">autorelease</span><span class="p">];</span>
<span class="p">}</span>
<span class="n">NSDictionary</span><span class="o">*</span> <span class="n">pictObj</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">pictures</span> <span class="nl">objectAtIndex:</span><span class="n">indexPath</span><span class="p">.</span><span class="n">row</span><span class="p">];</span>
<span class="n">NSString</span><span class="o">*</span> <span class="n">title</span> <span class="o">=</span> <span class="p">[</span><span class="n">pictObj</span> <span class="nl">objectForKey:</span><span class="s">@&quot;title&quot;</span><span class="p">];</span>
<span class="n">title</span> <span class="o">=</span> <span class="p">[</span><span class="n">title</span> <span class="n">length</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">?</span> <span class="s">@&quot;(no title)&quot;</span> <span class="o">:</span> <span class="n">title</span><span class="p">;</span>
<span class="n">cell</span><span class="p">.</span><span class="n">textLabel</span><span class="p">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">title</span><span class="p">;</span>
<span class="n">cell</span><span class="p">.</span><span class="n">detailTextLabel</span><span class="p">.</span><span class="n">text</span> <span class="o">=</span> <span class="p">[[</span><span class="n">pictObj</span> <span class="nl">objectForKey:</span><span class="s">@&quot;description&quot;</span><span class="p">]</span> <span class="nl">objectForKey:</span><span class="s">@&quot;_content&quot;</span><span class="p">];</span>
<span class="n">cell</span><span class="p">.</span><span class="n">accessoryType</span> <span class="o">=</span> <span class="n">UITableViewCellAccessoryDisclosureIndicator</span><span class="p">;</span>
<span class="c1">//identify which image the cell should be displaying right now</span>
<span class="n">cell</span><span class="p">.</span><span class="n">tag</span> <span class="o">=</span> <span class="n">indexPath</span><span class="p">.</span><span class="n">row</span><span class="p">;</span>
<span class="n">Photo</span><span class="o">*</span> <span class="n">photo</span> <span class="o">=</span> <span class="p">[</span><span class="n">Photo</span> <span class="nl">photoWithFlickrData:</span><span class="n">pictObj</span> <span class="nl">inManagedObjectContext:</span><span class="n">context</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="n">photo</span><span class="p">.</span><span class="n">thumbnail</span><span class="p">)</span> <span class="p">{</span>
<span class="n">cell</span><span class="p">.</span><span class="n">imageView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIImage</span> <span class="nl">imageWithData:</span><span class="n">photo</span><span class="p">.</span><span class="n">thumbnail</span><span class="p">];</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">cell</span><span class="p">.</span><span class="n">imageView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
<span class="p">[</span><span class="n">photo</span> <span class="nl">thumbnailWithBlock:</span><span class="o">^</span><span class="p">(</span><span class="n">UIImage</span><span class="o">*</span> <span class="n">image</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//check to make sure the image should be updated</span>
<span class="k">if</span> <span class="p">(</span><span class="n">cell</span><span class="p">.</span><span class="n">tag</span> <span class="o">==</span> <span class="n">indexPath</span><span class="p">.</span><span class="n">row</span><span class="p">)</span> <span class="p">{</span>
<span class="n">cell</span><span class="p">.</span><span class="n">imageView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="n">image</span><span class="p">;</span>
<span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">tableView</span> <span class="nl">reloadRowsAtIndexPaths:</span><span class="p">[</span><span class="n">NSArray</span> <span class="nl">arrayWithObject:</span><span class="n">indexPath</span><span class="p">]</span> <span class="nl">withRowAnimation:</span><span class="n">UITableViewRowAnimationNone</span><span class="p">];</span>
<span class="p">}</span>
<span class="p">}];</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">cell</span><span class="p">;</span>
<span class="p">}</span>
</pre></div></description><guid isPermaLink="true">http://www.infectmac.com/posts/2011-1-31-8-28-the-great-uitableview-race.html</guid><pubDate>Mon, 31 Jan 2011 08:28:00 GMT</pubDate></item><item><title>silly apple ui</title><link>http://www.infectmac.com/posts/2011-1-24-7-28-silly-apple-ui.html</link><description><p>I have been working my way through the Stanford iOS programming course. It’s been my biggest exposure to the Apple developer ecosystem. So far I have encountered three user interface components in the tooling that I trip me up. The first is Interface Builder (IB). This tool is separate from the XCode IDE. I typically forget to save changes. In my mind XCode and IB are one and so I expect my changes to be saved when I build. I usually end up with a blank screen and then I remember: save in IB! In XCode 4 IB is supposed to be integrated so hopefully this issue is fixed. On the code side of things all the UI pointers are nil. In Objective C it is perfectly valid to send messages to those nil objects. Personally, I would like to fail fast and have the program crash as I think that would help me find the root cause quicker. Second, when opening older projects I often get the “Base SDK is missing” error. It’s easy to change in the project’s build settings but after the change it seems you must reload the project in XCode. It wasn’t entirely obvious at first but restarting an application usually fixes everything regardless of the platform. Finally, I wanted to see how my custom drawRect: code was visually different on the retina display versus the old display. I checked out an older device from work and took it too my office and tried to provision only to receive this error message:</p>
<p><img alt="silly ui" src="static/img/silly-apple-ui.png" /></p>
<p>Only one developer gets to register a device I figured. I searched the internet a bit and finally decided I would just provision the device as a tester’s device. While I was looking for the page to do that I found my device list had two devices listed. That was odd because I only expected to see my iPod listed. I looked at the second device and sure enough it had the same ID number as the device I had checked out. The dialog meant to add devices didn’t tell me it had done this. It only displayed an error message asking for another ID number. Overall the tooling is pretty good and it does not get in the way that often.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2011-1-24-7-28-silly-apple-ui.html</guid><pubDate>Mon, 24 Jan 2011 07:28:00 GMT</pubDate></item><item><title>facebook ads</title><link>http://www.infectmac.com/posts/2011-1-17-7-28-facebook-ads.html</link><description><p>If Facebook ads are any indicator of the health of the economy then it must be great. For the past 2-3 months I have noticed an increase in the number of job ads. I think the cause might be one or a combination of the following:</p>
<ul>
<li>More employers are using Facebook to advertise open positions which could mean the economy is doing better. Yay!</li>
<li>I switched jobs from a Visual Studio SDET to Bing Mobile SDE back in October. The “developer” label probably draws more employer attention than the “tester” label.</li>
<li>The Microsoft keyword in my profile certainly helps. It’s like going to a big name school. Society assumes it must be good. In the big scheme of things it’s pretty silly to base potential success off of that attribute alone.</li>
</ul>
<p>Here are some of the job ads I have seen so far:
<em> <imdb.com>
</em> <logos.com>
<em> Various social game sites like <wooga.com> and <zynga.com>
</em> <palantir.com>
<em> <inrix.com>
</em> <marchex.com> - they advertise using the domain <makehistory.com> which appears to be their informational recruiting site. </p>
<p>It’s not uncommon for 2 or 3 of these to show up on any given Facebook page. The Marchex ad always catches my eye. Their tag line reads: “Tired of Reorgs.” Which probably catches the attention of most Microsoft employees. I think ads on Facebook are going to start to look more and more like this though. They will continue to get more personal in nature. I know I click on more Facebook ads than Google ads. When something is so relavent it sparks my curiosity. I don’t know that Facebook will take away Google’s AdWord revenue but I think they are in a pretty good position to compete for AdSense revenue. IMDB.com also advertises positions on Facebook. They didn’t take the “reorg” approach but went with the commute. The 520 bridge which connects Seattle to Microsoft can get backed up. Personally, I am not “tired of the bridge” as their ad said since I don’t live in Seattle. Their ad was clever but not clever enough to take my address into account. Finally, the last ad that caught my eye had the tag line: “Stressed At Microsoft?” The ad was for counseling services at <eastsidecounseling.org>. Between the competitor’s job ads and counseling ads a cynic might say Microsoft isn’t the place to work. I wonder what kind of targeted ads I would see if I worked at Google, Amazon, Facebook or Apple? For Amazon I am guessing “Tired of the Pager” would make a pretty catchy tag line. I am sure the others have quirks their competitors use to attract talent but I don’t know enough about those companies to venture a guess.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2011-1-17-7-28-facebook-ads.html</guid><pubDate>Mon, 17 Jan 2011 07:28:00 GMT</pubDate></item><item><title>my next side project</title><link>http://www.infectmac.com/posts/2010-4-25-22-23-my-next-side-project.html</link><description><p>For my next side project I am going to create a webapp that allows site maintainers to track what a user is doing with the UI of their site and view this in realtime. My plan is to record things like mouse position, window size and page content and push it all back to the server. It can be a poor man's usability study or simply used as a big brother tool by site maintainers. Either way it should be interesting.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2010-4-25-22-23-my-next-side-project.html</guid><pubDate>Sun, 25 Apr 2010 22:23:00 GMT</pubDate></item><item><title>tetris with twilio</title><link>http://www.infectmac.com/posts/2010-2-28-23-56-tetris-with-twilio.html</link><description><p>Last month I created <a href="http://tetris.evanlong.info/">Tetris with Twilio</a>. It allows any telephone (USA only) to be used as an input device to a game of tetris that is played within a web browser. The best part is that once you clear 5 lines your phone is redirected to me and I'll probably pick up and talk to you.</p>
<p>How does it work? I use <a href="http://www.twilio.com/">http://www.twilio.com/</a> to deal with input from the phone. The main purpose of this project was to learn more about <a href="http://www.tornadoweb.org/">http://www.tornadoweb.org/</a>. Tornado makes it easy to push data to the user in realtime. And for those that like source code it is available <a href="http://bitbucket.org/evanlong/twilio-tetris-game/">here</a>.</p>
<p>Enjoy!</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2010-2-28-23-56-tetris-with-twilio.html</guid><pubDate>Sun, 28 Feb 2010 23:56:00 GMT</pubDate></item><item><title>mystery function</title><link>http://www.infectmac.com/posts/2009-10-5-2-31-mystery-function.html</link><description><p>What does this mystery function do?</p>
<div class="codehilite"><pre><span class="nb">int</span> <span class="n">mystery</span><span class="p">(</span><span class="nb">int</span> <span class="n">input</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">long</span> <span class="n">long</span> <span class="n">n</span> <span class="o">=</span> <span class="p">(</span><span class="n">long</span> <span class="n">long</span><span class="p">)</span><span class="n">input</span> <span class="o">*</span> <span class="p">(</span><span class="n">long</span> <span class="n">long</span><span class="p">)</span><span class="mh">0x55555556</span><span class="p">;</span>
<span class="n">long</span> <span class="n">long</span> <span class="n">top</span> <span class="o">=</span> <span class="n">n</span> <span class="o">&gt;&gt;</span> <span class="mi">32</span><span class="p">;</span>
<span class="nb">int</span> <span class="n">edx</span> <span class="o">=</span> <span class="p">(</span><span class="nb">int</span><span class="p">)</span><span class="n">top</span><span class="p">;</span>
<span class="n">edx</span> <span class="o">*=</span> <span class="mi">3</span><span class="p">;</span>
<span class="nb">int</span> <span class="n">answer</span> <span class="o">=</span> <span class="n">input</span> <span class="o">-</span> <span class="n">edx</span><span class="p">;</span>
<span class="k">return</span> <span class="n">answer</span><span class="p">;</span>
<span class="p">}</span>
<span class="nb">int</span> <span class="n">mystery_one_liner</span><span class="p">(</span><span class="nb">int</span> <span class="n">input</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="n">input</span><span class="o">-</span><span class="p">(((</span><span class="nb">int</span><span class="p">)(((</span><span class="n">long</span> <span class="n">long</span><span class="p">)</span><span class="n">input</span> <span class="o">*</span> <span class="p">(</span><span class="n">long</span> <span class="n">long</span><span class="p">)</span><span class="mh">0x55555556</span><span class="p">)</span><span class="o">&gt;&gt;</span><span class="mi">32</span><span class="p">))</span> <span class="o">*</span> <span class="mi">3</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
<p>What it does is simple. How it does it is not. Or at least it's not obvious at
first. I still need to figure out the "magic" behind it. I think this site
might be a good start: <a href="http://wall.riscom.net/books/proc/ppc/cwg/code2.html">http://wall.riscom.net/books/proc/ppc/cwg/code2.html</a>.</p>
<p>Anyway, in my Theoretical Computer Science class we were tasked with writing a
DFA which determined if a number was evenly divisible by 3. I knew that %2 you
could simply look at the last bit. But what about %3? I wrote the code for
"argc % 3" and looked at how gcc with the "-O3" flag compiled it down. It's
just magic. Multiply by 0x55555556? I'll figure out the "why" later.</p>
<p>For some reason more than two years after taking that class I decided to start
figuring out the "why" to this particular compiler optimization I first ran
into back then.</p>
<p><strong>Note</strong>: What I have written above only works for positive integers.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2009-10-5-2-31-mystery-function.html</guid><pubDate>Mon, 05 Oct 2009 02:31:00 GMT</pubDate></item><item><title>reject her him twilio application</title><link>http://www.infectmac.com/posts/2009-9-29-4-6-reject-her-him-twilio-application.html</link><description><p>Yesterday I made <a href="http://rejectherhim.appspot.com/">http://rejectherhim.appspot.com/</a>. It allows you to enter in your phone number and a custom rejection message. The service will also give you a phone number you can then proxy a call through. The best part about it is that with a little social engineering you can make the other person think they are getting your phone number. When you call our proxy number, and enter in the rejectee's 10 digit phone number it will connect the two of you but they will see the caller-id of our service. When they call our number back (because they think it is you) they will be played the custom rejection message.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2009-9-29-4-6-reject-her-him-twilio-application.html</guid><pubDate>Tue, 29 Sep 2009 04:06:00 GMT</pubDate></item><item><title>thank you google</title><link>http://www.infectmac.com/posts/2009-9-5-6-20-thank-you-google.html</link><description><p>Google App Engine is now one step closer to making my <a href="posts/2008-9-6-16-19-in-5-years....html">dreams</a> become a <a href="http://code.google.com/appengine/docs/python/xmpp/overview.html">reality</a>. Now if I can just get my ticket to the moon I'll be set.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2009-9-5-6-20-thank-you-google.html</guid><pubDate>Sat, 05 Sep 2009 06:20:00 GMT</pubDate></item><item><title>Dial THE Joke</title><link>http://www.infectmac.com/posts/2009-6-22-7-50-Dial-THE-Joke.html</link><description><p>I spent some time this weekend working on my <a href="http://dialthejoke.appspot.com/">http://dialthejoke.appspot.com/</a> application. The idea is certainly not original. I first learned about these systems when I saw <a href="http://www.imdb.com/title/tt0168122/">Pirates of Silicon Valley</a>. It accepts user submitted jokes and those jokes are then voted on. The joke with the most votes will be the played when you call <strong>425-440-0035</strong>. </p>
<p>I built it with &lt;http://www.twilio.com/ and Google App Engine. It's the first
real app I built with twilio. It only uses the "say" verb so I still have a
lot to learn about the twilio system. But I do have another app I plan on
building during the evenings and weekends ahead. It's slightly more
complicated but I think it will be a bit more amusing.</p>
<p>For those that are interested the source code can be found here: <a href="http://code.google.com/p/dialthejoke/">http://code.google.com/p/dialthejoke/</a>.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2009-6-22-7-50-Dial-THE-Joke.html</guid><pubDate>Mon, 22 Jun 2009 07:50:00 GMT</pubDate></item><item><title>twitter search</title><link>http://www.infectmac.com/posts/2009-5-27-5-58-twitter-search.html</link><description><p>Obama nominated <a href="http://en.wikipedia.org/wiki/Sonia_Sotomayor">Sotomayor</a> to
the supreme court today but the top twitter trend as of now: <a href="http://search.twitter.com/search?q=%233wordsaftersex">#3wordsaftersex</a> I do understand twitter
search. So far I actually like twitter search. I find somewhat interesting
blog posts (on technical things) that I probably would not have found
otherwise. I don't know what twitter plans to do with search (fight Google?).
I could see how they could win. It would be nice if the searches were sorted
by "relevance" instead of most recent post. Grouping common tweets together
and categorizing them might be nice but I honestly don't know if I would like
that.</p>
<p>The power of these tweets seem to be the links and keywords and the time context. Perhaps mining the tweets would be a better way to <a href="http://en.wikipedia.org/wiki/Google_Image_Labeler">label images</a>? Or label websites, videos, blogs, and
news items that the tweets link to.</p>
<p>Just some thoughts. I guess I sort of get twitter now.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2009-5-27-5-58-twitter-search.html</guid><pubDate>Wed, 27 May 2009 05:58:00 GMT</pubDate></item><item><title>Why being a computer science major can suck...</title><link>http://www.infectmac.com/posts/2008-11-3-0-6-Why-being-a-computer-science-major-can-suck....html</link><description><p>...the people. Here is a question somebody asked on a class forum. I really hope they meant to be funny:</p>
<p>Professors response to the acceptable size of paper for notes used during an
exam:</p>
<blockquote>
<p>Let me clarify. Two pieces of A4 paper. Fourth sides. Hand writing notes.</p>
</blockquote>
<p>Students response:</p>
<blockquote>
<p>Hmm... since wikipedia states that A4 paper is '8.3 x 11.7"', I assume this means 8.5 x 11" will also suffice (where do one obtain "A4" paper around here?)</p>
</blockquote>
<p>TA's response:</p>
<blockquote>
<p>That is the most ridiculous question I have seen in my 25 years of existence. It even beats some of the other questions one hears in the election rallies these days. My official response to it is that I am going to go off to bed now as I have an early morning lecture to attend.</p>
</blockquote></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-11-3-0-6-Why-being-a-computer-science-major-can-suck....html</guid><pubDate>Mon, 03 Nov 2008 00:06:00 GMT</pubDate></item><item><title>in 5 years...</title><link>http://www.infectmac.com/posts/2008-9-6-16-19-in-5-years....html</link><description><p>I wrote this email to a friend on February 4th, 2008. Just a list of my predictions for the next 5 years:</p>
<blockquote>
<p>So within 5 years I think:</p>
<ol>
<li>XMPP will be the protocol for real-time web apps</li>
<li>Browsers will have javascript implementations that go through a JIT. Microsoft actually has this working. They have javascript working on their DLR (which is the newer virtual machine for dynamic languages).</li>
<li>People may implement their own virtual machines <span class="nfakPe">in</span> the javascript just so they can easily port existing code to the web. (This point is a big maybe but could be cool)</li>
<li>Erlang will be cool partly because of the XMPP server that is written in erlang.</li>
<li>And facebook will have gone public.</li>
</ol>
<p>So now you know and are my witness.</p>
<p>Evan</p>
</blockquote></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-9-6-16-19-in-5-years....html</guid><pubDate>Sat, 06 Sep 2008 16:19:00 GMT</pubDate></item><item><title>stanford btree problems: hasPathSum</title><link>http://www.infectmac.com/posts/2008-8-10-18-38-stanford-btree-problems:-hasPathSum.html</link><description><p>I decided to go through some of the <a href="http://cslibrary.stanford.edu/110/BinaryTrees.html">Stanford Btree problems</a>. Today I wrote a solution to the hasPathSum problem and part of the printPaths problem in SML. My solution will take a binary tree and return a list of all the paths that will sum to the given sum. A path starts at the root and ends at the descendant whose integer value adds to the sum.</p>
<div class="codehilite"><pre><span class="n">datatype</span> <span class="n">itree</span> <span class="o">=</span> <span class="nc">Node</span> <span class="k">of</span> <span class="n">itree</span> <span class="o">*</span> <span class="kt">int</span> <span class="o">*</span> <span class="n">itree</span>
<span class="o">|</span> <span class="nc">Leaf</span>
<span class="k">val</span> <span class="n">mytree</span> <span class="o">=</span> <span class="nc">Node</span><span class="o">(</span>
<span class="nc">Node</span><span class="o">(</span>
<span class="nc">Node</span><span class="o">(</span>
<span class="nc">Node</span><span class="o">(</span><span class="nc">Leaf</span><span class="o">,~</span><span class="mi">3</span><span class="o">,</span><span class="nc">Leaf</span><span class="o">),</span>
<span class="mi">2</span><span class="o">,</span>
<span class="nc">Node</span><span class="o">(</span><span class="nc">Leaf</span><span class="o">,</span><span class="mi">12</span><span class="o">,</span><span class="nc">Leaf</span><span class="o">)),</span>
<span class="mi">4</span><span class="o">,</span>
<span class="nc">Leaf</span><span class="o">),</span>
<span class="mi">1</span><span class="o">,</span>
<span class="nc">Node</span><span class="o">(</span><span class="nc">Node</span><span class="o">(</span><span class="nc">Leaf</span><span class="o">,</span><span class="mi">15</span><span class="o">,</span><span class="nc">Leaf</span><span class="o">),</span>
<span class="mi">3</span><span class="o">,</span>
<span class="nc">Leaf</span><span class="o">))</span>
<span class="c">(*</span>
<span class="c"> -should handle positive/negative weights</span>
<span class="c"> -should find all paths in the tree that are equal to this sum</span>
<span class="c">*)</span>
<span class="k">fun</span> <span class="n">hasPathSum</span> <span class="n">root</span> <span class="n">sum</span> <span class="o">=</span>
<span class="k">let</span>
<span class="k">fun</span> <span class="n">search</span> <span class="o">(</span><span class="nc">Node</span><span class="o">(</span><span class="n">left</span><span class="o">,</span><span class="n">i</span><span class="o">,</span><span class="n">right</span><span class="o">))</span> <span class="n">path</span> <span class="n">accum</span> <span class="n">all_paths</span> <span class="o">=</span>
<span class="k">let</span>
<span class="k">val</span> <span class="n">new_path</span> <span class="o">=</span> <span class="o">(</span><span class="n">i</span><span class="o">::</span><span class="n">path</span><span class="o">)</span>
<span class="k">val</span> <span class="n">new_accum</span> <span class="o">=</span> <span class="o">(</span><span class="n">accum</span> <span class="o">+</span> <span class="n">i</span><span class="o">)</span>
<span class="k">val</span> <span class="n">get_left_paths</span> <span class="o">=</span> <span class="n">search</span> <span class="o">(</span><span class="n">left</span><span class="o">)</span> <span class="o">(</span><span class="n">new_path</span><span class="o">)</span> <span class="o">(</span><span class="n">new_accum</span><span class="o">)</span>
<span class="k">val</span> <span class="n">get_right_paths</span> <span class="o">=</span> <span class="n">search</span> <span class="o">(</span><span class="n">right</span><span class="o">)</span> <span class="o">(</span><span class="n">new_path</span><span class="o">)</span> <span class="o">(</span><span class="n">new_accum</span><span class="o">)</span>
<span class="k">val</span> <span class="n">new_all_paths</span> <span class="o">=</span> <span class="k">if</span> <span class="n">sum</span> <span class="o">=</span> <span class="n">new_accum</span> <span class="k">then</span>
<span class="o">((</span><span class="n">rev</span> <span class="n">new_path</span><span class="o">)::</span><span class="n">all_paths</span><span class="o">)</span>
<span class="k">else</span>
<span class="n">all_paths</span>
<span class="k">in</span>
<span class="n">get_right_paths</span> <span class="o">(</span><span class="n">get_left_paths</span> <span class="n">new_all_paths</span><span class="o">)</span>
<span class="k">end</span>
<span class="o">|</span> <span class="n">search</span> <span class="o">(</span><span class="nc">Leaf</span><span class="o">)</span> <span class="o">(_)</span> <span class="o">(_)</span> <span class="o">(</span><span class="n">all_paths</span><span class="o">)</span> <span class="o">=</span> <span class="n">all_paths</span>
<span class="k">in</span>
<span class="n">search</span> <span class="o">(</span><span class="n">root</span><span class="o">)</span> <span class="o">(</span><span class="bp">[]</span><span class="o">)</span> <span class="o">(</span><span class="mi">0</span><span class="o">)</span> <span class="o">(</span><span class="bp">[]</span><span class="o">)</span>
<span class="k">end</span>
<span class="n">hasPathSum</span> <span class="o">(</span><span class="n">mytree</span><span class="o">)</span> <span class="o">(</span><span class="mi">4</span><span class="o">)</span> <span class="c">(*result: [[1,3], [1, 4, 2, ~3]] *)</span>
<span class="n">hasPathSum</span> <span class="o">(</span><span class="n">mytree</span><span class="o">)</span> <span class="o">(</span><span class="mi">1</span><span class="o">)</span> <span class="c">(*result: [[1]]*)</span>
<span class="n">hasPathSum</span> <span class="o">(</span><span class="n">mytree</span><span class="o">)</span> <span class="o">(</span><span class="mi">1024</span><span class="o">)</span> <span class="c">(*result: [] *)</span>
</pre></div></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-8-10-18-38-stanford-btree-problems:-hasPathSum.html</guid><pubDate>Sun, 10 Aug 2008 18:38:00 GMT</pubDate></item><item><title>RESTful Python</title><link>http://www.infectmac.com/posts/2008-8-2-22-15-RESTful-Python.html</link><description><p>My end goal is to make a tool that allows developers to describe their REST API in some sort of markup and then generate libraries that communicate with the server. The tool would generate language specific libraries that abstract away communication with the server. I also hope to provide someway to map between the XML/JSON that the server returns and objects that are defined by the user. I think the real benefit of this will be that developers won't have to write a new library for each language they wish to support on the client side. It seems like the community is responsible for building libraries for the different languages but it would be nice if it were a little more streamlined. </p>
<p>This snippet of code is simple but just the start. It just allows a way to use a python decorator to define the services interface and then the user can use the decorated function to actually communicate with the server. At the bottom I have already defined a couple of functions using the Twitter and Pownce APIs.</p>
<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">urllib</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="k">class</span> <span class="nc">WebApiOpener</span><span class="p">(</span><span class="n">urllib</span><span class="o">.</span><span class="n">FancyURLopener</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Provides a way for HTTP Basic authentication to take place without</span>
<span class="sd"> prompting the user for a username and password like FancyURLopener</span>
<span class="sd"> would.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span>
<span class="n">urllib</span><span class="o">.</span><span class="n">FancyURLopener</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,{})</span>
<span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">username</span>
<span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">password</span>
<span class="k">def</span> <span class="nf">prompt_user_passwd</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="n">realm</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">,</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">webcall</span><span class="p">(</span><span class="o">**</span><span class="n">apiargs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Decorator that is used to create a python function that communicates with</span>
<span class="sd"> a RESTful web service. The function it generates will be able to to do HTTP</span>
<span class="sd"> basic authorization. The generated function only accepts a keyword </span>
<span class="sd"> arguments. The following are reserved arguments:</span>
<span class="sd"> auth_username, string optional, only needed if web service needs </span>
<span class="sd"> basic HTTP auth</span>
<span class="sd"> auth_password, string optional, only needed if web service needs</span>
<span class="sd"> basic HTTP auth</span>
<span class="sd"> All other arguments will be used to first replace variables within the url</span>
<span class="sd"> and the remaining arguments will be passed as part of the parameter string.</span>
<span class="sd"> Take a look at the documentation below and the examples to get an idea of </span>
<span class="sd"> how to define variables within the url string.</span>
<span class="sd"> webcall Arguments: apiargs, keyword list of arguments</span>
<span class="sd"> apiargs[&#39;url&#39;], string, The url of the web service. Specify variables </span>
<span class="sd"> for within the url like this: {var_name=default_value} or {var_name}. </span>
<span class="sd"> These will be filled in when the user actually calls the decorated </span>
<span class="sd"> function.</span>
<span class="sd"> apiargs[&#39;method&#39;], string optional, Defaults to GET if not defined. If</span>
<span class="sd"> it is defined to something besides GET it will use POST.</span>
<span class="sd"> Example:</span>
<span class="sd"> #Here we define a call to twitter:</span>
<span class="sd"> @webcall(url=&#39;http://twitter.com/statuses/friends_timeline.{format=json}&#39;, method=&#39;GET&#39;)</span>
<span class="sd"> def friends_timeline(): pass</span>
<span class="sd"> #returns a a json string for this specific twitter call</span>
<span class="sd"> friends_timeline(auth_username=&#39;bob&#39;, auth_password=&#39;password&#39;)</span>
<span class="sd"> #Looking at the twitter documentation we see that this takes in other</span>
<span class="sd"> #parameters like since, since_id, count, page.</span>
<span class="sd"> #we will also get the RSS formatted response and limit it to two</span>
<span class="sd"> friends_timeline(auth_username=&#39;bob&#39;, auth_password=&#39;password&#39;, count=2, format=&#39;rss&#39;)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">method</span> <span class="o">=</span> <span class="n">apiargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&#39;method&#39;</span><span class="p">,</span><span class="s">&#39;GET&#39;</span><span class="p">)</span>
<span class="n">patter_obj</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">&quot;\{[^\}]+\}&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">dec</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">convert_url</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">replace_dict</span><span class="p">):</span>
<span class="k">for</span> <span class="n">match</span> <span class="ow">in</span> <span class="n">patter_obj</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">url</span><span class="p">):</span>
<span class="c">#figure if the key is in the dict if not and there is</span>
<span class="c">#no default value then don&#39;t replace and continue on</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">()[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="n">pair</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&#39;=&#39;</span><span class="p">)</span>
<span class="c">#if there is a default value and key not in dict use default</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">pair</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">replace_dict</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
<span class="n">url</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(),</span> <span class="n">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">pair</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">replace_dict</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
<span class="n">url</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(),</span> <span class="n">replace_dict</span><span class="p">[</span><span class="n">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]])</span>
<span class="c">#this allow for a {key} to only be user once but this could</span>
<span class="c">#be changed in the future</span>
<span class="k">del</span><span class="p">(</span><span class="n">replace_dict</span><span class="p">[</span><span class="n">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]])</span>
<span class="k">return</span> <span class="n">url</span>
<span class="k">def</span> <span class="nf">new</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> auth_username and auth_password are reserved</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">opener</span> <span class="o">=</span> <span class="n">WebApiOpener</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&#39;auth_username&#39;</span><span class="p">,</span><span class="s">&#39;&#39;</span><span class="p">),</span>
<span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&#39;auth_password&#39;</span><span class="p">,</span><span class="s">&#39;&#39;</span><span class="p">))</span>
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="s">&#39;auth_username&#39;</span><span class="p">):</span> <span class="k">del</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s">&#39;auth_username&#39;</span><span class="p">])</span>
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="s">&#39;auth_password&#39;</span><span class="p">):</span> <span class="k">del</span><span class="p">(</span><span class="n">kwargs</span><span class="p">[</span><span class="s">&#39;auth_password&#39;</span><span class="p">])</span>
<span class="n">url</span> <span class="o">=</span> <span class="n">convert_url</span><span class="p">(</span><span class="n">apiargs</span><span class="p">[</span><span class="s">&#39;url&#39;</span><span class="p">],</span> <span class="n">kwargs</span><span class="p">)</span>
<span class="n">params</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">urlencode</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="n">method</span> <span class="o">==</span> <span class="s">&#39;GET&#39;</span><span class="p">:</span>
<span class="n">stream</span> <span class="o">=</span> <span class="n">opener</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">url</span> <span class="o">+</span> <span class="s">&quot;?&quot;</span> <span class="o">+</span> <span class="n">params</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">stream</span> <span class="o">=</span> <span class="n">opener</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">stream</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">return</span> <span class="n">response</span>
<span class="k">return</span> <span class="n">new</span>
<span class="k">return</span> <span class="n">dec</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd">A set of example functions from pownce and twitter</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="nd">@webcall</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">&#39;http://twitter.com/statuses/public_timeline.{format=json}&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">public_timeline</span><span class="p">():</span> <span class="k">pass</span>
<span class="nd">@webcall</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">&#39;http://twitter.com/statuses/friends_timeline.{format=json}&#39;</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s">&#39;GET&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">friends_timeline</span><span class="p">():</span> <span class="k">pass</span>
<span class="nd">@webcall</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">&#39;http://twitter.com/statuses/user_timeline.{format=json}&#39;</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s">&#39;GET&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">user_timeline</span><span class="p">():</span> <span class="k">pass</span>
<span class="nd">@webcall</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">&#39;http://api.pownce.com/2.0/note_lists/{username}.{format=json}&#39;</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s">&#39;GET&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">pownce_note_list</span><span class="p">():</span> <span class="k">pass</span>
<span class="nd">@webcall</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="s">&#39;http://api.pownce.com/2.0/send/link.{format=json}&#39;</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s">&#39;POST&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">pownce_send_link</span><span class="p">():</span> <span class="k">pass</span>
</pre></div></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-8-2-22-15-RESTful-Python.html</guid><pubDate>Sat, 02 Aug 2008 22:15:00 GMT</pubDate></item><item><title>python tree</title><link>http://www.infectmac.com/posts/2008-7-22-1-15-python-tree.html</link><description><p>I implement a simple tree with the DFS and BFS defined using python generators.</p>
<div class="codehilite"><pre><span class="k">class</span> <span class="nc">Tree</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">data</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">children</span> <span class="o">=</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
<span class="k">def</span> <span class="nf">dfs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">yield</span> <span class="bp">self</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">children</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">child</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">children</span><span class="p">:</span>
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">child</span><span class="o">.</span><span class="n">dfs</span><span class="p">():</span>
<span class="k">yield</span> <span class="n">c</span>
<span class="k">def</span> <span class="nf">bfs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">yield</span> <span class="bp">self</span>
<span class="n">queue</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">children</span><span class="p">)</span>
<span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">queue</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">first</span> <span class="o">=</span> <span class="n">queue</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">queue</span> <span class="o">=</span> <span class="n">queue</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">queue</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">first</span><span class="o">.</span><span class="n">children</span><span class="p">)</span>
<span class="k">yield</span> <span class="n">first</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
<span class="n">root</span> <span class="o">=</span> <span class="n">Tree</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">root</span><span class="o">.</span><span class="n">children</span> <span class="o">=</span> <span class="p">[</span><span class="n">Tree</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">)]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
<span class="n">root</span><span class="o">.</span><span class="n">children</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">children</span> <span class="o">=</span> <span class="p">[</span><span class="n">Tree</span><span class="p">(</span><span class="n">i</span><span class="o">*</span><span class="n">j</span><span class="p">)</span> <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">)]</span>
<span class="c">#-1,0,0,0,0...</span>
<span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">dfs</span><span class="p">():</span>
<span class="k">print</span> <span class="n">node</span><span class="o">.</span><span class="n">data</span>
<span class="k">print</span>
<span class="k">print</span>
<span class="c">#-1,0,1,2,3,4,0,0,0,0,1,2,0,2,4...</span>
<span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">root</span><span class="o">.</span><span class="n">bfs</span><span class="p">():</span>
<span class="k">print</span> <span class="n">node</span><span class="o">.</span><span class="n">data</span>
</pre></div></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-7-22-1-15-python-tree.html</guid><pubDate>Tue, 22 Jul 2008 01:15:00 GMT</pubDate></item><item><title>chipmark2rss</title><link>http://www.infectmac.com/posts/2008-7-13-5-22-chipmark2rss.html</link><description><p>I have been busy this past week but I got a chance to create a new chipmark feature. It's not actually on your our <a href="https://www.chipmark.com">https://www.chipmark.com</a> server but I wrote an app Google App Engine that downloads your public bookmarks and puts them in an RSS feed. The downside of the app is that users must provide there username and password. It would be nice if we implemented OAuth on Chipmark so third party apps could be allowed access to the account without the user having to give their password away to the app. One goal this past year was to implement mashups with chipmark. Currently, we do not have a method that allow users to expose their public chipmarks. For right now the app engine app is the only way to embed a feed of your chipmarks in a website. Take a look at the sidebar and you'll see some of my recent chipmarks.</p>
<p>I should mention I thought of doing this after seeing this in my feed reader yesterday: <a href="http://torrentfreak.com/automate-your-bittorrent-downloads-with-mininova-bookmarks-080709/">remote torrent</a>.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-7-13-5-22-chipmark2rss.html</guid><pubDate>Sun, 13 Jul 2008 05:22:00 GMT</pubDate></item><item><title>A simple stack machine</title><link>http://www.infectmac.com/posts/2008-7-7-1-58-A-simple-stack-machine.html</link><description><p>A lot of popular virtual machines are stack based. The instruction sets take their inputs from a stack and then place their outputs on the same stack. It's pretty simple at face value but the virtual machines end up doing a lot of fancy things behind the scenes to make the code run fast. </p>
<p>Today I implement a REALLY REALLY BASIC stack based virtual machine that does basic math.</p>
<div class="codehilite"><pre><span class="n">s</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">e</span><span class="p">(</span><span class="n">cmd</span><span class="p">):</span>
<span class="k">global</span> <span class="n">s</span>
<span class="n">f</span><span class="o">=</span><span class="p">{</span><span class="s">&#39;add&#39;</span> <span class="p">:</span> <span class="s">&#39;s.append(s.pop()+s.pop())&#39;</span><span class="p">,</span>
<span class="s">&#39;dup&#39;</span> <span class="p">:</span> <span class="s">&#39;s.append(s[-1])&#39;</span><span class="p">,</span>
<span class="s">&#39;sub&#39;</span> <span class="p">:</span> <span class="s">&#39;s.append(s.pop()-s.pop())&#39;</span><span class="p">,</span>
<span class="s">&#39;mul&#39;</span> <span class="p">:</span> <span class="s">&#39;s.append(s.pop()*s.pop())&#39;</span><span class="p">,</span>
<span class="s">&#39;div&#39;</span> <span class="p">:</span> <span class="s">&#39;s.append(s.pop()/s.pop())&#39;</span><span class="p">,</span>
<span class="s">&#39;peak&#39;</span> <span class="p">:</span> <span class="s">&#39;print s[-1]&#39;</span><span class="p">,</span>
<span class="s">&#39;out&#39;</span> <span class="p">:</span> <span class="s">&#39;print s.pop()&#39;</span>
<span class="p">}[</span><span class="n">cmd</span><span class="p">]</span>
<span class="k">exec</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
<span class="n">s</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">s</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">e</span><span class="p">(</span><span class="s">&#39;add&#39;</span><span class="p">)</span>
<span class="n">e</span><span class="p">(</span><span class="s">&#39;dup&#39;</span><span class="p">)</span>
<span class="n">s</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">12</span><span class="p">)</span>
<span class="n">e</span><span class="p">(</span><span class="s">&#39;mul&#39;</span><span class="p">)</span>
<span class="n">e</span><span class="p">(</span><span class="s">&#39;sub&#39;</span><span class="p">)</span>
<span class="n">e</span><span class="p">(</span><span class="s">&#39;peak&#39;</span><span class="p">)</span>
<span class="n">e</span><span class="p">(</span><span class="s">&#39;out&#39;</span><span class="p">)</span>
</pre></div>
<p>The key of the dictionary is the instruction and the value defines what the instruction does.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-7-7-1-58-A-simple-stack-machine.html</guid><pubDate>Mon, 07 Jul 2008 01:58:00 GMT</pubDate></item><item><title>my_itoa and strrev</title><link>http://www.infectmac.com/posts/2008-7-3-23-16-my_itoa-and-strrev.html</link><description><p>Write C code to reverse a string in place and to convert a base 10 integer to a string of different base (a base that is &lt;= 10).<br />
</p>
<div class="codehilite"><pre><span class="cp">#include &lt;stdio.h&gt;</span>
<span class="c1">//reverse a string in place</span>
<span class="kt">void</span> <span class="n">strrev</span><span class="p">(</span><span class="kt">char</span><span class="o">*</span> <span class="n">str</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">len</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">str</span><span class="p">[</span><span class="n">len</span><span class="p">];</span> <span class="n">len</span><span class="o">++</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&amp;</span><span class="n">lt</span><span class="p">;</span><span class="n">len</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">char</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">str</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="n">str</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">str</span><span class="p">[</span><span class="n">len</span><span class="o">-</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">];</span>
<span class="n">str</span><span class="p">[</span><span class="n">len</span><span class="o">-</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">my_itoa</span><span class="p">(</span><span class="kt">int</span> <span class="n">num</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">buf</span><span class="p">,</span> <span class="kt">int</span> <span class="n">base</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">num</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">r</span> <span class="o">=</span> <span class="n">num</span> <span class="o">%</span> <span class="n">base</span><span class="p">;</span>
<span class="n">num</span> <span class="o">-=</span> <span class="n">r</span><span class="p">;</span>
<span class="n">num</span> <span class="o">/=</span> <span class="n">base</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">c</span> <span class="o">=</span> <span class="n">r</span> <span class="o">+</span> <span class="mi">48</span><span class="p">;</span> <span class="c1">//convert the digit to char</span>
<span class="n">buf</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>
<span class="n">i</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">buf</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">strrev</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">**</span> <span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">char</span> <span class="n">a</span><span class="p">[</span><span class="mi">50</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;hello world this&quot;</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">b</span><span class="p">[</span><span class="mi">50</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;stuff in the water&quot;</span><span class="p">;</span>
<span class="n">strrev</span><span class="p">(</span><span class="n">a</span><span class="p">);</span>
<span class="n">strrev</span><span class="p">(</span><span class="n">b</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;%s</span><span class="se">\n</span><span class="s">%s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
<span class="kt">char</span> <span class="n">c</span><span class="p">[</span><span class="mi">100</span><span class="p">];</span>
<span class="n">my_itoa</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="mi">5</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">&quot;%s</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">c</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-7-3-23-16-my_itoa-and-strrev.html</guid><pubDate>Thu, 03 Jul 2008 23:16:00 GMT</pubDate></item><item><title>subsequence sum</title><link>http://www.infectmac.com/posts/2008-7-3-1-4-subsequence-sum.html</link><description><p>Find the maximum sum of a subsequence in a list of positive and negative integer numbers and also provide the range over which it occurs. </p>
<div class="codehilite"><pre><span class="k">def</span> <span class="nf">maxsub</span><span class="p">(</span><span class="n">lst</span><span class="p">):</span>
<span class="n">sidx</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">eidx</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">currMax</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">currSum</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">lst</span><span class="p">)):</span>
<span class="n">currSum</span> <span class="o">+=</span> <span class="n">lst</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="k">if</span> <span class="n">currSum</span> <span class="o">&gt;</span> <span class="n">currMax</span><span class="p">:</span>
<span class="n">currMax</span> <span class="o">=</span> <span class="n">currSum</span>
<span class="n">eidx</span> <span class="o">=</span> <span class="n">i</span>
<span class="k">elif</span> <span class="n">currSum</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">currSum</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">sidx</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">return</span> <span class="p">(</span><span class="n">currMax</span><span class="p">,</span><span class="n">sidx</span><span class="p">,</span><span class="n">eidx</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="o">-</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">]</span>
<span class="n">b</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="o">-</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">]</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span>
<span class="k">print</span> <span class="n">maxsub</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="k">print</span> <span class="n">maxsub</span><span class="p">(</span><span class="n">b</span><span class="p">)</span>
<span class="k">print</span> <span class="n">maxsub</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
</pre></div></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-7-3-1-4-subsequence-sum.html</guid><pubDate>Thu, 03 Jul 2008 01:04:00 GMT</pubDate></item><item><title>Maximize the profit</title><link>http://www.infectmac.com/posts/2008-7-2-3-34-Maximize-the-profit.html</link><description><p>I decided to title these entries with something more related to the title. Here's today's problem:</p>
<blockquote>
<p>Given a matrix of profit where each row represents a worker and each column represents a job maximize the profit by assigning each worker to a specific job. It is only one employee per job and one job per employee. Even if each each could make $1000 dollars on job 1 they all could not be tasked with job 1. Each job will be assigned exactly ONCE and each employee will be assigned exactly ONCE. The matrix will be NxN. The entries will be positive integers. You must return the assignment in some reasonable form. For example this string: "0-&gt;1, 1-&gt;2, 2-&gt;0" would indicate that employee 0 is doing job 1 and employee 1 is doing job 2...</blockquote>To solve this I will use a recursive dynamic programming solution which would take O(n!) time but since this problems has LOTS of overlapping subproblems my memoization decorator can be used in this problem.</p>
</blockquote>
<p>The idea behind the recursive solution is something like this:</p>
<p><img alt="profit" src="http://www.codecogs.com/eq.latex?profit%28w,&amp;space;jobId%29&amp;space;=&amp;space;max%5Cleft%5C%7B%5Cbegin%7Bmatrix%7D&amp;space;costOf%28w_1,jobId%29&amp;space;+&amp;space;profit%28w-w_1,jobId+1%29%5C%5C&amp;space;&amp;space;costOf%28w_2,jobId%29&amp;space;+&amp;space;profit%28w-w_2,jobId+1%29%5C%5C&amp;space;...%5C%5C&amp;space;costOf%28w_n,jobId%29&amp;space;+&amp;space;profit%28w-w_n,jobId+1%29&amp;space;&amp;space;%5Cend%7Bmatrix%7D%5Cright" /></p>
<ul>
<li>w is a list of workers</li>
<li>w (subscript) i is the ith element in w</li>
<li>w-w (subscript) n indicates removal of that element from the list</li>
<li>The costOf function is the cost of assigning a worked to a specific jobId. It ends up being a lookup in the matrix in my case</li>
</ul>
<p>At each point we enumerate all possible job assignments a worker (A) may have and then enumerate all the job assignments their coworkers may have as a result of assigning worker (A) to each of those jobs. We end up doing this until we run out of possible assignments. This ends up being a brute force approach but just like fibonacci we can draw out the recursive calls that take place and see that there will end up being a LOT of overlapping recursive calls. That is, recursive calls to the <em>profit</em> function end up calling it with the same parameters over and over again. We can use memoization to speed things up quite a bit. That's what I do in this case.</p>
<p>Here is the code that I attempted to explain above. Good luck. It's not easy. But try banging your head against it for a while. There are also other ways to solve this problem. Some of them a lot faster because my solution uses a lot of recursion. I'll provide a list of other possible ways to solve it at the bottom.</p>
<div class="codehilite"><pre><span class="c1">#my modified memoization function to support list hashing (its a hack)</span>
<span class="n">def</span> <span class="n">mem</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
<span class="n">mem</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">def</span> <span class="n">mod</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
<span class="n">arg_list</span> <span class="o">=</span> <span class="o">[]</span>
<span class="k">for</span> <span class="n">a</span> <span class="n">in</span> <span class="n">args:</span>
<span class="n">try:</span>
<span class="n">arg_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tuple</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
<span class="n">except:</span>
<span class="n">arg_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">hash</span><span class="p">(</span><span class="n">tuple</span><span class="p">(</span><span class="n">arg_list</span><span class="p">))</span>
<span class="k">if</span> <span class="n">mem</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
<span class="k">return</span> <span class="n">mem</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">fn</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">mem</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span>
<span class="k">return</span> <span class="n">val</span>
<span class="k">return</span> <span class="n">mod</span>
<span class="n">def</span> <span class="n">profitimize</span><span class="p">(</span><span class="n">matrix</span><span class="p">):</span>
<span class="n">plist</span> <span class="o">=</span> <span class="n">range</span><span class="p">(</span><span class="n">len</span><span class="p">(</span><span class="n">matrix</span><span class="p">))</span>
<span class="n">def</span> <span class="n">costMapping</span><span class="p">(</span><span class="n">m</span><span class="p">):</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">k</span> <span class="n">in</span> <span class="n">m:</span>
<span class="n">tmp</span> <span class="o">+=</span> <span class="n">matrix</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="sr">m[k]</span><span class="p">]</span>
<span class="k">return</span> <span class="n">tmp</span>
<span class="nv">@mem</span>
<span class="n">def</span> <span class="n">profit</span><span class="p">(</span><span class="n">people</span><span class="p">,</span> <span class="n">jobId</span><span class="p">):</span>
<span class="k">if</span> <span class="n">len</span><span class="p">(</span><span class="n">people</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">return</span> <span class="p">{}</span>
<span class="n">currCost</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">mapping</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">bestPerson</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">for</span> <span class="n">person</span> <span class="n">in</span> <span class="n">people:</span>
<span class="n">indyCost</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">[</span><span class="n">person</span><span class="p">][</span><span class="n">jobId</span><span class="p">]</span>
<span class="n">newPeople</span> <span class="o">=</span> <span class="n">list</span><span class="p">(</span><span class="n">people</span><span class="p">)</span>
<span class="n">newPeople</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">person</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">dict</span><span class="p">(</span><span class="n">profit</span><span class="p">(</span><span class="n">newPeople</span><span class="p">,</span> <span class="n">jobId</span><span class="o">+</span><span class="mi">1</span><span class="p">))</span>
<span class="n">indyCost</span> <span class="o">+=</span> <span class="n">costMapping</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">if</span> <span class="n">currCost</span> <span class="o">&lt;</span> <span class="n">indyCost:</span>
<span class="n">currCost</span> <span class="o">=</span> <span class="n">indyCost</span>
<span class="n">mapping</span> <span class="o">=</span> <span class="n">result</span>
<span class="n">bestPerson</span> <span class="o">=</span> <span class="n">person</span>
<span class="n">mapping</span><span class="p">[</span><span class="n">bestPerson</span><span class="p">]</span> <span class="o">=</span> <span class="n">jobId</span>
<span class="k">return</span> <span class="n">mapping</span>
<span class="k">return</span> <span class="n">profit</span><span class="p">(</span><span class="n">plist</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
<span class="n">matrix4</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">],[</span><span class="mi">20</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">10</span><span class="p">],[</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">],[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">]]</span>
<span class="n">matrix7</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">90</span><span class="p">,</span><span class="mi">64</span><span class="p">],</span>
<span class="p">[</span><span class="mi">20</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">23</span><span class="p">],</span>
<span class="p">[</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">23</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">60</span><span class="p">,</span><span class="mi">73</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">12</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">65</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">12</span><span class="p">]]</span>
<span class="n">matrix10</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">50</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">60</span><span class="p">,</span><span class="mi">13</span><span class="p">,</span><span class="mi">25</span><span class="p">],</span>
<span class="p">[</span><span class="mi">20</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="mi">24</span><span class="p">,</span><span class="mi">63</span><span class="p">,</span><span class="mi">12</span><span class="p">],</span>
<span class="p">[</span><span class="mi">30</span><span class="p">,</span><span class="mi">20</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">75</span><span class="p">,</span><span class="mi">23</span><span class="p">,</span><span class="mi">86</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">45</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">36</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">53</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">36</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">53</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">36</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">53</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">36</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">53</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">36</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">53</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">36</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">53</span><span class="p">],</span>
<span class="p">[</span><span class="mi">40</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">40</span><span class="p">,</span><span class="mi">30</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">36</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">64</span><span class="p">,</span><span class="mi">12</span><span class="p">,</span><span class="mi">53</span><span class="p">]]</span>
<span class="n">matrix10_2</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">],</span>
<span class="p">[</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">],</span>
<span class="p">[</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">],</span>
<span class="p">[</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">],</span>
<span class="p">[</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">],</span>
<span class="p">[</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">],</span>
<span class="p">[</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">],</span>
<span class="p">[</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">],</span>
<span class="p">[</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">],</span>
<span class="p">[</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">7</span><span class="p">,</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">]]</span>
<span class="n">matrix2</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">10</span><span class="p">,</span><span class="mi">20</span><span class="p">],[</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">]]</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">profitimize</span><span class="p">(</span><span class="n">matrix10_2</span><span class="p">)</span>
<span class="k">print</span> <span class="n">result</span>
</pre></div>
<p>Couple of other techniques:
<em> <a href="http://en.wikipedia.org/wiki/Hungarian_algorithm">http://en.wikipedia.org/wiki/Hungarian_algorithm</a>
</em> <a href="http://en.wikipedia.org/wiki/Matching">http://en.wikipedia.org/wiki/Matching</a></p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-7-2-3-34-Maximize-the-profit.html</guid><pubDate>Wed, 02 Jul 2008 03:34:00 GMT</pubDate></item><item><title>interview prep part 6 & 7</title><link>http://www.infectmac.com/posts/2008-6-29-1-28-interview-prep-part-6-&-7.html</link><description><p>Today is a two-for-one deal since I forgot to post anything yesterday.</p>
<blockquote>
<p>Write a Python decorator to add <a href="http://en.wikipedia.org/wiki/Memoization">http://en.wikipedia.org/wiki/Memoization</a> to any function.</p>
</blockquote>
<p>Python decorators are very nice. Django uses them for users to specify which
views require login and things of that nature. Decorators give the ability to
modify how a function will behave. Now memoization is a technique that can be
used to speed up a recursive solution to a dynamic programming problem. Today
my example isn't really a dynamic programming problem (because I am a bit
lazy) but will illustrate how much of a speed up you can get by using
memoization.</p>
<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">time</span>
<span class="k">def</span> <span class="nf">mem</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
<span class="n">mem</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">mod</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="n">key</span> <span class="o">=</span> <span class="nb">hash</span><span class="p">((</span><span class="n">args</span><span class="p">,</span><span class="nb">tuple</span><span class="p">([(</span><span class="n">k</span><span class="p">,</span><span class="n">kwargs</span><span class="p">[</span><span class="n">k</span><span class="p">])</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">])))</span>
<span class="k">if</span> <span class="n">mem</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">key</span><span class="p">):</span>
<span class="k">return</span> <span class="n">mem</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">val</span> <span class="o">=</span> <span class="n">fn</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">mem</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">val</span>
<span class="k">return</span> <span class="n">val</span>
<span class="k">return</span> <span class="n">mod</span>
<span class="nd">@mem</span>
<span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">or</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">fib</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fib</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">fib</span><span class="p">(</span><span class="mi">35</span><span class="p">)</span>
<span class="n">t2</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="k">print</span> <span class="n">t2</span><span class="o">-</span><span class="n">t1</span>
</pre></div>
<p>With the @mem decorating the function it takes: 0.0002 seconds to compute fib(35). Without @mem it takes about 10 seconds. (Results may vary depending on your computer).</p>
<p>Now for the second part:</p>
<blockquote>
<p>You are on an alien world preparing for a potential invasion. The planet has some sort of <a href="http://www.memory-alpha.org/en/wiki/Dampening_field">dampening field</a> covering it so you cannot use any sort of wireless communication. Your mission is to connect all the bases under your command with the least amount of wire. Every base must be able to communicate to every other base. A base will be able to communicate with any other base if a path exists between the two.</p>
</blockquote>
<p>This can be solved by creating a minimum spanning tree.</p>
<div class="codehilite"><pre><span class="n">bases</span> <span class="o">=</span> <span class="p">[</span>
<span class="c">#distance, #start base, #end base</span>
<span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span>
<span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span>
<span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span>
<span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span>
<span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">),</span>
<span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span>
<span class="p">(</span><span class="mi">6</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span>
<span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span>
<span class="p">(</span><span class="mi">6</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">),</span>
<span class="p">(</span><span class="mi">6</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span>
<span class="p">(</span><span class="mi">7</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span>
<span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">)</span>
<span class="p">]</span>
<span class="k">def</span> <span class="nf">wire</span><span class="p">(</span><span class="n">num_bases</span><span class="p">,</span><span class="n">data</span><span class="p">):</span>
<span class="n">base_to_set</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">connections</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">data</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">num_bases</span><span class="p">):</span>
<span class="n">base_to_set</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="n">i</span><span class="p">])</span>
<span class="n">cost</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">entry</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
<span class="n">base1_set</span> <span class="o">=</span> <span class="n">base_to_set</span><span class="p">[</span><span class="n">entry</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span>
<span class="n">base2_set</span> <span class="o">=</span> <span class="n">base_to_set</span><span class="p">[</span><span class="n">entry</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">base1_set</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="n">base2_set</span><span class="p">))</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">merge</span> <span class="o">=</span> <span class="n">base1_set</span><span class="o">.</span><span class="n">union</span><span class="p">(</span><span class="n">base2_set</span><span class="p">)</span>
<span class="k">for</span> <span class="n">item_id</span> <span class="ow">in</span> <span class="n">merge</span><span class="p">:</span>
<span class="n">base_to_set</span><span class="p">[</span><span class="n">item_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">merge</span>
<span class="n">cost</span> <span class="o">+=</span> <span class="n">entry</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">connections</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">entry</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="n">entry</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
<span class="k">return</span> <span class="p">(</span><span class="n">connections</span><span class="p">,</span><span class="n">cost</span><span class="p">)</span>
</pre></div>
<p>The function takes in the number of bases and a list of tuples that contain the cost and two base ids indicating they are connected.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-6-29-1-28-interview-prep-part-6-&-7.html</guid><pubDate>Sun, 29 Jun 2008 01:28:00 GMT</pubDate></item><item><title>interview prep part 5</title><link>http://www.infectmac.com/posts/2008-6-27-2-16-interview-prep-part-5.html</link><description><p>The problem today is to find "dead" nodes in a graph. This sort of algorithm could be applied to all sorts of things such as eliminating the unreachable states in a DFA or unreachable code in a compiler. </p>
<div class="codehilite"><pre><span class="k">class</span> <span class="nc">State</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="nb">id</span>
<span class="bp">self</span><span class="o">.</span><span class="n">outs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">visited</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">dead</span><span class="p">(</span><span class="n">begins</span><span class="p">,</span> <span class="nb">all</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">search</span><span class="p">(</span><span class="n">state</span><span class="p">):</span>
<span class="k">if</span> <span class="n">state</span><span class="o">.</span><span class="n">visited</span><span class="p">:</span>
<span class="k">return</span>
<span class="n">state</span><span class="o">.</span><span class="n">visited</span> <span class="o">=</span> <span class="bp">True</span>
<span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">state</span><span class="o">.</span><span class="n">outs</span><span class="p">:</span>
<span class="n">search</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">begins</span><span class="p">:</span>
<span class="n">search</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="n">removable</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="nb">all</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="o">.</span><span class="n">visited</span><span class="p">:</span>
<span class="n">removable</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">s</span><span class="p">);</span>
<span class="k">return</span> <span class="n">removable</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span>
<span class="n">ss</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">6</span><span class="p">):</span>
<span class="n">ss</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">State</span><span class="p">(</span><span class="n">i</span><span class="p">))</span>
<span class="n">ss</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">outs</span> <span class="o">=</span> <span class="p">[</span><span class="n">ss</span><span class="p">[</span><span class="mi">5</span><span class="p">]]</span>
<span class="n">ss</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">outs</span> <span class="o">=</span> <span class="p">[</span><span class="n">ss</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span><span class="n">ss</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="n">ss</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">outs</span> <span class="o">=</span> <span class="p">[</span><span class="n">ss</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span>
<span class="n">ss</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span><span class="o">.</span><span class="n">outs</span> <span class="o">=</span> <span class="p">[</span><span class="n">ss</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span><span class="n">ss</span><span class="p">[</span><span class="mi">4</span><span class="p">]]</span>
<span class="n">ss</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span><span class="o">.</span><span class="n">outs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">ss</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span><span class="o">.</span><span class="n">outs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">print</span> <span class="n">dead</span><span class="p">([</span><span class="n">ss</span><span class="p">[</span><span class="mi">1</span><span class="p">]],</span> <span class="n">ss</span><span class="p">)</span>
<span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">ss</span><span class="p">:</span>
<span class="n">s</span><span class="o">.</span><span class="n">visited</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">print</span> <span class="n">dead</span><span class="p">([</span><span class="n">ss</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="n">ss</span><span class="p">)</span>
<span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="n">ss</span><span class="p">:</span>
<span class="n">s</span><span class="o">.</span><span class="n">visited</span> <span class="o">=</span> <span class="bp">False</span>
<span class="k">print</span> <span class="n">dead</span><span class="p">([</span><span class="n">ss</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="n">ss</span><span class="p">[</span><span class="mi">1</span><span class="p">]],</span> <span class="n">ss</span><span class="p">)</span>
</pre></div></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-6-27-2-16-interview-prep-part-5.html</guid><pubDate>Fri, 27 Jun 2008 02:16:00 GMT</pubDate></item><item><title>interview prep part 3</title><link>http://www.infectmac.com/posts/2008-6-25-3-38-interview-prep-part-3.html</link><description><p>I have been asked to do basic string problems before. The problem for today:</p>
<blockquote>
<p>Given a string, print out each character that appears, the number of times that it appears and it must be done in the order the characters appear in the original string. And it must be done in O(n) time.</p>
</blockquote>
<div class="codehilite"><pre><span class="k">def</span> <span class="nf">do</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
<span class="n">seenMap</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">orderList</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">seenMap</span><span class="o">.</span><span class="n">has_key</span><span class="p">(</span><span class="n">c</span><span class="p">):</span>
<span class="n">orderList</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
<span class="n">seenMap</span><span class="p">[</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">seenMap</span><span class="p">[</span><span class="n">c</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">orderList</span><span class="p">:</span>
<span class="k">print</span> <span class="n">c</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">seenMap</span><span class="p">[</span><span class="n">c</span><span class="p">])</span>
</pre></div>
<p>The important thing here is to do it in O(n) time. It is easy to get trapped and do this in polynomial time. The trick here is to use a list to store the order that characters appear and to use a dictionary to keep track of if a character has been seen and how many times it has been seen. Provided that the has_key function has O(1) running time my algorithm is O(n).</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-6-25-3-38-interview-prep-part-3.html</guid><pubDate>Wed, 25 Jun 2008 03:38:00 GMT</pubDate></item><item><title>interview prep part 2</title><link>http://www.infectmac.com/posts/2008-6-24-1-59-interview-prep-part-2.html</link><description><p>This might be a pretty common interview question. I personally have never been asked it but it seems like a reasonable technical question. The problem today:</p>
<blockquote>
<p>Reverse a linked list in C. The function should have the following function signature: <code>node_t* rev(node_t* n);</code>.</p>
</blockquote>
<p>I will provide an iterative solution, and a recursive solution. I came up with the iterative solution all by myself. The technique I used for the recursive solution is based off the one from the <a href="http://cslibrary.stanford.edu/103/">Stanford linked list page</a> However, when I solved it today I did it from memory. I first saw their method of solving it about a year ago and liked it. The first time I tried reversing a linked list in C recursively was pretty ugly ordeal. It took multiple parameters. It had a wrapper function for something that did the work and probably had a special case for the first element to make sure it pointed at null. Bad in every way. But I learned from a better method.</p>
<p>Here is the iterative solution:</p>
<div class="codehilite"><pre><span class="n">node_t</span><span class="o">*</span> <span class="nf">rev</span><span class="p">(</span><span class="n">node_t</span><span class="o">*</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">||</span> <span class="n">n</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="k">return</span> <span class="n">n</span><span class="p">;</span>
<span class="n">node_t</span><span class="o">*</span> <span class="n">a</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
<span class="n">node_t</span><span class="o">*</span> <span class="n">b</span> <span class="o">=</span> <span class="n">n</span><span class="p">;</span>
<span class="n">node_t</span><span class="o">*</span> <span class="n">c</span> <span class="o">=</span> <span class="n">n</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">c</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
<span class="n">b</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">c</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">b</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span>
<span class="k">return</span> <span class="n">b</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>The idea here is to walk down the list and point the 'next' at the previous element. This is what reverses the list. The trick is to have 'c' keep track of the list. Once 'b-&gt;next' points to 'a' we would lose the rest of the list if we did not have 'c' holding onto it.</p>
<p>Now for the recursive solution:</p>
<div class="codehilite"><pre><span class="n">node_t</span><span class="o">*</span> <span class="nf">rrev</span><span class="p">(</span><span class="n">node_t</span><span class="o">*</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">||</span> <span class="n">n</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="k">return</span> <span class="n">n</span><span class="p">;</span>
<span class="n">node_t</span><span class="o">*</span> <span class="n">a</span> <span class="o">=</span> <span class="n">n</span><span class="p">;</span>
<span class="n">node_t</span><span class="o">*</span> <span class="n">b</span> <span class="o">=</span> <span class="n">n</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
<span class="n">node_t</span><span class="o">*</span> <span class="n">rr</span> <span class="o">=</span> <span class="n">rrev</span><span class="p">(</span><span class="n">n</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">);</span>
<span class="n">a</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">b</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span> <span class="c1">//brings the NULL along to the front</span>
<span class="n">b</span><span class="o">-&gt;</span><span class="n">next</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span>
<span class="k">return</span> <span class="n">rr</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>I drew my picture of the linked list and wrote the code. You should <strong>always</strong> draw a picture when dealing with data structures. It saves a lot of time and you usually end up getting the code correct the first time. The main idea behind this code is to first find the end of the list. The end of the list ends up being the 'rr' variable in this example. Then as the functions return the actual reversing takes place. This is difficult to explain. The best thing to do is to draw a picture of the operations taking place. That's the way I really understood it the first time. And it's how I build it from scratch whenever I need a little puzzle to solve. Just understand that the the reversing takes place on the way back up the call stack.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-6-24-1-59-interview-prep-part-2.html</guid><pubDate>Tue, 24 Jun 2008 01:59:00 GMT</pubDate></item><item><title>Interview Prep Part 1</title><link>http://www.infectmac.com/posts/2008-6-22-22-14-Interview-Prep-Part-1.html</link><description><p>The reason I am doing this is to prep myself for interview's I plan/hope to have this fall. My past experience has been pretty bad when it comes to technical questions. I usually end up feeling completely stupid because I get a fairly simple question wrong. And when there are just 2 or 3 during a 45 minute interview my chances of getting another interview plummet. So the plan is that everyday this summer I will solve one technical problem that might arise during an interview. I will also try and provide a couple of different solutions to illustrate possible pitfalls. All solutions will be implemented in Python or C.</p>
<p>The first problem:</p>
<blockquote>
<p>Given a <a href="http://en.wikipedia.org/wiki/Binary_tree">binary tree</a>, determine if it is a valid <a href="http://en.wikipedia.org/wiki/Binary_search_tree">binary search tree</a>.</p>
</blockquote>
<p>Wikipedia will do a better job of describing these two data structures. The task is to write some code that takes in a binary tree and returns true if it is a valid binary search tree and false otherwise.</p>
<p>To solve this problem I ended up doing an inorder traversal of the tree. This ends up being the best solution with O(n) complexity. So here it goes:</p>
<div class="codehilite"><pre><span class="k">def</span> <span class="nf">checkValidBtree</span><span class="p">(</span><span class="n">tt</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">inOrder</span><span class="p">(</span><span class="n">t</span><span class="p">,</span><span class="nb">min</span><span class="p">):</span>
<span class="k">if</span> <span class="n">t</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span> <span class="k">return</span> <span class="p">(</span><span class="bp">True</span><span class="p">,</span><span class="nb">min</span><span class="p">)</span>
<span class="n">valid</span><span class="p">,</span><span class="nb">min</span> <span class="o">=</span> <span class="n">inOrder</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">left</span><span class="p">,</span><span class="nb">min</span><span class="p">)</span>
<span class="k">if</span> <span class="n">valid</span> <span class="o">==</span> <span class="bp">False</span><span class="p">:</span> <span class="k">return</span> <span class="p">(</span><span class="bp">False</span><span class="p">,</span><span class="nb">min</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">min</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span>
<span class="nb">min</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">data</span>
<span class="k">elif</span> <span class="nb">min</span> <span class="o">&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="bp">False</span><span class="p">,</span><span class="nb">min</span><span class="p">)</span>
<span class="nb">min</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">data</span>
<span class="k">return</span> <span class="n">inOrder</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">right</span><span class="p">,</span><span class="nb">min</span><span class="p">)</span>
<span class="k">return</span> <span class="n">inOrder</span><span class="p">(</span><span class="n">tt</span><span class="p">,</span><span class="bp">None</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
<p>The inner function ends up doing the bulk of the work. The 'min' parameter is used to keep track of the most recently seen value in the tree. It is important because it allows us to verify that the next value in the traversal is always larger than the previous one. As soon as this rule is violated we know that we have encountered a binary tree that is not a valid binary search tree.</p></description><guid isPermaLink="true">http://www.infectmac.com/posts/2008-6-22-22-14-Interview-Prep-Part-1.html</guid><pubDate>Sun, 22 Jun 2008 22:14:00 GMT</pubDate></item></channel></rss>