Пример #1
0
const countPermN = R.curry((n, ds) =>
    R.pipe(
        R.map(permN(n)),
        R.reduce(R.concat, []),
        R.countBy(JSON.stringify),
        R.toPairs,
        R.map(x => R.append(x[1], JSON.parse(x[0])))
    )(ds)
Пример #2
0
 const getSuggestions = (apps, seeds) =>
   Promise.all(apps.map(buildGetAppKeywords(store)))
     .then(R.unnest)
     .then(rejectKeywords(seeds))
     .then(R.countBy(R.identity))
     .then(R.toPairs)
     .then(R.sortBy((pair) => -pair[1]))
     .then(R.map(R.prop(0)));
Пример #3
0
    checkBlock(newBlock, previousBlock, referenceBlockchain = this.blocks) {
        const blockHash = newBlock.toHash();

        if (previousBlock.index + 1 !== newBlock.index) { // Check if the block is the last one
            console.error(`Invalid index: expected '${previousBlock.index + 1}' got '${newBlock.index}'`);
            throw new BlockAssertionError(`Invalid index: expected '${previousBlock.index + 1}' got '${newBlock.index}'`);
        } else if (previousBlock.hash !== newBlock.previousHash) { // Check if the previous block is correct
            console.error(`Invalid previoushash: expected '${previousBlock.hash}' got '${newBlock.previousHash}'`);
            throw new BlockAssertionError(`Invalid previoushash: expected '${previousBlock.hash}' got '${newBlock.previousHash}'`);
        } else if (blockHash !== newBlock.hash) { // Check if the hash is correct
            console.error(`Invalid hash: expected '${blockHash}' got '${newBlock.hash}'`);
            throw new BlockAssertionError(`Invalid hash: expected '${blockHash}' got '${newBlock.hash}'`);
        } else if (newBlock.getDifficulty() >= this.getDifficulty(newBlock.index)) { // If the difficulty level of the proof-of-work challenge is correct
            console.error(`Invalid proof-of-work difficulty: expected '${newBlock.getDifficulty()}' to be smaller than '${this.getDifficulty(newBlock.index)}'`);
            throw new BlockAssertionError(`Invalid proof-of-work difficulty: expected '${newBlock.getDifficulty()}' be smaller than '${this.getDifficulty()}'`);
        }

        // INFO: Here it would need to check if the block follows some expectation regarging the minimal number of transactions, value or data size to avoid empty blocks being mined.

        // For each transaction in this block, check if it is valid
        R.forEach(this.checkTransaction.bind(this), newBlock.transactions, referenceBlockchain);

        // Check if the sum of output transactions are equal the sum of input transactions + MINING_REWARD (representing the reward for the block miner)
        let sumOfInputsAmount = R.sum(R.flatten(R.map(R.compose(R.map(R.prop('amount')), R.prop('inputs'), R.prop('data')), newBlock.transactions))) + Config.MINING_REWARD;
        let sumOfOutputsAmount = R.sum(R.flatten(R.map(R.compose(R.map(R.prop('amount')), R.prop('outputs'), R.prop('data')), newBlock.transactions)));

        let isInputsAmountGreaterOrEqualThanOutputsAmount = R.gte(sumOfInputsAmount, sumOfOutputsAmount);

        if (!isInputsAmountGreaterOrEqualThanOutputsAmount) {
            console.error(`Invalid block balance: inputs sum '${sumOfInputsAmount}', outputs sum '${sumOfOutputsAmount}'`);
            throw new BlockAssertionError(`Invalid block balance: inputs sum '${sumOfInputsAmount}', outputs sum '${sumOfOutputsAmount}'`, { sumOfInputsAmount, sumOfOutputsAmount });
        }

        // Check if there is double spending
        let listOfTransactionIndexInputs = R.flatten(R.map(R.compose(R.map(R.compose(R.join('|'), R.props(['transaction', 'index']))), R.prop('inputs'), R.prop('data')), newBlock.transactions));
        let doubleSpendingList = R.filter((x) => x >= 2, R.map(R.length, R.groupBy(x => x)(listOfTransactionIndexInputs)));

        if (R.keys(doubleSpendingList).length) {
            console.error(`There are unspent output transactions being used more than once: unspent output transaction: '${R.keys(doubleSpendingList).join(', ')}'`);
            throw new BlockAssertionError(`There are unspent output transactions being used more than once: unspent output transaction: '${R.keys(doubleSpendingList).join(', ')}'`);
        }

        // Check if there is only 1 fee transaction and 1 reward transaction;
        let transactionsByType = R.countBy(R.prop('type'), newBlock.transactions);
        if (transactionsByType.fee && transactionsByType.fee > 1) {
            console.error(`Invalid fee transaction count: expected '1' got '${transactionsByType.fee}'`);
            throw new BlockAssertionError(`Invalid fee transaction count: expected '1' got '${transactionsByType.fee}'`);
        }

        if (transactionsByType.reward && transactionsByType.reward > 1) {
            console.error(`Invalid reward transaction count: expected '1' got '${transactionsByType.reward}'`);
            throw new BlockAssertionError(`Invalid reward transaction count: expected '1' got '${transactionsByType.reward}'`);
        }

        return true;
    }
Пример #4
0
 function arrayToBuilds(data) {
   let ids = R.map(id => {
     id = id.toString();
     if (id === '2010') id = '2003'; // Biscuits
     return id;
   }, R.pluck('id')(data));
   const counts = R.countBy(R.identity)(ids);
   return R.map(id => ({
     id,
     count: counts[id]
   }), R.uniq(ids));
 }
Пример #5
0
    .then(skills => {
      // Calculate skill order.
      let skill_count = R.countBy(R.toLower)(R.slice(0, 9, skills));
      delete skill_count.r;
      skill_count = R.invertObj(skill_count);
      const counts = R.keys(skill_count).sort().reverse();
      const skill_order = R.join('>', R.map(count_num => {
        return R.toUpper(skill_count[count_num]);
      }, counts));

      return `Okay! Here's the skill order for **${champ_data.name} ${gg_position}**.

**Skill Priority:** ${skill_order}
**Full Order:** ${skills.join(',')}`;
    });
Пример #6
0
	const shannonEntropyByQuestion = unansweredQuestions.map(question => {
		const answerPopulation = Object.values(possibleStatusList).map(
			// $FlowFixMe
			status => status[question]
		)
		const frequencyOfAnswers = Object.values(
			countBy(x => x, answerPopulation.filter(x => x !== undefined))
		).map(
			numOccurrence =>
				// $FlowFixMe
				numOccurrence / answerPopulation.length
		)
		const shannonEntropy = -frequencyOfAnswers
			.map(p => p * Math.log2(p))
			// $FlowFixMe
			.reduce(add, 0)
		return [question, shannonEntropy]
	})
	(attacktree) => {
		if (!attacktree) {
			return [];
		}

		const histogramMap = R.countBy(
			R.toLower,
			helpers.getAllTreeLabels(attacktree)
		);
		const histogram = R.map(
			(pair) => ({
				value: pair[0],
				count: pair[1]
			}),
			R.toPairs(histogramMap)
		);
		return R.pipe(
			R.sortBy(R.prop('count')),
			R.reverse
		)(histogram);
	}
function getAllIdsFromTree(rootNode) {
	const allIds = R.flatten(
		trespass.attacktree.getAllNodes(rootNode)
			.map(R.prop('label'))
			.map(trespass.attacktree.getIdsFromLabel)
	);

	// create histogram
	const histogramMap = R.countBy(R.identity, allIds);
	const histogram = R.sortBy(
		R.prop('count'),
		R.toPairs(histogramMap)
			.map((pair) =>
				({ id: pair[0], count: pair[1] })
			)
	);

	return {
		ids: allIds,
		histogram,
	};
};
Пример #9
0
const checkRequired = isRequired => values => (isRequired && R.isEmpty(values))
  ? [ 'missing required value' ] : []

const check = isImmutable => isRequired => values => changed => {
  const warnings = (isImmutable && ! R.equals(values, changed.values))
    ? [ 'changing immutable field' ] : []
  return warnings.concat(checkRequired(isRequired)(changed.values))
}

const wrap = props => R.map(x => h(Box, props, x))

const countChanges = R.pipe(
  R.countBy(Change.case({
    Addition: () => 'added',
    Deletion: () => 'deleted',
    Mutation: () => 'changed',
    Preservation: () => 'unchanged',
  })),
  R.merge({ added: 0, deleted: 0, changed: 0, unchanged: 0 })
)

const formatCounts = counts => `
 ${counts.deleted} deleted,
 ${counts.added} added,
 ${counts.changed} changed,
 and ${counts.unchanged} unchanged
 ${counts.unchanged > 0 ? '(not shown)' : ''}
`

const showValues = ({
  values,
/*eslint-disable no-undef, no-unused-vars, no-console*/
import _, { compose, pipe, curry, filter, find, repeat, zipWith } from 'ramda'

const ns: Array<number> = [ 1, 2, 3, 4, 5 ]
const ss: Array<string> = [ 'one', 'two', 'three', 'four' ]
const obj: {[k:string]:number} = { a: 1, c: 2 }
const objMixed: {[k:string]:mixed} = { a: 1, c: 'd' }
const os: Array<{[k:string]: *}> = [ { a: 1, c: 'd' }, { b: 2 } ]
const str: string = 'hello world'

const cl:number = _.clamp(1, 10, -1)
const numbers = [ 1.0, 1.1, 1.2, 2.0, 3.0, 2.2 ]
const letters = _.split('', 'abcABCaaaBBc')
// In ramda docs example it's just `Math.floor`
// but we don't want the implicit number -> string
const countB = _.countBy(_.compose(_.toString, Math.floor))(numbers)
const countB1: {[k:string]:number} = _.countBy(_.toLower)(letters)
const diff: Array<number> = _.difference([ 1,2,3,4 ], [ 7,6,5,4,3 ])
//$ExpectError
const diff1: Array<string> = _.difference([ '1', '2' ,'3', '4' ], [ 7, 6, 5, 4, 3 ])

const cmp = (x, y) => x.a === y.a
const l1 = [ { a: 1 }, { a: 2 }, { a: 3 } ]
const l2 = [ { a: 3 }, { a: 4 } ]
const diff2 = _.differenceWith(cmp, l1, l2)

const eqb: boolean = _.eqBy(Math.abs, 5, -5)

const es: boolean = _.equals([ 1, 2, 3 ], [ 1, 2, 3 ])

const _gt: boolean = _.gt(2, 1)
Пример #11
0
  render() {
    const { allPatches, filteredTypes, expandAll } = this.state
        , { selectAll } = this.props
        , editing = !!this.props.onChange

    const filteredPatches =
      filteredTypes.length
        ? allPatches.filter(p => filteredTypes.contains(p.type._name))
        : allPatches

    const countsByType = R.countBy(p => p.type.getLabel(true), allPatches)

    // First, separate out all patches that have to do with periods and
    // authorities. They'll be treated specially
    const [ itemPatches, other ] = R.partition(
      ({ type }) => type.case({
        AddAuthority: R.T,
        ChangeAuthority: R.T,
        RemoveAuthority: R.T,
        AddPeriod: R.T,
        ChangePeriod: R.T,
        RemovePeriod: R.T,
        _: R.F,
      }),
      filteredPatches
    )

    // Then, partition by authority, so that changes to periods in the same
    // authority can be grouped together
    const byAuthority = R.groupBy(R.path(['type', 'authorityID']), itemPatches)

    return (
      h(Box, [
        h(Flex, {
          p: 3,
          mb: 3,
          justifyContent: 'space-between',
          alignItems: 'center',
          bg: 'gray.0',
          border: 1,
          borderColor: 'gray.4',
        }, [
          h(Box, [
            h(Heading, { level: 4, }, 'Patch summary'),
            h(Box, { is: 'ul', ml: 3 }, [
              Object.entries(countsByType).map(([label, count]) =>
                h(Box, { is: 'li', key: label }, `${label} (${count})`)
              )
            ])
          ]),

          h(Box, [
            h(Link, {
              fontSize: 16,
              fontWeight: 'bold',
              href: ' ',
              onClick(e) {
                e.preventDefault();
                const patch = new Blob([
                  JSON.stringify(allPatches.map(p => p.patch), true, '  ')
                ], { type: 'application/json' })

                saveAs(patch, 'patch.jsonpatch')
              }
            }, 'Download patch'),
          ]),
        ]),

        editing && h(Box, {
          is: 'a',
          href: '',
          color: 'blue',
          onClick: e => {
            e.preventDefault();

            this.setState(prev => {
              if (prev.expandAll) {
                return {
                  expandAll: false,
                  expandedPeriods: new Set(),
                  expandedAuthorities: new Set(),
                  viewedAllPeriods: new Set(),
                }
              } else {
                return {
                  expandAll: true,
                }
              }
            })
          }
        }, expandAll ? 'Collapse all' : 'Expand all'),

        editing && h(Box, {
          is: 'a',
          href: '',
          color: 'blue',
          onClick: e => {
            e.preventDefault();

            this.setState(prev => {
              if (prev.selectAll) {
                return {
                  selectAll: false,
                  selectedPatches: new Set(),
                  selectedPeriods: new Set(),
                }
              } else {
                return {
                  selectAll: true,
                }
              }
            })
          }
        }, selectAll ? 'Unselect all' : 'Select all'),

        h(Box, {
          is: 'table',
          css: {
            width: '100%',
            borderCollapse: 'collapse',
          }
        }, [
          h('colgroup', [
            h('col', { style: { width: "50%" }}),
            h('col', { style: { width: "50%" }}),
          ]),
          h('thead', [
            h('tr', [
              h('th', 'Authority'),
              h('th', 'Period'),
            ])
          ]),
          h('tbody', Object.entries(byAuthority).map(([authorityID, patches]) =>
            h(AuthorityRow, Object.assign({
              key: authorityID,
              editing,
              setState: this.setState.bind(this),
              getAuthority: this.getAuthority,
              getPeriod: this.getPeriod,
              patches,
            }, this.state))
          ))
        ])

      ])
    )
  }
Пример #12
0
"use strict";

const R = require('ramda')
    , { periodsWithAuthority } = require('./authority')

// Iterable<Authority> -> List<Period>
//
// Get all of the individual periods within the sequence of authorities.
const periods = R.chain(periodsWithAuthority)

const spatialCoverageCounts = R.pipe(
  R.map(p => p.spatialCoverage.map(
    R.pipe(R.prop('id'), encodeURIComponent))),
  R.countBy(R.identity),
  R.mapObjIndexed((count, countries) => ({
    count,
    countries: countries.split(',').map(x => encodeURIComponent(x)),
  })),
  R.values()
)

// Iterable<Authority> -> Array<Object({ uses, label })>
const spatialCoverages = R.pipe(
  periods,
  R.groupBy(R.prop('spatialCoverageDescription')),
  R.pickBy(R.identity),
  R.map(spatialCoverageCounts),
  R.mapObjIndexed((uses, label) => ({ uses, label })),
  R.values
)
Пример #13
0
import R from 'ramda'

const scoreUpper = scoreVal => R.compose(
  R.sum, 
  R.filter(R.equals(scoreVal))
)

export const scoreOnes = scoreUpper(1)
export const scoreTwos = scoreUpper(2)

const diceCounts = R.countBy(R.identity)
const diceCountsWith = predicate => R.compose(
  R.filter(predicate), 
  diceCounts
)

const diceWithAtleast = count => R.compose(Object.keys, diceCountsWith(c => c >= count))
 
const totalKinds = reducer => ofAKind => R.compose(
  R.reduce(reducer, 0),
  R.map(n => parseInt(n)*ofAKind), 
  diceWithAtleast(ofAKind)
)

const maxKind = totalKinds(R.max)
const sumKinds = totalKinds(R.add)

export const scorePair = maxKind(2)
export const scoreTriple = maxKind(3)
export const scoreTwoPair = sumKinds(2)