<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetManager.cpp
 */

#include "./JPetManager.h"

#include <cassert>
#include <string>
#include <exception>

#include "../JPetLoggerInclude.h"
#include "../JPetCommonTools/JPetCommonTools.h"
#include "../DBHandler/HeaderFiles/DBHandler.h"
#include "../JPetCmdParser/JPetCmdParser.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetUnzipAndUnpackTask/JPetUnzipAndUnpackTask.h"
#include "../JPetOptionsGenerator/JPetOptionsGenerator.h"

#include <TThread.h>

using namespace jpet_options_tools;

JPetManager::JPetManager()
{
  fTaskGeneratorChain = new TaskGeneratorChain;
}

JPetManager& JPetManager::getManager()
{
  static JPetManager instance;
  return instance;
}

bool JPetManager::areThreadsEnabled() const
{
  return fThreadsEnabled;
}

void JPetManager::setThreadsEnabled(bool enable)
{
  fThreadsEnabled = enable;
}

bool JPetManager::run(int argc, const char** argv)
{
  if (!parseCmdLine(argc, argv)) {
    ERROR("While parsing command line arguments");
    return false;
  }
  INFO( "======== Starting processing all tasks: " + JPetCommonTools::getTimeString() + " ========\n" );
  std::vector<JPetTaskChainExecutor*> executors;
  std::vector<TThread*> threads;
  auto inputDataSeq = 0;
  /// For every input option, new TaskChainExecutor is created, which creates the chain of previously
  /// registered tasks. The inputDataSeq is the identifier of given chain.
  for (auto opt : fOptions) {
    JPetTaskChainExecutor* executor = new JPetTaskChainExecutor(fTaskGeneratorChain, inputDataSeq, opt.second);
    executors.push_back(executor);
    if (areThreadsEnabled()) {
      auto thr = executor->run();
      if (thr) {
        threads.push_back(thr);
      } else {
        ERROR("thread pointer is null");
      }
    } else {
      if (!executor->process()) {
        ERROR("While running process");
        return false;
      }
    }
    inputDataSeq++;
  }
  if (areThreadsEnabled()) {
    for (auto thread : threads) {
      assert(thread);
      thread->Join();
    }
  }
  for (auto& executor : executors) {
    if (executor) {
      delete executor;
      executor = 0;
    }
  }
  INFO( "======== Finished processing all tasks: " + JPetCommonTools::getTimeString() + " ========\n" );
  return true;
}

bool JPetManager::parseCmdLine(int argc, const char** argv)
{
  auto addDefaultTasksFromOptions = [&](const std::map<std::string, boost::any>& options) {
    auto fileType = FileTypeChecker::getInputFileType(options);
    if (fileType == FileTypeChecker::kScope) {
      auto task2 = []() {
        return new JPetScopeLoader(std::unique_ptr<JPetScopeTask>(new JPetScopeTask("JPetScopeReader")));
      };
      fTaskGeneratorChain->insert(fTaskGeneratorChain->begin(), task2);
    }
    /// add task to unzip or unpack if needed
    auto task = []() {
      return new JPetUnzipAndUnpackTask("UnpackerAndUnzipper");
    };
    fTaskGeneratorChain->insert(fTaskGeneratorChain->begin(), task);
  };

  try {
    JPetOptionsGenerator optionsGenerator;
    JPetCmdParser parser;
    auto optionsFromCmdLine = parser.parseCmdLineArgs(argc, argv);
    /// One  common map of all options
    auto allValidatedOptions = optionsGenerator.generateAndValidateOptions(optionsFromCmdLine);
    addDefaultTasksFromOptions(allValidatedOptions);

    int numberOfRegisteredTasks = 1;
    if (fTaskGeneratorChain) {
      numberOfRegisteredTasks = fTaskGeneratorChain->size();
    }
    fOptions  = optionsGenerator.generateOptionsForTasks(allValidatedOptions, numberOfRegisteredTasks);
  } catch (std::exception& e) {
    ERROR(e.what());
    return false;
  }
  return true;
}

//
JPetManager::~JPetManager()
{
  /// delete shared caches for paramBanks
  /// @todo I think that should be changed
  JPetDBParamGetter::clearParamCache();
}

void JPetManager::useTask(const char* name, const char* inputFileType, const char* outputFileType){
  assert(fTaskGeneratorChain);
  if( fTasksDictionary.count(name) > 0 ){
    TaskGenerator userTaskGen = fTasksDictionary.at(name);
    // wrap the JPetUserTask-based task in a JPetTaskIO
    fTaskGeneratorChain->push_back( [name, inputFileType, outputFileType, userTaskGen]() {
	JPetTaskIO * task = new JPetTaskIO(name, inputFileType, outputFileType);
	task->setSubTask(std::unique_ptr<JPetTaskInterface>(userTaskGen()));
	return task;
      });
  }else{
    ERROR(Form("The requested task %s is unknown", name));
    exit(1);
  }
}

JPetManager::Options JPetManager::getOptions() const
{
  return fOptions;
}

/**
 * @brief Initialize connection to database if such connection is necessary
 *
 * @param configFilePath path to the config file with database connection details
 *
 * @return true if database connection was required and initialization was called,
 * false if database connection was not required and its initialization was skipped
 *
 * Database connection is only initialized if the user provided the run number
 * ("-i" option) and did not provide local database ("-l") at the same time.
 */
bool JPetManager::initDBConnection(const char* configFilePath)
{
  bool isDBrequired = false;

  if (fOptions.size() > 0) { // If at least one input file to process.
    auto optsVect = fOptions.begin()->second;
    if (optsVect.size() > 0) {
      auto opt = optsVect.front();
      if (getRunNumber(opt) >= 0) { // if run number is not default -1
        if (!isLocalDB(opt)) { // unless local DB file was provided
          isDBrequired = true;
        }
      }
    }
  }
  if (isDBrequired) {
    INFO("Attempting to set up connection to the database.");
    DB::SERVICES::DBHandler::createDBConnection(configFilePath);
  } else {
    INFO("Setting connection to database skipped.");
  }
  return isDBrequired;
}
<commit_msg>Adapt adding task in JPetManager to multiple subtasks version<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetManager.cpp
 */

#include "./JPetManager.h"

#include <cassert>
#include <string>
#include <exception>

#include "../JPetLoggerInclude.h"
#include "../JPetCommonTools/JPetCommonTools.h"
#include "../DBHandler/HeaderFiles/DBHandler.h"
#include "../JPetCmdParser/JPetCmdParser.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetUnzipAndUnpackTask/JPetUnzipAndUnpackTask.h"
#include "../JPetOptionsGenerator/JPetOptionsGenerator.h"

#include <TThread.h>

using namespace jpet_options_tools;

JPetManager::JPetManager()
{
  fTaskGeneratorChain = new TaskGeneratorChain;
}

JPetManager& JPetManager::getManager()
{
  static JPetManager instance;
  return instance;
}

bool JPetManager::areThreadsEnabled() const
{
  return fThreadsEnabled;
}

void JPetManager::setThreadsEnabled(bool enable)
{
  fThreadsEnabled = enable;
}

bool JPetManager::run(int argc, const char** argv)
{
  if (!parseCmdLine(argc, argv)) {
    ERROR("While parsing command line arguments");
    return false;
  }
  INFO( "======== Starting processing all tasks: " + JPetCommonTools::getTimeString() + " ========\n" );
  std::vector<JPetTaskChainExecutor*> executors;
  std::vector<TThread*> threads;
  auto inputDataSeq = 0;
  /// For every input option, new TaskChainExecutor is created, which creates the chain of previously
  /// registered tasks. The inputDataSeq is the identifier of given chain.
  for (auto opt : fOptions) {
    JPetTaskChainExecutor* executor = new JPetTaskChainExecutor(fTaskGeneratorChain, inputDataSeq, opt.second);
    executors.push_back(executor);
    if (areThreadsEnabled()) {
      auto thr = executor->run();
      if (thr) {
        threads.push_back(thr);
      } else {
        ERROR("thread pointer is null");
      }
    } else {
      if (!executor->process()) {
        ERROR("While running process");
        return false;
      }
    }
    inputDataSeq++;
  }
  if (areThreadsEnabled()) {
    for (auto thread : threads) {
      assert(thread);
      thread->Join();
    }
  }
  for (auto& executor : executors) {
    if (executor) {
      delete executor;
      executor = 0;
    }
  }
  INFO( "======== Finished processing all tasks: " + JPetCommonTools::getTimeString() + " ========\n" );
  return true;
}

bool JPetManager::parseCmdLine(int argc, const char** argv)
{
  auto addDefaultTasksFromOptions = [&](const std::map<std::string, boost::any>& options) {
    auto fileType = FileTypeChecker::getInputFileType(options);
    if (fileType == FileTypeChecker::kScope) {
      auto task2 = []() {
        return new JPetScopeLoader(std::unique_ptr<JPetScopeTask>(new JPetScopeTask("JPetScopeReader")));
      };
      fTaskGeneratorChain->insert(fTaskGeneratorChain->begin(), task2);
    }
    /// add task to unzip or unpack if needed
    auto task = []() {
      return new JPetUnzipAndUnpackTask("UnpackerAndUnzipper");
    };
    fTaskGeneratorChain->insert(fTaskGeneratorChain->begin(), task);
  };

  try {
    JPetOptionsGenerator optionsGenerator;
    JPetCmdParser parser;
    auto optionsFromCmdLine = parser.parseCmdLineArgs(argc, argv);
    /// One  common map of all options
    auto allValidatedOptions = optionsGenerator.generateAndValidateOptions(optionsFromCmdLine);
    addDefaultTasksFromOptions(allValidatedOptions);

    int numberOfRegisteredTasks = 1;
    if (fTaskGeneratorChain) {
      numberOfRegisteredTasks = fTaskGeneratorChain->size();
    }
    fOptions  = optionsGenerator.generateOptionsForTasks(allValidatedOptions, numberOfRegisteredTasks);
  } catch (std::exception& e) {
    ERROR(e.what());
    return false;
  }
  return true;
}

//
JPetManager::~JPetManager()
{
  /// delete shared caches for paramBanks
  /// @todo I think that should be changed
  JPetDBParamGetter::clearParamCache();
}

void JPetManager::useTask(const char* name, const char* inputFileType, const char* outputFileType){
  assert(fTaskGeneratorChain);
  if( fTasksDictionary.count(name) > 0 ){
    TaskGenerator userTaskGen = fTasksDictionary.at(name);
    // wrap the JPetUserTask-based task in a JPetTaskIO
    fTaskGeneratorChain->push_back( [name, inputFileType, outputFileType, userTaskGen]() {
	JPetTaskIO * task = new JPetTaskIO(name, inputFileType, outputFileType);
	task->addSubTask(std::unique_ptr<JPetTaskInterface>(userTaskGen()));
	return task;
      });
  }else{
    ERROR(Form("The requested task %s is unknown", name));
    exit(1);
  }
}

JPetManager::Options JPetManager::getOptions() const
{
  return fOptions;
}

/**
 * @brief Initialize connection to database if such connection is necessary
 *
 * @param configFilePath path to the config file with database connection details
 *
 * @return true if database connection was required and initialization was called,
 * false if database connection was not required and its initialization was skipped
 *
 * Database connection is only initialized if the user provided the run number
 * ("-i" option) and did not provide local database ("-l") at the same time.
 */
bool JPetManager::initDBConnection(const char* configFilePath)
{
  bool isDBrequired = false;

  if (fOptions.size() > 0) { // If at least one input file to process.
    auto optsVect = fOptions.begin()->second;
    if (optsVect.size() > 0) {
      auto opt = optsVect.front();
      if (getRunNumber(opt) >= 0) { // if run number is not default -1
        if (!isLocalDB(opt)) { // unless local DB file was provided
          isDBrequired = true;
        }
      }
    }
  }
  if (isDBrequired) {
    INFO("Attempting to set up connection to the database.");
    DB::SERVICES::DBHandler::createDBConnection(configFilePath);
  } else {
    INFO("Setting connection to database skipped.");
  }
  return isDBrequired;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkQuadEdgeTest1.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "itkQuadEdge.h"
#include <iostream>

int itkQuadEdgeTest1( int , char* [] )
{
  typedef itk::QuadEdge        QuadEdgeType;

  // Tests for the GetRot() SetRot() methods
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  const QuadEdgeType * quadEdge1c = quadEdge1;

  quadEdge1->GetRot(); // testing null case

  // Verify that it can be set.
  quadEdge1->SetRot( quadEdge2 );
  if( quadEdge1->GetRot() != quadEdge2 )
    {
    std::cerr << "Error in SetRot() / GetRot() " << std::endl;
    return EXIT_FAILURE;
    }
  // Test the const version
  if( quadEdge1c->GetRot() != quadEdge2 )
    {
    std::cerr << "Error in const GetRot() " << std::endl;
    return EXIT_FAILURE;
    }

  // Verify that it can be changed.
  quadEdge1->SetRot( quadEdge3 );
  if( quadEdge1->GetRot() != quadEdge3 )
    {
    std::cerr << "Error in changing SetRot() / GetRot() " << std::endl;
    return EXIT_FAILURE;
    }
  // Test the const version
  if( quadEdge1c->GetRot() != quadEdge3 )
    {
    std::cerr << "Error in changed const GetRot() " << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "GetRot()/SetRot() Test passed ! " << std::endl;
  std::cout << "Test passed" << std::endl;

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  } // end of local scope for tests

  // Tests for the GetOnext() SetOnext() methods
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  const QuadEdgeType * quadEdge1c = quadEdge1;

  quadEdge1->GetOnext(); // testing null case

  // Verify that it can be set.
  quadEdge1->SetOnext( quadEdge2 );
  if( quadEdge1->GetOnext() != quadEdge2 )
    {
    std::cerr << "Error in SetOnext() / GetOnext() " << std::endl;
    return EXIT_FAILURE;
    }
  // Test the const version
  if( quadEdge1c->GetOnext() != quadEdge2 )
    {
    std::cerr << "Error in const GetOnext() " << std::endl;
    return EXIT_FAILURE;
    }

  // Verify that it can be changed.
  quadEdge1->SetOnext( quadEdge3 );
  if( quadEdge1->GetOnext() != quadEdge3 )
    {
    std::cerr << "Error in changing SetOnext() / GetOnext() " << std::endl;
    return EXIT_FAILURE;
    }
  // Test the const version
  if( quadEdge1c->GetOnext() != quadEdge3 )
    {
    std::cerr << "Error changed const GetOnext() " << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "GetOnext()/SetOnext() Test passed ! " << std::endl;

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  } // end of local scope for tests

  // Tests for the GetSym() methods
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  QuadEdgeType * quadEdge4 = new QuadEdgeType;
  const QuadEdgeType * quadEdge1c = quadEdge1;
  const QuadEdgeType * quadEdge2c = quadEdge2;
  const QuadEdgeType * quadEdge3c = quadEdge3;
  const QuadEdgeType * quadEdge4c = quadEdge4;

  quadEdge1->GetSym(); // testing null case

  quadEdge1->SetRot( quadEdge2 );
  quadEdge2->SetRot( quadEdge3 );
  quadEdge3->SetRot( quadEdge4 );
  quadEdge4->SetRot( quadEdge1 );

  if( quadEdge1->GetSym() != quadEdge3 )
    {
    std::cerr << "Error in GetSym() " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge1c->GetSym() != quadEdge3 )
    {
    std::cerr << "Error in const GetSym() " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge2->GetSym() != quadEdge4 )
    {
    std::cerr << "Error in GetSym() B " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge2c->GetSym() != quadEdge4 )
    {
    std::cerr << "Error in const GetSym() B" << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge3->GetSym() != quadEdge1 )
    {
    std::cerr << "Error in GetSym() C " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge3c->GetSym() != quadEdge1 )
    {
    std::cerr << "Error in const GetSym() C" << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge4->GetSym() != quadEdge2 )
    {
    std::cerr << "Error in GetSym() D " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge4c->GetSym() != quadEdge2 )
    {
    std::cerr << "Error in const GetSym() D" << std::endl;
    return EXIT_FAILURE;
    }

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  delete quadEdge4;

  std::cout << "GetSym() Test passed ! " << std::endl;
  }

  // Tests for the GetLnext() methods
  // returns the next edge with same left face
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  QuadEdgeType * quadEdge4 = new QuadEdgeType;
  QuadEdgeType * quadEdgeA = new QuadEdgeType;
  QuadEdgeType * quadEdgeB = new QuadEdgeType;
  const QuadEdgeType * quadEdge1c = quadEdge1;

  quadEdge1->GetLnext(); // testing null case

  //                        /
  //                       / quadEdgeA
  //          Face        /
  //                     /
  //                    /
  //   --------------->O
  //   quadEdge1
  //

  quadEdgeB->SetRot( quadEdgeA );
  quadEdge4->SetOnext( quadEdgeB );

  quadEdge1->SetRot( quadEdge2 );
  quadEdge2->SetRot( quadEdge3 );
  quadEdge3->SetRot( quadEdge4 );
  quadEdge4->SetRot( quadEdge1 );

  if( quadEdge1->GetLnext() != quadEdgeA )
    {
    std::cerr << "Error in GetLnext()" << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge1c->GetLnext() != quadEdgeA )
    {
    std::cerr << "Error in const GetLnext()" << std::endl;
    return EXIT_FAILURE;
    }

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  delete quadEdge4;
  delete quadEdgeA;
  delete quadEdgeB;

  std::cout << "GetLnext() Test passed ! " << std::endl;
  }

  return EXIT_SUCCESS;
}

<commit_msg>ENH: Test for the GetRnext() method added.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkQuadEdgeTest1.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "itkQuadEdge.h"
#include <iostream>

int itkQuadEdgeTest1( int , char* [] )
{
  typedef itk::QuadEdge        QuadEdgeType;

  // Tests for the GetRot() SetRot() methods
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  const QuadEdgeType * quadEdge1c = quadEdge1;

  quadEdge1->GetRot(); // testing null case

  // Verify that it can be set.
  quadEdge1->SetRot( quadEdge2 );
  if( quadEdge1->GetRot() != quadEdge2 )
    {
    std::cerr << "Error in SetRot() / GetRot() " << std::endl;
    return EXIT_FAILURE;
    }
  // Test the const version
  if( quadEdge1c->GetRot() != quadEdge2 )
    {
    std::cerr << "Error in const GetRot() " << std::endl;
    return EXIT_FAILURE;
    }

  // Verify that it can be changed.
  quadEdge1->SetRot( quadEdge3 );
  if( quadEdge1->GetRot() != quadEdge3 )
    {
    std::cerr << "Error in changing SetRot() / GetRot() " << std::endl;
    return EXIT_FAILURE;
    }
  // Test the const version
  if( quadEdge1c->GetRot() != quadEdge3 )
    {
    std::cerr << "Error in changed const GetRot() " << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "GetRot()/SetRot() Test passed ! " << std::endl;
  std::cout << "Test passed" << std::endl;

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  } // end of local scope for tests

  // Tests for the GetOnext() SetOnext() methods
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  const QuadEdgeType * quadEdge1c = quadEdge1;

  quadEdge1->GetOnext(); // testing null case

  // Verify that it can be set.
  quadEdge1->SetOnext( quadEdge2 );
  if( quadEdge1->GetOnext() != quadEdge2 )
    {
    std::cerr << "Error in SetOnext() / GetOnext() " << std::endl;
    return EXIT_FAILURE;
    }
  // Test the const version
  if( quadEdge1c->GetOnext() != quadEdge2 )
    {
    std::cerr << "Error in const GetOnext() " << std::endl;
    return EXIT_FAILURE;
    }

  // Verify that it can be changed.
  quadEdge1->SetOnext( quadEdge3 );
  if( quadEdge1->GetOnext() != quadEdge3 )
    {
    std::cerr << "Error in changing SetOnext() / GetOnext() " << std::endl;
    return EXIT_FAILURE;
    }
  // Test the const version
  if( quadEdge1c->GetOnext() != quadEdge3 )
    {
    std::cerr << "Error changed const GetOnext() " << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "GetOnext()/SetOnext() Test passed ! " << std::endl;

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  } // end of local scope for tests

  // Tests for the GetSym() methods
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  QuadEdgeType * quadEdge4 = new QuadEdgeType;
  const QuadEdgeType * quadEdge1c = quadEdge1;
  const QuadEdgeType * quadEdge2c = quadEdge2;
  const QuadEdgeType * quadEdge3c = quadEdge3;
  const QuadEdgeType * quadEdge4c = quadEdge4;

  quadEdge1->GetSym(); // testing null case

  quadEdge1->SetRot( quadEdge2 );
  quadEdge2->SetRot( quadEdge3 );
  quadEdge3->SetRot( quadEdge4 );
  quadEdge4->SetRot( quadEdge1 );

  if( quadEdge1->GetSym() != quadEdge3 )
    {
    std::cerr << "Error in GetSym() " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge1c->GetSym() != quadEdge3 )
    {
    std::cerr << "Error in const GetSym() " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge2->GetSym() != quadEdge4 )
    {
    std::cerr << "Error in GetSym() B " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge2c->GetSym() != quadEdge4 )
    {
    std::cerr << "Error in const GetSym() B" << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge3->GetSym() != quadEdge1 )
    {
    std::cerr << "Error in GetSym() C " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge3c->GetSym() != quadEdge1 )
    {
    std::cerr << "Error in const GetSym() C" << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge4->GetSym() != quadEdge2 )
    {
    std::cerr << "Error in GetSym() D " << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge4c->GetSym() != quadEdge2 )
    {
    std::cerr << "Error in const GetSym() D" << std::endl;
    return EXIT_FAILURE;
    }

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  delete quadEdge4;

  std::cout << "GetSym() Test passed ! " << std::endl;
  }

  // Tests for the GetLnext() methods
  // returns the next edge with same left face
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  QuadEdgeType * quadEdge4 = new QuadEdgeType;
  QuadEdgeType * quadEdgeA = new QuadEdgeType;
  QuadEdgeType * quadEdgeB = new QuadEdgeType;
  const QuadEdgeType * quadEdge1c = quadEdge1;

  quadEdge1->GetLnext(); // testing null case

  //                        /
  //                       / quadEdgeA
  //          Face        /
  //                     /
  //                    /
  //   --------------->O
  //   quadEdge1
  //

  quadEdgeB->SetRot( quadEdgeA );
  quadEdge4->SetOnext( quadEdgeB );

  quadEdge1->SetRot( quadEdge2 );
  quadEdge2->SetRot( quadEdge3 );
  quadEdge3->SetRot( quadEdge4 );
  quadEdge4->SetRot( quadEdge1 );

  if( quadEdge1->GetLnext() != quadEdgeA )
    {
    std::cerr << "Error in GetLnext()" << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdge1c->GetLnext() != quadEdgeA )
    {
    std::cerr << "Error in const GetLnext()" << std::endl;
    return EXIT_FAILURE;
    }

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  delete quadEdge4;
  delete quadEdgeA;
  delete quadEdgeB;

  std::cout << "GetLnext() Test passed ! " << std::endl;
  }

  // Tests for the GetRnext() methods
  // returns the next edge with same left face
  { // create a local scope for these tests
  QuadEdgeType * quadEdge1 = new QuadEdgeType;
  QuadEdgeType * quadEdge2 = new QuadEdgeType;
  QuadEdgeType * quadEdge3 = new QuadEdgeType;
  QuadEdgeType * quadEdge4 = new QuadEdgeType;
  QuadEdgeType * quadEdgeA = new QuadEdgeType;
  QuadEdgeType * quadEdgeB = new QuadEdgeType;
  const QuadEdgeType * quadEdgeAc = quadEdgeA;

  quadEdge1->GetRnext(); // testing null case

  //
  //        quadEdge1
  //   --------------------->O
  //                        /
  //                       /
  //          Face        /
  //                     /quadEdgeA
  //                    /
  //

  quadEdgeA->SetRot( quadEdgeB );
  quadEdgeB->SetOnext( quadEdge2 );

  quadEdge1->SetRot( quadEdge2 );
  quadEdge2->SetRot( quadEdge3 );
  quadEdge3->SetRot( quadEdge4 );
  quadEdge4->SetRot( quadEdge1 );

  if( quadEdgeA->GetRnext() != quadEdge1 )
    {
    std::cerr << "Error in GetRnext()" << std::endl;
    return EXIT_FAILURE;
    }

  if( quadEdgeAc->GetRnext() != quadEdge1 )
    {
    std::cerr << "Error in const GetRnext()" << std::endl;
    return EXIT_FAILURE;
    }

  delete quadEdge1;
  delete quadEdge2;
  delete quadEdge3;
  delete quadEdge4;
  delete quadEdgeA;
  delete quadEdgeB;

  std::cout << "GetRnext() Test passed ! " << std::endl;
  }

  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>/**
 * File    : A.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-11-10 15:20:13
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, M, L;
string S[500];
string T[29];

void input()
{
  cin >> N >> M >> L;
  for (auto i = 0; i < N; i++)
  {
    cin >> S[i];
  }
}

void make_wall()
{
  string wall = "";
  for (auto i = 0; i < M; i++)
  {
    wall += "#";
  }
  for (auto i = 0; i < M; i++)
  {
    T[i] = wall;
  }
  T[14][14] = '.';
}

void flush()
{
  for (auto i = 0; i < M; i++)
  {
    cout << T[i] << endl;
  }
}

int main()
{
  input();
  make_wall();
  flush();
}<commit_msg>submit A.cpp to 'A - ばらばらロボット' (future-contest-2019-qual) [C++14 (GCC 5.4.1)]<commit_after>/**
 * File    : A.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-11-10 15:20:13
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, M, L;
string S[500];
string T[29];

void input()
{
  cin >> N >> M >> L;
  for (auto i = 0; i < N; i++)
  {
    cin >> S[i];
  }
}

void make_wall()
{
  string wall = "";
  for (auto i = 0; i < M; i++)
  {
    wall += "#";
  }
  for (auto i = 0; i < M; i++)
  {
    T[i] = wall;
  }
  T[14][14] = '.';
}

void flush()
{
  for (auto i = 0; i < M; i++)
  {
    cout << T[i] << endl;
  }
}

void solve()
{
  for (auto i = M / 2; i < M / 2 + 10; i++)
  {
    T[i][M / 2] = '.';
  }
}

int main()
{
  input();
  make_wall();
  solve();
  flush();
}<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <set>

#include <bh_component.h>
#include <bh.h>

using namespace std;

float_t bh_get_value(bh_constant constant)
{
    switch(constant.type) {
        case BH_UINT8:
            return (float_t)constant.value.uint8;
        case BH_UINT16:
            return (float_t)constant.value.uint16;
        case BH_UINT32:
            return (float_t)constant.value.uint32;
        case BH_UINT64:
            return (float_t)constant.value.uint64;

        case BH_INT8:
            return (float_t)constant.value.int8;
        case BH_INT16:
            return (float_t)constant.value.int16;
        case BH_INT32:
            return (float_t)constant.value.int32;
        case BH_INT64:
            return (float_t)constant.value.int64;

        case BH_FLOAT32:
            return (float_t)constant.value.float32;
        case BH_FLOAT64:
            return (float_t)constant.value.float64;

        default:
            fprintf(stderr, "Don't know this type (%s) for collect filter.\n", bh_type_text(constant.type));
            return 0;
    }
}

void bh_set_value(bh_constant* constant, float_t value)
{
    switch(constant->type) {
        case BH_UINT8:
            constant->value.uint8 = (uint)value;
            break;
        case BH_UINT16:
            constant->value.uint16 = (uint)value;
            break;
        case BH_UINT32:
            constant->value.uint32 = (uint)value;
            break;
        case BH_UINT64:
            constant->value.uint64 = (uint)value;
            break;

        case BH_INT8:
            constant->value.int8 = (int)value;
            break;
        case BH_INT16:
            constant->value.int16 = (int)value;
            break;
        case BH_INT32:
            constant->value.int32 = (int)value;
            break;
        case BH_INT64:
            constant->value.int64 = (int)value;
            break;

        case BH_FLOAT32:
            constant->value.float32 = value;
            break;
        case BH_FLOAT64:
            constant->value.float64 = value;
            break;

        default:
            fprintf(stderr, "Can't set value for this type (%s) for collect filter.\n", bh_type_text(constant->type));
    }
}

bool is_add_sub(bh_opcode opc)
{
    return opc == BH_ADD or opc == BH_SUBTRACT;
}

bool is_mul_div(bh_opcode opc)
{
    return opc == BH_MULTIPLY or opc == BH_DIVIDE;
}

bool chain_has_same_type(vector<bh_instruction*>& chain)
{
    bh_type type = chain.front()->constant.type;
    for(vector<bh_instruction*>::iterator ite=chain.begin()+1; ite != chain.end(); ++ite) {
        if (type != (**ite).constant.type)
            return false;
    }
    return true;
}

void rewrite_chain_add_sub(vector<bh_instruction*>& chain)
{
    bh_instruction& first = *chain.front();
    bh_instruction& last = *chain.back();

    if (!chain_has_same_type(chain))
        return;

    switch (first.constant.type) {
        // Don't know how to do complex types, yet.
        case BH_BOOL:
        case BH_COMPLEX64:
        case BH_COMPLEX128:
            return;
    }

    float_t sum = 0.0;

    // Update first instruction's result base to last
    first.operand[0].base = last.operand[0].base;

    // Get first instructions value
    if (first.opcode == BH_ADD) {
        sum += bh_get_value(first.constant);
    } else {
        sum -= bh_get_value(first.constant);
    }

    // Loop through rest and accumulate value
    for(vector<bh_instruction*>::iterator ite=chain.begin()+1; ite != chain.end(); ++ite) {
        bh_instruction& rinstr = **ite;
        if (rinstr.opcode == BH_ADD) {
            sum += bh_get_value(rinstr.constant);
        } else {
            sum -= bh_get_value(rinstr.constant);
        }
        // Remove instruction
        rinstr.opcode = BH_NONE;
    }

    // We might have to reverse the original first opcode
    // If sum is below zero, we want to subtract
    if (sum < 0) {
        first.opcode = BH_SUBTRACT;
        sum = -sum;
    } else {
        first.opcode = BH_ADD;
    }

    // Set first instruction's new value
    bh_set_value(&(first.constant), sum);
}

void rewrite_chain_mul_div(vector<bh_instruction*>& chain)
{
    bh_instruction& first = *chain.front();
    bh_instruction& last = *chain.back();

    if (!chain_has_same_type(chain))
        return;

    switch (first.constant.type) {
        // Don't know how to do complex types, yet.
        case BH_BOOL:
        case BH_COMPLEX64:
        case BH_COMPLEX128:
            return;
    }

    float_t result = 1.0;

    // Update first instruction's result base to last
    first.operand[0].base = last.operand[0].base;

    // Get first instructions value
    if (first.opcode == BH_MULTIPLY) {
        result *= bh_get_value(first.constant);
    } else {
        result /= bh_get_value(first.constant);
    }

    // Loop through rest and accumulate value
    for(vector<bh_instruction*>::iterator ite=chain.begin()+1; ite != chain.end(); ++ite) {
        bh_instruction& rinstr = **ite;
        if (rinstr.opcode == BH_MULTIPLY) {
            result *= bh_get_value(rinstr.constant);
        } else {
            result /= bh_get_value(rinstr.constant);
        }
        // Remove instruction
        rinstr.opcode = BH_NONE;
    }

    // Set first instruction's new value
    bh_set_value(&(first.constant), result);
}

void rewrite_chain(vector<bh_instruction*>& chain)
{
    bh_opcode opc = chain[0]->opcode;
    if (is_add_sub(opc)) {
        rewrite_chain_add_sub(chain);
    } else if (is_mul_div(opc)) {
        rewrite_chain_mul_div(chain);
    }
}

void collect_filter(bh_ir &bhir)
{
    bh_opcode collect_opcode = BH_NONE;
    vector<bh_view*> views;
    vector<bh_instruction*> chain;

    for(size_t pc = 0; pc < bhir.instr_list.size(); ++pc) {
        bh_instruction& instr = bhir.instr_list[pc];

        if ((is_add_sub(instr.opcode) or is_mul_div(instr.opcode)) and bh_is_constant(&(instr.operand[2]))) {
            collect_opcode = instr.opcode;
            views.push_back(&instr.operand[0]);
            chain.push_back(&instr);

            for(size_t pc_chain = pc+1; pc_chain < bhir.instr_list.size(); ++pc_chain) {
                bh_instruction& other_instr = bhir.instr_list[pc_chain];

                if (is_add_sub(collect_opcode) and is_add_sub(other_instr.opcode) and bh_is_constant(&instr.operand[2])) {
                    // Both are ADD or SUBTRACT
                    if (*views.back() == other_instr.operand[1]) {
                        views.push_back(&other_instr.operand[0]);
                        chain.push_back(&other_instr);
                    }
                } else if (is_mul_div(collect_opcode) and is_mul_div(other_instr.opcode) and bh_is_constant(&instr.operand[2])) {
                    // Both are MULTIPLY or DIVIDE

                    // We are not allowed to DIVIDE when the result operand has integer type
                    if (bh_type_is_integer(other_instr.operand[0].base->type)) {
                        chain.clear();
                        views.clear();
                        break;
                    } else if (*views.back() == other_instr.operand[1]) {
                        views.push_back(&other_instr.operand[0]);
                        chain.push_back(&other_instr);
                    }
                } else {
                    bool is_none      = other_instr.opcode == BH_NONE;
                    bool is_freed     = other_instr.opcode == BH_FREE;
                    bool is_discarded = other_instr.opcode == BH_DISCARD;

                    if (is_none or is_freed or is_discarded) {
                        continue;
                    } else {
                        // Is not ADD, SUBTRACT, MULTIPLY, DIVIDE, NONE, FREE, DISCARD
                        // End chain
                        if (chain.size() > 1) {
                            rewrite_chain(chain);
                        }
                        // Reset
                        chain.clear();
                        views.clear();
                        break;
                    }
                }
            }
        }

        chain.clear();
        views.clear();
    }
}
<commit_msg>Rewrite if end of instruction list<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <set>

#include <bh_component.h>
#include <bh.h>

using namespace std;

float_t bh_get_value(bh_constant constant)
{
    switch(constant.type) {
        case BH_UINT8:
            return (float_t)constant.value.uint8;
        case BH_UINT16:
            return (float_t)constant.value.uint16;
        case BH_UINT32:
            return (float_t)constant.value.uint32;
        case BH_UINT64:
            return (float_t)constant.value.uint64;

        case BH_INT8:
            return (float_t)constant.value.int8;
        case BH_INT16:
            return (float_t)constant.value.int16;
        case BH_INT32:
            return (float_t)constant.value.int32;
        case BH_INT64:
            return (float_t)constant.value.int64;

        case BH_FLOAT32:
            return (float_t)constant.value.float32;
        case BH_FLOAT64:
            return (float_t)constant.value.float64;

        default:
            fprintf(stderr, "Don't know this type (%s) for collect filter.\n", bh_type_text(constant.type));
            return 0;
    }
}

void bh_set_value(bh_constant* constant, float_t value)
{
    switch(constant->type) {
        case BH_UINT8:
            constant->value.uint8 = (uint)value;
            break;
        case BH_UINT16:
            constant->value.uint16 = (uint)value;
            break;
        case BH_UINT32:
            constant->value.uint32 = (uint)value;
            break;
        case BH_UINT64:
            constant->value.uint64 = (uint)value;
            break;

        case BH_INT8:
            constant->value.int8 = (int)value;
            break;
        case BH_INT16:
            constant->value.int16 = (int)value;
            break;
        case BH_INT32:
            constant->value.int32 = (int)value;
            break;
        case BH_INT64:
            constant->value.int64 = (int)value;
            break;

        case BH_FLOAT32:
            constant->value.float32 = value;
            break;
        case BH_FLOAT64:
            constant->value.float64 = value;
            break;

        default:
            fprintf(stderr, "Can't set value for this type (%s) for collect filter.\n", bh_type_text(constant->type));
    }
}

bool is_add_sub(bh_opcode opc)
{
    return opc == BH_ADD or opc == BH_SUBTRACT;
}

bool is_mul_div(bh_opcode opc)
{
    return opc == BH_MULTIPLY or opc == BH_DIVIDE;
}

bool chain_has_same_type(vector<bh_instruction*>& chain)
{
    bh_type type = chain.front()->constant.type;
    for(vector<bh_instruction*>::iterator ite=chain.begin()+1; ite != chain.end(); ++ite) {
        if (type != (**ite).constant.type)
            return false;
    }
    return true;
}

void rewrite_chain_add_sub(vector<bh_instruction*>& chain)
{
    bh_instruction& first = *chain.front();
    bh_instruction& last = *chain.back();

    if (!chain_has_same_type(chain))
        return;

    switch (first.constant.type) {
        // Don't know how to do complex types, yet.
        case BH_BOOL:
        case BH_COMPLEX64:
        case BH_COMPLEX128:
            return;
    }

    float_t sum = 0.0;

    // Update first instruction's result base to last
    first.operand[0].base = last.operand[0].base;

    // Get first instructions value
    if (first.opcode == BH_ADD) {
        sum += bh_get_value(first.constant);
    } else {
        sum -= bh_get_value(first.constant);
    }

    // Loop through rest and accumulate value
    for(vector<bh_instruction*>::iterator ite=chain.begin()+1; ite != chain.end(); ++ite) {
        bh_instruction& rinstr = **ite;
        if (rinstr.opcode == BH_ADD) {
            sum += bh_get_value(rinstr.constant);
        } else {
            sum -= bh_get_value(rinstr.constant);
        }
        // Remove instruction
        rinstr.opcode = BH_NONE;
    }

    // We might have to reverse the original first opcode
    // If sum is below zero, we want to subtract
    if (sum < 0) {
        first.opcode = BH_SUBTRACT;
        sum = -sum;
    } else {
        first.opcode = BH_ADD;
    }

    // Set first instruction's new value
    bh_set_value(&(first.constant), sum);
}

void rewrite_chain_mul_div(vector<bh_instruction*>& chain)
{
    bh_instruction& first = *chain.front();
    bh_instruction& last = *chain.back();

    if (!chain_has_same_type(chain))
        return;

    switch (first.constant.type) {
        // Don't know how to do complex types, yet.
        case BH_BOOL:
        case BH_COMPLEX64:
        case BH_COMPLEX128:
            return;
    }

    float_t result = 1.0;

    // Update first instruction's result base to last
    first.operand[0].base = last.operand[0].base;

    // Get first instructions value
    if (first.opcode == BH_MULTIPLY) {
        result *= bh_get_value(first.constant);
    } else {
        result /= bh_get_value(first.constant);
    }

    // Loop through rest and accumulate value
    for(vector<bh_instruction*>::iterator ite=chain.begin()+1; ite != chain.end(); ++ite) {
        bh_instruction& rinstr = **ite;
        if (rinstr.opcode == BH_MULTIPLY) {
            result *= bh_get_value(rinstr.constant);
        } else {
            result /= bh_get_value(rinstr.constant);
        }
        // Remove instruction
        rinstr.opcode = BH_NONE;
    }

    // Set first instruction's new value
    bh_set_value(&(first.constant), result);
}

void rewrite_chain(vector<bh_instruction*>& chain)
{
    bh_opcode opc = chain[0]->opcode;
    if (is_add_sub(opc)) {
        rewrite_chain_add_sub(chain);
    } else if (is_mul_div(opc)) {
        rewrite_chain_mul_div(chain);
    }
}

void collect_filter(bh_ir &bhir)
{
    bh_opcode collect_opcode = BH_NONE;
    vector<bh_view*> views;
    vector<bh_instruction*> chain;

    for(size_t pc = 0; pc < bhir.instr_list.size(); ++pc) {
        bh_instruction& instr = bhir.instr_list[pc];

        if ((is_add_sub(instr.opcode) or is_mul_div(instr.opcode)) and bh_is_constant(&(instr.operand[2]))) {
            collect_opcode = instr.opcode;
            views.push_back(&instr.operand[0]);
            chain.push_back(&instr);

            for(size_t pc_chain = pc+1; pc_chain < bhir.instr_list.size(); ++pc_chain) {
                bh_instruction& other_instr = bhir.instr_list[pc_chain];

                if (is_add_sub(collect_opcode) and is_add_sub(other_instr.opcode) and bh_is_constant(&instr.operand[2])) {
                    // Both are ADD or SUBTRACT
                    if (*views.back() == other_instr.operand[1]) {
                        views.push_back(&other_instr.operand[0]);
                        chain.push_back(&other_instr);
                    }
                } else if (is_mul_div(collect_opcode) and is_mul_div(other_instr.opcode) and bh_is_constant(&instr.operand[2])) {
                    // Both are MULTIPLY or DIVIDE

                    // We are not allowed to DIVIDE when the result operand has integer type
                    if (bh_type_is_integer(other_instr.operand[0].base->type)) {
                        chain.clear();
                        views.clear();
                        break;
                    } else if (*views.back() == other_instr.operand[1]) {
                        views.push_back(&other_instr.operand[0]);
                        chain.push_back(&other_instr);
                    }
                } else {
                    bool is_none      = other_instr.opcode == BH_NONE;
                    bool is_freed     = other_instr.opcode == BH_FREE;
                    bool is_discarded = other_instr.opcode == BH_DISCARD;

                    if (is_none or is_freed or is_discarded) {
                        continue;
                    } else {
                        // Is not ADD, SUBTRACT, MULTIPLY, DIVIDE, NONE, FREE, DISCARD
                        // End chain
                        if (chain.size() > 1)
                            rewrite_chain(chain);

                        // Reset
                        chain.clear();
                        views.clear();
                        break;
                    }
                }
            }
        }

        // Rewrite if end of instruction list
        if (chain.size() > 1)
            rewrite_chain(chain);

        chain.clear();
        views.clear();
    }
}
<|endoftext|>


<commit_before>#ifndef PROJECT_DEFS
#define PROJECT_DEFS

#include <cmath>
#include <limits>
#include <map>
#include <string>

typedef double flt_type;
typedef unsigned short int fg_node_idx_t;
typedef unsigned int msfg_node_idx_t;
typedef unsigned char factor_pos_t;
typedef unsigned char factor_len_t;

typedef std::map<std::string, std::map<std::string, flt_type> > transitions_t;

static flt_type FLOOR_LP = -15.0;
static flt_type SMALL_LP = -100.0;
static flt_type MIN_FLOAT = -std::numeric_limits<flt_type>::max();
static unsigned int MAX_LINE_LEN = 5000;

// Return log(X+Y) where a=log(X) b=log(Y)
static flt_type add_log_domain_probs(flt_type a, flt_type b) {
    flt_type delta = a - b;
    if (delta > 0) {
      b = a;
      delta = -delta;
    }
    return b + log1p(exp(delta));
}

// Return log(X-Y) where a=log(X) b=log(Y)
static flt_type sub_log_domain_probs(flt_type a, flt_type b) {
    flt_type delta = b - a;
    if (delta > 0) {
      fprintf(stderr, "invalid call to sub_log_domain_probs, a should be bigger than b (a=%f,b=%f)\n",a,b);
      exit(1);
    }
    return a + log1p(-exp(delta));
}

static void trim(std::string &str, char to_trim)
{
    std::string::size_type pos = str.find_last_not_of(to_trim);
    if(pos != std::string::npos) {
        str.erase(pos + 1);
        pos = str.find_first_not_of(to_trim);
        if(pos != std::string::npos) str.erase(0, pos);
    }
    else str.erase(str.begin(), str.end());
}

#endif /* PROJECT_DEFS */

<commit_msg>Changed factor pos data type to 2 bytes to allow sentence processing.<commit_after>#ifndef PROJECT_DEFS
#define PROJECT_DEFS

#include <cmath>
#include <limits>
#include <map>
#include <string>

typedef double flt_type;
typedef unsigned short int fg_node_idx_t;
typedef unsigned int msfg_node_idx_t;
typedef unsigned short int factor_pos_t;
typedef unsigned char factor_len_t;

typedef std::map<std::string, std::map<std::string, flt_type> > transitions_t;

static flt_type FLOOR_LP = -15.0;
static flt_type SMALL_LP = -100.0;
static flt_type MIN_FLOAT = -std::numeric_limits<flt_type>::max();
static unsigned int MAX_LINE_LEN = 5000;

// Return log(X+Y) where a=log(X) b=log(Y)
static flt_type add_log_domain_probs(flt_type a, flt_type b) {
    flt_type delta = a - b;
    if (delta > 0) {
      b = a;
      delta = -delta;
    }
    return b + log1p(exp(delta));
}

// Return log(X-Y) where a=log(X) b=log(Y)
static flt_type sub_log_domain_probs(flt_type a, flt_type b) {
    flt_type delta = b - a;
    if (delta > 0) {
      fprintf(stderr, "invalid call to sub_log_domain_probs, a should be bigger than b (a=%f,b=%f)\n",a,b);
      exit(1);
    }
    return a + log1p(-exp(delta));
}

static void trim(std::string &str, char to_trim)
{
    std::string::size_type pos = str.find_last_not_of(to_trim);
    if(pos != std::string::npos) {
        str.erase(pos + 1);
        pos = str.find_first_not_of(to_trim);
        if(pos != std::string::npos) str.erase(0, pos);
    }
    else str.erase(str.begin(), str.end());
}

#endif /* PROJECT_DEFS */

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Object.hxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-21 15:07:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_
#define _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_

#if STLPORT_VERSION>=321
// jni.h needs cstdarg for std::va_list
#include <cstdarg>
#endif

#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif
#ifndef _COM_SUN_STAR_SDBC_SQLEXCEPTION_HPP_
#include <com/sun/star/sdbc/SQLException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef INCLUDED_JVMACCESS_VIRTUALMACHINE_HXX
#include <jvmaccess/virtualmachine.hxx>
#endif // INCLUDED_JVMACCESS_VIRTUALMACHINE_HXX
#include <memory>
#include <boost/shared_ptr.hpp>

//=====================================================================

#ifdef HAVE_64BIT_POINTERS
#error "no 64 bit pointer"
#else
#ifdef OS2
#define PVOID_TO_INT64(x) (jlong)(sal_Int32)x
#define INT64_TO_PVOID(x) (void *)x
#endif // OS2
#endif //HAVE_64BIT_POINTERS

namespace comphelper
{
    class ResourceBasedEventLogger;
}

namespace connectivity
{
    typedef ::boost::shared_ptr< jvmaccess::VirtualMachine::AttachGuard> TGuard;
    class SDBThreadAttach
    {
        jvmaccess::VirtualMachine::AttachGuard m_aGuard;
        SDBThreadAttach(SDBThreadAttach&);
    public:
        SDBThreadAttach();
        ~SDBThreadAttach();

        JNIEnv* pEnv;
        static void addRef();
        static void releaseRef();

    public:
        JNIEnv& env() const
        {
            // according to the documentation of jvmaccess::VirtualMachine::AttachGuard, our env is never
            // NULL, so why bothering with pointer checks?
            return *pEnv;
        }
    };
    //=====================================================================
    class java_lang_Class;
    class  java_lang_Object
    {
        // Zuweisungsoperator und Copy Konstruktor sind verboten
        java_lang_Object& operator = (java_lang_Object&) { return *this;};
        java_lang_Object(java_lang_Object&) {};

        static jclass getMyClass();
        // nur zum Zerstoeren des C++ Pointers in vom JSbxObject
        // abgeleiteten Java Objekten
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;

    protected:
        // der JAVA Handle zu dieser Klasse
        jobject object;
        // Klassendefinition

        // neu in SJ2:
        static jclass theClass;             // die Klasse braucht nur einmal angefordert werden !

    public:
        // der Konstruktor, der fuer die abgeleiteten Klassen verwendet
        // werden soll.
        java_lang_Object( JNIEnv * pEnv, jobject myObj );
        // der eigentliche Konstruktor
        java_lang_Object(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory=NULL);

        virtual ~java_lang_Object();

        void                saveRef( JNIEnv * pEnv, jobject myObj );
        jobject             getJavaObject() const { return object; }
        java_lang_Object *  GetWrapper() { return this; }
        void clearObject(JNIEnv& rEnv);
        void clearObject();

        java_lang_Class *   getClass();

        virtual ::rtl::OUString toString() const;
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getORB() { return m_xFactory; }

        static void ThrowSQLException(JNIEnv * pEnv,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> & _rContext);
        static void ThrowLoggedSQLException(
            const ::comphelper::ResourceBasedEventLogger& _rLogger,
            JNIEnv* pEnvironment,
            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContext
        );

        static ::rtl::Reference< jvmaccess::VirtualMachine > getVM(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory=NULL);
    };
}
#endif //_CONNECTIVITY_JAVA_LANG_OBJJECT_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.14.64); FILE MERGED 2008/04/01 15:09:13 thb 1.14.64.3: #i85898# Stripping all external header guards 2008/04/01 10:53:35 thb 1.14.64.2: #i85898# Stripping all external header guards 2008/03/28 15:24:27 rt 1.14.64.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: Object.hxx,v $
 * $Revision: 1.15 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_
#define _CONNECTIVITY_JAVA_LANG_OBJECT_HXX_

#if STLPORT_VERSION>=321
// jni.h needs cstdarg for std::va_list
#include <cstdarg>
#endif
#include <osl/thread.h>
#include <com/sun/star/sdbc/SQLException.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <osl/diagnose.h>
#include <jvmaccess/virtualmachine.hxx>
#include <memory>
#include <boost/shared_ptr.hpp>

//=====================================================================

#ifdef HAVE_64BIT_POINTERS
#error "no 64 bit pointer"
#else
#ifdef OS2
#define PVOID_TO_INT64(x) (jlong)(sal_Int32)x
#define INT64_TO_PVOID(x) (void *)x
#endif // OS2
#endif //HAVE_64BIT_POINTERS

namespace comphelper
{
    class ResourceBasedEventLogger;
}

namespace connectivity
{
    typedef ::boost::shared_ptr< jvmaccess::VirtualMachine::AttachGuard> TGuard;
    class SDBThreadAttach
    {
        jvmaccess::VirtualMachine::AttachGuard m_aGuard;
        SDBThreadAttach(SDBThreadAttach&);
    public:
        SDBThreadAttach();
        ~SDBThreadAttach();

        JNIEnv* pEnv;
        static void addRef();
        static void releaseRef();

    public:
        JNIEnv& env() const
        {
            // according to the documentation of jvmaccess::VirtualMachine::AttachGuard, our env is never
            // NULL, so why bothering with pointer checks?
            return *pEnv;
        }
    };
    //=====================================================================
    class java_lang_Class;
    class  java_lang_Object
    {
        // Zuweisungsoperator und Copy Konstruktor sind verboten
        java_lang_Object& operator = (java_lang_Object&) { return *this;};
        java_lang_Object(java_lang_Object&) {};

        static jclass getMyClass();
        // nur zum Zerstoeren des C++ Pointers in vom JSbxObject
        // abgeleiteten Java Objekten
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xFactory;

    protected:
        // der JAVA Handle zu dieser Klasse
        jobject object;
        // Klassendefinition

        // neu in SJ2:
        static jclass theClass;             // die Klasse braucht nur einmal angefordert werden !

    public:
        // der Konstruktor, der fuer die abgeleiteten Klassen verwendet
        // werden soll.
        java_lang_Object( JNIEnv * pEnv, jobject myObj );
        // der eigentliche Konstruktor
        java_lang_Object(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory=NULL);

        virtual ~java_lang_Object();

        void                saveRef( JNIEnv * pEnv, jobject myObj );
        jobject             getJavaObject() const { return object; }
        java_lang_Object *  GetWrapper() { return this; }
        void clearObject(JNIEnv& rEnv);
        void clearObject();

        java_lang_Class *   getClass();

        virtual ::rtl::OUString toString() const;
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > getORB() { return m_xFactory; }

        static void ThrowSQLException(JNIEnv * pEnv,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> & _rContext);
        static void ThrowLoggedSQLException(
            const ::comphelper::ResourceBasedEventLogger& _rLogger,
            JNIEnv* pEnvironment,
            const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxContext
        );

        static ::rtl::Reference< jvmaccess::VirtualMachine > getVM(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory=NULL);
    };
}
#endif //_CONNECTIVITY_JAVA_LANG_OBJJECT_HXX_

<|endoftext|>


<commit_before>#include "jpeg_encoder.h"

JpegEncoder::JpegEncoder(unsigned char *ddata, int wwidth, int hheight,
    int qquality, buffer_type bbuf_type) :
    data(ddata), width(wwidth), height(hheight), quality(qquality),
    buf_type(bbuf_type),
    jpeg(NULL), jpeg_len(0) {}

JpegEncoder::~JpegEncoder() {
    free(jpeg);
}

void
JpegEncoder::encode()
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_compress(&cinfo);
    jpeg_mem_dest(&cinfo, &jpeg, &jpeg_len);

    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    unsigned char *rgb_data;
    if (buf_type == BUF_RGBA) {
        rgb_data = rgba_to_rgb(data, width*height*4);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/rgba_to_rgb.";
    }
    else if (buf_type == BUF_BGRA) {
        rgb_data = bgra_to_rgb(data, width*height*4);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/bgra_to_rgb.";

    }
    else if (buf_type == BUF_BGR) {
        rgb_data = bgr_to_rgb(data, width*height*3);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/bgr_to_rgb.";
    }
    else if (buf_type == BUF_RGB) {
        rgb_data = data;
    }
    else {
        throw "Unknown buf_type";
    }

    JSAMPROW row_pointer;
    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer = &rgb_data[cinfo.next_scanline*3*width];
        jpeg_write_scanlines(&cinfo, &row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);

    if (buf_type == BUF_RGBA || buf_type == BUF_BGRA)
        free(rgb_data);
}

const unsigned char *
JpegEncoder::get_jpeg() const
{
    return jpeg;
}

unsigned int
JpegEncoder::get_jpeg_len() const
{
    return jpeg_len;
}
<commit_msg>i like this weird syntax better<commit_after>#include "jpeg_encoder.h"

JpegEncoder::JpegEncoder(unsigned char *ddata, int wwidth, int hheight,
    int qquality, buffer_type bbuf_type)
    :
    data(ddata), width(wwidth), height(hheight), quality(qquality),
    buf_type(bbuf_type),
    jpeg(NULL), jpeg_len(0) {}

JpegEncoder::~JpegEncoder() {
    free(jpeg);
}

void
JpegEncoder::encode()
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_compress(&cinfo);
    jpeg_mem_dest(&cinfo, &jpeg, &jpeg_len);

    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    unsigned char *rgb_data;
    if (buf_type == BUF_RGBA) {
        rgb_data = rgba_to_rgb(data, width*height*4);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/rgba_to_rgb.";
    }
    else if (buf_type == BUF_BGRA) {
        rgb_data = bgra_to_rgb(data, width*height*4);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/bgra_to_rgb.";

    }
    else if (buf_type == BUF_BGR) {
        rgb_data = bgr_to_rgb(data, width*height*3);
        if (!rgb_data) throw "malloc failed in JpegEncoder::encode/bgr_to_rgb.";
    }
    else if (buf_type == BUF_RGB) {
        rgb_data = data;
    }
    else {
        throw "Unknown buf_type";
    }

    JSAMPROW row_pointer;
    while (cinfo.next_scanline < cinfo.image_height) {
        row_pointer = &rgb_data[cinfo.next_scanline*3*width];
        jpeg_write_scanlines(&cinfo, &row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);

    if (buf_type == BUF_RGBA || buf_type == BUF_BGRA)
        free(rgb_data);
}

const unsigned char *
JpegEncoder::get_jpeg() const
{
    return jpeg;
}

unsigned int
JpegEncoder::get_jpeg_len() const
{
    return jpeg_len;
}
<|endoftext|>


<commit_before>/**
 * File    : A.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-11-10 15:20:13
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, M, L;
string S[500];
string T[29];

void input()
{
  cin >> N >> M >> L;
  for (auto i = 0; i < N; i++)
  {
    cin >> S[i];
  }
}

void make_wall()
{
  string wall = "";
  for (auto i = 0; i < M; i++)
  {
    wall += "#";
  }
  for (auto i = 0; i < M; i++)
  {
    T[i] = wall;
  }
  T[14][14] = '.';
}

void flush()
{
  for (auto i = 0; i < M; i++)
  {
    cout << T[i] << endl;
  }
}

void solve(int k)
{
  assert(1 <= k && k <= 13);
  for (auto i = 1; i <= k; i++)
  {
    for (auto t = 0; t < 4; t++)
    {
      int x = M / 2 + dx[t] * i;
      int y = M / 2 + dy[t] * i;
      T[x][y] = '.';
    }
  }
}

int main()
{
  input();
  make_wall();
  solve(8);
  flush();
}<commit_msg>submit A.cpp to 'A - ばらばらロボット' (future-contest-2019-qual) [C++14 (GCC 5.4.1)]<commit_after>/**
 * File    : A.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-11-10 15:20:13
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N, M, L;
string S[500];
string T[29];

void input()
{
  cin >> N >> M >> L;
  for (auto i = 0; i < N; i++)
  {
    cin >> S[i];
  }
}

void make_wall()
{
  string wall = "";
  for (auto i = 0; i < M; i++)
  {
    wall += "#";
  }
  for (auto i = 0; i < M; i++)
  {
    T[i] = wall;
  }
  T[14][14] = '.';
}

void flush()
{
  for (auto i = 0; i < M; i++)
  {
    cout << T[i] << endl;
  }
}

void solve(int k)
{
  assert(1 <= k && k <= 13);
  for (auto i = 1; i <= k; i++)
  {
    for (auto t = 0; t < 4; t++)
    {
      int x = M / 2 + dx[t] * i;
      int y = M / 2 + dy[t] * i;
      T[x][y] = '.';
    }
  }
}

int main()
{
  input();
  make_wall();
  solve(9);
  flush();
}<|endoftext|>


<commit_before>// File: lzham_task_pool_win32.cpp
// See Copyright Notice and license at the end of include/lzham.h
#include "lzham_core.h"
#include "lzham_win32_threading.h"
#include "lzham_timer.h"
#include <process.h>

#if LZHAM_USE_WIN32_API

namespace lzham
{
   task_pool::task_pool() :
      m_num_threads(0),
      m_tasks_available(0, 32767),
      m_num_outstanding_tasks(0),
      m_exit_flag(false)
   {
      utils::zero_object(m_threads);
   }

   task_pool::task_pool(uint num_threads) :
      m_num_threads(0),
      m_tasks_available(0, 32767),
      m_num_outstanding_tasks(0),
      m_exit_flag(false)
   {
      utils::zero_object(m_threads);

      bool status = init(num_threads);
      LZHAM_VERIFY(status);
   }

   task_pool::~task_pool()
   {
      deinit();
   }

   bool task_pool::init(uint num_threads)
   {
      LZHAM_ASSERT(num_threads <= cMaxThreads);
      num_threads = math::minimum<uint>(num_threads, cMaxThreads);

      deinit();

      bool succeeded = true;

      m_num_threads = 0;
      while (m_num_threads < num_threads)
      {
         m_threads[m_num_threads] = (HANDLE)_beginthreadex(NULL, 32768, thread_func, this, 0, NULL);
         LZHAM_ASSERT(m_threads[m_num_threads] != 0);

         if (!m_threads[m_num_threads])
         {
            succeeded = false;
            break;
         }

         m_num_threads++;
      }

      if (!succeeded)
      {
         deinit();
         return false;
      }

      return true;
   }

   void task_pool::deinit()
   {
      if (m_num_threads)
      {
         join();

         atomic_exchange32(&m_exit_flag, true);

         m_tasks_available.release(m_num_threads);

         for (uint i = 0; i < m_num_threads; i++)
         {
            if (m_threads[i])
            {
               for ( ; ; )
               {
                  DWORD result = WaitForSingleObject(m_threads[i], 30000);
                  if ((result == WAIT_OBJECT_0) || (result == WAIT_ABANDONED))
                     break;
               }

               CloseHandle(m_threads[i]);
               m_threads[i] = NULL;
            }
         }

         m_num_threads = 0;

         atomic_exchange32(&m_exit_flag, false);
      }

      m_task_stack.clear();
      m_num_outstanding_tasks = 0;
   }

   bool task_pool::queue_task(task_callback_func pFunc, uint64 data, void* pData_ptr)
   {
      LZHAM_ASSERT(m_num_threads);
      LZHAM_ASSERT(pFunc);

      task tsk;
      tsk.m_callback = pFunc;
      tsk.m_data = data;
      tsk.m_pData_ptr = pData_ptr;
      tsk.m_flags = 0;

      if (!m_task_stack.try_push(tsk))
         return false;

      atomic_increment32(&m_num_outstanding_tasks);

      m_tasks_available.release(1);

      return true;
   }

   // It's the object's responsibility to delete pObj within the execute_task() method, if needed!
   bool task_pool::queue_task(executable_task* pObj, uint64 data, void* pData_ptr)
   {
      LZHAM_ASSERT(m_num_threads);
      LZHAM_ASSERT(pObj);

      task tsk;
      tsk.m_pObj = pObj;
      tsk.m_data = data;
      tsk.m_pData_ptr = pData_ptr;
      tsk.m_flags = cTaskFlagObject;

      if (!m_task_stack.try_push(tsk))
         return false;

      atomic_increment32(&m_num_outstanding_tasks);

      m_tasks_available.release(1);

      return true;
   }

   void task_pool::process_task(task& tsk)
   {
      if (tsk.m_flags & cTaskFlagObject)
         tsk.m_pObj->execute_task(tsk.m_data, tsk.m_pData_ptr);
      else
         tsk.m_callback(tsk.m_data, tsk.m_pData_ptr);

      atomic_decrement32(&m_num_outstanding_tasks);
   }

   void task_pool::join()
   {
      while (atomic_add32(&m_num_outstanding_tasks, 0) > 0)
      {
         task tsk;
         if (m_task_stack.pop(tsk))
         {
            process_task(tsk);
         }
         else
         {
            lzham_sleep(1);
         }
      }
   }

   unsigned __stdcall task_pool::thread_func(void* pContext)
   {
      task_pool* pPool = static_cast<task_pool*>(pContext);

      for ( ; ; )
      {
         if (!pPool->m_tasks_available.wait())
            break;

         if (pPool->m_exit_flag)
            break;

         task tsk;
         if (pPool->m_task_stack.pop(tsk))
         {
            pPool->process_task(tsk);
         }
      }

      _endthreadex(0);
      return 0;
   }

   static uint g_num_processors;

   uint lzham_get_max_helper_threads()
   {
      if (!g_num_processors)
      {
         SYSTEM_INFO system_info;
         GetSystemInfo(&system_info);
         g_num_processors = system_info.dwNumberOfProcessors;
      }

      if (g_num_processors > 1)
      {
         // use all CPU's
         return LZHAM_MIN(task_pool::cMaxThreads, g_num_processors - 1);
      }

      return 0;
   }

} // namespace lzham

#endif // LZHAM_USE_WIN32_API
<commit_msg>that's it for linux<commit_after>// File: lzham_task_pool_win32.cpp
// See Copyright Notice and license at the end of include/lzham.h
#include "lzham_core.h"
#include "lzham_win32_threading.h"
#include "lzham_timer.h"

#if LZHAM_USE_WIN32_API

#include <process.h>

namespace lzham
{
   task_pool::task_pool() :
      m_num_threads(0),
      m_tasks_available(0, 32767),
      m_num_outstanding_tasks(0),
      m_exit_flag(false)
   {
      utils::zero_object(m_threads);
   }

   task_pool::task_pool(uint num_threads) :
      m_num_threads(0),
      m_tasks_available(0, 32767),
      m_num_outstanding_tasks(0),
      m_exit_flag(false)
   {
      utils::zero_object(m_threads);

      bool status = init(num_threads);
      LZHAM_VERIFY(status);
   }

   task_pool::~task_pool()
   {
      deinit();
   }

   bool task_pool::init(uint num_threads)
   {
      LZHAM_ASSERT(num_threads <= cMaxThreads);
      num_threads = math::minimum<uint>(num_threads, cMaxThreads);

      deinit();

      bool succeeded = true;

      m_num_threads = 0;
      while (m_num_threads < num_threads)
      {
         m_threads[m_num_threads] = (HANDLE)_beginthreadex(NULL, 32768, thread_func, this, 0, NULL);
         LZHAM_ASSERT(m_threads[m_num_threads] != 0);

         if (!m_threads[m_num_threads])
         {
            succeeded = false;
            break;
         }

         m_num_threads++;
      }

      if (!succeeded)
      {
         deinit();
         return false;
      }

      return true;
   }

   void task_pool::deinit()
   {
      if (m_num_threads)
      {
         join();

         atomic_exchange32(&m_exit_flag, true);

         m_tasks_available.release(m_num_threads);

         for (uint i = 0; i < m_num_threads; i++)
         {
            if (m_threads[i])
            {
               for ( ; ; )
               {
                  DWORD result = WaitForSingleObject(m_threads[i], 30000);
                  if ((result == WAIT_OBJECT_0) || (result == WAIT_ABANDONED))
                     break;
               }

               CloseHandle(m_threads[i]);
               m_threads[i] = NULL;
            }
         }

         m_num_threads = 0;

         atomic_exchange32(&m_exit_flag, false);
      }

      m_task_stack.clear();
      m_num_outstanding_tasks = 0;
   }

   bool task_pool::queue_task(task_callback_func pFunc, uint64 data, void* pData_ptr)
   {
      LZHAM_ASSERT(m_num_threads);
      LZHAM_ASSERT(pFunc);

      task tsk;
      tsk.m_callback = pFunc;
      tsk.m_data = data;
      tsk.m_pData_ptr = pData_ptr;
      tsk.m_flags = 0;

      if (!m_task_stack.try_push(tsk))
         return false;

      atomic_increment32(&m_num_outstanding_tasks);

      m_tasks_available.release(1);

      return true;
   }

   // It's the object's responsibility to delete pObj within the execute_task() method, if needed!
   bool task_pool::queue_task(executable_task* pObj, uint64 data, void* pData_ptr)
   {
      LZHAM_ASSERT(m_num_threads);
      LZHAM_ASSERT(pObj);

      task tsk;
      tsk.m_pObj = pObj;
      tsk.m_data = data;
      tsk.m_pData_ptr = pData_ptr;
      tsk.m_flags = cTaskFlagObject;

      if (!m_task_stack.try_push(tsk))
         return false;

      atomic_increment32(&m_num_outstanding_tasks);

      m_tasks_available.release(1);

      return true;
   }

   void task_pool::process_task(task& tsk)
   {
      if (tsk.m_flags & cTaskFlagObject)
         tsk.m_pObj->execute_task(tsk.m_data, tsk.m_pData_ptr);
      else
         tsk.m_callback(tsk.m_data, tsk.m_pData_ptr);

      atomic_decrement32(&m_num_outstanding_tasks);
   }

   void task_pool::join()
   {
      while (atomic_add32(&m_num_outstanding_tasks, 0) > 0)
      {
         task tsk;
         if (m_task_stack.pop(tsk))
         {
            process_task(tsk);
         }
         else
         {
            lzham_sleep(1);
         }
      }
   }

   unsigned __stdcall task_pool::thread_func(void* pContext)
   {
      task_pool* pPool = static_cast<task_pool*>(pContext);

      for ( ; ; )
      {
         if (!pPool->m_tasks_available.wait())
            break;

         if (pPool->m_exit_flag)
            break;

         task tsk;
         if (pPool->m_task_stack.pop(tsk))
         {
            pPool->process_task(tsk);
         }
      }

      _endthreadex(0);
      return 0;
   }

   static uint g_num_processors;

   uint lzham_get_max_helper_threads()
   {
      if (!g_num_processors)
      {
         SYSTEM_INFO system_info;
         GetSystemInfo(&system_info);
         g_num_processors = system_info.dwNumberOfProcessors;
      }

      if (g_num_processors > 1)
      {
         // use all CPU's
         return LZHAM_MIN(task_pool::cMaxThreads, g_num_processors - 1);
      }

      return 0;
   }

} // namespace lzham

#endif // LZHAM_USE_WIN32_API
<|endoftext|>