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) data, err := archive.ReadFile("problem.xml") PanicIf(err) problem := new(Problem) xml.Unmarshal(data, problem) p := &model.Problem{ Title: problem.Names[0].Value, InputFile: problem.Judging.InputFile, OutputFile: problem.Judging.OutputFile, TimeLimit: float32(problem.Judging.TestSet.TimeLimit) / 1000, MemoryLimit: float32(problem.Judging.TestSet.MemoryLimit) / 1024 / 1024, Statement: model.RawText(""), Constraints: model.RawText(""), InputFormat: model.RawText(""), OutputFormat: model.RawText(""), Generators: make(map[string]*model.Generator), Solutions: make(map[string]*model.Solution), Images: make(model.ImagesDict), } if p.InputFile == "" { p.InputFile = "*STDIN" } if p.OutputFile == "" { p.OutputFile = "*STDOUT" } getFile := func(file *File) (*programs.Compiler, []byte, string, error) { path := file.Path name := filepath.Base(path) ext := filepath.Ext(path) compiler := programs.GetCompilerByExt(ext) if compiler == nil { return nil, nil, "", fmt.Errorf("Unknown language extension %s", ext) } data, err := archive.ReadFile(path) if err != nil { return nil, nil, "", fmt.Errorf("Cannot read file %s: %s", path, err) } return compiler, data, name, nil } var mainSolution *model.Solution for _, solution := range problem.Assets.Solutions { compiler, data, name, err := getFile(&solution.Source) PanicIf(err, "Solution error: %s", err) p.Solutions[name] = &model.Solution{ Name: name, Language: compiler.Name, SourceCode: string(data), } if solution.Tag == "main" { mainSolution = p.Solutions[name] } } getGenerator := func(name string) *model.Generator { if generator := p.Generators[name]; generator != nil { return generator } for _, executable := range problem.Files.Executables { path := executable.Source.Path filename := filepath.Base(path) ext := filepath.Ext(filename) genName := filename[:len(filename)-len(ext)] if genName == name { compiler, data, _, err := getFile(&executable.Source) PanicIf(err, "Generator error: %s", err) p.Generators[genName] = &model.Generator{ Name: genName, Language: compiler.Name, SourceCode: string(data), OutputFile: "*STDOUT", } return p.Generators[genName] } } return nil } p.Tests = make([]model.Test, len(problem.Judging.TestSet.Tests)) for i, test := range problem.Judging.TestSet.Tests { switch test.Method { case "manual": path := fmt.Sprintf(problem.Judging.TestSet.InputPathPattern, i+1) data, err := archive.ReadFile(path) PanicIf(err, "Cannot read test %d", i+1) p.Tests[i].Input = model.ConstTestData(data) case "generated": parts := strings.SplitN(test.Command, " ", 2) params := "" if len(parts) == 2 { params = parts[1] } generator := getGenerator(parts[0]) PanicIf(generator == nil, "Unknown generator %s for test %d", parts[0], i+1) p.Tests[i].Input = &model.GeneratedInput{ Generator: generator.Name, Parameters: params, } default: Panic("Unknown test method %s", test.Method) } if mainSolution != nil { p.Tests[i].Output = &model.SolutionOutput{ Solution: mainSolution.Name, } } } if checker := problem.Assets.Checker; checker != nil { compiler, data, _, err := getFile(&checker.Source) PanicIf(err, "Solution error: %s", err) p.Checker = &model.Checker{ Style: "testlib", Language: compiler.Name, SourceCode: string(data), } } for _, statement := range problem.Statements { if statement.Format == "tex" && statement.Language == problem.Names[0].Language { importStatement(archive, p, &statement) break } } 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 }