LoginSignup
0
0

More than 5 years have passed since last update.

「オフラインリアルタイムどう書く第15回(異星の電光掲示板)」の問題を解いてみた

Posted at

横浜へなちょこプログラミング勉強会にて過去に出題された異星の電光掲示板を解いてみた。
回答にかかった時間は80分程度と20分オーバー。

空白(点灯のない縦の列)を見て文字の部分を抜き出す部分の実装に非常に時間がかかってしまった。

class Board
  PATTERN = {
    "L" => ["10", "11"],
    "R" => ["11", "10"],
    "J" => ["01", "11"],
    "T" => ["111", "010"],
    "U" => ["101", "111"],
    "N" => ["111", "101"],
    "S" => ["011", "110"],
    "Z" => ["110", "011"]
  }

  def initialize input
    @chars = []
    top, bottom = input.split("/").map{|line| "%032b" % line.hex}

    indexes = []
    ("%032b" % (top.to_i(2) ^ bottom.to_i(2))).scan(/11/){ indexes << $~.begin(0) }
    indexes.reverse.each{|i|
      top = top[0..i] + "0" + top[(i+1)..(top.size - 1)]
      bottom = bottom[0..i] + "0" + bottom[(i+1)..(bottom.size - 1)]
    }
    format("%0*b", top.size, top.to_i(2) | bottom.to_i(2)).scan(/1{2,3}/){|char|
      start = $~.begin(0)
      last  = start + (char.size - 1)
      @chars << [top[start..last], bottom[start..last]]
    }
  end

  def chars
    @chars.map{|chr|
      PATTERN.select{|c, pattern| chr === pattern}.keys[0]
    }.join
  end
end

test = <<_TEST
/*0*/ test( "2ed8aeed/34b0ea5b", "LTRSUNTSJ" );    
/*1*/ test( "00000200/00000300", "L" );    
/*2*/ test( "00018000/00010000", "R" );    
/*3*/ test( "00002000/00006000", "J" );    
/*4*/ test( "00000700/00000200", "T" );    
/*5*/ test( "01400000/01c00000", "U" );    
/*6*/ test( "00003800/00002800", "N" );    
/*7*/ test( "000c0000/00180000", "S" );    
/*8*/ test( "00003000/00001800", "Z" );    
/*9*/ test( "132eae6c/1a64eac6", "LRJTUNSZ" );    
/*10*/ test( "637572d0/36572698", "ZSNUTJRL" );    
/*11*/ test( "baddb607/d66b6c05", "LTJZTSSSN" );    
/*12*/ test( "db74cd75/6dac6b57", "ZZZTJZRJNU" );    
/*13*/ test( "3606c2e8/1b0d8358", "ZZSSLTJ" );    
/*14*/ test( "ad98c306/e6cc6183", "UZZZZZZ" );    
/*15*/ test( "4a4aaee3/db6eeaa6", "JJLLUUNNS" );    
/*16*/ test( "ecd9bbb6/598cd124", "TSSZZTTRR" );    
/*17*/ test( "e0000002/40000003", "TL" );    
/*18*/ test( "a0000007/e0000005", "UN" );    
/*19*/ test( "c0000003/80000006", "RS" );    
/*20*/ test( "40000006/c0000003", "JZ" );    
/*21*/ test( "01da94db/00b3b6b2", "TSUJLRSR" );    
/*22*/ test( "76eeaaea/24aaeeae", "TRNNUUNU" );    
/*23*/ test( "1dacaeee/1566e444", "NRJZUTTT" );    
/*24*/ test( "26c9ac60/6c6d66c0", "JSZLRJZS" );    
/*25*/ test( "6c977620/36da5360", "ZZLLTNZJ" );    
/*26*/ test( "069aeae6/0db34eac", "SJSLTUNS" );    
/*27*/ test( "06d53724/049da56c", "RRULRNJJ" );    
/*28*/ test( "069b58b0/04d66da0", "RLRSLZJR" );    
/*29*/ test( "1b6eced4/11b46a9c", "RZZTZNRU" );    
/*30*/ test( "522e8b80/db6ad900", "JLLJNLJT" );    
/*31*/ test( "6546cdd0/376c6898", "ZULSZRTL" );    
/*32*/ test( "4e6d5b70/6ad9d620", "LNSSURST" );    
/*33*/ test( "37367772/65635256", "SNSZNTNJ" );    
/*34*/ test( "25535d58/377669cc", "LUUSLTUZ" );    
/*35*/ test( "0ae6a55d/0eacedcb", "UNSUJUTJ" );    
/*36*/ test( "76762edc/23536a88", "TZNZJNRT" );
_TEST

require 'minitest/autorun'

describe 'EleBoard' do
  test.split("\n").each do |line|
    t, n, input, expect = line.match(/^\/\*(\d+)\*\/\s*test\(\s*"([^"]+)",\s*"([^"]+)"\s*\);\s*$/).to_a
    board = Board.new input
    it input do
      assert_equal expect, board.chars
    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