[#246252] How to use standard library? — Jamal Soueidan <jkhaledsoueidan@...>

Hello,

18 messages 2007/04/01
[#246253] Re: How to use standard library? — Stefano Crocco <stefano.crocco@...> 2007/04/01

Alle domenica 1 aprile 2007, Jamal Soueidan ha scritto:

[#246263] Re: How to use standard library? — "Yamal Soueidan" <jkhaledsoueidan@...> 2007/04/01

Well, where does it identify its module and not a class?

[#246267] Re: How to use standard library? — Stefano Crocco <stefano.crocco@...> 2007/04/01

Alle domenica 1 aprile 2007, Yamal Soueidan ha scritto:

[#246368] Map Or Collect Redux — "RubyTalk@..." <rubytalk@...>

Looking in the old archives of ruby-talk I found a thread in 2005

11 messages 2007/04/02

[#246378] Test::Unit Reports — aidy.lewis@...

Hi,

23 messages 2007/04/02

[#246464] Last iteration condition — "Mike" <michaelst@...>

Hi,

14 messages 2007/04/03

[#246590] Everything is a object? — Jamal Soueidan <jkhaledsoueidan@...>

Hello,

40 messages 2007/04/03
[#246598] Re: Everything is a object? — Jamal Soueidan <jkhaledsoueidan@...> 2007/04/04

Jamal Soueidan wrote:

[#246600] Re: Everything is a object? — Gary Wright <gwtmp01@...> 2007/04/04

[#246601] Re: Everything is a object? — Jamal Soueidan <jkhaledsoueidan@...> 2007/04/04

Gary Wright wrote:

[#246614] fast XML parser, other than libxml — Peter Szinek <peter@...>

Hello all,

20 messages 2007/04/04
[#246615] Re: fast XML parser, other than libxml — "Keith Fahlgren" <keith@...> 2007/04/04

On 4/3/07, Peter Szinek <peter@rubyrailways.com> wrote:

[#246626] Re: fast XML parser, other than libxml — Peter Szinek <peter@...> 2007/04/04

Keith Fahlgren wrote:

[#246629] Re: fast XML parser, other than libxml — Robert Klemme <shortcutter@...> 2007/04/04

On 04.04.2007 10:53, Peter Szinek wrote:

[#246630] Re: fast XML parser, other than libxml — Peter Szinek <peter@...> 2007/04/04

Robert Klemme wrote:

[#246669] Problem Extracting Array Values — Dustin Anderson <rubyforum@...>

Hi All,

16 messages 2007/04/04
[#246672] Re: Problem Extracting Array Values — "ChrisH" <chris.hulan@...> 2007/04/04

On Apr 4, 10:02 am, Dustin Anderson <rubyfo...@dustinanderson.com>

[#246673] Re: Problem Extracting Array Values — "Ryan Leavengood" <leavengood@...> 2007/04/04

On 4/4/07, ChrisH <chris.hulan@gmail.com> wrote:

[#246679] Re: Problem Extracting Array Values — Dustin Anderson <rubyforum@...> 2007/04/04

[#246702] nil? and non-existent objects — "François Montel" <zerohalo@...>

Why is it that the nil? method can sometimes be called on an object that

12 messages 2007/04/04

[#246830] Redefining initialize while staying -w clean — "Daniel Berger" <djberg96@...>

Hi all,

11 messages 2007/04/05

[#246929] Getting to 100 (#119) — Ruby Quiz <james@...>

The three rules of Ruby Quiz:

57 messages 2007/04/06
[#247191] Re: Getting to 100 (#119) — "Carl Porth" <badcarl@...> 2007/04/08

here is my first pass:

[#247192] Re: Getting to 100 (#119) — "Carl Porth" <badcarl@...> 2007/04/08

After going back and reading the current solutions, I like Ken Bloom's

[#247215] Re: Getting to 100 (#119) — "Marcel Ward" <wardies@...> 2007/04/09

On 08/04/07, Carl Porth <badcarl@gmail.com> wrote:

[#246946] A few beginners questions — wannaberor <amldcc@...>

Guys,

15 messages 2007/04/06

[#247059] Question to all you newbies (others welcome) — SonOfLilit <sonoflilit@...>

Hello everyone,

40 messages 2007/04/07
[#247078] Re: Question to all you newbies (others welcome) — Michael Brooks <michael.brooks@...> 2007/04/07

SonOfLilit wrote:

[#247097] Re: Question to all you newbies (others welcome) — "ChrisKaelin" <ck.stonedragon@...> 2007/04/07

I totally agree, what people say about a single-entry-point: ruby-

[#247099] Re: Question to all you newbies (others welcome) — James Britt <james.britt@...> 2007/04/07

ChrisKaelin wrote:

[#247100] Re: Question to all you newbies (others welcome) — "Jeff" <cohen.jeff@...> 2007/04/07

On Apr 7, 4:30 pm, James Britt <james.br...@gmail.com> wrote:

[#247131] Minimum ruby installation. — "bino_oetomo" <bino@...> 2007/04/08

Dear Experts.

[#247151] Re: Minimum ruby installation. — Alex Young <alex@...> 2007/04/08

bino_oetomo wrote:

[#247062] rb_yield(), break, and C extensions — "Noah Easterly" <noah.easterly@...>

So, I'm working on a C extension.

11 messages 2007/04/07

[#247088] Trying to GET google with socket....problem — Hey You <r3madi@...>

Well I don't know why the socket can't connect to Google. Here is my

17 messages 2007/04/07

[#247155] code blocks and methods — andy <eps@...>

Hi,

13 messages 2007/04/08

[#247299] Infinate Loop - Please Advise — "Merrie" <merries@...>

This program produces an infinate loop. I am learning from Learn to =

13 messages 2007/04/09

[#247338] How to Write a Spelling Corrector — Brian Adkins <lojicdotcomNOSPAM@...>

Peter Norvig wrote a simple spelling corrector in 20 lines of Python 2.5,

12 messages 2007/04/10

[#247391] Slow ruby regexes — Emmanuel <emmanuel@...>

Hello i've been reading this article, wich has a few benchmarks

47 messages 2007/04/10
[#247402] Re: Slow ruby regexes — SonOfLilit <sonoflilit@...> 2007/04/10

Read wikipedia on Regex. It explains better than I can why one is used

[#247403] Re: Slow ruby regexes — MenTaLguY <mental@...> 2007/04/10

On Wed, 11 Apr 2007 02:59:29 +0900, SonOfLilit <sonoflilit@gmail.com> wrote:

[#247409] Re: Slow ruby regexes — "Robert Dober" <robert.dober@...> 2007/04/10

On 4/10/07, MenTaLguY <mental@rydia.net> wrote:

[#247410] Re: Slow ruby regexes — MenTaLguY <mental@...> 2007/04/10

On Wed, 11 Apr 2007 03:56:28 +0900, "Robert Dober" <robert.dober@gmail.com> wrote:

[#247455] Re: Slow ruby regexes — "Robert Dober" <robert.dober@...> 2007/04/11

On 4/10/07, MenTaLguY <mental@rydia.net> wrote:

[#247456] Re: Slow ruby regexes — "Robert Dober" <robert.dober@...> 2007/04/11

oops wrong button here :(

[#247499] Re: Slow ruby regexes — MenTaLguY <mental@...> 2007/04/11

On Wed, 11 Apr 2007 16:53:26 +0900, "Robert Dober" <robert.dober@gmail.com> wrote:

[#247518] Re: Slow ruby regexes — "Robert Dober" <robert.dober@...> 2007/04/11

On 4/11/07, MenTaLguY <mental@rydia.net> wrote:

[#247541] Re: Slow ruby regexes — MenTaLguY <mental@...> 2007/04/11

On Thu, 12 Apr 2007 03:27:04 +0900, "Robert Dober" <robert.dober@gmail.com> wrote:

[#247608] Re: Slow ruby regexes — Robert Klemme <shortcutter@...> 2007/04/12

On 11.04.2007 22:51, MenTaLguY wrote:

[#247683] Re: Slow ruby regexes — MenTaLguY <mental@...> 2007/04/12

On Thu, 12 Apr 2007 16:10:06 +0900, Robert Klemme <shortcutter@googlemail.com> wrote:

[#247770] Re: Slow ruby regexes — Robert Klemme <shortcutter@...> 2007/04/13

On 12.04.2007 18:31, MenTaLguY wrote:

[#247398] ClothRed (HTML to Textile) — Phillip Gawlowski <cmdjackryan@...>

I'm pleased to announce, that I've begun working on a small library to

16 messages 2007/04/10
[#247526] Re: [ANN] ClothRed (HTML to Textile) — "Victor \"Zverok\" Shepelev" <vshepelev@...> 2007/04/11

From: Phillip Gawlowski [mailto:cmdjackryan@googlemail.com]

[#247436] NameError: uninitialized constant Date::ABBR_MONTHS — Jigar Gosar <jigar.gosar@...>

DATE::ABBR_MONTHS exists in this doc here.

13 messages 2007/04/11

[#247471] How come this doesn't work? — Hey You <r3madi@...>

require 'socket'

13 messages 2007/04/11

[#247622] What is your favourite IDE? — "ChrisKaelin" <ck.stonedragon@...>

I prefer using eclipse for it's freedom, ruby and svn plugins etc. But

95 messages 2007/04/12
[#247681] Re: What is your favourite IDE? — Todd Werth <twerth@...> 2007/04/12

ChrisKaelin wrote:

[#247980] Re: IDEs, syntactic vs. semantic highlighting, etc. — Tim X <timx@...> 2007/04/15

Chad Perrin <perrin@apotheon.com> writes:

[#247737] Re: What is your favourite IDE? — Vlad Ciubotariu <vcciubot@...> 2007/04/12

Is anyone using Activestate's Kodomo? I know activestate is a player in

[#247757] Re: What is your favourite IDE? — "M. Edward (Ed) Borasky" <znmeb@...> 2007/04/13

Vlad Ciubotariu wrote:

[#247913] Re: What is your favourite IDE? Eclipse DLTK! — Tim X <timx@...> 2007/04/14

Todd Werth <twerth@infinitered.com> writes:

[#247636] Re: What is your favourite IDE? — "Alexey Kalmykov" <akalmykov@...>

15 messages 2007/04/12

[#247725] SNMP agent library? — "Marcus Bristav" <marcus.bristav@...>

I need to write an SNMP agent (raise traps and expose MIBs). Is there

15 messages 2007/04/12
[#247741] Re: SNMP agent library? — "Francis Cianfrocca" <garbagecat10@...> 2007/04/13

On 4/12/07, Marcus Bristav <marcus.bristav@gmail.com> wrote:

[#247790] Re: SNMP agent library? — "Marcus Bristav" <marcus.bristav@...> 2007/04/13

Hi Francis,

[#247809] Re: SNMP agent library? — "Francis Cianfrocca" <garbagecat10@...> 2007/04/13

On 4/13/07, Marcus Bristav <marcus.bristav@gmail.com> wrote:

[#247760] Idiom wanted (now hiring!) — Jonathan <terhorst@...>

Is there a cool way to do this without calling the function twice?:

28 messages 2007/04/13
[#247767] Re: Idiom wanted (now hiring!) — Joel VanderWerf <vjoel@...> 2007/04/13

Jonathan wrote:

[#247783] Re: Idiom wanted (now hiring!) — "Robert Dober" <robert.dober@...> 2007/04/13

On 4/13/07, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

[#247805] Magic Fingers (#120) — Ruby Quiz <james@...>

The three rules of Ruby Quiz:

14 messages 2007/04/13

[#247974] executing a system command and stopping it after a specified duration? — Robert La Ferla <robertlaferla@...>

I'd like to run a system command and then stop it after specified

9 messages 2007/04/15

[#248026] translate Perl diamond operator to Ruby — Chad Perrin <perrin@...>

Over the years, I've found the following to be an excellent way to whip

13 messages 2007/04/15

[#248151] factorial in ruby — "Trans" <transfire@...>

Is factorial defined anywhere in Ruby's core or standard library. If

21 messages 2007/04/16
[#248154] Re: factorial in ruby — "Jason Roelofs" <jameskilton@...> 2007/04/16

No and most likely not.

[#248245] Timeout errors using Net::HTTP on Windows — Toby DiPasquale <toby@...>

Hi all,

12 messages 2007/04/17

[#248255] new — "poison tooth" <fixxie.wits@...>

Im just learning ruby and im stuck the guide im using says

17 messages 2007/04/17

[#248263] how to have a default argument — "shawn bright" <nephish@...>

hello all,

11 messages 2007/04/17

[#248384] ruby scripting on microsoft active directory plus exchange — Pe, Botp <botp@...>

Hi All,

16 messages 2007/04/19
[#248445] Re: ruby scripting on microsoft active directory plus exchange — "Glen Holcomb" <damnbigman@...> 2007/04/19

I would recommend looking at Net::LDAP: gem install ruby-net-ldap

[#248463] Re: ruby scripting on microsoft active directory plus exchange — "Ball, Donald A Jr (Library)" <donald.ball@...> 2007/04/19

> I would recommend looking at Net::LDAP: gem install ruby-net-ldap

[#248516] what does this code do ? from libxml schema-test.rb ??? — "aktxyz@..." <aktxyz@...>

At the bottom of the schema-test.rb in the libxml gem, there is this

13 messages 2007/04/20
[#248522] Re: what does this code do ? from libxml schema-test.rb ??? — Reuben Grinberg <reuben.grinberg@...> 2007/04/20

aktxyz@gmail.com wrote:

[#248546] Morse Code (#121) — Ruby Quiz <james@...>

The three rules of Ruby Quiz:

32 messages 2007/04/20

[#248629] Tracking down a garbage collection problem — Wincent Colaiuta <win@...>

I'm trying to work out ways to reduce the memory use of one of my

12 messages 2007/04/21

[#248680] GameR 0.2 is out — Wim Vander Schelden <wim.vanderschelden@...>

I've released GameR, a small and simple game development framework for Ruby.

13 messages 2007/04/22

[#248744] Arrow operator with dash instead of equals (->) — Andrew Green <ndrw_grn@...>

Hi, all,

16 messages 2007/04/22
[#248747] Re: Arrow operator with dash instead of equals (->) — Timothy Hunter <TimHunter@...> 2007/04/22

Andrew Green wrote:

[#248750] Re: Arrow operator with dash instead of equals (->) — Andrew Green <ndrw_grn@...> 2007/04/23

> > Is it possible to use -> as a method name in Ruby?

[#248762] Question regarding design of the String Class — "Michael W. Ryder" <_mwryder@...>

Was there a reason the string class was implemented with str[i]

21 messages 2007/04/23
[#248774] Re: Question regarding design of the String Class — Daniel Martin <martin@...> 2007/04/23

"Michael W. Ryder" <_mwryder@worldnet.att.net> writes:

[#248777] Ruby Reports 1.0 RC1 (0.10.0) — "Gregory Brown" <gregory.t.brown@...>

== Ruby Reports 1.0, Release Candidate 1 (0.10.0) ==

13 messages 2007/04/23

[#248814] unix zcat with ruby? — music <music@...>

I have to read in many files.

14 messages 2007/04/23

[#248862] ruby and C — "smc smc" <fixxie.wits@...>

Would it be easier to learn ruby if i knew C/C+/C++ or the other way around?

14 messages 2007/04/24

[#248981] file-find 0.1.0 — Daniel Berger <djberg96@...>

Hi all,

18 messages 2007/04/24
[#248984] Re: [ANN] file-find 0.1.0 — "Leslie Viljoen" <leslieviljoen@...> 2007/04/24

On 4/24/07, Daniel Berger <djberg96@gmail.com> wrote:

[#248993] Re: [ANN] file-find 0.1.0 — "Daniel Berger" <djberg96@...> 2007/04/24

On 4/24/07, Leslie Viljoen <leslieviljoen@gmail.com> wrote:

[#249027] Using Watir and Ruby2Exe together — Jim Clark <diegoslice@...>

I've been asked to help solve a browser issue that I think Watir and

13 messages 2007/04/25

[#249034] C++ code into Ruby, I need it fast, no time for RTFM — Andrei Ursan <steelheart222@...>

[code]

41 messages 2007/04/25
[#249041] Re: C++ code into Ruby, I need it fast, no time for RTFM — John Joyce <dangerwillrobinsondanger@...> 2007/04/25

[#249043] Re: C++ code into Ruby, I need it fast, no time for RTFM — Andrei Ursan <steelheart222@...> 2007/04/25

> Translate this for me, right now. No, by yesterday. == A time when

[#249044] Re: C++ code into Ruby, I need it fast, no time for RTFM — "David Jones" <tafftoo@...> 2007/04/25

There are still ways to ask for things.

[#249060] Is it possible to make system use bash instead of sh? — Wai Tsang <simotsa@...>

Hi,

12 messages 2007/04/25

[#249076] DHH vs. WHY style — Trans <transfire@...>

Like to know others general opinions on having a comprehensive library

35 messages 2007/04/25

[#249226] 10 millisecond delay/callback — Earle Clubb <eclubb@...>

I need to perform a task every 10ms. I've been using

21 messages 2007/04/26
[#249228] Re: 10 millisecond delay/callback — khaines@... 2007/04/26

On Fri, 27 Apr 2007, Earle Clubb wrote:

[#249238] Using Ruby in a Corporate Environment — Steve Molitor <stevemolitor@...>

---------- Forwarded message ----------

10 messages 2007/04/26

[#249268] Looking for thoughts and opinions on Ruport, and reporting in Ruby in general. — "Gregory Brown" <gregory.t.brown@...>

Hi Folks,

24 messages 2007/04/27
[#249334] Re: Looking for thoughts and opinions on Ruport, and reporting in Ruby in general. — "Lyle Johnson" <lyle.johnson@...> 2007/04/27

On 4/27/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:

[#249338] Re: Looking for thoughts and opinions on Ruport, and reporting in Ruby in general. — "Jamey Cribbs" <jcribbs@...> 2007/04/27

Lyle Johnson wrote:

[#249340] Re: Looking for thoughts and opinions on Ruport, and reporting in Ruby in general. — "Gregory Brown" <gregory.t.brown@...> 2007/04/27

On 4/27/07, Jamey Cribbs <jcribbs@netpromi.com> wrote:

[#249342] Re: Looking for thoughts and opinions on Ruport, and reporting in Ruby in general. — John Joyce <dangerwillrobinsondanger@...> 2007/04/27

[#249343] Re: Looking for thoughts and opinions on Ruport, and reporting in Ruby in general. — "Gregory Brown" <gregory.t.brown@...> 2007/04/27

On 4/27/07, John Joyce <dangerwillrobinsondanger@gmail.com> wrote:

[#249347] Re: Looking for thoughts and opinions on Ruport, and reporting in Ruby in general. — John Joyce <dangerwillrobinsondanger@...> 2007/04/27

[#249269] Output A File w/ Line Numbers? — John Joyce <dangerwillrobinsondanger@...>

I'd like to read a file and output its contents (just to terminal is

18 messages 2007/04/27
[#249414] Re: Output A File w/ Line Numbers? — "Robert Dober" <robert.dober@...> 2007/04/28

On 4/27/07, John Joyce <dangerwillrobinsondanger@gmail.com> wrote:

[#249274] string replacement... — Josselin <josselin@...>

I have a string : str = "/proposal/list/31551"

15 messages 2007/04/27

[#249315] Checking Credit Cards (#122) — Ruby Quiz <james@...>

The three rules of Ruby Quiz:

65 messages 2007/04/27

[#249430] cyclic array — Josselin <josselin@...>

I would like to print n elements from an Array in a cyclic way.

18 messages 2007/04/28

[#249524] Array.which_long? ( I coded an extension for Array ) — "Billy Hsu" <ruby.maillist@...>

Hi, I'm CFC

31 messages 2007/04/29
[#249526] Re: Array.which_long? ( I coded an extension for Array ) — "Chris Carter" <cdcarter@...> 2007/04/29

On 4/29/07, Billy Hsu <ruby.maillist@gmail.com> wrote:

[#249664] Re: Array.which_long? ( I coded an extension for Array ) — Robert Klemme <shortcutter@...> 2007/04/30

On 29.04.2007 16:11, Chris Carter wrote:

[#249667] Re: Array.which_long? ( I coded an extension for Array ) — "Robert Dober" <robert.dober@...> 2007/04/30

On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:

[#249670] Re: Array.which_long? ( I coded an extension for Array ) — Robert Klemme <shortcutter@...> 2007/04/30

On 30.04.2007 12:39, Robert Dober wrote:

[#249688] Re: Array.which_long? ( I coded an extension for Array ) — "Robert Dober" <robert.dober@...> 2007/04/30

On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:

[#249527] Re: Array.which_long? ( I coded an extension for Array ) — "David A. Black" <dblack@...> 2007/04/29

Hi --

[#249531] Re: Array.which_long? ( I coded an extension for Array ) — "Robert Dober" <robert.dober@...> 2007/04/29

On 4/29/07, David A. Black <dblack@wobblini.net> wrote:

[#249532] Re: Array.which_long? ( I coded an extension for Array ) — "David A. Black" <dblack@...> 2007/04/29

Hi --

[#249587] Class Level Variables — Cory <coryw@...>

Alright, I'm missing some core ruby concept here that I just can't

23 messages 2007/04/30
[#249589] Re: Class Level Variables — Ari Brown <ari@...> 2007/04/30

[#249603] sorting by rand? — seebs@... (Peter Seebach)

Browsing something at a bookstore recently, I saw an example of

22 messages 2007/04/30

[#249689] RoR how does scaffold work? — anansi <kazaam@...>

Hi,

17 messages 2007/04/30

[#249691] ruby and true — aidy.lewis@...

Hi,

16 messages 2007/04/30

[#249759] relocatable ruby distribution — "fkc_email-news @ yahoo dot com" <fkchang2000@...>

Hi All:

11 messages 2007/04/30

Re: [QUIZ] Magic Fingers (#120)

From: Jesse Merriman <jesse.d.merriman@...>
Date: 2007-04-15 19:19:34 UTC
List: ruby-talk #248037
Note:
This didn't seem to get through the first time I sent it. And now that I look
at the online archives, I see my solution to last weeks isn't there either.
Perhaps the list didn't like the fact that I attached zip files, which I did
merely for the convenience of the person that puts the solutions on
rubyquiz.com so they won't have to copy-paste. I'll resend my 119 solution
in a bit, which was long and ugly, but did handle things like parentheses.

---------------------------

Here's another long-winded solution from me. I'm not sure its correct, but for
a few small examples (2 & 3 fingers per hand), it seems to know when a win is
unavoidable given perfect play. There are 2 main classes that do the important
work:

State: This holds two Arrays, one for each player (@players). Each of those hold
       two numbers - how many fingers are on each hand. These are kept sorted,
       because it doesn't matter if you have 3-left and 2-right or 2-right and
       3-left. State also has a @turn, which designates who moves next, a
       @parent, for back-tracing through a state tree, and a @best_outcome,
       which holds a value assigned by StateTree. Only @players and @turn are
       taken into account by ==, eql?, and hash. State's each_reachable_state
       method yields for each state reachable from itself, using the touch and
       clap rules.

StateTree: This class holds a @root State, and a recursive best_outcome method.
           This method will be called for each reachable state from its
           argument. Whichever leads to the best outcome for that State's
           player (@turn) is returned.

Then there's a few other classes and modules, like Outcome, which holds
constants P1Win, P2Win, and Loop; and Game, which creates a StateTree, runs
best_outcome, and prints the results. The number of fingers per hand can be
changed from 5 in constants.rb.

There are some commented-out simple examples in magic_fingers.rb, which seem
to work:

> Game.new([1,1], [0,4]).analyze
Player 1, with perfect play, can win:
1: ----|  |---- *
2: -----  ||||-

1: ----|  |----
2: -----  ----- *

> Game.new([4,4], [1,1]).analyze
Player 1, with perfect play, can win:
1: -||||  ||||- *
2: ----|  |----

1: -||||  ||||-
2: -----  |---- *

1: -----  ||||- *
2: -----  |----

1: -----  ||||-
2: -----  ----- *

> Game.new([0,1], [3,3]).analyze
No matter how well Player 1 plays, Player 2 can win. For example:
1: -----  |---- *
2: --|||  |||--

1: -----  |----
2: --|||  ||||- *

1: -----  ----- *
2: --|||  ||||-

However, for the regular game:

> Game.new.analyze
Player 1 can stay in a loop.

So my program thinks player 1 can forever repeat a loop of game states,
but can't force a win. This contradicts my initial guess, but I don't
know if its correct, so I think I have a bug.

Here's the code:

#!/usr/bin/env ruby
# constants.rb

Left,    Right   = 0, 1 # hand array indices
Player1, Player2 = 0, 1 # player array indices
FingersPerHand   = 5


#!/usr/bin/env ruby
# outcome.rb

require 'constants'

module Outcome
  # Order important: from best-for-player-1 to best-for-player-2
  Outcome::P1Win   = 0
  Outcome::Loop    = 1
  Outcome::P2Win   = 2

  # Given an array of outcomes, return the one that is best for the given
  # player.
  def Outcome.best(player, outcomes)
    (player == Player1) ? outcomes.min : outcomes.max
  end
end


#!/usr/bin/env ruby
# state.rb

require 'constants'
require 'set'

# Represents one state of the game, which includes how many fingers are on each
# player's hands, and whose turn it is. States can also have parents, and a
# best_outcome can be assigned to them, though this class doesn't do anything
# with that itself. The player's hands are always sorted, since it doesn't
# matter having 3-left and 2-right is equivalent to 2-left and 3-right. When
# comparing states with ==, eql?, or their hashes, only @players and @turn are
# taken into account.
class State
  attr_reader :players, :turn, :parent, :best_outcome
  attr_writer :best_outcome

  # player_1 and player_2 are Arrays of number-of-fingers on each hand.
  def initialize(player_1, player_2, turn, parent = nil)
    @players = [player_1, player_2]
    @turn = turn
    @parent = parent
    @best_outcome = nil

    for player in @players do
      State.normalize(player)
    end

    self
  end

  def hand_alive?(player_num, hand_num)
    @players[player_num][hand_num] > 0
  end

  def player_alive?(player_num)
    hand_alive?(player_num, Left) or hand_alive?(player_num, Right)
  end

  # true if at least one player is dead.
  def end_state?
    not player_alive?(Player1) or not player_alive?(Player2)
  end

  # Return the winner. This should only be called on end states (otherwise,
  # it'll always return Player1).
  def winner
    player_alive?(Player1) ? Player1 : Player2
  end

  # Turn the given player's hand into a fist if it has >= FingesPerHand
  # fingers up, and sort the hands.
  def State.normalize(player)
    for hand_num in [Left, Right] do
      player[hand_num] = 0 if player[hand_num] >= FingersPerHand
    end
    player.sort!
  end

  # Return a nice string representation of a player.
  def player_string(player_num)
    player = @players[player_num]
    '-' * (FingersPerHand-player[Left]) +
      '|' * player[Left] +
      '  ' +
      '|' * player[Right] +
      '-' * (FingersPerHand-player[Right])
  end

  # Return a nice string representation of this state (including both player
  # strings).
  def to_s
    s = "1: #{player_string(Player1)}"
    s << ' *' if @turn == Player1
    s << "\n2: #{player_string(Player2)}"
    s << ' *' if @turn == Player2
    s
  end

  # Equality only tests the players' hands and the turn.
  def ==(other)
    @players == other.players and @turn == other.turn
  end

  # Both eql? and hash are defined so that Sets/Hashes of states will only
  # differentiate states based on @players and @turn.
  def eql?(other); self == other; end
  def hash; [@players, @turn].hash; end

  # Yield once for each ancestor state, starting from the oldest and ending on
  # this state.
  def each_ancestor
    ancestors = [self]
    while not ancestors.last.parent.nil?
      ancestors << ancestors.last.parent
    end
    ancestors.reverse_each { |a| yield a }
  end

  # Have one player (the toucher) touch the other player (the touchee).
  # Also, the touchee is then normalized.
  def State.touch(toucher, toucher_hand, touchee, touchee_hand)
    touchee[touchee_hand] += toucher[toucher_hand]
    State.normalize(touchee)
  end

  # Yield each state reachable from self.
  def each_reachable_state
    reachable = Set[] # use a Set instead of yielding as we find them to remove
                      # yielding duplicates.
    player = @players[@turn]
    opponent_num = (@turn + 1) % 2
    opponent = @players[opponent_num]

    # Touch rules.
    for player_hand in [Left, Right] do
      for opponent_hand in [Left, Right] do
        if hand_alive?(@turn, player_hand) and
            hand_alive?(opponent_num, opponent_hand)
          op = opponent.clone # because touch modifies it
          State.touch(player, player_hand, op, opponent_hand)
          if @turn == Player1
            reachable << State.new(player, op, opponent_num, self)
          else
            reachable << State.new(op, player, opponent_num, self)
          end
        end
      end
    end

    # Clap rules.
    for source_hand in [Left, Right] do
      target_hand = (source_hand == Left ? Right : Left)
      # The first line is the number that can be removed from the source.
      # The second is the number that can be added to the target without killing
      # it.
      max_transfer = [player[source_hand] - 1,
                     (FingersPerHand - player[target_hand] - 1)].min
      (1..max_transfer).each do |i|
        p = player.clone
        p[source_hand] -= i
        p[target_hand] += i
        State.normalize(p)
        if @turn == Player1
          reachable << State.new(p, opponent.clone, opponent_num, self)
        else
          reachable << State.new(opponent.clone, p, opponent_num, self)
        end
      end
    end

    reachable.each { |r| yield r }
  end
end


#!/usr/bin/env ruby
# state_tree.rb

require 'constants'
require 'state'
require 'outcome'

# Represents a tree of States in parent-child relationships.
class StateTree
  attr_reader :root, :p1_win_node, :p2_win_node, :loop_node

  def initialize(root = State.new([1,1], [1,1], Player1))
    @root = root
    @old_nodes = Set[@root]
    @p1_win_node = @p2_win_node = nil
    self
  end

  # Determine the best outcome at the given node, for that node's player.
  #
  # If Outcome::P1Win is returned, @p1_win_node will hold one way for player 1
  # to win. Likewise for Outcome::P2Win.
  #
  # Because @old_nodes is filled up as it runs, it can only be called once.
  # Can't clear out @old_nodes at the end of the method, since its recursive,
  # and the next level up depends on it. Could just create a wrapper method
  # to do that, though.
  def best_outcome(node = @root)
    reachable_outcomes = []

    node.each_reachable_state do |reached|
      if @old_nodes.include?(reached)
        if reached.best_outcome.nil?
          reachable_outcomes << Outcome::Loop
        else
          reachable_outcomes << reached.best_outcome
        end
      elsif reached.end_state?
        # Note that end states are never added to @old_nodes, because @old_nodes
        # is only used for loop-checking, and loops shouldn't include end
        # states.
        if reached.winner == Player1
          @p1_win_node = reached
          reachable_outcomes << Outcome::P1Win
        else
          @p2_win_node = reached
          reachable_outcomes << Outcome::P2Win
        end
      else
        @old_nodes << node
        reachable_outcomes << best_outcome(reached)
      end
    end

    node.best_outcome = Outcome.best(node.turn, reachable_outcomes)
  end
end


#!/usr/bin/env ruby
# game.rb

require 'constants'
require 'outcome'
require 'state'
require 'state_tree'

class Game
  # Constructor. p1_start and p2_start are Arrays containing the number of
  # fingers on each of their hands at the start of the game.
  def initialize(p1_start = [1,1], p2_start = [1,1])
    @state_tree = StateTree.new(State.new(p1_start, p2_start, Player1))
    self
  end

  # Print out an analysis of the game.
  def analyze
    outcome = @state_tree.best_outcome

    if outcome == Outcome::P1Win
      puts 'Player 1, with perfect play, can win:'
      @state_tree.p1_win_node.each_ancestor do |state|
        puts "#{state}\n\n"
      end
    elsif outcome == Outcome::P2Win
      puts 'No matter how well Player 1 plays, Player 2 can win. For example:'
      @state_tree.p2_win_node.each_ancestor do |state|
        puts "#{state}\n\n"
      end
    elsif outcome == Outcome::Loop
      puts 'Player 1 can stay in a loop.'
    else
      puts 'I am broken.'
    end
  end
end


#!/usr/bin/env ruby
# magic_fingers.rb

# Ruby Quiz 120: Magic Fingers

require 'game'

Game.new.analyze # Normal, default game.
#Game.new([1,1], [0,4]).analyze # P1 should win on move 1.
#Game.new([4,4], [1,1]).analyze # P1 should win on move 2.
#Game.new([0,1], [3,3]).analyze # P2 should win on move 2.

-- 
Jesse Merriman
jessemerriman@warpmail.net
http://www.jessemerriman.com/

In This Thread