LoginSignup
4
3

More than 5 years have passed since last update.

オフラインリアルタイムどう書くE01 Ruby で解く

Last updated at Posted at 2016-02-08

リンク

問題 http://nabetani.sakura.ne.jp/hena/orde01rotbk/
実装リンク集 http://qiita.com/Nabetani/items/4bf43031749c81c35526

実装

当日はテストが半分くらい落ちて敗北
解説を聞いて飛び石に気づき、教わった chunk 使ってやっとテスト突破

強いて他の人との差別点を挙げるなら、 ActiveSupport の Array#fromObject#presence くらい。
transpose なのに transpose してないのはご愛嬌。
(当日は 90 度回転とか transpose でよゆーとか思ってた。 reverse すればよかったのね。)

require 'bundler'
Bundler.require

class Field
  attr_reader :field

  def initialize(size)
    @field = Array.new(size) { [nil] * size }
  end

  def fill_by(group)
    group.each do |size|
      fill(*detect_space, size)
    end
  end

  def fill(x, y, size)
    (x...(x + size)).each do |_x|
      (y...(y + size)).each do |_y|
        @field[_y][_x] = size
      end
    end
  end

  def detect_space
    y = @field.find_index(@field.detect {|row| row.include?(nil) })
    x = @field[y].find_index(nil)
    [x, y]
  end

  def inspect
    @field.map do |row|
      row.map {|column| "%03d" % column }.join(",")
    end.join("\n")
  end

  def to_s
    inspect
  end

  def size
    @field.size
  end

  def transpose
    field = Field.new(size)

    @field.each.with_index do |row, y|
      row.each.with_index do |column, x|
        field.field[x][size - y - 1] = column
      end
    end

    field
  end
end

def solve(input)
  ans_key, groups = input.match(/(\d+):(.*)/).captures
  groups = groups.scan(/\((.*?)\)/).flatten.map {|group| group.split(?,).map(&:to_i) }

  field = Field.new(groups.first.sum)
  groups.each do |group|
    field.fill_by(group)
  end
  groups = field.transpose.field.uniq.map(&:uniq)
  g = groups.map.with_index {|group, i| group.chunk {|e| (groups - groups.from(i)).flatten.exclude?(e).presence }.map(&:last) }.flatten(1)[ans_key.to_i - 1]
  "(#{g.join(?,)})"
end

def test(input, expect)
  actual = solve(input)

  if actual == expect
    puts "OK: #{input}"
  else
    raise "NG: #{input} : expect #{expect} but got #{actual}"
  end
end

DATA.each_line do |line|
  puts line
  eval line.match(%r{.*(test.*)}).captures.first
end

__END__
/*0*/ test( "4:(55,44,48)(40,4)(52)(26,29)(23,3)(20,31,21)(5,47)(43)(9,17)(1,8)(32)(25)", "(32,31)" );
/*1*/ test( "6:(33,29,50)(4,25)(37)(15,35)(16,9)(7,2)(17)(42,18)(6,11)(8,27)(24)(19)", "(6,17,2)" );
/*2*/ test( "7:(60,50)(23,27)(24,22,14)(7,16)(8,6)(12,15)(13)(2,28)(26)(4,21,3)(18)(17)", "(4,16)" );
/*3*/ test( "6:(99,73,56)(17,39)(68,22)(36,25)(57,42)(9,16)(2,7)(10,28)(23)(15,87,18)(72)(69)", "(10,36,22)" );
/*4*/ test( "7:(79,49,66,63)(32,17)(3,60)(29,57)(55,22,2)(20,14)(15,28)(33,9)(24)(11,134)(123)", "(29,17)" );
/*5*/ test( "7:(159,129)(57,72)(56,39,25,16,23)(9,7)(2,28)(36)(42,15)(17,22)(87)(10,18)(73)(68)(60)", "(10,28)" );
/*6*/ test( "14:(113,71,68)(32,36)(42,29)(13,44,4)(40)(62,37,38,31)(7,108)(25,12)(11,34)(23)(77,10)(67)", "(36)" );
/*7*/ test( "8:(145,125)(53,72)(45,11,9,16,31,33)(2,7)(13)(8,15)(21)(14,32)(30,37,19)(80)(18,73)(62)(55)", "(31)" );
/*8*/ test( "1:(175,140,164)(35,29,52,24)(28,160)(6,23)(130,86)(43,60)(26,17)(77)(44,68)(174)(5,155)(150)", "(174,130,175)" );
/*9*/ test( "6:(240,168,187)(149,19)(206)(163,77)(86,82,58)(40,18)(22,202)(4,78)(192,61)(62)(48,13)(35,118)(83)", "(4,82)" );
/*10*/ test( "5:(100,73,59)(14,45)(56,31)(58,42)(25,51)(19,36,26)(16,18,8)(2,17)(10)(77)(74)(28)(23,30)(44,7)(37)", "(2,19,56,73)" );
/*11*/ test( "8:(100,88,76)(27,49)(12,19,39,18)(95,11,6)(3,24)(5,1)(21)(20)(16)(2,47)(77,45)(92)(69,26)(17,60)(43)", "(19)" );
/*12*/ test( "11:(262,196,203)(83,106,7)(210)(161,84,17)(36,41,23)(18,111)(31,5)(64)(77,38)(102)(73,248)(238)(175)", "(248)" );
/*13*/ test( "9:(117,79,74)(5,69)(84)(71,46)(20,49)(25,39,57,29)(82,14)(78)(35,18)(13,12,50)(1,11)(4,10)(33,6)(27)", "(1,12)" );
/*14*/ test( "7:(163,95,78)(17,61)(68,44)(24,81)(89,94,72)(15,66)(42,45)(84,5)(79,20)(59,3)(26,22)(16,50)(4,34)(30)", "(30,26,3)" );
/*15*/ test( "10:(100,95,69)(26,43)(11,16,77,17)(88,12)(6,5)(1,20)(19)(60)(39)(18,21)(45,92)(76,27,3)(24)(49,2)(47)", "(47,2)" );
/*16*/ test( "8:(120,78,102)(34,20,24)(14,6)(2,10,23,91)(8)(53,13)(75,45)(36)(4,32)(30,47,25)(22,3)(19,107)(105)(88)", "(4,36,13)" );
/*17*/ test( "13:(119,124,96)(28,68)(114,5)(117,40)(56,52)(4,48)(21,15,24)(106,8)(6,9)(98,38,16)(13,20)(22,7)(75)(60)", "(20)" );
/*18*/ test( "2:(302,277,246)(57,189)(25,117,109,26)(235,92)(83)(8,135,49)(90,127)(81,157)(53,37)(5,76)(304)(288)(233)", "(53,90,92)" );
/*19*/ test( "13:(158,109,240)(49,60)(114,82,11)(71)(126,267)(62,52)(10,42)(40,32)(8,51,141)(48)(14,37)(39,9)(23)(7,53)(46)", "(60)" );
/*20*/ test( "8:(132,113,251)(19,36,58)(107,27,17)(10,21,22)(25,12)(1,20)(13)(80)(32,6)(26)(23,35)(130)(121,245)(127,3)(124)", "(26,6)" );
/*21*/ test( "4:(187,127,194)(60,67)(131,76,40)(33,72,156)(44,29)(19,10)(55,21)(82)(13,27,4)(23)(34)(50)(190,30)(160,2)(158)", "(60,127)" );
/*22*/ test( "12:(239,245)(132,107)(124,121)(27,25,32,23)(3,118)(35,115)(113,19)(12,13)(17,10)(6,26)(21,1)(20)(36)(22,80)(58)", "(124,245)" );
/*23*/ test( "3:(176,152)(24,38,90)(80,63,43,14)(52)(20,23)(17,26,40)(37,42,86)(72,25)(16,10)(6,4)(49,19,8,5)(47)(3,44)(11)(30)", "(17,63)" );
/*24*/ test( "15:(171,181)(95,76)(93,88)(19,30,27)(42,40,32)(5,83)(3,15,29,78)(21,12)(9,18)(8,54)(4,25)(2,46)(22)(44)(1,24)(23)", "(93,181)" );
/*25*/ test( "13:(152,88,112)(64,24)(44,92)(200,12,4)(8,7,33)(1,6)(16,5)(11)(27)(18,15)(3,31,73)(29,19)(10,9)(40)(39)(77,2)(75)", "(3,15)" );
/*26*/ test( "13:(484,316,379)(108,145,63)(82,360)(42,66)(29,198)(18,24)(308,194)(119)(69,50)(168,80)(114,149)(440)(387,35)(352)", "(379)" );
/*27*/ test( "12:(181,191)(93,88)(24,23,54,46,44)(1,22)(25)(2,42)(4,18)(8,40)(29)(9,21,32)(15,12)(3,30)(5,103,27)(98)(19,95)(76)", "(21)" );
/*28*/ test( "18:(83,79,123)(35,44)(52,31)(21,36,9)(27,60,89)(48,25)(10,20,33)(23,12)(2,5,13)(11,3)(8)(102,49,45)(16,73)(4,57)(53)", "(123)" );
/*29*/ test( "4:(649,439,456)(214,208,17)(473)(6,55,147)(385,260,4)(175,49)(104)(12,135)(116)(81,94)(125,216)(203,7)(615)(510)(419)", "(81,175,4)" );
/*30*/ test( "17:(100,114,48,53)(43,5)(58)(23,20)(61,25,14)(3,75)(11,47,96)(36)(95,49)(24,51)(37,105,27)(78)(9,28)(59,26,19)(7,40)(33)", "(58,5)" );
source 'https://rubygems.org'

gem 'activesupport', require: 'active_support/all'
gem 'pry'
gem 'tapp'
gem 'awesome_print'
GEM
  remote: https://rubygems.org/
  specs:
    activesupport (4.2.5.1)
      i18n (~> 0.7)
      json (~> 1.7, >= 1.7.7)
      minitest (~> 5.1)
      thread_safe (~> 0.3, >= 0.3.4)
      tzinfo (~> 1.1)
    awesome_print (1.6.1)
    coderay (1.1.0)
    i18n (0.7.0)
    json (1.8.3)
    method_source (0.8.2)
    minitest (5.8.4)
    pry (0.10.3)
      coderay (~> 1.1.0)
      method_source (~> 0.8.1)
      slop (~> 3.4)
    slop (3.6.0)
    tapp (1.5.0)
      thor
    thor (0.19.1)
    thread_safe (0.3.5)
    tzinfo (1.2.2)
      thread_safe (~> 0.1)

PLATFORMS
  ruby

DEPENDENCIES
  activesupport
  awesome_print
  pry
  tapp

BUNDLED WITH
   1.11.2
4
3
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
4
3