tag:blogger.com,1999:blog-151450592024-03-07T17:47:48.700-05:00predelusionalIf being delusional is having a false persistent belief or opinion not substantiated by sensory or objective evidence, then this blog is about what happens just before that. So, as you read and respond, keep the goal in mind. There is a big difference between being almost insane and being barely insane. This blog is about that difference.Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.comBlogger371125tag:blogger.com,1999:blog-15145059.post-61468965466334963032023-11-09T10:49:00.001-05:002023-11-09T10:49:41.400-05:00Ensign Rod indexYears ago, i wrote a seven part set of very short related stories. Part zero was rejected. The publisher wanted action, not set up. Part one was published to a collection of these stories. Later, this collection was dropped from the Internet. The goal was about 1,000 characters per story. My goal was to get as much plot as i could in that short space. I hadn't yet read any of Kathy's helpful Slash the Word Count hints.
https://kathysteinemann.com/Musings/word-count-main/ <br />Please enjoy Ensign Rod, the micro-story.
<br /><br />
https://predelusional.blogspot.com/2008/06/rod-part-zero-of-six.html<br />
https://predelusional.blogspot.com/2008/06/rod-part-one-of-six-battle.html<br />
https://predelusional.blogspot.com/2008/06/rod-part-two-of-six-adrift.html<br />
https://predelusional.blogspot.com/2008/06/rod-part-three-of-six-winders.html<br />
https://predelusional.blogspot.com/2008/06/rod-part-four-of-six-historian.html<br />
https://predelusional.blogspot.com/2008/06/rod-part-five-of-six-its-tie.html<br />
https://predelusional.blogspot.com/2008/06/rod-part-six-of-six-coffee.html<br />
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-51684991964809510322021-05-20T19:44:00.003-04:002021-07-19T08:28:24.772-04:00The golang tutorials<p> I started learning Google's computer language "go" (also called golang, likely due to how easy it is to search for "go" in Google) about three years ago. I run Linux, so I downloaded "go" and started the tutorials. I think i got pretty far into it because i wrote a couple of the benchmarks i've written in other languages: c, fortran, perl, java, guile (scheme), php. These are the matrix multiply and the prime number sieve. It took a while, but i found the "go" sources on my system. They even work.<br /></p><p>However, i had upgraded my Linux operating system to Linux Mint 19 (Mint is derived from Ubuntu, which is derived from Debian). I needed "go" again, so i installed it from the repository. Really easy. I got go version 1.10. The current version is 1.16.</p><p>I started the tutorials again, thinking i'd breeze through them, just as a refresher. However, bits from the tutorial stopped working pretty quickly. I did a bunch of Google searches. Frankly, it was frustrating. Eventually, concentrating on this one problem all day, i stumbled across something that suggested that the command "<b>go mod tidy</b>" was introduced in go version 1.14. I told the Linux package manager to remove go, downloaded the version 1.16 tarball and installed it.</p><p>That's what i get for trying to learn a new fast changing language. Hopefully, i'll use it often enough that i won't have to go through the tutorial again. At least my benchmarks still work.</p><p><br /></p>Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com1tag:blogger.com,1999:blog-15145059.post-14333591400113050222021-01-11T17:27:00.005-05:002021-01-11T17:27:55.016-05:00JOKER<p>One of the things i'd like to find out from a movie review is if i'll like the movie, but if at all possible, without learning the entire plot with nuances. And that's what is attempted here with Joker.</p><p>https://www.imdb.com/title/tt7286456/</p><p>Let me be clear. There's a pandemic, so i'm not saying you should go out and see this. I'm also not saying you should rent it or stream it. Be safe. But read on to see if you're wasting your time/money.<br /></p><p>The 2019 movie, <b>Joker</b>, is an origin story for the (primarily) DC's Batman villain - <i>The Joker</i>. As a comics fan, i'm generally disappointed in movies that do origin stories. As a classic example, Marvel Comic's <i>Spider-Man</i> suffers no less than three quick origin movies, two which are minor changes from the original comics origin, and the third which resets Spider-Man's character who should be about 60 years old now to some time in high school, with no rhyme or reason. That Marvel's characters generally age adds realism to their characters. That Marvel sometimes loses control and by default allows a rehash of the same story repeatedly is disappointing.<br /></p><p>The Batman character's story has changed dramatically in various iterations. The 60's TV Batman played by Adam West is a campy show that doesn't take itself too seriously, whereas the Dark Knight gets "why so serious?", from the villain, <i>The Joker</i>. Is this the same <b>Joker</b> as in this 2019 movie? Maybe. That the Dark Knight is so different suggests an excuse for the <i>Batman Begins</i> origin. Fortunately, that movie also has what the new Batman ends up doing, facing a villain, character growth, and so on. Not bad.<br /></p><p>You'll like <b>Joker</b> if realism is your thing. And yet, it's easy to imagine that a Joker story could venture into horror, with attendant paranormal activity. But there's none of that here. Joker's insanity is based on real mental conditions. The only horror sort of activity is that it's not at all clear what he's going to do next. In fact, it's not always clear if what has been shown is what the character actually did or what the character imagined. The plot is so good, script is so good, the acting is so good, the photography is so good, the situations are so good, that the result may be a little too close to home for many. Maybe you know someone with a similar diagnosis.<br /></p><p>It turns out that i liked it. Here's what i liked about it. With an origin with this kind of depth and realism, it should be easier to write additional excellent stories. It should be easy to add incidents to the base origin that are compatible with the existing story, and hints of these can be added to ongoing encounters with the hero or heros. The hero learns about the character and takes it into account, allowing the hero to be more heroic, and, for example, not simply a guy who spends his nights beating up people with his bare hands. The hero has goals. The villain has goals. They both need to have some complexity if your going to have very many stories with them.</p><p><br /></p>Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-83979670716021747462017-03-16T12:01:00.001-04:002017-03-16T12:03:58.536-04:00ResumeI've never rejected anyone on the basis of their resume.<br />
<br />
First, especially my early resumes were retyped by the agency, and all sorts of typos were introduced, especially in acronyms. I'd be in an interview, and they'd ask me what one of these means. I've never seen this resume. Often, when i'd told them stories about what the resume was supposed to say and what the job was really about, they made me an offer.<br />
<br />
Second, only about one in three candidates actually show up for their interviews. After about ten who actually show up, we get someone who's English is so bad, we can't tell if they know what they're doing or not, even after talking for an hour. I'm thinking (optimistically) that this is someone i could train. We get together and decide that this would, in fact, be someone we'd have to talk to from time to time, and a rejection is made.<br />
<br />
We finally get a competent candidate who accepts our offer. They show up and start working, but they go out to lunch and never return. I'm starting to think that the job wasn't so hot either.<br />
<br />Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-66652391672700262022015-03-27T18:15:00.000-04:002015-03-27T18:15:09.779-04:00PopupsI've been looking for stuff on the Internet. Gasp. Using a search engine. I'm going to many, many sites i don't usually go to. A ton of them have this annoying and pointless behavior. As the page is loading, i start reading it. I get about two sentences, tops into it. At that point, the entire content of the page is blocked by a popup. Is it an ad? Not exactly. It's a "click here to subscribe to our email list" or some equivalent. But two sentences into their content is not nearly enough for me to decide if it's at all interesting. So this is pointless. By the time i finish reading the content, i should have a better view on it. If i don't get there, the answer is likely "no" anyway. So, why not have a form, not in a popup, but at the bottom of the page, on the page itself? That's the right time. I won't have to dismiss it if i don't want to sign up. Don't get me wrong. I like <a href="http://predelusional.blogspot.com/2006/02/comment-spam.html">spam</a>. At least, i like spam if it's the kind of spam i like.<br />
<br />Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-34814843699599263942014-09-18T15:54:00.001-04:002014-09-18T15:54:17.117-04:00Steven Pinker and the Ivy League SchoolI nearly didn't read <a href="http://www.newrepublic.com/article/119321/harvard-ivy-league-should-judge-students-standardized-tests">this article</a>, because i haven't read <a href="http://www.newrepublic.com/article/118747/ivy-league-schools-are-overrated-send-your-kids-elsewhere">Deresiewicz’s article</a>. And, Deresiewicz’s article doesn't sound like a good use of time. I also haven't seen the movie Love Story, probably for the same reason that i haven't watched Titanic, despite owning a copy (not entirely my fault). But i may have to watch Love Story, since the wiki plot synopsis doesn't seem to have enlightened me enough. I'm likely missing details of the plot.
<br />
<br />
But, it's a good article. I'm glad i read it. And, it matches my experience working for four Universities, which includes Harvard, two state schools, and a selective university (i have additional experience at another selective university and a state school, and they match prior experience, more or less). Yes, i admit, i don't really want to spend time reading an article that doesn't support my biases.
<br />
<br />
I could have applied to go to Harvard. I considered MIT enough to order a course catalog. But they didn't look like a good deal, in fact, they seemed to offer less than the state school, and in ways consistent with this article. It seemed obvious, but in retrospect i spent great gobs of time on it. At the time, MIT was considered a great graduate school.
<br />
<br />
The "teach you how to think" line was in vogue where i went to school. No one seemed to have any idea how to do it, or measure the effectiveness of any ideas that might come up. That seems to be changing. But in any case, they did, for the most part, make an attempt to teach stuff one might need. And above all, they came up with a way to get the students to demonstrate competence. This last bit is important. Most schools don't do this (I'm not aware of another that does). And yet, it's why i went to school.
<br />
<br />
I love this: "Perhaps I am emblematic of everything that is wrong with elite American education, but I have no idea how to get my students to build a self or become a soul." Not many would have the courage to say something like that. But the emperor doesn't have any clothes. And it turns out that courage is something that is important for both student and teacher to have. Perhaps it should be taught. In any case, it should be easier than teaching "building a self".
<br />
<br />
His list of stuff students should learn is very good. Perhaps it should start in middle school, dumbing down nothing, and including the bits under "a liberal education". And the goals should be introduced even earlier. The idea that i'd ever "appreciate that people who disagree with me are not stupid or evil" is going to be hard to swallow. I've seen people who are obviously evil who act like they're stupid. While i try not to go off the deep end on conspiracy theories, Watergate really did happen. And, i think, the goal is in conflict with knowing how to distinguish vetted fact from superstition, etc.
<br />
<br />
At the end of the article there is a conclusion. Should Harvard adopt merit based admissions? Perhaps they could do it as a pilot project. Perhaps they've already got pilot project statistics, and they could go with the results. Perhaps they could look to see if someone else has already done this experiment, and go with the results. In summary, these ideas are <i>Run an experiment</i>, <i>look at data you already have</i>, and <i>learn from others</i>. As these are skills that Harvard should be teaching their students, perhaps they could simply turn these ideas into student projects, then evaluate the projects and use the results.
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com2tag:blogger.com,1999:blog-15145059.post-50688338372390147702014-05-19T12:58:00.003-04:002014-05-19T12:58:55.586-04:00Management and The Art of WarIn Sun Tzu's <a href="http://en.wikipedia.org/wiki/The_Art_of_War">The Art Of War</a>, one of the lessons is that a good strategy involves teaching your staff good tactics, then using the good tactics to advantage. So, today's Harvard B school management, with its emphasis on how much money is made each quarter, and stupid slogans totally misses the point. Following this plan dooms your business to slow death. Toyota seems to have noticed this. <a href="http://qz.com/196200/toyota-is-becoming-more-efficient-by-replacing-robots-with-humans/">Toyota replaces robots with humans</a>. this problem is not confined to the automotive industry. <br />
<br />
Readers of this blog may have noticed that there is a bias towards education. So, let's say that you're a leader of a major organization, involving multiple technologies. How do you educate your staff? You could simply hire college graduates. But the pool of graduates is getting smaller. College costs too much except for those lucky enough to be born into wealth. The middle class is becoming part of the poor. It's not enough. And besides, college doesn't teach people how to make your business work. They still need to learn that on the job. Who do they learn it from? Well, they need to learn it from people already doing the job. But doing this means that your business will tend to simply learn how the business operates, not how it should operate. You can get some more input from contractors. After all, these people very likely have worked for your competition. And even if they aren’t currently as good as you are, they have something to teach you, even if it is by obvious bad example. Contractors are currently treated as second class staff. This is not the way to build a smoothly working organization. It’s a way to alienate part of your staff. It was my opinion that engineers should spend at least some of their time on the factory floor figuring out how to make things work easier, faster and safer. And by engineers, i mean everyone who could learn something for the organization. <br />
<br />
In order to create strategy that incorporates good tactics, management must learn all the best tactics. But even if the CEO is already an engineer, that doesn't mean (s)he knows all kinds of engineering, or computer science, or networking, or communications security, or telephony, or building design, or logistics, or finances, or marketing and so on. How does one do it? Well, IMO, the CEO should have depth in at least something, but likely many such things. But also, the CEO should have a skills team covering all bases that can provide advice. And the CEO has to know the language of all the skill team members so that the advice can be evaluated. I'm not saying that the CEO should micromanage the whole system. I'm saying that the CEO should be able to build and tune strategy that allows the whole company to work efficiently. One of the things that management of larger companies currently does is build fiefdoms or silos that insulate groups from different disciplines making communication and cooperation between groups slow, difficult, unresponsive and otherwise dysfunctional. These structures build in inflexibility, and one hears "that's not the way we've always done things" (a phrase that is nearly always something that is demonstrably a lie). <br />
<br />Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-47035192082253832582014-03-06T13:55:00.000-05:002014-03-06T13:55:22.753-05:00Edmunds on fuel economy<a href="http://www.edmunds.com/fuel-economy/we-test-the-tips-part-ii.html">Edmunds</a>
has done a fairly complete set of tests of fuel economy in a sort of Myth Busters way. They mostly match my own results.
<p>
I use cruise control aggressively, if i have it. That is, i use if even if it only marginally makes sense. That's because it gives me 4% to 5% fuel economy at the same speed. And, it generally reduces my workload.
<p>
I consistently get 17% better fuel economy for going 62 MPH rather than 70 MPH. Why 70? Michigan's highest speed limit is 70. I try very hard to not speed. Why 62 MPH? My speedometer also shows KPH, so there's a handy reference - 100 KPH. Naturally, Edmunds gets a higher percent improvement. Often overlooked is that driving slower is safer. We tend to increase our risk to some threshold. I try to minimize my risk unless there's some corresponding benefit. Usually there isn't.
<p>
Drafting: I've tried drafting manually. I found that drafting a truck fairly got me worse fuel economy than driving at the same speed. And, driving at the same speed with cruise control is better yet. Drafting is risky, and pointless, so i don't do it. This test was done on a cross country trip, covering about 400 miles each. Wind and terrain were similar. My guess is this. Constant speed changes, through brakes or engine drag, kill fuel economy. Engine drag is the same as the brakes.
<p>
Roof luggage. I lost between 5% and 10% for putting roof luggage on my car. Cruise control was used at the same speed on the same course for thousands of miles. My luggage carrier at least looks fairly aerodynamically efficient. The way i look at it is that you put roof luggage up there if you need it. I'd love to be able to drag a trailer. It would be better than driving a pickup and paying the cost all the time.
<p>
A/C. I've not done this test. I'm not into noise, so i don't drive with the windows open on the highway. I've read articles about just this topic. The answer seems to depend on the details; such has speed, the kind of car, and so on. It's not a huge difference anyway.
<p>
Tire pressure. I underinflated the tires on my car. It did not change my fuel economy in any measureable way. I overinflated my tires, and again, no change. But i view it as a safety issue. For at least one of my historic cars over inflation leads to over steering.
<p>
Manual transmissions. I've heard otherwise, but my tests show that manual transmissions save you at least 5% in fuel economy over automatics. I'm not a gear head who likes to shift gears. What i'd like is a series hybrid. That is, and electric transmission. With no differential, we'd get an additional 7% to 15%. With no engine drag, we might get another 20%. There shouldn't have to be any gears, so there's smooth acceleration always. It should last longer than hydromechanical automatic transmissions. It should have redundancy that will get you home even if a wheel can't be powered. It should be cheaper to replace if it does fail.
<p>
My conclusions match too. The main issue is psychological. I used to have an hour commute to work. Driving faster could save me, at most, about five minutes. But since there were traffic slowdowns, it was impossible to measure five minutes. Psychologically, it's difficult to let everyone pass you. This is the biggest hurdle. But i can use the cruise control much more often at 62 MPH than at even 65 MPH. Everyone else has to pass me. I have the right of way. It's worth something.
<p>
<a href="http://www.edmunds.com/fuel-economy/we-test-the-tips-part-ii.html">Edmunds fuel economy tests</a>
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-88121131504803465292014-02-24T21:23:00.001-05:002014-02-24T21:23:56.140-05:00technologyI have a land line for a phone. I often get messages on my answering machine where the automated message machine gets the complete message onto my answering machine. Today i got "Press 2". That's an entire message. I also got "Press star now to repeat this message". These were different voices, so presumably, different senders. Total fail.
<br />
<br />
<i><b>For a list of the ways that technology has failed to improve our lives, please press 1.</b></i>
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-42931747605869530302014-02-05T10:32:00.001-05:002014-02-05T10:47:50.141-05:00Caffeine: last part with any luckLast May, my left shoulder started hurting really bad. I recognized the symptoms. I had them in <a href="http://predelusional.blogspot.com/2006/06/caffeine.html">2001</a>, though in my right shoulder. Back then, i noticed that it didn't <a href="http://predelusional.blogspot.com/2006/03/caffeine.html">hurt</a> quite so much on Sunday, especially Sunday afternoon. What did i know about Sunday? Well, that's when i'd get a headache from caffeine withdrawal if i'd had too much that week.
<img src="http://farm4.staticflickr.com/3133/2587169903_2618c0322e.jpg">
<p>I never acquired the taste for coffee, but i can drink Mt. Dew in the morning. Mt. Dew is also an acquired taste, especially in the morning. It's not as vile as beer in the morning, though pretty close. I'd get withdrawal headaches on Sunday because i don't drink soda at home, just at work. So, the obvious experiment was to switch to Sprite, which has no caffeine. After two weeks, there were two things that were obvious. First, there was a clear connection. My shoulder pain had backed off considerably. I still had restricted motion. But it wasn't getting worse.
<p>The second observation was unexpected. It turns out that i don't really like Sprite. So, i switched to water, and i ended up consuming about a half-gallon every day. A side effect of this switch was that i lost 37 pounds (17 kg). That's because water has about 700 fewer calories than Sprite or Mt. Dew in the quantities i consume. This lost weight wasn't hard to find. I don't remember, maybe it was under the bed.
<p>In any case, this started in February 2001. Just in case i wasn't convinced, in March 2001, i went on a job interview. They offered me a cup of coffee. Again, i don't drink coffee. But on interviews, i seem to lose about 50 IQ points. It's amazing i ever get hired. It was one of those small Styrofoam cups. I drank it. My shoulder hurt like hell for four days. I still reach for things with my left hand, even though now that's the shoulder that hurts. The pain held pretty steady until the month of October. Then the pain ramped down to zero, and my restricted motion became unrestricted. But fast forward to now. This is month nine. Every day, my left shoulder's pain noticeably decreases and the range of motion increases. I fully expect to be totally cured by month’s end. That is, if i don't fall off the wagon. It really hurts to fall off the wagon.
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-87264767959664113482014-01-19T14:44:00.000-05:002014-01-21T12:15:19.296-05:00Engines Under Ursus, SciFi podcast review<p>
I've been listening to <a href="http://www.enginesunderursus.com/">Engines Under Ursus</a>, by Marin Brady. I've just finished the 26 episodes i had downloaded. There are at least two more. But my ancient 32 bit computer died, more or less. That's another story. This more modern machine i'm using is in a sort of zombie mode, booted from thumb drive, while it gets a brain transplant. Apparently, Marin has written a <a href="http://www.enginesunderursus.com/short_stories/index.html">bunch</a> of short stories. He says he wrote <i>Engines</i>, sent it to Tor, and got something unintelligible back. I don't usually write reviews before i've finished them, but this is an exception. If Tor rejected this piece, it's a mistake on their part.
<p>
I've heard <a href="http://en.wikipedia.org/wiki/Scott_Sigler">Scott Sigler</a>'s audio for Ancestor, Infection (now called Infected), Earth Core, and The Rookie. I mention this for two reasons. First, i've had ear buds in my ears for about ten years now. And second, to compare experiences. Scott has great stories, uses voices for the parts, has some quirky reading. I couldn't get over how he'd mispronounce words sometimes. Easy words. He wrote the book, and the words are used right, but...
<p>
Martin Brady has some sort of accent. Maybe it's Irish. Whatever. He has multiple voices, and many don't have an Irish accent. They're quite consistent. While many actors, including voice actors, over act, Martin has a more subdued underacting style. It's not a monotone. I can only call it deliberate. And he takes the performance an extra step. He adds pod-safe music to each episode. The music is typically at the end of the episode. Frankly, i wasn't much interested in it. That is, until episode 19. I no longer have two hours of driving commute per day. So it's more unusual now to drive while listening. But for episode 19, i was. And i listened to the music because i didn't want to fiddle with the mp3 player. Holy shit. I practically had a nose bleed, it was so good. I don't even get nose bleeds. And there are lines and bits from the song that are in the episode. So now, i need to go back and listen to everything. So, while Scott moved the field forward by using audio books to get the word out (and it seems to be at least part of what's really working for him), Martin has added a dimension to audio story telling. The audio version is going to be, in my opinion, better than the printed version. I've had to go back and listen to the song, uhm, repeatedly. Apparently, Rockbox (open source firmware for my Sansa and other mp3 players) has a feature called "bookmarks". I figured out how to use them, and it has let me conveniently play this piece at will. I really hope Martin has high quality wav files so that his finished product can be released in higher quality mp3s, OGG, or FLACC files eventually. The piece deserves it. I'd buy it.
<p>
What about the story? Well, at first, i had no idea what to make of it. I mean for at least ten or fifteen episodes. For some books, at this point i'd stall, and either drop it, or pick it up later, often years later. But this was different. It was something like the movie Brazil (my favorite movie, BTW). Engines seems to be going somewhere. But in Brazil, even after watching the movie several times, and reading the screen play, i still have no idea where it's going, or for that matter, what happened. There's an unpredictability in Engines that i like. When i finished episode 26, i noticed that episodes 24 and 26 were on my player. Rockbox has a feature where you can delete a track before you've finished listening to it, if you're near the end. I must have listened to episode 25 out of order. I think it was in the low 20's. I recall wondering what Martin was up to. Martin wasn't up to anything. Sometimes authors move stuff around. But here, i did it, and it didn't matter as much as you'd expect. The story isn't over, but it's looking like a real winner.
<p>
Ursus is a planet other than Earth. There are aliens. Humans are aliens elsewhere. There are androids, and lots of tech stuff. It's not hard science fiction. But the science rules broken wouldn't completely change the story if they weren't, at least not so far. The story is about the story. I'd say more, but at this point, you should have all you need to decide if you want to read it. I wouldn't have written this review if i didn't like it.Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-79894802834879698922013-12-02T15:22:00.001-05:002013-12-02T15:22:36.695-05:00What's your biggest weakness?Interviewer: What is your biggest weakness?<br />
Candidate: I'm too honest.<br />
Interviewer: I don't think that's a weakness.<br />
Candidate: I don't care what you think.<br />
<br />
For the most part, i don't like most interview questions. Interview quizzes are terrible. A good question i heard in an interview was this:<br />
<br />
What are your favorite tools?<br />
<br />
This question draws out anecdotes and situations. The tools show diversity of activity, passion for the job, and can be genuinely informative. It can start a conversation. You don't really want a monologue. It can get you close to what should really happen in an interview. If the interviewer isn't competent, then the interviewer can't tell if the candidate is competent. The best interviews happen between two competent people. At the end of the interview, interviewers must ask themself this question: "Would I like to hang out with this person." Studies show that many companies have pockets of really good employees. <br />
I said that i don't like most interview questions. I come away thinking, "How could they be so stupid?" (And, "do i really want to work there?") But for a long time, i wondered what the interviewer should ask. I give them (and myself) a bit of a break now.<br />
<br />
It takes about two weeks to come up with a really good extemporaneous comment. -- <i>Mark Twain</i> <br />
<br />
Sam was a pretty smart dude. If it took him two weeks, then we all deserve a break. Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-63099907697522522722013-11-27T09:46:00.000-05:002013-11-27T09:46:02.818-05:00PasswordsI recommend making up a sentence. Start from a movie or book. Summarize an idea. Then maybe substitute a number for a letter. o, q => 0, i, l =>1, 4 => #, or whatever. Let's say you want to make up an 8 character password. You saw the first movie Thor. An original quote is this: <br />
<br />
"Whosoever holds this hammer, if he be worthy, shall possess the power of Thor." <br />
<br />
That's 14 words. Maybe "The worthy holding this hammer have the power of Thor". That's 10. Maybe "The power of Thor to the worthy". That's 7. But you heard it in the first movie. So add a 1. It's 1, so jam it in at the beginning. 1tpotttw. Of course, don't use this example. Use "The Password Of Thor To The Worthy One" instead. <br />
<br />
So, you have to change passwords every month. And you can't remember which of your passwords is current. You could write "Thor" on a Post It note, and put it on your monitor. You can keep a running list of all your recent passwords on your monitor, in case you failed to change one of them. You've seen other movies, right? <br />
<br />
<a href="https://lastpass.com/">lastpass.com</a><br />
<br />
I'm not a troglodyte. I've used a password manager. Can you say "Single point of failure"? Many companies have password length restrictions, adding together the restrictions of numerous operating systems. <br />
<br />
I wrote a password generator once. It tried hard to make up memorable passwords. They weren't that memorable. And, it turned out that it used the date/time to the second as a random number seed. What could go wrong? Well, if one can guess when a password might have been generated to within a year, that's only about 31,536,000 passwords to check. That's nothing for a computer. Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com1tag:blogger.com,1999:blog-15145059.post-33221782290321597522013-10-11T12:57:00.000-04:002013-10-11T12:57:13.420-04:00Fire or IceThe question was <b>When is the end of the world?</b><br />
<br />
Robert Frost had it right.<br />
<br />
In five billion years or so, the Sun will grow into a Red Giant. Its diameter will be about the size of the Earth's orbit. Earth either is engulfed and vaporized, or raises a tide behind itself on the Sun, which removes orbital energy from the Earth, causing it to spiral into the sun, where it is engulfed and vaporized.<br />
<br />
However, we're here. We already understand physics enough to know how to move the <a href="http://www.newscientist.com/article/dn14983-moving-the-earth-a-planetary-survival-guide.html">Earth's orbit</a> out from the Sun. Essentially we steal orbital energy from Jupiter using big asteroid flybys of both planets. At this point, it's an engineering project. A big engineering project that takes millions of years. However, it's feasible, and would be worth doing. After the Sun's Red Giant phase, it shrinks to about the size of the Earth, and though it's really hot, its much smaller size means that it emits less total energy. We reverse the process, and move the Earth into a much smaller orbit for maximum comfort. Eventually the Sun cools. The Earth freezes. But it's ten billion years later, at least.<br />
<br />
Robert Frost's <a href="http://www.poetryfoundation.org/poem/173527">Fire and Ice</a> poem says it might happen either way. In his <a href="http://www.poetryfoundation.org/poem/173536">The Road Not Taken</a> poem, he says "Two roads diverged in a yellow wood". The way that the Earth ends is our choice. Fire or Ice. Which do you want?Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-255704092671955312013-08-07T12:39:00.000-04:002013-08-07T12:39:26.349-04:00A moving experienceWhen i was in high school, one of my class mates said that he'd only been out of town once. That's when he was born. And that's because the town has no hospital. At the time, the idea that moving is anathema was a new idea. I didn't understand it. But it's much more common than my own history. I've moved 17 times since college. In fact, you can trace the movement of humans out of Africa and out the coast of India by using DNA. You call it movement, or migration. But it is really expansion. The descendants of people who moved out of Africa maybe fifty or seventy thousand years ago are still there. You sample their DNA to find out how long ago it was. How many generations stayed where they were for that long? Then we have a story like this: <br />
<br />
A <a href="http://www.motherjones.com/environment/2013/08/bayou-corne-sinkhole-disaster-louisiana-texas-brine">moving</a> experience. Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-62116799585327099632013-08-06T15:26:00.002-04:002013-08-06T15:26:42.784-04:00Something oddWhat if we discovered something odd by accident. If boys between the ages of 9 and 13 are starved (not to death, just reduced food intake), then not only do they do better, but so do their children (if any) and their grandchildren (if any).... In fact, three generations have one quarter the chance of death by heart attack. And, what if we had a single payer health system (like Austrailia), so that effectively, everyone pays for health issues, not just the victim. And, let's say that heart attacks are painful to have, and incredibly expensive to treat. Wouldn't it make sense to starve boys between the ages of 9 and 13? Wouldn't it be the ethical imperitive? How would one go about explaining it to Americans? <br />
<br />
Is there anything to this? Here's the podcast.<a href="http://www.radiolab.org/2012/nov/19/">Radiolab</a>Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com1tag:blogger.com,1999:blog-15145059.post-54267941449302983002013-07-31T12:52:00.001-04:002013-07-31T12:52:25.038-04:00MoviesI read <a href="http://phenomena.nationalgeographic.com/2013/07/30/madness-of-crowds-single-ants-beat-colonies-at-easy-choices/">this bit about ants</a> and immediately thought of how people pick movies. <br />
<br />
Movies are a great example. People see the trailers, and either watch or not. The first people who see the real movie talk about it. But movie promoters talk up a movie if the first week went well. But the first week's box office has to do with people who went because they liked the trailer. There's no information about the actual movie. And critics are no help. They either think their job is to criticize it, tell you if they liked it, or just tell you everything that could possibly be of interest in it. Their job is really to tell you enough about the movie so you can decide if you might like it or not, but not give so much away to ruin it. It's not an easy job, and few have succeeded. So we go to movies we don't like. In fact, one time, i went to the theater and watched the wrong movie. It turned out to be the better choice. And that's what i think about when we're talking about ants. Remember, there are way more ants than uncles. Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-73917259074292105282013-06-17T12:19:00.003-04:002013-06-17T12:19:35.144-04:00Google Reader Goes AwayAs you may know, Google Reader is set to disappear on July 1st. I (finally) transferred my subscriptions. It took longer than i expected, and transferred less than i'd hoped. Reader says you can export your date via <a href="https://www.google.com/takeout/#custom:reader">Takeout</a>. You get to save your stuff to your local hard disk. I downloaded everything, which gives you a .zip archive. I unzipped the zip (there's an unzip command line in Linux, but it's probably easy on any platform).<br />
<br />
Historically, i ran Sage in Firefox as a reader. When Google Reader came around, I switched to it so that I could continue where i left off on multiple machines. With Google Reader gone, i've switched back. The directions found by searching the Internet yielded lots of false leads. What works is to bring up Firefox and Sage, in the options menu (on the left), import OPML, browse to the .xml file in the stuff you downloaded and unzipped. What you get is the subscriptions. It didn't have the stuff that's marked as read/unread, however.<br />
<br />
Sage has changed since I last used it. It looks better. But it's still a basically simple blog reader. Since I really mainly use one machine, i think i'm going to like it better than Google Reader. For one, it either seemed impossible, or was impossible to mark something as unread that i might have started but didn't finish, or simply wanted to reread.<br />
<br />
Sage shows the articles in the browser, just like they'd appear on the original blog. That's because you're looking at the original blog. Google Reader reformatted stuff. This was OK sometimes, but not always. And though you could click to see it in the original form, you had to do that in order to see if you were missing anything. Why not always look at the original? And, some blogs would make a big deal of how their work was copyrighted, and prohibited <span style="font-family: 'Calibri','sans-serif'; font-size: 11pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;"><span style="font-family: Times New Roman; font-size: small;">derivative </span></span>work. Google Reader was clearly making a <span style="font-family: 'Calibri','sans-serif'; font-size: 11pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;"><span style="font-family: Times New Roman; font-size: small;">derivative </span></span>work. And, this could hurt the original blog. That's because Google Reader didn't do any advertising for the original author - though they did do some for themselves.<br />
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-80720775624427624102013-06-14T11:56:00.000-04:002013-06-17T12:20:24.727-04:00How far can the Sun be seen?How far away from the Sun can you just barely see the Sun (using Wikipedia)? The Sun is magnitude -26.74 (from <a href="http://en.wikipedia.org/wiki/Sun">Wikipedia</a>). The dimmest stars one can see with the naked eye are approximately magnitude 6. The Sun would have to be |-26.74 - (6)| = 32.76 magnitudes dimmer. The <a href="http://en.wikipedia.org/wiki/Magnitude_(astronomy)">formula</a> for magnitudes is x^5 = 100, x = 100^(1/5), where x is the multiplier to get from one magnitude to the next. The factor dimmer that Sun must be is x^32.76=12,705,741,052,085 (more or less). Light gets dimmer with the square of the distance. Since the Sun is at one AU (x^32.76)^(1/2)=3,564,511 AU is the distance where you can just barely see the Sun. How far is that? 1 AU = 149,597,870,700 meters, <a href="http://en.wikipedia.org/wiki/Astronomical_unit">exactly</a>. 3,564,511 AU * 149,597,870,700 m/AU = 533,243,305,691,677,319 meters. 1 light-year = 9460730472580800 metres (<a href="http://en.wikipedia.org/wiki/Light-year">exactly</a>). 533,243,305,691,677,319 m / 9.4607×10^15 m/LY = 56.363861885414590497131460401964 light years. (OK, so that's more digits than we need). If you were 56.364 Light Years away, you'd be just barely able to see the Sun. Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-6917339675874052402013-05-16T14:34:00.004-04:002013-05-16T14:34:51.410-04:00GarnetNever saw the web magazine <a href="http://www.theshallot.org/">The Shallot</a> before. Of particular note is the announcement of a new programming language: <b>Garnet</b>. This is the very first pure non-functional language. <b>Garnet</b> is related to <b>Ruby</b>, only not really.
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-64107414645646400822013-02-21T10:24:00.000-05:002013-02-21T10:24:47.105-05:00Eight Queens part one<html><head><title>Eight Queens part one</title></head><body>
<table border=1>
<tr><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td align="center">Q</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td align="center">Q</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
</table>
<p>If you get out a chess board, and put a queen in the lower left square, it's pretty clear that you can't put a second queen in the lowest row of the second column. That's the same row that the first queen is in. So there are really only seven choices available for the second queen. And the third queen only has six choices. It follows that there are 8 * 7 * 6 ... or 8! = 40,320 possible board positions to check for solutions. So combining the not-in-the-same-column rule with the not-in-the-same-row rule reduces the number of board positions to check by a factor of (8^8)/8! = 416.
<p>There are algorithms that turn a counting integer into a unique permutation of a list. One could use this sort of thing. There are three reasons for not moving forward in this direction. First, the permutation algorithm is a bit complicated. It's nearly as long as the current program. Second, this permutation algorithm is fairly slow, though not anywhere near a factor of 416 slow. And its performance per call is proportional to the number of items to permute, in this case eight. Third, changing an exponential algorithm (8^8) into a factorial problem (8!) still gives you exponential time. If the board size is increased, the solution increases in time proportional to x^n of the board size. The permutation algorithm is handy. So perhaps it'll get a write up in some other series. This series has another direction. And if this code is converted to counting permutations, then it will be difficult or impossible to go where we're going.
<table border=1>
<tr><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td><td width="5%"> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td> </td><td align="center">Q</td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td align="center">Q</td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td align="center"><font color="red">Q</font></td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td align="center">Q</td><td align="center"><font color="red">Q</font></td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td></tr>
</table>
<p>Let's return to the chess board. Put the first queen in the lower left square. In the second column, you can't put a queen in the lowest square. If you put the second queen in the second row, then the two queens are also attacking each other, this time <a href="http://en.wikipedia.org/wiki/Places_in_Harry_Potter#Diagon_Alley">diagonally</a>. In fact, with the second queen in either of these positions, there are no queen positions of the remaining six queens that are solutions to the Eight Queens problem. You may as well move the second column queen up one more square. If you skip checking the positions with the other six queens, you've skipped 2*8^6 = 524,288 positions (of 16 million). And, you've skipped all these board positions with a two checks. It's easy to show that if the first two queens are as shown, the third column queen must be at least at the fifth row. To get the third column queen that high, four more checks are made, eliminating 4*8^5 = 131,072 boards. Big chunks of the problem space are vanishing, though they're vanishing in smaller chunks as the queens farther to the right are placed and checked. But this is the general way that the student in 1979 came up with his nearly zero time solution. It's also what Dijkstra did in his 1972 article about <a href="http://en.wikipedia.org/wiki/Structured_programming">Structured Programming</a>. However, this article isn't about <i>Structured Programming</i> (that would be a completely different rant) so much as it's about the technique Dijkstra used called <a href="http://en.wikipedia.org/wiki/Backtracking">Backtracking</a>.
<p>To make use of <i>Backtracking</i> you need to be able to generate a first board, a next board (and know if there aren't any more), you need to be able to check the partial solution, and you need to be able to print or otherwise identify the solutions you found.
<p>Let's see how it works. The <i>first board</i> routine needs to simply place the first queen. In the <i>check board</i> routine, there's only one queen, so there are no attacks. The <i>next board</i> code knows that there is a possible solution, so it puts a new queen on the board in the next column. From here on, it's only <i>check board</i> and <i>next board</i>. The <i>check board</i> function needs to know how many queens are on the board so it can check rows and diagonals for attacks. In this case there are two queens, and they're in the same row, attacking. The <i>next board</i> function needs to know if the <i>check board</i> found an attack or not. Since there's an attack, it needs to move the rightmost queen up a row. When it finds a queen is at the top already, then it is removed, and the previous queen needs to be moved up. This is <i>Backtracking</i>.
<p>For the Eight Queens problem, the initial solution space was so large, that it seemed hopeless. But it turns out that <i>Backtracking</i> is an approach that can be used to attack many of these combinatorial problems. The downside for <i>Backtracking</i> seems to be that it isn't very easy to decide how good the performance will become without first trying it. In this case, as queens to the right of the board are considered, smaller chunks of the problem space are eliminated. With increasing board size, does the problem stay exponential? Or is it something else? Knuth wrote about this issue in 1975. From my perspective, it doesn't matter. That's because Knuth is primarily thinking about the problem as a mathematician. Mathematicians want to think about a problem and come up with a solution. Programmers have another tool. They can write yet another program and see how it works. If the program takes too long, the programmer can tell the computer to count something of interest to help the analysis. Often this shows the programmer where to attack the problem next.
<p>Don't agree with me? Here's an analogy. My favorite sorting algorithm is <a href="http://en.wikipedia.org/wiki/Shellsort">Shell's Sort</a>. How long it should take is an open question. One advantage that it has over other algorithms is that an in-place sort doesn't require extra memory. It usually performs similar to n*log(n). In practice, it's usually quicker than <a href="http://en.wikipedia.org/wiki/Quicksort">Quicksort</a> which has a best case of n*log(n) time, but requires more space. It doesn't bother me that its computation time is an open question.
<p>In any case, let's look at a modification to the 8^8 version of <a href="http://xkcd.com/312/">the Perl program</a> that does <i>Backtracking</i>. It's instrumented to find out how many rows needed to be checked (which is the number of <i>next</i> boards, and the number of diagonals checked. One should note that the board checks are faster than the previous version. That's because instead of checking all eight queens against all eight queens, it only has to compare the most recent queen to other queens. The previous queens have already been checked, and none are attacking. Since only 15,720 boards were checked, that's less than one in a thousand compared to the 8^8 solution. Fewer than one in three thousand diagonals need be checked. What does that mean for the order of computation? Not much. This code is written for an 8x8 board. It could be generalized to nxn, and then run, and then we'd find out... something. Since the checks are proportional to the size of the board, we'd expect time to rise faster than board size. However, the chunks that would be eliminated would be a larger proportion for larger boards. So, who knows? I'd be willing to bet that someone has written this up somewhere.
<pre>
#!/usr/bin/perl
# Eight queens - incremental backtracking version.
# Chess board where eight queens are not attacking each other.
# Can't have two queens in the same column, so represent row numbers in columns.
# There are 8^8 (1e7) positions to check.
# The check for one queen per row gives you unique digits.
# If there's an attack between queens to the left, there's no
# need to keep checking to the right.
# This reduces the problem further.
# 92 winning boards. 15720 rows checked, 5508 diags checked.
# 0 seconds - likely less than 0.05 seconds.
# main
my $col = 0; # current column under consideration
my $x;
my @b; # board, 0 - 7 are columns, values are positions, 0-7
my $cnt = 0;
my $chkh = 0; # horizontal checks
my $chkd = 0; # diagonal checks
# set board to queens at bottom.
for ($x = 0; $x < 8; $x++) {
$b[$x] = 0;
}
while (1) { # The big loop, count to 8^8-1
# check for a win
if (&chkwin($col)) {
if ($col != 7) {
$col++; # Don't increment board, as new col is zero.
} else {
$cnt++;
# print "win ";
&prbrd();
$col = &incbrd($col); # increment the board
if ($col == -1) {
print "$cnt winning boards.\n";
exit(0);
}
}
} else {
$col = &incbrd($col); # Increment the board
if ($col == -1) {
print "$cnt winning boards. $chkh rows, $chkd diags.\n";
exit(0);
}
}
}
sub incbrd { # Returns $col. -1 when done.
my $col = shift;
$b[$col]++;
while ($b[$col] > 7) {
if ($col != 0) {
$b[$col] = 0;
$col--;
$b[$col]++;
} else {
return -1; # done
}
}
return $col;
}
sub prbrd { # Print the board
my $x;
for ($x = 0; $x < 8; $x++) {
print "$b[$x]";
}
print "\n";
# sleep(1);
}
# Assumes partial incremental board.
# Only have to check the rightmost column.
sub chkwin {
my $col = shift;
my ($x, $y, $a);
# Check for same row.
$chkh++; # How many horizontal checks.
for ($x = 0; $x < $col; $x++) {
if ($b[$x] == $b[$col]) {
return 0;
}
}
# Check for diagonal.
$chkd++; # How many diagonal checks.
$a = 1;
$y = $b[$col];
for ($x = $col - 1; $x >= 0; $x--) {
if (($y == $b[$x] - $a) ||
($y == $b[$x] + $a)) {
return 0;
}
$a++;
}
return 1; # 1 is good, 0 is not a win.
}
0;
</pre>
<p>Could this code be made faster? Sure. For one thing, any solution that is up/down mirrored is also a solution. So the left most queen only needs to go from 1 through 4. The mirror solution can be created by subtracting the row number for each column from nine. So one becomes eight. It's an easy change. It would produce all the answers in a little over half the time. Perhaps tricks like that allowed someone to <a href="http://en.wikipedia.org/wiki/Eight_queens_puzzle#Counting_solutions">compute the number of distinct solutions</a> for a 26x26 board. Time spent counting alone would take forever. One expects that they used a compiled language. That would improve performance by a factor of about three hundred. This code could be converted to C without changing much of the look. And it could be converted to run on multiple processors fairly easily.
<p>The interested reader might note that the general algorithm for <a href="http://en.wikipedia.org/wiki/Backtracking">Backtracking</a> is presented as recursive, and the <a href="http://en.wikipedia.org/wiki/Eight_queens_puzzle#Sample_program">Eight Queens code that Wirth presented</a> is also recursive. My Perl solutions are not. My policy on recursion is to introduce it if it helps with dynamic storage. In this case, restoring the previous state is a simple matter of changing the value of the column under consideration ($col). A further issue is parallelization. Multiple core processors are now common. We should be considering parallel computations. It looks pretty easy to start with my code and modify it for multiple processors. For example, it could be modified to consider the case where the first queen is set once, and not moved. All of the other boards with this first queen would be considered. Eight instances would be run, possibly at the same time. Perhaps something similar could be done with a recursive version, but it may not be so easy. It's something for future investigation.
<p>This code was timed with a resolution of one second. Why work hard to reduce a fifty second program you need to run once to nearly zero? The answer is that these techniques are worth learning. There are other problems where even modern machines are hopelessly slow. We'll get to one of those soon.
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-79784034182610482642013-02-20T15:37:00.000-05:002013-02-20T15:37:58.339-05:00Eight Queens part zero<p>How many queens can be put on a chess board where none of them are attacking any others?
<p>A chess board has eight by eight squares. A queen attacks all squares in the same row or the same column, or on either of the two diagonals.
<p>If one considers putting queens on a chess board at random, the maximum number of board positions to consider is 64! That is, one puts a queen on the board, and there are 64 choices for where to put her. For the second position, there are only 63 open squares left. So for two queens, 64 * 63 positions need to be considered. There are 64 squares, so the maximum number of queens is 64. The number of positions to check is 64 * 63 * 62... or a total of 64!. That's about 10^89 positions. All the computers on Earth could not check that many board positions in the current age of the Universe. The overwhelming majority of these board positions can be shown to have at least two queens attacking each other. And there are some simple ideas to eliminate whole chunks of these at a time. For example, here's one idea.
<p>Since a queen attacks all the squares in the same column, one can't have two queens in the same column. Since there are only eight columns on a chess board, it's not possible to have more than eight queens on a chess board without any attacking any others. It can be ruled out. That doesn't mean that there <b>are</b> any board positions with eight queens. It only means there aren't any with nine or more. This is apparently obvious enough that the problem is called the <a href="http://en.wikipedia.org/wiki/Eight_queens_puzzle">Eight Queens</a> problem.
<p>This not-in-the-same-column rule means that the queen in the first column can be in any of eight positions. For each of those, the queen in the second column can be in any of eight positions, for eight squared combinations. It follows that the total number of board positions to check is eight to the eigth power (8^8), or a bit over 16 million board positions. This is a speed increase over our original idea of a factor of about 10^81.
<p>The Eight Queens problem, is an example of a combinatorial problem. It is said to be NP-complete. The solutions for these problems suggest that the entire solution space must be searched to find solutions. NP-complete problems strike fear in the hearts of computer science students. Having never been a computer science student, it's not much of a worry. However, my understanding of gravity is excellent, so acrophobia is available. It's always something.
<p>While at school in 1979, i had a job sitting behind the I/O desk, answering student's computer questions. One day, an advanced computer science student asked me about the problem. The professor had likely read Dijkstra's 1972 article, and assigned it to a class. He prepared the class for the worst by implementing an 8^8 solution that attempted to get all solutions by brute force. After three days, it had covered a third of the solution space, and he killed it. The estimate was nine days for the full solution. This is on a <a href="http://en.wikipedia.org/wiki/PDP-10#KA10">PDP-10 designed in 1966</a> that performed at about a fifth of a MIPS.
<p>Anyway, on a modern machine, 10^7 is not such a big number of things to do, so let's just plow into it. How should a computer program represent the board? It could have an eight by eight grid, with a one representing a queen, and a zero representing an open space. Since the numbers are either zero or one, the numbers don't have to be larger than one bit. 64 bits could be used.
<p>A program with this representation needs code to generate a first board position, code to generate the next board position in any way that covers all possible board positions, code to check to see if a board position is a solution, and code to print or otherwise note a solution. One can imagine each of these routines. The first board position could be all eight queens at the bottoms of their columns. The next board position could move the rightmost queen up a row. But if that move the queen off the top of the board, it should move it down to the bottom of that column, and move the queen to the left up a row. When all the queens are at the top, it should report that all positions have been searched. The check for win must check each queen's row for other queens, and each queen's diagonals for other queens. A board position print might print a space where there are zeros and a queen where there are ones in an eight by eight square.
<p>Here's another way to represent a board position. In each column, only one queen may be present. So each column can be represented by a single number. This number says what row that queen is in. There are only eight columns, so there are only eight numbers. Each column has eight rows. So each number can have one of eight values, so only three bits are needed. That's a total of 24 bits. In any case, you can think of each column as a digit in a number. As long as the <i>digits</i> are constrained to one of eight unique digits, you can <i>count</i> through all possible board positions. One of the nice features of this representation (compared with a bit per square) is that as you "count" through possible board positions, you don't have to check that two queens are in the same column. That is, the board representation can't violate this constraint, so there's no need to check.
<p>The same routines are needed for the eight numbers as above. If each <i>digit</i> is one through eight, then the intial board could be all ones. The next board looks like counting by one. Checking for a queen in the same row is the same as checking the other queens for the same digit number. Checking diagonals is a bit more complicated. Two columns that are next to each other have a diagonal that are off by one row. If they're one row farther apart, then diagonals are two rows different. Finally, though a full board can be printed, it's easy enough to simply print the row numbers for each column.
<p>This 8^8 <a href="http://xkcd.com/1171/">Perl program</a> takes 50 seconds to find all solutions. That's because a modern desktop machine is at least 15,000 times faster.
<pre>
#!/usr/bin/perl
# Chess boards where 8 queens are not attacking each other.
# Can't have two queens in the same column.
# Represent row numbers in columns.
# There are 8^8 (1e7) positions to check.
# 50 seconds - 335544 board checks per second.
# main and global variables
my $col = 0; # current column under consideration
my $x;
my @b; # board, 0 - 7 are columns, values 0 - 7 are positions
my $cnt = 0;
# Set board to queens at bottom.
for ($x = 0; $x < 8; $x++) {
$b[$x] = 0;
}
while (1) {
if (&chkwin()) { # check for a win
$cnt++;
&prbrd();
}
if (&incbrd() == -1) { # increment the board
print "Done $cnt winning boards.\n";
exit(0);
}
}
sub incbrd { # Increment board.
my $col = 7;
$b[$col]++;
while ($b[$col] > 7) {
if ($col != 0) {
$b[$col] = 0;
$col--;
$b[$col]++;
} else {
return -1; # Puzzle is done
}
}
return $col;
}
sub chkwin { # Check a board for a win.
my ($x, $y, $a);
for ($x = 0; $x < 8; $x++) { # Check row
for ($y = $x + 1; $y < 8; $y++) {
if ($b[$x] == $b[$y]) {
return 0; # not win
}
}
}
for ($x = 0; $x < 8; $x++) { # Check diagonals
$a = 1;
for ($y = $x + 1; $y < 8; $y++) {
if (($b[$y] - $a == $b[$x]) ||
($b[$y] + $a == $b[$x])) {
return 0; # not win
}
$a++;
}
}
return 1; # win
}
sub prbrd { # Show the board.
my $x;
for ($x = 0; $x < 8; $x++) {
print "$b[$x]";
}
print "\n";
}
0;
</pre>
<p>The <a href="http://en.wikipedia.org/wiki/Eight_queens_puzzle">Eight Queens wiki page</a> tells us that the first solutions were found in 1850, about 96 years before the first fully functional computer, depending on who you talk to, and what your definition of fully functional computer is. If any solutions can be found by hand, there must be better ways to approach this problem.
<p>My help to the student was likely limited to some hand waving about reducing the problem space, without any real direction. A couple days later, he showed me that he'd reduced the time required to less than a second. He even removed the print statements showing that most of that time was spent printing the answers. There are only 92 of them.
<p>In the next part, the problem is approached using a better technique. It may seem pointless, since the most time that can be saved is about fifty seconds. But the general technique can be used on many such problems. And many of these problems are considerably more complicated. It's best to practice on easier problems first.
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-39074771721292048612013-02-18T11:46:00.000-05:002013-02-18T11:46:24.199-05:00Crimson<p>It was mostly clear last night. I thought it might be fun to see if i could find R Laporis, also called Hind's Crimson Star. Though visible from my back yard, which has better stray light blocking, it did not appear that i could get my telescope's computer aligned in a spot where i could see it. So, i brought the scope to the front sidewalk (the Mercury Vapor Observatory). The MVO has had a much wider sky view than the jungle in the back yard ever since the <a href="http://en.wikipedia.org/wiki/Emerald_ash_borer">Emerald Ash Borer</a> took down the front yard's twin gorgeous ash trees. I've never actually seen one of these beasts.
</p>The constellation Lepus (the hare) is below the feet of Orion. This part of the sky looks entirely star free at first glance. 10x50 binoculars show the stars of the constellation easily. But after a few minutes, there seemed to be enough stars visible to the naked eye to sort of fill it in. At the MVO, there really isn't anything like dark adaptation for the eyes. It's more like scanning the area, paying attention, and using averted vision techniques to bring out the dimmer stars. I should note that the constellation looks more like <a href="http://en.wikipedia.org/wiki/Orion_(constellation)">LEPUS on the Orion wiki page</a> than on the <a href="http://en.wikipedia.org/wiki/R_Leporis">R Laporis</a> wiki page.
<p>The ten inch scope cooled down, and i performed an alignment using Rigel and Polaris. Rigel was chosen because it's near the target. Polaris was chosen because it was handy. The computer reports how good the alignment was, and it was excellent. R Laporis is less than a degree above NGC 1710. NGC 1710 is a galaxy that is absolutely invisible from the Mercury Vapor Observatory, since it's not one of the three brightest galaxies in the sky. The idea was to get into the neighborhood. It took about a minute of searching to find it. My wife also got a look at it briefly, before clouds blocked it. It looks like a <font color="#C00000">seriously red LED</font> light. Orion's Betelgeuse is also a red supergiant. And it's nearby in the sky, so i took a look at it for comparison. While Betelgeuse is somewhat orangish naked eye, it looked positively white in the scope, though not white like Rigel. The difference for R Laporis is that the star pushes carbon into its atmosphere. This carbon blocks blue light from the otherwise red giant, making it look much, much redder.
<p>R Leporis is fairly faint, at about 10th magnitude. This is not a problem at the MVO. This ten inch (254 mm) scope has a collecting area (with the secondary mirror subtracted) of 47,553 square millimeters. My eyes dilate to 6.5 mm, which works out to 33 square millimeters. So the scope brings in 1,433 times more light into my eyes. That works out to a light grasp improvement of about 7.9 magnitudes. I was seeing 4th magnitude stars naked eye, so 12th magnitude should have been reachable with the scope. In addition to that, even low magnification (48x) tends to dim extended objects like galaxies and the sky glow, but not point like objects like stars. So the contrast is much, much better. A tenth magnitude star is fairly bright in the scope. Unfortunately, I didn't get a chance to see if R Laporis was visible in the 9x50 finder scope. It wasn't obvious in the 10x50 binoculars, but i didn't yet know exactly where to look.
<p><img src="http://farm9.staticflickr.com/8521/8485297339_8d2fe2e9a3_z.jpg" align="right">R Laporis is a variable star with a period of about 432 days (14 months). It most recently peaked near magnitude 6 in November 2012. So it should be faintest in June 2013 near magnitude 11. Here's the current <a href="http://www.aavso.org/lcg/plot?auid=000-BBH-722&starname=R%20LEP&lastdays=1000&start=&stop=2456288.658213553&obscode=&obscode_symbol=2&obstotals=yes&calendar=calendar&forcetics=&grid=on&visual=on&v=on&pointsize=1&width=800&height=450&mag1=&mag2=&mean=&vmean=
">AAVSO light curve</a>. To search for the star, use <b>R LEP</b> on the <a href="http://www.aavso.org/">AAVSO</a> web site. R Laporis should be at peak brightness again in January 2014 (about 40 times brighter). And, Orion, and therefore Lepus, will be well placed in the evening sky as well.
<p>It was freezing cold, so i limited myself to a few other objects. Polaris and Rigel were alignment stars. Though i could have aligned using the finder scope's cross hairs, the main scope was used. Betelgeuse, Rigel and Sirius were used for comparison. Sirius was blinding. Jupiter was above the first quarter moon. The four Galilean moons were clearly visible in 10x50 binoculars. I didn't look at the Moon with optics, as the sky was very clear, and the moon filter was in the house.
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-51952419987668559472013-02-14T14:45:00.000-05:002013-02-14T14:45:56.023-05:00Forth for Enlightenment, part thirteen of ten, Primes too<p>In <a href="http://predelusional.blogspot.com/2011/06/forth-for-enlightenment-part-nine-of.html">part nine</a> we had an introduction to testing if a number is prime. A function to check for primality was presented. It's short and to the point. And, since it checks by dividing the number by all integers up to the square root of the number, the execution time is proportional to the square root of the number. Is there something that can be done to speed it up? Absolutely.
<p>For one thing, all numbers greater than two are divisible by two. So dividing by those numbers doesn't have to be done. One can test for even numbers by starting with three and skipping every other number. That's a quick and easy test. One can apply the same logic and skip numbers divisible by three after three. That's a little more complicated. The easiest approach appears to be to note that you can skip every other division by three, since those are divisible by two. That is, one can skip by six, and only check some of the numbers in each block. This code performs this sort of check. It searches two and three, then by sixes starting with five.
<pre>
«
0 0 → n s a «
IF n 2 < THEN
1 'a' STO
ELSE
IF n 3 > THEN
IF n 2 MOD 0 == THEN
2 'a' STO
ELSE
IF n 3 MOD 0 == THEN
3 'a' STO
ELSE
IF n 7 > THEN
n √ FLOOR 's' STO
5 s FOR x
IF n x MOD 0 == THEN
x 'a' STO
s 'x' STO
END
IF n x 2 + MOD 0 == THEN
x 2 + 'a' STO
s 'x' STO
END
6 STEP
END
END
END
END
END
a
»
» 'ISP2' STO
</pre>
<p>Here are some timings to show the speed up. On the left is the number that is tested. Then, the number of seconds for ISP and ISP2 to complete the check. Note that all numbers tested are, in fact, primes. So this is sort of the worst case. There was no run of 10000019 for ISP.
<table border=1><tr><th>Number</th><th>ISP</th><th>ISP2</th></tr>
<tr><td align=right>10007</td><td align=right>5</td><td align=right>2.3</td></tr>
<tr><td align=right>100003</td><td align=right>15</td><td align=right>5.4</td></tr>
<tr><td align=right>1000003</td><td align=right>47.3</td><td align=right>15.5</td></tr>
<tr><td align=right>10000019</td><td align=right>na</td><td align=right>47.7</td></tr>
</table>
<p>In any case, it's pretty clear that as the number goes up, so does the time. Of note is that ISP2 performs about as well as ISP does on numbers that are ten times larger. That's because both algorithms have time that goes up with the square root of the number. The ISP2 implementation is faster because instead of checking every number, it checks two numbers for every six. That's one third the number of divide checks. Since it does one third as much work, it should perform about as well on number 3 * 3 = 9 times larger. Nine is pretty similar to ten from a benchmark perspective.
<p>This factor of three performance increase comes at a cost. For the HP-28c, this cost is size. While ISP only requires 82 bytes, ISP2 requires 443 bytes. Is that a big deal? Yes. For one thing, since this is a single big function, if you make a mistake and need to edit it, you get "No room to enter". You have to type the whole function in again from scratch.
<p>Are there prime number test algorithms that do better than going up in time with the square root of the number? Yes. But they either require remembering stuff, or have more code, or both. The HP-28c simply doesn't have the memory to do a significant sieve or the code for the <a href="http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test">Miller-Rabin primality test</a>.
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0tag:blogger.com,1999:blog-15145059.post-58236650314876751992013-02-06T15:55:00.000-05:002013-02-06T15:55:49.599-05:00Forth for Enlightenment, part twelve of ten, Four Digit Puzzle<p>This is another number based logic puzzle. It can be solved without a computer. It's not difficult. The mostly brute force coded solution is straight forward too. It's included because of the rewrites. Like the previous puzzle, individual digits need to be examined. An experiment for this code is to use strings to extract digits. First the problem statement.
<p>What is the four digit number in which the first digit is one-third the second, the third is the sum of the first and second, and the last is three times the second?
<p>First, just a minor bit of analysis. We're looking for a four digit number. One imagines that four digit numbers have a range from 1000 to 9999. I mean, what's the difference between 0000 and 00000? Is the later a five digit number? But 0000 is a solution, right? This program assumes 1000 to 9999, but to save time, it <a href="http://predelusional.blogspot.com/2013/01/forth-for-enlightenment-part-ten-of-ten.html">stops when it finds</a> a solution. The code <b>9999 'X' STO</b> sets the variable <b>X</b> to its final value, so that the <b>FOR</b> loop ends. Without this, the program takes well over an hour to execute, and finds only the one solution.
<pre>
«
1000 9999 FOR X
X →STR 1 1 SUB STR→ 'A' STO
X →STR 2 2 SUB STR→ 'B' STO
X →STR 3 3 SUB STR→ 'C' STO
X →STR 4 4 SUB STR→ 'D' STO
IF A 3 * B ==
A B + C == AND
B 3 * D == AND THEN
X
9999 'X' STO
END
NEXT
'A' PURGE 'B' PURGE 'C' PURGE 'D' PURGE
440 .1 BEEP
» 'PUZ4' STO
</pre>
<p>This code requires 307 bytes of memory, and takes and 225 seconds for execution. It produces the right answer, 1349.
<p>So, <b>X →STR</b> takes the number <b>X</b>, and converts it to a string. <b>1 1 SUB</b> returns the substring that is the first character. Since more arithmetic needs to be done, <b>STR→</b> converts it back to a number. Once each digit is isolated, it is assigned to a global variable. The number, <b>X</b> or <b>ABCD</b>, is a candidate solution. The <b>IF</b> statement figures out if <b>ABCD</b> is a solution or not.
<p>The <b>IF</b> statement performs each of the tests. <b>A 3 * B ==</b> multiplies A * 3, and compares it to <b>B</b>. <b>A</b> has to be an integer from 0 to 9. And so does <b>B</b>. One can multiply <b>A</b> by 3 or divide <b>B</b> by 3 and get the same result. The next bit, <b>A B + C == AND</b> adds <b>A</b> and <b>B</b> and compares the result to <b>C</b>. The <b>AND</b> bit combines the first two logic results. The result of the <b>AND</b> is true only if both of the conditions are true. Finally, <b>B 3 * D == AND</b> multiplies the second digit by 3 and compares that to the 4th digit. <b>AND</b> combines the result with the first two results.
<p>The code <b>440 .1 BEEP</b> makes the machine beep at the end. That makes it easier to time the execution with a stopwatch.
<p>The next idea explored is saving <b>X →STR</b> on the stack, instead of recalling X and converting it to a string 4 times. The code <b>X DUP DUP2</b> puts 4 copies of X converted to a string onto the stack. One copy is consumed in each of the following lines.
<pre>
«
1000 9999 FOR X
X →STR DUP DUP2
1 1 SUB STR→ 'A' STO
2 2 SUB STR→ 'B' STO
3 3 SUB STR→ 'C' STO
4 4 SUB STR→ 'D' STO
IF A 3 * B ==
A B + C == AND
B 3 * D == AND THEN
X
9999 'X' STO
END
NEXT
'A' PURGE 'B' PURGE 'C' PURGE 'D' PURGE
440 .1 BEEP
» 'PUZ4' STO
</pre>
<p>This version is smaller, using only 291 bytes. It's also faster, taking 190 seconds.
<p>Using strings to extract digits was an experiment. We had a numeric digit extractor called G in our <a href="http://predelusional.blogspot.com/2013/02/forth-for-enlightenment-part-eleven-of.html">previous number puzzle</a>. Here it is.
<pre>
«
DUP 10 / FLOOR SWAP 10 MOD
» 'G' STO
</pre>
<p>The G function takes a number, and produces the number divided by ten, and the remainder. This peels off the least significant digit. So the right most digit, <b>D</b> is obtained first. G is then called with the new smaller number to peel off the next digit. It doesn't get called for the last digit, since we know that the number had four digits. The third call to G must produce the first two digits. The program that uses it looks like this:
<pre>
«
1000 9999 FOR X
X G 'D' STO
G 'C' STO
G 'B' STO
'A' STO
IF A 3 * B ==
A B + C == AND
B 3 * D == AND THEN
X
9999 'X' STO
END
NEXT
'A' PURGE 'B' PURGE 'C' PURGE 'D' PURGE
440 .1 BEEP
» 'PUZ4' STO
</pre>
<p>It's slightly bigger than our optimized string version at 306 bytes of memory. But it's faster, taking only 103 seconds. The substring idea looked like it might be quicker, but it wasn't.
<p>One thing of note is the <b>PURGE</b> commands towards the end. Global variables are convenient, but they've got to be cleaned up at the end, otherwise, they stay around for the user to clean up. This isn't much of a big deal on the HP-28c, but on the HP-28s, there's much more memory, and more than one program might be loaded at a time. These variables would add clutter everywhere. Local variables get cleaned up automatically. And we <a href="http://predelusional.blogspot.com/2013/01/forth-for-enlightenment-part-ten-of-ten.html">learned how to use them</a> in a recent post. However, we need to change the G function to produce the digits on the stack all at once. That is, it leaves the shortened number on the stack where it can be used to produce the next digit. All the digits produced stay on the stack until converted to local variables.
<pre>
«
DUP 10 MOD SWAP 10 / FLOOR
» 'G' STO
</pre>
<p>Then the program follows.
<pre>
«
1000 9999 FOR X
X G G G
→ D C B A «
IF A 3 * B ==
A B + C == AND
B 3 * D == AND THEN
X
9999 'X' STO
END
»
NEXT
440 .1 BEEP
» 'PUZ4' STO
</pre>
<p>This local variable version is shorter, using 266 bytes and faster, taking 69 seconds. I'd have thought this version would be slower, since variables are created and destroyed every loop. So, not only is this version smaller and faster, but it looks easier to read to me.
<p>The code <b>→ D C B A «</b> takes the four digits that are on the stack, assigns them to local variables D, C, B and A. Local variable blocks can go anywhere.
<p>Curiously, in RPL, variables of any kind must be given an initial value. It's impossible to have a variable that isn't initialized. Using a variable that doesn't yet have a value is simply not a bug you can code in this language. Fortunately, there are lots of other kinds of bugs you can code, more than making up for this deficiency.
<p>The next idea is to try nested IF statements. Nested IFs are logically the same as the AND statements. They should be quicker since the tests can stop as soon as one is false. The C language allows shortcut logicals where additional conditionals are not evaluated. RPL on the HP-28c does not.
<pre>
«
1000 9999 FOR X
X G G G
→ D C B A «
IF A 3 * B == THEN
IF A B + C == THEN
IF B 3 * D == THEN
X
9999 'X' STO
END
END
END
»
NEXT
440 .1 BEEP
» 'PUZ4' STO
</pre>
<p>This version is larger at 296 bytes, but it's also faster at 54 seconds. Is it easier to read? Experimentation with the order of the IF statements did not yield a change in speed. One might expect that putting the condition that is false most often first would be faster, as less code is executed on average.
<p>Finally, we'll inline the G function. The HP-28c's RPL encourages using and calling functions, but it takes time to call a function and return. The resulting code is bigger since the G function is 49 bytes by itself, and this version has three copies of it. It's not necessarily easier to read, but it is quicker.
<pre>
«
1000 9999 FOR X
X
DUP 10 MOD SWAP 10 / FLOOR
DUP 10 MOD SWAP 10 / FLOOR
DUP 10 MOD SWAP 10 / FLOOR
→ D C B A «
IF A 3 * B == THEN
IF A B + C == THEN
IF B 3 * D == THEN
X
9999 'X' STO
END
END
END
»
NEXT
440 .1 BEEP
» 'PUZ4' STO
</pre>
<p>This version requires 334 bytes, but comes in at 47 seconds. That's about 4.8 times faster than the first version. Is that as fast as it can be done? Of course not. For one thing, the problem can be solved without a program, and it doesn't take very long. This exercise is about optimization. In this case, we didn't know the relative speeds of different functions before we started. So, a black box trial and error system was used to deduce what turns out to be fast or small. For RPL, this is what it takes. But it often takes something like it in other languages. You might think that instruction speed in assembly language would be well known. But most modern processors sometimes can perform instructions while waiting on external memory, or can even execute multiple instructions simultaneously. And often, one needs to sign a non-disclosure form to get the documentation. If that's not enough, various levels of cache miss or TLB thrashing can toss your best estimates out the window. Trial and error has the advantage of trial, which is sort of a final arbiter anyway. So make your best guess, and ask the universe if you're right.
Stephenhttp://www.blogger.com/profile/03934169832326108710noreply@blogger.com0