Beispiel #1
0
func (self *ProblemArchiveReader) LoadSolutions(problem *model.Problem, rePattern string) error {
	re, err := regexp.Compile(rePattern)
	if err != nil {
		return err
	}

	for _, file := range self.FileList() {
		match := re.FindStringSubmatch(file)
		if match != nil {
			ext := filepath.Ext(match[1])

			compiler := programs.GetCompilerByExt(ext)
			if compiler == nil {
				return fmt.Errorf("Unknown solution language %s", ext)
			}

			data, err := self.ReadFile(file)
			if err != nil {
				return err
			}

			problem.Solutions[match[1]] = &model.Solution{
				Name:       match[1],
				Language:   compiler.Name,
				SourceCode: string(data),
			}
		}
	}
	return nil
}
Beispiel #2
0
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
}