#!/usr/bin/env ruby def _c s s.strip.lstrip.gsub("'", '').gsub(/\s+/, "_") end class Item attr_accessor :predicate, :arguments def initialize predicate='', arguments=[] @predicate = predicate @arguments = [] end def to_s args = @arguments.each{|i| i.to_s}.to_s.gsub('[','(').gsub(']',')') "#{@predicate}#{args}" end end def parse_funql s s = "(#{s})" structure = Item.new prev_p = nil p = structure collect = '' just_closed = false s.each_char { |c| if c == '(' p.arguments << Item.new(_c(collect)) collect = '' prev_p = p p = p.arguments.last just_closed = false elsif c == ')' if collect != '' p.arguments << _c(collect) collect = '' end p = prev_p just_closed = true elsif c == ',' if collect != '' p.arguments << _c(collect) collect = '' end if just_closed p = prev_p end just_closed = false else collect += c end } return structure end def flatten_funql a return "#{a} " if a.class == String s = "#{a.predicate}$#{a.arguments.size} " a.arguments.each { |i| s += flatten_funql(i) } return s end def _fix_output s s[5..s.size-1].lstrip.strip.gsub("'", '') end def reverse s s.strip! open = 0 r = '' s.split.each { |i| term, n = i.split '$' n = n.to_i out = term if n == 0 out = "'#{out}'" elsif n > 0 out += '(' open += 1 else puts "ERROR" exit end r += out } open.times { r += ')' } return r.gsub("''", "','") end def test a = [] a << "answer(exclude(state(all), next_to_2(stateid('texas'))))" a << "answer(most(state(traverse_1(river(all)))))" a << "answer(state(loc_1(river(riverid('red')))))" a << "answer(smallest_one(area_1(state(next_to_2(stateid('texas'))))))" a << "answer(smallest_one(density_1(state(all))))" a << "answer(smallest_one(density_1(state(all))))" a << "answer(smallest_one(density_1(state(all))))" a << "answer(state(loc_1(cityid('kalamazoo', _))))" a.each { |i| puts i r = parse_funql(i) puts r.to_s puts _fix_output(flatten_funql(r)) puts } end def main #test while line = STDIN.gets x = _fix_output(flatten_funql(parse_funql(line.strip))) puts line puts x puts reverse(x) puts end end main