While it's not much to look at on it's own, today's Irregular, and most especially the long annotation that accompanies it, offers an interesting look at art. The discussion on the piece of "music" title 4' 33" almost killed me, but it was much too long to repost here. I strongly suggest giving it all a read, espescially if you enjoy modern art jokes.
Douglas Hofstadter once wrote in his seminal book Gödel, Escher, Bach: an Eternal Golden Braid that it's difficult for an author to write something with a sudden, unexpected ending, because the fact that the reader is running out of pages makes it obvious well before the end that the ending must be coming soon. He suggested a way to prevent this. I'll discuss this in the context of a novel, just to make the concept clearer.
The idea is that you actually end the story partway through the book, so that you can't tell from how much remains how close you are to the end. Just filling the rest of the book with blank pages isn't good enough, because a reader can just turn back to the last bit of text and figure out that that's where the story ends. So when the story ends, you keep writing more of the events that happen afterwards. In this way you fill an extra 10 or 30 or 100 pages of the book, thus making it impossible for someone to tell where the actual end of the story is without reading it.
And in order to make it clear where the end of the story is to the diligent reader who works all the way through, you subtly change the writing in some way when the end occurs. You could change the mood or the writing style or the characters or the topic, in a way that marks a clear disconnect to the diligent reader. The reader will then know where the true end of the story occurs, and realise that everything that comes after it is just filler text to fool them into thinking that there was more to the story than there really is.
I think that's a pretty amazing idea. I'm not sure I've ever seen anyone actually do it, though.
From Computers are Lousy Random Number Generators:
The world is random. Computers aren't. Randomness is really, really hard for computers. It's important to understand the ramifications of this big divide between the analog and digital world, otherwise you're likely to make the same rookie mistakes Netscape did.
The article provides a decent explanation of why random numbers are important for cryptography and why computers aren't any good at it. The biggest problem with using a computer as a random number generator is that they are designed for the opposite. They are made to provide the consistent results. To get true randomness, you have to "reach outside the computer".
This year, I'd like to say thank you to my friends and my family. Without you, I wouldn't make it through most days.
So that I don't end this on a serious note, I wanted everyone to enjoy soem Pumpkin Pi this Thanksgiving.
It's come to my attention that the possible combinations of letters possible with 7 letter tiles is just shy of a million. That's just with those seven letters. It doesn't take into account the combinations with what's already on the board. Running a spell check against all of those combinations is way too costly in terms of CPU cycles. I'll have to work it another way.
Instead of starting from a list of over a million possible combinations of letters, I can start from a list of valid words. There's good news here.
From http://personal.riverusers.com/~thegrendel/software.html
Updated millennial edition of ENABLE (ENABLE2K): The Enhanced North American Benchmark LEexicon package provides a 173,000+ word standardized tournament-level master list, more carefully researched than "official" and proprietary lists. It is not restricted to words of an arbitrary length and it features all "official" updates. The ENABLE list has been placed in the Public Domain and is both free and freely distributable. This is the list used by the WORDY word study system, above, and by various online Scrabble® servers and software developers (at least two commercial word games use it as its dictionary). It is highly recommended that the (updated) ENABLE SUPPLEMENT [785K], and the ABLE SUPPLEMENT [559K], additional lists and documentation packages for ENABLE be obtained. Freeware.
...
The YAWL LIST (updated Y2K version) is a combination of the ENABLE list and all the above supplementary lists, effectively a superset of the international SOWPODS list. It contains over 264,000 words and is probably the largest and most comprehensive list of its kind. This free Public Domain list is targeted toward Linux, BSD, Be OS, and other 'nix systems and is in standard UNIX ASCII format. It may require conversion before it can be viewed, edited, or accessed by Windows or Mac users. [704K]
That shortens our starting list from over a million to just over a quarter of a million. My idea, which is currently untested, is to go through this list in a series of iterations. Each iteration through the list would delete words we can't use from the list. This could get complicated, but it still looks like it will be faster than working at it from the other direction.
You take some salmon, cream cheese and jalapeños, then wrap that in rice and seaweed. Fry the whole thing, then top it with spicy mayo, green onions and sesame seeds.
Cost: $8.25
Worth every penny.
If you can't tell yet, I thoroughly enjoyed my dinner last night at Okura Sushi & Grill. The baby gecko was not mine, unfortunately. I only got a piece of it. I'd already ordered a spicy scallop roll before I'd heard about it. It was good too, just not as good as the gecko. The steak was delicious as well.
The Sake was pretty good too; good enough to make us order more of it.
After looking at the picture of the gecko for awhile, the name of the roll is starting to make more sense. After it's fried and topped, it comes close to those colors.
I was poking around trying to find some spell checking API information and came across a blog entry that summed up a thought I had yesterday pretty well.
From The Wayward Weblog
Of course, the best feature of hosting your own game, is the reload option. I don't think we could play without it. Approaching the next door. What's beyond it? Better save the game here. Whoops, an ambush? Reload.
I wish life had a reload. I really do. Every time you encounter someone new there is a new chance to do something or say something stupid. If you could reload you could perfect the moment. You could keep trying until you finally did something just right, or found something incredibly clever to say. It would almost be like editing reality, like with a word processor with spell check. That would be a great product to sell, Reality Checker 1.0. Well, better not buy the first version; 3.0 then, that'd do it.
I was playing Literati with Kortnee this evening. In the middle of the game, I had a Very Bad IdeaTM. I thought, how hard would it be to create a program to automatically calculate the best possible move for me? The program itself wouldn't be too bad, but I’m not sure I could make the whole thing fast enough to be usable. But I like a challenge.
So now, I’m in the process of installing Visual Studio 2005 on Wraith so I can start the project. And I’ve got a short list of preliminary design requirements and ideas.
- Preliminary Design Requirements
- Must track current state of board
- Must keep track of current letters in hand
- Must use dictionary.com spell checker or equivalent
- Must give the results as best scores possible
- Must be able to do so within 3 minutes
- Must be able to quickly enter your moves and opponents moves
- Ideas & Things That Would Be NiceTM
- A branching algorithm may be able to speed up the searches
- Combination plays should have higher priority for searching
- If possible, it should be pretty too
- Would an interface that resembles the game be the easiest and quickest way to enter your opponents moves?
- Some Things I’ll Need to Research
- Scrabble theory
- Spell checker theory
- Searching algorithms
After the mess that was fixing my car this weekend, my problems from yesterday were not a welcome addition. Monday morning, I was woken up at 9:30 by a call from work. One of the registers up front had crashed and wouldn't boot up again.
Tuesday, after I got to work, it was immediately apparent that it was a failed hard drive. It was receiving SMART errors and making clicking sounds instead of booting. Because it was a necessity to get it up and running quickly, I went down the street (in someone else's car) to get a new hard drive for it. I hadn't even bothered to check the warranty, because get a replacement that way would have taken too long. I've discovered since then that it doesn't matter anyway. The drive was 4 years old.
The rest of my morning, up until about 1:00 PM, was spent reinstalling Windows and the various programs required to make it work as a register on our system. But I kept being interrupted by a printer problem on the other register up front. At about 1:00, I took the almost finished register computer back up front to hook it up and install the printer drivers. But the fun didn't stop there.
As I was hooking it up, I discovered that our AS/400, that hosts most of our software, had crashed. I ran to the back to find out what was wrong. The UPS for the server was off. I turned it on and walked away. A minute later, I walked back by and it was off again. Every time I turned it back on, it would almost immediately shut back down. This wasn't going to work.
To bypass the problem and get us running again, I plugged the AS/400 directly into the wall. We have another UPS in the building, but it's already running 3 servers and doesn't have enough capacity to run the AS/400 as well.
Forty-five minutes later, after the AS/400 had booted back up, I was finally able to finish setting up the register computer. But then the other printer kept failing all day and it's hard to work on it when they're trying to use it. So for the last two hours, I rigged that register to use the printer from the newly rebuilt one that wasn't being used that day anyway.
This morning, I spent 30 minutes cleaning out the non-working printer. Once I could finally watch it failing to feed properly, it was apparent it was a mechanical problem. I converted it to feed from the front instead of the back after cleaning it, and it seems to be working fine now.
If my car hadn't started working yesterday, it would have been a complete disaster of a day.
After a week worth of frustration, the ol' car is up and running again. After two failed attempts, we got the new fuel filter on. The hose we put on there kept kinking up, so we had to put in a connector with a 90 degree angle in it. My coat needs to go through the washer. It still smells like gasoline from getting sprayed by the pressure I'd forgetten to release before removing our first failed attempt.
After that fiasco, the engine was still not getting fuel, so we checked the fuel rail and the injectors. The result was inconclusive, so we decided to replace the fuel injectors. No one had 4 of them in stock, and we didn't have time to round them up and work on it on Monday, so we ordered them online (for about half that price). They came in yesterday.
My Dad installed them while I was still at work. Although, by the time he was done installing them, he was so frustrated that he left it up to me to finish getting everything back together.
I replaced three of the tires on Monday, but by the time I got home with the front tires, I was too tired and lazy to finish putting them on, so I'd just propped them on so no one would steal them. I got them on last night and finish getting engine together. Then I had to head to the car wash to get the layers of dirt of the windows so I could drive. Didn't take long and the car looks much nicer for the effort.
I was worried about my ability to drive the car, since it had been over a year and a half since I'd driven with a manual transmission. It's just like riding a bike, only easier. I only killed it twice, and one of those time was due to the incline in my driveway when I was first leaving.
Now, I just need an oil change and to get the muffler mounted properly. The only change is coming after work today, and the muffler will be fixed soon. I discovered, while changed the fuel filter, that some of the bumber will have to be cut out to allow for the muffler to go where it needs to, but that shouldn't be too much trouble.
After about an hour of working through the logic in my Payroll History program, I finally found the bug that was causing it to report the wrong goal number of hours for each employee. It was a small mistake in the code, but a huge logical mistake. Then I discovered an even bigger one. To calculate the Goal Hours, we take the number of pay periods (which are two weeks) in the year and multiply it by 80.
To calculate the number of pay periods in the year, we use this formula:
yearend = {@yearend}
// Find the number of days between yearstart and yearend and add one to the result.
// The +1 lets us count the first day, which we would otherwise be excluding. days = DateDiff("d", yearstart, yearend) + 1
// Perform an integer division on it, so we can ignore the remainder. formula = days 14
The first mistake was that I’d excluded the +1, so if you printed the report on payday, it would give you results that were too small because of the rounding involved.
To get the year end, you just have to use the current day if you’re in the year you’re printing, but otherwise, you use December 31st. Getting the year start is more difficult. This is where the big logic error came in.
yearstart = DateSerial(ToNumber({payperiod.year}), 1, 1)
// unless the employee started after the first of the year.
if ({@hiredthisyear}) Then yearstart = DateValue({employee.fdthir})
// Then find the number of days between that day and the start of a known pay period before the
// software was written.
days = DateDiff("d", DateSerial(2001,6,1), yearstart)
// Now subtract the number of days that difference is from the start of a payperiod from the
// year start day.
days = 0 - (days mod 14)
formula = DateAdd("d", days, yearstart)
When I first wrote the formula, I was adding 14 – days mod 14 to the year start date and adding 1 to the number of payperiods I calculated. It only worked right when you had a year start date in the middle of the year, which was the case I was trying to fix at the time. However, it gave a result that was always a pay period off for people who’d been there the whole year. Now it properly counts that pay period that technically started before the year did since it’s the date you get paid that matters.



