using System;
using System.Linq;
struct ShortRateTreeNode
{
public double DF;
public double PU;
public double PM;
public double PD;
public int IU;
public int IM;
public int ID;
public ShortRateTreeNode(double df, double pu, double pm, double pd, int iu, int im, int id)
{
this.DF = df;
this.PU = pu;
this.PM = pm;
this.PD = pd;
this.IU = iu;
this.IM = im;
this.ID = id;
}
}
class Program
{
static double[] InduceForward(double[] values, ShortRateTreeNode[] nodes)
{
Func<int, double> next = k => values[values.Length / 2 + k];
return nodes
.Select(node => (node.PU * next(node.IU) + node.PM * next(node.IM) + node.PD * next(node.ID)) * node.DF)
.ToArray();
}
static void Main()
{
var ITERATION = 10000;
Func<double, double[]> maturityValues = x => Enumerable.Repeat(x, 201).ToArray();
var reversedTree = Enumerable.Range(0, 100)
.Reverse()
.Select(i => Enumerable.Range(-i, i * 2 + 1)
.Select(j => new ShortRateTreeNode(1.0, 1.0 / 6.0, 2.0 / 3.0, 1.0 / 6.0, j + 1, j, j - 1))
.ToArray())
.ToArray();
var result = Enumerable.Range(0, ITERATION)
.Select(i => reversedTree.Aggregate(maturityValues(i), InduceForward)[0])
.Max();
Console.WriteLine(result);
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uTGlucTsKCnN0cnVjdCBTaG9ydFJhdGVUcmVlTm9kZQp7CiAgICBwdWJsaWMgZG91YmxlIERGOwogICAgcHVibGljIGRvdWJsZSBQVTsKICAgIHB1YmxpYyBkb3VibGUgUE07CiAgICBwdWJsaWMgZG91YmxlIFBEOwogICAgcHVibGljIGludCBJVTsKICAgIHB1YmxpYyBpbnQgSU07CiAgICBwdWJsaWMgaW50IElEOwoKICAgIHB1YmxpYyBTaG9ydFJhdGVUcmVlTm9kZShkb3VibGUgZGYsIGRvdWJsZSBwdSwgZG91YmxlIHBtLCBkb3VibGUgcGQsIGludCBpdSwgaW50IGltLCBpbnQgaWQpCiAgICB7CiAgICAgICAgdGhpcy5ERiA9IGRmOwogICAgICAgIHRoaXMuUFUgPSBwdTsKICAgICAgICB0aGlzLlBNID0gcG07CiAgICAgICAgdGhpcy5QRCA9IHBkOwogICAgICAgIHRoaXMuSVUgPSBpdTsKICAgICAgICB0aGlzLklNID0gaW07CiAgICAgICAgdGhpcy5JRCA9IGlkOwogICAgfQp9CgpjbGFzcyBQcm9ncmFtCnsKICAgIHN0YXRpYyBkb3VibGVbXSBJbmR1Y2VGb3J3YXJkKGRvdWJsZVtdIHZhbHVlcywgU2hvcnRSYXRlVHJlZU5vZGVbXSBub2RlcykKICAgIHsKICAgICAgICBGdW5jPGludCwgZG91YmxlPiBuZXh0ID0gayA9PiB2YWx1ZXNbdmFsdWVzLkxlbmd0aCAvIDIgKyBrXTsKICAgICAgICByZXR1cm4gbm9kZXMKICAgICAgICAgICAgLlNlbGVjdChub2RlID0+IChub2RlLlBVICogbmV4dChub2RlLklVKSArIG5vZGUuUE0gKiBuZXh0KG5vZGUuSU0pICsgbm9kZS5QRCAqIG5leHQobm9kZS5JRCkpICogbm9kZS5ERikKICAgICAgICAgICAgLlRvQXJyYXkoKTsKICAgIH0KCiAgICBzdGF0aWMgdm9pZCBNYWluKCkKICAgIHsKICAgICAgICB2YXIgSVRFUkFUSU9OID0gMTAwMDA7CiAgICAgICAgRnVuYzxkb3VibGUsIGRvdWJsZVtdPiBtYXR1cml0eVZhbHVlcyA9IHggPT4gRW51bWVyYWJsZS5SZXBlYXQoeCwgMjAxKS5Ub0FycmF5KCk7CiAgICAgICAgdmFyIHJldmVyc2VkVHJlZSA9IEVudW1lcmFibGUuUmFuZ2UoMCwgMTAwKQogICAgICAgICAgICAuUmV2ZXJzZSgpCiAgICAgICAgICAgIC5TZWxlY3QoaSA9PiBFbnVtZXJhYmxlLlJhbmdlKC1pLCBpICogMiArIDEpCiAgICAgICAgICAgICAgICAuU2VsZWN0KGogPT4gbmV3IFNob3J0UmF0ZVRyZWVOb2RlKDEuMCwgMS4wIC8gNi4wLCAyLjAgLyAzLjAsIDEuMCAvIDYuMCwgaiArIDEsIGosIGogLSAxKSkKICAgICAgICAgICAgICAgIC5Ub0FycmF5KCkpCiAgICAgICAgICAgIC5Ub0FycmF5KCk7CiAgICAgICAgdmFyIHJlc3VsdCA9IEVudW1lcmFibGUuUmFuZ2UoMCwgSVRFUkFUSU9OKQogICAgICAgICAgICAuU2VsZWN0KGkgPT4gcmV2ZXJzZWRUcmVlLkFnZ3JlZ2F0ZShtYXR1cml0eVZhbHVlcyhpKSwgSW5kdWNlRm9yd2FyZClbMF0pCiAgICAgICAgICAgIC5NYXgoKTsKICAgICAgICBDb25zb2xlLldyaXRlTGluZShyZXN1bHQpOwogICAgfQp9Cg==