[#129195] Is compatibility important for us? — Esteban Manchado Vel痙quez <zoso@...>

Hi all,

28 messages 2005/02/01
[#129199] Re: Is compatibility important for us? — James Britt <jamesUNDERBARb@...> 2005/02/01

Esteban Manchado Vel痙quez wrote:

[#129204] Re: Is compatibility important for us? — Francis Hwang <sera@...> 2005/02/01

[#129207] Re: Is compatibility important for us? — Eric Hodel <drbrain@...7.net> 2005/02/01

On 31 Jan 2005, at 18:21, Francis Hwang wrote:

[#129209] Re: Is compatibility important for us? — Francis Hwang <sera@...> 2005/02/01

[#129214] Re: Is compatibility important for us? — "Trans" <transfire@...> 2005/02/01

Francis,

[#129216] Re: Is compatibility important for us? — Francis Hwang <sera@...> 2005/02/01

[#129698] Re: Is compatibility important for us? — Esteban Manchado Vel痙quez <zoso@...> 2005/02/04

I had this on "postponed", and I just realized. Sorry.

[#129718] Re: Is compatibility important for us? — James Britt <jamesUNDERBARb@...> 2005/02/05

Esteban Manchado Vel痙quez wrote:

[#129808] Re: Is compatibility important for us? — Esteban Manchado Vel痙quez <zoso@...> 2005/02/05

On Sat, Feb 05, 2005 at 10:29:11AM +0900, James Britt wrote:

[#129218] Partial function application (was: Re: Binding precedence for first sym...) — E S <eero.saynatkari@...>

Trans wrote:

13 messages 2005/02/01
[#129220] Re: Partial function application (was: Re: Binding precedence for first sym...) — "Trans" <transfire@...> 2005/02/01

[#129289] Newbie: How to delete a Rails app (Windows) — peter.cutting@...

Hi

25 messages 2005/02/01
[#129362] Re: Newbie: How to delete a Rails app (Windows) — Douglas Livingstone <rampant@...> 2005/02/02

> but how do I delete? (If I just delete then I get a permissions

[#129373] Re: Newbie: How to delete a Rails app (Windows) — Caio Tiago Oliveira <caiot1@...> 2005/02/02

Douglas Livingstone, 2/2/2005 06:04:

[#129380] Re: Newbie: How to delete a Rails app (Windows) — peter.cutting@... 2005/02/02

yes the switching off may have helped (will try logging off next time

[#129385] Nuby needs an intro to testing for Win 2K — Barry Sperling <barry@...> 2005/02/02

[#129293] Re: [QUIZ] To Excel (#17) — "Graham Foster" <graham@...>

> Years ago, on a job developing custom reporting software, this was

15 messages 2005/02/01

[#129316] Wee 0.7.0 + Tutorial Videos — Michael Neumann <mneumann@...>

Hi,

27 messages 2005/02/01
[#129449] Re: Wee 0.7.0 + Tutorial Videos — itsme213@... 2005/02/03

Michael, I may be doing something wrong, but none of the MPEGs worked

[#129345] ANN: ParseTree 1.3.3 and ruby2c 1.0.0 beta 1 — Ryan Davis <ryand-ruby@...>

Actual announcements are on http://blog.zenspider.com/

24 messages 2005/02/02

[#129351] yarv and dbi — jm <jeffm@...>

Anyone out there tried dbi with yarv

18 messages 2005/02/02
[#129358] Re: yarv and dbi — SASADA Koichi <ko1@...> 2005/02/02

jm <jeffm@ghostgun.com> wrote :

[#129451] - E01: The Java Failure - May Ruby Helps? — Ilias Lazaridis <ilias@...>

"

90 messages 2005/02/03
[#130693] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Ilias Lazaridis <ilias@...> 2005/02/13

Ilias Lazaridis wrote:

[#130749] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Douglas Livingstone <rampant@...> 2005/02/14

> From the communities behaviour, I extract the following answer:

[#130784] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Ilias Lazaridis <ilias@...> 2005/02/14

Douglas Livingstone wrote:

[#130785] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Luke Graham <spoooq@...> 2005/02/14

From the link - "fictive technology collection". Ive worked on some of

[#130786] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Luke Graham <spoooq@...> 2005/02/14

Some of it is possible. I have created persistent Ruby objects, for

[#130823] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Austin Ziegler <halostatue@...> 2005/02/14

On Mon, 14 Feb 2005 17:49:18 +0900, Luke Graham <spoooq@gmail.com> wrote:

[#130856] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Ilias Lazaridis <ilias@...> 2005/02/14

Austin Ziegler wrote:

[#130871] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Austin Ziegler <halostatue@...> 2005/02/14

On Tue, 15 Feb 2005 04:09:54 +0900, Ilias Lazaridis

[#131021] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Ilias Lazaridis <ilias@...> 2005/02/15

Austin Ziegler wrote:

[#131025] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Thomas E Enebo <enebo@...> 2005/02/15

On Wed, 16 Feb 2005, Ilias Lazaridis defenestrated me:

[#131031] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Ilias Lazaridis <ilias@...> 2005/02/15

Thomas E Enebo wrote:

[#131036] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Thomas E Enebo <enebo@...> 2005/02/15

On Wed, 16 Feb 2005, Ilias Lazaridis defenestrated me:

[#131039] Re: [EVALUATION] - E01: The Java Failure - May Ruby Helps? — Ilias Lazaridis <ilias@...> 2005/02/15

Thomas E Enebo wrote:

[#129452] RedCloth 3.0.2 -- Please, oh please, let this be the one — why the lucky stiff <ruby-talk@...>

Okay, okay. The tumblers are clicking, the clouds are parting.

15 messages 2005/02/03

[#129554] lack of reaction to latest ruby implementations — Alexander Kellett <ruby-lists@...>

working on alternatives for the ruby runtime has

37 messages 2005/02/03

[#129686] iteration the ruby way — Navindra Umanee <navindra@...>

Hi,

18 messages 2005/02/04

[#129726] Ruby for closed source projects — Michael Gebhart <mail@...>

Hi,

16 messages 2005/02/05

[#129778] Korundum: error when overriding a KDE::RootPixmap method — Martin Traverso <martin@...>

Hi,

15 messages 2005/02/05

[#129831] Benchmark Mono - Ruby — Michael Gebhart <mail@...>

Hi,

21 messages 2005/02/06

[#129878] Ruby Interactive Shell — "Jenjhiz" <jenjhiz@...>

Hello,

18 messages 2005/02/06

[#129959] delayed string interpolation — Navindra Umanee <navindra@...>

Hi,

14 messages 2005/02/07

[#130044] web testing with Ruby — Jason Sweat <jason.sweat@...>

Does anyone have suggestions for projects/libraries to web test code

12 messages 2005/02/07

[#130068] Grid computing with Ruby? — Alexander Staubo <alex@...>

I have an interest in distributed computing and so-called grid

11 messages 2005/02/08

[#130090] Squeak like environment for Ruby — Logan Capaldo <logancapaldo@...>

Lately I've been playing around with Squeak (http://www.squeak.org/),

20 messages 2005/02/08
[#130091] Re: Squeak like environment for Ruby — Caio Tiago Oliveira <caiot1@...> 2005/02/08

Logan Capaldo, 8/2/2005 00:45:

[#130108] Re: Squeak like environment for Ruby — Alexander Kellett <ruby-lists@...> 2005/02/08

On Feb 8, 2005, at 4:59 AM, Caio Tiago Oliveira wrote:

[#130102] Syck 0.50 -- The new YAML is here for testing — why the lucky stiff <ruby-talk@...>

Finally, I can go back to drawing ponies out on the bridge by the old

13 messages 2005/02/08

[#130180] Ruby users in India? — Premshree Pillai <premshree.pillai@...>

Hi,

20 messages 2005/02/08

[#130280] How to mimic Perl's `s///' in Ruby? — Jos Backus <jos@...>

Given Perl's

18 messages 2005/02/09

[#130305] Phone number to words — Jordi Bunster <jordi@...>

Does anyone have one of those algorithms that convert a phone number to

13 messages 2005/02/10

[#130327] Building a Better Functor — "John W. Long" <ng@...>

Hi,

29 messages 2005/02/10

[#130399] A Ruby-relevant quote from Alan Kay — "Curt Hibbs" <curt@...>

ACM Queue just published an interview with Alan Kay (the creator of

27 messages 2005/02/10
[#130400] Re: A Ruby-relevant quote from Alan Kay — PA <petite.abeille@...> 2005/02/10

[#130408] Re: A Ruby-relevant quote from Alan Kay — Douglas Livingstone <rampant@...> 2005/02/10

> Steve Wart about "why Smalltalk never caught on":

[#130573] utilizing ++ and -- for comments — "Pe, Botp" <botp@...>

Since ++ and -- wont see the light of day in ruby, can we use it for comment

27 messages 2005/02/12
[#130587] Re: utilizing ++ and -- for comments — "George Moschovitis" <george.moschovitis@...> 2005/02/12

I also think that the =begin, =end notation is not comfortable to use.

[#130595] Re: utilizing ++ and -- for comments — Douglas Livingstone <rampant@...> 2005/02/12

> for example /* */

[#130707] Printing why's (poignant) guide to ruby — Richard Dale <Richard_Dale@...>

I'd like to try ruby on non-programmers teaching them using why's amazing

62 messages 2005/02/13
[#130714] Re: Printing why's (poignant) guide to ruby — Navindra Umanee <navindra@...> 2005/02/13

Richard Dale <Richard_Dale@tipitina.demon.co.uk> wrote:

[#130716] Re: Printing why's (poignant) guide to ruby — Alexander Kellett <ruby-lists@...> 2005/02/13

i'm really puzzled by this.

[#130731] Re: Printing why's (poignant) guide to ruby — Navindra Umanee <navindra@...> 2005/02/13

Alexander Kellett <ruby-lists@lypanov.net> wrote:

[#130843] Re: Printing why's (poignant) guide to ruby — Marcus Sharp <brothermarcus@...> 2005/02/14

*putting on flame retardant pants*

[#130715] Ruby on Windows: debugger questions and comments — umptious@... (JC)

'm evaluating scripting languages for a client. Ruby as a language

28 messages 2005/02/13

[#130742] (OT) Programmer's editors for the Mac — Timothy Hunter <cyclists@...>

Just got a new Powerbook, so I'm looking for suggestions for a good

43 messages 2005/02/14

[#130975] Is this old style Ruby? — centrepins@...

In Why's guide, I see the line:

30 messages 2005/02/15
[#130980] Re: Is this old style Ruby? — Jeremy Tregunna <jtregunna@...> 2005/02/15

[#130982] Re: Is this old style Ruby? — Nikolai Weibull <mailing-lists.ruby-talk@...> 2005/02/15

* Jeremy Tregunna (Feb 15, 2005 15:10):

[#130986] Re: Is this old style Ruby? — centrepins@... 2005/02/15

Page 349 of the (printed) pickaxe2 mentions '::' and '.', but doesn't

[#130988] Re: Is this old style Ruby? — "David A. Black" <dblack@...> 2005/02/15

Hi --

[#131103] Wee web-framework. It's great! — Joao Pedrosa <joaopedrosa@...>

Hi,

21 messages 2005/02/16
[#131111] Re: Wee web-framework. It's great! — "Vincent Foley" <vfoley@...> 2005/02/16

You know, I think Wee could become really hot if someone could mix it

[#131127] adding a dynamic method handler? (long post) — Mark Hubbart <discordantus@...>

Hi,

12 messages 2005/02/16

[#131132] Ruby + end user applications — "martinus" <martin.ankerl@...>

Ruby definitely needs more cool, simple to use, end user applications.

16 messages 2005/02/16

[#131168] FileSystem 0.1.0: Beta for me, Alpha for you — Francis Hwang <sera@...>

Greetings!

23 messages 2005/02/16

[#131252] Where is Ruby headed etc. — centrepins@... (Glenn)

A few musings/questions/dribble from an excited newbie. And my first

21 messages 2005/02/16
[#131256] Re: Where is Ruby headed etc. — Ben Giddings <bg-rubytalk@...> 2005/02/16

Glenn wrote:

[#131283] Re: Where is Ruby headed etc. — Brian McCallister <brianm@...> 2005/02/17

[#131286] Re: Where is Ruby headed etc. — Yukihiro Matsumoto <matz@...> 2005/02/17

Hi,

[#131275] installed ruby on linux without su access — Eko Budi Setiyo <contact_us@...>

Hi all,

17 messages 2005/02/17

[#131284] Ruby Visual Identity Team — "John W. Long" <ng@...>

Recently I've seen a couple of people mention how much they would like

43 messages 2005/02/17
[#131288] Re: Ruby Visual Identity Team — James Britt <jamesUNDERBARb@...> 2005/02/17

John W. Long wrote:

[#131307] Re: Ruby Visual Identity Team — gabriele renzi <rff_rff@...> 2005/02/17

James Britt ha scritto:

[#131404] - E02 - Nitro, a Ruby Based WebFramework — Ilias Lazaridis <ilias@...>

50 messages 2005/02/17
[#131445] Re: [EVALUATION] - E02 - Nitro, a Ruby Based WebFramework — Aredridel <aredridel@...> 2005/02/17

>

[#131490] Re: [EVALUATION] - E02 - Nitro, a Ruby Based WebFramework — Luke Graham <spoooq@...> 2005/02/18

Wow, I actually predicted this post in another thread. Nitro vs ruby is clearly

[#131494] Re: [EVALUATION] - E02 - Nitro, a Ruby Based WebFramework — Alexander Kellett <ruby-lists@...> 2005/02/18

not too sure to be honest.

[#131496] Re: [EVALUATION] - E02 - Nitro, a Ruby Based WebFramework — Alexander Kellett <ruby-lists@...> 2005/02/18

i take this back i read some of the various

[#131506] Re: [EVALUATION] - E02 - Nitro, a Ruby Based WebFramework — Bill Guindon <agorilla@...> 2005/02/18

On Fri, 18 Feb 2005 11:30:49 +0900, Alexander Kellett

[#131592] Re: [EVALUATION] - E02 - Nitro, a Ruby Based WebFramework — Christian Neukirchen <chneukirchen@...> 2005/02/18

Bill Guindon <agorilla@gmail.com> writes:

[#131605] Re: [EVALUATION] - E02 - Nitro, a Ruby Based WebFramework — Ilias Lazaridis <ilias@...> 2005/02/18

Christian Neukirchen wrote:

[#131422] ICFP Contest Dates Are Set — James Edward Gray II <james@...>

It's pretty early yet, but a lot of coders need time to plan and gather

13 messages 2005/02/17

[#131469] Virtual Ruby Group — Zach Dennis <zdennis@...>

Ok, I have a question for fellow rubyists, rubyiers, etc... There seem

55 messages 2005/02/17
[#131906] Re: Virtual Ruby Group — Zach Dennis <zdennis@...> 2005/02/21

It looks like there are a few folks interested in the Virtual Ruby Group

[#131921] Re: Virtual Ruby Group — "Curt Hibbs" <curt@...> 2005/02/21

One more suggestion: you could make a FreeRIDE plugin out of jabber4r, and

[#131942] Re: Virtual Ruby Group — Tanner Burson <tanner.burson@...> 2005/02/21

On Mon, 21 Feb 2005 21:02:19 +0900, Curt Hibbs <curt@hibbs.com> wrote:

[#131946] Re: Virtual Ruby Group — Bill Guindon <agorilla@...> 2005/02/21

On Tue, 22 Feb 2005 00:41:36 +0900, Tanner Burson

[#132114] Re: Virtual Ruby Group — Zach Dennis <zdennis@...> 2005/02/23

Bill Guindon wrote:

[#131499] pulling my hair out, why won't Kernel.sleep(0) sleep? — Sam Roberts <sroberts@...>

Can anybody give me any hints as to what I should be looking for? What

17 messages 2005/02/18

[#131545] Require when Executed file is required by another file. — "Zev Blut" <rubyzbibd@...>

Hello,

11 messages 2005/02/18

[#131563] 1-800-THE-QUIZ (#20) — Ruby Quiz <james@...>

The three rules of Ruby Quiz:

12 messages 2005/02/18

[#131635] Rails presentation — Jamis Buck <jamis_buck@...>

So I gave a presentation on Rails to the Utah Java Users Group last

14 messages 2005/02/18

[#131685] FXIrb 0.14 - a Win32 GUI wrapper around IRB — Martin DeMello <martindemello@...>

- What?

19 messages 2005/02/18

[#131753] Array#join non string arguments — Simon Strandgaard <neoneye@...>

A proposal:

15 messages 2005/02/19

[#131808] destructive! operations — Navindra Umanee <navindra@...>

Hi,

58 messages 2005/02/20
[#131847] Re: destructive! operations — "Robert Klemme" <bob.news@...> 2005/02/20

[#131852] Re: destructive! operations — Caio Tiago Oliveira <caiot1@...> 2005/02/20

Robert Klemme, 20/2/2005 12:04:

[#131859] Re: destructive! operations — James Edward Gray II <james@...> 2005/02/20

On Feb 20, 2005, at 10:23 AM, Caio Tiago Oliveira wrote:

[#131880] Re: destructive! operations — Navindra Umanee <navindra@...> 2005/02/20

James Edward Gray II <james@grayproductions.net> wrote:

[#131929] Re: destructive! operations — Austin Ziegler <halostatue@...> 2005/02/21

On Mon, 21 Feb 2005 06:07:58 +0900, Navindra Umanee

[#131939] Re: destructive! operations — "Bill Kelly" <billk@...> 2005/02/21

From: "Christian Neukirchen" <chneukirchen@gmail.com>

[#131943] Re: destructive! operations — Christian Neukirchen <chneukirchen@...> 2005/02/21

"Bill Kelly" <billk@cts.com> writes:

[#131958] Re: destructive! operations — Pit Capitain <pit@...> 2005/02/21

Christian Neukirchen schrieb:

[#131964] Re: destructive! operations — Christian Neukirchen <chneukirchen@...> 2005/02/21

Pit Capitain <pit@capitain.de> writes:

[#131969] Re: destructive! operations — Pit Capitain <pit@...> 2005/02/21

Christian Neukirchen schrieb:

[#131973] Re: destructive! operations — Christian Neukirchen <chneukirchen@...> 2005/02/21

Pit Capitain <pit@capitain.de> writes:

[#131985] Re: destructive! operations — "ES" <ruby-ml@...> 2005/02/21

On Mon, February 21, 2005 6:07 pm, Christian Neukirchen said:

[#131988] Re: destructive! operations — Pit Capitain <pit@...> 2005/02/21

ES schrieb:

[#131940] ANN: 2005 International Obfuscated Ruby Code Contest (IORCC) — Todd Nathan <iorcc@...>

Dear Fellow Rubists,

39 messages 2005/02/21
[#132095] Re: ANN: 2005 International Obfuscated Ruby Code Contest (IORCC) — "Josef 'Jupp' Schugt" <jupp@...> 2005/02/22

Todd Nathan wrote:

[#132102] Re: ANN: 2005 International Obfuscated Ruby Code Contest (IORCC) — Yukihiro Matsumoto <matz@...> 2005/02/22

Hi,

[#132105] Re: ANN: 2005 International Obfuscated Ruby Code Contest (IORCC) — "David A. Black" <dblack@...> 2005/02/22

Hi --

[#132107] Re: ANN: 2005 International Obfuscated Ruby Code Contest (IORCC) — Bill Guindon <agorilla@...> 2005/02/22

On Wed, 23 Feb 2005 08:23:08 +0900, David A. Black <dblack@wobblini.net> wrote:

[#132036] Proposal for nil, 0, and "" in an if statement — Dan Fitzpatrick <dan@...>

The following was derived from a portion of the destrutive! operations

38 messages 2005/02/22
[#132041] Re: Proposal for nil, 0, and "" in an if statement — David Heinemeier Hansson <david@...> 2005/02/22

> Here is a proposal for evaluating "", 0, and nil in an if statement:

[#132046] Re: Proposal for nil, 0, and "" in an if statement — Pit Capitain <pit@...> 2005/02/22

David Heinemeier Hansson schrieb:

[#132047] Re: Proposal for nil, 0, and "" in an if statement — Gavin Kistner <gavin@...> 2005/02/22

On Feb 22, 2005, at 6:41 AM, Pit Capitain wrote:

[#132053] Re: Proposal for nil, 0, and "" in an if statement — Gavin Kistner <gavin@...> 2005/02/22

On Feb 22, 2005, at 6:47 AM, Gavin Kistner wrote:

[#132054] Re: Proposal for nil, 0, and "" in an if statement — "David A. Black" <dblack@...> 2005/02/22

Hi --

[#132156] surprising: class A; end; A === A ==> false — Sam Roberts <sroberts@...>

I'm used to thinking of === being MORE useful

10 messages 2005/02/23

[#132186] Lighting the candles on the cake? — James Britt <jamesUNDERBARb@...>

Don't want to eat birthday cake too soon, but I know that someplace it's

12 messages 2005/02/24

[#132246] Simple HTML Renderer / Browser? — Randy Kramer <rhkramer@...>

I need a simple HTML renderer (to get started--eventually, I want to be able

18 messages 2005/02/24

[#132257] ruby-talk.com Expired? — James Edward Gray II <james@...>

I use http://ruby-talk.com/# style links on the Ruby Quiz site and I

13 messages 2005/02/24

[#132373] Ajax: A New Approach to Web Applications — "Curt Hibbs" <curt@...>

I always have trouble remembering whether its HttpXmlRequest, or

37 messages 2005/02/25
[#132379] Re: [OT] Ajax: A New Approach to Web Applications — "James G. Britt " <ruby.talk.list@...> 2005/02/25

On Sat, 26 Feb 2005 06:45:34 +0900, Curt Hibbs <curt@hibbs.com> wrote:

[#132382] Re: [OT] Ajax: A New Approach to Web Applications — "Curt Hibbs" <curt@...> 2005/02/25

James G. Britt wrote:

[#132375] Re: [OT] Ajax: A New Approach to Web Applications — PA <petite.abeille@...> 2005/02/25

[#132455] RubyGems 0.8.5 — Jim Weirich <jim@...>

= Announce: RubyGems Release 0.8.5

23 messages 2005/02/27
[#132525] RubyGems 0.8.6 (was Re: [ANN] RubyGems 0.8.5) — Chad Fowler <chadfowler@...> 2005/02/27

On Sun, 27 Feb 2005 10:34:34 +0900, Jim Weirich <jim@weirichhouse.org> wrote:

[#132500] Parsers vs. Homemade "Parsing" via REs — Randy Kramer <rhkramer@...>

I have the need to translate several megabytes of TWiki marked up text to

10 messages 2005/02/27

[SUMMARY] Solving Tactics (#18)

From: Ruby Quiz <james@...>
Date: 2005-02-10 13:52:58 UTC
List: ruby-talk #130356
Tactics is a strange game to us chess players.  I'm so use to considering going
first to be an advantage that I was just sure it would be true here too.  Wrong
again.  In Tactics, the second player can always force a win.

Though "why" this is true was part of the quiz, it hasn't really been answered
to my satisfaction.  I suspect it has to do with the moves remaining.  The first
player starts with the lead.  The second player can always choose to respond
with moves that keep the first player in the lead.  If you're in the lead at the
end of the game, you lose.  Put another way, the second player can always add to
the first player's move just the right amount of squares to keep the number of
remaining moves optimal.

What does that have to do with the quiz?  Not much.  It's just a good example of
the kinds of things I lose sleep over.

This quiz turned out to be a little tougher than I expected, though it really
shouldn't be.  A couple of people, including myself, posted about our failed
attempts to build the entire move tree.  You need to be a bit move clever than
that.

Sea&Gull shaved the move tree in half and even came up with the right answer.  I
haven't been able to convince myself it's for the right reasons yet though, so
I'm not going to look into that here.

The key optimization hit on by both solutions is simple:  All squares are either
on or off, thus ideal bit representation material.  An empty board is just
0b0000_0000_0000_0000 and the final board is 0b1111_1111_1111_1111.  To make a
move, just "or" (|) it to the board.  To see if a move is possible "and" (&) it
to the board and check for a result of zero.

As Bob Sidebotham said in the README of his solution, there are only 2**16
(65536) possible positions and bit math is as fast as a computer gets.  My
machine needs about 4 seconds to get the answer with Bob's code.  Let's look at
that code now:

	class Tactics
	  # The tactics board is represented as a 16-bit integer,
	  # 0's representing empty square; 1's representing filled squares.
	  EMPTY, FULL = 0, 0xFFFF

	  # Record a WIN or LOSS for potentially each of the 2**16 possible
	  # board positions. A position is recorded as a WIN (or LOSS) if
	  # that position represents a WIN (or LOSS) to a player prior to
	  # moving from that position.
	  WIN, LOSS = 1, 0
	  (@@position = Array.new(0x10000))[FULL] = WIN

	  # Create a new Tactics game, starting at the specified position.
	  def initialize( board = EMPTY,
	                  possible_moves = Tactics.all_possible_moves )
	    @board = board
	    @possible_moves = prune_possible_moves(board, possible_moves)
	  end

	  # Play from the current position. If *any* move guarantees a win,
	  # then mark this position as a WIN and return it. Otherwise this
	  # position loses.
	  def play
	    @possible_moves.each do |move|
	      new_board = @board | move
	      if ( @@position[new_board] ||
			   Tactics.new(new_board, @possible_moves).play) == LOSS then
	        return @@position[@board] = WIN 
	      end
	    end
	    @@position[@board] = LOSS
	  end

	  private

	  # Reduce the set of possible moves provided to the actual moves
	  # that are possible from the specified starting position.
	  def prune_possible_moves(board, possible_moves)
	    possible_moves.reject { |move| (board & move) != 0 }
	  end
  
	  # Compute all possible moves from an empty board.
	  def self.all_possible_moves
	    # Replicate the possibilities for a single row over each row and
	    # column of the grid.
	    (0..3).inject([]) do |moves, row|
	      [ 0b1000, 0b0100, 0b0010, 0b0001, 0b1100,
	        0b0110, 0b0011, 0b1110, 0b0111, 0b1111 ].each do |bits|
	        move = bits << 4 * row
	        moves << move << transpose(move)
	      end
	      moves
	    end.uniq
	  end

	  # Return the transposed board (horizontal to vertical, or vice-versa)
	  def self.transpose(board)
	    (0..15).inject(0) { |xboard, i|
			q,r = i.divmod(4); xboard |= board[i] << q + r*4
		}
	  end
	end

I'm not going to insult everyone's intelligence by breaking down well commented
code, but I do want to point out a few things.  Note toward the top that FULL is
set to 0xFFFF.  0xFFFF is just another way to say 0b1111_1111_1111_1111, which I
mentioned earlier.  Then on the second line of play(), you can see moves being
made with |.  prune_possible_moves() uses & and the check for zero to see what's
possible at a given position.

The other point of interest is all_possible_moves().  This method builds up a
list of all the moves that can be made, from the moves that can be made over a
single row.  That row of moves is bit shifted to cover the other rows and, with
help from transpose(), rotated to cover the columns too.  That's scary cool,
isn't it?

Bob's actual solution, using the above library:

	require 'tactics'
	
	puts %(#{ Tactics.new.play == Tactics::WIN ? "First" :
	                                             "Second" } player wins.)

I'm assuming that speaks for itself.  I'm not done showing off Bob yet though. 
Have a look at this beautiful set of unit tests:

	require 'test/unit'
	require 'tactics.rb'
	
	class TestTactics < Test::Unit::TestCase
	  # Test the play engine by trying various board positions that we
	  # know are winning or losing positions. Each of these is justified
	  # (no point in using ones that are just hunches on our part--'cause
	  # then what would we be verifying?).
	  def test_play
	    # Each position description is the position you're faced with
	    # just before playing. So "1 square loses" means that if it's
	    # your turn to play, and there's only one square available,
	    # you lose.
	
	    # 1 square loses (obviously)
	    assert_equal(Tactics::LOSS, Tactics.new(0b0111_1111_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1011_1111_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1101_1111_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1110_1111_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_0111_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1011_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1101_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1110_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_0111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1011_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1101_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1110_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1111_0111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1111_1011).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1111_1101).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1111_1110).play)
	
	    # 2 squares in a row wins (because you can reduce to one square) 
	    assert_equal(Tactics::WIN, Tactics.new(0b0011_1111_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1001_1111_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1100_1111_1111_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_0011_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1001_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1100_1111_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_0011_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1001_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1100_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1111_0011).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1111_1001).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1111_1100).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b0111_0111_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_0111_0111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_0111_0111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1011_1011_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1011_1011_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1011_1011).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1101_1101_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1101_1101_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1101_1101).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1110_1110_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1110_1110_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1110_1110).play)
	
	    # 3 squares in a row wins (because you can reduce to one square)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b0001_1111_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1000_1111_1111_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_0001_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1000_1111_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_0001_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1000_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1111_0001).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1111_1000).play)
	
	
	    assert_equal(Tactics::WIN, Tactics.new(0b0111_0111_0111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_0111_0111_0111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1011_1011_1011_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1011_1011_1011).play)
	
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1101_1101_1101_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1101_1101_1101).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1110_1110_1110_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1110_1110_1110).play)
	
	    # 4 squares in a row wins (because you can reduce to one square)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b0000_1111_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_0000_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_0000_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1111_0000).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b0111_0111_0111_0111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1011_1011_1011_1011).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1101_1101_1101_1101).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1110_1110_1110_1110).play)
	
	    # 2x2 square loses (because your opponent can always reduce it to one
	    # square immediately after your move)
	    assert_equal(Tactics::LOSS, Tactics.new(0b0011_0011_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_0011_0011_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_0011_0011).play)
	
	    assert_equal(Tactics::LOSS, Tactics.new(0b1001_1001_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1001_1001_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1001_1001).play)
	
	    assert_equal(Tactics::LOSS, Tactics.new(0b1100_1100_1111_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1100_1100_1111).play)
	    assert_equal(Tactics::LOSS, Tactics.new(0b1111_1111_1100_1100).play)
	
	    # 2x3 (or 3x2) rectangle wins (because you can reduce it to a 2x2)
	    assert_equal(Tactics::WIN, Tactics.new(0b0011_0011_0011_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1001_1001_1001_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1100_1100_1100_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_0011_0011_0011).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1001_1001_1001).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1100_1100_1100).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b0001_0001_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1000_1000_1111_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_0001_0001_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1000_1000_1111).play)
	
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_0001_0001).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1111_1000_1000).play)
	
	    # Now we'll play from an empty board. The purpose of this assertion
	    # is just to verify that we get the same answer that we get when
	    # the engine is started from scratch. In this case, we have done all
	    # the preceding plays--the results of which are stored in the engine.
	    assert_equal(Tactics::LOSS, Tactics.new(0b0000_0000_0000_0000).play)
	
	    # Also check that it works the same with the defaulted empty board.
	    assert_equal(Tactics::LOSS, Tactics.new.play)
	
	    # Continue with a few random assertions. No attempt to be exhaustive
	    # this time. This is deliberately located below the full play, above,
	    # to see that intermediate board positions that have been stored
	    # are accurate. Of course, this doesn't test very many of them.
	    
	    # A 2x2 L shape. Trivially reducible to 1 square.
	    assert_equal(Tactics::WIN, Tactics.new(0b0011_0111_1111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1011_1001_1111).play)
	    
	    # A 2x3 L shape. Trivially reducible to 1 square.
	    assert_equal(Tactics::WIN, Tactics.new(0b0011_0111_0111_1111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_1011_1000_1111).play)
	    
	    # A 2x4 L shape. Trivially reducible to 1 square.
	    assert_equal(Tactics::WIN, Tactics.new(0b0011_0111_0111_0111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1111_0111_0000_1111).play)
	
	    # A 3x4 L shape. Reducible to two lengths of two.
	    assert_equal(Tactics::WIN, Tactics.new(0b0001_0111_0111_0111).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b0000_0111_0111_1111).play)
	
	    # A checkerboard. Wins as long as the number of open squares is even.
	    assert_equal(Tactics::WIN, Tactics.new(0b0101_1010_0101_1010).play)
	    assert_equal(Tactics::WIN, Tactics.new(0b1010_0101_1010_0101).play)
	  end
	end

That's a flawless combination of code and comment logic, if you ask me.  Very
nice.

My thanks to Bob Sidebotham for sending in a thought provoking quiz and then
showing us how it's done.  Thanks for the free lessons, Bob.

Tomorrow's quiz is a choose your own difficulty problem so I expect to see all
of you submitting solutions!  :)

In This Thread

Prev Next