func (self *ProblemArchiveReader) LoadTests(problem *model.Problem, inPattern, outPattern string) error { inRe, err := regexp.Compile(inPattern) if err != nil { return err } outRe, err := regexp.Compile(outPattern) if err != nil { return err } tests := make(map[string]int) getData := func(name, file string) (id int, data []byte, err error) { id, ok := tests[name] if !ok { problem.Tests = append(problem.Tests, model.Test{}) id = len(problem.Tests) - 1 tests[name] = id } data, err = self.ReadFile(file) return } for _, file := range self.FileList() { in := inRe.FindStringSubmatch(file) if in != nil { id, data, err := getData(in[1], file) if err != nil { return err } problem.Tests[id].Input = model.ConstTestData(data) } out := outRe.FindStringSubmatch(file) if out != nil { id, data, err := getData(out[1], file) if err != nil { return err } problem.Tests[id].Output = model.ConstSolutionData(data) } } return nil }
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) { defer SuppressPanic(&err) reader, err := archive.Open("problem.xml") PanicIf(err) defer reader.Close() problem := new(Problem) utils.NewXmlDecoder(reader).Decode(problem) testset := &problem.Script.Testset p := &model.Problem{ InputFile: testset.InputName, OutputFile: testset.OutputName, TimeLimit: float32(parseTime(testset.TimeLimit)), MemoryLimit: float32(testset.MemoryLimit) / 1024 / 1024, Tests: make([]model.Test, testset.TestCount), } inputPattern := preparePattern(testset.InputPattern) outputPattern := preparePattern(testset.AnswerPattern) for i := 0; i < testset.TestCount; i++ { inputPattern = inputPattern outputPattern = outputPattern data, err := archive.ReadFile(fmt.Sprintf(inputPattern, i+1)) PanicIf(err, "Cannot read test %d input: %s", i+1, err) p.Tests[i].Input = model.ConstTestData(data) data, err = archive.ReadFile(fmt.Sprintf(outputPattern, i+1)) PanicIf(err, "Cannot read test %d input: %s", i+1, err) p.Tests[i].Output = model.ConstSolutionData(data) } return []*model.Problem{p}, nil }
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) { defer SuppressPanic(&err) files := archive.Glob("*.xml") PanicIf(len(files) == 0, "Task file not found") PanicIf(len(files) > 1, "Several xml files found in the archive") reader, err := archive.Open(files[0]) PanicIf(err) defer reader.Close() container := new(Container) utils.NewXmlDecoder(reader).Decode(container) problem := container.Problem PanicIf(problem == nil, "Problem node not found") p := &model.Problem{ Title: problem.Title, Author: problem.Author, TimeLimit: float32(problem.TimeLimit), MemoryLimit: float32(problem.MemoryLimit), Statement: parseSGML(problem.Statement), Constraints: parseSGML(problem.Constraints), InputFormat: parseSGML(problem.InputFormat), OutputFormat: parseSGML(problem.OutputFormat), Generators: make(map[string]*model.Generator), Solutions: make(map[string]*model.Solution), Images: make(model.ImagesDict), } getSample := func(res *SampleResource) string { if res.Source != "" { data, err := archive.ReadFile(res.Source) PanicIf(err) return string(data) } return res.Text } p.Samples = make([]model.Sample, len(problem.Samples)) for i, sample := range problem.Samples { p.Samples[i].Input = getSample(&sample.SampleIn) p.Samples[i].Output = getSample(&sample.SampleOut) } for _, picture := range problem.Pictures { data, err := archive.ReadFile(picture.Source) PanicIf(err) p.Images[picture.Name] = data } for _, generator := range problem.Generators { addGenerator(archive, p, &generator) } for _, genRange := range problem.GeneratorRanges { for j := genRange.From; j <= genRange.To; j++ { generator := genRange.Generator generator.Name = applyTestRank(generator.Name, j) generator.Source = applyTestRank(generator.Source, j) addGenerator(archive, p, &generator) } } for _, solution := range problem.Solutions { lang := getLanguage(solution.LanguageCode, solution.Source) PanicIf(lang == nil, "Unknown solution language") data, err := archive.ReadFile(solution.Source) PanicIf(err) p.Solutions[solution.Name] = &model.Solution{ Name: solution.Name, Language: lang.Name, SourceCode: string(data), } } convertTest := func(t *model.Test, test *Test) { t.Points = test.Points if in := test.InputFile; in != nil { if in.Source != "" { data, err := archive.ReadFile(in.Source) PanicIf(err) t.Input = model.ConstTestData(data) } else if in.Generator != "" || in.Parameters != "" { if t.Input == nil { t.Input = &model.GeneratedInput{} } if in.Generator != "" { t.Input.(*model.GeneratedInput).Generator = in.Generator } if in.Parameters != "" { t.Input.(*model.GeneratedInput).Parameters = in.Parameters } } } if out := test.OutputFile; out != nil { if out.Source != "" { data, err := archive.ReadFile(out.Source) PanicIf(err) t.Output = model.ConstSolutionData(data) } else if out.Solution != "" { t.Output = &model.SolutionOutput{Solution: out.Solution} } } } addTestGroup := func(test *Test) { for rank := range stringRange(test.Rank) { if rank < 1 { continue } for len(p.Tests) < rank { p.Tests = append(p.Tests, model.Test{}) } processedTest := *test if in := processedTest.InputFile; in != nil { processedTest.InputFile = &InputFile{ Generator: applyTestRank(in.Generator, rank), Source: applyTestRank(in.Source, rank), Parameters: applyTestRank(in.Parameters, rank), GenerateAll: in.GenerateAll, } } if out := processedTest.OutputFile; out != nil { processedTest.OutputFile = &OutputFile{ Solution: applyTestRank(out.Solution, rank), Source: applyTestRank(out.Source, rank), } } convertTest(&p.Tests[rank-1], &processedTest) } } for _, testRange := range problem.TestRanges { test := Test{ Rank: fmt.Sprintf("%d-%d", testRange.From, testRange.To), TestDataMixin: testRange.TestDataMixin, } addTestGroup(&test) } for _, test := range problem.Tests { addTestGroup(&test) } for i, test := range p.Tests { if test.Input == nil || test.Output == nil { Panic("Test %d: incomplete input or output section", i+1) } } return []*model.Problem{p}, nil }
func convertProblem(problem *Problem) (*model.Problem, error) { p := &model.Problem{ Title: problem.Title, Author: problem.Source, InputFile: "*STDIN", OutputFile: "*STDOUT", TimeLimit: float32(problem.TimeLimit), MemoryLimit: float32(problem.MemoryLimit), } p.Samples = make([]model.Sample, min(len(problem.SampleInput), len(problem.SampleOutput))) for i := range p.Samples { p.Samples[i].Input = problem.SampleInput[i] p.Samples[i].Output = problem.SampleOutput[i] } p.Tests = make([]model.Test, min(len(problem.TestInput), len(problem.TestOutput))) for i := range p.Tests { p.Tests[i].Input = model.ConstTestData(problem.TestInput[i]) p.Tests[i].Output = model.ConstSolutionData(problem.TestOutput[i]) } p.Images = make(model.ImagesDict) for _, image := range problem.Images { content, err := base64.StdEncoding.DecodeString(image.Data) if err != nil { return nil, err } p.Images[image.Source] = content } i := 0 p.Solutions = make(map[string]*model.Solution) for _, solution := range problem.Solutions { if len(solution.Language) > 0 && len(solution.Text) > 0 { name := fmt.Sprintf("sol_%d", i+1) p.Solutions[name] = &model.Solution{ Name: name, Language: strings.ToLower(solution.Language), SourceCode: solution.Text, } } i++ } p.Statement = processHTML(problem.Description, p.Images) p.InputFormat = processHTML(problem.InputFormat, p.Images) p.OutputFormat = processHTML(problem.OutputFormat, p.Images) if problem.Checker != nil { if len(problem.Checker.Text) > 0 && len(problem.Checker.Language) > 0 { p.Checker = &model.Checker{ Style: "testlib", Language: strings.ToLower(problem.Checker.Language), SourceCode: problem.Checker.Text, } } } return p, nil }