Ask HN: What PHP Framework should I use? - <AUTHOR>

I'm building a healthcare tool -- about to land first client for a large amount of money. I wrote a bunch of code by hand in PHP with jQuery and Bootstrap. MySQL in the backend.
Most of the User Interface is scrolling through DataTables or looking at graphs (Google Charts API) based on the data.
I was looking at either CakePHP or CodeIgniter -- but I'm open to others.
What would HN recommend?
Thanks! <comment><USER2> [http://mavrck.com/blog/2013/01/ive-evaluated-php- frameworks-...](http://mavrck.com/blog/2013/01/ive-evaluated-php-frameworks- and-the-answer-is-laravel/)

A recent writeup (not by me).

Would not recommend CodeIgniter, last time (~1 year ago) I used it it was a pain to get a proper ORM working with it.

</comment><comment><USER3> <http://www.yiiframework.com>

It is actually really well suited to integrating existing code/database (with component architecture and model/controller generators) and takes a lot of principles from the RoR way of doing MVC.

</comment><comment><AUTHOR> Also, I'm a self taught developer and will be learning MVC and other concepts as I go.. From an old thread I'm seeing some people recommend Laravel but I haven't read into it further.

</comment><comment><USER4> <http://www.laravel.com>

</comment><comment><USER5> I recommend CodeIgniter Simple, fast, and did I mention simple?

</comment><comment><USER6> how about symfony?

or why not do what many PHP devs have, and learn Ruby, then use something like Rails.

<comment><AUTHOR> Well I'm interested in reusing my existing code and moving to a framework to increase flexibility and allow me to improve/update/change the site faster. I'd like this to be a small project of migrating my code into a framework.

</comment></comment><comment><USER7> I liked Silex

</comment><comment><USER8> yii</comment>


Show HN: Waves.js – Text animation in JavaScript - <AUTHOR> http://mateogianolio.github.io/waves-js/

<comment><AUTHOR> Apart from the great amount of fun you can have playing with it, are there any other (more useful) applications that can be developed from this?

I'm thinking along the lines of how it could make the layout of articles on the web more fluid. The algorithm is currently limited to fitting the text to the wave function on the right side, but could be expanded by adding alternating amounts of spaces on the left side.

Thoughts? Opinions?</comment>


Is this YC's algo? - <AUTHOR>

Submission hits New/New submission is graduated based upon a set level Level can be found by the following ...
Points count, but they count more when given by a user with higher Karma
Comments count, and might be weighted by karma of those who left them (to help rank the overall submission)
Time between comments, probably counts, although this is a little neglected with some stories on the main page have no comments.
(update) Sites that have made the front page before (or frequency) might have a "trusted" status and the level needed to obtain the front page lowered.
Pg, anywhere close? <comment><USER2> Umm...Isn't the source available in the examples included with arc?

</comment><comment><USER3> We should have algorithm hunts weekly on hacker news, that'd be sweet. Ahh, I sense a voice telling me I should get back into IRC...

</comment><comment><USER4> Ranking on stories/comments is not based on karma of the poster, but on how quickly a particular comment/story has been voted up.

But yeah, go check out the code.</comment>


DESIGN FRIDAY. THE COLOR OF GULF RACING - <AUTHOR> http://modular4kc.com/2011/04/22/design-friday-the-color-of-gulf-racing/

<comment><AUTHOR> OP here; I just thought this was so cool. It's not really about Gulf Racing, its about the 2 colors they chose. Here's an excerpt:

 _" This phenomenon is called "Equiluminant Colors". When our eyes encounter colors that are Equiluminant, we have a hard time assigning them positions, so the color tends to vibrate or move slightly. A great example of this is Richard Anusziewicz's painting "Plus Reversed". Artists use the technique of "equiluminance" to blur outlines and suggest motion. Because of the way our eyes and brains work, humans cannot perceive the edges of objects where object and background have the same luminance. If parts of a painting are equiluminant, their positions become ambiguous. They may seem to shift position or to float."_</comment>


Costco CEO Craig Jelinek Leads the Cheapest, Happiest Company in the World - <AUTHOR> http://www.businessweek.com/articles/2013-06-06/costco-ceo-craig-jelinek-leads-the-cheapest-happiest-company-in-the-world <comment><USER2> Costco is just starting to establish itself here in Australia. There is currently one store in my city (Melbourne). I personally know people who travel 40+km to shop there so they are doing something right. I understand that more "local" stores will be opening soon.

I'm not sure how the focus on pay & conditions translates across the pacific however; our national minimum wage for casual workers is already AU$20.34 (US$18.54) and we have universal healthcare. So I'm guessing the relative benefits of working for Costco are lower as compared to in the USA.

<comment><USER3> I grew up in Anchorage, Alaska, and its not uncommon for people who live in remote areas of the state to travel hundreds of miles to go to Costco. Mind you, they don't exactly have a local grocery store for the most part, but its interesting how widespread that usage pattern is.

<comment><USER4> That probably ties in nicely with Costco's emphasis on extreme bulk sales. If the nearest Costco is hundreds of miles away, at least you can buy a month+ worth of most supplies while you're there and load them all into your vehicle.

<comment><USER5> Also an Australian, Costco is also a single location here, 20km away. My house travels out there once every ~3 months for everything and spend ~$500

The only things we really buy from the supermarket are week to week things like meat etc.

</comment></comment></comment></comment><comment><USER6> Costco is also interesting due to subtle non-uniformity between stores and a steadily changing product line-up. I'm lucky to live in an area where I'm an easy drive to 3 Costcos within 10-15 minutes and 2 more within 25-30 minutes from my home and they all have subtly different products.

We'll find some item that we like there only for it to be completely gone 3 months later and never to return. While at another local Costco they have palettes full of it. 3 months after that the product will disappear from all Costcos and a different, but better one will show up everywhere. Things like Wine selection will also differ quite a bit from store to store.

That or there will be sudden changes to the packaging of staple items in the store for no real reason. Milk, for example, seems to get a packaging overhaul every year or so.

Either way, even with limited choice, _over time_ the number of products you might buy at a Costco turns out to be quite a few.

Other retailers, on the other hand, are surprisingly more uniform in their product selection. The half dozen Targets in my area offer more or less the same products and fit it all within 1 or 2 master floor layouts.

<comment><USER7> I have heard that Costco is brutal with their suppliers and has no compunction about dropping products if they can't get them at a price that makes sense, given the limited number of SKUs they're prepared to stock. Their customers are now more or less trained to expect this, but I think it's a definite weakness in their model. If Amazon can reliably provide me with my "favorite" detergent, I'm likely to forgive a few dollars a year in added cost.

Wine selection is probably a little easier to explain, given the bizarre maze of the three tier system. Thank god for the 21st Amendment, but the way states handle alcohol distribution makes me thankful for an expansive reading of the Commerce Clause.

<comment><USER8> I'm not sure that's a weakness so much as merely a difference.

Some people have a "favorite detergent". Other people, such as myself, just want something of decent quality, and could not really care less what name is on the container.

For you, Amazon's approach is better, because you're willing to pay more for the specific item you want. For me, that's completely unimportant, so why would I pay more?

The two companies are covering different niches in that respect. Nothing wrong with that. No single company needs to be all things to all people, although I suspect Amazon _wants_ to (and Costco does not).

<comment><USER7> Sure. If you can live the "Kirkland Life", you are Costco's perfect customer. But as the parent comment pointed out, their strategy puts them in a somewhat awkward position. As a rule, you want your customers to love your products. But then your business model requires that you take away products whether they're loved or not. Indeed, if they're loved so much that your supplier thinks they're entitled to a higher premium than an un-loved competitor, it's the more popular product that goes! Even the Kirkland products are doubtlessly farmed out to varying suppliers (with varying results).

You're probably right that there's a big market for consumers of "good enough, consistency be damned". But I think a lot of Costco's market is after convenience and "low enough" prices. If Amazon can hit "low enough" prices and a wider, more consistent selection, Costco could be in trouble. Zero trips to the store is better than one, especially when you don't need to supplement Costco with other retailers to cover their gaps.

<comment><USER8> Costco needs their customers to love their products _in aggregate_ , but not any one product in particular. They're good about quality, so I don't really have to care about brands. If I want detergent or paper towels or whatever, I just pick whatever looks good. If they pull one in favor of another, I don't care. If you want to buy specific brands on any given trip, Costco isn't for you, but if you just want something decent and don't care who made it, it works out well. You don't have to love the specific brands, just the stuff they carry in general.

I'm sure Amazon could cause a lot of trouble for Costco if they can match their prices or come close, but I don't see that happening. I basically buy three categories of products at Costco: frozen food, fruit, and non-perishable bulk items like paper towels or toilet paper. I can't see Amazon ever coming close on the first two, simply because the inherent costs of delivering perishable items to the house are too high. They can pull off Prime because they're delivering items that have no problem being in transit for two days, but I can't see how they could deliver e.g. strawberries for a reasonable price ever. I'd love to be wrong, but I don't see it happening.

<comment><USER9> I think I agree with both you and the commenter to whom you're replying. My general purchasing process involves:

1\. Go to Costco and purchase as many huge things in bulk as I can. People like to equate 'buying in bulk' with 'pricing', but honestly for me its just as much about the convenience: I don't care about saving $.50 on toilet paper so much as I care about having to buy toilet paper only once a year. I'm picky with some things (like hand soap), but like you said I know Kirkland products are going to be good enough.

2\. For everything else, buy off Amazon/Target/TJ's.

One of the cues I'm surprised Costco hasn't taken is subscription-based shopping (as in, I set up a list of X items that I can schedule for a pickup every few months) that would make this process even better. Given the decidedly non-marketing-oriented layout of their stores, I don't think they'd miss the opportunity for up-selling.

<comment><USER7> _Given the decidedly non-marketing-oriented layout of their stores, I don 't think they'd miss the opportunity for up-selling._

I think they're more marketing-oriented than you're suggesting. There's a reason I have to walk by the big-screen TVs every time I walk in to my Costco, and why they hire all those workers (who are contractors, no?) to give out food samples. Come to think of it, at my local store, everything you might want to "browse through", from clothes to books to seasonal stuff, is in the low-shelved center of the store, while the "dependables" are in the back.

I'm sure they make money from the members who buy the same dozen things every time they visit, but I bet they make a lot more from the folks who browse the sample stations and who buy TVs on impulse.

Anyway, that counters my argument about Amazon, since they'll never be able to hand out Bagel Bites!

<comment><USER8> I wouldn't be surprised if Amazon eventually reached the point where they start including samples in your shipments. "Based on your purchase history, your e-mail traffic, and data from the webcam we hid in your shower, we think you might like Product X. We've included a few, give them a try!"

<comment><USER10> I order TP and paper towels via Amazon prime and the other day I was shipped gratis a bar of soap. It wasn't an accident, it was listed as a gift on the invoice.

<comment><USER8> Fun. Clearly I'm behind the times. Either that, or it happened to me as well, and I forgot, but that subconsciously prompted the idea.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER11> Another company that treats its employees very well and enjoys similar success (though as it's privately held, it's not as easy to analyze) is Trader Joe's.

<comment><USER12> Astonishing as it belongs to the same foundation as Germanys Aldi, and Aldi is not known for it's people management.

[http://en.wikipedia.org/wiki/Trader_Joe%27s](http://en.wikipedia.org/wiki/Trader_Joe%27s)

<comment><USER13> I never knew Trader Joe's and Aldi's were related companies. I had jokingly referred to Trader Joe's as the "Aldi's" or organic food stores, but never thought the comparison was so close. I was mostly basing it off of the cheap prices and smallish store sizes.

I've generally been impressed by Aldi's ability to maintain a quality shopping experience while maintaining such low prices. Typically in the US, bargain- type stores tend to skimp on things like cleaning, repairs, merchandising/stocking, etc. This isn't really the case with Aldi.

<comment><USER14> As I remember hearing it... Companies are willing to do white label products for trader joe's because of the purchasing leverage of aldi

</comment></comment></comment></comment><comment><USER15> I remember investors getting mad at the CEO for paying his employees too much, that had me confused as a 12 year old amatuer stock picker. Great company, my friends work there and they love it

</comment><comment><USER16> Costco is one of 2 companies I truly admire. Always looking for more. Anyone with other suggestions?

<comment><USER17> Curious to who is the second? Penny for your thoughts?

<comment><USER18> I'd like to know too. Zappos? Just the first thought that came to mind. I don't know that much about them but I have heard good things.

</comment></comment></comment><comment><USER19> low turnover = higher profit

longer term employees = more knowledgeable = better customer service

some decade walmart and target might get a clue about this

<comment><USER9> The implication that Walmart and Target executives have a worse idea about what's best for their business model than someone who reads an article about CostCo is hilariously disingenuous.

<comment><USER8> The implication is that Wal-Mart and Target executives have a worse idea about what's best for their business model than Costco executives, which is not necessarily correct, but neither is it obviously wrong.

</comment></comment></comment><comment><USER20> I'm happy to see that they're treating their employees well. I really am. And I know this seems petty but; why the hell do they insist on starting Christmas in August? I walked into my local Costco last summer and one of the first things I see are Christmas tree's for sale. In August. I've grown to _HATE_ the Christmas holidays because of retail behavior like this.

</comment><comment><USER21> Awesome company, I just hope it's sustainable.

Good pay + Low prices seems like a difficult combination

<comment><USER8> They've been around for almost 40 years and are highly profitable. You don't have to "hope" it's sustainable, as it clearly is.

<comment><USER21> I was also thinking about them in terms of tech, relative to the marketplace.

If Amazon decides to open "Costozon" will Costco be able to compete?

<comment><USER8> If you mean a giant retail store, I think Costco will do fine. They have a lot more experience in that area, and they've done fine so far against existing cost-cutting retailers like Wal-Mart.</comment></comment></comment></comment>


Economic indicator: Spam sales are up - <AUTHOR> http://www.nytimes.com/2008/11/15/business/15spam.html

<comment><USER2> I completely misunderstood, I thought this article was going to be talking about sales from spam emails. Instead, it's about actual spam.

Still a great article, pleasantly surprised. Though as a person living in Hawaii, I haven't noticed an increase in spam habits with my friends: we regularly eat spam in spam musubies, in omelettes and fried rice - I think we are one of the top consumers of spam per capita, if not the top.</comment>


Startup Database for Early Adopters: Relaunch of StartupList - <AUTHOR> http://StartupLi.st

<comment><AUTHOR> StartupList is set to relaunch a new social experience for early adopters to discover brilliant startups.

What startup would you like to see on the new StartupList?</comment>


The Ruby Stdlib is not a Ghetto - <AUTHOR> http://blog.segment7.net/articles/2010/11/24/the-ruby-stdlib-is-not-a-ghetto

<comment><USER2> People also need to be a little more careful about using the word "ghetto". It has a long history, from Jewish ghettos in Europe during World War II, to modern day black ghettos that persist in most big cities in the U.S.

Many people today still grow up in "The Ghetto," which is a place of geographic, economic, and political marginalization. Before you go talking about "Wii is a ghetto" or "Ruby is a ghetto" you should really understand something about what that means, and who you might be affecting with your words.

And even if you've decided that you want to throw the word around, use it fucking properly. A ghetto is not just something that "sucks". Ghettos are defined not just by being run-down, but by being isolated in some way. If you want to say something sucks, just say it sucks.

<comment><USER3> _If you want to say something sucks, just say it sucks._

People also need to be a little more careful about using the word "sucks". It has a long history of homophobic connotations--originally it was used to denigrate people, generally men, by suggesting (in a derogatory sense) that they performed certain homosexual acts.

(When I was a kid, something that was really cheap and crappy was "ghetto"--"ghetto" being an adjective. Like if you had a really crappy car from the 80's, your car was ghetto. So maybe, even if the Ruby stdlib isn't _a_ ghetto, the Ruby stdlib is still pretty ghetto in the adjective sense.)

<comment><USER4> You should be more careful about using the word "People" with its connotations of common and of the masses (as distinguished from the nobility)..etc. etc. ;-)

<comment><USER2> I know you're trolling, but I'll bite. No one is hurt if you use the word "people". People are hurt when you use the words "ghetto" and "sucks". That's the difference.

See <http://en.wikipedia.org/wiki/Consequentialism>

</comment></comment></comment></comment><comment><USER5> This is tangential, but I've found that ruby's non-standard libs have, for the most part, been horribly named. Recall from the article: curb, nokogiri, syck, psych, home_run. Others: sinatra, rack, thin, unicorn, maruku. None of these give me the slightest clue about what they do, and if I wanted, for example, to parse XML, how on earth would I know that I wanted to find "nokogiri" (or "hpricot")? Could I pick what I wanted out of a lineup?

How do you ruby people find the good libraries when you need to perform a task? Is it all word-of-mouth (word-of-blog I guess)?

<comment><USER6> How do you propose to differentiate between multiple implementations of the same concept otherwise? It is nice that there is a "nokogiri" and "hpricot," unlike the PostgreSQL gems, which are called "postgres", "pg", and "postgres- ruby". The one you actually want to use is "pg" though.

Should "rack" be called standard-http-server-api-with-support-for-middleware, and then "unicorn" be called pre-forking-web-server-using-standard-http- server-api-with-support-for-middleware?

<comment><USER7> > Should "rack" be called standard-http-server-api-with-support-for- > middleware, and then "unicorn" be called pre-forking-web-server-using- > standard-http-server-api-with-support-for-middleware?

No, but perhaps we could have:

        WebServer = require_any_satisfying_protocol 'http-server/with-middleware-support'
        WebServer.new

where each rubygem installed has a table of protocols each of its classes and modules support. For example, Mongrel would have a table that starts:

        {Mongrel::HttpServer => ['http-server', 'http-server/with-middleware-support']}

<comment><USER8> There are two problems with that.

1\. In practice you almost never want to load a random library that says it supports a certain interface, you will want a specific library. Notable exceptions are glibc where the interfaces are well-defined over several decades but that brings us to...

2\. Few libraries implement the same exact interface. Mongrel and Unicorn have totally different interfaces. Phusion Passenger is also a web server but works in a fundamentally different way from either of them. Hpricot and Nokogiri are both XML parsers but their usage API is different.

<comment><USER7> Thus, I imagine, why djacob's link to HTTPI talks about protocol _adapters_ , rather than expecting the implementations to adhere to the protocols directly. Still, the adapters could come with each protocol-supporting gem, rather than being housed in some third party "interface library." Then we could have something more like this in each class of a gem:

        class Mongrel::HttpServer
          class HttpServerProtocolAdapter < Gem::ProtocolAdapter
            implements 'http-server'
            implements 'http-server/with-middleware-support'
            ...

and the manifests (which would then look more like this:)

        {'http-server'                         => Mongrel::HttpServer::HttpServerProtocolAdapter,
         'http-server/with-middleware-support' => Mongrel::HttpServer::HttpServerProtocolAdapter,
         ...}

would be generated automatically at gem installation by loading the gem and then probing for ProtocolAdapter instances in ObjectSpace.

Of course, if you had a class that matched the protocol exactly, you could just use something like

        class Mongrel::HttpServer
          supports_protocol 'http-server'
        end

and be done with it.

This is all assuming that we don't actually want our protocols to be modules or classes or something else that we have to include in the adapter somehow (because this is Ruby, and we do well without needing IDuck.) Instead, protocols would just be externally specified things, with their name-strings perhaps being the URIs of standards docs. At most, if a Gem::Protocol was a reified type, it would be a unit test suite to determine whether a ProtocolAdapter actually supported its protocol (minimally, via a series of #respond_to?s.)

</comment></comment></comment></comment></comment><comment><USER9> We should probably aim higher than "not a ghetto" :)

I didn't read the article in great detail, but I noticed this:

      it provides many ways to do the same thing for programmer convenience

This is not a good thing, in my opinion.

I do, however, find it peculiar that utilities like RSS, FTP and mail handling are included in a stdlib.

<comment><USER10> > This is not a good thing, in my opinion.

This is extremely common, and not at all unique to Ruby. For example, providing defaults for parameters is perhaps the most common and simplest form of this.

Whenever a library is used by wildly different clients, there is a good chance the API it chooses will be better suited to one or the other. The same Net::HTTP is presumably used for the simplest of uses, maybe 5 line download scripts, and the most complex of cases, perhaps forwarding http requests with all headers intact.

In general I go by "minimal, but complete"; but for widely used libraries that have clients of very different complexities, it makes sense to provide a simple API for convenience. I'd rather not be specifying the client headers, user agent, supported encodings, etc, etc each time I want to fetch a file over http.

</comment></comment><comment><USER11> With all due respect, Net::HTTP _is_ clunky. I'm typing the following from memory, too:

        require 'open-uri'
        response = open("http://blog.segment7.net/").read

<comment><USER12> that's great if all you're trying to do is HTTP GET. standard libs are supposed to make all use cases fairly easy. making an http post isn't too bad:

      Net::HTTP.new(host, port).start do |http|
        post = Net::HTTP::Post.new(url)
        post.set_form_data('blah' => '123')
        http.request(post)
      end

<comment><USER13> That's "not too bad" if you're coming from Java. Thankfully most other Ruby libraries have significantly less verbose APIs than this.

<comment><USER14> There's a much simpler way to do POSTs with Net::HTTP:

      response = Net::HTTP.post_form(URI.parse("http://example.com"), {:param => "val"})

</comment></comment></comment></comment><comment><USER15> His counter argument seems to be that the original blog post didn't offer alternatives or patches and so it is invalid.

Which of course is not a counter argument at all.

IMO the Ruby stdlib is a mess. Denying it won't improve it.

</comment><comment><USER16> His argument is rather poor. The other post doesn't offer details or alternatives, but all his does is offer details that really don't support his argument ("it's /only/ 2.4 times slower, and you should use persistent connections anyway!"). What kind of defense is that?</comment>


Hospital Kept Vegetative Patient on Life Support to Boost Survival Rates - <AUTHOR> https://www.propublica.org/article/audio-shows-hospital-kept-vegetative-patient-on-life-support-to-boost-survival-rates <comment><USER2> This is classic Goodhart's law [1]. Humans or systems of humans will automatically game any metric that is used to measure them. Whenever you start using a number of measure performance, people start to forget about ethics.

This is also happening in university education these days where professor's performance is being measured by metrics that only roughly correlate to teaching ability. So, profs spend more time ensuring their metrics don't fall below the acceptable value than they do trying to improve their teaching performance. In other words, introducing these bad metrics to somehow measure and improve teaching performance, actually results in worse teaching performance.

[1] "When a measure becomes a target, it ceases to be a good measure." or

"when a feature of the economy is picked as an indicator of the economy, then it inexorably ceases to function as that indicator because people start to game it." [https://en.wikipedia.org/wiki/Goodhart%27s_law](https://en.wikipedia.org/wiki/Goodhart%27s_law)

<comment><USER3> I had previously heard about similar problems with surgeons not wanting to dent their "mortality" rate by refusing to operate on cases that were in some way likely to result in death.

Obviously this results in worse outcomes for those patients either by requiring a less experienced surgeon or possibly not being operated on at all.

Can't immediately find a citation.

</comment></comment><comment><USER4> This is why healthcare is broken. I've also heard that hospitals can lose accreditation for having bad outcomes and will turn away risky patients which is just as horrible.

<comment><USER5> Healthcare in the US certainly.

I mean other health care systems have various problems but when the profit- motive (in the form of the hospital administration) clashes with the medical side, we know which one usually wins.

</comment></comment><comment><USER6> So, basically, everybody wins

</comment><comment><USER7> Isn't this the perfect case of having the wrong incentives?!</comment>


A tutorial for creating 3D lenticular prints using a non-3D version of Photoshop - <AUTHOR> http://www.vicgi.com/lenticular-interlacing-algorithm.html

<comment><USER2> That's exactly what I need. I've been searching this algorithm for years to write my Photoshop action script. Thanks!

</comment><comment><USER3> Great article! Very informative.</comment>


Complexity of Python Operations (2013) - <AUTHOR> https://www.ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt <comment><USER2> People reading this write-up should keep in mind that the author uses the term "complexity class" incorrectly. When the author says this, they actually mean "worst case runtime". It never dives into space complexity, which is yet another complexity measure for evaluating the performance of these operations. In some spots they completely abuse big O notation to make it do things it is not supposed to. For example:

"O(==) is the complexity class for checking whether two values in the list are =="

This stuff needs to be fixed since it is only going to lead to later confusion (and embarrassment).

A complexity class is a set of problems that tend to be similar in resource requirements. O(f(n)), more or less, means asymptotically bounded from above by c*f(n) for some constant, c, as n -> inf. It is a general way to represent the asymptotic growth rate of functions and is NOT married to the concept of complexity classes.

<comment><USER3> > When the author says this, they actually mean "worst case runtime".

Actually, the author says that all dict operations take O(1) time, which is the best (or average) case and not the worst case. I think it should at least mention the worst case! No hash table exists where you get worst case O(1) (non-amortized) for all three of insertion, deletion, and lookup. You either have to resize the table at some point or you have to deal with hash collisions.

(BTW, I've been asked this question numerous times in job interviews and answering O(1) without qualifying the statement is definitely wrong.)

See [https://wiki.python.org/moin/TimeComplexity](https://wiki.python.org/moin/TimeComplexity)

and [http://cs.stackexchange.com/questions/249/when-is-hash- table...](http://cs.stackexchange.com/questions/249/when-is-hash-table- lookup-o1)

<comment><USER4> This is a good point. The reason for this error in the notes, I believe, is that they are for an introductory programming class at this university and introducing this nuance may put off some students with its complexity.

</comment></comment></comment><comment><USER5> Some of these don't seem quite right. For example, set difference:

      Difference    | s - t        | O(len(t))     |

Worst case, we do something like `set(range(1000)) - {1}`; the bulk of this is going to be making a copy of s from which to subtract t, which is O(|s|). (If this were `s -= t`, I'd agree, O(|t|).) (Same logic applies to the other set operations.)

      Clear         | d.clear()    | O(1)	     | similar to s = {} or = dict()

I would actually guess d.clear() is O(|d|) _in CPython_ : you're doing to need to deref each item in the dictionary[1]. Similarly, earlier it states,

      Binding a value to any name is O(1).

If there's already a value stored in the variable that gets unref'd, leading to more derefs… (though I don't know how you'd express that in O(…); perhaps we might say that it might be a larger constant time than you expect!)

      Note that for i in range(...) is O(len(...)); so for i in range(1,10) is O(1).

I feel like O(…) notation's purpose in life is to show how an algorithm's complexity in time or space responds to changes in its inputs. Saying a constant expression such as `for i in range(1,10)` is "O(1)" somewhat misses the point, I feel, as there aren't any real inputs to vary. (As opposed to `for i in range(n)`, where the `n` is an unknown input, and the run time of the loop is going to be O(n).)

      check ==, !=  | s != t       | O(min(len(s),lent(t))

(this is for sets again) This one isn't wrong, but there's an interesting opportunity for the notation here, I feel. CPython keeps track of the set's length along with the data internally[2], and checks that prior to iteration over the set[3]; so you _could_ notate this `O(|s|) == O(|t|)` as the worst case. This is because in the worst case, |s| and |t| must be equal; if they're not, the internal size comparison fails, and you're O(1) (how long to check the sizes). (A lot of language implementations' set implementations do this I think; in fact, I'd say most programmers would expect it, because they'd expect len(a_set) to be O(1).)

Also, I think some of these are great examples of just how easy CPython's implementation is to read in many cases.

[1]: see this, for example: [https://github.com/python/cpython/blob/0eb5f5996feed30ade8c2...](https://github.com/python/cpython/blob/0eb5f5996feed30ade8c2e8a7f5a056c3006965d/Objects/dictobject.c#L1355-L1359)

[2]: [https://github.com/python/cpython/blob/0eb5f5996feed30ade8c2...](https://github.com/python/cpython/blob/0eb5f5996feed30ade8c2e8a7f5a056c3006965d/Include/setobject.h#L46)

[3]: [https://github.com/python/cpython/blob/0eb5f5996feed30ade8c2...](https://github.com/python/cpython/blob/0eb5f5996feed30ade8c2e8a7f5a056c3006965d/Objects/setobject.c#L1835-L1836)

<comment><USER6> How do you deal with GC in reality though? I mean, if you include it in calculations, then any operation which derefs an object is at least `O(number_of_heap_objects)`. Or in a compacting GC anything that creates a new object potentially is at least `O(heap_size)`.

I think it makes perfect sense to ignore this.

Edit: actually it's higher than `O(number_of_heap_objects)` for refcount, because you can trigger a cycle collector which is unlikely to be `O(N)`

<comment><USER5> I thought about trying to generalize the previous post to a generic GC, but it proved more difficult, so I left it out.

In my first post, I was mostly focused specifically on CPython, which does ref-counting with some GC to catch cycles. I was ignoring the real GC and cycles in my post; my understanding of d.clear() is that the ref counting happens and happens immediately, so _at best_ it's still O(|d|). My main point was that in the implementation you're likely to be using, it happens at the time you run the code, and can thus change the order notation of the code (and perhaps how you expect it to perform, though you did have to construct d, which was O(|d|) at best to begin with…).

In a generic GC, I was thinking it _might_ be fair game to ignore the GC. If GC can be done completely concurrently with the remainder of the app, and doesn't end up effectively stealing resources (mostly, CPU, I guess) from the app, then I think I might be persuaded to call it "free", or at least close to it. One might cynically call a "never free; just alloc and let the OS free on process death" a very naive form of garbage collection, and there, it is definitely close to free.

</comment></comment></comment><comment><USER7> pattis ftw

<comment><USER8> It's pretty cool that you guys like your professor so much and that probably means he's an awesome prof, but comments like these don't belong here, so the community is likely to treat them pretty harshly.

We'd be happy if you stuck around and learned the ways of HN and started making solid contributions, so please do! Best to read these links to get an idea of what's good on the site:

[https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html)

[https://news.ycombinator.com/newswelcome.html](https://news.ycombinator.com/newswelcome.html)

</comment></comment><comment><USER9> Based Pattis

</comment><comment><USER10> This is my professor</comment>


Uses of Tmux Explained - <AUTHOR> http://www.slideshare.net/spolu1/uses-of-tmux-explained

<comment><USER2> These slides are always so out of context without hearing the audio presentation, or better, seeing the video of the presenter.. when I flip through these slideshows with the mem/macros/whatever they are called, I always imagine the audience sitting there, forced smiles, maybe a cough, and then on to the next slide.

These should be refactored after the local presentation. Like how episodes of The Simpsons will cull out really topical jokes that won't be funny in a month for the sake of syndication.

tmux is cool, and wemux is a tool we use regularly to share sessions. I am an old screen guy and appreciate that there is something similar being produced, as both products get invigorated by new features and bug fixes. I believe there is even a screenrc mode for tmux so that I can keep my muscle memory - what a great feature!

<comment><AUTHOR> The presentation will actually take place tomorrow. I'll do my best to be entertaining!

<comment><USER3> Will it be taped? Would be interested in seeing it :)

</comment></comment></comment><comment><USER4> I have a feeling tmux would be useful to me, but it seems to be one of these things where all the documentation is useless unless you already understand it.

I understand it's a terminal multiplexer: so, on the one side, I have one or more terminals (typically pseudo; X or ssh in my case), and one or more ∗nix sessions (typically each a single process group; shells and their children like editors). In between sits tmux, with its 'sessions' and 'windows' and 'clients' and 'buffers' and 'panes'. What are these things, how are they related, and how do they correspond to ∗nix sessions and terminals?

Or have I got it all wrong? <http://i.imgur.com/zJGunty.png>

<comment><USER5> Nice PNG, heh.

First of all, "clients" are the things that TFA labels "tmux (screen)". Each of "windows" and "panes" are things you can ignore, or not, as you find them useful. Windows are like browser tabs, panes are screen-splits. I use windows, I don't (yet) use panes. Otoh, many people are in it just for the planes. YMMV. But you cannot use tmux without "clients" and "sessions".

Second of all, `man screen` does discuss the theory and how things interact. So if you have 20 or 30 minutes, you can read the man page and basically Learn All The Things.

\</comment></comment><comment>----

Third, you said you're interested in m:n. Maybe my tmux workflow is relevant to you.

I have, let's imagine, a need for 5 terminals. "notes", version-control, make/tests/etc, misc-bash, and vim. I make space on my desktop physical monitor for three terminals (100x60); but only one on my laptop (100x40).

I start by creating one Session that contains five Windows, and each window corresponds to one of the five ptys that I want (notes, vcs, make, bash, vim). But I can only view one of these at a time, right?

      TMUXSESS=foo
      tmux new -d -n notes -s "$TMUXSESS"1     # new detached session "foo1", with window "notes"
      tmux neww -P -n vcs -t "$TMUXSESS"1:     # new window "vcs" in existing session "foo1"
      tmux neww -P -n make -t "$TMUXSESS"1:
      tmux neww -P -n bash -t "$TMUXSESS"1:
      tmux neww -P -n vim -t "$TMUXSESS"1:

So now I could connect three (or twenty) clients all to the same session. BUT, this isn't the solution, because they'd all the same view of what I'm doing (which is amusing at first, but useless).

But, hooray, introducing another tmux concept, "groups". "Groups" are groups of sessions, that contain the same windows, but do not have to share a view.

      tmux new -d -s "$TMUXSESS"2 -t "$TMUXSESS"1   # new session "foo2" grouped with "foo1"
      tmux new -d -s "$TMUXSESS"3 -t "$TMUXSESS"1

Now I open my three gnome-terminals. In the first one I do

      tmux a -t "$TMUXSESS"1    # attach to "foo1"

and likewise for the second and third.

And if I feel like working from my laptop, I vpn+ssh to my desktop, and just attach another tmux client to foo1 or foo2 or foo3. This one shares a lock- stepped view with the session it's attached to, but who cares, I'm not watching the desktop. Tmux resizes every session to the minimum-sized attached client, so it's important that I _detach_ my laptop-client when I wanna go back to my desktop. If I forget, no problem, tmux lets me do that from either keyboard (though I have to look up the syntax to do it from my desktop's keyboard).

So, 5 things to look at, 3 or 4 views into those things, arbitrary swapping each to the other. I haven't been using this very long. It's GLORIOUS. Does that help?

<comment><USER4> Yes, that sounds very close to my intended workflow, and 'groups' are the thing I was missing to make it work.

</comment></comment><comment><USER6> Since this is a post about tmux, I feel obligated to tell you about teamocil (<http://teamocil.com>) a small utility I wrote to automatically create sessions, windows and panes in tmux with YAML files :)

<comment><USER7> Your site hijacked my back button, so we're not friends anymore.

<comment><USER8> How did it hijack your back button? My back button works perfectly fine navigating to and from this site.

<comment><USER9> It seemed to hijack in Firefox but not Chrome (Ubuntu), but it's a little hard to tell since the site's dependency on documentup.com, which appears to be taking a shit right now, is screwing with page loads and such.

<comment><USER7> Yeah, I'm on Firefox.

</comment></comment></comment></comment></comment><comment><USER10> This is what I use with Tmux: [https://github.com/sorin- ionescu/prezto/blob/master/modules/...](https://github.com/sorin- ionescu/prezto/blob/master/modules/tmux/init.zsh)

Basically a daemon session is started (if it wasn't there before) and every terminal you open automatically connects to that session. This means that you can close every terminal, the session is still open and new terminals will use the already existing session. As long as tmux itself isn't stopped (reboot, etc.) you'll stay in the same session.

Which is cool because everything is de facto detached.

<comment><AUTHOR> That's a pretty cool setup. These slides have been prepared for a 4mn lightning talk so I had to keep things simple and short enough!

Anyway, I really like your setup. I'm thinking these days about writing my own terminal multiplexer just for fun using node.js. I already have the VT emulation part ready so there's no that much work left to do.

Do you have any feature you don't have in tmux that you would love to see in a terminal multiplexer or is tmux just right for you?

<comment><AUTHOR> BTW if someone is interested by a reusable VT emulation library in javascript: <https://github.com/spolu/vt.js>

</comment></comment></comment><comment><USER11> By Thor, are image macros really necessary? It seems you can't have a technical presentation these days without some silly generic "memes" sprinkled all around, it's ridiculous.

<comment><USER12> You need _something_ , yes. The purpose of a presentation is to be entertaining enough that your audience will not be bored to tears, and will actually still care about the subject after you're done.

Images work well, because they evoke a more emotional response. Memes are there for a different reason - they are a non-verbal way of saying "hey, we're all part of the same subculture. I'm one of you!".

Yes, presentations are to some extent an exercise in psychology, at least when they're good.

If you just want to convey info, a whitepaper/article is a better choice. Information density is _much_ higher there.

</comment></comment><comment><USER13> I sit beside a coworker who wrestles with tmux daily.

He likes it, but it also frustrates him; it crashes semi-regularly, it sometimes locks out input when one program is spamming one of the tiles, and due to it intrinsic nature you can no longer select-copy large blocks of text with the mouse if you have any vertical splitters.

The lack of block text select-copy is alone enough to keep me away.

Most of the other benefits can be gotten with screen, with better reliability and performance. I use several customized .screenrcs for various tasks, to get started up quickly every reboot. But I don't run screen in every terminal because native scrollback buffer is too valuable.

<comment><USER14> Mac specific, but hold option+command when selecting and you can select in block mode.

<comment><USER13> Block mode selects don't know whether to wrap lines or not; most half-decent terminals keep track of whether wrapping was due to carriage return or hitting the last column.

I do this all the time to e.g. select deleted files from a git status command so I can xclip paste the selection out through awk to xargs git rm (or rather, use some scripts which simplify the above). Similarly for rspec / cucumber test results to extract out the failures for use with $(<failures.txt) on repeated runs as I fix broken tests. I have a script that analyzes ruby stack traces, which I copy from the crashed session. All sorts of ad-hoc clickery, I rely on word wrap being detected consistently.

</comment></comment></comment><comment><USER15> I love tmux and I use for my daily work.

I switched from screen after reading this awesome book: <http://pragprog.com/book/bhtmux/tmux>

<comment><USER16> Seconded. That book make tmux usable for me. I switched from Screen and haven't looked back since.

</comment></comment><comment><USER17> Tmux is great for working together with someone. Syme[1] uses tmux as well, and allows you to quickly program on a GitHub project with others, without setting up a server or needing to add users. I think this is relevant, as it shows the convenience of tmux.

[1] <https://syme.herokuapp.com/>

</comment><comment><USER18> So as a user of emacs, a user of tmux, and the soon to be recipient of a dell XPS 13 which I intend to dock at home with a very big screen and use with Xmonad... Do I need tmux?

It seems to fall between the gaps between easily switching between panes and applications, which you can do with Xmonad and what you can do with buffers in emacs.

With my previous setup I used tmux to run all my deamons (web servers I was developing on, continuous coffeescript and less building etc) in one terminal, but I'm not sure there was a huge benefit vs just opening a new terminal for each process (in hte same workspace) and using Xmonad to manage the layoutt/switching. Am I missing a trick here?

<comment><USER19> It's useful if you need to connect to a remote server and leave stuff running after you disconnect. Otherwise... you already have a window manager.

<comment><AUTHOR> I definitely agree that the multi window/pane feature of tmux can be repetitive of your window manager, especially if you use a tiled window manager.

But at the same time I keep thinking that most people do not use their window manager to manager their browser tabs (despite the existence of surf (<http://surf.suckless.org/>). Why? Not sure...

<comment><USER19> It's much more useful to have several terminals displayed on the same screen. On the other hand, 20-30 tabs? Not so much.

</comment></comment></comment></comment><comment><USER20> I've written a CLI (ruby gem: tmux-connector) that uses tmux to help you handle connections to multiple servers with ease. I use it on a daily basis to manage ec2 instances. <https://github.com/ikusalic/tmux-connector>

</comment><comment><USER5> Every slide that says "tmux (screen)" should say "tmux (client)".

This is especially true because when people who view these slides google for more information, and they google for "tmux screen", they're gonna get rants about tmux vs screen.

EDIT: also, I would suggest renaming this to "elementary uses of tmux explained". Because obviously this is like 1% of the use of tmux (but the best 1% to start with, imo!)

</comment><comment><USER21> If one likes tmux, may I recommend having a look at 'byobu'. It's built to use either tmux or screen as a backend and provides some features that make life slightly easier than using barebones tmux or screen. However, I must warn that it is just a matter of convenience and it doesn't really add anything significant.

</comment><comment><USER22> So.. I never really understood why we need tmux/screen beyond some vanity things like running irc clients. Most applications should have sufficient log output to a file. Editing a document, want to return to it later? Save the thing.

Not sure I understand why people would be so excited about this tool?

<comment><USER23> The traditional monster use-case for screen is making your login session independent of the terminal connection. So you can do your work from home, detach your screen session, go to work, re-attach from work, and continue where you left off. If your terminal connection dies, you can just re-attach from a new connection.

It also offers other convenient session management functions like multiplexing of multiple shells (maintaining a separate screen image and scrollback for each), cut-and-paste, etc., but the above is the big one I think.

</comment></comment><comment><USER24> Don't want to sound too greedy, but I can't wait for your following tmux presentation ;)

</comment><comment><USER25> I would use only tmux instead of a wm/de if I could get 256 colors with it in fbterm.

</comment><comment><USER26> ah you see thanks for reminding me of this thing I wanted to try: <http://byobu.co>

</comment><comment><USER27> I heard about tmux at work two days ago, very powerful, nice prez.

</comment><comment><USER28> Nice presentation!</comment>


Ask HN: How to Raise Money for Healthcare SaaS at Idea/concept Stage? - <AUTHOR> I have an idea for Healthcare that makes hospitals become the insurer, taking out the middleman, while covering more people locally, and also without the hassle of hiring medical billers.
The SaaS is essentially a networked billing solution to act as the intermediary between multiple hospitals and auto-bill patients monthly.
Development for something like this -- to cover legal, and hipaa, etc is going to be somewhat costly - if it succeeds it could revolutionize healthcare in America, even negate the need for Single-payer healthcare.
How does one approach Angel's or Vc's on an 'idea' only?
Right now it's just a concept, as I have a family to feed so can't devote much time to this because I'm business doing freelance dev work. <comment><USER2> Have you created a deck ? It would help immensely if you have a deck on how your solution/SaaS solves a problem. Also networking, goto Meetups. Try YCombinator or TechCrunch Disrupt.

Just my 2 cents.</comment>


Gender and speedcubing - <AUTHOR> http://rcm-papers.info/gender-and-speedcubing.html

<comment><AUTHOR> The complaining about women's representation at conferences seems to be predicated on the belief that women would be equally represented if merit assessment was unbiased (thus gender imbalance is proof of bias): well, here is a situation where merit assessment is unbiased (performance is measured by a timer). And the gender situation is more or less the same (women's representation is much lower at the top than overall). This leads me to conclude that the women in tech complaining is unfounded.</comment>


Brain region discovered that only processes spoken, not written words - <AUTHOR> https://www.sciencedaily.com/releases/2019/03/190321163609.htm <comment><USER2> > if a patient in the study saw the word 'hippopotamus' written on a piece of > paper, they could identify a hippopotamus in flashcards. But when that > patient heard someone say 'hippopotamus,' they could not point to the > picture of the animal

It's obvious the written word and the spoken word are stored separately in the brain. I remember once following a sign at a zoo which said "Hippo ---> ", and when we got there someone said "Wow, look at dat potamus!"

</comment><comment><USER3> I have never understood psychotic or schizophrenic people to have said, "The text I read in my head told me to do it!"</comment>


Application for Astronaut candidate class of 2013  - <AUTHOR> https://cosmicrays.wordpress.com/2011/11/15/nasa-now-accepting-applications-to-the-astronaut-candidate-class-of-2013/

<comment><USER2> heh, that's me! was wondering where those HN hits were coming from... thanks for dropping by.</comment>


Show HN: Solve and generate mazes with JavaScript on HTML Canvas - <AUTHOR> https://github.com/dmaydan/Maze_Solver_Generator <comment><USER2> [https://bost.ocks.org/mike/algorithms/#maze- generation](https://bost.ocks.org/mike/algorithms/#maze-generation) has some visualizations for various different maze generation algorithms.

<comment><USER3> Great link. Here's another good one.

[https://www.jamisbuck.org/mazes/](https://www.jamisbuck.org/mazes/)

<comment><USER4> And here's another one. It introduces maze building ideas in a simple way.

[http://www.jamisbuck.org/presentations/rubyconf2011/index.ht...](http://www.jamisbuck.org/presentations/rubyconf2011/index.html)

</comment></comment></comment><comment><USER5> It would be cool to see the cells checked as well. To someone unfamiliar with BFS, the demo makes it seem like the process of finding the solution doesn't involve exploring any other tiles than the solution itself.

<comment><USER6> A pretty neat example of this is mbostock's A* search: [https://beta.observablehq.com/@mbostock/best-first- search](https://beta.observablehq.com/@mbostock/best-first-search)

</comment></comment><comment><USER7> I explored the test site and tried different maze sizes with values in the 50s, 70s, 110s, 150 (including odd numbers). Curiously, I found the maze could be visually divided into four Cartesian-like quadrants. Consistently the middle divider had only one gap, and other major quadrants also consistently have only one gap. So, when I wondered if BFS solution might be different if I ran it multiple times, I couldn't tell. Because of the curious constraint I just mentioned, all paths had to traverse these major divisions through the same gap. In other words, if there was variance, it would be constrained to a very small movement in a corner.

I imagine if I dived into the code I would realize if my hypothesis that multiple runs of the BFS would always result in the same solution, was plausible or not. And it might also be the case if I understood BFS more, I would also know if it would always result in the same solution.

But how much fun if I could see it visually with a few clicks in the GUI.

Thanks and Good luck.

<comment><AUTHOR> Thanks so much for the compliment. This is probably a bi-product of the maze generation algorithm I used. Essentially, at every step, the algorithm bisects the maze horizontally or vertically - then, it chooses a random cell along this bisection to leave open (that way the 2 resulting regions are still connected). Then, the same algorithm is performed on the 2 new regions. Recursion continues until it no longer makes sense to continue bisecting.

Wikipedia has an article on maze generation that explains the algorithm - [https://en.m.wikipedia.org/wiki/Maze_generation_algorithm](https://en.m.wikipedia.org/wiki/Maze_generation_algorithm)

<comment><USER8> I can confirm that that's exactly what happened, different generation algorithms have a different "texture" to them in precisely this way and those textures do sometimes have a byproduct of making the maze easier or harder to solve.

The algorithm with the least helpful "texture" is probably Wilson's algorithm, which basically says: choose a point at random out in the unsolved territory and begin a random walk: when you reach the solved territory (the maze as it is already known), add those points back to the maze; when you self-intersect you should delete the random walk back to where you self-intersected. (For the very first walk, furthermore, there is only one "solved" point in the maze so you may wish to speed up maze generation by doing a different random walk that just "busts down walls" into the as-yet-unknown area; this is called Aldous- Broder and it has the opposite problem where it tries to randomly walk into unsolved space so it takes forever when the unsolved space becomes rare.) So one would start from,

        function* randomWalkPoints({ x, y }, height, width) {
          const incr = [{dx: -1, dy: 0}, {dx: 1, dy: 0}, {dx: 0, dy: -1}, {dx: 0, dy: 1}];
          while (true) {
            const { dx, dy } = incr[Math.floor(4 * Math.random())];
            const new_x = x + dx, new_y = y + dy;
            if (new_x >= 0 && new_x < width && new_y >= 0 && new_y < width) {
              x = new_x;
              y = new_y;
              yield { x, y };
            }
          }
        }

Now, the algorithm might get a bit weird because it looks like you are using block mazes rather than conventional thin-walled mazes; every n-by-m thin- walled maze has an embedding as a block maze of size (2n+1)-by-(2m+1) simply by making (0, y) and (x, 0) all walls, every (odd, odd) point is empty space representing one of the squares of the original maze, every (even, even) point is a block, and (odd, even) and (even, odd) points are blocks if and only if there is a vertical/horizontal wall between the corresponding squares in the original maze. So all of the resources you will find are talking about mazes that look like,

        ╔═══════════╦═══════╗
        ║           ║       ║
        ║   ╔═══         ═══╣
        ║   ║               ║
        ║   ║    ═══╗    ═══╣
        ║   ║       ║       ║
        ║   ╚═══════╣   ║   ║
        ║           ║   ║   ║
        ╠═══════    ╚═══╣   ║
        ║               ║   ║
        ╚═══════════════╩═══╝

and then in your context this becomes:

        X X X X X X X X X X X
        X . . . . . X . . . X
        X . X X X . X . X X X
        X . X . . . . . . . X
        X . X . X X X . X X X
        X . X . . . X . . . X
        X . X X X X X . X . X
        X . . . . . X . X . X
        X X X X X . X X X . X
        X . . . . . . . X . X
        X X X X X X X X X X X

So I'm not 100% sure whether you would want to just restrict yourself to block mazes of this type, or whether you would want to just try something like "I modify Wilson's to keep track of walls I have already placed, too, and then when I intersect with myself on a path that already hit a block wall, I discard back to the open-space which placed that block" to get a slightly more general vision of the problem... I am not sure how you'd want to handle that.

<comment><USER9> +1 for the ascii art alone. HN never ceases to amaze me

</comment></comment></comment></comment><comment><USER10> Nice. I created a maze solver in js and canvas as well, solving using the A* and Tremaux algorithms.

You can even create your own mazes by passing json in the url.

Simple Maze Solver in HTML5 and Js [http://www.primaryobjects.com/maze/](http://www.primaryobjects.com/maze/)

</comment><comment><USER11> This will be an interesting book to read... also showcasing multiple maze generation algorithms: [https://pragprog.com/book/jbmaze/mazes-for- programmers](https://pragprog.com/book/jbmaze/mazes-for-programmers)

<comment><USER12> I love this book. It's on my retirement pile! (Hopefully mazes will still be relevant by then.)

</comment></comment><comment><USER13> Bug Report: [http://prntscr.com/mcyc1b](http://prntscr.com/mcyc1b)

When the website loads, if I put in a large number such as 500 and hit the generate button, it does not clear the previous puzzle and overlays on top. Second click still shows it bit now its a but transparent. Third click removes it altogether. I tried to skim through the code but not sure what the cause is given that you create a new Maze every single time. It seems to be some sort of canvas rendering bug as if I clear the canvas [1] it seems to work.

1: [https://stackoverflow.com/a/2142549](https://stackoverflow.com/a/2142549)

<comment><AUTHOR> Thanks a lot for the bug report! You're right - I was forgetting to clear the canvas on render. So I added ctx.clearRect(0, 0, WIDTH, HEIGHT); to the start of the render method.

</comment></comment><comment><USER14> I'm surprised it doesn't allow you to "draw" on it to solve the maze. That seems like an essential (and easy to add) feature.

<comment><AUTHOR> What sort of drawing are you thinking? Dragging the mouse around on the screen or navigating with the arrows?

<comment><USER14> Well I would pick drawing with a mouse, but arrow keys would work in a pinch.

</comment></comment></comment><comment><USER15> Very cool! I started making a very unpolished game based on a similar sort of map design a few months ago for ludum dare -- caution that there are sounds on this link and no volume control: [https://wcarss.ca/maze_of_sacrifice/](https://wcarss.ca/maze_of_sacrifice/)

</comment><comment><USER16> It's cool, but I expected some explanation about the steps, challenges. Luckily the HN crowd filled that in :)

</comment><comment><USER17> The solutions for mazes of size 50-200 look quite like a river on a map; which is pleasant to me.

</comment><comment><USER18> Nice work!

Seems to freeze if you put a number too high though. Perhaps you should add a limit?

<comment><AUTHOR> Thanks for checking it out! I am wondering how big is the number you are putting in? If the number is really high, it's probably causing a stack overflow. I would limit the size, but each browser has its own recursion limits so that would be quite a pain. In retrospect, I probably should not have used a recursive algorithm for this task :).

<comment><USER19> I put in a value of 500, and while it didn't freeze completely, it really struggled to respond.

<comment><AUTHOR> Recursive division may be elegant, but it seems that may also have its disadvantages.

<comment><USER20> One trick you could use is to add a setTimeout or asnyc/await somewhere during the recursion. By forcing a step to be asynchronous, the stack count will be reset.

</comment></comment></comment></comment></comment><comment> dan-robertson Solving mazes of the kind of size one can see tends to be an easy problem in that once you know about eg breadth first search it isn't too hard to write a program that will solve this sort of maze. Solving them is still necessary to show there is a solution but it isn't super interesting because it is sort of obvious that breadth-first search gives the best solution and if you know about it then it is quite easy to think of using breadth-first search.

A much harder problem is generating mazes.

The algorithm used here seems to be:

1\. Know how to generate a tiny maze 2\. To generate a big maze, divide it into smaller mazes, generate those, then cut some things out (the tiny maze algorithm) to connect the sub mazes.

You can see the bias in the algorithm from the grid pattern inside the generated mazes.

One might wonder how to generate mazes such that each possible valid maze has the same probability of being generated.

First one should define what a valid maze is. Here it seems the definition should be something like:

A maze is an array of cells which are either white or black such that:

1\. There is no 2x2 square of white squares

2\. There is no 2x2 square of black squares (maybe this could be changed?)

3\. Any two white squares are connected by a unique* path of (horizontally/vertically) adjacent white squares with no loops

* one may want to drop the uniqueness requirement.

I do not know how one would uniformly generate all such mazes.

Another definition of maze that I do know how to generate uniformly is one made of thick maze cells and thin separating lines:

A maze is a spanning tree of the graph where the nodes are cells and the edges are possible passages (so for a squarish maze the graph would basically be a grid: nodes at integer coordinates and edges between any horizontally/vertically adjacent nodes).

The problem of generating such a maze uniformly is therefore the same as that of picking a spanning tree such that each spanning tree is chosen with the same probability. An algorithm for this is _Wilson's algorithm_ and works as follows:

1\. Pick (not necessarily randomly) some node and add it to your spanning tree (so your tree has one node and no edges)

2\. Pick (not necessarily randomly) some node not in your tree. If no such node exists then you are done. Say that the current path is this node.

3\. Randomly (uniformly) choose an edge touching the last node of the current path (it is ok to not choose the edge which is the last edge of the current path). Add that edge and the node on the end to the current path.

4 (a). If the current path contains a loop then delete all nodes (and edges) in the loop. Go to step 3.

4 (b). If the last node of the current path is in the spanning tree, add the current path to the spanning tree. Go to step 2.

4 (c). Otherwise go to step (3).

This algorithm isn't _too_ hard to implement (although drawing this sort of maze is a bit annoying). A compatible definition of maze with this one that fits into a "grid of black and white cells" pattern is the following:

A maze is a rectangular array of cells which are either black or white such that:

1\. All cells with odd x and y coordinates are white

2\. All cells with even x and y coordinates are black

3\. For any two given white cells, there is exactly one path (ie with no loops) of adjacent white cells between them.

If one redraws the spanning tree and current path occasionally as this algorithm runs, the animation of maze generating is quite interesting to watch.

I think implementing these sorts of maze drawing generating and solving algorithms is good fun and quite a varied exercise. It's definitely one I like doing.

Here is a visualisation of Wilson's algorithm: [https://bl.ocks.org/mbostock/11363008](https://bl.ocks.org/mbostock/11363008) Observe how different the shape of the tree is between runs.

If you want to skip implementing it yourself first and just see the result then here it is for a maze: [https://bl.ocks.org/mbostock/11357811](https://bl.ocks.org/mbostock/11357811)</comment>


How Fake Money Saved Brazil - <AUTHOR> http://www.npr.org/blogs/money/2010/10/04/130329523/how-fake-money-saved-brazil <comment><USER3> The article doesn't tell lies, but it certainly spices up a lot the story. Some points to clarify:

* The "finance minister who knew nothing about economics" was actually a very respected sociologist, a senator and a very intelligent and skilled politician. He later became known as president Fernando Henrique Cardoso. I.M.O. one of the best 3 presidents this country had.

* What Edmar Bacha, Pedro Malan and others did was to break inflation's inertia/momentum. A lot of people already knew it was necessary; but no one else knew how to do it.

* The article doesn't comment on the strict and cautious monetary policy implemented by Fernando Cardoso. It was as much important as the "fake money" trick.

* Big inflation was a huge tax on the poorest people. Because they were poor, they didn't have the knowledge and means to protect against rising prices. It is because inflation ended that they began consuming more and the country increased their internal markets.

[Edit]Wikipedia has a more comprehensive explanation about what we call here Plano Real : <http://en.wikipedia.org/wiki/Plano_real> [/Edit]

<comment><USER4> It's also valid to mention that the impeached president also ended up helping out in one way: he froze the saving accounts, since one way to stop inflation is to cut down the buying power of the population.

<comment><USER3> That is what classic theory says and, in truth, for a brief period of time, inflation receded when Collor (the impeached) froze savings.

However the fact is that it recovered back again to high levels during Collor's mandate.

The cut down in buying power was achieved mostly through fiscal policy, not consumption restriction.

<comment><USER4> Well, I was 7 back then, so I really said what someone else explained to me. That was my bad.

</comment></comment></comment></comment><comment><USER5> _"He said, 'Well, I've just been named the finance minister. You know I don't know economics, so please come to meet me in Brasilia tomorrow,' " Bacha recalls._

So, three things had to happen:

1\. A politician had to admit his ignorance

2\. Some bright spark technocrat somewhere had the right solution to a seemingly impossible problem.

3\. The right politician asked for help from the right technocrat

They're not kidding. It _is_ a miracle.

<comment><USER6> And it definitely felt like one. You have no idea how much the country changed (for the better) because of this improbable miracle.

Nobody believed it would work because the whole country had lost faith in "magical" economic reforms like the one before it, the Collor Plan.

Imagine you wake up one day and all of your bank accounts are frozen - that's what happened to my parents (and most of the population) on March 16, 1990 when the Collor Plan was announced. It's your money, but you can't spend it - sorry. My father had been saving money in order to buy a new house. Years later he recovered less than 1/10 of the original sum. Lots of small businesses (including family and friends) went broke.

When I talk to my parents about pre-real days it feels like they were born in a different country than I was.

<comment><USER7> Wow, I guess that explains the uptick in the brazilian population in South Florida during that time. One year of school I only knew one brazilian kid on the bus. The next year over half the bus was brazilian. Big migrations like that usually happen because of economic reasons or war. I just never put 2 and 2 together until now.

</comment></comment></comment><comment><USER8> It's a 100% real story. I lived in these days. I had to put a feature called "currency change" in my softwares because every year we had to divide by 1000 all values in databases. One major work was to adjust fields sizes because currency values are allways causing data overflow.

<comment><USER9> > we had to divide by 1000 all values in databases

Those were the days!

It's absolutely impossible for me to say how much I paid for my first car. I know it were 4000 monetary units, but I cannot recall its name nor how much it cost. That's weird.

</comment></comment><comment><USER10> Wow. Last night I was thinking... if I was a supermarket manager in an inflation-ridden country, how would I save money by not changing price tags everyday? And my answer was to set one of my products as "1 Unit" and just price every other product in multiples of that "Unit". That way I only had to change the price of a single product!

And then today I read this! What a coincidence! I never would've thought you could scale up this technique up to do it to the whole country!

<comment><USER11> During the hyperinflation in the Weimar Republic, grocers dealt with this by changing the organization of their stores. Instead of grouping like-kind items together, they grouped like-priced items, then they would just bump the prices for each aisle.

</comment></comment><comment><USER12> So they used the real, which was fake, to make the money that was real fake, so they could make real money out of the fake real.

Dr. Seuss would be proud.

<comment><USER13> _Dr. Seuss would be proud._

Or Baudrillard.

</comment></comment><comment><USER14> It's an interesting story but the frightening thing is the comments of people wondering out loud what's wrong with inflation, or asking for more inflation in the USA.

Out of control inflation is a terrifying, society-destroying phenomenon. Stable and prosperous societies rely on stable money values.

<comment><USER15> The people who are asking for more inflation in the USA are asking for something in the 2% range, or (for those who are truly bold) asking for prices to rise to the level they would be at if inflation had remained in the 2% range for the past five years or so.

Stable money is good, but so is providing people with an incentive to spend and invest, rather than incentives to hoard cash and default on their debts.

<comment><USER3> Sorry, but this is playing with fire.

What scientists, technocrats and economists forget is that public policy is rarely driven by rationality. It is driven mostly by private interests, demagoguery, blind ideology, prejudice and the public misconceptions.

The idea of taking a little bit of a very dangerous medicine is something that no one should take lightheartedly.

<comment><USER16> It's also "playing with fire" to, in the name of keeping inflation down, depress demand so much that it plunges the whole country into a massive recession. In other words, any economic policy can be taken too far, and the dangers of any approach can be caricatured and exaggerated. It's not like the policy of inflation fighting isn't equally driven by "private interests, demagoguery, blind ideology," &c.

<comment><USER17> Demand _should_ be depressed because it was artificially stimulated before.

ie. if demand for homes was normal and not stimulated by easy money then there would not have been a housing bubble. a dotcom bubble. etc.

Government stimulated demand is the problem not the solution. (see my other post a few msgs above)

</comment></comment></comment></comment></comment><comment><USER18> Heh. I always assumed that the name of the currency, real, has the meaning "royal". Instead, it's literally the same as the English word. What an interesting story.

Have any other governments suffering from high inflation tried this?

Instead of calling it a fictional unit, they could also just use an existing currency like the euro for the transitional period, then switch to a new national currency that has an initial exchange rate of 1:1 against the euro. (I'm picking the euro because it has a fairly neutral image, with over 20 countries using it already.)

<comment><USER19> I would assume that the Brazilian real is named after the Portuguese real which does mean "royal". It is an odd name in a democratic country, though.

<comment><USER20> You are correct that 'real' means royal but it also means true or authentic (similarly in English).

I think that probably more accurately describes their intention behind the meaning of the name.

When I lived in Brazil in the 1990's, shortly after the currency changed from Cruzeiros to reais, the exchange rate was around 1.5. Today, it's 1.69 - <USER2> have been some relatively mild fluctuations since then but it has stayed remarkably stable.

<comment><USER14> You're right when you think about it - royal does have a double meaning of 'real' - as in 'what a royal pain in the ass'.

</comment></comment></comment></comment><comment><USER21> Anyone here who experienced post-Soviet currency collapses would instantly remember prices in У.Е. ("convention unit", in reality a legal way to put U.S. dollar price tag), monthly re-indexed МРОТ ("salary unit"), and so on. Alone they did not help anything, until economy and fiscal policies fundamentally changed.

<comment><USER22> Until oil prices skyrocketed, I'd say.

<comment><USER21> Inflation receded by 1996, well before oil prices went up.

</comment></comment></comment><comment><USER23> I don't understand something about this story.

Hyperinflation is primary caused by government printing money right? So if switching to another currency helped stop this...I get how it could help people changing their perceptions, but wouldn't the root cause be that the government stopped printing money with the new currency?

It seems like it would have been almost as effective if they had simply stopped printing more of the original currency until things stabilized?

Maybe I'm missing something. But the article seems to put too much weight on this clever idea of shifting to a new currency. While if monetary policy had stayed the same with the new currency I don't think it would have made any difference. The monetary policy here was the important part, not the new currency.

<comment><USER24> I had the same question. The Wikipedia article on the URV lead me to "Inertial inflation."

 _In the medium-to-long term, economic agents begin to forecast inflation and to use those forecasts as de facto price indexes that can trigger price adjustments before the actual price indices are made known to the public. This cycle of forecast-price adjustment-forecast closes itself in the form of a feedback loop and inflation indices get beyond control since current inflation becomes the basis for future inflation (more formally, economic agents start to adjust prices solely based on their expectations of future inflation). At worst, inflation tends to grow exponentially (leading to hyperinflation)._

<http://en.wikipedia.org/wiki/Inertial_inflation>

<comment><USER23> Interesting, thanks for posting that (it is probably what the author is basing it on)...although it's probably more accurate to call this one theory of how it could happen.

The reasoning behind it doesn't fully make sense to me.

Simple reason: people spending money as fast as they can (the shot in the arm that can accelerate hyperinflation) has a natural limit: when people have no more savings! So I don't think it's correct to call this a positive feedback loop. It has a natural limit that could be reached quite quickly under hyperinflation.

Indexes can only takes things so far too - if you (as a business owner) follow them and nobody can afford your products, you'll quickly figure it out and drop prices. So it seems weird to say indexes could cause hyperinflation over any medium-long time frame.

</comment></comment></comment><comment><USER25> 80% per month sounds crazy, but it is not even close to top 6: [http://en.wikipedia.org/wiki/Hyperinflation#Worst_Hyperinfla...](http://en.wikipedia.org/wiki/Hyperinflation#Worst_Hyperinflations_in_World_History)

</comment><comment><USER26> An extra level of indirection?

Reminded me of the quote: "All problems in computer science can be solved by another level of indirection"

<comment><USER27> ...except too many levels of indirection.

<comment><USER28> I think you can solve that, to some degree, with a cache (if it's performance that's troubling you) or a simplified facade (if it's the complexity of the deep stack).

Yes, those are indirections.

<comment><USER27> Then you have cache invalidation problems (one of the two known hard problems in CS), as well as impedance mismatch issues with your facade.

</comment></comment></comment></comment><comment><USER29> All money is of course "fake" in that it only has value if people believe that it does. Economics could be thought of as a branch of psychology, with "real value" being connected to the transient and sometimes hard to quantify needs, wants and desires of people.

</comment><comment><USER30> "Brazil's inflation rate hit 80 percent per month. At that rate, if eggs cost $1 one day, they'll cost $2 a month later."

Really.

<comment><USER31> Rule of 72

Divide 72 by the periodic interest rate to find the number of periods to double the money.

<http://en.wikipedia.org/wiki/Rule_of_72>

<comment><USER32> Great rule, should be the very first thing taught in high school when you get to exponents.

Dr. Albert Bartlet of University of Colorado has an excellent lecture on its implications for population growth, environmental degradation, and other big picture problems:

<http://www.youtube.com/watch?v=F-QA2rkpBSY>

</comment></comment></comment><comment><USER15> ...and now that Brazilians are no longer so spooked by inflation that they spend money as soon as they receive it, three Brazilian banks are among the world's top ten credit issuers. ([http://www.npr.org/blogs/money/2010/10/04/130329294/life- on-...](http://www.npr.org/blogs/money/2010/10/04/130329294/life-on-the- installment-plan?ft=1&f=93559255))

One liberal wonk wonders if this is a sign that the country is facing a consumer debt bubble. ([http://yglesias.thinkprogress.org/2010/10/tomorrows- credit-b...](http://yglesias.thinkprogress.org/2010/10/tomorrows-credit- bust/))

</comment><comment><USER33> The article never mentioned it, but it's a called a _wage-price spiral_.

</comment><comment><USER34> Hopefully the U.S. won't ever have to deal with this type of issue (out of control inflation). I'm very surprised that inflation hasn't hit the U.S. yet in a big way, but from what I hear that is because China and the U.S. are buying U.S. treasury bonds in a big way.

<comment><USER4> but the big problem for you guys is: it's expected that China holds something around 1 trillion of the US GDP in treasury bonds. So whenever they feel the US economy isn't trustworthy anymore, selling these will hit like a train.

their growth rate is really high right now, so it's a delicate situation.

<comment><USER35> The Chinese can't stop buying bonds if they want to keep their currency depressed relative to the dollar. Moreover, they have no intention of stopping the gravy train - tanking the US economy (further) would only hurt their own largest market, and no other large market is as willing to accept one-sided trade and currency policies as the US.

</comment></comment></comment><comment><USER36> There's no such thing are fake money, only false promises. Money is debt on the side of the government. Fake money therefore, is debt that the government defaults on.

</comment><comment><USER37> wonderful article.. I really love it :) it raises lots of question how this is possible, how many people get impacted.. Anybody did any significant financial loss?? or few people know about this able to take any benefit?? but this is definitely a bold decision and executed well towards result..

</comment><comment><USER38> What are the implications of this for startups?

Has a startup ever benefited from using a fake currency? In what ways?

<comment><USER39> Inflation is a useful tactic to make RPG style games addictive.

I worked with someone who built a popular facebook RPG game, and part of what made it popular was that as you became an established player the amount earned per day rose exponentially. As the game became more and more popular the virtual economy started to hyperinflate almost out of control, and the established players started hitting the MySQL integer limits. The author never expected that would ever be possible, but the exponential rate of inflation plus the exponential rate of new players joining created a giant pyramid scheme.

<comment><USER40> Good story, reminds me of a favorite quotation: _The greatest shortcoming of the human race is our inability to understand the exponential function. — Albert Bartlett_

<comment><USER41> From what I've seen, I think that we don't understand S-curves, either. No matter which side of it we're on.

They can look exponential... until they hit the limit.

</comment></comment></comment></comment><comment><USER42> It is coming to the USA. It is called the SDR.

</comment><comment><USER43> Will this trick work in America?

</comment><comment><USER44> It's a matter of governement control (assuming your are not connected to the outside world/Internet and don't have, therefore, a real-time currency update).

Let's assume gov. X, printed an additional $3bn. Will prices increase? No, they won't. The gov. can use this money, to do things, like building roads, schools... These expenses has to be considered as investments; if roads are built, industry will benefit and exports will increase lowering the inflation that the gov. had already made.

So the gov. can print as much papers as they want. It's paper in the end. But the ROI of the money they spent/printed, is going to decide if inflation will happen or not (in the future).

If inflation is spiking, it means the gov. lost control over the banking sector and a new currency needs to be made to return confidence to people and companies.

<comment><USER45> The government could do things like building roads, but they are usually just using that extra paper to pay off their debts, which makes investors demand a higher interest rate to hold the debt, which leads to a vicious cycle. Inflation is caused by the speed of money creation exceeding the speed of creation of real value, and the banking sector is not the only actor in the money creation process.

<comment><USER46> That was the problem in Brazil, money was created not to invest but to pay existing debt.

<comment><USER47> Not really. Brazil's inflation had an extra factor helping it: lots of prices (as well as salaries) were automatically revalued by "triggers". The plan wouldn't have worked if the government hadn't also dropped all these mechanisms.</comment></comment></comment></comment>