module AtCoderFriends::Parser::Constraints

parses constraints

Constants

MAX_PATTERN
NAMES_PAT
NAME_PAT
NUM_PAT
SECTIONS

Public Instance Methods

normalize_content(s) click to toggle source
# File lib/at_coder_friends/parser/constraints.rb, line 47
def normalize_content(s)
  # 1) &npsp; , fill-width space -> half width space
  # 2) {i, j}->{i,j} {N-1}->{N} shortest match
  s
    .tr('0-9A-Za-z', '0-9A-Za-z')
    .gsub(/[[:space:]]/) { |c| c.gsub(/[^\t\n]/, ' ') } # 1)
    .gsub(%r{</?var>}i, "\t")
    .gsub(%r{<sup>([^<>]+)</sup>}i, '^\1')
    .gsub(%r{<sub>([^<>]+)</sub>}i, '_{\1}')
    .gsub(/<("[^"]*"|'[^']*'|[^'"<>])*>/, '')
    .gsub('&amp;', '&')
    .gsub(/(<|≦|≤|&lt;|&leq?;|\\lt|\\leq?q?)/i, '<')
    .gsub('\\ ', ' ')
    .gsub('\\,', ',')
    .gsub('\\|', '|')
    .gsub(',', ', ')
    .gsub('×', '*')
    .gsub('\\lvert', '|')
    .gsub('\\rvert', '|')
    .gsub('\\mathit', '')
    .gsub('\\mathrm', '')
    .gsub('\\times', '*')
    .gsub(/\\begin(\{[^{}]*\})*/, '')
    .gsub(/\\end(\{[^{}]*\})*/, '')
    .gsub(/\{\}/, ' ')
    .gsub('|', '')
    .gsub(/\{.*?\}/) { |w| w.delete(' ()').gsub(/{(.+)-1}\z/, '\1') } # 2)
end
normalize_names(s) click to toggle source
# File lib/at_coder_friends/parser/constraints.rb, line 76
def normalize_names(s)
  # 1) {i,j}->{ij} shortest match
  s
    .gsub(/\{.*?\}/) { |w| w.delete(',') } # 1)
    .delete('{}')
    .gsub(/\s+/, '')
    .split(',')
    .reject(&:empty?)
end
normalize_value(s) click to toggle source
# File lib/at_coder_friends/parser/constraints.rb, line 86
def normalize_value(s)
  s
    .split(', ')
    &.map do |v|
      v
        .delete(' {}')
        .gsub(/\A[+*^,]+/, '') # remove preceding symbols
        .gsub(/[+*^,]+\z/, '') # remove trailing symbols
    end
    &.reject(&:empty?)
    &.first
end
parse(str) click to toggle source
# File lib/at_coder_friends/parser/constraints.rb, line 35
def parse(str)
  str = normalize_content(str)
  str
    .scan(MAX_PATTERN)
    .map(&:compact)
    .map { |k, v| [normalize_names(k), normalize_value(v)] }
    .select { |_, v| v && !v.empty? }
    .flat_map { |ks, v| ks.map { |k| [k, v] } }
    .uniq
    .map { |k, v| Problem::Constant.new(k, :max, v) }
end
process(pbm) click to toggle source
# File lib/at_coder_friends/parser/constraints.rb, line 25
def process(pbm)
  maxs = []
  SECTIONS.any? do |section|
    next unless (text = pbm.sections[section]&.html)

    !(maxs = parse(text)).empty?
  end
  pbm.constants += maxs
end