Created
August 21, 2025 10:38
-
-
Save cmelchior/411345e53e55c978bed8bfa3432fcb16 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells" : [ { | |
"metadata" : { }, | |
"cell_type" : "markdown", | |
"source" : [ "# Luck-Meter Exploration\n", "\n", "This notebook is an attempt to explore different ways of representing “luck” in Blood Bowl. \"Luck\" is not well-defined, and will likely mean different things dependig on the context, so the goal of this notebook is to examine several possible approaches and compare them against each other. Ideally finding a way to represent this in the Jervis FFB Client.\n", "\n", "Most statistical analysis requires that we can assign probabilities to rolls. For some rolls, like Dodges or Rushes, this is trivial. For others, like block dice, it gets harder as it is unclear how to treat pushes, e.g., during one-turn-attempts they are probably \"success\" while during normal play, they are at best \"neutral\" (with exceptions). And finally, we have rolls like bounces that are close to impossible to assign success probabilities to.\n", "\n", "For now, we just examine the simple case of rolling single D6 with clear failure/success probabilities.\n", "\n", "**Caveat:** I am not a trained statistician, so it is very likely I am using some terms in this notebook imprecise or wrong. A lot of the implementations and wordings in this notebook came from either Wikipedia or ChatGPT." ], | |
"id" : "59a96b414314441c" | |
}, { | |
"metadata" : { }, | |
"cell_type" : "markdown", | |
"source" : [ "### How to look at dice rolls?\n", "\n", "When rolling dice in Blood Bowl, we are looking at two properties:\n", "1) We want them to be fair, i.e., each value needs to roll each value roughly the same number of times (16.67%).\n", "2) We want to roll the target number (e.g. 4+) every time. If we do, we say we are \"lucky\".\n", "\n", "Some observations:\n", "- These two properties are not connected, but generally it will not be possible to be maximally lucky using fair dice.\n", "- The same set of rolls can result in very different \"luck\" values. E.g. if you use all you 6's on 2+ dodges vs. using them rolling for armor.\n", "\n", "\n", "### Statistical analysis of dice rolls\n", "\n", "If we are rolling _n_ D6, each with their own probability of success. The following properties are true:\n", "\n", "* The total number of successes X is the sum of n independent but non-identical Bernoulli random variables.\n", "* That distribution of this is the Poisson Binomial Distribution.\n", "* For the amount of dice rolls in Blood Bowl, we expect 100-200 rolls and their probability of success is between\n", " 0.83 and 0.16. In this case the Normal Distribution can be used as an approximation.\n" ], | |
"id" : "e624aa99c2987b1c" | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:02.846240Z", | |
"start_time" : "2025-08-21T10:33:02.843524Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : "%use dataframe, kandy", | |
"id" : "4120b9c33fe16d2d", | |
"outputs" : [ ], | |
"execution_count" : 79 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:03.078572Z", | |
"start_time" : "2025-08-21T10:33:02.852782Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "import kotlin.random.Random\n", "\n", "// Helpers and create various distributions\n", "// For now, we only look at single D6's\n", "\n", "// Set to hard-coded value to reproduce results\n", "val seed = 8033212925733483815 // Random.nextLong()\n", "val random = Random(seed)\n", "\n", "/**\n", " * Dice that can be configured to not be fair.\n", " * [bias] determines the percentage a given range is selected\n", " * [towardsLow] determines if [bias] is applied to 1-3 (on D6) or 4-6 (on D6)\n", " */\n", "fun skewedDie(\n", " sides: Int = 6,\n", " bias: Double = 0.5,\n", " towardsLow: Boolean = true\n", "): Int {\n", " require(sides >= 2) { \"Die must have at least 2 sides\" }\n", " require(bias in 0.0..1.0) { \"Bias must be between 0.0 and 1.0\" }\n", "\n", " val half = sides / 2\n", " val lowCount = half + if (sides % 2 != 0) 1 else 0\n", " val highCount = sides - lowCount\n", "\n", " val (favoredCount, unfavoredCount) =\n", " if (towardsLow) lowCount to highCount else highCount to lowCount\n", "\n", " val pFav = bias / favoredCount\n", " val pUnfav = (1 - bias) / unfavoredCount\n", "\n", " val r = random.nextDouble()\n", " var acc = 0.0\n", "\n", " if (towardsLow) {\n", " for (i in 1..lowCount) {\n", " acc += pFav\n", " if (r < acc) return i\n", " }\n", " for (i in (lowCount + 1)..sides) {\n", " acc += pUnfav\n", " if (r < acc) return i\n", " }\n", " } else {\n", " for (i in 1..lowCount) {\n", " acc += pUnfav\n", " if (r < acc) return i\n", " }\n", " for (i in (lowCount + 1)..sides) {\n", " acc += pFav\n", " if (r < acc) return i\n", " }\n", " }\n", " return sides // fallback due to rounding\n", "}\n", "\n", "@DataSchema\n", "data class DiceRoll(val roll: Int, val target: Int, val sides: Int) {\n", " fun successPropability(): Double {\n", " return (sides - (target - 1)) / sides.toDouble()\n", " }\n", " fun failurePropability(): Double {\n", " if (target > sides) return 1.0\n", " return (target - 1) / sides.toDouble()\n", " }\n", " fun neturalPropability() = 0.0\n", " fun isSuccess() = roll >= target\n", " fun isFailure() = roll < target\n", "}" ], | |
"id" : "fe97ccc62aa12d7c", | |
"outputs" : [ ], | |
"execution_count" : 80 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:03.513598Z", | |
"start_time" : "2025-08-21T10:33:03.082216Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "val rolls: Int = 20 * 6 // So we can support tests with an even distribution of buckets\n", "val d6BucketSize: Int = rolls / 6\n", "\n", "// All dice roll the same value\n", "val allOnes = (1..rolls).map {\n", " DiceRoll(1, random.nextInt(2, 7), 6)\n", "}\n", "val allSixes = (1..rolls).map {\n", " DiceRoll(6, random.nextInt(2, 7), 6)\n", "}\n", "\n", "// Even buckets, all fail\n", "val fairDiceAllFail = (1..rolls).map { n ->\n", " val roll = ((n - 1) / d6BucketSize) + 1 // Set dice value based on \"bucket\n", " DiceRoll(roll, 7, 6)\n", "}\n", "val fairDiceAllSucceed = (1..rolls).map { n ->\n", " val roll = ((n - 1) / d6BucketSize) + 1 // Set dice value based on \"bucket\n", " DiceRoll(roll, 1, 6)\n", "}\n", "\n", "// Even distribution of dice. Target roll of 4 (=50% success)\n", "val fairDiceHalfSucceed = (1..rolls).map { n ->\n", " val roll = ((n - 1) / d6BucketSize) + 1 // Set dice value based on \"bucket\n", " DiceRoll(roll, 4, 6)\n", "}\n", "\n", "// Distribution scewed with 75% towards the bottom\n", "val skewedTowardsBottomHalf = (1..rolls).map { n ->\n", " val roll = skewedDie(sides = 6, bias = 0.75, towardsLow = true)\n", " val target = random.nextInt(2, 7)\n", " DiceRoll(roll, target, 6)\n", "}\n", "\n", "// Distribution scewed with 75% towards the top\n", "val skewedTowardsTopHalf = (1..rolls).map { n ->\n", " val roll = skewedDie(sides = 6, bias = 0.75, towardsLow = false)\n", " val target = random.nextInt(2, 7)\n", " DiceRoll(roll, target, 6)\n", "}\n", "\n", "val random1 = (1..rolls).map { n ->\n", " val roll = random.nextInt(1, 7)\n", " val target = random.nextInt(2, 7)\n", " DiceRoll(roll, target, 6)\n", "}\n", "val random2 = (1..rolls).map { n ->\n", " val roll = random.nextInt(1, 7)\n", " val target = random.nextInt(2, 7)\n", " DiceRoll(roll, target, 6)\n", "}\n", "val random3 = (1..rolls).map { n ->\n", " val roll = random.nextInt(1, 7)\n", " val target = random.nextInt(2, 7)\n", " DiceRoll(roll, target, 6)\n", "}\n", "\n", "val randomDiceWith4Target = (1..rolls).map {\n", " val roll = random.nextInt(1, 7)\n", " DiceRoll(roll, 4, 6)\n", "}\n", "\n", "val distributions = listOf(\n", " \"All 1's\" to allOnes,\n", " \"All 6's\" to allSixes,\n", " \"Even buckets - All fail\" to fairDiceAllFail,\n", " \"Even buckets - All succed\" to fairDiceAllSucceed,\n", " \"Even buckets - Half succeed\" to fairDiceHalfSucceed,\n", " \"Scewed towards bottom\" to skewedTowardsBottomHalf,\n", " \"Scewed towards top\" to skewedTowardsTopHalf,\n", " \"Random (4+)\" to randomDiceWith4Target,\n", " \"Random 1\" to random1,\n", " \"Random 2\" to random2,\n", " \"Random 3\" to random3\n", ")" ], | |
"id" : "b9560acdf7223042", | |
"outputs" : [ ], | |
"execution_count" : 81 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:03.969224Z", | |
"start_time" : "2025-08-21T10:33:03.538292Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "// Bucket distributions (how many of each dice was rolled).\n", "// For fair dice we expect 20 in each bucket.\n", "val rollDistributions = distributions.map {\n", " val title = it.first\n", " val df = it.second.toDataFrame()\n", " title to df.groupBy { roll }.count()\n", "}.let { dfs ->\n", " // ensure full dice set {1..6}, fill missing with 0\n", " dfs.map { (name, df) ->\n", " (1..6).toDataFrame(\"roll\")\n", " .leftJoin(df) { \"roll\" match \"roll\" }\n", " .fillNA(\"count\").withZero()\n", " .rename(\"count\").into(name)\n", " }.reduce { acc, df ->\n", " acc.join(df) { \"roll\" match \"roll\" }\n", " }\n", "}.gather { allExcept(\"roll\") }\n", " .into(\"distribution\", \"value\")\n", " .groupBy(\"distribution\")\n", " .pivot(\"roll\")\n", " .aggregate { first().get(\"value\") }\n", " .flatten()\n", "rollDistributions" ], | |
"id" : "67f398fa5ea2e16b", | |
"outputs" : [ { | |
"data" : { | |
"text/html" : [ " <iframe onload=\"o_resize_iframe_out_67()\" style=\"width:100%;\" class=\"result_container\" id=\"iframe_out_67\" frameBorder=\"0\" srcdoc=\" <html theme='dark'>\n", " <head>\n", " <style type="text/css">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme="dark"], :root [data-jp-theme-light="false"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", ":root {\n", " --scroll-bg: #f5f5f5;\n", " --scroll-fg: #b3b3b3;\n", "}\n", ":root[theme="dark"], :root [data-jp-theme-light="false"]{\n", " --scroll-bg: #3c3c3c;\n", " --scroll-fg: #97e1fb;\n", "}\n", "body {\n", " scrollbar-color: var(--scroll-fg) var(--scroll-bg);\n", "}\n", "body::-webkit-scrollbar {\n", " width: 10px; /* Mostly for vertical scrollbars */\n", " height: 10px; /* Mostly for horizontal scrollbars */\n", "}\n", "body::-webkit-scrollbar-thumb {\n", " background-color: var(--scroll-fg);\n", "}\n", "body::-webkit-scrollbar-track {\n", " background-color: var(--scroll-bg);\n", "}\n", " </style>\n", " </head>\n", " <body>\n", " <table class="dataframe" id="df_1946157188"></table>\n", "\n", "<p class="dataframe_description">DataFrame: rowsCount = 11, columnsCount = 7</p>\n", "\n", " </body>\n", " <script>\n", " (function () {\n", " window.DataFrame = window.DataFrame || new (function () {\n", " this.addTable = function (df) {\n", " let cols = df.cols;\n", " for (let i = 0; i < cols.length; i++) {\n", " for (let c of cols[i].children) {\n", " cols[c].parent = i;\n", " }\n", " }\n", " df.nrow = 0\n", " for (let i = 0; i < df.cols.length; i++) {\n", " if (df.cols[i].values.length > df.nrow) df.nrow = df.cols[i].values.length\n", " }\n", " if (df.id === df.rootId) {\n", " df.expandedFrames = new Set()\n", " df.childFrames = {}\n", " const table = this.getTableElement(df.id)\n", " table.df = df\n", " for (let i = 0; i < df.cols.length; i++) {\n", " let col = df.cols[i]\n", " if (col.parent === undefined && col.children.length > 0) col.expanded = true\n", " }\n", " } else {\n", " const rootDf = this.getTableData(df.rootId)\n", " rootDf.childFrames[df.id] = df\n", " }\n", " }\n", "\n", " this.computeRenderData = function (df) {\n", " let result = []\n", " let pos = 0\n", " for (let col = 0; col < df.cols.length; col++) {\n", " if (df.cols[col].parent === undefined)\n", " pos += this.computeRenderDataRec(df.cols, col, pos, 0, result, false, false)\n", " }\n", " for (let i = 0; i < result.length; i++) {\n", " let row = result[i]\n", " for (let j = 0; j < row.length; j++) {\n", " let cell = row[j]\n", " if (j === 0)\n", " cell.leftBd = false\n", " if (j < row.length - 1) {\n", " let nextData = row[j + 1]\n", " if (nextData.leftBd) cell.rightBd = true\n", " else if (cell.rightBd) nextData.leftBd = true\n", " } else cell.rightBd = false\n", " }\n", " }\n", " return result\n", " }\n", "\n", " this.computeRenderDataRec = function (cols, colId, pos, depth, result, leftBorder, rightBorder) {\n", " if (result.length === depth) {\n", " const array = [];\n", " if (pos > 0) {\n", " let j = 0\n", " for (let i = 0; j < pos; i++) {\n", " let c = result[depth - 1][i]\n", " j += c.span\n", " let copy = Object.assign({empty: true}, c)\n", " array.push(copy)\n", " }\n", " }\n", " result.push(array)\n", " }\n", " const col = cols[colId];\n", " let size = 0;\n", " if (col.expanded) {\n", " let childPos = pos\n", " for (let i = 0; i < col.children.length; i++) {\n", " let child = col.children[i]\n", " let childLeft = i === 0 && (col.children.length > 1 || leftBorder)\n", " let childRight = i === col.children.length - 1 && (col.children.length > 1 || rightBorder)\n", " let childSize = this.computeRenderDataRec(cols, child, childPos, depth + 1, result, childLeft, childRight)\n", " childPos += childSize\n", " size += childSize\n", " }\n", " } else {\n", " for (let i = depth + 1; i < result.length; i++)\n", " result[i].push({id: colId, span: 1, leftBd: leftBorder, rightBd: rightBorder, empty: true})\n", " size = 1\n", " }\n", " let left = leftBorder\n", " let right = rightBorder\n", " if (size > 1) {\n", " left = true\n", " right = true\n", " }\n", " result[depth].push({id: colId, span: size, leftBd: left, rightBd: right})\n", " return size\n", " }\n", "\n", " this.getTableElement = function (id) {\n", " return document.getElementById("df_" + id)\n", " }\n", "\n", " this.getTableData = function (id) {\n", " return this.getTableElement(id).df\n", " }\n", "\n", " this.createExpander = function (isExpanded) {\n", " const svgNs = "http://www.w3.org/2000/svg"\n", " let svg = document.createElementNS(svgNs, "svg")\n", " svg.classList.add("expanderSvg")\n", " let path = document.createElementNS(svgNs, "path")\n", " if (isExpanded) {\n", " svg.setAttribute("viewBox", "0 -2 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 4 4 4 -4 -1 -1 -3 3Z")\n", " } else {\n", " svg.setAttribute("viewBox", "-2 0 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 3 3 -3 3 1 1 4 -4Z")\n", " }\n", " path.setAttribute("fill", "currentColor")\n", " svg.appendChild(path)\n", " return svg\n", " }\n", "\n", " this.renderTable = function (id) {\n", "\n", " let table = this.getTableElement(id)\n", "\n", " if (table === null) return\n", "\n", " table.innerHTML = ""\n", "\n", " let df = table.df\n", " let rootDf = df.rootId === df.id ? df : this.getTableData(df.rootId)\n", "\n", " // header\n", " let header = document.createElement("thead")\n", " table.appendChild(header)\n", "\n", " let renderData = this.computeRenderData(df)\n", " for (let j = 0; j < renderData.length; j++) {\n", " let rowData = renderData[j]\n", " let tr = document.createElement("tr");\n", " let isLastRow = j === renderData.length - 1\n", " header.appendChild(tr);\n", " for (let i = 0; i < rowData.length; i++) {\n", " let cell = rowData[i]\n", " let th = document.createElement("th");\n", " th.setAttribute("colspan", cell.span)\n", " let colId = cell.id\n", " let col = df.cols[colId];\n", " if (!cell.empty) {\n", " if (col.children.length === 0) {\n", " th.innerHTML = col.name\n", " } else {\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " col.expanded = !col.expanded\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(col.expanded))\n", " link.innerHTML += col.name\n", " th.appendChild(link)\n", " }\n", " }\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (isLastRow)\n", " classes += " bottomBorder"\n", " if (classes.length > 0)\n", " th.setAttribute("class", classes)\n", " tr.appendChild(th)\n", " }\n", " }\n", "\n", " // body\n", " let body = document.createElement("tbody")\n", " table.appendChild(body)\n", "\n", " let columns = renderData.pop()\n", " for (let row = 0; row < df.nrow; row++) {\n", " let tr = document.createElement("tr");\n", " body.appendChild(tr)\n", " for (let i = 0; i < columns.length; i++) {\n", " let cell = columns[i]\n", " let td = document.createElement("td");\n", " let colId = cell.id\n", " let col = df.cols[colId]\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (classes.length > 0)\n", " td.setAttribute("class", classes)\n", " tr.appendChild(td)\n", " let value = col.values[row]\n", " if (value.frameId !== undefined) {\n", " let frameId = value.frameId\n", " let expanded = rootDf.expandedFrames.has(frameId)\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " if (rootDf.expandedFrames.has(frameId))\n", " rootDf.expandedFrames.delete(frameId)\n", " else rootDf.expandedFrames.add(frameId)\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(expanded))\n", " link.innerHTML += value.value\n", " if (expanded) {\n", " td.appendChild(link)\n", " td.appendChild(document.createElement("p"))\n", " const childTable = document.createElement("table")\n", " childTable.className = "dataframe"\n", " childTable.id = "df_" + frameId\n", " let childDf = rootDf.childFrames[frameId]\n", " childTable.df = childDf\n", " td.appendChild(childTable)\n", " this.renderTable(frameId)\n", " if (childDf.nrow !== childDf.totalRows) {\n", " const footer = document.createElement("p")\n", " footer.innerText = `... showing only top ${childDf.nrow} of ${childDf.totalRows} rows`\n", " td.appendChild(footer)\n", " }\n", " } else {\n", " td.appendChild(link)\n", " }\n", " } else if (value.style !== undefined) {\n", " td.innerHTML = value.value\n", " td.setAttribute("style", value.style)\n", " } else td.innerHTML = value\n", " this.nodeScriptReplace(td)\n", " }\n", " }\n", " }\n", "\n", " this.nodeScriptReplace = function (node) {\n", " if (this.nodeScriptIs(node) === true) {\n", " node.parentNode.replaceChild(this.nodeScriptClone(node), node);\n", " } else {\n", " let i = -1, children = node.childNodes;\n", " while (++i < children.length) {\n", " this.nodeScriptReplace(children[i]);\n", " }\n", " }\n", "\n", " return node;\n", " }\n", "\n", " this.nodeScriptClone = function (node) {\n", " let script = document.createElement("script");\n", " script.text = node.innerHTML;\n", "\n", " let i = -1, attrs = node.attributes, attr;\n", " while (++i < attrs.length) {\n", " script.setAttribute((attr = attrs[i]).name, attr.value);\n", " }\n", " return script;\n", " }\n", "\n", " this.nodeScriptIs = function (node) {\n", " return node.tagName === 'SCRIPT';\n", " }\n", " })()\n", "\n", " window.call_DataFrame = function (f) {\n", " return f();\n", " };\n", "\n", " let funQueue = window["kotlinQueues"] && window["kotlinQueues"]["DataFrame"];\n", " if (funQueue) {\n", " funQueue.forEach(function (f) {\n", " f();\n", " });\n", " funQueue = [];\n", " }\n", "})()\n", "\n", "/*<!--*/\n", "call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "<span title=\"distribution: String\">distribution</span>", children: [], rightAlign: false, values: ["All 1&#39;s","All 6&#39;s","Even buckets - All fail","Even buckets - All succed","Even buckets - Half succeed","Scewed towards bottom","Scewed towards top","Random (4+)","Random 1","Random 2","Random 3"] }, \n", "{ name: "<span title=\"1: Int\">1</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">28</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">9</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">22</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">27</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">19</span></span>"] }, \n", "{ name: "<span title=\"2: Int\">2</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">37</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">10</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">16</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">16</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">15</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">16</span></span>"] }, \n", "{ name: "<span title=\"3: Int\">3</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">26</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">10</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">23</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">22</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">19</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">18</span></span>"] }, \n", "{ name: "<span title=\"4: Int\">4</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">9</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">22</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">21</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">15</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">24</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">26</span></span>"] }, \n", "{ name: "<span title=\"5: Int\">5</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">10</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">41</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">19</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">23</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">18</span></span>"] }, \n", "{ name: "<span title=\"6: Int\">6</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">10</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">28</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">19</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">20</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">19</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">23</span></span>"] }, \n", "], id: 1946157188, rootId: 1946157188, totalRows: 11 } ) });\n", "/*-->*/\n", "\n", "call_DataFrame(function() { DataFrame.renderTable(1946157188) });\n", "\n", "\n", " </script>\n", " </html>\"></iframe>\n", " <script>\n", " function o_resize_iframe_out_67() {\n", " let elem = document.getElementById(\"iframe_out_67\");\n", " resize_iframe_out_67(elem);\n", " setInterval(resize_iframe_out_67, 5000, elem);\n", " }\n", " function resize_iframe_out_67(el) {\n", " let h = el.contentWindow.document.body.scrollHeight;\n", " el.height = h === 0 ? 0 : h + 41;\n", " }\n", " </script> <html theme='dark'>\n", " <head>\n", " <style type=\"text/css\">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme=\"dark\"], :root [data-jp-theme-light=\"false\"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", " </style>\n", " </head>\n", " <body>\n", " <table class=\"dataframe\" id=\"static_df_1946157189\"><thead><tr><th class=\"bottomBorder\" style=\"text-align:left\">distribution</th><th class=\"bottomBorder\" style=\"text-align:left\">1</th><th class=\"bottomBorder\" style=\"text-align:left\">2</th><th class=\"bottomBorder\" style=\"text-align:left\">3</th><th class=\"bottomBorder\" style=\"text-align:left\">4</th><th class=\"bottomBorder\" style=\"text-align:left\">5</th><th class=\"bottomBorder\" style=\"text-align:left\">6</th></tr></thead><tbody><tr><td style=\"vertical-align:top\">All 1's</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0</td></tr><tr><td style=\"vertical-align:top\">All 6's</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">120</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All fail</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All succed</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td></tr><tr><td style=\"vertical-align:top\">Even buckets - Half succeed</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td></tr><tr><td style=\"vertical-align:top\">Scewed towards bottom</td><td style=\"vertical-align:top\">28</td><td style=\"vertical-align:top\">37</td><td style=\"vertical-align:top\">26</td><td style=\"vertical-align:top\">9</td><td style=\"vertical-align:top\">10</td><td style=\"vertical-align:top\">10</td></tr><tr><td style=\"vertical-align:top\">Scewed towards top</td><td style=\"vertical-align:top\">9</td><td style=\"vertical-align:top\">10</td><td style=\"vertical-align:top\">10</td><td style=\"vertical-align:top\">22</td><td style=\"vertical-align:top\">41</td><td style=\"vertical-align:top\">28</td></tr><tr><td style=\"vertical-align:top\">Random (4+)</td><td style=\"vertical-align:top\">22</td><td style=\"vertical-align:top\">16</td><td style=\"vertical-align:top\">23</td><td style=\"vertical-align:top\">21</td><td style=\"vertical-align:top\">19</td><td style=\"vertical-align:top\">19</td></tr><tr><td style=\"vertical-align:top\">Random 1</td><td style=\"vertical-align:top\">27</td><td style=\"vertical-align:top\">16</td><td style=\"vertical-align:top\">22</td><td style=\"vertical-align:top\">15</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">20</td></tr><tr><td style=\"vertical-align:top\">Random 2</td><td style=\"vertical-align:top\">20</td><td style=\"vertical-align:top\">15</td><td style=\"vertical-align:top\">19</td><td style=\"vertical-align:top\">24</td><td style=\"vertical-align:top\">23</td><td style=\"vertical-align:top\">19</td></tr><tr><td style=\"vertical-align:top\">Random 3</td><td style=\"vertical-align:top\">19</td><td style=\"vertical-align:top\">16</td><td style=\"vertical-align:top\">18</td><td style=\"vertical-align:top\">26</td><td style=\"vertical-align:top\">18</td><td style=\"vertical-align:top\">23</td></tr></tbody></table>\n", " </body>\n", " <script>\n", " document.getElementById(\"static_df_1946157189\").style.display = \"none\";\n", " </script>\n", " </html>" ], | |
"application/kotlindataframe+json" : "{\"$version\":\"2.1.1\",\"metadata\":{\"columns\":[\"distribution\",\"1\",\"2\",\"3\",\"4\",\"5\",\"6\"],\"types\":[{\"kind\":\"ValueColumn\",\"type\":\"kotlin.String\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Int\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Int\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Int\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Int\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Int\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Int\"}],\"nrow\":11,\"ncol\":7},\"kotlin_dataframe\":[{\"distribution\":\"All 1's\",\"1\":120,\"2\":0,\"3\":0,\"4\":0,\"5\":0,\"6\":0},{\"distribution\":\"All 6's\",\"1\":0,\"2\":0,\"3\":0,\"4\":0,\"5\":0,\"6\":120},{\"distribution\":\"Even buckets - All fail\",\"1\":20,\"2\":20,\"3\":20,\"4\":20,\"5\":20,\"6\":20},{\"distribution\":\"Even buckets - All succed\",\"1\":20,\"2\":20,\"3\":20,\"4\":20,\"5\":20,\"6\":20},{\"distribution\":\"Even buckets - Half succeed\",\"1\":20,\"2\":20,\"3\":20,\"4\":20,\"5\":20,\"6\":20},{\"distribution\":\"Scewed towards bottom\",\"1\":28,\"2\":37,\"3\":26,\"4\":9,\"5\":10,\"6\":10},{\"distribution\":\"Scewed towards top\",\"1\":9,\"2\":10,\"3\":10,\"4\":22,\"5\":41,\"6\":28},{\"distribution\":\"Random (4+)\",\"1\":22,\"2\":16,\"3\":23,\"4\":21,\"5\":19,\"6\":19},{\"distribution\":\"Random 1\",\"1\":27,\"2\":16,\"3\":22,\"4\":15,\"5\":20,\"6\":20},{\"distribution\":\"Random 2\",\"1\":20,\"2\":15,\"3\":19,\"4\":24,\"5\":23,\"6\":19},{\"distribution\":\"Random 3\",\"1\":19,\"2\":16,\"3\":18,\"4\":26,\"5\":18,\"6\":23}]}" | |
}, | |
"execution_count" : 82, | |
"metadata" : { }, | |
"output_type" : "execute_result" | |
} ], | |
"execution_count" : 82 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:04.274600Z", | |
"start_time" : "2025-08-21T10:33:04.035390Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "// Transpose dataframe so we can create a grouped bar chart\n", "val bucketData = rollDistributions\n", " .gather { colsOf<Int>() }\n", " .into(\"roll\", \"count\")\n", "\n", "// Plot how many of each roll to get a sense of how fair they roll\n", "plot(bucketData) {\n", " bars {\n", " x(\"roll\")\n", " y(\"count\")\n", " fillColor(\"distribution\")\n", " position = Position.dodge()\n", " }\n", " hLine {\n", " yIntercept.constant(20)\n", " color = Color.WHITE\n", " width = 1.0\n", " alpha = 0.8\n", " type = LineType.DASHED\n", " }\n", "\n", " x.axis.name = \"Roll\"\n", " y.axis.name = \"Count\"\n", "}" ], | |
"id" : "dc14e45747b1b762", | |
"outputs" : [ { | |
"data" : { | |
"text/html" : [ " <iframe src='about:blank' style='border:none !important;' width='600' height='400' srcdoc=\"<html lang="en">\n", " <head>\n", " <meta charset="UTF-8">\n", " <style> html, body { margin: 0; overflow: hidden; } </style>\n", " <script type="text/javascript" data-lets-plot-script="library" src="https://cdn.jsdelivr.net/gh/JetBrains/[email protected]/js-package/distr/lets-plot.min.js"></script>\n", " </head>\n", " <body>\n", " <div id="Vy2QFm"></div>\n", " <script type="text/javascript" data-lets-plot-script="plot">\n", " \n", " (function() {\n", " // ----------\n", " \n", " var plotSpec={\n", ""mapping":{\n", "},\n", ""data":{\n", ""roll":["1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6","1","2","3","4","5","6"],\n", ""count":[120.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,120.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,20.0,28.0,37.0,26.0,9.0,10.0,10.0,9.0,10.0,10.0,22.0,41.0,28.0,22.0,16.0,23.0,21.0,19.0,19.0,27.0,16.0,22.0,15.0,20.0,20.0,20.0,15.0,19.0,24.0,23.0,19.0,19.0,16.0,18.0,26.0,18.0,23.0],\n", ""distribution":["All 1's","All 1's","All 1's","All 1's","All 1's","All 1's","All 6's","All 6's","All 6's","All 6's","All 6's","All 6's","Even buckets - All fail","Even buckets - All fail","Even buckets - All fail","Even buckets - All fail","Even buckets - All fail","Even buckets - All fail","Even buckets - All succed","Even buckets - All succed","Even buckets - All succed","Even buckets - All succed","Even buckets - All succed","Even buckets - All succed","Even buckets - Half succeed","Even buckets - Half succeed","Even buckets - Half succeed","Even buckets - Half succeed","Even buckets - Half succeed","Even buckets - Half succeed","Scewed towards bottom","Scewed towards bottom","Scewed towards bottom","Scewed towards bottom","Scewed towards bottom","Scewed towards bottom","Scewed towards top","Scewed towards top","Scewed towards top","Scewed towards top","Scewed towards top","Scewed towards top","Random (4+)","Random (4+)","Random (4+)","Random (4+)","Random (4+)","Random (4+)","Random 1","Random 1","Random 1","Random 1","Random 1","Random 1","Random 2","Random 2","Random 2","Random 2","Random 2","Random 2","Random 3","Random 3","Random 3","Random 3","Random 3","Random 3"]\n", "},\n", ""kind":"plot",\n", ""scales":[{\n", ""aesthetic":"x",\n", ""discrete":true\n", "},{\n", ""aesthetic":"y",\n", ""limits":[null,null]\n", "},{\n", ""aesthetic":"fill",\n", ""discrete":true\n", "},{\n", ""aesthetic":"x",\n", ""name":"Roll",\n", ""limits":[null,null]\n", "},{\n", ""aesthetic":"y",\n", ""name":"Count",\n", ""limits":[null,null]\n", "}],\n", ""layers":[{\n", ""mapping":{\n", ""x":"roll",\n", ""y":"count",\n", ""fill":"distribution"\n", "},\n", ""stat":"identity",\n", ""sampling":"none",\n", ""inherit_aes":false,\n", ""position":"dodge",\n", ""geom":"bar",\n", ""data":{\n", "}\n", "},{\n", ""mapping":{\n", "},\n", ""stat":"identity",\n", ""yintercept":20.0,\n", ""color":"#ffffff",\n", ""size":1.0,\n", ""linetype":"dashed",\n", ""sampling":"none",\n", ""alpha":0.8,\n", ""inherit_aes":false,\n", ""position":"identity",\n", ""geom":"hline",\n", ""data":{\n", "}\n", "}],\n", ""data_meta":{\n", ""series_annotations":[{\n", ""type":"str",\n", ""column":"roll"\n", "},{\n", ""type":"int",\n", ""column":"count"\n", "},{\n", ""type":"str",\n", ""column":"distribution"\n", "}]\n", "},\n", ""spec_id":"8"\n", "};\n", " var containerDiv = document.getElementById("Vy2QFm");\n", " \n", " var toolbar = null;\n", " var plotContainer = containerDiv; \n", " \n", " var options = {\n", " sizing: {\n", " width_mode: "fixed",\n", " height_mode: "fixed",\n", " width: 600.0,\n", " height: 400.0\n", " }\n", " };\n", " var fig = LetsPlot.buildPlotFromProcessedSpecs(plotSpec, -1, -1, plotContainer, options);\n", " if (toolbar) {\n", " toolbar.bind(fig);\n", " }\n", " \n", " // ----------\n", " })();\n", " \n", " </script>\n", " </body>\n", "</html>\"></iframe> <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" display=\"block\" class=\"plt-container\" id=21948750-29f9-4263-8528-dc3a62002700 width=\"100%\" height=\"100%\" style=\"max-width: 600.0px; max-height: 400.0px;\" viewBox=\"0 0 600.0 400.0\" preserveAspectRatio=\"xMinYMin meet\">\n", " <style type=\"text/css\">\n", " .plt-container {\n", " font-family: Lucida Grande, sans-serif;\n", " user-select: none;\n", " -webkit-user-select: none;\n", " -moz-user-select: none;\n", " -ms-user-select: none;\n", "}\n", "text {\n", " text-rendering: optimizeLegibility;\n", "}\n", "#pfc9sN6 .plot-title {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 16.0px;\n", "\n", "}\n", "#pfc9sN6 .plot-subtitle {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 15.0px;\n", "\n", "}\n", "#pfc9sN6 .plot-caption {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#pfc9sN6 .hyperlink-element {\n", "fill: #118ed8;\n", "font-weight: normal;\n", " font-style: normal;\n", "}\n", "#pfc9sN6 .legend-title {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 15.0px;\n", "\n", "}\n", "#pfc9sN6 .legend-item {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#pfc9sN6 .axis-title-x {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 15.0px;\n", "\n", "}\n", "#pfc9sN6 .axis-text-x {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#dw8fuiZ .axis-tooltip-text-x {\n", "fill: #ffffff;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#pfc9sN6 .axis-title-y {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 15.0px;\n", "\n", "}\n", "#pfc9sN6 .axis-text-y {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#dw8fuiZ .axis-tooltip-text-y {\n", "fill: #ffffff;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#pfc9sN6 .facet-strip-text-x {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#pfc9sN6 .facet-strip-text-y {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#dw8fuiZ .tooltip-text {\n", "fill: #474747;\n", "font-weight: normal;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#dw8fuiZ .tooltip-title {\n", "fill: #474747;\n", "font-weight: bold;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "#dw8fuiZ .tooltip-label {\n", "fill: #474747;\n", "font-weight: bold;\n", " font-style: normal;font-family: Lucida Grande, sans-serif;\n", "font-size: 13.0px;\n", "\n", "}\n", "\n", " </style>\n", " <g id=\"pfc9sN6\">\n", " <path fill-rule=\"evenodd\" fill=\"rgb(255,255,255)\" fill-opacity=\"1.0\" d=\"M0.0 0.0 L0.0 400.0 L600.0 400.0 L600.0 0.0 Z\">\n", " </path>\n", " <g transform=\"translate(29.5 6.5 ) \">\n", " <g>\n", " <g transform=\"translate(29.941816366404606 0.0 ) \">\n", " <g>\n", " <line x1=\"29.428164112747407\" y1=\"0.0\" x2=\"29.428164112747407\" y2=\"341.0\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"74.70226274774342\" y1=\"0.0\" x2=\"74.70226274774342\" y2=\"341.0\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"119.97636138273943\" y1=\"0.0\" x2=\"119.97636138273943\" y2=\"341.0\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"165.25046001773543\" y1=\"0.0\" x2=\"165.25046001773543\" y2=\"341.0\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"210.52455865273143\" y1=\"0.0\" x2=\"210.52455865273143\" y2=\"341.0\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"255.79865728772742\" y1=\"0.0\" x2=\"255.79865728772742\" y2=\"341.0\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " </g>\n", " </g>\n", " <g transform=\"translate(29.941816366404606 0.0 ) \">\n", " <g>\n", " <line x1=\"0.0\" y1=\"341.0\" x2=\"285.2268214004749\" y2=\"341.0\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"0.0\" y1=\"286.8730158730159\" x2=\"285.2268214004749\" y2=\"286.8730158730159\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"0.0\" y1=\"232.74603174603175\" x2=\"285.2268214004749\" y2=\"232.74603174603175\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"0.0\" y1=\"178.61904761904762\" x2=\"285.2268214004749\" y2=\"178.61904761904762\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"0.0\" y1=\"124.4920634920635\" x2=\"285.2268214004749\" y2=\"124.4920634920635\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"0.0\" y1=\"70.36507936507934\" x2=\"285.2268214004749\" y2=\"70.36507936507934\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " <line x1=\"0.0\" y1=\"16.23809523809524\" x2=\"285.2268214004749\" y2=\"16.23809523809524\" stroke=\"rgb(233,233,233)\" stroke-opacity=\"1.0\" stroke-width=\"1.0\" fill=\"none\">\n", " </line>\n", " </g>\n", " </g>\n", " </g>\n", " <g clip-path=\"url(#cSTgUta)\" clip-bounds-jfx=\"[rect (29.941816366404606, 0.0), (285.2268214004749, 341.0)]\">\n", " <g transform=\"translate(29.941816366404606 0.0 ) \">\n", " <g>\n", " <g>\n", " <rect x=\"272.46775723970325\" y=\"278.75396825396825\" height=\"62.24603174603175\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(199,41,111)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"227.19365860470722\" y=\"292.2857142857143\" height=\"48.71428571428572\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(199,41,111)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"181.91955996971123\" y=\"270.6349206349206\" height=\"70.3650793650794\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(199,41,111)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"136.6454613347152\" y=\"292.2857142857143\" height=\"48.71428571428572\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(199,41,111)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"91.37136269971921\" y=\"297.6984126984127\" height=\"43.30158730158729\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(199,41,111)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"46.097264064723205\" y=\"289.57936507936506\" height=\"51.42063492063494\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(199,41,111)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"268.7635128059308\" y=\"289.57936507936506\" height=\"51.42063492063494\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(155,196,172)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"223.48941417093482\" y=\"278.75396825396825\" height=\"62.24603174603175\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(155,196,172)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"178.21531553593883\" y=\"276.04761904761904\" height=\"64.95238095238096\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(155,196,172)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"132.94121690094283\" y=\"289.57936507936506\" height=\"51.42063492063494\" width=\"3.7042444337723737\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(155,196,172)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"87.66711826594681\" y=\"300.4047619047619\" height=\"40.595238095238074\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(155,196,172)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"42.39301963095081\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772395\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(155,196,172)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"265.05926837215844\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.7042444337723737\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(153,153,153)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"219.78516973716242\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(153,153,153)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"174.51107110216643\" y=\"300.4047619047619\" height=\"40.595238095238074\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(153,153,153)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"129.23697246717043\" y=\"281.46031746031747\" height=\"59.53968253968253\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(153,153,153)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"83.96287383217442\" y=\"297.6984126984127\" height=\"43.30158730158729\" width=\"3.704244433772388\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(153,153,153)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"38.68877519717841\" y=\"267.92857142857144\" height=\"73.07142857142856\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(153,153,153)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"261.35502393838607\" y=\"289.57936507936506\" height=\"51.42063492063494\" width=\"3.7042444337723737\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(247,129,191)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"216.08092530339005\" y=\"289.57936507936506\" height=\"51.42063492063494\" width=\"3.7042444337723737\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(247,129,191)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"170.80682666839402\" y=\"284.1666666666667\" height=\"56.833333333333314\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(247,129,191)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"125.53272803339802\" y=\"278.75396825396825\" height=\"62.24603174603175\" width=\"3.7042444337724163\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(247,129,191)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"80.25862939840202\" y=\"297.6984126984127\" height=\"43.30158730158729\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(247,129,191)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"34.984530763406006\" y=\"281.46031746031747\" height=\"59.53968253968253\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(247,129,191)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"257.65077950461364\" y=\"265.22222222222223\" height=\"75.77777777777777\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(166,86,40)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"212.37668086961764\" y=\"230.03968253968253\" height=\"110.96031746031747\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(166,86,40)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"167.10258223462162\" y=\"281.46031746031747\" height=\"59.53968253968253\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(166,86,40)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"121.82848359962563\" y=\"313.93650793650795\" height=\"27.06349206349205\" width=\"3.704244433772388\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(166,86,40)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"76.55438496462962\" y=\"313.93650793650795\" height=\"27.06349206349205\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(166,86,40)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"31.280286329633608\" y=\"316.64285714285717\" height=\"24.357142857142833\" width=\"3.7042444337723985\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(166,86,40)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"253.94653507084124\" y=\"313.93650793650795\" height=\"27.06349206349205\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,255,51)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"208.6724364358452\" y=\"313.93650793650795\" height=\"27.06349206349205\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,255,51)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"163.39833780084922\" y=\"316.64285714285717\" height=\"24.357142857142833\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,255,51)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"118.12423916585323\" y=\"270.6349206349206\" height=\"70.3650793650794\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,255,51)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"72.85014053085722\" y=\"240.86507936507934\" height=\"100.13492063492066\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,255,51)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"27.576041895861206\" y=\"265.22222222222223\" height=\"75.77777777777777\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,255,51)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"250.24229063706883\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,127,0)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"204.96819200207284\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.7042444337723737\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,127,0)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"159.69409336707682\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,127,0)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"114.41999473208082\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,127,0)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"69.14589609708482\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,127,0)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"23.871797462088807\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.7042444337723985\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,127,0)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"246.53804620329646\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.7042444337723737\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(152,78,163)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"201.26394756830044\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(152,78,163)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"155.98984893330442\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(152,78,163)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"110.71575029830842\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(152,78,163)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"65.44165166331241\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(152,78,163)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"20.167553028316405\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(152,78,163)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"242.83380176952406\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(77,175,74)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"197.559703134528\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(77,175,74)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"152.285604499532\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(77,175,74)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"107.01150586453602\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(77,175,74)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"61.73740722954001\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(77,175,74)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"16.463308594544003\" y=\"286.8730158730159\" height=\"54.1269841269841\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(77,175,74)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"239.12955733575163\" y=\"16.23809523809524\" height=\"324.76190476190476\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(55,126,184)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"193.85545870075563\" y=\"341.0\" height=\"0.1\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(55,126,184)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"148.58136006575964\" y=\"341.0\" height=\"0.1\" width=\"3.7042444337723737\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(55,126,184)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"103.30726143076363\" y=\"341.0\" height=\"0.1\" width=\"3.704244433772388\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(55,126,184)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"58.03316279576761\" y=\"341.0\" height=\"0.1\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(55,126,184)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"12.759064160771604\" y=\"341.0\" height=\"0.1\" width=\"3.7042444337723985\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(55,126,184)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"235.42531290197923\" y=\"341.0\" height=\"0.1\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(228,26,28)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"190.1512142669832\" y=\"341.0\" height=\"0.1\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(228,26,28)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"144.8771156319872\" y=\"341.0\" height=\"0.1\" width=\"3.7042444337724305\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(228,26,28)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"99.60301699699123\" y=\"341.0\" height=\"0.1\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(228,26,28)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"54.328918361995214\" y=\"341.0\" height=\"0.1\" width=\"3.704244433772395\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(228,26,28)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " <rect x=\"9.054819726999202\" y=\"16.23809523809524\" height=\"324.76190476190476\" width=\"3.704244433772402\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(228,26,28)\" fill-opacity=\"1.0\" stroke-width=\"1.6500000000000001\">\n", " </rect>\n", " </g>\n", " <g>\n", " <line x1=\"0.0\" y1=\"286.8730158730159\" x2=\"285.2268214004749\" y2=\"286.8730158730159\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"0.8\" fill=\"none\" stroke-width=\"2.2\" stroke-dasharray=\"8.8,8.8\" stroke-dashoffset=\"0.0\">\n", " </line>\n", " </g>\n", " </g>\n", " </g>\n", " <defs>\n", " <clipPath id=\"coBwMap\">\n", " <rect x=\"29.941816366404606\" y=\"0.0\" width=\"285.2268214004749\" height=\"341.0\">\n", " </rect>\n", " </clipPath>\n", " </defs>\n", " <defs>\n", " <clipPath id=\"cSTgUta\">\n", " <rect x=\"29.941816366404606\" y=\"0.0\" width=\"285.2268214004749\" height=\"341.0\">\n", " </rect>\n", " </clipPath>\n", " </defs>\n", " </g>\n", " <g>\n", " <g transform=\"translate(29.941816366404606 341.0 ) \">\n", " <g transform=\"translate(29.428164112747407 0.0 ) \">\n", " <line stroke-width=\"1.0\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\" x2=\"0.0\" y2=\"4.0\">\n", " </line>\n", " <g transform=\"translate(0.0 7.0 ) \">\n", " <text class=\"axis-text-x\" text-anchor=\"middle\" dy=\"0.7em\">\n", " <tspan>1</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(74.70226274774342 0.0 ) \">\n", " <line stroke-width=\"1.0\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\" x2=\"0.0\" y2=\"4.0\">\n", " </line>\n", " <g transform=\"translate(0.0 7.0 ) \">\n", " <text class=\"axis-text-x\" text-anchor=\"middle\" dy=\"0.7em\">\n", " <tspan>2</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(119.97636138273943 0.0 ) \">\n", " <line stroke-width=\"1.0\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\" x2=\"0.0\" y2=\"4.0\">\n", " </line>\n", " <g transform=\"translate(0.0 7.0 ) \">\n", " <text class=\"axis-text-x\" text-anchor=\"middle\" dy=\"0.7em\">\n", " <tspan>3</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(165.25046001773543 0.0 ) \">\n", " <line stroke-width=\"1.0\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\" x2=\"0.0\" y2=\"4.0\">\n", " </line>\n", " <g transform=\"translate(0.0 7.0 ) \">\n", " <text class=\"axis-text-x\" text-anchor=\"middle\" dy=\"0.7em\">\n", " <tspan>4</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(210.52455865273143 0.0 ) \">\n", " <line stroke-width=\"1.0\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\" x2=\"0.0\" y2=\"4.0\">\n", " </line>\n", " <g transform=\"translate(0.0 7.0 ) \">\n", " <text class=\"axis-text-x\" text-anchor=\"middle\" dy=\"0.7em\">\n", " <tspan>5</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(255.79865728772742 0.0 ) \">\n", " <line stroke-width=\"1.0\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\" x2=\"0.0\" y2=\"4.0\">\n", " </line>\n", " <g transform=\"translate(0.0 7.0 ) \">\n", " <text class=\"axis-text-x\" text-anchor=\"middle\" dy=\"0.7em\">\n", " <tspan>6</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <line x1=\"0.0\" y1=\"0.0\" x2=\"285.2268214004749\" y2=\"0.0\" stroke-width=\"1.0\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\">\n", " </line>\n", " </g>\n", " <g transform=\"translate(29.941816366404606 0.0 ) \">\n", " <g transform=\"translate(0.0 341.0 ) \">\n", " <g transform=\"translate(-3.0 0.0 ) \">\n", " <text class=\"axis-text-y\" text-anchor=\"end\" dy=\"0.35em\">\n", " <tspan>0</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 286.8730158730159 ) \">\n", " <g transform=\"translate(-3.0 0.0 ) \">\n", " <text class=\"axis-text-y\" text-anchor=\"end\" dy=\"0.35em\">\n", " <tspan>20</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 232.74603174603175 ) \">\n", " <g transform=\"translate(-3.0 0.0 ) \">\n", " <text class=\"axis-text-y\" text-anchor=\"end\" dy=\"0.35em\">\n", " <tspan>40</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 178.61904761904762 ) \">\n", " <g transform=\"translate(-3.0 0.0 ) \">\n", " <text class=\"axis-text-y\" text-anchor=\"end\" dy=\"0.35em\">\n", " <tspan>60</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 124.4920634920635 ) \">\n", " <g transform=\"translate(-3.0 0.0 ) \">\n", " <text class=\"axis-text-y\" text-anchor=\"end\" dy=\"0.35em\">\n", " <tspan>80</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 70.36507936507934 ) \">\n", " <g transform=\"translate(-3.0 0.0 ) \">\n", " <text class=\"axis-text-y\" text-anchor=\"end\" dy=\"0.35em\">\n", " <tspan>100</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 16.23809523809524 ) \">\n", " <g transform=\"translate(-3.0 0.0 ) \">\n", " <text class=\"axis-text-y\" text-anchor=\"end\" dy=\"0.35em\">\n", " <tspan>120</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(16.0 177.0 ) rotate(-90.0 ) \">\n", " <text class=\"axis-title-y\" y=\"0.0\" text-anchor=\"middle\">\n", " <tspan>Count</tspan>\n", " </text>\n", " </g>\n", " <g transform=\"translate(202.05522706664203 393.0 ) \">\n", " <text class=\"axis-title-x\" y=\"0.0\" text-anchor=\"middle\">\n", " <tspan>Roll</tspan>\n", " </text>\n", " </g>\n", " <g transform=\"translate(356.1686377668795 34.25 ) \">\n", " <rect x=\"0.0\" y=\"0.0\" height=\"285.5\" width=\"243.8313622331205\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\" stroke-width=\"0.0\" fill=\"rgb(255,255,255)\" fill-opacity=\"1.0\">\n", " </rect>\n", " <g transform=\"translate(5.0 5.0 ) \">\n", " <g transform=\"translate(0.0 12.0 ) \">\n", " <text class=\"legend-title\" y=\"0.0\">\n", " <tspan>distribution</tspan>\n", " </text>\n", " </g>\n", " <g transform=\"translate(0.0 22.5 ) \">\n", " <g transform=\"\">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(228,26,28)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>All 1's</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 23.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(55,126,184)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>All 6's</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 46.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(77,175,74)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Even buckets - All fail</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 69.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(152,78,163)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Even buckets - All succed</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 92.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,127,0)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Even buckets - Half succeed</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 115.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(255,255,51)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Scewed towards bottom</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 138.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(166,86,40)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Scewed towards top</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 161.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(247,129,191)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Random (4+)</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 184.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(153,153,153)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Random 1</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 207.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(155,196,172)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Random 2</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " <g transform=\"translate(0.0 230.0 ) \">\n", " <g>\n", " <g transform=\"translate(1.0 1.0 ) \">\n", " <g>\n", " <rect x=\"0.0\" y=\"0.0\" height=\"21.0\" width=\"21.0\" stroke=\"rgb(255,255,255)\" stroke-opacity=\"1.0\" fill=\"rgb(199,41,111)\" fill-opacity=\"1.0\" stroke-width=\"1.5\">\n", " </rect>\n", " </g>\n", " </g>\n", " </g>\n", " <g transform=\"translate(26.9903027277341 16.05 ) \">\n", " <text class=\"legend-item\" y=\"0.0\">\n", " <tspan>Random 3</tspan>\n", " </text>\n", " </g>\n", " </g>\n", " </g>\n", " </g>\n", " </g>\n", " <path fill=\"rgb(0,0,0)\" fill-opacity=\"0.0\" stroke=\"rgb(71,71,71)\" stroke-opacity=\"1.0\" stroke-width=\"0.0\" d=\"M0.0 0.0 L0.0 400.0 L600.0 400.0 L600.0 0.0 Z\" pointer-events=\"none\">\n", " </path>\n", " </g>\n", " <g id=\"dw8fuiZ\">\n", " </g>\n", "</svg>\n", " <script>document.getElementById(\"21948750-29f9-4263-8528-dc3a62002700\").style.display = \"none\";</script>" ], | |
"application/plot+json" : { | |
"output_type" : "lets_plot_spec", | |
"output" : { | |
"mapping" : { }, | |
"data" : { | |
"roll" : [ "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6", "1", "2", "3", "4", "5", "6" ], | |
"count" : [ 120.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 120.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 28.0, 37.0, 26.0, 9.0, 10.0, 10.0, 9.0, 10.0, 10.0, 22.0, 41.0, 28.0, 22.0, 16.0, 23.0, 21.0, 19.0, 19.0, 27.0, 16.0, 22.0, 15.0, 20.0, 20.0, 20.0, 15.0, 19.0, 24.0, 23.0, 19.0, 19.0, 16.0, 18.0, 26.0, 18.0, 23.0 ], | |
"distribution" : [ "All 1's", "All 1's", "All 1's", "All 1's", "All 1's", "All 1's", "All 6's", "All 6's", "All 6's", "All 6's", "All 6's", "All 6's", "Even buckets - All fail", "Even buckets - All fail", "Even buckets - All fail", "Even buckets - All fail", "Even buckets - All fail", "Even buckets - All fail", "Even buckets - All succed", "Even buckets - All succed", "Even buckets - All succed", "Even buckets - All succed", "Even buckets - All succed", "Even buckets - All succed", "Even buckets - Half succeed", "Even buckets - Half succeed", "Even buckets - Half succeed", "Even buckets - Half succeed", "Even buckets - Half succeed", "Even buckets - Half succeed", "Scewed towards bottom", "Scewed towards bottom", "Scewed towards bottom", "Scewed towards bottom", "Scewed towards bottom", "Scewed towards bottom", "Scewed towards top", "Scewed towards top", "Scewed towards top", "Scewed towards top", "Scewed towards top", "Scewed towards top", "Random (4+)", "Random (4+)", "Random (4+)", "Random (4+)", "Random (4+)", "Random (4+)", "Random 1", "Random 1", "Random 1", "Random 1", "Random 1", "Random 1", "Random 2", "Random 2", "Random 2", "Random 2", "Random 2", "Random 2", "Random 3", "Random 3", "Random 3", "Random 3", "Random 3", "Random 3" ] | |
}, | |
"kind" : "plot", | |
"scales" : [ { | |
"aesthetic" : "x", | |
"discrete" : true | |
}, { | |
"aesthetic" : "y", | |
"limits" : [ null, null ] | |
}, { | |
"aesthetic" : "fill", | |
"discrete" : true | |
}, { | |
"aesthetic" : "x", | |
"name" : "Roll", | |
"limits" : [ null, null ] | |
}, { | |
"aesthetic" : "y", | |
"name" : "Count", | |
"limits" : [ null, null ] | |
} ], | |
"layers" : [ { | |
"mapping" : { | |
"x" : "roll", | |
"y" : "count", | |
"fill" : "distribution" | |
}, | |
"stat" : "identity", | |
"sampling" : "none", | |
"inherit_aes" : false, | |
"position" : "dodge", | |
"geom" : "bar" | |
}, { | |
"mapping" : { }, | |
"stat" : "identity", | |
"yintercept" : 20.0, | |
"color" : "#ffffff", | |
"size" : 1.0, | |
"linetype" : "dashed", | |
"sampling" : "none", | |
"alpha" : 0.8, | |
"inherit_aes" : false, | |
"position" : "identity", | |
"geom" : "hline" | |
} ], | |
"data_meta" : { | |
"series_annotations" : [ { | |
"type" : "str", | |
"column" : "roll" | |
}, { | |
"type" : "int", | |
"column" : "count" | |
}, { | |
"type" : "str", | |
"column" : "distribution" | |
} ] | |
} | |
}, | |
"apply_color_scheme" : true, | |
"swing_enabled" : true | |
} | |
}, | |
"execution_count" : 83, | |
"metadata" : { }, | |
"output_type" : "execute_result" | |
} ], | |
"execution_count" : 83 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:04.587904Z", | |
"start_time" : "2025-08-21T10:33:04.585329Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : "\n", | |
"id" : "9753b2dc86fd0153", | |
"outputs" : [ ], | |
"execution_count" : 84 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:05.435541Z", | |
"start_time" : "2025-08-21T10:33:04.866494Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "import org.jetbrains.letsPlot.commons.intern.json.getAsDouble\n", "\n", "/**\n", " * Jensen–Shannon divergence (JSD)\n", " * Informally, this is the \"distance\" [0-1] away from the expected distribution.\n", " * This can be converted to a 0-100% value, where 100% is \"maximum fair\" and \"0\"\n", " * is not.\n", " *\n", " * Critic:\n", " * - While the JSD value tells you something about how \"fair\" a die is, it doesn't\n", " * say anything about \"luck\", .e.g., rolling all 1's and rolling all 6's will\n", " * result in the same JSD value.\n", " * - It turns out the maximum value is ~0.65486. Apparently because bigger values\n", " * can only happen when the distributions have disjoint support. I didn't totally\n", " * understand ChatGPTs answer here with regard to dice rolls, but I guess we can\n", " * scale the values so they fit in the [0-1] range.\n", " * - JSD doesn't scale linearly, so exposing it as 0-100% is wrong. If exposed it\n", " * should be a \"fairness index\" instead.\n", " *\n", " * See https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence\n", " */\n", "\n", "/**\n", " * Calculate the Jensen-Shanon Divergence value\n", " * @param rollProberbilities The result of all dice rolls with each index + 1\n", " * being a side on the die and the probability for rolling that die in the trial.\n", " */\n", "fun jensenShannonBits(rollProberbilities: List<Double>): Double {\n", " val sides = rollProberbilities.size\n", " val u = 1 / sides.toDouble() // Uniform distribution\n", " var jsd = 0.0\n", " for (i in 1..sides) {\n", " val p = rollProberbilities[i - 1]\n", " val m = 0.5 * (p + u)\n", " if (p > 0.0) {\n", " jsd += 0.5 * p * (ln(p / m) / ln(2.0))\n", " }\n", " jsd += 0.5 * u * (ln(u / m) / ln(2.0))\n", " }\n", " return jsd // ∈ [0, 1] (bounded by 1 bit)\n", "}\n", "\n", "val jsdMaxForD6 = 0.6548575458\n", "val jsdScale = 1.0 / jsdMaxForD6\n", "val rollProbabilities = rollDistributions\n", " // Informally try to use the numeric \"distance\" from the expected value as a heuristic.\n", " // Since this will require another value to also shift, we just count values above the expected,\n", " // so we do not \"double-count\".\n", " .add(\"distance\") { row ->\n", " row.valuesOf<Int>().fold(0) { acc, v ->\n", " if (v > d6BucketSize) {\n", " acc + (v - d6BucketSize)\n", " } else {\n", " acc\n", " }\n", " }\n", " }\n", " .convert { allExcept(\"distribution\", \"distance\") }.toDouble()\n", " .update { colsOf<Double>() }.with { it / rolls }\n", " .groupBy(\"distribution\")\n", " .aggregate {\n", " val rollProps = it.values { colsOf<Double>() }.toList()\n", " val jsd = jensenShannonBits(rollProps)\n", " // Convert into a [0-1] range with 1.0 meaning uniform distribution\n", " abs(jsdMaxForD6 - jsd)*jsdScale into \"adjustedJSD\"\n", " it.values().last() into \"distance\"\n", " }\n", "rollProbabilities" ], | |
"id" : "230c79eb87fad39b", | |
"outputs" : [ { | |
"data" : { | |
"text/html" : [ " <iframe onload=\"o_resize_iframe_out_69()\" style=\"width:100%;\" class=\"result_container\" id=\"iframe_out_69\" frameBorder=\"0\" srcdoc=\" <html theme='dark'>\n", " <head>\n", " <style type="text/css">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme="dark"], :root [data-jp-theme-light="false"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", ":root {\n", " --scroll-bg: #f5f5f5;\n", " --scroll-fg: #b3b3b3;\n", "}\n", ":root[theme="dark"], :root [data-jp-theme-light="false"]{\n", " --scroll-bg: #3c3c3c;\n", " --scroll-fg: #97e1fb;\n", "}\n", "body {\n", " scrollbar-color: var(--scroll-fg) var(--scroll-bg);\n", "}\n", "body::-webkit-scrollbar {\n", " width: 10px; /* Mostly for vertical scrollbars */\n", " height: 10px; /* Mostly for horizontal scrollbars */\n", "}\n", "body::-webkit-scrollbar-thumb {\n", " background-color: var(--scroll-fg);\n", "}\n", "body::-webkit-scrollbar-track {\n", " background-color: var(--scroll-bg);\n", "}\n", " </style>\n", " </head>\n", " <body>\n", " <table class="dataframe" id="df_1946157192"></table>\n", "\n", "<p class="dataframe_description">DataFrame: rowsCount = 11, columnsCount = 3</p>\n", "\n", " </body>\n", " <script>\n", " (function () {\n", " window.DataFrame = window.DataFrame || new (function () {\n", " this.addTable = function (df) {\n", " let cols = df.cols;\n", " for (let i = 0; i < cols.length; i++) {\n", " for (let c of cols[i].children) {\n", " cols[c].parent = i;\n", " }\n", " }\n", " df.nrow = 0\n", " for (let i = 0; i < df.cols.length; i++) {\n", " if (df.cols[i].values.length > df.nrow) df.nrow = df.cols[i].values.length\n", " }\n", " if (df.id === df.rootId) {\n", " df.expandedFrames = new Set()\n", " df.childFrames = {}\n", " const table = this.getTableElement(df.id)\n", " table.df = df\n", " for (let i = 0; i < df.cols.length; i++) {\n", " let col = df.cols[i]\n", " if (col.parent === undefined && col.children.length > 0) col.expanded = true\n", " }\n", " } else {\n", " const rootDf = this.getTableData(df.rootId)\n", " rootDf.childFrames[df.id] = df\n", " }\n", " }\n", "\n", " this.computeRenderData = function (df) {\n", " let result = []\n", " let pos = 0\n", " for (let col = 0; col < df.cols.length; col++) {\n", " if (df.cols[col].parent === undefined)\n", " pos += this.computeRenderDataRec(df.cols, col, pos, 0, result, false, false)\n", " }\n", " for (let i = 0; i < result.length; i++) {\n", " let row = result[i]\n", " for (let j = 0; j < row.length; j++) {\n", " let cell = row[j]\n", " if (j === 0)\n", " cell.leftBd = false\n", " if (j < row.length - 1) {\n", " let nextData = row[j + 1]\n", " if (nextData.leftBd) cell.rightBd = true\n", " else if (cell.rightBd) nextData.leftBd = true\n", " } else cell.rightBd = false\n", " }\n", " }\n", " return result\n", " }\n", "\n", " this.computeRenderDataRec = function (cols, colId, pos, depth, result, leftBorder, rightBorder) {\n", " if (result.length === depth) {\n", " const array = [];\n", " if (pos > 0) {\n", " let j = 0\n", " for (let i = 0; j < pos; i++) {\n", " let c = result[depth - 1][i]\n", " j += c.span\n", " let copy = Object.assign({empty: true}, c)\n", " array.push(copy)\n", " }\n", " }\n", " result.push(array)\n", " }\n", " const col = cols[colId];\n", " let size = 0;\n", " if (col.expanded) {\n", " let childPos = pos\n", " for (let i = 0; i < col.children.length; i++) {\n", " let child = col.children[i]\n", " let childLeft = i === 0 && (col.children.length > 1 || leftBorder)\n", " let childRight = i === col.children.length - 1 && (col.children.length > 1 || rightBorder)\n", " let childSize = this.computeRenderDataRec(cols, child, childPos, depth + 1, result, childLeft, childRight)\n", " childPos += childSize\n", " size += childSize\n", " }\n", " } else {\n", " for (let i = depth + 1; i < result.length; i++)\n", " result[i].push({id: colId, span: 1, leftBd: leftBorder, rightBd: rightBorder, empty: true})\n", " size = 1\n", " }\n", " let left = leftBorder\n", " let right = rightBorder\n", " if (size > 1) {\n", " left = true\n", " right = true\n", " }\n", " result[depth].push({id: colId, span: size, leftBd: left, rightBd: right})\n", " return size\n", " }\n", "\n", " this.getTableElement = function (id) {\n", " return document.getElementById("df_" + id)\n", " }\n", "\n", " this.getTableData = function (id) {\n", " return this.getTableElement(id).df\n", " }\n", "\n", " this.createExpander = function (isExpanded) {\n", " const svgNs = "http://www.w3.org/2000/svg"\n", " let svg = document.createElementNS(svgNs, "svg")\n", " svg.classList.add("expanderSvg")\n", " let path = document.createElementNS(svgNs, "path")\n", " if (isExpanded) {\n", " svg.setAttribute("viewBox", "0 -2 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 4 4 4 -4 -1 -1 -3 3Z")\n", " } else {\n", " svg.setAttribute("viewBox", "-2 0 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 3 3 -3 3 1 1 4 -4Z")\n", " }\n", " path.setAttribute("fill", "currentColor")\n", " svg.appendChild(path)\n", " return svg\n", " }\n", "\n", " this.renderTable = function (id) {\n", "\n", " let table = this.getTableElement(id)\n", "\n", " if (table === null) return\n", "\n", " table.innerHTML = ""\n", "\n", " let df = table.df\n", " let rootDf = df.rootId === df.id ? df : this.getTableData(df.rootId)\n", "\n", " // header\n", " let header = document.createElement("thead")\n", " table.appendChild(header)\n", "\n", " let renderData = this.computeRenderData(df)\n", " for (let j = 0; j < renderData.length; j++) {\n", " let rowData = renderData[j]\n", " let tr = document.createElement("tr");\n", " let isLastRow = j === renderData.length - 1\n", " header.appendChild(tr);\n", " for (let i = 0; i < rowData.length; i++) {\n", " let cell = rowData[i]\n", " let th = document.createElement("th");\n", " th.setAttribute("colspan", cell.span)\n", " let colId = cell.id\n", " let col = df.cols[colId];\n", " if (!cell.empty) {\n", " if (col.children.length === 0) {\n", " th.innerHTML = col.name\n", " } else {\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " col.expanded = !col.expanded\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(col.expanded))\n", " link.innerHTML += col.name\n", " th.appendChild(link)\n", " }\n", " }\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (isLastRow)\n", " classes += " bottomBorder"\n", " if (classes.length > 0)\n", " th.setAttribute("class", classes)\n", " tr.appendChild(th)\n", " }\n", " }\n", "\n", " // body\n", " let body = document.createElement("tbody")\n", " table.appendChild(body)\n", "\n", " let columns = renderData.pop()\n", " for (let row = 0; row < df.nrow; row++) {\n", " let tr = document.createElement("tr");\n", " body.appendChild(tr)\n", " for (let i = 0; i < columns.length; i++) {\n", " let cell = columns[i]\n", " let td = document.createElement("td");\n", " let colId = cell.id\n", " let col = df.cols[colId]\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (classes.length > 0)\n", " td.setAttribute("class", classes)\n", " tr.appendChild(td)\n", " let value = col.values[row]\n", " if (value.frameId !== undefined) {\n", " let frameId = value.frameId\n", " let expanded = rootDf.expandedFrames.has(frameId)\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " if (rootDf.expandedFrames.has(frameId))\n", " rootDf.expandedFrames.delete(frameId)\n", " else rootDf.expandedFrames.add(frameId)\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(expanded))\n", " link.innerHTML += value.value\n", " if (expanded) {\n", " td.appendChild(link)\n", " td.appendChild(document.createElement("p"))\n", " const childTable = document.createElement("table")\n", " childTable.className = "dataframe"\n", " childTable.id = "df_" + frameId\n", " let childDf = rootDf.childFrames[frameId]\n", " childTable.df = childDf\n", " td.appendChild(childTable)\n", " this.renderTable(frameId)\n", " if (childDf.nrow !== childDf.totalRows) {\n", " const footer = document.createElement("p")\n", " footer.innerText = `... showing only top ${childDf.nrow} of ${childDf.totalRows} rows`\n", " td.appendChild(footer)\n", " }\n", " } else {\n", " td.appendChild(link)\n", " }\n", " } else if (value.style !== undefined) {\n", " td.innerHTML = value.value\n", " td.setAttribute("style", value.style)\n", " } else td.innerHTML = value\n", " this.nodeScriptReplace(td)\n", " }\n", " }\n", " }\n", "\n", " this.nodeScriptReplace = function (node) {\n", " if (this.nodeScriptIs(node) === true) {\n", " node.parentNode.replaceChild(this.nodeScriptClone(node), node);\n", " } else {\n", " let i = -1, children = node.childNodes;\n", " while (++i < children.length) {\n", " this.nodeScriptReplace(children[i]);\n", " }\n", " }\n", "\n", " return node;\n", " }\n", "\n", " this.nodeScriptClone = function (node) {\n", " let script = document.createElement("script");\n", " script.text = node.innerHTML;\n", "\n", " let i = -1, attrs = node.attributes, attr;\n", " while (++i < attrs.length) {\n", " script.setAttribute((attr = attrs[i]).name, attr.value);\n", " }\n", " return script;\n", " }\n", "\n", " this.nodeScriptIs = function (node) {\n", " return node.tagName === 'SCRIPT';\n", " }\n", " })()\n", "\n", " window.call_DataFrame = function (f) {\n", " return f();\n", " };\n", "\n", " let funQueue = window["kotlinQueues"] && window["kotlinQueues"]["DataFrame"];\n", " if (funQueue) {\n", " funQueue.forEach(function (f) {\n", " f();\n", " });\n", " funQueue = [];\n", " }\n", "})()\n", "\n", "/*<!--*/\n", "call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "<span title=\"distribution: String\">distribution</span>", children: [], rightAlign: false, values: ["All 1&#39;s","All 6&#39;s","Even buckets - All fail","Even buckets - All succed","Even buckets - Half succeed","Scewed towards bottom","Scewed towards top","Random (4+)","Random 1","Random 2","Random 3"] }, \n", "{ name: "<span title=\"adjustedJSD: Double\">adjustedJSD</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.915791</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.908715</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.996210</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.989426</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.993842</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.992308</span></span>"] }, \n", "{ name: "<span title=\"distance: Any\">distance</span>", children: [], rightAlign: false, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">100</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">100</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">31</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">31</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">6</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">9</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">7</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">9</span></span>"] }, \n", "], id: 1946157192, rootId: 1946157192, totalRows: 11 } ) });\n", "/*-->*/\n", "\n", "call_DataFrame(function() { DataFrame.renderTable(1946157192) });\n", "\n", "\n", " </script>\n", " </html>\"></iframe>\n", " <script>\n", " function o_resize_iframe_out_69() {\n", " let elem = document.getElementById(\"iframe_out_69\");\n", " resize_iframe_out_69(elem);\n", " setInterval(resize_iframe_out_69, 5000, elem);\n", " }\n", " function resize_iframe_out_69(el) {\n", " let h = el.contentWindow.document.body.scrollHeight;\n", " el.height = h === 0 ? 0 : h + 41;\n", " }\n", " </script> <html theme='dark'>\n", " <head>\n", " <style type=\"text/css\">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme=\"dark\"], :root [data-jp-theme-light=\"false\"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", " </style>\n", " </head>\n", " <body>\n", " <table class=\"dataframe\" id=\"static_df_1946157193\"><thead><tr><th class=\"bottomBorder\" style=\"text-align:left\">distribution</th><th class=\"bottomBorder\" style=\"text-align:left\">adjustedJSD</th><th class=\"bottomBorder\" style=\"text-align:left\">distance</th></tr></thead><tbody><tr><td style=\"vertical-align:top\">All 1's</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">100</td></tr><tr><td style=\"vertical-align:top\">All 6's</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">100</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All fail</td><td style=\"vertical-align:top\">1.000000</td><td style=\"vertical-align:top\">0</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All succed</td><td style=\"vertical-align:top\">1.000000</td><td style=\"vertical-align:top\">0</td></tr><tr><td style=\"vertical-align:top\">Even buckets - Half succeed</td><td style=\"vertical-align:top\">1.000000</td><td style=\"vertical-align:top\">0</td></tr><tr><td style=\"vertical-align:top\">Scewed towards bottom</td><td style=\"vertical-align:top\">0.915791</td><td style=\"vertical-align:top\">31</td></tr><tr><td style=\"vertical-align:top\">Scewed towards top</td><td style=\"vertical-align:top\">0.908715</td><td style=\"vertical-align:top\">31</td></tr><tr><td style=\"vertical-align:top\">Random (4+)</td><td style=\"vertical-align:top\">0.996210</td><td style=\"vertical-align:top\">6</td></tr><tr><td style=\"vertical-align:top\">Random 1</td><td style=\"vertical-align:top\">0.989426</td><td style=\"vertical-align:top\">9</td></tr><tr><td style=\"vertical-align:top\">Random 2</td><td style=\"vertical-align:top\">0.993842</td><td style=\"vertical-align:top\">7</td></tr><tr><td style=\"vertical-align:top\">Random 3</td><td style=\"vertical-align:top\">0.992308</td><td style=\"vertical-align:top\">9</td></tr></tbody></table>\n", " </body>\n", " <script>\n", " document.getElementById(\"static_df_1946157193\").style.display = \"none\";\n", " </script>\n", " </html>" ], | |
"application/kotlindataframe+json" : "{\"$version\":\"2.1.1\",\"metadata\":{\"columns\":[\"distribution\",\"adjustedJSD\",\"distance\"],\"types\":[{\"kind\":\"ValueColumn\",\"type\":\"kotlin.String\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Any\"}],\"nrow\":11,\"ncol\":3},\"kotlin_dataframe\":[{\"distribution\":\"All 1's\",\"adjustedJSD\":4.119314821038707E-11,\"distance\":\"100\"},{\"distribution\":\"All 6's\",\"adjustedJSD\":4.119314821038707E-11,\"distance\":\"100\"},{\"distribution\":\"Even buckets - All fail\",\"adjustedJSD\":1.0,\"distance\":\"0\"},{\"distribution\":\"Even buckets - All succed\",\"adjustedJSD\":1.0,\"distance\":\"0\"},{\"distribution\":\"Even buckets - Half succeed\",\"adjustedJSD\":1.0,\"distance\":\"0\"},{\"distribution\":\"Scewed towards bottom\",\"adjustedJSD\":0.9157912410123433,\"distance\":\"31\"},{\"distribution\":\"Scewed towards top\",\"adjustedJSD\":0.9087146889914467,\"distance\":\"31\"},{\"distribution\":\"Random (4+)\",\"adjustedJSD\":0.9962098509221087,\"distance\":\"6\"},{\"distribution\":\"Random 1\",\"adjustedJSD\":0.98942612739687,\"distance\":\"9\"},{\"distribution\":\"Random 2\",\"adjustedJSD\":0.9938422701625094,\"distance\":\"7\"},{\"distribution\":\"Random 3\",\"adjustedJSD\":0.9923078702224883,\"distance\":\"9\"}]}" | |
}, | |
"execution_count" : 85, | |
"metadata" : { }, | |
"output_type" : "execute_result" | |
} ], | |
"execution_count" : 85 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:05.791959Z", | |
"start_time" : "2025-08-21T10:33:05.480340Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "/**\n", " * Luck-meter, as described on FUMBBL: https://fumbbl.com/help:Luck\n", " * The luck value is a semi-statistical figure that represents the outcome of your rolls compared to the statistically expected average.\n", " *\n", " * It produces a value between [0 - 100], where 50% is \"expected luck\" and 0% is maximally unlucky and 100% is maximally lucky.\n", " *\n", " * Luck = Nominator / Denominator\n", " *\n", " * **Success**\n", " * - Nominator is increased by 1 / (pSuccess + pNeutral / 2)\n", " * - Denominator is increased by 1 / (pSuccess + pNeutral / 2)\n", " *\n", " * This will increase the luck value, but never take it above 1.0.\n", " *\n", " * **Failure**\n", " * - Nominator is unchanged.\n", " * - Denominator is increased by 1 / (pFailure + pNeutral / 2)\n", " *\n", " * This will decrease the luck value, but never take it below 0.\n", " *\n", " * **Neutral**\n", " * - Nominator is increased by 1 / (2 * pSuccess + pNeutral)\n", " * - Denominator is increased by 1 / (2 * pSuccess + pNeutral) + 1 / (2 * pFailure + pNeutral)\n", " *\n", " * Advantage:\n", " * - Tells you something about how lucky or unlucky you are.\n", " * - Easy to calculate.\n", " *\n", " * Critic:\n", " * - Number cannot be compared between games and players.*\n", " */\n", "val names = mutableListOf<String>()\n", "val nominators = mutableListOf<Double>()\n", "val denominators = mutableListOf<Double>()\n", "val luckValues = mutableListOf<Double>()\n", "distributions.forEach { (name, rolls) ->\n", " var nominator = 0.0\n", " var denominator = 0.0\n", " rolls.forEach { roll ->\n", " when (roll.isSuccess()) {\n", " true -> {\n", " val change = (1.0 / ((roll.successPropability() + roll.neturalPropability()/2.0)) )\n", " nominator += change\n", " denominator += change\n", " }\n", " false -> {\n", " denominator += (1.0 / ((roll.failurePropability() + roll.neturalPropability()/2.0)) )\n", " }\n", " }\n", " }\n", " names.add(name)\n", " nominators.add(nominator)\n", " denominators.add(denominator)\n", " luckValues.add(if (denominator == 0.0) 1.0 else (nominator/denominator))\n", "}\n", "val df = dataFrameOf(\n", " \"name\" to names,\n", " \"nominator\" to nominators,\n", " \"denominator\" to denominators,\n", " \"luck\" to luckValues\n", ")\n", "df" ], | |
"id" : "92a73f2edcc5840", | |
"outputs" : [ { | |
"data" : { | |
"text/html" : [ " <iframe onload=\"o_resize_iframe_out_70()\" style=\"width:100%;\" class=\"result_container\" id=\"iframe_out_70\" frameBorder=\"0\" srcdoc=\" <html theme='dark'>\n", " <head>\n", " <style type="text/css">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme="dark"], :root [data-jp-theme-light="false"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", ":root {\n", " --scroll-bg: #f5f5f5;\n", " --scroll-fg: #b3b3b3;\n", "}\n", ":root[theme="dark"], :root [data-jp-theme-light="false"]{\n", " --scroll-bg: #3c3c3c;\n", " --scroll-fg: #97e1fb;\n", "}\n", "body {\n", " scrollbar-color: var(--scroll-fg) var(--scroll-bg);\n", "}\n", "body::-webkit-scrollbar {\n", " width: 10px; /* Mostly for vertical scrollbars */\n", " height: 10px; /* Mostly for horizontal scrollbars */\n", "}\n", "body::-webkit-scrollbar-thumb {\n", " background-color: var(--scroll-fg);\n", "}\n", "body::-webkit-scrollbar-track {\n", " background-color: var(--scroll-bg);\n", "}\n", " </style>\n", " </head>\n", " <body>\n", " <table class="dataframe" id="df_1946157194"></table>\n", "\n", "<p class="dataframe_description">DataFrame: rowsCount = 11, columnsCount = 4</p>\n", "\n", " </body>\n", " <script>\n", " (function () {\n", " window.DataFrame = window.DataFrame || new (function () {\n", " this.addTable = function (df) {\n", " let cols = df.cols;\n", " for (let i = 0; i < cols.length; i++) {\n", " for (let c of cols[i].children) {\n", " cols[c].parent = i;\n", " }\n", " }\n", " df.nrow = 0\n", " for (let i = 0; i < df.cols.length; i++) {\n", " if (df.cols[i].values.length > df.nrow) df.nrow = df.cols[i].values.length\n", " }\n", " if (df.id === df.rootId) {\n", " df.expandedFrames = new Set()\n", " df.childFrames = {}\n", " const table = this.getTableElement(df.id)\n", " table.df = df\n", " for (let i = 0; i < df.cols.length; i++) {\n", " let col = df.cols[i]\n", " if (col.parent === undefined && col.children.length > 0) col.expanded = true\n", " }\n", " } else {\n", " const rootDf = this.getTableData(df.rootId)\n", " rootDf.childFrames[df.id] = df\n", " }\n", " }\n", "\n", " this.computeRenderData = function (df) {\n", " let result = []\n", " let pos = 0\n", " for (let col = 0; col < df.cols.length; col++) {\n", " if (df.cols[col].parent === undefined)\n", " pos += this.computeRenderDataRec(df.cols, col, pos, 0, result, false, false)\n", " }\n", " for (let i = 0; i < result.length; i++) {\n", " let row = result[i]\n", " for (let j = 0; j < row.length; j++) {\n", " let cell = row[j]\n", " if (j === 0)\n", " cell.leftBd = false\n", " if (j < row.length - 1) {\n", " let nextData = row[j + 1]\n", " if (nextData.leftBd) cell.rightBd = true\n", " else if (cell.rightBd) nextData.leftBd = true\n", " } else cell.rightBd = false\n", " }\n", " }\n", " return result\n", " }\n", "\n", " this.computeRenderDataRec = function (cols, colId, pos, depth, result, leftBorder, rightBorder) {\n", " if (result.length === depth) {\n", " const array = [];\n", " if (pos > 0) {\n", " let j = 0\n", " for (let i = 0; j < pos; i++) {\n", " let c = result[depth - 1][i]\n", " j += c.span\n", " let copy = Object.assign({empty: true}, c)\n", " array.push(copy)\n", " }\n", " }\n", " result.push(array)\n", " }\n", " const col = cols[colId];\n", " let size = 0;\n", " if (col.expanded) {\n", " let childPos = pos\n", " for (let i = 0; i < col.children.length; i++) {\n", " let child = col.children[i]\n", " let childLeft = i === 0 && (col.children.length > 1 || leftBorder)\n", " let childRight = i === col.children.length - 1 && (col.children.length > 1 || rightBorder)\n", " let childSize = this.computeRenderDataRec(cols, child, childPos, depth + 1, result, childLeft, childRight)\n", " childPos += childSize\n", " size += childSize\n", " }\n", " } else {\n", " for (let i = depth + 1; i < result.length; i++)\n", " result[i].push({id: colId, span: 1, leftBd: leftBorder, rightBd: rightBorder, empty: true})\n", " size = 1\n", " }\n", " let left = leftBorder\n", " let right = rightBorder\n", " if (size > 1) {\n", " left = true\n", " right = true\n", " }\n", " result[depth].push({id: colId, span: size, leftBd: left, rightBd: right})\n", " return size\n", " }\n", "\n", " this.getTableElement = function (id) {\n", " return document.getElementById("df_" + id)\n", " }\n", "\n", " this.getTableData = function (id) {\n", " return this.getTableElement(id).df\n", " }\n", "\n", " this.createExpander = function (isExpanded) {\n", " const svgNs = "http://www.w3.org/2000/svg"\n", " let svg = document.createElementNS(svgNs, "svg")\n", " svg.classList.add("expanderSvg")\n", " let path = document.createElementNS(svgNs, "path")\n", " if (isExpanded) {\n", " svg.setAttribute("viewBox", "0 -2 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 4 4 4 -4 -1 -1 -3 3Z")\n", " } else {\n", " svg.setAttribute("viewBox", "-2 0 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 3 3 -3 3 1 1 4 -4Z")\n", " }\n", " path.setAttribute("fill", "currentColor")\n", " svg.appendChild(path)\n", " return svg\n", " }\n", "\n", " this.renderTable = function (id) {\n", "\n", " let table = this.getTableElement(id)\n", "\n", " if (table === null) return\n", "\n", " table.innerHTML = ""\n", "\n", " let df = table.df\n", " let rootDf = df.rootId === df.id ? df : this.getTableData(df.rootId)\n", "\n", " // header\n", " let header = document.createElement("thead")\n", " table.appendChild(header)\n", "\n", " let renderData = this.computeRenderData(df)\n", " for (let j = 0; j < renderData.length; j++) {\n", " let rowData = renderData[j]\n", " let tr = document.createElement("tr");\n", " let isLastRow = j === renderData.length - 1\n", " header.appendChild(tr);\n", " for (let i = 0; i < rowData.length; i++) {\n", " let cell = rowData[i]\n", " let th = document.createElement("th");\n", " th.setAttribute("colspan", cell.span)\n", " let colId = cell.id\n", " let col = df.cols[colId];\n", " if (!cell.empty) {\n", " if (col.children.length === 0) {\n", " th.innerHTML = col.name\n", " } else {\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " col.expanded = !col.expanded\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(col.expanded))\n", " link.innerHTML += col.name\n", " th.appendChild(link)\n", " }\n", " }\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (isLastRow)\n", " classes += " bottomBorder"\n", " if (classes.length > 0)\n", " th.setAttribute("class", classes)\n", " tr.appendChild(th)\n", " }\n", " }\n", "\n", " // body\n", " let body = document.createElement("tbody")\n", " table.appendChild(body)\n", "\n", " let columns = renderData.pop()\n", " for (let row = 0; row < df.nrow; row++) {\n", " let tr = document.createElement("tr");\n", " body.appendChild(tr)\n", " for (let i = 0; i < columns.length; i++) {\n", " let cell = columns[i]\n", " let td = document.createElement("td");\n", " let colId = cell.id\n", " let col = df.cols[colId]\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (classes.length > 0)\n", " td.setAttribute("class", classes)\n", " tr.appendChild(td)\n", " let value = col.values[row]\n", " if (value.frameId !== undefined) {\n", " let frameId = value.frameId\n", " let expanded = rootDf.expandedFrames.has(frameId)\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " if (rootDf.expandedFrames.has(frameId))\n", " rootDf.expandedFrames.delete(frameId)\n", " else rootDf.expandedFrames.add(frameId)\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(expanded))\n", " link.innerHTML += value.value\n", " if (expanded) {\n", " td.appendChild(link)\n", " td.appendChild(document.createElement("p"))\n", " const childTable = document.createElement("table")\n", " childTable.className = "dataframe"\n", " childTable.id = "df_" + frameId\n", " let childDf = rootDf.childFrames[frameId]\n", " childTable.df = childDf\n", " td.appendChild(childTable)\n", " this.renderTable(frameId)\n", " if (childDf.nrow !== childDf.totalRows) {\n", " const footer = document.createElement("p")\n", " footer.innerText = `... showing only top ${childDf.nrow} of ${childDf.totalRows} rows`\n", " td.appendChild(footer)\n", " }\n", " } else {\n", " td.appendChild(link)\n", " }\n", " } else if (value.style !== undefined) {\n", " td.innerHTML = value.value\n", " td.setAttribute("style", value.style)\n", " } else td.innerHTML = value\n", " this.nodeScriptReplace(td)\n", " }\n", " }\n", " }\n", "\n", " this.nodeScriptReplace = function (node) {\n", " if (this.nodeScriptIs(node) === true) {\n", " node.parentNode.replaceChild(this.nodeScriptClone(node), node);\n", " } else {\n", " let i = -1, children = node.childNodes;\n", " while (++i < children.length) {\n", " this.nodeScriptReplace(children[i]);\n", " }\n", " }\n", "\n", " return node;\n", " }\n", "\n", " this.nodeScriptClone = function (node) {\n", " let script = document.createElement("script");\n", " script.text = node.innerHTML;\n", "\n", " let i = -1, attrs = node.attributes, attr;\n", " while (++i < attrs.length) {\n", " script.setAttribute((attr = attrs[i]).name, attr.value);\n", " }\n", " return script;\n", " }\n", "\n", " this.nodeScriptIs = function (node) {\n", " return node.tagName === 'SCRIPT';\n", " }\n", " })()\n", "\n", " window.call_DataFrame = function (f) {\n", " return f();\n", " };\n", "\n", " let funQueue = window["kotlinQueues"] && window["kotlinQueues"]["DataFrame"];\n", " if (funQueue) {\n", " funQueue.forEach(function (f) {\n", " f();\n", " });\n", " funQueue = [];\n", " }\n", "})()\n", "\n", "/*<!--*/\n", "call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "<span title=\"name: String\">name</span>", children: [], rightAlign: false, values: ["All 1&#39;s","All 6&#39;s","Even buckets - All fail","Even buckets - All succed","Even buckets - Half succeed","Scewed towards bottom","Scewed towards top","Random (4+)","Random 1","Random 2","Random 3"] }, \n", "{ name: "<span title=\"nominator: Double\">nominator</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">309.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">69.300000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">166.400000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">118.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">109.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">140.600000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">149.500000</span></span>"] }, \n", "{ name: "<span title=\"denominator: Double\">denominator</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">312.200000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">309.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">240.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">243.600000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">240.600000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">240.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">256.700000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">274.100000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">250.600000</span></span>"] }, \n", "{ name: "<span title=\"luck: Double\">luck</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.500000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.284483</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.691604</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.491667</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.424620</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.512951</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.596568</span></span>"] }, \n", "], id: 1946157194, rootId: 1946157194, totalRows: 11 } ) });\n", "/*-->*/\n", "\n", "call_DataFrame(function() { DataFrame.renderTable(1946157194) });\n", "\n", "\n", " </script>\n", " </html>\"></iframe>\n", " <script>\n", " function o_resize_iframe_out_70() {\n", " let elem = document.getElementById(\"iframe_out_70\");\n", " resize_iframe_out_70(elem);\n", " setInterval(resize_iframe_out_70, 5000, elem);\n", " }\n", " function resize_iframe_out_70(el) {\n", " let h = el.contentWindow.document.body.scrollHeight;\n", " el.height = h === 0 ? 0 : h + 41;\n", " }\n", " </script> <html theme='dark'>\n", " <head>\n", " <style type=\"text/css\">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme=\"dark\"], :root [data-jp-theme-light=\"false\"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", " </style>\n", " </head>\n", " <body>\n", " <table class=\"dataframe\" id=\"static_df_1946157195\"><thead><tr><th class=\"bottomBorder\" style=\"text-align:left\">name</th><th class=\"bottomBorder\" style=\"text-align:left\">nominator</th><th class=\"bottomBorder\" style=\"text-align:left\">denominator</th><th class=\"bottomBorder\" style=\"text-align:left\">luck</th></tr></thead><tbody><tr><td style=\"vertical-align:top\">All 1's</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">312.200000</td><td style=\"vertical-align:top\">0.000000</td></tr><tr><td style=\"vertical-align:top\">All 6's</td><td style=\"vertical-align:top\">309.000000</td><td style=\"vertical-align:top\">309.000000</td><td style=\"vertical-align:top\">1.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All fail</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">120.000000</td><td style=\"vertical-align:top\">0.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All succed</td><td style=\"vertical-align:top\">120.000000</td><td style=\"vertical-align:top\">120.000000</td><td style=\"vertical-align:top\">1.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - Half succeed</td><td style=\"vertical-align:top\">120.000000</td><td style=\"vertical-align:top\">240.000000</td><td style=\"vertical-align:top\">0.500000</td></tr><tr><td style=\"vertical-align:top\">Scewed towards bottom</td><td style=\"vertical-align:top\">69.300000</td><td style=\"vertical-align:top\">243.600000</td><td style=\"vertical-align:top\">0.284483</td></tr><tr><td style=\"vertical-align:top\">Scewed towards top</td><td style=\"vertical-align:top\">166.400000</td><td style=\"vertical-align:top\">240.600000</td><td style=\"vertical-align:top\">0.691604</td></tr><tr><td style=\"vertical-align:top\">Random (4+)</td><td style=\"vertical-align:top\">118.000000</td><td style=\"vertical-align:top\">240.000000</td><td style=\"vertical-align:top\">0.491667</td></tr><tr><td style=\"vertical-align:top\">Random 1</td><td style=\"vertical-align:top\">109.000000</td><td style=\"vertical-align:top\">256.700000</td><td style=\"vertical-align:top\">0.424620</td></tr><tr><td style=\"vertical-align:top\">Random 2</td><td style=\"vertical-align:top\">140.600000</td><td style=\"vertical-align:top\">274.100000</td><td style=\"vertical-align:top\">0.512951</td></tr><tr><td style=\"vertical-align:top\">Random 3</td><td style=\"vertical-align:top\">149.500000</td><td style=\"vertical-align:top\">250.600000</td><td style=\"vertical-align:top\">0.596568</td></tr></tbody></table>\n", " </body>\n", " <script>\n", " document.getElementById(\"static_df_1946157195\").style.display = \"none\";\n", " </script>\n", " </html>" ], | |
"application/kotlindataframe+json" : "{\"$version\":\"2.1.1\",\"metadata\":{\"columns\":[\"name\",\"nominator\",\"denominator\",\"luck\"],\"types\":[{\"kind\":\"ValueColumn\",\"type\":\"kotlin.String\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"}],\"nrow\":11,\"ncol\":4},\"kotlin_dataframe\":[{\"name\":\"All 1's\",\"nominator\":0.0,\"denominator\":312.19999999999993,\"luck\":0.0},{\"name\":\"All 6's\",\"nominator\":308.9999999999999,\"denominator\":308.9999999999999,\"luck\":1.0},{\"name\":\"Even buckets - All fail\",\"nominator\":0.0,\"denominator\":120.0,\"luck\":0.0},{\"name\":\"Even buckets - All succed\",\"nominator\":120.0,\"denominator\":120.0,\"luck\":1.0},{\"name\":\"Even buckets - Half succeed\",\"nominator\":120.0,\"denominator\":240.0,\"luck\":0.5},{\"name\":\"Scewed towards bottom\",\"nominator\":69.30000000000003,\"denominator\":243.59999999999985,\"luck\":0.28448275862068995},{\"name\":\"Scewed towards top\",\"nominator\":166.40000000000003,\"denominator\":240.59999999999994,\"luck\":0.6916043225270161},{\"name\":\"Random (4+)\",\"nominator\":118.0,\"denominator\":240.0,\"luck\":0.49166666666666664},{\"name\":\"Random 1\",\"nominator\":109.00000000000004,\"denominator\":256.6999999999998,\"luck\":0.4246201791975073},{\"name\":\"Random 2\",\"nominator\":140.60000000000002,\"denominator\":274.0999999999998,\"luck\":0.5129514775629337},{\"name\":\"Random 3\",\"nominator\":149.50000000000006,\"denominator\":250.59999999999985,\"luck\":0.5965682362330412}]}" | |
}, | |
"execution_count" : 86, | |
"metadata" : { }, | |
"output_type" : "execute_result" | |
} ], | |
"execution_count" : 86 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:06.623331Z", | |
"start_time" : "2025-08-21T10:33:05.954806Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "import org.jetbrains.kotlinx.statistics.math3.special.Erf.erf\n", "\n", "/**\n", " * Asking ChatGPT it suggested using the Z-Score for a series of Bernoulli Trials.\n", " *\n", " * Definition: Z score is the number (distance) of standard deviation away (above or below) the mean.\n", " * By definition the Z score of the mean is 0.\n", " *\n", " * This means that the Z-score can say something about how extreme an outcome is within its own distribution,\n", " * which can be compared to other games or players. The absolute number of dice rolled and success can be different\n", " * and still have the same Z-score. It just tells you something about how likely the outcome was given the total\n", " * amount of dice rolled.\n", " *\n", " *\n", " * Advantage:\n", " * - Standard way to look at probabilities\n", " * - Can be compared against other players and games\n", " *\n", " *\n", " * Critic:\n", " * - Z-score is hard to map to a [0-1] range, so it is more like a \"luck-index\"\n", " * - Z-score is not linear.\n", " * - If either all succeed or all fail the Z-score is `null`.\n", " *\n", " * Keep the setup classes in a seperate cell so we can create the @DataSchema automatically\n", " *\n", " * See https://en.wikipedia.org/wiki/Standard_score\n", " * See https://en.wikipedia.org/wiki/Bernoulli_trial\n", " */\n", "\n", "/**\n", " * Wrap Roll results for Bernoulli trial calculations\n", " * @param p Probability [0-1] that the roll is a success\n", " * @param success the roll was an actual success\n", " */\n", "data class Roll(val p: Double, val success: Boolean)\n", "\n", "/** Core aggregates */\n", "@DataSchema\n", "data class LuckSummary(\n", " val n: Int,\n", " val successes: Int,\n", " val expected: Double,\n", " val variance: Double,\n", " val centeredLuck: Double, // S - μ\n", " val zScore: Double?, // (S-μ)/σ, null if σ==0\n", " val tailP: Double, // P(X >= S)\n", " val surprisalLog10: Double, // -log10(tailP)\n", " val rarityPercentage: Double? // Two-sided rarity % (assuming normal distribution)\n", ")\n", "\n", "@DataSchema\n", "data class LuckRow(\n", " val name: String,\n", " val summary: LuckSummary\n", ")\n", "\n", "\n", "/** Exact Poisson–binomial tail P(X >= s) via O(n^2) DP. */\n", "fun tailProbAtLeast(ps: DoubleArray, s: Int): Double {\n", " val n = ps.size\n", " var dp = DoubleArray(n + 1) { 0.0 }\n", " dp[0] = 1.0\n", " for (p in ps) {\n", " val next = DoubleArray(n + 1)\n", " for (k in 0..n) {\n", " if (dp[k] == 0.0) continue\n", " next[k] += dp[k] * (1 - p) // failure\n", " if (k + 1 <= n) next[k + 1] += dp[k] * p // success\n", " }\n", " dp = next\n", " }\n", " var tail = 0.0\n", " for (k in s..n) tail += dp[k]\n", " return tail.coerceIn(0.0, 1.0)\n", "}\n", "\n", "/**\n", " * one-sided rarity % for a Z-score (negative is \"bad luck\", positive is \"good luck\")\n", " * Note, this assumes a normal distribution, which dice rolls only approximate. It will especially be off at a low amount of rolls\n", " */\n", "fun rarityPercent(zScore: Double): Double {\n", " val oneSidedTail = 0.5 * (1 - erf(abs(zScore) / sqrt(2.0))) * 100.0\n", " return if (zScore >= 0) oneSidedTail else -oneSidedTail\n", "}\n", "\n", "fun summarizeLuck(rolls: List<Roll>): LuckSummary {\n", " val ps = rolls.map { it.p }.toDoubleArray()\n", " val s = rolls.count { it.success }\n", " val expected = ps.sum()\n", " val variance = ps.sumOf { it * (1 - it) }\n", " val sigma = kotlin.math.sqrt(variance)\n", " val centered = s - expected\n", " val z = if (sigma > 0) centered / sigma else null\n", " val tailP = tailProbAtLeast(ps, s)\n", " val surprisal = if (tailP > 0) -kotlin.math.log10(tailP) else Double.POSITIVE_INFINITY\n", " return LuckSummary(\n", " n = rolls.size,\n", " successes = s,\n", " expected = expected,\n", " variance = variance,\n", " centeredLuck = centered,\n", " zScore = z,\n", " tailP = tailP,\n", " surprisalLog10 = surprisal,\n", " rarityPercentage = if (z != null) rarityPercent(z) else null\n", " )\n", "}" ], | |
"id" : "e473c59b8da9bbc6", | |
"outputs" : [ ], | |
"execution_count" : 87 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:06.843720Z", | |
"start_time" : "2025-08-21T10:33:06.691663Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "val zScoreLuckSummary = distributions.map { (name, rolls) ->\n", " val rollsWithProbabilities = rolls.map {\n", " Roll(it.successPropability(), it.isSuccess())\n", " }\n", " LuckRow(name, summarizeLuck(rollsWithProbabilities))\n", "}.toDataFrame().flatten()\n", "zScoreLuckSummary" ], | |
"id" : "1302d416180e2539", | |
"outputs" : [ { | |
"data" : { | |
"text/html" : [ " <iframe onload=\"o_resize_iframe_out_73()\" style=\"width:100%;\" class=\"result_container\" id=\"iframe_out_73\" frameBorder=\"0\" srcdoc=\" <html theme='dark'>\n", " <head>\n", " <style type="text/css">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme="dark"], :root [data-jp-theme-light="false"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", ":root {\n", " --scroll-bg: #f5f5f5;\n", " --scroll-fg: #b3b3b3;\n", "}\n", ":root[theme="dark"], :root [data-jp-theme-light="false"]{\n", " --scroll-bg: #3c3c3c;\n", " --scroll-fg: #97e1fb;\n", "}\n", "body {\n", " scrollbar-color: var(--scroll-fg) var(--scroll-bg);\n", "}\n", "body::-webkit-scrollbar {\n", " width: 10px; /* Mostly for vertical scrollbars */\n", " height: 10px; /* Mostly for horizontal scrollbars */\n", "}\n", "body::-webkit-scrollbar-thumb {\n", " background-color: var(--scroll-fg);\n", "}\n", "body::-webkit-scrollbar-track {\n", " background-color: var(--scroll-bg);\n", "}\n", " </style>\n", " </head>\n", " <body>\n", " <table class="dataframe" id="df_1946157200"></table>\n", "\n", "<p class="dataframe_description">DataFrame: rowsCount = 11, columnsCount = 10</p>\n", "\n", " </body>\n", " <script>\n", " (function () {\n", " window.DataFrame = window.DataFrame || new (function () {\n", " this.addTable = function (df) {\n", " let cols = df.cols;\n", " for (let i = 0; i < cols.length; i++) {\n", " for (let c of cols[i].children) {\n", " cols[c].parent = i;\n", " }\n", " }\n", " df.nrow = 0\n", " for (let i = 0; i < df.cols.length; i++) {\n", " if (df.cols[i].values.length > df.nrow) df.nrow = df.cols[i].values.length\n", " }\n", " if (df.id === df.rootId) {\n", " df.expandedFrames = new Set()\n", " df.childFrames = {}\n", " const table = this.getTableElement(df.id)\n", " table.df = df\n", " for (let i = 0; i < df.cols.length; i++) {\n", " let col = df.cols[i]\n", " if (col.parent === undefined && col.children.length > 0) col.expanded = true\n", " }\n", " } else {\n", " const rootDf = this.getTableData(df.rootId)\n", " rootDf.childFrames[df.id] = df\n", " }\n", " }\n", "\n", " this.computeRenderData = function (df) {\n", " let result = []\n", " let pos = 0\n", " for (let col = 0; col < df.cols.length; col++) {\n", " if (df.cols[col].parent === undefined)\n", " pos += this.computeRenderDataRec(df.cols, col, pos, 0, result, false, false)\n", " }\n", " for (let i = 0; i < result.length; i++) {\n", " let row = result[i]\n", " for (let j = 0; j < row.length; j++) {\n", " let cell = row[j]\n", " if (j === 0)\n", " cell.leftBd = false\n", " if (j < row.length - 1) {\n", " let nextData = row[j + 1]\n", " if (nextData.leftBd) cell.rightBd = true\n", " else if (cell.rightBd) nextData.leftBd = true\n", " } else cell.rightBd = false\n", " }\n", " }\n", " return result\n", " }\n", "\n", " this.computeRenderDataRec = function (cols, colId, pos, depth, result, leftBorder, rightBorder) {\n", " if (result.length === depth) {\n", " const array = [];\n", " if (pos > 0) {\n", " let j = 0\n", " for (let i = 0; j < pos; i++) {\n", " let c = result[depth - 1][i]\n", " j += c.span\n", " let copy = Object.assign({empty: true}, c)\n", " array.push(copy)\n", " }\n", " }\n", " result.push(array)\n", " }\n", " const col = cols[colId];\n", " let size = 0;\n", " if (col.expanded) {\n", " let childPos = pos\n", " for (let i = 0; i < col.children.length; i++) {\n", " let child = col.children[i]\n", " let childLeft = i === 0 && (col.children.length > 1 || leftBorder)\n", " let childRight = i === col.children.length - 1 && (col.children.length > 1 || rightBorder)\n", " let childSize = this.computeRenderDataRec(cols, child, childPos, depth + 1, result, childLeft, childRight)\n", " childPos += childSize\n", " size += childSize\n", " }\n", " } else {\n", " for (let i = depth + 1; i < result.length; i++)\n", " result[i].push({id: colId, span: 1, leftBd: leftBorder, rightBd: rightBorder, empty: true})\n", " size = 1\n", " }\n", " let left = leftBorder\n", " let right = rightBorder\n", " if (size > 1) {\n", " left = true\n", " right = true\n", " }\n", " result[depth].push({id: colId, span: size, leftBd: left, rightBd: right})\n", " return size\n", " }\n", "\n", " this.getTableElement = function (id) {\n", " return document.getElementById("df_" + id)\n", " }\n", "\n", " this.getTableData = function (id) {\n", " return this.getTableElement(id).df\n", " }\n", "\n", " this.createExpander = function (isExpanded) {\n", " const svgNs = "http://www.w3.org/2000/svg"\n", " let svg = document.createElementNS(svgNs, "svg")\n", " svg.classList.add("expanderSvg")\n", " let path = document.createElementNS(svgNs, "path")\n", " if (isExpanded) {\n", " svg.setAttribute("viewBox", "0 -2 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 4 4 4 -4 -1 -1 -3 3Z")\n", " } else {\n", " svg.setAttribute("viewBox", "-2 0 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 3 3 -3 3 1 1 4 -4Z")\n", " }\n", " path.setAttribute("fill", "currentColor")\n", " svg.appendChild(path)\n", " return svg\n", " }\n", "\n", " this.renderTable = function (id) {\n", "\n", " let table = this.getTableElement(id)\n", "\n", " if (table === null) return\n", "\n", " table.innerHTML = ""\n", "\n", " let df = table.df\n", " let rootDf = df.rootId === df.id ? df : this.getTableData(df.rootId)\n", "\n", " // header\n", " let header = document.createElement("thead")\n", " table.appendChild(header)\n", "\n", " let renderData = this.computeRenderData(df)\n", " for (let j = 0; j < renderData.length; j++) {\n", " let rowData = renderData[j]\n", " let tr = document.createElement("tr");\n", " let isLastRow = j === renderData.length - 1\n", " header.appendChild(tr);\n", " for (let i = 0; i < rowData.length; i++) {\n", " let cell = rowData[i]\n", " let th = document.createElement("th");\n", " th.setAttribute("colspan", cell.span)\n", " let colId = cell.id\n", " let col = df.cols[colId];\n", " if (!cell.empty) {\n", " if (col.children.length === 0) {\n", " th.innerHTML = col.name\n", " } else {\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " col.expanded = !col.expanded\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(col.expanded))\n", " link.innerHTML += col.name\n", " th.appendChild(link)\n", " }\n", " }\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (isLastRow)\n", " classes += " bottomBorder"\n", " if (classes.length > 0)\n", " th.setAttribute("class", classes)\n", " tr.appendChild(th)\n", " }\n", " }\n", "\n", " // body\n", " let body = document.createElement("tbody")\n", " table.appendChild(body)\n", "\n", " let columns = renderData.pop()\n", " for (let row = 0; row < df.nrow; row++) {\n", " let tr = document.createElement("tr");\n", " body.appendChild(tr)\n", " for (let i = 0; i < columns.length; i++) {\n", " let cell = columns[i]\n", " let td = document.createElement("td");\n", " let colId = cell.id\n", " let col = df.cols[colId]\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (classes.length > 0)\n", " td.setAttribute("class", classes)\n", " tr.appendChild(td)\n", " let value = col.values[row]\n", " if (value.frameId !== undefined) {\n", " let frameId = value.frameId\n", " let expanded = rootDf.expandedFrames.has(frameId)\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " if (rootDf.expandedFrames.has(frameId))\n", " rootDf.expandedFrames.delete(frameId)\n", " else rootDf.expandedFrames.add(frameId)\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(expanded))\n", " link.innerHTML += value.value\n", " if (expanded) {\n", " td.appendChild(link)\n", " td.appendChild(document.createElement("p"))\n", " const childTable = document.createElement("table")\n", " childTable.className = "dataframe"\n", " childTable.id = "df_" + frameId\n", " let childDf = rootDf.childFrames[frameId]\n", " childTable.df = childDf\n", " td.appendChild(childTable)\n", " this.renderTable(frameId)\n", " if (childDf.nrow !== childDf.totalRows) {\n", " const footer = document.createElement("p")\n", " footer.innerText = `... showing only top ${childDf.nrow} of ${childDf.totalRows} rows`\n", " td.appendChild(footer)\n", " }\n", " } else {\n", " td.appendChild(link)\n", " }\n", " } else if (value.style !== undefined) {\n", " td.innerHTML = value.value\n", " td.setAttribute("style", value.style)\n", " } else td.innerHTML = value\n", " this.nodeScriptReplace(td)\n", " }\n", " }\n", " }\n", "\n", " this.nodeScriptReplace = function (node) {\n", " if (this.nodeScriptIs(node) === true) {\n", " node.parentNode.replaceChild(this.nodeScriptClone(node), node);\n", " } else {\n", " let i = -1, children = node.childNodes;\n", " while (++i < children.length) {\n", " this.nodeScriptReplace(children[i]);\n", " }\n", " }\n", "\n", " return node;\n", " }\n", "\n", " this.nodeScriptClone = function (node) {\n", " let script = document.createElement("script");\n", " script.text = node.innerHTML;\n", "\n", " let i = -1, attrs = node.attributes, attr;\n", " while (++i < attrs.length) {\n", " script.setAttribute((attr = attrs[i]).name, attr.value);\n", " }\n", " return script;\n", " }\n", "\n", " this.nodeScriptIs = function (node) {\n", " return node.tagName === 'SCRIPT';\n", " }\n", " })()\n", "\n", " window.call_DataFrame = function (f) {\n", " return f();\n", " };\n", "\n", " let funQueue = window["kotlinQueues"] && window["kotlinQueues"]["DataFrame"];\n", " if (funQueue) {\n", " funQueue.forEach(function (f) {\n", " f();\n", " });\n", " funQueue = [];\n", " }\n", "})()\n", "\n", "/*<!--*/\n", "call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "<span title=\"name: String\">name</span>", children: [], rightAlign: false, values: ["All 1&#39;s","All 6&#39;s","Even buckets - All fail","Even buckets - All succed","Even buckets - Half succeed","Scewed towards bottom","Scewed towards top","Random (4+)","Random 1","Random 2","Random 3"] }, \n", "{ name: "<span title=\"n: Int\">n</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>"] }, \n", "{ name: "<span title=\"successes: Int\">successes</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">60</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">39</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">80</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">59</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">53</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">62</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">66</span></span>"] }, \n", "{ name: "<span title=\"expected: Double\">expected</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">58.333333</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">62.166667</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">120.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">60.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">60.166667</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">60.500000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">60.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">62.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">60.500000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">58.500000</span></span>"] }, \n", "{ name: "<span title=\"variance: Double\">variance</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">23.777778</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">23.750000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">30.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">24.083333</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">23.250000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">30.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">23.444444</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">23.194444</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">22.638889</span></span>"] }, \n", "{ name: "<span title=\"centeredLuck: Double\">centeredLuck</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">-58.333333</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">57.833333</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-21.166667</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">19.500000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-9.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.500000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">7.500000</span></span>"] }, \n", "{ name: "<span title=\"zScore: Double?\">zScore</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">-11.962754</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">11.867150</span></span>","<span class=\"formatted\" title=\"\"><span class=\"null\">null</span></span>","<span class=\"formatted\" title=\"\"><span class=\"null\">null</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-4.313146</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">4.044112</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-0.182574</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-1.858757</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.311458</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.576281</span></span>"] }, \n", "{ name: "<span title=\"tailP: Double\">tailP</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.536342</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.999996</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000035</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.607836</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.975214</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.417738</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.070507</span></span>"] }, \n", "{ name: "<span title=\"surprisalLog10: Double\">surprisalLog10</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">-0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">40.819193</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.270558</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000002</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">4.456033</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.216214</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.010900</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.379096</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">1.151769</span></span>"] }, \n", "{ name: "<span title=\"rarityPercentage: Double?\">rarityPercentage</span>", children: [], rightAlign: true, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">-0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"null\">null</span></span>","<span class=\"formatted\" title=\"\"><span class=\"null\">null</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">50.000000</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-0.000805</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.002626</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-42.756607</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-3.153082</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">37.772629</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">5.748050</span></span>"] }, \n", "], id: 1946157200, rootId: 1946157200, totalRows: 11 } ) });\n", "/*-->*/\n", "\n", "call_DataFrame(function() { DataFrame.renderTable(1946157200) });\n", "\n", "\n", " </script>\n", " </html>\"></iframe>\n", " <script>\n", " function o_resize_iframe_out_73() {\n", " let elem = document.getElementById(\"iframe_out_73\");\n", " resize_iframe_out_73(elem);\n", " setInterval(resize_iframe_out_73, 5000, elem);\n", " }\n", " function resize_iframe_out_73(el) {\n", " let h = el.contentWindow.document.body.scrollHeight;\n", " el.height = h === 0 ? 0 : h + 41;\n", " }\n", " </script> <html theme='dark'>\n", " <head>\n", " <style type=\"text/css\">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme=\"dark\"], :root [data-jp-theme-light=\"false\"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", " </style>\n", " </head>\n", " <body>\n", " <table class=\"dataframe\" id=\"static_df_1946157201\"><thead><tr><th class=\"bottomBorder\" style=\"text-align:left\">name</th><th class=\"bottomBorder\" style=\"text-align:left\">n</th><th class=\"bottomBorder\" style=\"text-align:left\">successes</th><th class=\"bottomBorder\" style=\"text-align:left\">expected</th><th class=\"bottomBorder\" style=\"text-align:left\">variance</th><th class=\"bottomBorder\" style=\"text-align:left\">centeredLuck</th><th class=\"bottomBorder\" style=\"text-align:left\">zScore</th><th class=\"bottomBorder\" style=\"text-align:left\">tailP</th><th class=\"bottomBorder\" style=\"text-align:left\">surprisalLog10</th><th class=\"bottomBorder\" style=\"text-align:left\">rarityPercentage</th></tr></thead><tbody><tr><td style=\"vertical-align:top\">All 1's</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">58.333333</td><td style=\"vertical-align:top\">23.777778</td><td style=\"vertical-align:top\">-58.333333</td><td style=\"vertical-align:top\">-11.962754</td><td style=\"vertical-align:top\">1.000000</td><td style=\"vertical-align:top\">-0.000000</td><td style=\"vertical-align:top\">-0.000000</td></tr><tr><td style=\"vertical-align:top\">All 6's</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">62.166667</td><td style=\"vertical-align:top\">23.750000</td><td style=\"vertical-align:top\">57.833333</td><td style=\"vertical-align:top\">11.867150</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">40.819193</td><td style=\"vertical-align:top\">0.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All fail</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">0</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">null</td><td style=\"vertical-align:top\">1.000000</td><td style=\"vertical-align:top\">-0.000000</td><td style=\"vertical-align:top\">null</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All succed</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">120.000000</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">null</td><td style=\"vertical-align:top\">1.000000</td><td style=\"vertical-align:top\">-0.000000</td><td style=\"vertical-align:top\">null</td></tr><tr><td style=\"vertical-align:top\">Even buckets - Half succeed</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">60</td><td style=\"vertical-align:top\">60.000000</td><td style=\"vertical-align:top\">30.000000</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">0.000000</td><td style=\"vertical-align:top\">0.536342</td><td style=\"vertical-align:top\">0.270558</td><td style=\"vertical-align:top\">50.000000</td></tr><tr><td style=\"vertical-align:top\">Scewed towards bottom</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">39</td><td style=\"vertical-align:top\">60.166667</td><td style=\"vertical-align:top\">24.083333</td><td style=\"vertical-align:top\">-21.166667</td><td style=\"vertical-align:top\">-4.313146</td><td style=\"vertical-align:top\">0.999996</td><td style=\"vertical-align:top\">0.000002</td><td style=\"vertical-align:top\">-0.000805</td></tr><tr><td style=\"vertical-align:top\">Scewed towards top</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">80</td><td style=\"vertical-align:top\">60.500000</td><td style=\"vertical-align:top\">23.250000</td><td style=\"vertical-align:top\">19.500000</td><td style=\"vertical-align:top\">4.044112</td><td style=\"vertical-align:top\">0.000035</td><td style=\"vertical-align:top\">4.456033</td><td style=\"vertical-align:top\">0.002626</td></tr><tr><td style=\"vertical-align:top\">Random (4+)</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">59</td><td style=\"vertical-align:top\">60.000000</td><td style=\"vertical-align:top\">30.000000</td><td style=\"vertical-align:top\">-1.000000</td><td style=\"vertical-align:top\">-0.182574</td><td style=\"vertical-align:top\">0.607836</td><td style=\"vertical-align:top\">0.216214</td><td style=\"vertical-align:top\">-42.756607</td></tr><tr><td style=\"vertical-align:top\">Random 1</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">53</td><td style=\"vertical-align:top\">62.000000</td><td style=\"vertical-align:top\">23.444444</td><td style=\"vertical-align:top\">-9.000000</td><td style=\"vertical-align:top\">-1.858757</td><td style=\"vertical-align:top\">0.975214</td><td style=\"vertical-align:top\">0.010900</td><td style=\"vertical-align:top\">-3.153082</td></tr><tr><td style=\"vertical-align:top\">Random 2</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">62</td><td style=\"vertical-align:top\">60.500000</td><td style=\"vertical-align:top\">23.194444</td><td style=\"vertical-align:top\">1.500000</td><td style=\"vertical-align:top\">0.311458</td><td style=\"vertical-align:top\">0.417738</td><td style=\"vertical-align:top\">0.379096</td><td style=\"vertical-align:top\">37.772629</td></tr><tr><td style=\"vertical-align:top\">Random 3</td><td style=\"vertical-align:top\">120</td><td style=\"vertical-align:top\">66</td><td style=\"vertical-align:top\">58.500000</td><td style=\"vertical-align:top\">22.638889</td><td style=\"vertical-align:top\">7.500000</td><td style=\"vertical-align:top\">1.576281</td><td style=\"vertical-align:top\">0.070507</td><td style=\"vertical-align:top\">1.151769</td><td style=\"vertical-align:top\">5.748050</td></tr></tbody></table>\n", " </body>\n", " <script>\n", " document.getElementById(\"static_df_1946157201\").style.display = \"none\";\n", " </script>\n", " </html>" ], | |
"application/kotlindataframe+json" : "{\"$version\":\"2.1.1\",\"metadata\":{\"columns\":[\"name\",\"n\",\"successes\",\"expected\",\"variance\",\"centeredLuck\",\"zScore\",\"tailP\",\"surprisalLog10\",\"rarityPercentage\"],\"types\":[{\"kind\":\"ValueColumn\",\"type\":\"kotlin.String\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Int\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Int\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double?\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Double?\"}],\"nrow\":11,\"ncol\":10},\"kotlin_dataframe\":[{\"name\":\"All 1's\",\"n\":120,\"successes\":0,\"expected\":58.33333333333334,\"variance\":23.77777777777776,\"centeredLuck\":-58.33333333333334,\"zScore\":-11.962753722931613,\"tailP\":1.0,\"surprisalLog10\":-0.0,\"rarityPercentage\":-0.0},{\"name\":\"All 6's\",\"n\":120,\"successes\":120,\"expected\":62.16666666666669,\"variance\":23.749999999999986,\"centeredLuck\":57.83333333333331,\"zScore\":11.867149605784947,\"tailP\":1.5163777549713305E-41,\"surprisalLog10\":40.81919259523219,\"rarityPercentage\":0.0},{\"name\":\"Even buckets - All fail\",\"n\":120,\"successes\":0,\"expected\":0.0,\"variance\":0.0,\"centeredLuck\":0.0,\"zScore\":null,\"tailP\":1.0,\"surprisalLog10\":-0.0,\"rarityPercentage\":null},{\"name\":\"Even buckets - All succed\",\"n\":120,\"successes\":120,\"expected\":120.0,\"variance\":0.0,\"centeredLuck\":0.0,\"zScore\":null,\"tailP\":1.0,\"surprisalLog10\":-0.0,\"rarityPercentage\":null},{\"name\":\"Even buckets - Half succeed\",\"n\":120,\"successes\":60,\"expected\":60.0,\"variance\":30.0,\"centeredLuck\":0.0,\"zScore\":0.0,\"tailP\":0.5363424894550584,\"surprisalLog10\":0.2705577965388452,\"rarityPercentage\":50.0},{\"name\":\"Scewed towards bottom\",\"n\":120,\"successes\":39,\"expected\":60.16666666666667,\"variance\":24.083333333333318,\"centeredLuck\":-21.16666666666667,\"zScore\":-4.313146128651913,\"tailP\":0.9999958229067214,\"surprisalLog10\":1.8140923501107664E-6,\"rarityPercentage\":-8.047383087683713E-4},{\"name\":\"Scewed towards top\",\"n\":120,\"successes\":80,\"expected\":60.5,\"variance\":23.249999999999996,\"centeredLuck\":19.5,\"zScore\":4.044111609448659,\"tailP\":3.4991842627240265E-5,\"surprisalLog10\":4.456033187503593,\"rarityPercentage\":0.0026260948221668023},{\"name\":\"Random (4+)\",\"n\":120,\"successes\":59,\"expected\":60.0,\"variance\":30.0,\"centeredLuck\":-1.0,\"zScore\":-0.18257418583505536,\"tailP\":0.6078359113338617,\"surprisalLog10\":0.2162136451027175,\"rarityPercentage\":-42.7566070292353},{\"name\":\"Random 1\",\"n\":120,\"successes\":53,\"expected\":62.000000000000014,\"variance\":23.444444444444436,\"centeredLuck\":-9.000000000000014,\"zScore\":-1.8587566552180916,\"tailP\":0.9752140209765248,\"surprisalLog10\":0.010900063348491217,\"rarityPercentage\":-3.153081943852709},{\"name\":\"Random 2\",\"n\":120,\"successes\":62,\"expected\":60.50000000000002,\"variance\":23.19444444444444,\"centeredLuck\":1.4999999999999787,\"zScore\":0.31145784309268787,\"tailP\":0.41773762641060946,\"surprisalLog10\":0.3790964052554684,\"rarityPercentage\":37.772629324558004},{\"name\":\"Random 3\",\"n\":120,\"successes\":66,\"expected\":58.50000000000001,\"variance\":22.63888888888888,\"centeredLuck\":7.499999999999993,\"zScore\":1.5762812492341312,\"tailP\":0.07050673954225631,\"surprisalLog10\":1.151769368028194,\"rarityPercentage\":5.7480500483650605}]}" | |
}, | |
"execution_count" : 88, | |
"metadata" : { }, | |
"output_type" : "execute_result" | |
} ], | |
"execution_count" : 88 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:33:07.596326Z", | |
"start_time" : "2025-08-21T10:33:06.889807Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "import org.jetbrains.kotlinx.statistics.math3.special.Erf.erf\n", "\n", "/**\n", " * Extension to Z-score, trying to map it into a [0-1] range. In the general case, this isn't possible since Z-score is unbounded,\n", " * but since we know how many rolls there are, we can calculate the minimum and maximum z-score. ChatGPT described it as:\n", " *\n", " * 1. Compute your Z-score from the game.\n", " * 2. Convert it to a percentile using the normal CDF — this gives you a 0–1 range where 0.5 = average.\n", " * 3. Rescale so that the lowest possible Z maps to 0% and highest possible Z maps to 100%.\n", " *\n", " * My understanding is that e.g. 98% means that the oucome is in the top 2% of outcomes, i.e. very lucky\n", " *\n", " * Advantage:\n", " * - It brings the values into something that looks more \"normal\"\n", " *\n", " * Critic:\n", " * - It is not linear.\n", " * - Calling it percentage is still wrong, it is still an \"index\", but now from [0-100]\n", " */\n", "\n", "/** Poisson–binomial PMF over total successes 0..n (O(n^2) DP) */\n", "fun poissonBinomialPmf(ps: List<Double>): DoubleArray {\n", " val n = ps.size\n", " var dp = DoubleArray(n + 1) { 0.0 }\n", " dp[0] = 1.0\n", " for (p in ps) {\n", " val next = DoubleArray(n + 1)\n", " for (k in 0..n) {\n", " val v = dp[k]\n", " if (v == 0.0) continue\n", " next[k] += v * (1 - p)\n", " if (k + 1 <= n) next[k + 1] += v * p\n", " }\n", " dp = next\n", " }\n", " return dp\n", "}\n", "\n", "/** Mid-rank CDF at s: P(X < s) + 0.5 P(X = s) */\n", "fun midCdf(pmf: DoubleArray, s: Int): Double {\n", " var lt = 0.0\n", " for (k in 0 until s) lt += pmf[k]\n", " return lt + 0.5 * pmf[s]\n", "}\n", "\n", "/**\n", " * Luck% in [0,100]:\n", " * - 0% = all fails\n", " * - 50% ≈ typical/median outcome\n", " * - 100% = all successes\n", " */\n", "fun luckPercent(ps: List<Double>, successes: Int): Double {\n", " val pmf = poissonBinomialPmf(ps)\n", " val n = ps.size\n", " val mid = midCdf(pmf, successes)\n", " val lo = 0.5 * pmf[0] // mid-CDF at all-fails\n", " val hi = 1.0 - 0.5 * pmf[n] // mid-CDF at all-successes\n", " return ((mid - lo) / (hi - lo) * 100.0).coerceIn(0.0, 100.0)\n", "}\n", "\n", "val adjustedZIndexValues = distributions.map { (name, rolls) ->\n", " val rollsWithProbabilities = rolls.map {\n", " Roll(it.successPropability(), it.isSuccess())\n", " }\n", " val successes = rollsWithProbabilities.count { it.success }\n", " val ps = rollsWithProbabilities.map { it.p }\n", " name to luckPercent(ps, successes)\n", "}.toDataFrame().rename(\"first\").into(\"name\").rename(\"second\").into(\"adjustedZ\")\n", "adjustedZIndexValues" ], | |
"id" : "bdb7904b7762224b", | |
"outputs" : [ { | |
"data" : { | |
"text/html" : [ " <iframe onload=\"o_resize_iframe_out_74()\" style=\"width:100%;\" class=\"result_container\" id=\"iframe_out_74\" frameBorder=\"0\" srcdoc=\" <html theme='dark'>\n", " <head>\n", " <style type="text/css">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme="dark"], :root [data-jp-theme-light="false"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", ":root {\n", " --scroll-bg: #f5f5f5;\n", " --scroll-fg: #b3b3b3;\n", "}\n", ":root[theme="dark"], :root [data-jp-theme-light="false"]{\n", " --scroll-bg: #3c3c3c;\n", " --scroll-fg: #97e1fb;\n", "}\n", "body {\n", " scrollbar-color: var(--scroll-fg) var(--scroll-bg);\n", "}\n", "body::-webkit-scrollbar {\n", " width: 10px; /* Mostly for vertical scrollbars */\n", " height: 10px; /* Mostly for horizontal scrollbars */\n", "}\n", "body::-webkit-scrollbar-thumb {\n", " background-color: var(--scroll-fg);\n", "}\n", "body::-webkit-scrollbar-track {\n", " background-color: var(--scroll-bg);\n", "}\n", " </style>\n", " </head>\n", " <body>\n", " <table class="dataframe" id="df_1946157202"></table>\n", "\n", "<p class="dataframe_description">DataFrame: rowsCount = 11, columnsCount = 2</p>\n", "\n", " </body>\n", " <script>\n", " (function () {\n", " window.DataFrame = window.DataFrame || new (function () {\n", " this.addTable = function (df) {\n", " let cols = df.cols;\n", " for (let i = 0; i < cols.length; i++) {\n", " for (let c of cols[i].children) {\n", " cols[c].parent = i;\n", " }\n", " }\n", " df.nrow = 0\n", " for (let i = 0; i < df.cols.length; i++) {\n", " if (df.cols[i].values.length > df.nrow) df.nrow = df.cols[i].values.length\n", " }\n", " if (df.id === df.rootId) {\n", " df.expandedFrames = new Set()\n", " df.childFrames = {}\n", " const table = this.getTableElement(df.id)\n", " table.df = df\n", " for (let i = 0; i < df.cols.length; i++) {\n", " let col = df.cols[i]\n", " if (col.parent === undefined && col.children.length > 0) col.expanded = true\n", " }\n", " } else {\n", " const rootDf = this.getTableData(df.rootId)\n", " rootDf.childFrames[df.id] = df\n", " }\n", " }\n", "\n", " this.computeRenderData = function (df) {\n", " let result = []\n", " let pos = 0\n", " for (let col = 0; col < df.cols.length; col++) {\n", " if (df.cols[col].parent === undefined)\n", " pos += this.computeRenderDataRec(df.cols, col, pos, 0, result, false, false)\n", " }\n", " for (let i = 0; i < result.length; i++) {\n", " let row = result[i]\n", " for (let j = 0; j < row.length; j++) {\n", " let cell = row[j]\n", " if (j === 0)\n", " cell.leftBd = false\n", " if (j < row.length - 1) {\n", " let nextData = row[j + 1]\n", " if (nextData.leftBd) cell.rightBd = true\n", " else if (cell.rightBd) nextData.leftBd = true\n", " } else cell.rightBd = false\n", " }\n", " }\n", " return result\n", " }\n", "\n", " this.computeRenderDataRec = function (cols, colId, pos, depth, result, leftBorder, rightBorder) {\n", " if (result.length === depth) {\n", " const array = [];\n", " if (pos > 0) {\n", " let j = 0\n", " for (let i = 0; j < pos; i++) {\n", " let c = result[depth - 1][i]\n", " j += c.span\n", " let copy = Object.assign({empty: true}, c)\n", " array.push(copy)\n", " }\n", " }\n", " result.push(array)\n", " }\n", " const col = cols[colId];\n", " let size = 0;\n", " if (col.expanded) {\n", " let childPos = pos\n", " for (let i = 0; i < col.children.length; i++) {\n", " let child = col.children[i]\n", " let childLeft = i === 0 && (col.children.length > 1 || leftBorder)\n", " let childRight = i === col.children.length - 1 && (col.children.length > 1 || rightBorder)\n", " let childSize = this.computeRenderDataRec(cols, child, childPos, depth + 1, result, childLeft, childRight)\n", " childPos += childSize\n", " size += childSize\n", " }\n", " } else {\n", " for (let i = depth + 1; i < result.length; i++)\n", " result[i].push({id: colId, span: 1, leftBd: leftBorder, rightBd: rightBorder, empty: true})\n", " size = 1\n", " }\n", " let left = leftBorder\n", " let right = rightBorder\n", " if (size > 1) {\n", " left = true\n", " right = true\n", " }\n", " result[depth].push({id: colId, span: size, leftBd: left, rightBd: right})\n", " return size\n", " }\n", "\n", " this.getTableElement = function (id) {\n", " return document.getElementById("df_" + id)\n", " }\n", "\n", " this.getTableData = function (id) {\n", " return this.getTableElement(id).df\n", " }\n", "\n", " this.createExpander = function (isExpanded) {\n", " const svgNs = "http://www.w3.org/2000/svg"\n", " let svg = document.createElementNS(svgNs, "svg")\n", " svg.classList.add("expanderSvg")\n", " let path = document.createElementNS(svgNs, "path")\n", " if (isExpanded) {\n", " svg.setAttribute("viewBox", "0 -2 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 4 4 4 -4 -1 -1 -3 3Z")\n", " } else {\n", " svg.setAttribute("viewBox", "-2 0 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 3 3 -3 3 1 1 4 -4Z")\n", " }\n", " path.setAttribute("fill", "currentColor")\n", " svg.appendChild(path)\n", " return svg\n", " }\n", "\n", " this.renderTable = function (id) {\n", "\n", " let table = this.getTableElement(id)\n", "\n", " if (table === null) return\n", "\n", " table.innerHTML = ""\n", "\n", " let df = table.df\n", " let rootDf = df.rootId === df.id ? df : this.getTableData(df.rootId)\n", "\n", " // header\n", " let header = document.createElement("thead")\n", " table.appendChild(header)\n", "\n", " let renderData = this.computeRenderData(df)\n", " for (let j = 0; j < renderData.length; j++) {\n", " let rowData = renderData[j]\n", " let tr = document.createElement("tr");\n", " let isLastRow = j === renderData.length - 1\n", " header.appendChild(tr);\n", " for (let i = 0; i < rowData.length; i++) {\n", " let cell = rowData[i]\n", " let th = document.createElement("th");\n", " th.setAttribute("colspan", cell.span)\n", " let colId = cell.id\n", " let col = df.cols[colId];\n", " if (!cell.empty) {\n", " if (col.children.length === 0) {\n", " th.innerHTML = col.name\n", " } else {\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " col.expanded = !col.expanded\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(col.expanded))\n", " link.innerHTML += col.name\n", " th.appendChild(link)\n", " }\n", " }\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (isLastRow)\n", " classes += " bottomBorder"\n", " if (classes.length > 0)\n", " th.setAttribute("class", classes)\n", " tr.appendChild(th)\n", " }\n", " }\n", "\n", " // body\n", " let body = document.createElement("tbody")\n", " table.appendChild(body)\n", "\n", " let columns = renderData.pop()\n", " for (let row = 0; row < df.nrow; row++) {\n", " let tr = document.createElement("tr");\n", " body.appendChild(tr)\n", " for (let i = 0; i < columns.length; i++) {\n", " let cell = columns[i]\n", " let td = document.createElement("td");\n", " let colId = cell.id\n", " let col = df.cols[colId]\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (classes.length > 0)\n", " td.setAttribute("class", classes)\n", " tr.appendChild(td)\n", " let value = col.values[row]\n", " if (value.frameId !== undefined) {\n", " let frameId = value.frameId\n", " let expanded = rootDf.expandedFrames.has(frameId)\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " if (rootDf.expandedFrames.has(frameId))\n", " rootDf.expandedFrames.delete(frameId)\n", " else rootDf.expandedFrames.add(frameId)\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(expanded))\n", " link.innerHTML += value.value\n", " if (expanded) {\n", " td.appendChild(link)\n", " td.appendChild(document.createElement("p"))\n", " const childTable = document.createElement("table")\n", " childTable.className = "dataframe"\n", " childTable.id = "df_" + frameId\n", " let childDf = rootDf.childFrames[frameId]\n", " childTable.df = childDf\n", " td.appendChild(childTable)\n", " this.renderTable(frameId)\n", " if (childDf.nrow !== childDf.totalRows) {\n", " const footer = document.createElement("p")\n", " footer.innerText = `... showing only top ${childDf.nrow} of ${childDf.totalRows} rows`\n", " td.appendChild(footer)\n", " }\n", " } else {\n", " td.appendChild(link)\n", " }\n", " } else if (value.style !== undefined) {\n", " td.innerHTML = value.value\n", " td.setAttribute("style", value.style)\n", " } else td.innerHTML = value\n", " this.nodeScriptReplace(td)\n", " }\n", " }\n", " }\n", "\n", " this.nodeScriptReplace = function (node) {\n", " if (this.nodeScriptIs(node) === true) {\n", " node.parentNode.replaceChild(this.nodeScriptClone(node), node);\n", " } else {\n", " let i = -1, children = node.childNodes;\n", " while (++i < children.length) {\n", " this.nodeScriptReplace(children[i]);\n", " }\n", " }\n", "\n", " return node;\n", " }\n", "\n", " this.nodeScriptClone = function (node) {\n", " let script = document.createElement("script");\n", " script.text = node.innerHTML;\n", "\n", " let i = -1, attrs = node.attributes, attr;\n", " while (++i < attrs.length) {\n", " script.setAttribute((attr = attrs[i]).name, attr.value);\n", " }\n", " return script;\n", " }\n", "\n", " this.nodeScriptIs = function (node) {\n", " return node.tagName === 'SCRIPT';\n", " }\n", " })()\n", "\n", " window.call_DataFrame = function (f) {\n", " return f();\n", " };\n", "\n", " let funQueue = window["kotlinQueues"] && window["kotlinQueues"]["DataFrame"];\n", " if (funQueue) {\n", " funQueue.forEach(function (f) {\n", " f();\n", " });\n", " funQueue = [];\n", " }\n", "})()\n", "\n", "/*<!--*/\n", "call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "<span title=\"name: Any\">name</span>", children: [], rightAlign: false, values: ["All 1&#39;s","All 6&#39;s","Even buckets - All fail","Even buckets - All succed","Even buckets - Half succeed","Scewed towards bottom","Scewed towards top","Random (4+)","Random 1","Random 2","Random 3"] }, \n", "{ name: "<span title=\"adjustedZ: Any\">adjustedZ</span>", children: [], rightAlign: false, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">50.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">42.8</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">3.2</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">62.2</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">94.2</span></span>"] }, \n", "], id: 1946157202, rootId: 1946157202, totalRows: 11 } ) });\n", "/*-->*/\n", "\n", "call_DataFrame(function() { DataFrame.renderTable(1946157202) });\n", "\n", "\n", " </script>\n", " </html>\"></iframe>\n", " <script>\n", " function o_resize_iframe_out_74() {\n", " let elem = document.getElementById(\"iframe_out_74\");\n", " resize_iframe_out_74(elem);\n", " setInterval(resize_iframe_out_74, 5000, elem);\n", " }\n", " function resize_iframe_out_74(el) {\n", " let h = el.contentWindow.document.body.scrollHeight;\n", " el.height = h === 0 ? 0 : h + 41;\n", " }\n", " </script> <html theme='dark'>\n", " <head>\n", " <style type=\"text/css\">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme=\"dark\"], :root [data-jp-theme-light=\"false\"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", " </style>\n", " </head>\n", " <body>\n", " <table class=\"dataframe\" id=\"static_df_1946157203\"><thead><tr><th class=\"bottomBorder\" style=\"text-align:left\">name</th><th class=\"bottomBorder\" style=\"text-align:left\">adjustedZ</th></tr></thead><tbody><tr><td style=\"vertical-align:top\">All 1's</td><td style=\"vertical-align:top\">0.000000</td></tr><tr><td style=\"vertical-align:top\">All 6's</td><td style=\"vertical-align:top\">100.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All fail</td><td style=\"vertical-align:top\">0.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All succed</td><td style=\"vertical-align:top\">100.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - Half succeed</td><td style=\"vertical-align:top\">50.000000</td></tr><tr><td style=\"vertical-align:top\">Scewed towards bottom</td><td style=\"vertical-align:top\">0.000751</td></tr><tr><td style=\"vertical-align:top\">Scewed towards top</td><td style=\"vertical-align:top\">99.997551</td></tr><tr><td style=\"vertical-align:top\">Random (4+)</td><td style=\"vertical-align:top\">42.791080</td></tr><tr><td style=\"vertical-align:top\">Random 1</td><td style=\"vertical-align:top\">3.213106</td></tr><tr><td style=\"vertical-align:top\">Random 2</td><td style=\"vertical-align:top\">62.168332</td></tr><tr><td style=\"vertical-align:top\">Random 3</td><td style=\"vertical-align:top\">94.161063</td></tr></tbody></table>\n", " </body>\n", " <script>\n", " document.getElementById(\"static_df_1946157203\").style.display = \"none\";\n", " </script>\n", " </html>" ], | |
"application/kotlindataframe+json" : "{\"$version\":\"2.1.1\",\"metadata\":{\"columns\":[\"name\",\"adjustedZ\"],\"types\":[{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Any\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Any\"}],\"nrow\":11,\"ncol\":2},\"kotlin_dataframe\":[{\"name\":\"All 1's\",\"adjustedZ\":\"0.0\"},{\"name\":\"All 6's\",\"adjustedZ\":\"100.0\"},{\"name\":\"Even buckets - All fail\",\"adjustedZ\":\"0.0\"},{\"name\":\"Even buckets - All succed\",\"adjustedZ\":\"100.0\"},{\"name\":\"Even buckets - Half succeed\",\"adjustedZ\":\"50.000000000000014\"},{\"name\":\"Scewed towards bottom\",\"adjustedZ\":\"7.513720993058864E-4\"},{\"name\":\"Scewed towards top\",\"adjustedZ\":\"99.99755060899224\"},{\"name\":\"Random (4+)\",\"adjustedZ\":\"42.791079960554\"},{\"name\":\"Random 1\",\"adjustedZ\":\"3.2131062720979027\"},{\"name\":\"Random 2\",\"adjustedZ\":\"62.16833207594941\"},{\"name\":\"Random 3\",\"adjustedZ\":\"94.16106314041102\"}]}" | |
}, | |
"execution_count" : 89, | |
"metadata" : { }, | |
"output_type" : "execute_result" | |
} ], | |
"execution_count" : 89 | |
}, { | |
"metadata" : { | |
"ExecuteTime" : { | |
"end_time" : "2025-08-21T10:37:26.176326Z", | |
"start_time" : "2025-08-21T10:37:25.889097Z" | |
} | |
}, | |
"cell_type" : "code", | |
"source" : [ "/**\n", " * Instead of using the Z-Score, we instead describe the \"likely outcome\" in the given distribution, mapped\n", " * to [-100 - 100] range.\n", " *\n", " * Formally:\n", " * LuckSym is a linear rescale of the mid-rank CDF of the Poisson–binomial distribution of successes.\n", " * With -100 being maximally unlucky, 0 being average and +100 being maximally lucky.\n", " *\n", " * Informal interpretation\n", " * - 0: The average outcome\n", " * - +100: Maximally lucky, all rolls succeed\n", " * - -100: Maximally unlucky, all rolls fail\n", " * - +20: 80% of all games are going to be more \"lucky\" than this game\n", " * - -60%: 60% or all games are going to be more \"lucky\" than this outcome.\n", " */\n", "\n", "\n", "// -------- Exact LuckSym from per-roll p_i and observed successes S --------\n", "fun pbPmf(ps: List<Double>): DoubleArray {\n", " val n = ps.size\n", " var dp = DoubleArray(n + 1) { 0.0 }\n", " dp[0] = 1.0\n", " for (p in ps) {\n", " val next = DoubleArray(n + 1)\n", " for (k in 0..n) {\n", " val v = dp[k]; if (v == 0.0) continue\n", " next[k] += v * (1 - p)\n", " if (k + 1 <= n) next[k + 1] += v * p\n", " }\n", " dp = next\n", " }\n", " return dp\n", "}\n", "\n", "fun midCdf(pmf: DoubleArray, s: Int): Double {\n", " val ss = s.coerceIn(0, pmf.lastIndex)\n", " var lt = 0.0\n", " for (k in 0 until ss) lt += pmf[k]\n", " return lt + 0.5 * pmf[ss]\n", "}\n", "\n", "// ps: Probability array of \"success\" for each roll\n", "fun luckSymExact(ps: List<Double>, successes: Int): Double {\n", " // Check for all fail/succeed case, since this will reported wrong otherwise\n", " val variance = ps.sumOf { it * (1 - it) }\n", " if (variance == 0.0) {\n", " return when (successes > 0) {\n", " true -> 100.0\n", " false -> -100.0\n", " }\n", " }\n", " val pmf = pbPmf(ps)\n", " val mid = midCdf(pmf, successes) // in [0,1]\n", " return (2.0 * mid - 1.0) * 100.0 // in [-100,+100]\n", "}\n", "\n", "distributions.map {\n", " val title = it.first\n", " val rolls = it.second\n", " val ps = rolls.map { it.successPropability() }\n", " val successes = rolls.count { it.isSuccess() }\n", " val luckSym = luckSymExact(ps, successes)\n", " title to luckSym\n", "}.toDataFrame()" ], | |
"id" : "f872d2e60efaa2fd", | |
"outputs" : [ { | |
"data" : { | |
"text/html" : [ " <iframe onload=\"o_resize_iframe_out_81()\" style=\"width:100%;\" class=\"result_container\" id=\"iframe_out_81\" frameBorder=\"0\" srcdoc=\" <html theme='dark'>\n", " <head>\n", " <style type="text/css">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme="dark"], :root [data-jp-theme-light="false"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", ":root {\n", " --scroll-bg: #f5f5f5;\n", " --scroll-fg: #b3b3b3;\n", "}\n", ":root[theme="dark"], :root [data-jp-theme-light="false"]{\n", " --scroll-bg: #3c3c3c;\n", " --scroll-fg: #97e1fb;\n", "}\n", "body {\n", " scrollbar-color: var(--scroll-fg) var(--scroll-bg);\n", "}\n", "body::-webkit-scrollbar {\n", " width: 10px; /* Mostly for vertical scrollbars */\n", " height: 10px; /* Mostly for horizontal scrollbars */\n", "}\n", "body::-webkit-scrollbar-thumb {\n", " background-color: var(--scroll-fg);\n", "}\n", "body::-webkit-scrollbar-track {\n", " background-color: var(--scroll-bg);\n", "}\n", " </style>\n", " </head>\n", " <body>\n", " <table class="dataframe" id="df_1946157216"></table>\n", "\n", "<p class="dataframe_description">DataFrame: rowsCount = 11, columnsCount = 2</p>\n", "\n", " </body>\n", " <script>\n", " (function () {\n", " window.DataFrame = window.DataFrame || new (function () {\n", " this.addTable = function (df) {\n", " let cols = df.cols;\n", " for (let i = 0; i < cols.length; i++) {\n", " for (let c of cols[i].children) {\n", " cols[c].parent = i;\n", " }\n", " }\n", " df.nrow = 0\n", " for (let i = 0; i < df.cols.length; i++) {\n", " if (df.cols[i].values.length > df.nrow) df.nrow = df.cols[i].values.length\n", " }\n", " if (df.id === df.rootId) {\n", " df.expandedFrames = new Set()\n", " df.childFrames = {}\n", " const table = this.getTableElement(df.id)\n", " table.df = df\n", " for (let i = 0; i < df.cols.length; i++) {\n", " let col = df.cols[i]\n", " if (col.parent === undefined && col.children.length > 0) col.expanded = true\n", " }\n", " } else {\n", " const rootDf = this.getTableData(df.rootId)\n", " rootDf.childFrames[df.id] = df\n", " }\n", " }\n", "\n", " this.computeRenderData = function (df) {\n", " let result = []\n", " let pos = 0\n", " for (let col = 0; col < df.cols.length; col++) {\n", " if (df.cols[col].parent === undefined)\n", " pos += this.computeRenderDataRec(df.cols, col, pos, 0, result, false, false)\n", " }\n", " for (let i = 0; i < result.length; i++) {\n", " let row = result[i]\n", " for (let j = 0; j < row.length; j++) {\n", " let cell = row[j]\n", " if (j === 0)\n", " cell.leftBd = false\n", " if (j < row.length - 1) {\n", " let nextData = row[j + 1]\n", " if (nextData.leftBd) cell.rightBd = true\n", " else if (cell.rightBd) nextData.leftBd = true\n", " } else cell.rightBd = false\n", " }\n", " }\n", " return result\n", " }\n", "\n", " this.computeRenderDataRec = function (cols, colId, pos, depth, result, leftBorder, rightBorder) {\n", " if (result.length === depth) {\n", " const array = [];\n", " if (pos > 0) {\n", " let j = 0\n", " for (let i = 0; j < pos; i++) {\n", " let c = result[depth - 1][i]\n", " j += c.span\n", " let copy = Object.assign({empty: true}, c)\n", " array.push(copy)\n", " }\n", " }\n", " result.push(array)\n", " }\n", " const col = cols[colId];\n", " let size = 0;\n", " if (col.expanded) {\n", " let childPos = pos\n", " for (let i = 0; i < col.children.length; i++) {\n", " let child = col.children[i]\n", " let childLeft = i === 0 && (col.children.length > 1 || leftBorder)\n", " let childRight = i === col.children.length - 1 && (col.children.length > 1 || rightBorder)\n", " let childSize = this.computeRenderDataRec(cols, child, childPos, depth + 1, result, childLeft, childRight)\n", " childPos += childSize\n", " size += childSize\n", " }\n", " } else {\n", " for (let i = depth + 1; i < result.length; i++)\n", " result[i].push({id: colId, span: 1, leftBd: leftBorder, rightBd: rightBorder, empty: true})\n", " size = 1\n", " }\n", " let left = leftBorder\n", " let right = rightBorder\n", " if (size > 1) {\n", " left = true\n", " right = true\n", " }\n", " result[depth].push({id: colId, span: size, leftBd: left, rightBd: right})\n", " return size\n", " }\n", "\n", " this.getTableElement = function (id) {\n", " return document.getElementById("df_" + id)\n", " }\n", "\n", " this.getTableData = function (id) {\n", " return this.getTableElement(id).df\n", " }\n", "\n", " this.createExpander = function (isExpanded) {\n", " const svgNs = "http://www.w3.org/2000/svg"\n", " let svg = document.createElementNS(svgNs, "svg")\n", " svg.classList.add("expanderSvg")\n", " let path = document.createElementNS(svgNs, "path")\n", " if (isExpanded) {\n", " svg.setAttribute("viewBox", "0 -2 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 4 4 4 -4 -1 -1 -3 3Z")\n", " } else {\n", " svg.setAttribute("viewBox", "-2 0 8 8")\n", " path.setAttribute("d", "M1 0 l-1 1 3 3 -3 3 1 1 4 -4Z")\n", " }\n", " path.setAttribute("fill", "currentColor")\n", " svg.appendChild(path)\n", " return svg\n", " }\n", "\n", " this.renderTable = function (id) {\n", "\n", " let table = this.getTableElement(id)\n", "\n", " if (table === null) return\n", "\n", " table.innerHTML = ""\n", "\n", " let df = table.df\n", " let rootDf = df.rootId === df.id ? df : this.getTableData(df.rootId)\n", "\n", " // header\n", " let header = document.createElement("thead")\n", " table.appendChild(header)\n", "\n", " let renderData = this.computeRenderData(df)\n", " for (let j = 0; j < renderData.length; j++) {\n", " let rowData = renderData[j]\n", " let tr = document.createElement("tr");\n", " let isLastRow = j === renderData.length - 1\n", " header.appendChild(tr);\n", " for (let i = 0; i < rowData.length; i++) {\n", " let cell = rowData[i]\n", " let th = document.createElement("th");\n", " th.setAttribute("colspan", cell.span)\n", " let colId = cell.id\n", " let col = df.cols[colId];\n", " if (!cell.empty) {\n", " if (col.children.length === 0) {\n", " th.innerHTML = col.name\n", " } else {\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " col.expanded = !col.expanded\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(col.expanded))\n", " link.innerHTML += col.name\n", " th.appendChild(link)\n", " }\n", " }\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (isLastRow)\n", " classes += " bottomBorder"\n", " if (classes.length > 0)\n", " th.setAttribute("class", classes)\n", " tr.appendChild(th)\n", " }\n", " }\n", "\n", " // body\n", " let body = document.createElement("tbody")\n", " table.appendChild(body)\n", "\n", " let columns = renderData.pop()\n", " for (let row = 0; row < df.nrow; row++) {\n", " let tr = document.createElement("tr");\n", " body.appendChild(tr)\n", " for (let i = 0; i < columns.length; i++) {\n", " let cell = columns[i]\n", " let td = document.createElement("td");\n", " let colId = cell.id\n", " let col = df.cols[colId]\n", " let classes = (cell.leftBd ? " leftBorder" : "") + (cell.rightBd ? " rightBorder" : "")\n", " if (col.rightAlign)\n", " classes += " rightAlign"\n", " if (classes.length > 0)\n", " td.setAttribute("class", classes)\n", " tr.appendChild(td)\n", " let value = col.values[row]\n", " if (value.frameId !== undefined) {\n", " let frameId = value.frameId\n", " let expanded = rootDf.expandedFrames.has(frameId)\n", " let link = document.createElement("a")\n", " link.className = "expander"\n", " let that = this\n", " link.onclick = function () {\n", " if (rootDf.expandedFrames.has(frameId))\n", " rootDf.expandedFrames.delete(frameId)\n", " else rootDf.expandedFrames.add(frameId)\n", " that.renderTable(id)\n", " }\n", " link.appendChild(this.createExpander(expanded))\n", " link.innerHTML += value.value\n", " if (expanded) {\n", " td.appendChild(link)\n", " td.appendChild(document.createElement("p"))\n", " const childTable = document.createElement("table")\n", " childTable.className = "dataframe"\n", " childTable.id = "df_" + frameId\n", " let childDf = rootDf.childFrames[frameId]\n", " childTable.df = childDf\n", " td.appendChild(childTable)\n", " this.renderTable(frameId)\n", " if (childDf.nrow !== childDf.totalRows) {\n", " const footer = document.createElement("p")\n", " footer.innerText = `... showing only top ${childDf.nrow} of ${childDf.totalRows} rows`\n", " td.appendChild(footer)\n", " }\n", " } else {\n", " td.appendChild(link)\n", " }\n", " } else if (value.style !== undefined) {\n", " td.innerHTML = value.value\n", " td.setAttribute("style", value.style)\n", " } else td.innerHTML = value\n", " this.nodeScriptReplace(td)\n", " }\n", " }\n", " }\n", "\n", " this.nodeScriptReplace = function (node) {\n", " if (this.nodeScriptIs(node) === true) {\n", " node.parentNode.replaceChild(this.nodeScriptClone(node), node);\n", " } else {\n", " let i = -1, children = node.childNodes;\n", " while (++i < children.length) {\n", " this.nodeScriptReplace(children[i]);\n", " }\n", " }\n", "\n", " return node;\n", " }\n", "\n", " this.nodeScriptClone = function (node) {\n", " let script = document.createElement("script");\n", " script.text = node.innerHTML;\n", "\n", " let i = -1, attrs = node.attributes, attr;\n", " while (++i < attrs.length) {\n", " script.setAttribute((attr = attrs[i]).name, attr.value);\n", " }\n", " return script;\n", " }\n", "\n", " this.nodeScriptIs = function (node) {\n", " return node.tagName === 'SCRIPT';\n", " }\n", " })()\n", "\n", " window.call_DataFrame = function (f) {\n", " return f();\n", " };\n", "\n", " let funQueue = window["kotlinQueues"] && window["kotlinQueues"]["DataFrame"];\n", " if (funQueue) {\n", " funQueue.forEach(function (f) {\n", " f();\n", " });\n", " funQueue = [];\n", " }\n", "})()\n", "\n", "/*<!--*/\n", "call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "<span title=\"first: Any\">first</span>", children: [], rightAlign: false, values: ["All 1&#39;s","All 6&#39;s","Even buckets - All fail","Even buckets - All succed","Even buckets - Half succeed","Scewed towards bottom","Scewed towards top","Random (4+)","Random 1","Random 2","Random 3"] }, \n", "{ name: "<span title=\"second: Any\">second</span>", children: [], rightAlign: false, values: ["<span class=\"formatted\" title=\"\"><span class=\"numbers\">-100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">0.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">100.0</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-14.4</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">-93.6</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">24.3</span></span>","<span class=\"formatted\" title=\"\"><span class=\"numbers\">88.3</span></span>"] }, \n", "], id: 1946157216, rootId: 1946157216, totalRows: 11 } ) });\n", "/*-->*/\n", "\n", "call_DataFrame(function() { DataFrame.renderTable(1946157216) });\n", "\n", "\n", " </script>\n", " </html>\"></iframe>\n", " <script>\n", " function o_resize_iframe_out_81() {\n", " let elem = document.getElementById(\"iframe_out_81\");\n", " resize_iframe_out_81(elem);\n", " setInterval(resize_iframe_out_81, 5000, elem);\n", " }\n", " function resize_iframe_out_81(el) {\n", " let h = el.contentWindow.document.body.scrollHeight;\n", " el.height = h === 0 ? 0 : h + 41;\n", " }\n", " </script> <html theme='dark'>\n", " <head>\n", " <style type=\"text/css\">\n", " :root {\n", " --background: #fff;\n", " --background-odd: #f5f5f5;\n", " --background-hover: #d9edfd;\n", " --header-text-color: #474747;\n", " --text-color: #848484;\n", " --text-color-dark: #000;\n", " --text-color-medium: #737373;\n", " --text-color-pale: #b3b3b3;\n", " --inner-border-color: #aaa;\n", " --bold-border-color: #000;\n", " --link-color: #296eaa;\n", " --link-color-pale: #296eaa;\n", " --link-hover: #1a466c;\n", "}\n", "\n", ":root[theme=\"dark\"], :root [data-jp-theme-light=\"false\"], .dataframe_dark{\n", " --background: #303030;\n", " --background-odd: #3c3c3c;\n", " --background-hover: #464646;\n", " --header-text-color: #dddddd;\n", " --text-color: #b3b3b3;\n", " --text-color-dark: #dddddd;\n", " --text-color-medium: #b2b2b2;\n", " --text-color-pale: #737373;\n", " --inner-border-color: #707070;\n", " --bold-border-color: #777777;\n", " --link-color: #008dc0;\n", " --link-color-pale: #97e1fb;\n", " --link-hover: #00688e;\n", "}\n", "\n", "p.dataframe_description {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe {\n", " font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n", " font-size: 12px;\n", " background-color: var(--background);\n", " color: var(--text-color-dark);\n", " border: none;\n", " border-collapse: collapse;\n", "}\n", "\n", "table.dataframe th, td {\n", " padding: 6px;\n", " border: 1px solid transparent;\n", " text-align: left;\n", "}\n", "\n", "table.dataframe th {\n", " background-color: var(--background);\n", " color: var(--header-text-color);\n", "}\n", "\n", "table.dataframe td {\n", " vertical-align: top;\n", " white-space: nowrap;\n", "}\n", "\n", "table.dataframe th.bottomBorder {\n", " border-bottom-color: var(--bold-border-color);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(odd) {\n", " background: var(--background-odd);\n", "}\n", "\n", "table.dataframe tbody > tr:nth-child(even) {\n", " background: var(--background);\n", "}\n", "\n", "table.dataframe tbody > tr:hover {\n", " background: var(--background-hover);\n", "}\n", "\n", "table.dataframe a {\n", " cursor: pointer;\n", " color: var(--link-color);\n", " text-decoration: none;\n", "}\n", "\n", "table.dataframe tr:hover > td a {\n", " color: var(--link-color-pale);\n", "}\n", "\n", "table.dataframe a:hover {\n", " color: var(--link-hover);\n", " text-decoration: underline;\n", "}\n", "\n", "table.dataframe img {\n", " max-width: fit-content;\n", "}\n", "\n", "table.dataframe th.complex {\n", " background-color: var(--background);\n", " border: 1px solid var(--background);\n", "}\n", "\n", "table.dataframe .leftBorder {\n", " border-left-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightBorder {\n", " border-right-color: var(--inner-border-color);\n", "}\n", "\n", "table.dataframe .rightAlign {\n", " text-align: right;\n", "}\n", "\n", "table.dataframe .expanderSvg {\n", " width: 8px;\n", " height: 8px;\n", " margin-right: 3px;\n", "}\n", "\n", "table.dataframe .expander {\n", " display: flex;\n", " align-items: center;\n", "}\n", "\n", "/* formatting */\n", "\n", "table.dataframe .null {\n", " color: var(--text-color-pale);\n", "}\n", "\n", "table.dataframe .structural {\n", " color: var(--text-color-medium);\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .dataFrameCaption {\n", " font-weight: bold;\n", "}\n", "\n", "table.dataframe .numbers {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe td:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "table.dataframe tr:hover .formatted .structural, .null {\n", " color: var(--text-color-dark);\n", "}\n", "\n", "\n", " </style>\n", " </head>\n", " <body>\n", " <table class=\"dataframe\" id=\"static_df_1946157217\"><thead><tr><th class=\"bottomBorder\" style=\"text-align:left\">first</th><th class=\"bottomBorder\" style=\"text-align:left\">second</th></tr></thead><tbody><tr><td style=\"vertical-align:top\">All 1's</td><td style=\"vertical-align:top\">-100.000000</td></tr><tr><td style=\"vertical-align:top\">All 6's</td><td style=\"vertical-align:top\">100.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All fail</td><td style=\"vertical-align:top\">-100.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - All succed</td><td style=\"vertical-align:top\">100.000000</td></tr><tr><td style=\"vertical-align:top\">Even buckets - Half succeed</td><td style=\"vertical-align:top\">0.000000</td></tr><tr><td style=\"vertical-align:top\">Scewed towards bottom</td><td style=\"vertical-align:top\">-99.998497</td></tr><tr><td style=\"vertical-align:top\">Scewed towards top</td><td style=\"vertical-align:top\">99.995101</td></tr><tr><td style=\"vertical-align:top\">Random (4+)</td><td style=\"vertical-align:top\">-14.417840</td></tr><tr><td style=\"vertical-align:top\">Random 1</td><td style=\"vertical-align:top\">-93.573787</td></tr><tr><td style=\"vertical-align:top\">Random 2</td><td style=\"vertical-align:top\">24.336664</td></tr><tr><td style=\"vertical-align:top\">Random 3</td><td style=\"vertical-align:top\">88.322126</td></tr></tbody></table>\n", " </body>\n", " <script>\n", " document.getElementById(\"static_df_1946157217\").style.display = \"none\";\n", " </script>\n", " </html>" ], | |
"application/kotlindataframe+json" : "{\"$version\":\"2.1.1\",\"metadata\":{\"columns\":[\"first\",\"second\"],\"types\":[{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Any\"},{\"kind\":\"ValueColumn\",\"type\":\"kotlin.Any\"}],\"nrow\":11,\"ncol\":2},\"kotlin_dataframe\":[{\"first\":\"All 1's\",\"second\":\"-100.0\"},{\"first\":\"All 6's\",\"second\":\"100.0000000000004\"},{\"first\":\"Even buckets - All fail\",\"second\":\"-100.0\"},{\"first\":\"Even buckets - All succed\",\"second\":\"100.0\"},{\"first\":\"Even buckets - Half succeed\",\"second\":\"2.220446049250313E-14\"},{\"first\":\"Scewed towards bottom\",\"second\":\"-99.99849725580138\"},{\"first\":\"Scewed towards top\",\"second\":\"99.99510121798447\"},{\"first\":\"Random (4+)\",\"second\":\"-14.417840078891997\"},{\"first\":\"Random 1\",\"second\":\"-93.5737874558042\"},{\"first\":\"Random 2\",\"second\":\"24.336664151898812\"},{\"first\":\"Random 3\",\"second\":\"88.32212628082203\"}]}" | |
}, | |
"execution_count" : 92, | |
"metadata" : { }, | |
"output_type" : "execute_result" | |
} ], | |
"execution_count" : 92 | |
} ], | |
"metadata" : { | |
"kernelspec" : { | |
"display_name" : "Kotlin", | |
"language" : "kotlin", | |
"name" : "kotlin" | |
}, | |
"language_info" : { | |
"name" : "kotlin", | |
"version" : "2.2.20-Beta2", | |
"mimetype" : "text/x-kotlin", | |
"file_extension" : ".kt", | |
"pygments_lexer" : "kotlin", | |
"codemirror_mode" : "text/x-kotlin", | |
"nbconvert_exporter" : "" | |
} | |
}, | |
"nbformat" : 4, | |
"nbformat_minor" : 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment