#88/111: Skunk Works

What is it about?

If you never heard of Skunk Works, it is a innovation branch of Lockheed which specialized in building air crafts. Kelly Johnson managed since the creation to 1971 and was succeed by the author Ben Rich. Ben Rich tells about their projects, their philosophy and why Skunk Works was one of the most special projects in the USA.

What can I learn?

Prototype and improve: The Skunk Works was originally built as a prototyping/R&D/innovative branch of Lockheed. Therefore they approached problems differently. Instead of years planing, they built lots of prototypes, tested them and improved them. They never wanted to achieve perfection (80% is good enough). This allowed them to give 3-5 prototypes to their customer (often the CIA or Air force), so their customers could test them in depth without spending hundreds of millions of dollars.

Rapid development cycles: This was an other main advantage of Skunk Works over lots of other innovation branches. Kelly Johnson wanted the engineers to be at most 40 feet away from the shop workers because he wanted them to see how their designs were created. Furthermore, it allowed both sides to communicate more easily and the shop workers felt that they are important.

Bureaucracy is your enemy: Ben Rich tells about two similar projects. One was completed in 6 months and with about 50 people. The second one took 24 month and about 200 people. Why? Thanks to comptrollers, regulations and such. Skunk Works worked independently from Lockheed which was unique and extremely important. Kelly Johnson hadn’t promoted people because of seniority, which is quite normal in most corporations. He also hadn’t allowed outsiders (e.g. gov’ officials) to stay at the Skunk Works for a long time. He managed the shop independently and successful.

Conclusion

Skunk Works is a awesome book but although a bit lengthy. It’s extremely interesting to see how such great air vehicles were built and which methods they used to keep their startup spirit alive. Essentially this book covers so much stuff which was rediscovered recently, like MVPs, lean development, etc. Definitely worth reading. Recommendation!

#87/111: Make: Electronics

(Picture by Rain Rabbit)

The book

Firstly, I forgot to take a photograph, therefore I use this picture by Rain Rabbit from flickr.

I wanted to refresh my electronics knowledge and decided to work through this book. Charles Platt introduces you gently into electronics, beginning with measuring current up to building your own robot car. About the first half of this book is pretty good, however lacking lots of rather important theory. That is, if you never heard the theory before and want to dive deeper into electronics, you should consider reading other books. If you’re just a hobbyist who wants to build some stuff, this book and some googling should be sufficient. A big problem for many people is the high start up costs for electronics in contrast to programming which this book doesn’t really consider. Especially in the last quarter of the book you had to invest hundreds of dollars to build your stuff, which isn’t really acceptable. In conclusion, if you want to dive into electronics this book is pretty neat however if you just want to refresh your knowledge, you should look into more theoretical books like Basic Circuit Analysis. If you’re completely new to electronics, one of these electronics kits would probably be a better choice.

Concrete Abstractions: Chapter 12

Exercise 12.4: Draw a tree, analogous to Figure 4.4 on page 92, showing how the value of C(4, 2) is computed by choose. Your tree should have C(4, 2) at the root and six 1s as its leaves.
Solution:

Exercise 12.6: Using these procedures, write
a. A procedure called table-fill! that takes a table and an element and sets every entry in the table to the given element. For example, (table-fill! table 0) would have a similar effect to that of zero-out-vector! in Section 11.6.
b. A procedure called display-table that nicely displays its table parameter.

Solution:

(define table-fill!
  (lambda (table value)
    (define loop-row
      (lambda (row column)
        (if (= column (table-width table))
            'done
            (begin
              (table-set! table row column value)
              (loop-row row (+ column 1))))))
    (define loop
      (lambda (row)
        (if (= row (table-height table))
            'done
            (begin
              (loop-row row 0)
              (loop (+ row 1))))))
    (loop 0)))

b.

(define display-table
  (lambda (table)
    (define show-row
      (lambda (row column)
        (if (= column (table-width table))
            (newline)
            (begin
              (display (table-ref table row column))
              (display " ")
              (show-row row (+ column 1))))))
    (define show
      (lambda (row)
        (if (= row (table-height table))
            (newline)
            (begin
              (show-row row 0)
              (show (+ row 1))))))
    (show 0)))

Exercise 12.31: Imagine the following game: You are given a path that consists of white and black squares. The exact configuration of white and black squares varies with the game. You start on the leftmost square (which we’ll call square 0), and your goal is to move off the right end of the path in the least number of moves. However, the rules stipulate that:
If you are on a white square, you can move either 1 or 2 squares to the right.
If you are on a black square, you can move either 1 or 4 squares to the right. […]
Write a memoized version of fewest-moves.
Solution:

(define fewest-moves-mem
  (lambda (path)
    (let ((table (make-vector (vector-length path))))
      (define fewest-moves-f
        (lambda (path i)
          (cond ((>= i (vector-length path))
                 0)
                ((equal? (vector-ref path i) 'white)
                 (+ 1 (min (fewest-moves-sub path (+ i 1))
                           (fewest-moves-sub path (+ i 2)))))
                (else
                 (+ 1 (min (fewest-moves-sub path (+ i 1))
                           (fewest-moves-sub path (+ i 4))))))))

      (define fewest-moves-sub
        (lambda (path i)
          (ensure-in-table! path i)
          (vector-ref table i)))

      (define ensure-in-table!
        (lambda (path i)
          (if (vector-ref table i)
              'done
              (store-in-table! table i))))

      (define store-in-table!
        (lambda (table i)
          (vector-set! table i (fewest-moves path i))))

      (vector-fill! table #f)

      (fewest-moves-f path 0))))

Exercise 12.33: The function h(n) is defined for nonnegative integers n as follows:
h(n) = \begin{cases} 1 & \text{ if } n<2\\ h(n-1) + h(n-2) & \text{ if n } < \text{2 and n is odd}\\ h(n-1) + h(n/2) & \text{ if n } \geq \text{2 and n is even}\\ \end{cases}
a. Write a dynamic programming procedure for efficiently calculating h(n).
b. Is it possible to modify the procedure so that it stores all the values it needs in a vector of fixed size, as walk-count can be modified to store the values it needs in a two-element vector? (A vector of “fixed size” is one with a size that does not depend on the parameter, n.) Justify your answer.
Solution: a & b. I implemented b directly into the code.

(define h
  (lambda (n)
    (let ((vector (make-vector (+ n 1))))
      (define calc-h
        (lambda (n)
          (cond ((< n 2) 1)
                ((odd? n) (+
                           (calc-h-sub (- n 1))
                           (calc-h-sub (- n 2))))
                (else (+
                       (calc-h-sub (- n 1))
                       (calc-h-sub (/ n 2)))))))

      (define calc-h-sub
        (lambda (n)
          (vector-ref vector n)))

      (from-to-do 0 n
                  (lambda (i)
                    (vector-set! vector i (calc-h i))))

      (calc-h n))))