Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import groovy.transform.Canonical
- import groovy.transform.EqualsAndHashCode
- import java.util.concurrent.atomic.AtomicLong
- import java.util.stream.Collectors
- import java.util.stream.Stream
- def memo = new HashMap<List<Integer>, Integer>()
- //def N = 8
- //def input = new IntRange(false, 0, N).collect { (Math.random() * 1000).intValue() }
- //println input
- /*
- def getKey(Integer i, Integer w) {
- return Arrays.asList(i, w)
- }
- Integer m(Integer i, Integer w, List<Integer> input, Map<List<Integer>, Integer> memo) {
- def key = Arrays.asList(i, w)
- if (memo.containsKey(key)) {
- return memo.get(key)
- }
- if (i == -1) {
- return 0
- }
- if (input.get(i) > w) {
- def value = m(i - 1, w, input, memo)
- memo.put(key, value)
- return value
- }
- def value = Math.max(
- m(i - 1, w, input, memo),
- m(i - 1, w - input.get(i), input, memo) + input.get(i)
- )
- memo.put(key, value)
- return value
- }
- def ans(Integer i, Integer w, List<Integer> input, Map<List<Integer>, Integer> memo, List<Integer> output) {
- if (i == -1) {
- return
- }
- if (memo.get(getKey(i, w)) == memo.get(getKey(i - 1, w))) {
- ans(i - 1, w, input, memo, output)
- } else {
- output.push(input.get(i))
- ans(i - 1, w - input.get(i), input, memo, output)
- }
- }
- */
- /*def average = input.stream().collect(Collectors.averagingInt { it }).intValue()
- def ref = (average * N * 3 / 4).intValue()
- println average
- println "ref: $ref"
- println m(input.size() - 1, ref, input, memo)
- def result = new ArrayList<Integer>()
- ans(input.size() - 1, ref, input, memo, result)
- println "anwser: $result"*/
- @Canonical
- @EqualsAndHashCode(excludes = ['pledges', 'amount'])
- class Kd {
- Long id
- Double initial
- Double amount
- List<Oo> pledges
- Kd(Long id, Double amount, List<Oo> pledges) {
- this.id = id
- this.initial = this.amount = amount
- this.pledges = pledges
- }
- }
- @Canonical(excludes = 'loans')
- @EqualsAndHashCode(excludes = ['loans', 'amount'])
- class Oo {
- Long id
- Double initial
- Double amount
- Map<Kd, Double> loans
- Oo(Long id, Double amount) {
- this.id = id
- this.amount = this.initial = amount
- }
- }
- /*def reFilter(List<Kd> kdList) {
- List<Kd> newList = kdList.stream().filter { it -> it.amount > 0 }.collect ( Collectors.toList() )
- newList.stream().map { it.pledges }.map { it.stream().filter { it.amount == 0 } }.
- }*/
- def iter(List<Kd> kdList) {
- /* 1. Calculate koef */
- Kd kd = kdList.stream()
- .filter {Kd kd -> kd.pledges.stream().mapToDouble { a -> a.amount }.sum() / kd.amount >= 1 }
- .min(Comparator.comparing { Kd kd -> kd.pledges.stream().mapToDouble { a -> a.amount }.sum() / kd.amount })
- .orElse(
- kdList.stream()
- .filter { !it.pledges.stream().filter { it.amount > 0 }.collect(Collectors.toList()).isEmpty() }
- .findAny()
- .orElse(null)
- )
- if (kd == null) {
- println "ready exit from that devil code"
- return Collections.emptyList()
- }
- print "before: $kd - "
- /* 2. Select min oo */
- Oo oo = kd.pledges.stream()
- .filter { it.amount > 0d }
- .min(Comparator.comparing { Oo oo -> oo.loans.keySet().size() })
- .get()
- /* 3. Push oo to kd and save pledge koef */
- if (kd.amount <= oo.amount) {
- // kd.pledges.put(oo, kd.amount / oo.initial)
- oo.loans.put(kd, oo.loans.get(kd) + kd.amount)
- oo.amount -= kd.amount
- kd.amount = 0
- } else {
- // kd.pledges.put(oo, oo.amount / oo.initial)
- oo.loans.put(kd, oo.loans.get(kd) + oo.amount)
- kd.amount -= oo.amount
- oo.amount = 0
- }
- println "after: $kd"
- //kdList.stream().map { it.pledges.keySet().removeIf { it.amount == 0 } }
- return kdList.stream().filter { it -> it.amount > 0 }.collect ( Collectors.toList() )
- }
- /* 4. Iterate while kd is not empty */
- def calc(List<Kd> kdList) {
- while ( !kdList.isEmpty() ) {
- kdList = iter(kdList)
- }
- }
- def prepareData(List<Kd> kdList, List<Oo> ooList) {
- println "- calc 30%"
- /* 30% */
- List<Kd> initial = kdList.stream().peek { Kd kd -> kd.setAmount( kd.initial * 0.3 ) }.collect(Collectors.toList())
- calc(initial)
- if ( !ooList.stream().filter { it.amount > 0 }.findAny().isPresent() ) {
- return
- }
- /* 100% */
- println "- calc 100%"
- List<Kd> step2 = kdList.stream().peek { Kd kd -> kd.setAmount( kd.initial * 0.7 ) }.collect(Collectors.toList())
- calc(step2)
- if ( !ooList.stream().filter { it.amount > 0 }.findAny().isPresent() ) {
- return
- }
- /* 140% */
- println "- calc 140%"
- List<Kd> step3 = kdList.stream().peek { Kd kd -> kd.setAmount( kd.initial * 0.4 ) }.collect(Collectors.toList())
- calc(step3)
- }
- def test1() {
- println "TEST 1 - BEGIN"
- def N = 6
- def input = new IntRange(false, 0, N).collect { (Math.random() * 1000).intValue() }
- def average = input.stream().collect(Collectors.averagingInt { it }).intValue()
- def ref = (average * N * 3 / 4).doubleValue()
- def oo = new Oo(1L, ref.doubleValue())
- AtomicLong idSeq = new AtomicLong(0)
- def input2 = input.stream().map { new Kd(idSeq.incrementAndGet(), it.doubleValue(), [oo]) }.collect(Collectors.toList())
- oo.setLoans(input2.stream().collect(Collectors.toMap({it -> it}, {Double.valueOf(0)})) as HashMap<Kd, Double>)
- println "kdList: $input"
- println "oo: $oo"
- prepareData(input2, [oo])
- print "coef: "
- oo.loans.values().stream().mapToDouble { it / oo.initial }.forEach { print "$it " }
- def coefSum = oo.loans.values().sum()
- println()
- println "Sum $coefSum"
- println "TEST 2 - END"
- }
- def test2() {
- println "TEST 2 - BEGIN"
- def input = Arrays.asList(10,10,15)
- def oo = new Oo(1, 20d)
- AtomicLong idSeq = new AtomicLong(0)
- List<Kd> input2 = input.stream().map { new Kd(idSeq.incrementAndGet() , it.doubleValue(), [oo]) }.collect(Collectors.toList())
- oo.setLoans(input2.stream().collect(Collectors.toMap({it -> it}, {Double.valueOf(0)})) as HashMap<Kd, Double>)
- println "kdList: $input"
- println "oo: $oo"
- prepareData(input2, [oo])
- print "coef: "
- oo.loans.values().stream().mapToDouble { it / oo.initial }.forEach { print "$it " }
- def coefSum = oo.loans.values().sum()
- println()
- println "Sum $coefSum"
- println "TEST 2 - END"
- }
- def test3() {
- println "TEST 3 - BEGIN"
- def oo1 = new Oo(1L, 20 )
- def oo2 = new Oo(2L, 150 )
- def oo3 = new Oo(3L, 380 )
- def kd1 = new Kd(1L, 100, [oo1, oo2])
- def kd2 = new Kd(2L, 200, [oo1, oo2, oo3])
- def kd3 = new Kd(3L, 300, [oo2, oo3])
- List<Kd> input = [kd1, kd2, kd3]
- List<Oo> ooList = [oo1, oo2, oo3]
- oo1.setLoans([(kd1):0d, (kd2):0d])
- oo2.setLoans([(kd1):0d, (kd2):0d, (kd3):0d])
- oo3.setLoans([(kd2):0d, (kd3):0d])
- println "kdList: $input"
- prepareData(input, ooList)
- print "coef: "
- println()
- ooList.forEach {
- print "oo[$it.id]:"
- println()
- it.loans.keySet().forEach {Kd kd ->
- def amount = it.loans.get(kd)
- def koef = amount / it.initial
- println "$kd.id - $amount ($koef)"
- }
- //it.loans.values().stream().mapToDouble { amount -> amount }.forEach { print "$it " }
- println()
- def sum = it.loans.values().sum()
- println "sum for links: $sum of $it.initial"
- }
- println "TEST 3 - END"
- }
- def all(List<List> list) {
- if (list.size() == 1) {
- return list
- }
- all(list.tail()).stream()
- .flatMap { Stream.of(list.head() + it, it) }
- .collect(Collectors.toList()) << list.head()
- }
- def generate(int count, double chance = 0.2, int ooMax = 50) {
- def kdResult = new IntRange(false, 0, count).collect { id ->
- new Kd(id, (Math.random() * 10).intValue() * 100 + 100d, [])
- }
- long idCounter = 0
- def ooResult = all(kdResult.collect { [it] }).stream()
- .filter { Math.random() > chance }
- .filter { it.size() != 1 }
- .map { List<Kd> kdList ->
- def amount = (Math.random() * ooMax).intValue() * 10 + 20
- def oo = new Oo(idCounter++, amount)
- oo.loans = kdList.collectEntries { [(it): 0d] }
- kdList.each { kd ->
- kd.pledges << oo
- }
- return oo
- }
- .collect(Collectors.toList())
- return [kd: kdResult, oo: ooResult]
- }
- void printTable(List<Kd> kdList, List<Oo> ooList, Closure<Double> mapper = { kd, oo -> oo.loans.get(kd) }) {
- print String.format('%29s', '')
- ooList.each {
- print String.format('%7s', "OO ${it.id + 1}")
- }
- println()
- kdList.each { kd ->
- print String.format('KD %d (%7.1f%7.1f%7.1f):', kd.id + 1, kd.initial * 0.3, kd.initial, kd.initial * 1.4)
- double sum = 0d
- ooList.each { oo ->
- if (kd.pledges.contains(oo)) {
- sum += mapper(kd, oo)
- print String.format('%7.1f', mapper(kd, oo))
- } else {
- print String.format('%6s%1s', '--', '')
- }
- }
- print String.format('%9.1f', sum)
- println()
- }
- }
- def result = generate(5, 0.1, 17)
- printTable(result['kd'], result['oo']) { kd, oo -> oo.amount }
- prepareData(result['kd'], result['oo'])
- printTable(result['kd'], result['oo'])
- //test1()
- //println()
- //test2()
- //println()
- //test3()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement