text:
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2018-2021 The SorachanCoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <db.h>
#include <txdb.h>
#include <init.h>
#include <miner.h>
#include <kernel.h>
#include <rpc/bitcoinrpc.h>
#include <block/block_process.h>
#include <miner/diff.h>
#include <block/block_alert.h>
#include <boost/format.hpp>
#include <util/strencodings.h>

json_spirit::Value CRPCTable::getsubsidy(const json_spirit::Array &params, CBitrpcData &data) {
    if (data.fHelp() || params.size() > 1) {
        return data.JSONRPCSuccess(
            "getsubsidy [nTarget]\n"
            "Returns proof-of-work subsidy value for the specified value of target.");
    }

    unsigned int nBits = 0;
    if (params.size() != 0) {
        json_spirit::json_flags status;
        std::string str = params[0].get_str(status);
        if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
        CBigNum bnTarget(uint256(str.c_str()));
        nBits = bnTarget.GetCompact();
    } else
        nBits = diff::spacing::GetNextTargetRequired(block_info::pindexBest, false);

    return data.JSONRPCSuccess((uint64_t)diff::reward::GetProofOfWorkReward(nBits));
}

json_spirit::Value CRPCTable::getmininginfo(const json_spirit::Array &params, CBitrpcData &data) {
    if (data.fHelp() || params.size() != 0) {
        return data.JSONRPCSuccess(
            "getmininginfo\n"
            "Returns an object containing mining-related information.");
    }

    json_spirit::Object obj, diff;
    obj.push_back(json_spirit::Pair("blocks", (int)block_info::nBestHeight));
    obj.push_back(json_spirit::Pair("currentblocksize", (uint64_t)block_info::nLastBlockSize));
    obj.push_back(json_spirit::Pair("currentblocktx", (uint64_t)block_info::nLastBlockTx));

    diff.push_back(json_spirit::Pair("proof-of-work", GetDifficulty()));
    diff.push_back(json_spirit::Pair("proof-of-stake", GetDifficulty(diff::spacing::GetLastBlockIndex(block_info::pindexBest, true))));
    diff.push_back(json_spirit::Pair("search-interval", (int)block_info::nLastCoinStakeSearchInterval));
    obj.push_back(json_spirit::Pair("difficulty", diff));

    obj.push_back(json_spirit::Pair("blockvalue", (uint64_t)diff::reward::GetProofOfWorkReward(diff::spacing::GetLastBlockIndex(block_info::pindexBest, false)->get_nBits())));
    obj.push_back(json_spirit::Pair("netmhashps", GetPoWMHashPS()));
    obj.push_back(json_spirit::Pair("netstakeweight", GetPoSKernelPS()));
    obj.push_back(json_spirit::Pair("errors", block_alert::GetWarnings("statusbar")));
    obj.push_back(json_spirit::Pair("pooledtx", (uint64_t)CTxMemPool::mempool.size()));

    obj.push_back(json_spirit::Pair("stakeinputs", (uint64_t)miner::nStakeInputsMapSize));
    obj.push_back(json_spirit::Pair("stakeinterest", diff::reward::GetProofOfStakeReward(0, diff::spacing::GetLastBlockIndex(block_info::pindexBest, true)->get_nBits(), diff::spacing::GetLastBlockIndex(block_info::pindexBest, true)->get_nTime(), true)));

    obj.push_back(json_spirit::Pair("testnet", (bool)args_bool::fTestNet));
    return data.JSONRPCSuccess(obj);
}

// scaninput '{"txid":"95d640426fe66de866a8cf2d0601d2c8cf3ec598109b4d4ffa7fd03dad6d35ce","difficulty":0.01, "days":10}'
json_spirit::Value CRPCTable::scaninput(const json_spirit::Array &params, CBitrpcData &data) {
    if (data.fHelp() || params.size() != 1) {
        return data.JSONRPCSuccess(
            "scaninput '{\"txid\":\"txid\", \"vout\":[vout1, vout2, ..., voutN], \"difficulty\":difficulty, \"days\":days}'\n"
            "Scan specified transaction or input for suitable kernel solutions.\n"
            "    difficulty - upper limit for difficulty, current difficulty by default;\n"
            "    days - time window, 90 days by default.\n"
        );
    }

    bitrpc::RPCTypeCheck(data, params, boost::assign::list_of(json_spirit::obj_type));
    if(! data.fSuccess()) return data.JSONRPCError();

    json_spirit::json_flags status;
    json_spirit::Object scanParams = params[0].get_obj(status);
    if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
    const json_spirit::Value &txid_v = find_value(scanParams, "txid");
    if (txid_v.type() != json_spirit::str_type)
        return data.JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing txid key");

    std::string txid = txid_v.get_str(status);
    if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
    if (! strenc::IsHex(txid))
        return data.JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");

    uint256 hash(txid);
    int32_t nDays = 90;
    uint32_t nBits = diff::spacing::GetNextTargetRequired(block_info::pindexBest, true);
    const json_spirit::Value &diff_v = find_value(scanParams, "difficulty");
    if (diff_v.type() == json_spirit::real_type || diff_v.type() == json_spirit::int_type) {
        double dDiff = diff_v.get_real(status);
        if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
        if (dDiff <= 0)
            return data.JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, diff must be greater than zero");

        CBigNum bnTarget(diff::nPoWBase);
        bnTarget *= 1000;
        bnTarget /= (int) (dDiff * 1000);
        nBits = bnTarget.GetCompact();
    }

    const json_spirit::Value &days_v = find_value(scanParams, "days");
    if (days_v.type() == json_spirit::int_type) {
        nDays = days_v.get_int(status);
        if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
        if (nDays <= 0)
            return data.JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, interval length must be greater than zero");
    }

    CTransaction tx;
    uint256 hashBlock = 0;
    if (block_transaction::manage::GetTransaction(hash, tx, hashBlock)) {
        if (hashBlock == 0)
            return data.JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to find transaction in the blockchain");

        std::vector<int> vInputs(0);
        const json_spirit::Value &inputs_v = find_value(scanParams, "vout");
        if (inputs_v.type() == json_spirit::array_type) {
            json_spirit::Array inputs = inputs_v.get_array(status);
            if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
            for(const json_spirit::Value &v_out: inputs) {
                int nOut = v_out.get_int(status);
                if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
                if (nOut < 0 || nOut > (int)tx.get_vout().size() - 1) {
                    std::stringstream strErrorMsg;
                    strErrorMsg << boost::format("Invalid parameter, input number %d is out of range") % nOut;
                    return data.JSONRPCError(RPC_INVALID_PARAMETER, strErrorMsg.str());
                }
                vInputs.push_back(nOut);
            }
        } else if(inputs_v.type() == json_spirit::int_type) {
            int nOut = inputs_v.get_int(status);
            if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
            if (nOut < 0 || nOut > (int)tx.get_vout().size() - 1) {
                std::stringstream strErrorMsg;
                strErrorMsg << boost::format("Invalid parameter, input number %d is out of range") % nOut;
                return data.JSONRPCError(RPC_INVALID_PARAMETER, strErrorMsg.str());
            }
            vInputs.push_back(nOut);
        } else {
            for (size_t i = 0; i != tx.get_vout().size(); ++i)
                vInputs.push_back(i);
        }

        CTxDB txdb("r");
        CBlock block;
        CTxIndex txindex;

        // Load transaction index item
        if (! txdb.ReadTxIndex(tx.GetHash(), txindex))
            return data.JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Unable to read block index item");

        // Read block header
        if (! block.ReadFromDisk(txindex.get_pos().get_nFile(), txindex.get_pos().get_nBlockPos(), false))
            return data.JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "CBlock::ReadFromDisk() failed");

        uint64_t nStakeModifier = 0;
        if (! bitkernel<uint256>::GetKernelStakeModifier(block.GetHash(), nStakeModifier))
            return data.JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No kernel stake modifier generated yet");

        std::pair<uint32_t, uint32_t> interval;
        interval.first = bitsystem::GetTime();

        // Only count coins meeting min age requirement
        if (block_check::nStakeMinAge + block.get_nTime() > interval.first)
            interval.first += (block_check::nStakeMinAge + block.get_nTime() - interval.first);
        interval.second = interval.first + nDays * util::nOneDay;

        json_spirit::Array results;
        for(const int &nOut: vInputs) {
            // Check for spent flag
            // It doesn't make sense to scan spent inputs.
            if (! txindex.get_vSpent(nOut).IsNull())
                continue;

            // Skip zero value outputs
            if (tx.get_vout(nOut).get_nValue() == 0)
                continue;

            // Build static part of kernel
            CDataStream ssKernel;
            ssKernel << nStakeModifier;
            ssKernel << block.get_nTime() << (txindex.get_pos().get_nTxPos() - txindex.get_pos().get_nBlockPos()) << tx.get_nTime() << nOut;
            CDataStream::const_iterator itK = ssKernel.begin();
            std::vector<std::pair<uint256, uint32_t> > result;
            if (bitkernel<uint256>::ScanKernelForward((unsigned char *)&itK[0], nBits, tx.get_nTime(), tx.get_vout(nOut).get_nValue(), interval, result)) {
                for(const std::pair<uint256, uint32_t> solution: result) {
                    json_spirit::Object item;
                    item.push_back(json_spirit::Pair("nout", nOut));
                    item.push_back(json_spirit::Pair("hash", solution.first.GetHex()));
                    item.push_back(json_spirit::Pair("time", util::DateTimeStrFormat(solution.second)));
                    results.push_back(item);
                }
            }
        }
        if (results.size() == 0)
            return data.JSONRPCSuccess(false);

        return data.JSONRPCSuccess(results);
    } else
        return data.JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
}

json_spirit::Value CRPCTable::getworkex(const json_spirit::Array &params, CBitrpcData &data) {
    using mapNewBlock_t = std::map<uint256, std::pair<CBlock *, CScript> >;
    static mapNewBlock_t mapNewBlock;
    static std::vector<CBlock *> vNewBlock;
    static CReserveKey reservekey(entry::pwalletMain);

    if (data.fHelp() || params.size() > 2) {
        return data.JSONRPCSuccess(
            "getworkex [data, coinbase]\n"
            "If [data, coinbase] is not specified, returns extended work data.\n"
        );
    }

    LOCK(CRPCTable::cs_getwork);
    if (net_node::vNodes.empty())
        return data.JSONRPCError(-9, strCoinName " is not connected!");
    if (block_notify<uint256>::IsInitialBlockDownload())
        return data.JSONRPCError(-10, strCoinName " is downloading blocks...");
    if (params.size() == 0) {
        // Update block
        static unsigned int nTransactionsUpdatedLast = 0;
        static CBlockIndex *pindexPrev = nullptr;
        static int64_t nStart = 0;
        static CBlock *pblock = nullptr;

        if (pindexPrev != block_info::pindexBest || (block_info::nTransactionsUpdated != nTransactionsUpdatedLast && bitsystem::GetTime() - nStart > 60)) {
            if (pindexPrev != block_info::pindexBest) {
                // Deallocate old blocks since they're obsolete now
                mapNewBlock.clear();
                for(CBlock *pblock: vNewBlock)
                    delete pblock;
                vNewBlock.clear();
            }

            nTransactionsUpdatedLast = block_info::nTransactionsUpdated;
            pindexPrev = block_info::pindexBest;
            nStart = bitsystem::GetTime();

            // Create new block
            pblock = miner::CreateNewBlock(entry::pwalletMain);
            if (! pblock)
                return data.JSONRPCError(-7, "Out of memory");
            vNewBlock.push_back(pblock);
        }

        // Update nTime
        pblock->set_nTime(std::max(pindexPrev->GetMedianTimePast()+1, bitsystem::GetAdjustedTime()));
        pblock->set_nNonce(0);

        // Update nExtraNonce
        static unsigned int nExtraNonce = 0;
        miner::IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);

        // Save
        mapNewBlock[pblock->get_hashMerkleRoot()] = std::make_pair(pblock, pblock->get_vtx(0).get_vin(0).get_scriptSig());

        // Prebuild hash buffers
        char pmidstate[32];
        char pdata[128];
        char phash1[64];
        miner::FormatHashBuffers(pblock, pmidstate, pdata, phash1);

        uint256 hashTarget = CBigNum().SetCompact(pblock->get_nBits()).getuint256();
        CTransaction coinbaseTx = pblock->get_vtx(0);
        auto merkle = pblock->GetMerkleBranch(0);
        json_spirit::Object result;
        result.push_back(json_spirit::Pair("data",     util::HexStr(BEGIN(pdata), END(pdata))));
        result.push_back(json_spirit::Pair("target",   util::HexStr(BEGIN(hashTarget), END(hashTarget))));

        CDataStream ssTx;
        ssTx << coinbaseTx;
        result.push_back(json_spirit::Pair("coinbase", util::HexStr(ssTx.begin(), ssTx.end())));
        json_spirit::Array merkle_arr;
        for(uint256 merkleh: merkle)
            merkle_arr.push_back(util::HexStr(BEGIN(merkleh), END(merkleh)));

        result.push_back(json_spirit::Pair("merkle", merkle_arr));
        return data.JSONRPCSuccess(result);
    } else {
        // Parse parameters
        json_spirit::json_flags status;
        std::string str = params[0].get_str(status);
        if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
        rpctable_vector vchData = strenc::ParseHex(str);
        rpctable_vector coinbase;
        if(params.size() == 2) {
            str = params[1].get_str(status);
            if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
            coinbase = strenc::ParseHex(str);
        }
        if (vchData.size() != 128)
            return data.JSONRPCError(-8, "Invalid parameter");

        CBlockHeader<uint256> *pdata = (CBlockHeader<uint256> *)&vchData[0];

        // Byte reverse
        for (int i = 0; i < 128 / 4; ++i)
            ((unsigned int *)pdata)[i] = util::ByteReverse(((unsigned int *)pdata)[i]);

        // Get saved block
        if (! mapNewBlock.count(pdata->get_hashMerkleRoot()))
            return false;

        CBlock *pblock = mapNewBlock[pdata->get_hashMerkleRoot()].first;
        pblock->set_nTime(pdata->get_nTime());
        pblock->set_nNonce(pdata->get_nNonce());
        if(coinbase.size() == 0)
            pblock->set_vtx(0).set_vin(0).set_scriptSig(mapNewBlock[pdata->get_hashMerkleRoot()].second);
        else {
            // check vtx size
            CTransaction ctx;
            CDataStream(coinbase, SER_NETWORK, version::PROTOCOL_VERSION) >> ctx; // [OK] FIXME - HACK!
            pblock->set_vtx(0) = ctx;
        }

        pblock->set_hashMerkleRoot(pblock->BuildMerkleTree());
        return data.JSONRPCSuccess(miner::CheckWork(pblock, *entry::pwalletMain, reservekey));
    }
}

json_spirit::Value CRPCTable::getwork(const json_spirit::Array &params, CBitrpcData &data) {
    using mapNewBlock_t = std::map<uint256, std::pair<CBlock *, CScript> >;
    static mapNewBlock_t mapNewBlock;
    static std::vector<CBlock *> vNewBlock;
    static CReserveKey reservekey(entry::pwalletMain);

    if (data.fHelp() || params.size() > 1) {
        return data.JSONRPCSuccess(
            "getwork [data]\n"
            "If [data] is not specified, returns formatted hash data to work on:\n"
            "  \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated
            "  \"data\" : block data\n"
            "  \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated
            "  \"target\" : little endian hash target\n"
            "If [data] is specified, tries to solve the block and returns true if it was successful.");
    }

    LOCK(CRPCTable::cs_getwork);
    if (net_node::vNodes.empty())
        return data.JSONRPCError(RPC_CLIENT_NOT_CONNECTED, strCoinName " is not connected!");
    if (block_notify<uint256>::IsInitialBlockDownload())
        return data.JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, strCoinName " is downloading blocks...");
    if (params.size() == 0) {
        // Update block
        static unsigned int nTransactionsUpdatedLast = 0;
        static CBlockIndex *pindexPrev = nullptr;
        static int64_t nStart = 0;
        static CBlock *pblock = nullptr;

        if (pindexPrev != block_info::pindexBest ||
           (block_info::nTransactionsUpdated != nTransactionsUpdatedLast && bitsystem::GetTime() - nStart > 60)) {
            if (pindexPrev != block_info::pindexBest) {
                // Deallocate old blocks since they're obsolete now
                mapNewBlock.clear();
                for(CBlock *pblock: vNewBlock)
                    delete pblock;
                vNewBlock.clear();
            }

            // Clear pindexPrev so future getworks make a new block, despite any failures from here on
            pindexPrev = nullptr;

            // Store the block_info::pindexBest used before miner::CreateNewBlock, to avoid races
            nTransactionsUpdatedLast = block_info::nTransactionsUpdated;
            CBlockIndex *pindexPrevNew = block_info::pindexBest;
            nStart = bitsystem::GetTime();

            // Create new block
            //logging::LogPrintf("ThreadRPCServer3 getwork new Block\n");
            pblock = miner::CreateNewBlock(entry::pwalletMain);
            if (! pblock)
                return bitjson::JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
            vNewBlock.push_back(pblock);

            // Need to update only after we know miner::CreateNewBlock succeeded
            pindexPrev = pindexPrevNew;
        }

        // Update nTime
        pblock->UpdateTime(pindexPrev);
        pblock->set_nNonce(0);

        // Update nExtraNonce
        static unsigned int nExtraNonce = 0;
        miner::IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);

        // Save
        mapNewBlock[pblock->get_hashMerkleRoot()] = std::make_pair(pblock, pblock->get_vtx(0).get_vin(0).get_scriptSig());

        // Pre-build hash buffers
        char pmidstate[32];
        char pdata[128];
        char phash1[64];
        miner::FormatHashBuffers(pblock, pmidstate, pdata, phash1);

        uint256 hashTarget = CBigNum().SetCompact(pblock->get_nBits()).getuint256();
        json_spirit::Object result;
        result.push_back(json_spirit::Pair("midstate", util::HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated
        result.push_back(json_spirit::Pair("data",     util::HexStr(BEGIN(pdata), END(pdata))));
        result.push_back(json_spirit::Pair("hash1",    util::HexStr(BEGIN(phash1), END(phash1)))); // deprecated
        result.push_back(json_spirit::Pair("target",   util::HexStr(BEGIN(hashTarget), END(hashTarget))));
        return data.JSONRPCSuccess(result);
    } else {
        // Parse parameters
        json_spirit::json_flags status;
        std::string str = params[0].get_str(status);
        if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
        rpctable_vector vchData = strenc::ParseHex(str);
        if (vchData.size() != 128)
            return data.JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");

        CBlockHeader<uint256> *pdata = (CBlockHeader<uint256> *)&vchData[0];

        // Byte reverse
        for (int i = 0; i < 128 / 4; ++i)
            ((unsigned int *)pdata)[i] = util::ByteReverse(((unsigned int *)pdata)[i]);

        // Get saved block
        if (! mapNewBlock.count(pdata->get_hashMerkleRoot()))
            return data.JSONRPCSuccess(false);

        CBlock *pblock = mapNewBlock[pdata->get_hashMerkleRoot()].first;
        pblock->set_nTime(pdata->get_nTime());
        pblock->set_nNonce(pdata->get_nNonce());
        pblock->set_vtx(0).set_vin(0).set_scriptSig(mapNewBlock[pdata->get_hashMerkleRoot()].second);
        pblock->set_hashMerkleRoot(pblock->BuildMerkleTree());
        return data.JSONRPCSuccess(miner::CheckWork(pblock, *entry::pwalletMain, reservekey));
    }
}

json_spirit::Value CRPCTable::getblocktemplate(const json_spirit::Array &params, CBitrpcData &data) {
    if (data.fHelp() || params.size() > 1) {
        return data.JSONRPCSuccess(
            "getblocktemplate [params]\n"
            "Returns data needed to construct a block to work on:\n"
            "  \"version\" : block version\n"
            "  \"previousblockhash\" : hash of current highest block\n"
            "  \"transactions\" : contents of non-coinbase transactions that should be included in the next block\n"
            "  \"coinbaseaux\" : data that should be included in coinbase\n"
            "  \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
            "  \"target\" : hash target\n"
            "  \"mintime\" : minimum timestamp appropriate for next block\n"
            "  \"curtime\" : current timestamp\n"
            "  \"mutable\" : list of ways the block template may be changed\n"
            "  \"noncerange\" : range of valid nonces\n"
            "  \"sigoplimit\" : limit of sigops in blocks\n"
            "  \"sizelimit\" : limit of block size\n"
            "  \"bits\" : compressed target of next block\n"
            "  \"height\" : height of the next block\n"
            "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.");
    }

    LOCK(CRPCTable::cs_getwork);
    std::string strMode = "template";
    if (params.size() > 0) { // json_spirit::null_type do nothing
        json_spirit::json_flags status;
        const json_spirit::Object &oparam = params[0].get_obj(status);
        if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
        const json_spirit::Value &modeval = find_value(oparam, "mode");
        if (modeval.type() == json_spirit::str_type) {
            strMode = modeval.get_str(status);
            if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
        } else
            return data.JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
    }

    if (strMode != "template")
        return data.JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
    if (net_node::vNodes.empty())
        return data.JSONRPCError(RPC_CLIENT_NOT_CONNECTED, strCoinName " is not connected!");
    if (block_notify<uint256>::IsInitialBlockDownload())
        return data.JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, strCoinName " is downloading blocks...");

    //static CReserveKey reservekey(entry::pwalletMain);

    // Update block
    static unsigned int nTransactionsUpdatedLast = 0;
    static CBlockIndex *pindexPrev = nullptr;
    static int64_t nStart = 0;
    static CBlock *pblock = nullptr;
    if (pindexPrev != block_info::pindexBest || (block_info::nTransactionsUpdated != nTransactionsUpdatedLast && bitsystem::GetTime() - nStart > 5)) {
        // Clear pindexPrev so future calls make a new block, despite any failures from here on
        pindexPrev = nullptr;

        // Store the block_info::pindexBest used before miner::CreateNewBlock, to avoid races
        nTransactionsUpdatedLast = block_info::nTransactionsUpdated;
        CBlockIndex *pindexPrevNew = block_info::pindexBest;
        nStart = bitsystem::GetTime();

        // Create new block
        if(pblock) {
            delete pblock;
            pblock = nullptr;
        }

        pblock = miner::CreateNewBlock(entry::pwalletMain);
        if (! pblock)
            return data.JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");

        // Need to update only after we know miner::CreateNewBlock succeeded
        pindexPrev = pindexPrevNew;
    }

    // Update nTime
    pblock->UpdateTime(pindexPrev);
    pblock->set_nNonce(0);

    json_spirit::Array transactions;
    std::map<uint256, int64_t> setTxIndex;
    int i = 0;
    CTxDB txdb("r");
    for(CTransaction &tx: pblock->set_vtx()) {
        uint256 txHash = tx.GetHash();
        setTxIndex[txHash] = i++;
        if (tx.IsCoinBase() || tx.IsCoinStake())
            continue;

        json_spirit::Object entry;
        CDataStream ssTx;
        ssTx << tx;
        entry.push_back(json_spirit::Pair("data", util::HexStr(ssTx.begin(), ssTx.end())));
        entry.push_back(json_spirit::Pair("hash", txHash.GetHex()));

        MapPrevTx mapInputs;
        std::map<uint256, CTxIndex> mapUnused;
        bool fInvalid = false;
        if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) {
            entry.push_back(json_spirit::Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut())));
            json_spirit::Array deps;
            for(MapPrevTx::value_type &inp: mapInputs) {
                if (setTxIndex.count(inp.first))
                    deps.push_back(setTxIndex[inp.first]);
            }
            entry.push_back(json_spirit::Pair("depends", deps));

            int64_t nSigOps = tx.GetLegacySigOpCount();
            nSigOps += tx.GetP2SHSigOpCount(mapInputs);
            entry.push_back(json_spirit::Pair("sigops", nSigOps));
        }

        transactions.push_back(entry);
    }

    json_spirit::Object aux;
    aux.push_back(json_spirit::Pair("flags", util::HexStr(block_info::COINBASE_FLAGS.begin(), block_info::COINBASE_FLAGS.end())));

    uint256 hashTarget = CBigNum().SetCompact(pblock->get_nBits()).getuint256();
    static json_spirit::Array aMutable;
    if (aMutable.empty()) {
        aMutable.push_back("time");
        aMutable.push_back("transactions");
        aMutable.push_back("prevblock");
    }

    json_spirit::Object result;
    result.push_back(json_spirit::Pair("version", pblock->get_nVersion()));
    result.push_back(json_spirit::Pair("previousblockhash", pblock->get_hashPrevBlock().GetHex()));
    result.push_back(json_spirit::Pair("transactions", transactions));
    result.push_back(json_spirit::Pair("coinbaseaux", aux));
    result.push_back(json_spirit::Pair("coinbasevalue", (int64_t)pblock->get_vtx(0).get_vout(0).get_nValue()));
    result.push_back(json_spirit::Pair("target", hashTarget.GetHex()));
    result.push_back(json_spirit::Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
    result.push_back(json_spirit::Pair("mutable", aMutable));
    result.push_back(json_spirit::Pair("noncerange", "00000000ffffffff"));
    result.push_back(json_spirit::Pair("sigoplimit", (int64_t)block_params::MAX_BLOCK_SIGOPS));
    result.push_back(json_spirit::Pair("sizelimit", (int64_t)block_params::MAX_BLOCK_SIZE));
    result.push_back(json_spirit::Pair("curtime", (int64_t)pblock->get_nTime()));
    result.push_back(json_spirit::Pair("bits", HexBits(pblock->get_nBits())));
    result.push_back(json_spirit::Pair("height", (int64_t)(pindexPrev->get_nHeight()+1)));

    return data.JSONRPCSuccess(result);
}

json_spirit::Value CRPCTable::submitblock(const json_spirit::Array &params, CBitrpcData &data) {
    if (data.fHelp() || params.size() < 1 || params.size() > 2) {
        return data.JSONRPCSuccess(
            "submitblock <hex data> [optional-params-obj]\n"
            "[optional-params-obj] parameter is currently ignored.\n"
            "Attempts to submit new block to network.\n"
            "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.");
    }

    LOCK(CRPCTable::cs_getwork);
    json_spirit::json_flags status;
    std::string hex = params[0].get_str(status);
    if(! status.fSuccess()) return data.JSONRPCError(RPC_JSON_ERROR, status.e);
    rpctable_vector blockData(strenc::ParseHex(hex));
    CDataStream ssBlock(blockData, SER_NETWORK, version::PROTOCOL_VERSION);
    CBlock block;
    try {
        ssBlock >> block;
    } catch (const std::exception &) {
        return data.JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
    }

    bool fAccepted = block_process::manage::ProcessBlock(nullptr, &block);
    if (! fAccepted)
        return data.JSONRPCSuccess("rejected");

    return data.JSONRPCSuccess(json_spirit::Value::null);
}

max_stars_repo_name: Penny-Admixture/SorachanCoin-qt

max_issues_repo_name: JTAG-Romney/SorachanCoin-qt

max_forks_repo_name: JTAG-Romney/SorachanCoin-qt


text:
#ifndef CREDIBLE_BALL_HPP
#define CREDIBLE_BALL_HPP

#include <Eigen/Dense>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <set>

#include "../lossfunction/BinderLoss.hpp"
#include "../lossfunction/LossFunction.hpp"
#include "../lossfunction/VariationInformation.hpp"

class CredibleBall {
 private:
  LossFunction* loss_function;     // metric to compute the region
  Eigen::MatrixXi mcmc_sample;     // MCMC matrix of clusters
  Eigen::VectorXi point_estimate;  // output of the greedy algorithm
  set<int, greater<int>>
      credibleBall;     // set of index clusters inside the credible region
  int T;                // number of clusters, ie mcmc_sample.rows
  int N;                // dimension of cluster, ie mcmc_sample.cols
  double alpha;         // level of the credible ball region
  double radius;        // radius of the credible ball
  double prob;          // estimated probability
  double vlb_distance;  // distance to the vertical lower bounds
  double vub_distance;  // distance to the vertical upper bounds
  double hb_distance;   // distance to the horizontal bounds

 public:
  CredibleBall(LOSS_FUNCTION loss_type_, Eigen::MatrixXi& mcmc_sample_,
               double alpha_, Eigen::VectorXi& point_estimate_);
  ~CredibleBall();

  void calculateRegion(
      double rate);    // calculate the points in the credible region
  double getRadius();  // returns the calculated radius
  Eigen::VectorXi VerticalUpperBound();  // index of cluusters of the VUB
  Eigen::VectorXi VerticalLowerBound();  // index of the clusters of the VLB
  Eigen::VectorXi HorizontalBound();     // index of the clusters of the HB
  void sumary(
      Eigen::VectorXi HB, Eigen::VectorXi VUB, Eigen::VectorXi VLB,
      string filename);  // generates a file with the bounds information

 protected:
  void populateCredibleSet();  // populate the credibleBall
  int count_cluster_row(int index);
  int getMinimalCrdinality();
  int getMaximalCardinality();
  double getMaxDistance(set<int, greater<int>> vec1);
  double getMinDistance();
  void saveSelectedClusters(set<int, greater<int>>& vec1, double& max_distance,
                            set<int, greater<int>>& vlb);
};
#endif  // CREDIBLE_BALL_HPP

ext: hpp

max_stars_repo_name: ricardaxel/bayesmix

max_issues_repo_name: ricardaxel/bayesmix

max_forks_repo_name: ricardaxel/bayesmix


text:
#pragma once

#include <common/scheduler/task.hpp>

#include <boost/asio.hpp>
#include <date/date.h>

#include <common/utils/datetime.hpp>
#include <common/scheduler/scheduler_durations.hpp>

namespace common::scheduler
{
template<class THandler>
class EverydayAtTask : public Task
{
public:
  template<class TDurationArg, class THandlerArg>
  EverydayAtTask(
    boost::uuids::uuid id,
    std::string owner,
    boost::asio::io_context& io,
    TDurationArg&& duration,
    THandlerArg&& handler
  )
  : id_{std::move(id)}
  , owner_{std::move(owner)}
  , timer_{io}
  , duration_{std::forward<TDurationArg>(duration)}
  , handler_{std::forward<THandlerArg>(handler)}
  {
    //TODO: Add static_assert to check if duration property is constructible from provided argument.

    configure_expiry();
  }

  const Id_t& id() const override
  {
    return id_;
  }

  const std::string& owner() const override
  {
    return owner_;
  }

  Timepoint_t expiry() const override
  {
    return timer_.expiry();
  }

  void set_expiry(Timepoint_t tp) override
  {
    spdlog::debug(fmt::format("Updating task expiry. From: {}, to: {}",
      common::utils::datetime::to_string(timer_.expiry()),
      common::utils::datetime::to_string(tp)
    ));
    timer_.expires_at(std::move(tp));
  }

  void activate() override
  {
    spdlog::debug("Installing task: {}", to_string());

    timer_.async_wait([&](const boost::system::error_code& ec) {
      if (ec) {
        spdlog::error("Timer error");
        return;
      }
      handler_();
      timer_.expires_at(timer_.expiry() + duration_.days);
      activate();
    });
  }

  std::string to_string() const override
  {
    using std::to_string;

    return "EverydaysAt - TaskId: " + to_string(id_) + " expires: " + common::utils::datetime::to_string(timer_.expiry());
  }

private:
  void configure_expiry()
  {
    using namespace date;
    using namespace std::chrono;

    const auto current_tp = common::utils::datetime::get_now();
    auto expiry_tp = common::utils::datetime::parse_time(duration_.at, current_tp);

    if (current_tp > expiry_tp) {
      expiry_tp += duration_.days;
    }

    timer_.expires_at(expiry_tp);
  }

private:
  boost::uuids::uuid id_;
  std::string owner_;
  boost::asio::system_timer timer_;
  days_at duration_;
  THandler handler_;
  };
}

max_stars_repo_name: pblxptr/hhctrl-management

max_issues_repo_name: pblxptr/hhctrl-management

max_forks_repo_name: pblxptr/hhctrl-management


text: #include <boost/log/sources/channel_feature.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#include <stan/math/rev/scal.hpp>
#include <gtest/gtest.h>
#include <boost/math/special_functions/digamma.hpp>
#include <test/unit/math/rev/scal/fun/nan_util.hpp>
#include <test/unit/math/rev/scal/util.hpp>

TEST(AgradRev,log_rising_factorial_var_double) {
  double a(1);
  AVAR b(4.0);
  AVAR f = stan::math::log_rising_factorial(b,a);
  EXPECT_FLOAT_EQ(std::log(4.0),f.val());

  AVEC x = createAVEC(a,b);
  VEC g;
  f.grad(x,g);
  EXPECT_FLOAT_EQ(0, g[0]);
  EXPECT_FLOAT_EQ(boost::math::digamma(5) - boost::math::digamma(4),g[1]);

  double eps = 1e-6;
  EXPECT_FLOAT_EQ((stan::math::log_rising_factorial(4.0 + eps, 1.0)
                  - stan::math::log_rising_factorial(4.0 - eps, 1.0))
                  / (2 * eps), g[1]);
}

TEST(AgradRev, log_rising_factorial_exceptions) {
  double a(1);
  AVAR b(-3.0);
  EXPECT_THROW(stan::math::log_rising_factorial(b,a), std::domain_error);
  EXPECT_THROW(stan::math::log_rising_factorial(b,b), std::domain_error);
}

TEST(AgradRev, log_rising_factorial_double_var) {
  double a(5.0);
  AVAR b(4.0);
  AVAR f = stan::math::log_rising_factorial(a,b);
  EXPECT_FLOAT_EQ(std::log(5*6*7*8), f.val());
  AVEC x = createAVEC(a,b);
  VEC g;
  f.grad(x,g);
  EXPECT_FLOAT_EQ(0, g[0]);
  EXPECT_FLOAT_EQ(boost::math::digamma(9), g[1]);

  double eps = 1e-6;
  EXPECT_FLOAT_EQ((stan::math::log_rising_factorial(5.0, 4.0 + eps)
                  - stan::math::log_rising_factorial(5.0, 4.0 - eps))
                  / (2 * eps), g[1]);
}

TEST(AgradRev, log_rising_factorial_var_var) {
  AVAR c(5.0);
  AVAR b(4.0);
  AVAR f = stan::math::log_rising_factorial(b,c);
  EXPECT_FLOAT_EQ(std::log(4*5*6*7*8), f.val());
  AVEC x = createAVEC(b,c);
  VEC g;
  f.grad(x,g);
  EXPECT_FLOAT_EQ(boost::math::digamma(9.0) - boost::math::digamma(4.0), g[0]);
  EXPECT_FLOAT_EQ(boost::math::digamma(9), g[1]);

  double eps = 1e-6;
  EXPECT_FLOAT_EQ((stan::math::log_rising_factorial(4.0 + eps, 5.0)
                  - stan::math::log_rising_factorial(4.0 - eps, 5.0))
                  / (2 * eps), g[0]);
  EXPECT_FLOAT_EQ((stan::math::log_rising_factorial(4.0, 5.0 + eps)
                  - stan::math::log_rising_factorial(4.0, 5.0 - eps))
                  / (2 * eps), g[1]);
}

struct log_rising_factorial_fun {
  template <typename T0, typename T1>
  inline
  typename stan::return_type<T0,T1>::type
  operator()(const T0& arg1,
             const T1& arg2) const {
    return log_rising_factorial(arg1,arg2);
  }
};

TEST(AgradRev, log_rising_factorial_nan) {
  log_rising_factorial_fun log_rising_factorial_;
  test_nan(log_rising_factorial_,3.0,5.0,false,true);
}

TEST(AgradRev, check_varis_on_stack) {
  AVAR a(1.0);
  AVAR b(4.0);
  test::check_varis_on_stack(stan::math::log_rising_factorial(b, a));
  test::check_varis_on_stack(stan::math::log_rising_factorial(b, 1.0));
  test::check_varis_on_stack(stan::math::log_rising_factorial(4.0, a));
}

ext: cpp

max_stars_repo_name: yizhang-cae/torsten

max_issues_repo_name: yizhang-cae/torsten

max_forks_repo_name: yizhang-cae/torsten


text:
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2014, Oracle and/or its affiliates.

// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle

// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html

#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP

#include <iterator>

#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/util/math.hpp>

#include <boost/geometry/algorithms/dispatch/distance.hpp>

namespace geofeatures_boost {} namespace boost = geofeatures_boost; namespace geofeatures_boost { namespace geometry
{

#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace closest_feature
{

// returns the range iterator the realizes the closest
// distance between the geometry and the element of the range
class geometry_to_range
{
private:
    template
    <
        typename Geometry,
        typename RangeIterator,
        typename Strategy,
        typename Distance
    >
    static inline void apply(Geometry const& geometry,
                             RangeIterator first,
                             RangeIterator last,
                             Strategy const& strategy,
                             RangeIterator& it_min,
                             Distance& dist_min)
    {
        BOOST_GEOMETRY_ASSERT( first != last );

        Distance const zero = Distance(0);

        // start with first distance
        it_min = first;
        dist_min = dispatch::distance
            <
                Geometry,
                typename std::iterator_traits<RangeIterator>::value_type,
                Strategy
            >::apply(geometry, *it_min, strategy);

        // check if other elements in the range are closer
        for (RangeIterator it = ++first; it != last; ++it)
        {
            Distance dist = dispatch::distance
                <
                    Geometry,
                    typename std::iterator_traits<RangeIterator>::value_type,
                    Strategy
                >::apply(geometry, *it, strategy);

            if (geometry::math::equals(dist, zero))
            {
                dist_min = dist;
                it_min = it;
                return;
            }
            else if (dist < dist_min)
            {
                dist_min = dist;
                it_min = it;
            }
        }
    }

public:
    template
    <
        typename Geometry,
        typename RangeIterator,
        typename Strategy,
        typename Distance
    >
    static inline RangeIterator apply(Geometry const& geometry,
                                      RangeIterator first,
                                      RangeIterator last,
                                      Strategy const& strategy,
                                      Distance& dist_min)
    {
        RangeIterator it_min;
        apply(geometry, first, last, strategy, it_min, dist_min);

        return it_min;
    }

    template
    <
        typename Geometry,
        typename RangeIterator,
        typename Strategy
    >
    static inline RangeIterator apply(Geometry const& geometry,
                                      RangeIterator first,
                                      RangeIterator last,
                                      Strategy const& strategy)
    {
        typename strategy::distance::services::return_type
            <
                Strategy,
                typename point_type<Geometry>::type,
                typename point_type
                    <
                        typename std::iterator_traits
                            <
                                RangeIterator
                            >::value_type
                    >::type
            >::type dist_min;

        return apply(geometry, first, last, strategy, dist_min);
    }
};

}} // namespace detail::closest_feature
#endif // DOXYGEN_NO_DETAIL

}} // namespace geofeatures_boost::geometry

#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_CLOSEST_FEATURE_GEOMETRY_TO_RANGE_HPP

max_stars_repo_name: xarvey/Yuuuuuge

max_issues_repo_name: xarvey/Yuuuuuge

max_forks_repo_name: xarvey/Yuuuuuge


text:
// Copyright 2016-2020 Tim Kouters (Falcons)
// SPDX-License-Identifier: Apache-2.0
/*
 * cWorldStateFunctionTypes.hpp
 *
 *  Created on: Jan 24, 2016
 *      Author: Tim Kouters
 */

#ifndef CWORLDSTATEFUNCTIONTYPES_HPP_
#define CWORLDSTATEFUNCTIONTYPES_HPP_

#include <string>
#include <map>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/assign/list_of.hpp>

#include "int/cWorldStateFunctions.hpp"

enum class worldStateFunctionEnum
{
	INVALID = 0,

	IS_LOWEST_ACTIVE_ROBOT,
	IS_HIGHEST_ACTIVE_ROBOT,
	IS_SECOND_HIGHEST_ACTIVE_ROBOT,
	IS_THIRD_HIGHEST_ACTIVE_ROBOT,
	IS_ONLY_ACTIVE_ROBOT,

	IS_IN_MATCH,

	IS_SETPIECE,
	IS_OWN_SETPIECE,
	IS_PREPARE_SETPIECE,
	IS_KICKOFF_SETPIECE,
	IS_DROPPEDBALL_SETPIECE,
	IS_PENALTY_SETPIECE,
	IS_GOALKICK_SETPIECE,
	IS_FREEKICK_SETPIECE,
	IS_CORNER_SETPIECE,
	IS_THROWIN_SETPIECE,
	IS_PARKING_SETPIECE,

	WITHIN_1M_OF_BALL,
	DOES_TEAM_HAVE_BALL,
	DOES_OWN_ROBOT_HAVE_BALL,
	IS_OWN_ROBOT_AT_OPPONENT_SIDE,
	IS_BALL_AT_SIDE,
	IS_OWN_ROBOT_CLOSEST_TO_POI,
	IS_OWN_ROBOT_SECOND_CLOSEST_TO_POI,
	IS_OWN_ROBOT_FURTHEST_FROM_POI,
	IS_OWN_ROBOT_SETPIECE_DEFENDER_ASSIST,
	IS_OWN_ROBOT_NEAREST_TO_BALL,
	IS_OWN_ROBOT_NEAREST_TO_LAST_KNOWN_BALL_LOCATION,
	IS_BALL_LOCATION_KNOWN,
	IS_BALL_IN_OWN_PENALTY_AREA,
	IS_BALL_IN_OPPONENT_PENALTY_AREA,
	IS_LAST_KNOWN_BALL_LOCATION_ON_THE_HALF_OF_MY_ROLE,

	IS_ASSISTENT_PRESENT,
	IS_POTENTIAL_OPP_ATTACKER_PRESENT,

	IS_SHORT_TURN_TO_GOAL_BLOCKED_BY_OPPONENT,
	IS_LONG_TURN_TO_GOAL_BLOCKED_BY_OPPONENT,

	IS_VALID_NUMBER_OF_PASSES_GIVEN,

	IS_OPPONENT_GOALKEEPER_IN_LEFT_CORNER,
	IS_OPPONENT_GOALKEEPER_IN_RIGHT_CORNER,

	IS_BALL_APPROACHING_ROBOT,
	IS_PASS_APPROACHING_ROBOT,
	IS_OPPONENT_HALF_REACHABLE,

	IS_IN_SCORING_POSITION,
	IS_SHOT_ON_GOAL_BLOCKED,
	IS_LOB_SHOT_ON_GOAL_BLOCKED,
	IS_PASS_TO_CLOSEST_TEAMMEMBER_BLOCKED,
	IS_PASS_TO_CLOSEST_ATTACKER_BLOCKED,
	IS_PASS_TO_FURTHEST_ATTACKER_BLOCKED,
	IS_PASS_TO_FURTHEST_DEFENDER_BLOCKED,
	IS_TIP_IN_BLOCKED,
	IS_PATH_TO_BALL_BLOCKED,

	DOES_ASSISTANT_HAVE_BALL,
	ALL_ROBOTS_ACTIVE,

	DEFENDING_STRATEGY_ON,

	MULTIPLE_OPPONENTS_ON_OWN_HALF,
	IS_AN_ATTACKER_ON_OPP_HALF,

	SIZE_OF_ENUM
};

static std::map<std::string, worldStateFunctionEnum> worldStateFunctionMappingStrToEnum = boost::assign::map_list_of
		("INVALID", worldStateFunctionEnum::INVALID)
		("IS_LOWEST_ACTIVE_ROBOT", worldStateFunctionEnum::IS_LOWEST_ACTIVE_ROBOT)
		("IS_HIGHEST_ACTIVE_ROBOT", worldStateFunctionEnum::IS_HIGHEST_ACTIVE_ROBOT)
		("IS_SECOND_HIGHEST_ACTIVE_ROBOT", worldStateFunctionEnum::IS_SECOND_HIGHEST_ACTIVE_ROBOT)
		("IS_THIRD_HIGHEST_ACTIVE_ROBOT", worldStateFunctionEnum::IS_THIRD_HIGHEST_ACTIVE_ROBOT)
		("IS_ONLY_ACTIVE_ROBOT", worldStateFunctionEnum::IS_ONLY_ACTIVE_ROBOT)
		("IS_IN_MATCH", worldStateFunctionEnum::IS_IN_MATCH)
		("IS_SETPIECE", worldStateFunctionEnum::IS_SETPIECE)
		("IS_OWN_SETPIECE", worldStateFunctionEnum::IS_OWN_SETPIECE)
		("IS_PREPARE_SETPIECE", worldStateFunctionEnum::IS_PREPARE_SETPIECE)
		("IS_KICKOFF_SETPIECE", worldStateFunctionEnum::IS_KICKOFF_SETPIECE)
		("IS_DROPPEDBALL_SETPIECE", worldStateFunctionEnum::IS_DROPPEDBALL_SETPIECE)
		("IS_PENALTY_SETPIECE", worldStateFunctionEnum::IS_PENALTY_SETPIECE)
		("IS_GOALKICK_SETPIECE", worldStateFunctionEnum::IS_GOALKICK_SETPIECE)
		("IS_FREEKICK_SETPIECE", worldStateFunctionEnum::IS_FREEKICK_SETPIECE)
		("IS_CORNER_SETPIECE", worldStateFunctionEnum::IS_CORNER_SETPIECE)
		("IS_THROWIN_SETPIECE", worldStateFunctionEnum::IS_THROWIN_SETPIECE)
		("IS_PARKING_SETPIECE", worldStateFunctionEnum::IS_PARKING_SETPIECE)
		("WITHIN_1M_OF_BALL", worldStateFunctionEnum::WITHIN_1M_OF_BALL)
		("DOES_TEAM_HAVE_BALL", worldStateFunctionEnum::DOES_TEAM_HAVE_BALL)
		("DOES_OWN_ROBOT_HAVE_BALL", worldStateFunctionEnum::DOES_OWN_ROBOT_HAVE_BALL)
		("IS_OWN_ROBOT_AT_OPPONENT_SIDE", worldStateFunctionEnum::IS_OWN_ROBOT_AT_OPPONENT_SIDE)
		("IS_BALL_AT_SIDE", worldStateFunctionEnum::IS_BALL_AT_SIDE)
		("IS_OWN_ROBOT_CLOSEST_TO_POI", worldStateFunctionEnum::IS_OWN_ROBOT_CLOSEST_TO_POI)
		("IS_OWN_ROBOT_SECOND_CLOSEST_TO_POI", worldStateFunctionEnum::IS_OWN_ROBOT_SECOND_CLOSEST_TO_POI)
		("IS_OWN_ROBOT_FURTHEST_FROM_POI", worldStateFunctionEnum::IS_OWN_ROBOT_FURTHEST_FROM_POI)
		("IS_OWN_ROBOT_SETPIECE_DEFENDER_ASSIST", worldStateFunctionEnum::IS_OWN_ROBOT_SETPIECE_DEFENDER_ASSIST)
		("IS_OWN_ROBOT_NEAREST_TO_BALL", worldStateFunctionEnum::IS_OWN_ROBOT_NEAREST_TO_BALL)
		("IS_OWN_ROBOT_NEAREST_TO_LAST_KNOWN_BALL_LOCATION", worldStateFunctionEnum::IS_OWN_ROBOT_NEAREST_TO_LAST_KNOWN_BALL_LOCATION)
		("IS_BALL_LOCATION_KNOWN", worldStateFunctionEnum::IS_BALL_LOCATION_KNOWN)
		("IS_BALL_IN_OWN_PENALTY_AREA", worldStateFunctionEnum::IS_BALL_IN_OWN_PENALTY_AREA)
		("IS_BALL_IN_OPPONENT_PENALTY_AREA", worldStateFunctionEnum::IS_BALL_IN_OPPONENT_PENALTY_AREA)
		("IS_LAST_KNOWN_BALL_LOCATION_ON_THE_HALF_OF_MY_ROLE", worldStateFunctionEnum::IS_LAST_KNOWN_BALL_LOCATION_ON_THE_HALF_OF_MY_ROLE)
		("IS_ASSISTENT_PRESENT", worldStateFunctionEnum::IS_ASSISTENT_PRESENT)
		("IS_POTENTIAL_OPP_ATTACKER_PRESENT", worldStateFunctionEnum::IS_POTENTIAL_OPP_ATTACKER_PRESENT)
		("IS_SHORT_TURN_TO_GOAL_BLOCKED_BY_OPPONENT", worldStateFunctionEnum::IS_SHORT_TURN_TO_GOAL_BLOCKED_BY_OPPONENT)
		("IS_LONG_TURN_TO_GOAL_BLOCKED_BY_OPPONENT", worldStateFunctionEnum::IS_LONG_TURN_TO_GOAL_BLOCKED_BY_OPPONENT)
		("IS_VALID_NUMBER_OF_PASSES_GIVEN", worldStateFunctionEnum::IS_VALID_NUMBER_OF_PASSES_GIVEN)
		("IS_OPPONENT_GOALKEEPER_IN_LEFT_CORNER", worldStateFunctionEnum::IS_OPPONENT_GOALKEEPER_IN_LEFT_CORNER)
		("IS_OPPONENT_GOALKEEPER_IN_RIGHT_CORNER", worldStateFunctionEnum::IS_OPPONENT_GOALKEEPER_IN_RIGHT_CORNER)
		("IS_BALL_APPROACHING_ROBOT", worldStateFunctionEnum::IS_BALL_APPROACHING_ROBOT)
		("IS_PASS_APPROACHING_ROBOT", worldStateFunctionEnum::IS_PASS_APPROACHING_ROBOT)
		("IS_OPPONENT_HALF_REACHABLE", worldStateFunctionEnum::IS_OPPONENT_HALF_REACHABLE)
		("IS_IN_SCORING_POSITION", worldStateFunctionEnum::IS_IN_SCORING_POSITION)
		("IS_SHOT_ON_GOAL_BLOCKED", worldStateFunctionEnum::IS_SHOT_ON_GOAL_BLOCKED)
		("IS_LOB_SHOT_ON_GOAL_BLOCKED", worldStateFunctionEnum::IS_LOB_SHOT_ON_GOAL_BLOCKED)
		("IS_PASS_TO_CLOSEST_TEAMMEMBER_BLOCKED", worldStateFunctionEnum::IS_PASS_TO_CLOSEST_TEAMMEMBER_BLOCKED)
		("IS_PASS_TO_CLOSEST_ATTACKER_BLOCKED", worldStateFunctionEnum::IS_PASS_TO_CLOSEST_ATTACKER_BLOCKED)
		("IS_PASS_TO_FURTHEST_ATTACKER_BLOCKED", worldStateFunctionEnum::IS_PASS_TO_FURTHEST_ATTACKER_BLOCKED)
		("IS_PASS_TO_FURTHEST_DEFENDER_BLOCKED", worldStateFunctionEnum::IS_PASS_TO_FURTHEST_DEFENDER_BLOCKED)
		("IS_TIP_IN_BLOCKED", worldStateFunctionEnum::IS_TIP_IN_BLOCKED)
		("IS_PATH_TO_BALL_BLOCKED", worldStateFunctionEnum::IS_PATH_TO_BALL_BLOCKED)
		("DOES_ASSISTANT_HAVE_BALL", worldStateFunctionEnum::DOES_ASSISTANT_HAVE_BALL)
		("ALL_ROBOTS_ACTIVE", worldStateFunctionEnum::ALL_ROBOTS_ACTIVE)
		("DEFENDING_STRATEGY_ON", worldStateFunctionEnum::DEFENDING_STRATEGY_ON)
		("MULTIPLE_OPPONENTS_ON_OWN_HALF", worldStateFunctionEnum::MULTIPLE_OPPONENTS_ON_OWN_HALF)
		("IS_AN_ATTACKER_ON_OPP_HALF", worldStateFunctionEnum::IS_AN_ATTACKER_ON_OPP_HALF)
		;

typedef boost::function<bool(const std::map<std::string, std::string>&)> worldstateFunctionType;

#endif /* CWORLDSTATEFUNCTIONTYPES_HPP_ */

max_stars_repo_name: Falcons-Robocup/code

max_issues_repo_name: Falcons-Robocup/code

max_forks_repo_name: Falcons-Robocup/code


text:
/*
 * libnetlinkplus - A portable netlink extension for Boost::ASIO.
 * Copyright (C) 2010-2011 Julien KAUFFMANN <julien.kauffmann@freelan.org>
 *
 * This file is part of libnetlinkplus.
 *
 * libnetlinkplus is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * libnetlinkplus 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 General Public
 * License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * file(s) with this exception, you may extend this exception to your
 * version of the file(s), but you are not obligated to do so.  If you
 * do not wish to do so, delete this exception statement from your
 * version.  If you delete this exception statement from all source
 * files in the program, then also delete it here.
 *
 * If you intend to use libnetlinkplus in a commercial software, please
 * contact me : we may arrange this for a small fee or no fee at all,
 * depending on the nature of your project.
 */

/**
 * \file endpoint.hpp
 * \author Julien KAUFFMANN <julien.kauffmann@freelan.org>
 * \brief A netlink endpoint class.
 */

#pragma once

#include <boost/asio.hpp>

#include <linux/netlink.h>
#include <linux/rtnetlink.h>

namespace netlinkplus
{
	/**
	 * \brief A netlink endpoint class.
	 */
	template <typename ProtocolType>
	class netlink_endpoint
	{
		public:
			/**
			 * \brief The associated protocol type.
			 */
			typedef ProtocolType protocol_type;

			/**
			 * \brief The data type.
			 */
			typedef boost::asio::detail::socket_addr_type data_type;

			/**
			 * \brief Create a new endpoint.
			 * \param groups The multicast groups to be a member of.
			 * \param pid The pid associated to the endpoint.
			 */
			explicit netlink_endpoint(uint32_t groups = 0, uint32_t pid = 0) :
				m_sockaddr{AF_NETLINK, 0, pid, groups}
			{
			}

			/**
			 * \brief Get the associated protocol.
			 * \return An instance of the associated protocol.
			 */
			protocol_type protocol() const
			{
				return protocol_type();
			}

			/**
			 * \brief Get the data.
			 * \return The data.
			 */
			data_type* data()
			{
				return reinterpret_cast<sockaddr*>(&m_sockaddr);
			}

			/**
			 * \brief Get the data.
			 * \return The data.
			 */
			const data_type* data() const
			{
				return reinterpret_cast<const sockaddr*>(&m_sockaddr);
			}

			/**
			 * \brief Get the size of the endpoint.
			 * \return The size.
			 */
			size_t size() const
			{
				return sizeof(m_sockaddr);
			}

			/**
			 * \brief Get the capacity of the endpoint.
			 * \return The capacity.
			 */
			size_t capacity() const
			{
				return size();
			}

			friend bool operator==(const netlink_endpoint& lhs, const netlink_endpoint& rhs)
			{
				return (lhs.m_sockaddr == rhs.m_sockaddr);
			}

			friend bool operator!=(const netlink_endpoint& lhs, const netlink_endpoint& rhs)
			{
				return (lhs.m_sockaddr != rhs.m_sockaddr);
			}

			friend bool operator<(const netlink_endpoint& lhs, const netlink_endpoint& rhs)
			{
				return (lhs.m_sockaddr < rhs.m_sockaddr);
			}

		private:

			sockaddr_nl m_sockaddr;
	};
}

max_stars_repo_name: krattai/AEBL

max_issues_repo_name: krattai/AEBL

max_forks_repo_name: krattai/AEBL


text:
//
// Created by hodge on 24/11/2021.
//

#ifndef BOOST_CONNECTOR_SHA256_DIGEST_HPP
#define BOOST_CONNECTOR_SHA256_DIGEST_HPP

#include <boost/functional/hash.hpp>

#include <functional>
#include <iosfwd>
#include <span>

namespace boost::connector
{
struct sha256_digest
{
    static constexpr std::size_t digest_length = 32;

    using mutable_span = std::span< unsigned char, digest_length >;

    using const_span = std::span< unsigned char const, digest_length >;

    const_span
    data() const
    {
        return const_span(data_, data_ + digest_length);
    }

    mutable_span
    data()
    {
        return mutable_span(data_, data_ + digest_length);
    }

    bool
    operator==(sha256_digest const &r) const
    {
        return std::memcmp(data_, r.data_, sizeof(data_)) == 0;
    }

  private:
    friend std::size_t
    hash_value(sha256_digest const &self);

    friend std::ostream &
    operator<<(std::ostream &os, sha256_digest const &digest);

  private:
    unsigned char data_[digest_length];
};

}   // namespace boost::connector

namespace std
{
template <>
struct hash< boost::connector::sha256_digest >
: boost::hash< boost::connector::sha256_digest >
{
};

}   // namespace std

#endif   // BOOST_CONNECTOR_SHA256_DIGEST_HPP


text:
/*
 * Copyright (C) 2012-2014 Open Source Robotics Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 *
 */
/* Desc: Actarray Interface for Player-Gazebo
 * Author: Alexis Maldonado
 * Date: 19 September 2006
 */

#include <math.h>
#include <iostream>
#include <boost/thread/recursive_mutex.hpp>

#include "GazeboDriver.hh"
#include "ActarrayInterface.hh"

using namespace libgazebo;

boost::recursive_mutex *ActarrayInterface::mutex = NULL;

// The data for the interface (gz_actarray_data_t in gazebo.h) contains
// information about each joint plus variables to store the commands. When
// a new command is sent, it modifies the cmd_pos, cmd_speed, ... variables
// and sets new_cmd to 1. The gazebo model can look at this variable to find
// out if a new command came Since joints in gazebo only support velocity
// control, the model has to implement at least a P controller to implement
// position commands. The model should support position and velocity commands.
// Home commands, brake requests, and power requests are simply translated to
// a sensible meaning in velocity or position commands.
// If the models need it, this interface should be extended.

ActarrayInterface::ActarrayInterface(player_devaddr_t addr,
    GazeboDriver *driver, ConfigFile *cf,
    int section)
: GazeboInterface(addr, driver, cf, section)
{
  /*
  // Get the ID of the interface
  this->gz_id = GazeboClient::prefixId + cf->ReadString(section, "gz_id", "");

  // Allocate a Actarray Interface
  this->iface = new ActarrayIface();

  memset(&this->actData, 0, sizeof(this->actData));

  this->datatime = -1;

  if (this->mutex == NULL)
    this->mutex = new boost::recursive_mutex();
    */
}

ActarrayInterface::~ActarrayInterface()
{
  /*
  delete [] this->actData.actuators;

  // Release this interface
  delete this->iface;
  */
}

int ActarrayInterface::ProcessMessage(QueuePointer &respQueue,
    player_msghdr_t *hdr, void *data)
{
  /*
  boost::recursive_mutex::scoped_lock lock(*this->mutex);
  if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
        PLAYER_ACTARRAY_CMD_POS, this->device_addr))
  {
    assert(hdr->size >= sizeof(player_actarray_position_cmd_t));

    player_actarray_position_cmd_t *cmd;
    cmd = (player_actarray_position_cmd_t*) data;

    this->iface->Lock(1);
    this->iface->data->cmd_pos[cmd->joint] = cmd->position;
    this->iface->data->joint_mode[cmd->joint] =
      GAZEBO_ACTARRAY_JOINT_POSITION_MODE;
    this->iface->data->new_cmd = true;
    this->iface->Unlock();

    return(0);

  }
  else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
        PLAYER_ACTARRAY_CMD_SPEED, this->device_addr))
  {
    assert(hdr->size >= sizeof(player_actarray_speed_cmd_t));

    player_actarray_speed_cmd_t *cmd;
    cmd = (player_actarray_speed_cmd_t*) data;

    this->iface->Lock(1);

    this->iface->data->cmd_speed[cmd->joint]= cmd->speed;
    this->iface->data->joint_mode[cmd->joint]= GAZEBO_ACTARRAY_JOINT_SPEED_MODE;

    this->iface->data->new_cmd = true;
    this->iface->Unlock();

    return(0);

  }
  else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
        PLAYER_ACTARRAY_CMD_HOME, this->device_addr))
  {
    assert(hdr->size >= sizeof(player_actarray_home_cmd_t));
    player_actarray_home_cmd_t *cmd;
    cmd = (player_actarray_home_cmd_t*) data;

    this->iface->Lock(1);

    this->iface->data->cmd_pos[cmd->joint]= 0.0;
    this->iface->data->joint_mode[cmd->joint] =
      GAZEBO_ACTARRAY_JOINT_POSITION_MODE;
    this->iface->data->new_cmd = true;

    this->iface->Unlock();

    return(0);

  }
  else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
        PLAYER_ACTARRAY_REQ_SPEED, this->device_addr))
  {
    assert(hdr->size >= sizeof(player_actarray_speed_config_t));
    player_actarray_speed_config_t *req;
    player_actarray_speed_config_t response;

    req = (player_actarray_speed_config_t*)(data);

    if (req->joint < GAZEBO_ACTARRAY_MAX_NUM_ACTUATORS)
    {
      this->iface->Lock(1);

      response.joint = req->joint;
      response.speed = this->iface->data->actuators[req->joint].speed;

      this->iface->Unlock();

      driver->Publish(this->device_addr, respQueue,
          PLAYER_MSGTYPE_RESP_ACK, PLAYER_ACTARRAY_REQ_SPEED, &response);

    }
  }
  else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
        PLAYER_ACTARRAY_REQ_BRAKES, this->device_addr))
  {
    assert(hdr->size >= sizeof(player_actarray_brakes_config_t));
    player_actarray_brakes_config_t *req;
    req = (player_actarray_brakes_config_t*) data;

    // If brakes = on -> Stop all the joints. If they are off, don't do anything
    if (req->value == 1)
    {
      this->iface->Lock(1);

      for (unsigned int i = 0 ; i != GAZEBO_ACTARRAY_MAX_NUM_ACTUATORS ; ++i)
      {
        this->iface->data->cmd_speed[i] = 0.0;
        this->iface->data->joint_mode[i] = GAZEBO_ACTARRAY_JOINT_SPEED_MODE;
        this->iface->data->new_cmd = true;

      }
      this->iface->Unlock();
    }

    driver->Publish(this->device_addr, respQueue,
        PLAYER_MSGTYPE_RESP_ACK, PLAYER_ACTARRAY_REQ_BRAKES);
    return(0);

  }
  else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
        PLAYER_ACTARRAY_REQ_POWER, this->device_addr))
  {
    assert(hdr->size >= sizeof(player_actarray_power_config_t));
    player_actarray_power_config_t *req;
    req = (player_actarray_power_config_t*) data;

    // If power = off -> Stop all the joints. If power = on, don't do anything
    if (req->value == 0)
    {
      this->iface->Lock(1);

      for (unsigned int i = 0 ; i != GAZEBO_ACTARRAY_MAX_NUM_ACTUATORS ; ++i)
      {
        this->iface->data->cmd_speed[i]= 0.0;
        this->iface->data->joint_mode[i]= GAZEBO_ACTARRAY_JOINT_SPEED_MODE;
        this->iface->data->new_cmd = true;
      }
      this->iface->Unlock();
    }

    driver->Publish(this->device_addr, respQueue,
        PLAYER_MSGTYPE_RESP_ACK, PLAYER_ACTARRAY_REQ_POWER);
    return(0);
  }
  else if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_REQ,
        PLAYER_ACTARRAY_REQ_GET_GEOM, this->device_addr))
  {
    player_actarray_geom response;
    this->iface->Lock(1);
    response.actuators_count = this->iface->data->actuators_count;

    player_actarray_actuatorgeom_t geoms[GAZEBO_ACTARRAY_MAX_NUM_ACTUATORS];
    for (unsigned int i = 0; i < GAZEBO_ACTARRAY_MAX_NUM_ACTUATORS; ++i)
    {
      ActarrayActuatorGeom& gazeboGeom = this->iface->data->actuator_geoms[i];
      geoms[i].type = gazeboGeom.type;
      // unused
      geoms[i].length = 0;
      // unused
      memset(&(geoms[i].orientation), 0, sizeof(geoms[i].orientation));
      // unused
      memset(&(geoms[i].axis), 0, sizeof(geoms[i].axis));
      geoms[i].min = gazeboGeom.min;
      geoms[i].centre = gazeboGeom.center;
      geoms[i].max = gazeboGeom.max;
      geoms[i].home = gazeboGeom.home;
      geoms[i].config_speed = gazeboGeom.config_speed;
      geoms[i].hasbrakes = gazeboGeom.hasbrakes;
    }
    response.actuators = geoms;

    // unused
    memset(&response.base_pos, 0, sizeof(response.base_pos));
    // unused
    memset(&response.base_orientation, 0, sizeof(response.base_orientation));
    this->iface->Unlock();

    driver->Publish(this->device_addr, respQueue,
        PLAYER_MSGTYPE_RESP_ACK, PLAYER_ACTARRAY_REQ_GET_GEOM, &response);
    return(0);
  }

  */
  return -1;
}

void ActarrayInterface::Update()
{
  /*
  boost::recursive_mutex::scoped_lock lock(*this->mutex);
  this->iface->Lock(1);

  // Only Update when new data is present
  if (this->iface->data->head.time > this->datatime)
  {
    // Update the local time so we know when new info comes
    this->datatime = this->iface->data->head.time;

    unsigned int prevCount = this->actData.actuators_count;

    // The number of actuators in the array.
    this->actData.actuators_count = this->iface->data->actuators_count;

    if (prevCount != this->actData.actuators_count)
    {
      delete [] this->actData.actuators;

      this->actData.actuators =
        new player_actarray_actuator_t[this->actData.actuators_count];
    }

    for (unsigned int i = 0; i < this->actData.actuators_count ; ++i)
    {
      float pos = this->iface->data->actuators[i].position;
      float speed = this->iface->data->actuators[i].speed;

      // float current = this->iface->data->actuators_data[i].current;
      uint8_t report_state = this->iface->data->actuators[i].state;
      this->actData.actuators[i].position = pos;
      this->actData.actuators[i].speed = speed;
      // data.actuators[i].current = current;
      this->actData.actuators[i].state = report_state;

    }

    driver->Publish(this->device_addr,
        PLAYER_MSGTYPE_DATA,
        PLAYER_ACTARRAY_DATA_STATE,
        (void*)&this->actData, sizeof(this->actData), &this->datatime);
  }

  this->iface->Unlock();
  */
}

void ActarrayInterface::Subscribe()
{
  /*
  try
  {
    boost::recursive_mutex::scoped_lock lock(*this->mutex);
    this->iface->Open(GazeboClient::client, this->gz_id);
  }
  catch (std::string &e)
  {
    // std::ostringstream stream;
    std::cout << "Error subscribing to Gazebo Actarray Interface\n"
              << e << "\n";
    // gzthrow(stream.str());
    exit(0);
  }
  */
}

void ActarrayInterface::Unsubscribe()
{
  /*
  boost::recursive_mutex::scoped_lock lock(*this->mutex);
  this->iface->Close();
  */
}

ext: cc

max_stars_repo_name: hyunoklee/Gazebo

max_issues_repo_name: hyunoklee/Gazebo

max_forks_repo_name: hyunoklee/Gazebo


text:
#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
using namespace std;
using namespace boost::multiprecision;

cpp_int dp[55][4004];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, k, x;
    while (cin >> k >> n >> x) {
        cpp_int nom = 0;
        if (x <= k * n && x >= n) {
            for (int i = 0; i <= 50; i++)
                for (int j = 0; j <= 4000; j++)
                    dp[i][j] = 0;

            dp[0][0] = 1;

            for (int i = 1; i <= k; i++)
                dp[1][i] = 1;

            for (int i = 2; i <= n; i++) {
                cpp_int ps = 0;
                for (int j = i; j <= k * i; j++) {
                    ps += dp[i - 1][j - 1];
                    if (j - i >= k)ps -= dp[i - 1][j - k - 1];
                    dp[i][j] = ps;
                }
            }
            nom = dp[n][x];
        }

        cpp_int denom = 1;
        for (int i = 1; i <= n; i++)denom *= k;

        cout << nom << "/" << denom << endl;
    }

    return 0;
}

max_stars_repo_path: Mathematics/Probability Theory/Standard/Throw the Dice.cpp