LoginSignup
0
0

More than 5 years have passed since last update.

第16回オフラインリアルタイムどう書く rubyで解く

Posted at

会場で 1 時間 + その後 30 分くらいやって解けました

class LineCounter
  attr_reader :field

  def initialize(input = '')
    @field = build_field(input)
  end

  def count_lines
    [count_h_lines(h_edge_field(@field)), count_h_lines(h_edge_field(@field.transpose))].transpose.map {|(a, b)| a + b }.join(',')
  end

  def h_edge_field(target)
    before = target[0..-2]
    after  = target[1..-1]

    [before, after].transpose.each_with_object([]) do |(b_r, a_r), array|
      array << [b_r, a_r].transpose.each_with_object([]) do |(b, a), ary|
        ary << (([b, a] == [0, 1] || [b, a] == [1, 0]) ? 1 : 0)
      end
    end
  end

  def count_h_lines(target)
    target.inject([0] * 6) do |array, row|
      [count_line(row), array].transpose.map do |a, b|
        a + b
      end
    end
  end

  def count_line(row)
    row.join.split('0').map(&:length).each_with_object([0] * 6) {|i, a| a[i-1] += 1 if i > 0 }
  end

  private

  def build_field(input)
    f = input.each_char.map {|c| '%03d' % c.to_i(8).to_s(2) }.join
    f = f.split('').each_slice(6).to_a
    f.map {|row| row.map(&:to_i) }
  end
end
require 'spec_helper'

describe LineCounter do
  describe '#count_lines' do
    subject { described_class.new(input).count_lines }

    test_data = <<-EOS
    /*0*/ test( "060276724276", "6,2,1,1,0,1" );
    /*1*/ test( "770175454177", "2,3,0,3,1,0" );
    /*2*/ test( "743733377170", "9,3,1,0,0,0" );
    /*3*/ test( "724212121273", "5,2,1,1,1,1" );
    /*4*/ test( "100000000000", "3,0,0,0,0,0" );
    /*5*/ test( "000002000000", "4,0,0,0,0,0" );
    /*6*/ test( "003622223600", "0,4,0,4,0,0" );
    /*7*/ test( "520073737070", "8,3,1,1,0,0" );
    /*8*/ test( "770077007700", "0,0,0,0,0,5" );
    /*9*/ test( "555555555514", "2,0,0,0,2,2" );
    /*10*/ test( "764252427600", "4,0,4,0,2,0" );
    /*11*/ test( "774555554177", "3,3,1,3,0,0" );
    /*12*/ test( "674574754557", "11,5,0,1,0,0" );
    /*13*/ test( "000000000000", "0,0,0,0,0,0" );
    /*14*/ test( "777777777777", "0,0,0,0,0,0" );
    /*15*/ test( "774377777577", "6,0,2,0,0,0" );
    /*16*/ test( "070777777777", "0,1,1,0,0,0" );
    /*17*/ test( "373737373737", "0,0,0,0,0,1" );
    /*18*/ test( "603260327725", "30,0,0,0,0,0" );
    /*19*/ test( "466331144663", "30,0,0,0,0,0" );
    /*20*/ test( "000000000242", "3,2,0,0,0,0" );
    /*21*/ test( "567656043772", "18,2,1,0,0,0" );
    /*22*/ test( "200763012420", "15,4,1,0,0,0" );
    /*23*/ test( "400101140052", "14,3,0,0,0,0" );
    /*24*/ test( "764767476476", "13,2,0,1,0,0" );
    /*25*/ test( "001110140110", "12,2,1,0,0,0" );
    /*26*/ test( "765405076527", "16,3,0,1,0,0" );
    /*27*/ test( "377323370373", "8,4,2,0,0,0" );
    /*28*/ test( "250541131216", "11,5,2,0,0,0" );
    /*29*/ test( "744165741476", "12,3,2,0,0,0" );
    /*30*/ test( "042101000300", "10,3,0,0,0,0" );
    /*31*/ test( "002004554101", "11,3,1,0,0,0" );
    /*32*/ test( "371707762706", "15,1,1,0,0,0" );
    /*33*/ test( "130371310175", "7,3,1,2,0,0" );
    /*34*/ test( "212537003613", "13,2,1,1,1,0" );
    /*35*/ test( "157700063411", "15,3,0,0,0,1" );
    /*36*/ test( "011500036007", "6,7,1,0,0,0" );
    /*37*/ test( "743113313517", "17,2,1,0,0,0" );
    /*38*/ test( "174105270405", "13,3,1,1,0,0" );
    /*39*/ test( "427272200311", "13,3,2,0,0,0" );
    /*40*/ test( "725370332237", "12,5,1,1,0,0" );
    /*41*/ test( "005640420046", "12,1,3,0,0,0" );
    /*42*/ test( "700350001101", "14,3,1,0,0,0" );
    /*43*/ test( "577627744076", "16,1,1,1,0,0" );
    /*44*/ test( "620332232007", "10,4,2,1,0,0" );
    /*45*/ test( "260406401000", "15,1,1,0,0,0" );
    /*46*/ test( "737272723276", "5,0,0,0,3,0" );
    /*47*/ test( "000400040444", "7,0,2,0,0,0" );
    /*48*/ test( "370222002177", "13,2,2,0,0,0" );
    /*49*/ test( "372236024656", "9,3,2,0,1,0" );
    /*50*/ test( "276131137003", "11,6,2,0,0,0" );
    /*51*/ test( "742134007240", "13,4,2,0,0,0" );
    /*52*/ test( "777721775571", "13,1,2,0,0,0" );
    /*53*/ test( "700301232233", "11,2,3,0,0,0" );
    EOS

    test_data.each_line do |t|
      t =~ /test\( "(\d*)", "(.*)" \)/

      context do
        let(:input) { $1 }
        let(:expectation) { $2 }
        it { should eq expectation }
      end
    end
  end

  describe '#field' do
    subject { described_class.new(input).field }

    context do
      let(:input) { '060276724276' }

      it {
        should eq(
          [[0, 0, 0, 1, 1, 0],
           [0, 0, 0, 0, 1, 0],
           [1, 1, 1, 1, 1, 0],
           [1, 1, 1, 0, 1, 0],
           [1, 0, 0, 0, 1, 0],
           [1, 1, 1, 1, 1, 0]]
        )
      }
    end
  end

  describe '#h_edge_field' do
    subject { described_class.new.h_edge_field(target) }

    context do
      let(:target) {
        [[0, 0, 0, 1, 1, 0],
         [0, 0, 0, 0, 1, 0],
         [1, 1, 1, 1, 1, 0],
         [1, 1, 1, 0, 1, 0],
         [1, 0, 0, 0, 1, 0],
         [1, 1, 1, 1, 1, 0]]
      }

      it {
        should eq(
          [[0, 0, 0, 1, 0, 0],
           [1, 1, 1, 1, 0, 0],
           [0, 0, 0, 1, 0, 0],
           [0, 1, 1, 0, 0, 0],
           [0, 1, 1, 1, 0, 0]]
        )
      }
    end
  end

  describe '#count_h_lines' do
    subject { described_class.new.count_h_lines(target) }

    context do
      let(:target) {
        [[0, 0, 0, 1, 0, 0],
         [1, 1, 1, 1, 0, 0],
         [0, 0, 0, 1, 0, 0],
         [0, 1, 1, 0, 0, 0],
         [0, 1, 1, 1, 0, 0]]
      }

      it { should eq [2, 1, 1, 1, 0, 0] }
    end
  end

  describe '#count_line' do
    subject { described_class.new.count_line(target) }

    context do
      let(:target) { [1, 1, 0, 1, 0, 1] }

      it { should eq [2, 1, 0, 0, 0, 0] }
    end

    context do
      let(:target) { [0, 0, 0, 1, 0, 0] }

      it { should eq [1, 0, 0, 0, 0, 0] }
    end
  end
end
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0