module AtCoderFriends::Parser::InputType

parses input data types and updates input definitons

Constants

DECIMAL_PAT
NUMBER_PAT
TYPE_TBL

Public Instance Methods

detect_col_type(arr) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 83
def detect_col_type(arr)
  ret = :string
  TYPE_TBL.any? do |type, pat|
    arr.all? { |v| v =~ pat } && ret = type
  end
  ret
end
detect_cols_type(rows) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 74
def detect_cols_type(rows)
  cols = fill_transpose(rows).map(&:compact)
  cols.map { |col| detect_col_type(col) }
end
fill_transpose(arr) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 79
def fill_transpose(arr)
  Array.new(arr.map(&:size).max) { |i| arr.map { |e| e[i] } }
end
get_line_cnt(inpdef) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 49
def get_line_cnt(inpdef)
  case inpdef.size.size
  when 0
    1
  when 1
    inpdef.container == :harray ? 1 : inpdef.size[0]
  when 2
    inpdef.size[0]
  end
end
match_smp(inpdefs, lines) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 32
def match_smp(inpdefs, lines)
  vars = {}
  inpdefs.each do |inpdef|
    break unless  (k = get_line_cnt(inpdef))

    k, parsed = parse_line_cnt(k, vars)
    rows = lines.shift(k).map { |line| line.split(/[#{inpdef.delim} ]/) }
    break if rows.empty?

    inpdef.container == :single &&
      vars.merge!(inpdef.names.zip(rows[0]).to_h)
    inpdef.cols = detect_cols_type(rows)
    break unless parsed
  end
  inpdefs
end
max_smp(smps) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 25
def max_smp(smps)
  smps
    .select { |smp| smp.ext == :in }
    .max_by { |smp| smp.txt.size }
    &.txt
end
parse(inpdefs, smps) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 20
def parse(inpdefs, smps)
  lines = max_smp(smps)&.split("\n")
  lines && match_smp(inpdefs, lines)
end
parse_line_cnt(k, vars) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 60
def parse_line_cnt(k, vars)
  if k.is_a?(Integer)
    [k, true]
  elsif k =~ NUMBER_PAT
    [k.to_i, true]
  elsif vars[k] =~ NUMBER_PAT
    [vars[k].to_i, true]
  elsif vars[(k2 = k.gsub(/-1\z/, ''))] =~ NUMBER_PAT
    [vars[k2].to_i - 1, true]
  else
    [1, false]
  end
end
process(pbm) click to toggle source
# File lib/at_coder_friends/parser/input_type.rb, line 16
def process(pbm)
  parse(pbm.formats_src, pbm.samples)
end