Forum: Ruby Conway's Life de-golfed

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ad4caa46eebe9347305177fc33468563?d=identicon&s=25 Mike Nelson (miken700)
on 2006-05-14 17:15
I took some golfed code from a discussion here little while back (
http://www.ruby-forum.com/search?query=Golfing+a+s...
) and tried my hand at de-golfing and re-working it a bit to make it
readable.

There are some things here that are a little clumsy, I think. I'm
wondering if there are other things that I might do to it to make it
even more readable. Any ideas?


Cell_Set, Cell_Clear = "#", " "
Line_Range = 0...20
before = Line_Range.map {Line_Range.map {(rand<0.7) ? Cell_Set :
Cell_Clear}}

Neighbors = []
(-1..1).map do |x|
  (-1..1).map do |y|
    Neighbors << [x,y] unless x==0 && y==0
  end
end

puts "\e[2J" # clear screen
save = nil
until save == before do
  puts "\e[H" # go 'home'
  puts before.map {|x| x.join(" ")} * "\n"
  save = before.map {|x| x.dup}
  before =Line_Range.map do |x|
            Line_Range.map do |y|
              count = (Neighbors.map do |n|
                         dx, dy = x+n[0], y+n[1]
                         if Line_Range===dx and Line_Range===dy
                           before[dx][dy]
                         else
                           Cell_Clear
                         end
                       end - [Cell_Clear, nil]).size
              count==2 ? before[x][y] : (count==3 ? Cell_Set :
Cell_Clear)
            end
          end
  sleep 0.1
end
5d15f83f0e681b138d95f1ec430868fa?d=identicon&s=25 Joey (Guest)
on 2006-05-14 20:30
(Received via mailing list)
Thanks alot Mike, I was the one who started that thread, and wrote most
of
the basic code.
Even though I wrote it, I couldn't deobfuscate it afterwards! Is it ok
if I
pop this on my site?
http://code.eachmapinject.com/game_of_life_golf.rb

j`ey
http://www.eachmapinject.com
896cfc242a7762467c2a0b2af86598e5?d=identicon&s=25 Simon Strandgaard (Guest)
on 2006-05-15 09:24
(Received via mailing list)
On 5/14/06, Mike Nelson <miken700@yahoo.com> wrote:
> I took some golfed code from a discussion here little while back (
> http://www.ruby-forum.com/search?query=Golfing+a+s...
> ) and tried my hand at de-golfing and re-working it a bit to make it
> readable.
>
> There are some things here that are a little clumsy, I think. I'm
> wondering if there are other things that I might do to it to make it
> even more readable. Any ideas?

I made a game of life example some time ago, for
an online ruby book (in danish):
http://aeditor.rubyforge.org/book/refining.html


--
Simon Strandgaard


module GameOfLife
  def determine_destiny(alive, count)
    unless alive
      return (count == 3)
    end
    (count == 2) or (count == 3)
  end
  def get(cells, y, x)
    return 0 if x < 0 or y < 0
    return 0 if y >= cells.size
    row = cells[y]
    return 0 if x >= row.size
    row[x]
  end
  def count_neighbours(cells, x, y)
    n = 0
    n += get(cells, y-1, x-1)
    n += get(cells, y-1, x)
    n += get(cells, y-1, x+1)
    n += get(cells, y, x-1)
    n += get(cells, y, x+1)
    n += get(cells, y+1, x-1)
    n += get(cells, y+1, x)
    n += get(cells, y+1, x+1)
    n
  end
  def lifecycle(cells)
    y = 0
    next_cells = cells.map do |row|
      x = 0
      next_row = row.map do |cell|
        n = count_neighbours(cells, x, y)
        x += 1
        determine_destiny((cell != 0), n) ? 1 : 0
      end
      y += 1
      next_row
    end
    next_cells
  end
end

if $0 == __FILE__
  puts "lets play a game"
  class Game
    include GameOfLife
    def initialize
      @cells = [
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0],
        [0, 0, 1, 1, 1, 0],
        [0, 1, 1, 1, 0, 0],
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0]
      ]
    end
    def next
      @cells = lifecycle(@cells)
    end
    def inspect
      rows = @cells.map do |row|
        row.join(" ")
      end
      rows.join("\n")
    end
  end
  game = Game.new
  loop do
    p game
    gets
    game.next
  end
end
Ad4caa46eebe9347305177fc33468563?d=identicon&s=25 Mike Nelson (Guest)
on 2006-05-15 17:08
Joey wrote:
> Even though I wrote it, I couldn't deobfuscate it afterwards! Is it ok
> if I
> pop this on my site?
> http://code.eachmapinject.com/game_of_life_golf.rb

Joey,

Go right ahead. Feel free.

Thanks,
Mike
0b561a629b87f0bbf71b45ee5a48febb?d=identicon&s=25 Dave Burt (Guest)
on 2006-05-15 18:27
(Received via mailing list)
Mike Nelson wrote:
> I took some golfed code from a discussion here little while back (
> http://www.ruby-forum.com/search?query=Golfing+a+s...
> ) and tried my hand at de-golfing and re-working it a bit to make it
> readable.

What version did you deobfuscate?

I have here the version on J`ey's site, and then a three-line version of
mine.

I used these clarification methods:
* add whitespace
* add comments
* rename variables
* translate conditional tri-graphs (foo?bar:baz) to if blocks

Cheers,
Dave

> #############################################################################
> # http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life                      #
> # joey@eachmapinject.com                                                    #
> # j`ey (with thanks to Florian Gross and Dave Burt)                         #
> # 305 characters                                                            #
> #############################################################################
> s,o,f,c,u=20,"#"," ";b=(z=0..s).map{z.map{(rand<0.3)?o:f}};$><<"\e[2J";until
> c==b;$><<"\e[H"<<b.map{|x|x*" "}*"\n";c=b.map{|z|z.dup};s.times{|i|s.times{|
> e|n=(q,z=-1..1,[];q.map{|x|q.map{|y|z<<[x,y]}};(z-=[[0,0]]).map{|x|c[i+x[0]][
> e+x[1]]rescue u}-[f,u]).size;b[i][e]=(n==2?b[i][e]:n==3?o:f)}};sleep 0.2;end

size,  occupied, forsaken, combat_area_last_turn,  undefined =
  20,  "#",      " "       # nil,                  nil

battlefield = (z = 0..size).map {
  z.map {
    if rand < 0.3
      occupied
    else
      forsaken
    end
  }
}

$> << "\e[2J"

until combat_area_last_turn == battlefield

  $> << "\e[H" <<
        battlefield.map {|x| x * " " } * "\n"

  combat_area_last_turn = battlefield.map {|z| z.dup }

  # iterate over the entire grid
  size.times {|i|
    size.times {|e|

      neighbour_count =
        (q, z = -1..1, []
         q.map {|x| q.map {|y| z << [x, y] } }

         # x iterates over the set of 8 relative neighbour coordinates
         (z -= [[0, 0]]).map {|x|

           # return the neighbour's value from last turn
           combat_area_last_turn[i + x[0]][e + x[1]] rescue undefined

         } - [forsaken, undefined]  # don't count empties or
off-the-edges
        ).size

      # update the cell based on last turn's neighbour count
      battlefield[i][e] =
        if neighbour_count == 2
          battlefield[i][e]
        else
          if neighbour_count == 3
            occupied
          else
            forsaken
          end
        end
    }
  }
  sleep 0.2
end



# And my version. You will need to hit Ctrl+Break to stop it.
o,f,m,c="#","
",[-1,0,1]*3;b=([7]*20).map{(0..20).map{(rand<0.3)?o:f}};loop{
$><<b.map{|x|x*f+"\n"};c=b.map{|x|x.dup};20.times{|i|20.times{|e|n=(m.sort.zip(
m)-[[0,0]]).select{|x,y|o==(c[i+x]||[])[e+y]}.size;n!=2?b[i][e]=n==3?o:f:9}}}


# And the same thing with a little whitespace.
o = "#"
f = " "
c = nil    # copy of b
# b        # main grid
m = [-1, 0, 1] * 3

b = ([7] * 20).map { (0..20).map { (rand < 0.3) ? o : f } }

loop {
  $> << b.map {|x| x * f + "\n" }
  c = b.map {|x| x.dup }
  20.times {|i|
    20.times {|e|
      n =
        (m.sort.zip(m) - [[0, 0]]).select {|x, y|
          o == (c[i + x] || [])[e + y]
        }.size
      n != 2 ? b[i][e] = n == 3 ? o :
                                  f :
               9
    }
  }
  #sleep 0.1
}
Ad4caa46eebe9347305177fc33468563?d=identicon&s=25 Mike Nelson (Guest)
on 2006-05-15 20:15
Dave Burt wrote:
> Mike Nelson wrote:
>> I took some golfed code from a discussion here little while back (
>> http://www.ruby-forum.com/search?query=Golfing+a+s...
>> ) and tried my hand at de-golfing and re-working it a bit to make it
>> readable.
>
> What version did you deobfuscate?
This is the orginal version that I worked from,
#############################################################################
# http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
#
# joey@eachmapinject.com
#
# j`ey (with thanks to Florian Gross and Dave Burt)
#
# 305 characters
#
#############################################################################
s,o,f,c,u=20,"#","
";b=(z=0..s).map{z.map{(rand<0.3)?o:f}};$><<"\e[2J";until
c==b;$><<"\e[H"<<b.map{|x|x*"
"}*"\n";c=b.map{|z|z.dup};s.times{|i|s.times{|
e|n=(q,z=-1..1,[];q.map{|x|q.map{|y|z<<[x,y]}};(z-=[[0,0]]).map{|x|c[i+x[0]][
e+x[1]]rescue u}-[f,u]).size;b[i][e]=(n==2?b[i][e]:n==3?o:f)}};sleep
0.2;end

> I have here the version on J`ey's site, and then a three-line version of
> mine.
I didn't see that one. I really like the sort.zip part, like this
pseudoquote,

(m =[-1,0,1]*3).sort.zip(m) - [[0,0]]

that's just lovely.
0b561a629b87f0bbf71b45ee5a48febb?d=identicon&s=25 Dave Burt (Guest)
on 2006-05-15 23:33
(Received via mailing list)
Mike Nelson wrote:
> Dave Burt wrote:
>> I have here the version on J`ey's site, and then a three-line version of
>> mine.
> I didn't see that one. I really like the sort.zip part, like this
> pseudoquote,
>
> (m =[-1,0,1]*3).sort.zip(m) - [[0,0]]
>
> that's just lovely.

I should have credited Daniel Sheppard originally. He's responsible for
this gem and a few other bits -- you can see his contribution in the
original thread.

Cheers,
Dave
This topic is locked and can not be replied to.