golf: tabs to bullets

Discussion in 'Ruby' started by Martin DeMello, Mar 25, 2008.

  1. Given:
    an outline list, with each line indented by a series of tabs
    a list of bullets (assume a circular list, for simplicity)

    Write a function that replaces every tab with two spaces, except for
    the last one, which is replaced by a bullet.

    example:

    input file:
    foo
    \t bar
    \t \t baz
    \t \t \t hello
    \t \t world

    bullets: %w(* - o x)

    output (view in fixed width):
    foo
    * bar
    - baz
    o hello
    - world

    martin
    Martin DeMello, Mar 25, 2008
    #1
    1. Advertising

  2. On Tue, Mar 25, 2008 at 2:02 PM, Martin DeMello <> wrote:
    > Given:
    > an outline list, with each line indented by a series of tabs
    > a list of bullets (assume a circular list, for simplicity)
    >
    > Write a function that replaces every tab with two spaces, except for
    > the last one, which is replaced by a bullet.


    Code is worth a thousand descriptions:

    #!/usr/bin/ruby

    file = ARGV[0]
    MARKERS = "*-ox".split(//)

    def bullet(n)
    MARKERS[n % MARKERS.length]
    end

    IO.foreach(file) {|line|
    a = line.gsub(/^\t+/, "")
    n = line.length - a.length - 1
    replace = n == -1 ? "" : " "*(n)+ bullet(n) + " "
    out = line.gsub(/^\t+/, replace)
    puts out
    }

    martin
    Martin DeMello, Mar 25, 2008
    #2
    1. Advertising

  3. Martin DeMello

    James Gray Guest

    On Mar 25, 2008, at 4:02 PM, Martin DeMello wrote:

    > Given:
    > an outline list, with each line indented by a series of tabs
    > a list of bullets (assume a circular list, for simplicity)
    >
    > Write a function that replaces every tab with two spaces, except for
    > the last one, which is replaced by a bullet.
    >
    > example:
    >
    > input file:
    > foo
    > \t bar
    > \t \t baz
    > \t \t \t hello
    > \t \t world
    >
    > bullets: %w(* - o x)
    >
    > output (view in fixed width):
    > foo
    > * bar
    > - baz
    > o hello
    > - world


    I didn't really golf it, but my answer is:

    #!/usr/bin/env ruby -wKU

    input = <<END_INPUT
    foo
    \t bar
    \t \t baz
    \t \t \t hello
    \t \t world
    END_INPUT

    bullets = %w[* - o x]
    input.gsub!(/^(\t ?)+/) do |indent|
    tabs = indent.count("\t") - 1
    " " * tabs + bullets[tabs] + " "
    end

    puts input

    __END__

    James Edward Gray II
    James Gray, Mar 25, 2008
    #3
  4. On Tue, Mar 25, 2008 at 2:16 PM, James Gray <> wrote:
    >
    > I didn't really golf it, but my answer is:


    You have a point - I wasn't looking for golf so much as for neat
    and/or offbeat approaches to the problem of counting the tabs.

    martin
    Martin DeMello, Mar 25, 2008
    #4
  5. Hi --

    On Wed, 26 Mar 2008, Martin DeMello wrote:

    > On Tue, Mar 25, 2008 at 2:16 PM, James Gray <> wrote:
    >>
    >> I didn't really golf it, but my answer is:

    >
    > You have a point - I wasn't looking for golf so much as for neat
    > and/or offbeat approaches to the problem of counting the tabs.


    Darn, I took you literally :)

    def t(s)b='*-ox';s.map{|l|c=l.count("\t")
    (c-1).times{l.sub!(/\t/,' ')}
    l.sub(/\t/,b[c-1,1])}end

    t(some_string)

    (Thanks to JEG2 for reminding me of count, which I had hypercorrected
    in my mind into thinking only existed in 1.9 because of Array#count
    :)


    David

    --
    Rails training from David A. Black and Ruby Power and Light:
    ADVANCING WITH RAILS April 14-17 New York City
    INTRO TO RAILS June 9-12 Berlin
    ADVANCING WITH RAILS June 16-19 Berlin
    See http://www.rubypal.com for details and updates!
    David A. Black, Mar 25, 2008
    #5
  6. A slightly different approach (count the tabs once!), starting from
    James's code:

    input = <<END_INPUT
    foo
    \t bar
    \t \t baz
    \t \t \t hello
    \t \t world
    END_INPUT

    bullets = %w[* - o x]

    h = Hash.new {|h, k|
    bullet = bullets[(k.count("\t")-1) % bullets.size]
    h[k] = k.gsub(/(\t )(?=\t )/, " ").sub(/\t/, bullet)
    }

    input.gsub!(/^(\t ?)+/) do |indent|
    h

    end

    puts input

    __END__

    foo
    * bar
    - baz
    o hello
    - world

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407​
    Joel VanderWerf, Mar 25, 2008
    #6
  7. Similar to Joel's approach...

    #bullets.rb
    h={}
    %w(\ * - o x).each_with_index{|b, i| h["\t" * i]= " " * i + "#{b} " }
    puts gets.gsub(/^(\t*)/){ h[$1]} until $stdin.eof?

    C:\ruby\scripts\>cat input_file | ruby bullets.rb
    foo
    * bar
    - baz
    o hello
    - world
    Gordon Thiesfeld, Mar 25, 2008
    #7
  8. On Tue, Mar 25, 2008 at 5:11 PM, Gordon Thiesfeld <> wrote:
    > Similar to Joel's approach...
    >
    > #bullets.rb
    > h={}
    > %w(\ * - o x).each_with_index{|b, i| h["\t" * i]= " " * i + "#{b} " }
    > puts gets.gsub(/^(\t*)/){ h[$1]} until $stdin.eof?
    >
    > C:\ruby\scripts\>cat input_file | ruby bullets.rb
    >
    >
    > foo
    > * bar
    > - baz
    > o hello
    > - world
    >



    Except it was broken. I'll try it again.

    #bullets.rb
    h={''=>''}
    %w(* - o x).each_with_index{|b, i| h["\t" * (i+1)]= "#{' ' * i}#{b} " }
    puts gets.gsub(/^(\t*)/){ h[$1] } until $stdin.eof?
    Gordon Thiesfeld, Mar 25, 2008
    #8
  9. Joel VanderWerf wrote:
    > h[k] = k.gsub(/(\t )(?=\t )/, " ").sub(/\t/, bullet)


    a little more robust:

    h[k] = k.gsub(/(\t ?)(?=\t)/, " ").sub(/\t/, bullet)

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
    Joel VanderWerf, Mar 25, 2008
    #9
  10. Martin DeMello

    ara howard Guest

    On Mar 25, 2008, at 3:02 PM, Martin DeMello wrote:

    > Given:
    > an outline list, with each line indented by a series of tabs
    > a list of bullets (assume a circular list, for simplicity)
    >
    > Write a function that replaces every tab with two spaces, except for
    > the last one, which is replaced by a bullet.
    >
    > example:
    >
    > input file:
    > foo
    > \t bar
    > \t \t baz
    > \t \t \t hello
    > \t \t world
    >
    > bullets: %w(* - o x)


    cfp2:~ > cat a.rb
    DATA.read.gsub(%r/(?:\t\ ?)+/){|s|' '*(n=s.count("\t")-1)+%w(* - o x)
    [n]+' '}.display

    __END__
    foo
    bar
    baz
    hello
    world


    cfp2:~ > ruby a.rb
    foo
    * bar
    - baz
    o hello
    - world



    a @ http://drawohara.com/
    --
    sleep is the best meditation.
    h.h. the 14th dalai lama
    ara howard, Mar 25, 2008
    #10
  11. Hi --

    On Wed, 26 Mar 2008, ara howard wrote:

    >
    > On Mar 25, 2008, at 3:02 PM, Martin DeMello wrote:
    >
    >> Given:
    >> an outline list, with each line indented by a series of tabs
    >> a list of bullets (assume a circular list, for simplicity)
    >>
    >> Write a function that replaces every tab with two spaces, except for
    >> the last one, which is replaced by a bullet.
    >>
    >> example:
    >>
    >> input file:
    >> foo
    >> \t bar
    >> \t \t baz
    >> \t \t \t hello
    >> \t \t world
    >>
    >> bullets: %w(* - o x)

    >
    > cfp2:~ > cat a.rb
    > DATA.read.gsub(%r/(?:\t\ ?)+/){|s|' '*(n=s.count("\t")-1)+%w(* - o x)[n]+'
    > '}.display


    I don't think that does the two-space thing:

    david-blacks-macbook:hacking dblack$ cat ara.rb
    <<EOM.gsub(%r/(?:\t\ ?)+/){|s|' '*(n=s.count("\t")-1)+%w(* - o x)[n]+'
    '}.display
    \t\t\ta
    \t\tb
    \t\t\t\tc
    EOM
    david-blacks-macbook:hacking dblack$ ruby ara.rb
    o a
    - b
    x c

    Then again, mine didn't either....


    David

    --
    Rails training from David A. Black and Ruby Power and Light:
    ADVANCING WITH RAILS April 14-17 New York City
    INTRO TO RAILS June 9-12 Berlin
    ADVANCING WITH RAILS June 16-19 Berlin
    See http://www.rubypal.com for details and updates!
    David A. Black, Mar 25, 2008
    #11
  12. Hi --

    On Wed, 26 Mar 2008, David A. Black wrote:

    > Hi --
    >
    > On Wed, 26 Mar 2008, Martin DeMello wrote:
    >
    >> On Tue, Mar 25, 2008 at 2:16 PM, James Gray <>
    >> wrote:
    >>>
    >>> I didn't really golf it, but my answer is:

    >>
    >> You have a point - I wasn't looking for golf so much as for neat
    >> and/or offbeat approaches to the problem of counting the tabs.

    >
    > Darn, I took you literally :)
    >
    > def t(s)b='*-ox';s.map{|l|c=l.count("\t")
    > (c-1).times{l.sub!(/\t/,' ')}


    Whoops, that should be ' ' (two spaces).


    David

    --
    Rails training from David A. Black and Ruby Power and Light:
    ADVANCING WITH RAILS April 14-17 New York City
    INTRO TO RAILS June 9-12 Berlin
    ADVANCING WITH RAILS June 16-19 Berlin
    See http://www.rubypal.com for details and updates!
    David A. Black, Mar 25, 2008
    #12
  13. Martin DeMello

    ara howard Guest

    On Mar 25, 2008, at 4:58 PM, David A. Black wrote:

    > Then again, mine didn't either....


    neither did the OPs - my gives back the sample data, which actually
    required one - easy to change though.

    a @ http://codeforpeople.com/
    --
    we can deny everything, except that we have the possibility of being
    better. simply reflect on that.
    h.h. the 14th dalai lama
    ara howard, Mar 25, 2008
    #13
  14. Hi --

    On Wed, 26 Mar 2008, ara howard wrote:

    >
    > On Mar 25, 2008, at 4:58 PM, David A. Black wrote:
    >
    >> Then again, mine didn't either....

    >
    > neither did the OPs - my gives back the sample data, which actually required
    > one - easy to change though.


    I'm seeing it differently; I see Martin's like this:

    foo
    * bar
    - baz
    o hello
    - world

    and yours like this:

    foo
    * bar
    - baz
    o hello
    - world

    That's what I was referring to.


    David

    --
    Rails training from David A. Black and Ruby Power and Light:
    ADVANCING WITH RAILS April 14-17 New York City
    INTRO TO RAILS June 9-12 Berlin
    ADVANCING WITH RAILS June 16-19 Berlin
    See http://www.rubypal.com for details and updates!
    David A. Black, Mar 25, 2008
    #14
  15. Martin DeMello

    ara howard Guest

    On Mar 25, 2008, at 5:22 PM, David A. Black wrote:

    > I'm seeing it differently; I see Martin's like this:


    oh yeah - interesting. the fix:

    cfp2:~ > cat a.rb
    DATA.read.gsub(%r/(?:\t\ ?)+/){|s|' '*(n=s.count("\t")-1)+%w(* - o x)
    [n]+' '}.display

    __END__
    foo
    bar
    baz
    hello
    world


    cfp2:~ > ruby a.rb
    foo
    * bar
    - baz
    o hello
    - world


    a @ http://codeforpeople.com/
    --
    it is not enough to be compassionate. you must act.
    h.h. the 14th dalai lama
    ara howard, Mar 25, 2008
    #15
  16. 2008/3/25, David A. Black <>:

    > Darn, I took you literally :)
    >
    > def t(s)b=3D'*-ox';s.map{|l|c=3Dl.count("\t")
    > (c-1).times{l.sub!(/\t/,' ')}
    > l.sub(/\t/,b[c-1,1])}end
    >
    > t(some_string)


    You forgot the modulo :

    with c =3D l.count("\t')-1, it gives :

    def t(s)b=3D'*-ox';d=3Db.size;s.map{|l|c=3Dl.count("\t")-1
    c.times{l.sub! /\t/,' '}
    l.sub /\t/,b[c%d,1]}end

    input :

    input =3D <<END_INPUT
    foo
    \t bar
    \t \t baz
    \t \t \t hello
    \t \t \t \t ciao
    \t \t \t \t \t bye
    \t \t \t \t \t \t konnichiwa
    \t \t world
    END_INPUT

    James has also forgotten :

    bullets =3D %w[* - o x]
    length =3D bullets.size
    input.gsub!(/^(\t ?)+/) do |indent|
    tabs =3D indent.count("\t") - 1
    " " * tabs + bullets[tabs%length] + " "
    end

    -- Jean-Fran=E7ois.
    Jean-François Trân, Mar 25, 2008
    #16
  17. On Mar 25, 3:02 pm, Martin DeMello <> wrote:
    > Given:
    > an outline list, with each line indented by a series of tabs
    > a list of bullets (assume a circular list, for simplicity)
    >
    > Write a function that replaces every tab with two spaces, except for
    > the last one, which is replaced by a bullet.
    >
    > example:
    >
    > input file:
    > foo
    > \t bar
    > \t \t baz
    > \t \t \t hello
    > \t \t world
    >
    > bullets: %w(* - o x)
    >
    > output (view in fixed width):
    > foo
    > * bar
    > - baz
    > o hello
    > - world
    >
    > martin


    bullets = %w(. * - o x)

    "foo
    \t bar
    \t \t baz
    \t \t \t hello
    \t \t world
    ".each{|x| puts x.reverse.sub("\t",bullets[x.count("\t")]).
    reverse.gsub("\t"," ") }
    William James, Mar 26, 2008
    #17
  18. Martin DeMello

    Adam Shelly Guest

    On 3/25/08, ara howard <> wrote:
    > On Mar 25, 2008, at 5:22 PM, David A. Black wrote:
    > > I'm seeing it differently; I see Martin's like this:

    > oh yeah - interesting. the fix:
    >
    > cfp2:~ > cat a.rb
    > DATA.read.gsub(%r/(?:\t\ ?)+/){|s|' '*(n=s.count("\t")-1)+%w(* - o x)
    > [n]+' '}.display
    >
    > __END__
    > foo
    > bar
    > baz
    > hello
    > world
    >
    >

    (86 bytes of code)


    Here's one that shaves 9 bytes of Ara's while adding 2 fixes to match
    the original spec:
    use modulo for a circular list of bullets, and take an input filename
    from the command line, instead of imbedding it.

    $><<$<.read.gsub(/(?:\t\ ?)+/){|s|' '*(n=s.chop.size-1)+'*-ox'[n%4].chr+' '}

    (77 bytes)
    Adam Shelly, Mar 26, 2008
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bob H

    Datagrid and bullets

    Bob H, Feb 5, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    388
    =?Utf-8?B?QXZuZWVzaA==?=
    Feb 5, 2004
  2. ComputerSnack
    Replies:
    7
    Views:
    1,850
    Jonathan N. Little
    Apr 13, 2006
  3. qwweeeit
    Replies:
    2
    Views:
    637
    qwweeeit
    Dec 14, 2005
  4. rantingrick

    Tabs -vs- Spaces: Tabs should have won.

    rantingrick, Jul 16, 2011, in forum: Python
    Replies:
    95
    Views:
    1,796
    Roy Smith
    Jul 19, 2011
  5. John Kopanas
    Replies:
    2
    Views:
    266
    Gregory Brown
    Jan 29, 2007
Loading...

Share This Page