{"id":13428806,"url":"https://github.com/dkandalov/kotlin-99","last_synced_at":"2025-04-13T02:19:40.021Z","repository":{"id":42618589,"uuid":"67445237","full_name":"dkandalov/kotlin-99","owner":"dkandalov","description":"Ninety-Nine Problems in Kotlin","archived":false,"fork":false,"pushed_at":"2024-05-28T14:21:42.000Z","size":602,"stargazers_count":654,"open_issues_count":7,"forks_count":91,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-04-04T04:11:09.921Z","etag":null,"topics":["exercise","graph","kotlin","tree"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dkandalov.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"contributing.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-05T19:16:04.000Z","updated_at":"2024-12-22T02:06:22.000Z","dependencies_parsed_at":"2024-01-14T02:37:45.058Z","dependency_job_id":"0c492f56-7f98-47fe-9340-2a3ecada9534","html_url":"https://github.com/dkandalov/kotlin-99","commit_stats":{"total_commits":297,"total_committers":6,"mean_commits":49.5,"dds":0.04040404040404044,"last_synced_commit":"ae8e6cea14dc75ab79ef3cfa92d5bff65014d370"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkandalov%2Fkotlin-99","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkandalov%2Fkotlin-99/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkandalov%2Fkotlin-99/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dkandalov%2Fkotlin-99/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dkandalov","download_url":"https://codeload.github.com/dkandalov/kotlin-99/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654386,"owners_count":21140288,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["exercise","graph","kotlin","tree"],"created_at":"2024-07-31T01:01:05.604Z","updated_at":"2025-04-13T02:19:39.997Z","avatar_url":"https://github.com/dkandalov.png","language":"Kotlin","funding_links":[],"categories":["Libraries","Languages"],"sub_categories":["Kotlin"],"readme":"# Ninety-Nine Kotlin Problems\n\n![Build Status](https://github.com/dkandalov/kotlin-99/workflows/CI/badge.svg)\n\n## Table of Contents\n\n* [Introduction](#introduction)\n* [Lists](#lists)\n* [Arithmetic](#arithmetic)\n* [Logic and Codes](#logic-and-codes)\n* [Binary Trees](#binary-trees)\n* [Multiway Trees](#multiway-trees)\n* [Graphs](#graphs)\n* [Miscellaneous](#miscellaneous)\n\n\n## Introduction\n\nThis is an adaptation of [Ninety-Nine Scala Problems](http://aperiodic.net/phil/scala/s-99/) by Phil Gold \nwhich itself is an adaptation of the [Ninety-Nine Prolog Problems](https://sites.google.com/site/prologsite/prolog-problems) \nwritten by Werner Hett at the Berne University of Applied Sciences in Berne, Switzerland.\nSome problems have been altered to be more amenable to programming in [Kotlin][]. \n\nYou might want to do these problems if you want to learn [Kotlin][], are interested in the problems described below, or both.\nThe main reason to prefer this to using websites like hackerrank.com and codewars.com\nis that there is no vendor lock-in and no hidden agenda pursued by the website owner.\n\nThe suggested workflow is to solve a problem yourself and then compare solution to the one provided.  \nSolutions are available by clicking on the link at the beginning of the problem description.\nYour goal should be to find the most elegant solution to the given problems. \nEfficiency is important, but clarity is even more crucial. \nSome of the (easy) problems can be trivially solved using built-in functions. \nHowever, in these cases, you can learn more if you try to find your own solution.\n\nThe problems have different levels of difficulty. \nThose marked with a single asterisk `*` are easy.\nIf you have successfully solved the preceding problems, you might be able to solve them within a few (say 15) minutes. \nProblems marked with two asterisks `**` are of intermediate difficulty and might take about 30-90 minutes to solve. \nProblems marked with three asterisks `***` are more difficult. You may need more time (i.e. a few hours or more) to find a good solution.\nPlease note that levels of difficulty is just a guess and assumes you are somewhat familiar with the problem domain.\nIt is perfectly ok if some of them take longer. Overall, the goal is to learn, not to finish \"on time\".\n\nYou might notice that there are less than 99 problems.\nThis is because numbering of original problems was wrong. \nIt was kept here for consistency with 99 problems in other programming languages.\n\nThe first 50 or so problems are easy. \nIf this is boring for you, feel free to jump to [Binary Trees](#binary-trees). \n\nAll contributions are welcome (including alternative solutions for problems which already have a solution).\n\n\n\n## Lists\n\n### [P01][] (*) Find the last element of a list.\nExample:\n``` kotlin\n\u003e last(listOf(1, 1, 2, 3, 5, 8))\n8\n```\n\n### [P02][] (*) Find the last but one element of a list.\nExample:\n``` kotlin\n\u003e penultimate(listOf(1, 1, 2, 3, 5, 8))\n5\n```\n\n### [P03][] (*) Find the Nth element of a list.\nBy convention, the first element in the list is element ``0``.\nExample:\n``` kotlin\n\u003e nth(2, listOf(1, 1, 2, 3, 5, 8))\n2\n```\n\n### [P04][] (*) Find the number of elements of a list.\nExample:\n``` kotlin\n\u003e length(listOf(1, 1, 2, 3, 5, 8))\n6\n```\n\n### [P05][] (*) Reverse a list.\nExample:\n``` kotlin\n\u003e reverse(listOf(1, 1, 2, 3, 5, 8))\n[8, 5, 3, 2, 1, 1]\n```\n\n### [P06][] (*) Find out whether a list is a palindrome.\nExample:\n``` kotlin\n\u003e isPalindrome(listOf(1, 2, 3, 2, 1))\ntrue\n```\n\n### [P07][] (*) Flatten a nested list structure.\nExample:\n``` kotlin\n\u003e flatten(listOf(listOf(1, 1), 2, listOf(3, listOf(5, 8))))\n[1, 1, 2, 3, 5, 8]\n```\n\n### [P08][] (*) Eliminate consecutive duplicates of list elements.\nIf a list contains repeated elements, they should be replaced with a single copy of the element. \nThe order of the elements should not be changed.\nExample:\n``` kotlin\n\u003e compress(\"aaaabccaadeeee\".toList())\n[a, b, c, a, d, e]\n```\n\n### [P09][] (*) Pack consecutive duplicates of list elements into sublists.\nIf a list contains repeated elements, they should be placed in separate sublists.\nExample:\n``` kotlin\n\u003e pack(\"aaaabccaadeeee\".toList())\n[[a, a, a, a], [b], [c, c], [a, a], [d], [e, e, e, e]]\n```\n\n### [P10][] (*) Run-length encoding of a list.\nUse the result of problem P09 to implement the so-called run-length encoding data compression method. \nConsecutive duplicates of elements are encoded as tuples (N, E) where N is the number of duplicates of the element E.\nExample:\n``` kotlin\n\u003e encode(\"aaaabccaadeeee\".toList())\n[(4, a), (1, b), (2, c), (2, a), (1, d), (4, e)]\n```\n\n### [P11][] (*) Modified run-length encoding.\nModify the result of problem P10 in such a way that if an element has no duplicates it is simply copied into the result list. \nOnly elements with duplicates are transferred as (N, E) terms.\nExample:\n``` kotlin\n\u003e encodeModified(\"aaaabccaadeeee\".toList())\n[(4, a), b, (2, c), (2, a), d, (4, e)]\n```\n\n### [P12][] (*) Decode a run-length encoded list.\nGiven a run-length code list generated as specified in the problem P10, construct its uncompressed version.\nExample:\n``` kotlin\n\u003e decode(List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e)))\n[a, a, a, a, b, c, c, a, a, d, e, e, e, e]\n```\n\n### [P13][] (*) Run-length encoding of a list (direct solution).\nImplement the so-called run-length encoding data compression method directly. \nI.e. don't use other methods you've written (like P09's pack); do all the work directly.\nExample:\n``` kotlin\n\u003e encodeDirect(\"aaaabccaadeeee\".toList())\n[(4, a), (1, b), (2, c), (2, a), (1, d), (4, e)]\n```\n\n### [P14][] (*) Duplicate the elements of a list.\nExample:\n``` kotlin\n\u003e duplicate(\"abccd\".toList())\n[a, a, b, b, c, c, c, c, d, d]\n```\n\n### [P15][] (*) Duplicate the elements of a list a given number of times.\nExample:\n``` kotlin\n\u003e duplicateN(3, \"abccd\".toList())\n[a, a, a, b, b, b, c, c, c, c, c, c, d, d, d]\n```\n\n### [P16][] (*) Drop every Nth element from a list.\nExample:\n``` kotlin\n\u003e drop(3, \"abcdefghijk\".toList())\n[a, b, d, e, g, h, j, k]\n```\n\n### [P17][] (*) Split a list into two parts.\nThe length of the first part is given. Use a `Pair` for your result.\nExample:\n``` kotlin\n\u003e split(3, \"abcdefghijk\".toList())\n([a, b, c], [d, e, f, g, h, i, j, k])\n```\n\n### [P18][] (*) Extract a slice from a list.\nGiven two indices, I and K, the slice is the list containing the elements from and including the Ith element \nup to but not including the Kth element of the original list. Start counting the elements with 0.\nExample:\n``` kotlin\n\u003e slice(3, 7, \"abcdefghijk\".toList())\n[d, e, f, g]\n```\n\n### [P19][] (*) Rotate a list N places to the left.\nExamples:\n``` kotlin\n\u003e rotate(3, \"abcdefghijk\".toList())\n[d, e, f, g, h, i, j, k, a, b, c]\n\n\u003e rotate(-2, \"abcdefghijk\".toList())\n[j, k, a, b, c, d, e, f, g, h, i]\n```\n\n### [P20][] (*) Remove the Kth element from a list.\nReturn the list and the removed element in a Tuple. Elements are numbered from 0.\nExample:\n``` kotlin\n\u003e removeAt(1, \"abcd\".toList())\n([a, c, d], b)\n```\n\n### [P21][] (*) Insert an element at a given position into a list.\nExample:\n``` kotlin\n\u003e insertAt('X', 1, \"abcd\".toList())\n[a, X, b, c, d]\n```\n\n### [P22][] (*) Create a list containing all integers within a given range.\nExample:\n``` kotlin\n\u003e range(4, 9)\n[4, 5, 6, 7, 8, 9]\n```\n\n### [P23][] (*) Extract a given number of randomly selected elements from a list.\nMake sure there is a way to produce deterministic results.\nExample:\n``` kotlin\n\u003e randomSelect(3, \"abcdefgh\".toList())\n[c, h, f]\n```\n\n### [P24][] (*) Lotto: Draw N different random numbers from the set 1..M.\nMake sure there is a way to produce deterministic results.\nExample:\n``` kotlin\n\u003e lotto(3, 49)\n[32, 28, 8]\n```\n\n### [P25][] (*) Generate a random permutation of the elements of a list.\nMake sure there is a way to produce deterministic results.\nHint: Use the solution of problem P23.\nExample:\n``` kotlin\n\u003e randomPermute(\"abcdef\".toList())\n[d, b, e, f, a, c]\n```\n\n### [P26][] (**) Generate the combinations of K distinct objects chosen from the N elements of a list.\nIn how many ways can a committee of 3 be chosen from a group of 12 people? \nThere are ``C(12,3) = 220`` possibilities, where ``C(N,K)`` denotes [binomial coefficient](https://en.wikipedia.org/wiki/Binomial_coefficient). \nFor pure mathematicians, this result may be great. But we want to really generate all the possibilities.\nExample:\n``` kotlin\n\u003e combinations(3, \"abcde\".toList())\n[[c, b, a], [d, b, a], [e, b, a], [d, c, a], [e, c, a], [e, d, a], [d, c, b], [e, c, b], [e, d, b], [e, d, c]]\n```\n\n### [P27][] (**) Group the elements of a set into disjoint subsets.\na) In how many ways can a group of 9 people work in 3 disjoint subgroups of 2, 3 and 4 persons? \nWrite a function that generates all the possibilities.\nExample:\n``` kotlin\n\u003e group3(listOf(\"Aldo\", \"Beat\", \"Carla\", \"David\", \"Evi\", \"Flip\", \"Gary\", \"Hugo\", \"Ida\"))\n[[[\"Ida\", \"Hugo\", \"Gary\", \"Flip\"], [\"Evi\", \"David\", \"Carla\"], [\"Beat\", \"Aldo\"]], ...\n```\nb) Generalize the above predicate in a way that we can specify a list of group sizes and the predicate will return a list of groups.\nExample:\n``` kotlin\n\u003e group(listOf(2, 2, 5), listOf(\"Aldo\", \"Beat\", \"Carla\", \"David\", \"Evi\", \"Flip\", \"Gary\", \"Hugo\", \"Ida\"))\n[[[\"Ida\", \"Hugo\", \"Gary\", \"Flip\", \"Evi\"], [\"David\", \"Carla\"], [\"Beat\", \"Aldo\"]], ...\n```\nNote that we do not want permutations of the group members, i.e. ``[[Aldo, Beat], ...]]`` is the same solution as ``[[Beat, Aldo], ...]``. \nHowever, ``[[Aldo, Beat], [Carla, David], ...]`` and ``[[Carla, David], [Aldo, Beat], ...]`` are considered to be different solutions.\n\nYou may find more about this combinatorial problem in a good book on discrete mathematics under the term \n[multinomial coefficients](http://mathworld.wolfram.com/MultinomialCoefficient.html).\n\n### [P28][] (*) Sorting a list of lists according to length of sublists.\na) We suppose that a list contains elements that are lists themselves. \nThe objective is to sort elements of the list according to their length. \nE.g. short lists first, longer lists later, or vice versa.\nExample:\n``` kotlin\n\u003e lengthSort(listOf(\"abc\".toList(), \"de\".toList(), \"fgh\".toList(), \"de\".toList(), \"ijkl\".toList(), \"mn\".toList(), \"o\".toList()))\n[[o], [d, e], [d, e], [m, n], [a, b, c], [f, g, h], [i, j, k, l]]\n```\nb) Again, we suppose that a list contains elements that are lists themselves. \nBut this time the objective is to sort elements according to their length frequency; \ni.e. lists with rare lengths are placed first, others with more frequent lengths come later.\nExample:\n``` kotlin\n\u003e lengthFreqSort(listOf(\"abc\".toList(), \"de\".toList(), \"fgh\".toList(), \"de\".toList(), \"ijkl\".toList(), \"mn\".toList(), \"o\".toList()))\n[[i, j, k, l], [o], [a, b, c], [f, g, h], [d, e], [d, e], [m, n]]\n```\nNote that in the above example, the first two lists in the result have length 4 and 1 and both lengths appear just once. \nThe third and fourth lists have length 3 and there are two list of this length. Finally, the last three lists have length 2. \nThis is the most frequent length.\n         \t                                                                        \n\n\n## Arithmetic\n\n### [P31][] (*) Determine whether a given integer number is [prime](https://en.wikipedia.org/wiki/Prime_number).\n``` kotlin\n\u003e 7.isPrime()\ntrue\n```\n\n### [P32][] (*) Determine the greatest common divisor of two positive integer numbers.\nUse [Euclid's algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm).\n``` kotlin\n\u003e gcd(36, 63)\n9\n```\n\n### [P33][] (*) Determine whether two positive integer numbers are [coprime](https://en.wikipedia.org/wiki/Coprime_integers).\nTwo numbers are [coprime](https://en.wikipedia.org/wiki/Coprime_integers) if their greatest common divisor equals 1.\n``` kotlin\n\u003e 35.isCoprimeTo(64)\ntrue\n```\n\n### [P34][] (*) Calculate Euler's totient function phi(m).\nEuler's so-called [totient function](https://en.wikipedia.org/wiki/Euler%27s_totient_function) \nphi(m) is defined as the number of positive integers r (1 \u003c= r \u003c= m) that are coprime to m.\n``` kotlin\n\u003e 10.totient()\n4\n```\n\n### [P35][] (*) Determine prime factors of a given positive integer.\nConstruct a list containing prime factors in ascending order.\n``` kotlin\n\u003e 315.primeFactors()\n[3, 3, 5, 7]\n```\n\n### [P36][] (*) Determine the prime factors of a given positive integer (2).\nConstruct a list containing prime factors and their multiplicity.\n``` kotlin\n\u003e 315.primeFactorMultiplicity()\n[(3, 2), (5, 1), (7, 1)]\n```\n\n### [P37][] (*) Calculate Euler's totient function phi(m) (improved).\nSee problem P34 for the definition of Euler's totient function. \nIf the list of the prime factors of a number ``m`` is known in the form of problem P36, \nthen the function ``phi(m)`` can be efficiently calculated as follows: \nLet ``[[p1, m1], [p2, m2], [p3, m3], ...]`` be the list of prime factors (and their multiplicities) of a given number ``m``. \nThen ``phi(m)`` can be calculated with the following formula:\n``phi(m) = (p1-1)*p1^(m1-1) * (p2-1)*p2^(m2-1) * (p3-1)*p3^(m3-1) * ...``\n\n### [P38][] (*) Compare the two methods of calculating Euler's totient function.\nOmitted. The assumption is that you already did the comparison, e.g. as unit test assertions. \n\n### [P39][] (*) A list of prime numbers.\nGiven a range of integers by its lower and upper limit, construct a list of all prime numbers in that range.\n``` kotlin\n\u003e listPrimesInRange(7..31)\n[7, 11, 13, 17, 19, 23, 29, 31]\n```\n\n### [P40][] (*) Goldbach's conjecture.\n[Goldbach's conjecture](https://en.wikipedia.org/wiki/Goldbach's_conjecture) \nsays that every positive even number greater than 2 is the sum of two prime numbers. \nE.g. ``28 = 5 + 23``. It is one of the most famous facts in number theory that has not been proved to be correct \nin the general case. It has been numerically confirmed up to very large numbers (much larger than Kotlin's Int can represent). \nWrite a function to find the two prime numbers that sum up to a given even integer.\n``` kotlin\n\u003e 28.goldbach()\n(5, 23)\n```\n\n### [P41][] (*) A list of Goldbach compositions.\nGiven a range of integers by its lower and upper limit, print a list of all even numbers and their Goldbach composition.\n``` kotlin\n\u003e printGoldbachList(9..20)\n10 = 3 + 7\n12 = 5 + 7\n14 = 3 + 11\n16 = 3 + 13\n18 = 5 + 13\n20 = 3 + 17\n```\nIn most cases, if an even number is written as the sum of two prime numbers, one of them is very small. \nVery rarely, the primes are both bigger than, say, 50. Example (minimum value of 50 for the primes):\n``` kotlin\n\u003e printGoldbachListLimited(2..3000, 50)\n992 = 73 + 919\n1382 = 61 + 1321\n1856 = 67 + 1789\n...\n```\n\n\n## Logic and Codes\n\n### [P46][] (*) Truth tables for logical expressions.\nDefine functions ``and_``, ``or_``, ``nand_``, ``nor_``, ``xor_``, ``impl_``, and ``equ_`` (for logical equivalence) \nwhich return ``true`` or ``false`` according to the result of their respective operations.\n``` kotlin\n\u003e true.and_(true)\ntrue\n\u003e true.xor_(true)\nfalse\n```\n\nWrite a function called ``printTruthTable`` which prints the truth table of a given logical expression.\n``` kotlin\n\u003e printTruthTable{ a, b -\u003e a.and_(a.or_(b.not_())) }\na\tb\tresult\ntrue\ttrue\ttrue\ntrue\tfalse\ttrue\nfalse\ttrue\tfalse\nfalse\tfalse\tfalse\n```\n\n### P47 (*) Truth tables for logical expressions (2).\nFor Scala the task was to use implicit conversion.\nThis is much simpler in Kotlin so the task omitted assuming it was done in the previous problem.\n\n### [P48][] (*) Truth tables for logical expressions (3).\nGeneralize problem 46 in such a way that the logical expression may contain any number of logical variables.\nExample:\n``` kotlin\n\u003e true.xor_(true, false, true)\ntrue\n```\n\n### [P49][] (*) Gray code.\nAn n-bit [Gray code](https://en.wikipedia.org/wiki/Gray_code) is a sequence of n-bit strings constructed according to certain rules. \nFind out the construction rules and write a function to generate Gray codes.\nFor example:\n``` kotlin\n\u003e grayCodes(bits = 1)\n[0, 1]\n\u003e grayCodes(bits = 2)\n[00, 01, 11, 10]\n\u003e grayCodes(bits = 3)\n[000, 001, 011, 010, 110, 111, 101, 100]\n```\n\n### [P50][] (**) Huffman code.\nIf you are not familiar with [Huffman coding](https://en.wikipedia.org/wiki/Huffman_coding), consult internet (or a good book). \n\na) Given characters with their frequencies, e.g. ``{a=25, b=21, c=18, d=14, e=9, f=7, g=6}``.\nOur objective is to construct a ``Map``, where key is character and value is the Huffman code for it.\n``` kotlin\n\u003e createEncoding(linkedMapOf(Pair('a', 25), Pair('b', 21), Pair('c', 18), Pair('d', 14), Pair('e', 9), Pair('f', 7), Pair('g', 6)))\n{a=10, b=00, c=111, d=110, e=010, f=0111, g=0110}\n```\nb) Write ``encode`` and ``decode`` functions for conversion between ``String`` and encoded ``String`` with zeroes and ones.\nFor example:\n``` kotlin\n\"this is a sentence\".encode(encoding)\n\"00110000101011100101011101001110101111011001111011000111\"\n\n\"00110000101011100101011101001110101111011001111011000111\".decode(encoding)\n\"this is a sentence\"\n```\n\n## Binary Trees\n\nA binary tree is either empty or it is composed of a root element and two successors, which are binary trees themselves.\n\n![binary tree][binary-tree]\n\nWe will use the following classes to represent binary trees (see [Tree.kt](https://github.com/dkandalov/kotlin-99/blob/master/src/org/kotlin99/binarytrees/Tree.kt)). \nAn ``End`` is equivalent to an empty tree. A ``Node`` has a value, and two child trees. \nThe ``toString()`` functions are relatively arbitrary and were written to produce minimal readable output.\nNote the usage of [variance annotation](https://kotlinlang.org/docs/reference/generics.html#declaration-site-variance) \n``out T`` which makes classes covariant; it will be able to hold subtypes of whatever type it's created for. \n``End`` is declared as value because [data classes](https://kotlinlang.org/docs/reference/data-classes.html) \nmust have at least one constructor parameter.\n``End`` has type parameter of ``Nothing`` which is a subtype of every other type.\n\n``` kotlin\ninterface Tree\u003cout T\u003e\n\ndata class Node\u003cout T\u003e(val value: T, val left: Tree\u003cT\u003e = End, val right: Tree\u003cT\u003e = End) : Tree\u003cT\u003e {\n    override fun toString(): String {\n        val children = if (left == End \u0026\u0026 right == End) \"\" else \" $left $right\"\n        return \"T($value$children)\"\n    }\n}\n\nval End = object : Tree\u003cNothing\u003e{\n    override fun toString() = \".\"\n}\n```\nThe example of tree above can be written as:\n``` kotlin\nNode('a',\n    Node('b',\n        Node('d'),\n        Node('e')),\n    Node('c', End,\n        Node('f', Node('g'),\n        End)))\n```\nA tree with only a root node would be ``Node('a')`` and an empty tree would be ``End``.\n\n\n### P54 Omitted; our tree representation will only allow well-formed trees.\nScore one for static typing.\n\n### [P55][] (*) Construct completely balanced binary trees.\nIn a completely balanced binary tree, the following property holds for every node. \nThe number of nodes in its left subtree and the number of nodes in its right subtree are almost equal, \nwhich means their difference is not greater than one.\nDefine an object named Tree. Write a function ``balancedTrees`` to construct completely balanced binary trees for a given number of nodes. \nThe function should generate all solutions. The function should take as parameters the number of nodes and a single value to put in all of them.\n``` kotlin\n\u003e balancedTrees(4, \"x\")\n[T(x T(x) T(x . T(x))), T(x T(x . T(x)) T(x)), T(x T(x) T(x T(x) .)), T(x T(x T(x) .) T(x))]\n```\n\n### [P56][] (*) Symmetric binary trees.\nLet us call a binary tree symmetric if you can draw a vertical line through the root node and \nthen the right subtree is the mirror image of the left subtree. \nAdd an ``isSymmetric`` method to the ``Tree`` to check whether a given binary tree is symmetric. \nHint: Write ``isMirrorOf`` method first to check whether one tree is the mirror image of another. \nWe are only interested in the structure, not in the contents of the nodes.\n``` kotlin\n\u003e Node(\"a\", Node(\"b\"), Node(\"c\")).isSymmetric()\ntrue\n```\n\n### [P57][] (*) Binary search trees (dictionaries).\nWrite a function to add an element to a binary search tree.\n``` kotlin\n\u003e End.add(2)\nT(2)\n\u003e res0.add(3)\nT(2 . T(3))\n\u003e res1.add(0)\nT(2 T(0) T(3))\n```\nNote that definition of ``add`` should have ``T : Comparable\u003cT\u003e`` type constraint \nto allows us to use the ``\u003c`` operator on the values in the tree.\n\nUse that function to construct a binary tree from a list of integers.\n``` kotlin\n\u003e listOf(3, 2, 5, 7, 1).toTree()\nT(3 T(2 T(1) .) T(5 . T(7)))\n```\nFinally, use ``isSymmetric()`` from [P56](#p56--symmetric-binary-trees) to check conversion to tree.\n``` kotlin\n\u003e listOf(5, 3, 18, 1, 4, 12, 21).toTree().isSymmetric()\ntrue\n\u003e listOf(3, 2, 5, 7, 4).toTree().isSymmetric()\nfalse\n```\n\n### [P58][] (*) Generate-and-test paradigm.\nApply the generate-and-test paradigm to construct all symmetric, \ncompletely balanced binary trees with a given number of nodes.\n``` kotlin\n\u003e symmetricBalancedTrees(5, \"x\")\n[T(x T(x . T(x)) T(x T(x) .)), T(x T(x T(x) .) T(x . T(x)))]\n```\n\n### [P59][] (**) Construct height-balanced binary trees.\nIn a height-balanced binary tree, the following property holds for every node: \nThe height of its left subtree and the height of its right subtree are almost equal, which means their difference is not greater than one.\nWrite a method ``heightBalancedTrees`` to construct height-balanced binary trees for a given height with a supplied value for the nodes. \nThe function should generate all solutions.\n``` kotlin\n\u003e heightBalancedTrees(3, \"x\")\n[T(x T(x T(x) T(x)) T(x T(x) T(x))), T(x T(x T(x) T(x)) T(x T(x) .)), ...]\n```\n\n### [P60][] (**) Construct height-balanced binary trees with a given number of nodes.\nConsider a height-balanced binary tree of height ``H``. \nThe maximum number of nodes it can contain is ``MaxN = 2**H - 1``. \nHowever, what is the minimum number ``MinN``? This question is more difficult. \nTry to find a recursive statement and turn it into a function ``minNodeAmountInHBTree`` that takes a height and returns ``MinN``.\n``` kotlin\n\u003e minNodeAmountInHBTree(height = 3)\n4\n```\nOn the other hand, we might ask: what is the maximum height ``H`` a height-balanced binary tree with ``N`` nodes can have? \nWrite a ``maxHeightOfHBTree`` function.\n``` kotlin\n\u003e maxHeightOfHBTree(nodeAmount = 4)\n3\n```\nNow, we can attack the main problem: construct all the height-balanced binary trees with a given number of nodes.\n``` kotlin\n\u003e allHBTreesWithNodeAmount(4, \"x\")\n[T(x T(x T(x) .) T(x)), T(x T(x . T(x)) T(x)), ...]\n```\nFind out how many height-balanced trees exist for ``N = 15``.\n\n### [P61][] (*) Leaves and internal nodes of a binary tree.\nA leaf is a node with no successors. \nWrite a method ``leafCount`` to count them.\n``` kotlin\n\u003e Node(\"x\", Node(\"x\"), End).leafCount()\n1\n```\nWrite a method ``leafValues`` to collect leaf values into a list.\n``` kotlin\n\u003e Node(\"a\", Node(\"b\"), Node(\"c\", Node(\"d\"), Node(\"e\"))).leafValues()\n[b, d, e]\n```\nAn internal node of a binary tree has either one or two non-empty successors. \nWrite a method ``internalValues`` to collect their values into a list.\n``` kotlin\n\u003e Node(\"a\", Node(\"b\"), Node(\"c\", Node(\"d\"), Node(\"e\"))).internalValues()\n[a, c]\n```\n\n### [P62][] (*) Collect nodes at a given level in a list.\nA node of a binary tree is at level ``N`` if the path from the root to the node has length ``N-1``. \nThe root node is at level 1. Write a method ``valuesAtLevel`` to collect all node values at a given level into a list.\n``` kotlin\n\u003e Node('a', Node('b'), Node('c', Node('d'), Node('e'))).valuesAtLevel(2)\n[b, c]\n```\nUsing ``valuesAtLevel`` it is easy to construct a method to create the level-order sequence of the nodes. \nHowever, there are more efficient ways to do that.\n\n### [P63][] (*) Construct a complete binary tree.\nA [complete binary tree](https://en.wikipedia.org/wiki/Binary_tree#Types_of_binary_trees) with height ``H`` is defined as follows: \nThe levels ``1,2,3,...,H-1`` contain the maximum number of nodes, i.e ``2(i-1)`` nodes at the level ``i`` (note that we start counting the levels from 1 at the root). \nAt level ``H``, which may contain less than the maximum possible number of nodes, all the nodes are \"left-adjusted\". \nThis means that in a level-order tree traversal all internal nodes come first, the leaves come second, \nand empty successors (the ``End``s which are not really nodes) come last.\nParticularly, complete binary trees are used as data structures (or addressing schemes) for heaps.\n\nWe can assign an address number to each node in a complete binary tree by enumerating the nodes in level order, \nstarting at the root with number 1. In doing so, we realize that for every node ``X`` with address ``A`` the following property holds: \nThe address of ``X``'s left and right children are ``2*A`` and ``2*A+1`` (assuming the children exist). \nThis fact can be used to elegantly construct a complete binary tree structure.\n \nWrite a method ``completeBinaryTree`` that takes as parameters the number of nodes and the value to put in each node.\n``` kotlin\n\u003e completeBinaryTree(6, \"x\")\nT(x T(x T(x) T(x)) T(x T(x) .))\n```\n\n### [P64][] (**) Layout a binary tree (1).\nAs a preparation for drawing a tree, a layout algorithm is required to determine the position of each node in a rectangular grid. \nSeveral layout methods are conceivable, one of them is shown in the illustration below.\nThis tree can be constructed with ``\"nkmcahgeupsq\".toList().toTree()``.\n\n![P64][P64-layout]\n\nIn this layout strategy, the position of a node ``v`` is obtained by the following two rules:\n- ``x(v)`` is equal to the position of the node ``v`` in the in-order sequence\n- ``y(v)`` is equal to the depth of the node ``v`` in the tree\nIn order to store the position of the nodes, we add a new data classes with the additional information.\n``` kotlin\ndata class Point(val x: Int, val y: Int)\n\ndata class Positioned\u003cout T\u003e(val value: T, val point: Point) {\n    constructor (value: T, x: Int, y: Int) : this(value, Point(x, y))\n\n    override fun toString(): String =\n            \"[\" + point.x.toString() + \",\" + point.y.toString() + \"] \" + value.toString()\n}\n```\nWrite a method ``layout`` that turns a tree of normal ``Node``s into a tree with positions ``Tree\u003cPositioned\u003cT\u003e\u003e``.\n``` kotlin\n\u003e Node(\"a\", Node(\"b\", End, Node(\"c\")), Node(\"d\")).layout()\nT([3,1] a T([1,2] b . T([2,3] c)) T([4,2] d))\n```\n\n### [P65][] (**) Layout a binary tree (2).\nAn alternative layout method is depicted in the illustration below \n(note that it is not the same tree as in the previous problem).\nThis tree can be constructed with ``\"nkmcaedgupq\".toList().toTree()``.\n\n![P65][P65-layout]\n\nFind out the rules and write the corresponding method. \nHint: On a given level, the horizontal distance between neighboring nodes is constant.\nUse the same conventions as in the problem [P64](#p64--layout-a-binary-tree-1).\n``` kotlin\n\u003e Node(\"a\", Node(\"b\", End, Node(\"c\")), Node(\"d\")).layout2()\nT[3,1]('a T[1,2]('b . T[2,3]('c . .)) T[5,2]('d . .))\n```\n\n\n### [P66][] (***) Layout a binary tree (3).\nYet another layout strategy is shown in the illustration below. \nThis tree can be constructed with ``\"nkmcaedgupq\".toList().toTree()``.\n\n![P66][P66-layout]\n\nThe method yields a very compact layout while maintaining a certain symmetry in every node. \nFind out the rules and write the corresponding method. \nHint: Consider the horizontal distance between a node and its successor nodes. \nHow tight can you pack together two subtrees to construct the combined binary tree?\nUse the same conventions as in problem [P64](#p64--layout-a-binary-tree-1) and [P65](#p65--layout-a-binary-tree-2). \nNote: This is a difficult problem. Don't give up too early!\n``` kotlin\n\u003e Node('a', Node('b', End, Node('c')), Node('d')).layoutBinaryTree3()\nT[2,1]('a T[1,2]('b . T[2,3]('c . .)) T[3,2]('d . .))\n```\nWhich layout do you like most?\n\n### [P67][] (**) A string representation of binary trees.\nBinary trees can be represented as strings of the following type:\n``a(b(d,e),c(,f(g,)))``.\n\n![P67][P67-tree]\n\nWrite a method which generates this string representation given tree as ``Node``s and ``End``s. \nAnd a method which does this inverse, i.e. given the string representation, construct the tree in the usual form.\n``` kotlin\n\u003e Node(\"a\", Node(\"b\", Node(\"d\"), Node(\"e\")), Node(\"c\", End, Node(\"f\", Node(\"g\"), End))).convertToString()\na(b(d,e),c(,f(g,)))\n\u003e \"a(b(d,e),c(,f(g,)))\".convertToTree()\nT(a T(b T(d) T(e)) T(c . T(f T(g) .)))\n```\n\n### [P68][] (**) Preorder and inorder sequences of binary trees.\na) Write methods ``preorder`` and ``inorder`` that construct the pre-order and in-order sequence of a given binary tree, respectively. \nThe results should be lists, e.g. ``[\"a\",\"b\",\"d\",\"e\",\"c\",\"f\",\"g\"]`` for the preorder sequence of the example in problem \n[P67](#p67--a-string-representation-of-binary-trees).\n``` kotlin\n\u003e \"a(b(d,e),c(,f(g,)))\".convertToTree().preorder()\n[a, b, d, e, c, f, g]\n\u003e \"a(b(d,e),c(,f(g,)))\".convertToTree().inorder()\n[d, b, e, a, c, g, f]\n```\nb) If both the preorder sequence and the in-order sequence of the nodes of a binary tree are given, \nthen the tree is determined unambiguously. Write a method ``createTree`` that does the job.\n``` kotlin\n\u003e createTree(preorder = listOf(\"a\", \"b\", \"d\", \"e\", \"c\", \"f\", \"g\"), inorder = listOf(\"d\", \"b\", \"e\", \"a\", \"c\", \"g\", \"f\"))\na(b(d,e),c(,f(g,)))\n```\nWhat happens if the same character appears in more than one node? Try, for instance: \n``` kotlin\ncreateTree(preorder = listOf(\"a\", \"b\", \"a\"), inorder = listOf(\"b\", \"a\", \"a\"))\n```\n\n### [P69][] (*) Dot-string representation of binary trees.\nBinary tree in which leaves contain only single characters can be represented by the preorder sequence of its nodes \nin which dots ``.`` are inserted where an empty subtree ``End`` is encountered during tree traversal. \nFor example, the tree shown in problem [P67](#p67--a-string-representation-of-binary-trees) is represented as ``abd..e..c.fg...``.\n\nFirst, try to establish a syntax ([BNF](https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form) or syntax diagrams) \nand then write two methods, ``toDotString`` and ``fromDotString``, which do the conversion in both directions.\n``` kotlin\n\u003e \"a(b(d,e),c(,f(g,)))\".convertToTree().toDotString()\nabd..e..c.fg...\n\u003e \"abd..e..c.fg...\".fromDotString()\na(b(d,e),c(,f(g,)))\n```\n\n\n## Multiway Trees\n\nA [multiway tree](https://en.wikipedia.org/wiki/List_of_data_structures#Multiway_trees) \nis composed of a root element and a (possibly empty) set of successors which are multiway trees themselves. \nA multiway tree is never empty. The set of successor trees is sometimes called a forest.\n\n![Multiway tree][multiway-tree]\n\nThe code to represent multiway-trees is somewhat simpler than the code for binary trees, partly because we don't separate classes \nfor nodes and terminators, and partly because we don't need the restriction for the value type to be ordered.\n``` kotlin\ndata class MTree\u003cout T\u003e(val value: T, val children: List\u003cMTree\u003cT\u003e\u003e = emptyList()) {\n\n    constructor(value: T, vararg children: MTree\u003cT\u003e): this(value, children.toList())\n\n    override fun toString(): String =\n        if (children.isEmpty()) value.toString()\n        else value.toString() + \" {\" + children.joinToString(\", \"){ it.toString() } + \"}\"\n} \n```\nThe example tree is, thus:\n``` kotlin\nMTree(\"a\",\n    MTree(\"f\",\n        MTree(\"g\")),\n    MTree(\"c\"),\n    MTree(\"b\",\n        MTree(\"d\"), MTree(\"e\"))\n))\n\n```\nThe starting code for this section is in [MTree.kt](https://github.com/dkandalov/kotlin-99/blob/master/src/org/kotlin99/multiwaytrees/MTree.kt).\n\n\n### [P70A][] (*) Count the nodes of a multiway tree.\nWrite a method ``nodeCount`` which counts the nodes of a given multiway tree.\n``` kotlin\n\u003e MTree(\"a\", MTree(\"f\")).nodeCount()\n2\n```\n\n### [P70B][] (*) Tree construction from a node string.\nSuppose that the nodes of a multiway tree contain single characters. In the depth-first order sequence of its nodes, \na special character ``^`` has been inserted whenever, during the tree traversal, the move is a backtrack to the previous level.\nBy this rule, the tree in the following figure is represented as: ``afg^^c^bd^e^^^``.\n\n![Multiway tree][multiway-tree]\n\nDefine the syntax of the string and write a function ``convertToMTree`` to construct an ``MTree`` from a ``String``. \nWrite the reverse ``convertToString`` function.\n``` kotlin\n\u003e MTree('a', MTree('f', MTree('g')), MTree('c'), MTree('b', MTree('d'), MTree('e'))).toString()\nafg^^c^bd^e^^^\n```\n\n### [P71][] (*) Determine the internal path length of a tree.\nWe define the internal path length of a multiway tree as the total sum of the path lengths from the root to all nodes of the tree. \nBy this definition, the tree in the figure of problem [P70B](#p70b--tree-construction-from-a-node-string) \nhas an internal path length of 9. Write a method ``internalPathLength`` to return that sum.\n``` kotlin\n\u003e \"afg^^c^bd^e^^^\".convertToMTree().internalPathLength()\n9\n```\n\n### [P72][] (*) Construct the postorder sequence of the tree nodes.\nWrite a method postorder which constructs the postorder sequence of the node values of a multiway tree. \nThe result should be a ``List``.\n``` kotlin\n\u003e \"afg^^c^bd^e^^^\".convertToMTree().postorder()\n[g, f, c, d, e, b, a]\n```\n\n### [P73][] (**) Lisp-like tree representation.\n[Lisp](https://en.wikipedia.org/wiki/Lisp_(programming_language)) is a prominent functional programming language. \nIn Lisp almost everything is a list. Our example tree would be represented in Lisp as ``(a (f g) c (b d e))``. \nThe following pictures give some more examples.\n\n![P73][P73-s-expr]\n\nNote that in the Lisp notation a node with successors (children) in the tree is always the first element in a list, followed by its children. \nThe \"lispy\" representation of a multiway tree is a sequence of atoms and parentheses ``(`` and ``)``, with the atoms separated by spaces. \n\na) Write a method ``toLispString`` which constructs a \"lispy\" ``String`` from an ``MTree``.\n``` kotlin\n\u003e MTree(\"a\", MTree(\"b\", MTree(\"c\"))).toLispString()\n(a (b c))\n```\nb) As a second, even more interesting, exercise try to write a method that takes a \"lispy\" string and turns it into a multiway tree.\n``` kotlin\n\u003e \"(a (f g) c (b d e))\".fromLispString()\na {f {g}, c, b {d, e}}\n```\n\n\n## Graphs\n\n(Warning! The introductory text below is quite long. If you are familiar with graphs, \nyou might just look at source code in [Graph.kt](https://github.com/dkandalov/kotlin-99/blob/master/src/org/kotlin99/graphs/Graph.kt).)\n\nA [graph](https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)) \nis defined as a set of nodes and a set of edges, where each edge is a pair of nodes.\n\nThe class to represent a graph is mutable, which isn't in keeping with pure functional programming, \nbut a pure functional data structure would make things much, much more complicated. \nPure functional graphs with cycles require laziness; Kotlin can probably handle it, \nbut I think that would add too much of a barrier to the following questions.\n\n![graph][undirected-graph]\n\nOur graphs use an incidence list internally. Each has a list of nodes and a list of edges. \nEach node also has a list of edges that connect it to other nodes. \nIn a [directed graph](https://en.wikipedia.org/wiki/Directed_graph), \nnodes, that are the target of arcs, do not have references to those arcs in their adjacency list.\n``` kotlin\nclass Graph\u003cT, U\u003e {\n    val nodes: MutableMap\u003cT, Node\u003cT, U\u003e\u003e = HashMap()\n    val edges: MutableList\u003cEdge\u003cT, U\u003e\u003e = ArrayList()\n\n    fun addNode(value: T): Node\u003cT, U\u003e {\n        val node = Node\u003cT, U\u003e(value)\n        nodes.put(value, node)\n        return node\n    }\n\n    fun addUndirectedEdge(n1: T, n2: T, label: U?) {\n        if (!nodes.contains(n1) || !nodes.contains(n2)) {\n            throw IllegalStateException(\"Expected '$n1' and '$n2' nodes to exist in graph\")\n        }\n        val edge = UndirectedEdge(nodes[n1]!!, nodes[n2]!!, label)\n        if (edges.all{ !it.equivalentTo(edge) }) {\n            edges.add(edge)\n            nodes[n1]!!.edges.add(edge)\n            nodes[n2]!!.edges.add(edge)\n        }\n    }\n\n    fun addDirectedEdge(source: T, dest: T, label: U?) {\n        val edge = DirectedEdge(nodes[source]!!, nodes[dest]!!, label)\n        if (!edges.contains(edge)) {\n            edges.add(edge)\n            nodes[source]!!.edges.add(edge)\n        }\n    }\n\n\n    data class Node\u003cT, U\u003e(val value: T) {\n        val edges: MutableList\u003cEdge\u003cT, U\u003e\u003e = ArrayList()\n        fun neighbors(): List\u003cNode\u003cT, U\u003e\u003e = edges.map{ edge -\u003e edge.target(this)!! }\n        override fun toString() = value.toString()\n    }\n\n    interface Edge\u003cT, U\u003e {\n        val n1: Node\u003cT, U\u003e\n        val n2: Node\u003cT, U\u003e\n        val label: U?\n        fun target(node: Node\u003cT, U\u003e): Node\u003cT, U\u003e?\n        fun equivalentTo(other: Edge\u003cT, U\u003e) =\n                (n1 == other.n1 \u0026\u0026 n2 == other.n2) || (n1 == other.n2 \u0026\u0026 n2 == other.n1)\n    }\n\n    data class UndirectedEdge\u003cT, U\u003e(override val n1: Node\u003cT, U\u003e, override val n2: Node\u003cT, U\u003e, override val label: U?) : Edge\u003cT, U\u003e {\n        override fun target(node: Node\u003cT, U\u003e) = if (n1 == node) n2 else if (n2 == node) n1 else null\n        override fun toString() = n1.toString() + \"-\" + n2 + (if (label == null) \"\" else \"/\" + label.toString())\n    }\n\n    data class DirectedEdge\u003cT, U\u003e(override val n1: Node\u003cT, U\u003e, override val n2: Node\u003cT, U\u003e, override val label: U?) : Edge\u003cT, U\u003e {\n        override fun target(node: Node\u003cT, U\u003e) = if (n1 == node) n2 else null\n        override fun toString() = n1.toString() + \"\u003e\" + n2 + (if (label == null) \"\" else \"/\" + label.toString())\n    }\n}\n\n```\n\nThere are a few ways to create a graph from primitives. The graph-term form lists the nodes and edges separately:\n``` kotlin\nGraph.terms(TermForm(\n    nodes = listOf(\"b\", \"c\", \"d\", \"f\", \"g\", \"h\", \"k\"),\n    edges = listOf(Term(\"b\", \"c\"), Term(\"b\", \"f\"), Term(\"c\", \"f\"), Term(\"f\", \"k\"), Term(\"g\", \"h\"))))\n```\nThe adjacency-list form associates each node with its adjacent nodes. In an undirected graph, care must be taken to ensure \nthat all links are symmetric, i.e. if ``b`` is adjacent to ``c``, ``c`` must also be adjacent to ``b``.\n``` kotlin\nGraph.adjacent(AdjacencyList(\n    Entry(\"b\", links(\"c\", \"f\")),\n    Entry(\"c\", links(\"b\", \"f\")),\n    Entry(\"d\"),\n    Entry(\"f\", links(\"b\", \"c\", \"k\")),\n    Entry(\"g\", links(\"h\")),\n    Entry(\"h\", links(\"g\")),\n    Entry(\"k\", links(\"f\"))))\n```\nThe representations we introduced so far are bound to our implementation and therefore well suited for automated processing, \nbut their syntax is not very user-friendly. Typing the terms by hand is cumbersome and error-prone. \nWe can define a more compact and \"human-friendly\" notation as follows: \nA graph is represented by a string of terms of the type ``X`` or ``Y-Z`` separated by commas. \nThe standalone terms stand for isolated nodes, the ``Y-Z`` terms describe edges. \nIf an ``X`` appears as an endpoint of an edge, it is automatically defined as a node. \nOur example could be written as:\n```\n[b-c, f-c, g-h, f-b, k-f, h-g, d]\n```\nWe call this the human-friendly form. As the example shows, the list does not have to be sorted \nand may even contain the same edge multiple times. Notice the isolated node ``d``.\n\n[Directed graph](https://en.wikipedia.org/wiki/Directed_graph) is a graph where edges have direction.\nTo represent a directed graph, the forms discussed above are slightly modified. \nThe example graph is represented as follows:\n\n![graph][directed-graph]\n\nIn graph-term form:\n``` kotlin\nGraph.directedTerms(TermForm(\n    listOf(\"r\", \"s\", \"t\", \"u\", \"v\"),\n    listOf(Term(\"s\", \"r\"), Term(\"s\", \"u\"), Term(\"u\", \"r\"), Term(\"u\", \"s\"), Term(\"v\", \"u\"))))\n```\nIn adjacency-list form (note that the adjacency-list form is the same for graphs and digraphs):\n``` kotlin\nGraph.directedAdjacent(AdjacencyList(\n    Entry(\"r\"),\n    Entry(\"s\", links(\"r\", \"u\")),\n    Entry(\"t\"),\n    Entry(\"u\", links(\"r\", \"s\")),\n    Entry(\"v\", links(\"u\"))))\n```\n\nHuman-friendly form:\n```\n[s\u003er, s\u003eu, u\u003er, u\u003es, v\u003eu, t]\n```\nFinally, graphs with additional information attached to edges are called labeled graphs.\n\n![graph][directed-labeled-graph]\n\nGraph-term form:\n``` kotlin\nGraph.labeledTerms(TermForm(\n    listOf(\"k\", \"m\", \"p\", \"q\"),\n    listOf(Term(\"m\", \"q\", 7), Term(\"p\", \"m\", 5), Term(\"p\", \"q\", 9))))\n```                  \nAdjacency-list form:\n``` kotlin\nGraph.labeledDirectedAdjacent(AdjacencyList(\n    Entry(\"k\"),\n    Entry(\"m\", Link(\"q\", 7)),\n    Entry(\"p\", Link(\"m\", 5), Link(\"q\", 9)),\n    Entry(\"q\")))\n```\nHuman-friendly form:\n```\n[m-q/7, p-m/5, p-q/9, k]\n```\nThe notation for labeled graphs can also be used for so-called multi-graphs, \nwhere more than one edge is allowed between two given nodes.\n\n### [P80][] (*) Conversions.\nWrite ``String.toGraph()`` and ``String.toLabeledGraph()`` functions to create graphs from strings \n(you can detect if graph is labeled or unlabeled based on input string format).\nWrite functions ``toTermForm`` and ``toAdjacencyList`` to generate the graph-term and adjacency-list forms of a ``Graph``. \n``` kotlin\n\u003e \"[b-c, b-f, c-f, f-k, g-h, d]\".toGraph().toTermForm()\nTermForm(nodes=[f, g, d, b, c, k, h], edges=[Term(b, c), Term(b, f), Term(c, f), Term(f, k), Term(g, h)])\n\u003e \"[m\u003eq/7, p\u003em/5, p\u003eq/9, k]\".toLabeledGraph().toAdjacencyList()\nAdjacencyList(Entry(\"q\"), Entry(\"p\", listOf(Link(\"q\", 9), Link(\"m\", 5))), Entry(\"m\", listOf(Link(\"q\", 7))), Entry(\"k\"))\n```\n\n### [P81][] (***) Path between nodes.\na) Write method ``findAllPaths`` to find acyclic paths from one node to another in a graph. \nThe method should return all paths.\n``` kotlin\n\u003e \"[p\u003eq/9, m\u003eq/7, k, p\u003em/5]\".toLabeledGraph().findAllPaths(\"p\", \"q\")\n[[p, q], [p, m, q]]\n\u003e \"[p\u003eq/9, m\u003eq/7, k, p\u003em/5]\".toLabeledGraph().findAllPaths(\"p\", \"k\")\n[]\n```\nb) Write method ``findShortestPath`` to find [shortest path](https://en.wikipedia.org/wiki/Shortest_path_problem) between two nodes.\nHint: use [Dijkstra](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) or [A* algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm).\n``` kotlin\n\"[a-b/1, b-c/1, a-c/3]\".toLabeledGraph().findShortestPath(\"a\", \"c\")\n[a, b, c]\n```\n\n### [P82][] (*) Cycles from a node.\nWrite a method named ``findCycles`` to find closed paths (cycles) starting at a given node in a graph. \nThe method should return all cycles. (Note that single edge doesn't count as a cycle.)\n``` kotlin\n\u003e \"[a-b]\".toGraph().findCycles(\"a\")\n[]\n\u003e \"[b-c, b-f, c-f, f-k, g-h, d]\".toGraph().findCycles(\"f\")\n[[f, c, b, f], [f, b, c, f]]\n```\n\n### [P83][] (**) Spanning trees.\nWrite a method ``spanningTrees`` to construct all [spanning trees](https://en.wikipedia.org/wiki/Spanning_tree) of a given graph. \n\nWhen you have a correct solution for the ``spanningTrees`` method, \nuse it to define two other useful methods: ``Graph.isTree`` and ``Graph.isConnected``.\n``` kotlin\n\u003e \"[a-b, b-c, a-c]\".toGraph().spanningTrees()\n[[a-b, b-c], [a-b, c-a], [b-c, c-a]]\n\u003e \"[a-b, b-c, a-c]\".toGraph().isTree()\nfalse\n\u003e \"[a-b, b-c, a-c]\".toGraph().isConnected()\ntrue\n``` \nFind out how many spanning trees there are for the graph depicted below.\n\n![graph][P83-graph]\n\n``` kotlin\n\"[a-b, a-d, b-c, b-e, c-e, d-e, d-f, d-g, e-h, f-g, g-h]\".toGraph()\n```\n\n### [P84][] (**) Minimum spanning tree.\nWrite a method ``minSpanningTree`` to construct the [minimum spanning tree](https://en.wikipedia.org/wiki/Minimum_spanning_tree)\nof a given labeled graph. Hint: Use [Prim's Algorithm](https://en.wikipedia.org/wiki/Prim's_algorithm).\n``` kotlin\n\u003e \"[a-b/1, b-c/2, a-c/3]\".toLabeledGraph().minSpanningTree()\n[a-b/1, b-c/2]\n``` \nFind minimum spanning tree for the graph below:\n\n![graph][P84-graph]\n\n``` kotlin\n\"[a-b/5, a-d/3, b-c/2, b-e/4, c-e/6, d-e/7, d-f/4, d-g/3, e-h/5, f-g/4, g-h/1]\".toLabeledGraph()\n```\n\n### [P85][] (**) [Graph isomorphism](https://en.wikipedia.org/wiki/Graph_isomorphism_problem).\nTwo graphs ``G1(N1,E1)`` and ``G2(N2,E2)`` are [isomorphic](https://en.wikipedia.org/wiki/Graph_isomorphism) \nif there is a [bijection](https://en.wikipedia.org/wiki/Bijection) ``f: N1 → N2`` \nsuch that for any nodes ``X``,``Y`` of ``N1``, ``X`` and ``Y`` are adjacent if and only if ``f(X)`` and ``f(Y)`` are adjacent. \n\nWrite a method that determines whether two graphs are isomorphic.\n``` kotlin\n\u003e \"[a-b]\".toGraph().isIsomorphicTo(\"[5-7]\".toGraph())\ntrue\n\u003e \"[a-b, b-c]\".toGraph().isIsomorphicTo(\"[1-2, 3]\".toGraph())\nfalse\n\u003e \"[a-b, b-c, c-d, d-a]\".toGraph().isIsomorphicTo(\"[1-2, 2-3, 3-4, 4-1]\".toGraph()\ntrue\n```\n\n### [P86][] (**) Node degree and graph coloration.\na) Write a method ``Node.degree`` that determines the [degree](https://en.wikipedia.org/wiki/Degree_(graph_theory)) \nof a given node in an undirected graph.\n``` kotlin\n\u003e \"[a-b, b-c, a-c, a-d]\".toGraph().nodes[\"a\"].degree()\n3\n```\nb) Use [Welsh-Powell's](http://graphstream-project.org/doc/Algorithms/Welsh-Powell/) algorithm \nto paint the nodes of an undirected graph in such a way that adjacent nodes have different colors. \nWrite a method ``colorNodes`` that returns a list of tuples, each of which contains a node and an integer representing its color.\n``` kotlin\n\u003e \"[a-b, b-c, a-c, a-d]\".toGraph().colorNodes()\n[(a,1), (b,2), (c,3), (d,2)]\n```\n\n### [P87][] (**) Depth-first order graph traversal.\na) Write a method that generates a depth-first order graph traversal sequence. \nThe starting point should be specified, and the output should be a list of nodes \nthat are reachable from this starting point (in depth-first order).\n``` kotlin\n\u003e \"[a-b, b-c, c-d, d-e]\".toGraph().nodesByDepthFrom(\"c\")\n[c, b, a, d, e]\n```\nb) Write similar method for breadth-first graph traversal.\n``` kotlin\n\u003e \"[a-b, b-c, c-d, d-e]\".toGraph().nodesByBreadthFrom(\"c\")\n[c, b, d, a, e]\n```\n\n### [P88][] (*) Connected components.\nWrite a function that splits a graph into its [connected components](https://en.wikipedia.org/wiki/Connected_component_(graph_theory)).\n``` kotlin\n\u003e \"[a-b, c-d]\".toGraph().components()\n[[a-b], [c-d]]\n```\n\n### [P89][] (**) Bipartite graphs.\nWrite a function that determines whether a given graph is [bipartite](http://en.wikipedia.org/wiki/Bipartite_graph).\n``` kotlin\n\u003e \"[a-b, b-c]\".toGraph().isBipartite()\ntrue\n\u003e \"[a-b, b-c, c-a]\".toGraph().isBipartite()\nfalse\n\u003e \"[a-b, b-c, d]\".toGraph().isBipartite()\ntrue\n\u003e \"[a-b, b-c, d, e-f, f-g, g-e, h]\".toGraph().isBipartite()\nfalse\n\u003e \"[a\u003eb, c\u003ea, d\u003eb]\".toGraph().isBipartite()\ntrue\n```\n\n\n\n## Miscellaneous\n\n\n### [P90][] (**) [Eight queens](https://en.wikipedia.org/wiki/Eight_queens_puzzle).\nThis is a classical problem in computer science. \nThe objective is to place eight queens on a chessboard so that no two queens are attacking each other, \ni.e. no two queens are in the same row, column or diagonal.\n\nHint: it might be easier to represent positions of the queens as a list of numbers ``1..N``.\nFor example, ``listOf(4, 2, 7, 3, 6, 8, 5, 1)`` meaning that queen in the first column is in row 4, \nthe queen in the second column is in row 2, etc. Otherwise, feel free to use a data class for queen position. \n\n\n### [P91][] (**) [Knight's tour](https://en.wikipedia.org/wiki/Knight%27s_tour).\nThis is another classical problem in computer science. \nHow can a knight jump on an ``N×N`` chessboard in such a way that it visits every square exactly once?\n\nWrite a function ``knightsTours(N, (X, Y))`` to list all knight tours that be made from ``(X, Y)`` on a ``N×N`` chessboard. \nHints: It might help to represent squares by pairs of their coordinates of the form ``Pair(X, Y)``, \nwhere ``X`` and ``Y`` are integers between ``0`` and ``N-1``. Alternatively, define a ``Point`` data class for this purpose. \n\nCan you find only \"closed tours\", where the knight can jump from its final position back to its starting position?\nCan you make a lazy list that only calculates the tours as needed?\n\n\n### [P92][] (***) Von Koch's conjecture (see also [graceful labeling](https://en.wikipedia.org/wiki/Graceful_labeling)).\nSeveral years ago I met a mathematician who was intrigued by a problem for which he didn't know a solution. \nHis name was Von Koch, and I don't know whether the problem has been solved since. \n(The \"I\" here refers to the author of the Prolog problems.) \n\nAnyway the puzzle goes like this: Given a tree with ``N`` nodes (and hence ``N-1`` edges), \nfind a way to enumerate the nodes from ``1`` to ``N`` and, accordingly, the edges from ``1`` to ``N-1`` in such a way, \nthat for each edge ``K`` the difference of its node numbers is equal to ``K``. \nThe conjecture is that this is always possible.\n\n![tree][P92-tree1]\n\nFor small trees the problem is easy to solve by hand. However, for larger trees, and 14 is already very large, it is extremely difficult \nto find a solution. And remember, we don't know for sure whether there is always a solution!\n\nWrite a function that calculates a numbering scheme for a given tree. What is the solution for the larger tree pictured below?\n\n![tree][P92-tree2]\n\n\n### [P93][] (***) An arithmetic puzzle.\nGiven a list of integer numbers, find a correct way of inserting arithmetic operators ``+-*/()`` such that the result is a correct equation. \nExample: With the list of numbers ``2, 3, 5, 7, 11`` we can form the equations ``2 - 3 + 5 + 7 = 11``, ``2 = (3 * 5 + 7) / 11`` and others.\n\n### [P94][] (***) [Regular graphs](https://en.wikipedia.org/wiki/Regular_graph) with N nodes.\nIn a K-regular graph all nodes have a degree of ``K``, i.e. the number of edges incident in each node is ``K``. \nWrite a function to find all non-isomorphic 3-regular graphs with 6 nodes. \n\n### [P95][] (**) English number words.\nOn financial documents, like checks, numbers must sometimes be written in full words. \nFor example, ``175`` will be written as ``one hundred seventy five``. \nWrite a function ``Int.toWords()`` to convert (non-negative) integer numbers to words.\n\n### [P96][] (**) [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life).\nThe Game of Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.\n\nThe game is represented by a 2-dimensional grid populated with cells.\nEvery cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, \nor diagonally adjacent. At each step in time, the following transitions occur:\n- Any live cell with fewer than two live neighbours dies, as if caused by under-population.\n- Any live cell with two or three live neighbours lives on to the next generation.\n- Any live cell with more than three live neighbours dies, as if by over-population.\n- Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.\n\nNote that there are certain patterns which can keep cells alive forever.\nSee [examples of patterns](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life#Examples_of_patterns) on Wikipedia.\n\nWrite a program to simulate evolution of cells in The Game of Life.\n\n\n### [P97][] (***) [Sudoku](https://en.wikipedia.org/wiki/Sudoku).\nSudoku puzzles go like this:\n```\nProblem          Solution\n\n..4|8..|.17\t 934|825|617\n67.|9..|...\t 672|914|853\n5.8|.3.|..4\t 518|637|924\n---+---+---\t ---+---+---\n3..|74.|1..\t 325|748|169\n.69|...|78.\t 469|153|782\n..1|.69|..5\t 781|269|435\n---+---+---\t ---+---+---\n1..|.8.|3.6\t 197|582|346\n...|..6|.91\t 853|476|291\n24.|..1|5..\t 246|391|578\n```\nEvery cell in the puzzle belongs to a (horizontal) row and a (vertical) column, as well as to one single ``3×3`` square. \nAt the beginning, some of the cells carry a single-digit number between ``1`` and ``9``. \nThe problem is to fill the missing cells with digits in such a way that every number between ``1`` and ``9`` appears exactly once in each row, \nin each column, and in each square.\n\n### [P98][] (***) [Nonograms](https://en.wikipedia.org/wiki/Nonogram).\nAround 1994, a certain kind of puzzles was very popular in England. The \"Sunday Telegraph\" newspaper wrote: \n\"Nonograms are puzzles from Japan and are currently published each week only in The Sunday Telegraph. \nSimply use your logic and skill to complete the grid and reveal a picture or diagram.\" \nAs a programmer, you are in a better situation: you can have your computer do the work! Just write a little program ;-)\n\nEach row and column of a rectangular bitmap is annotated with the respective lengths \nof its distinct strings of occupied cells. The person who solves the puzzle must complete the bitmap given only these lengths.\n```\nProblem                     Solution\n\n|_|_|_|_|_|_|_|_| 3         |_|X|X|X|_|_|_|_| 3           \n|_|_|_|_|_|_|_|_| 2 1       |X|X|_|X|_|_|_|_| 2 1         \n|_|_|_|_|_|_|_|_| 3 2       |_|X|X|X|_|_|X|X| 3 2         \n|_|_|_|_|_|_|_|_| 2 2       |_|_|X|X|_|_|X|X| 2 2         \n|_|_|_|_|_|_|_|_| 6         |_|_|X|X|X|X|X|X| 6           \n|_|_|_|_|_|_|_|_| 1 5       |X|_|X|X|X|X|X|_| 1 5         \n|_|_|_|_|_|_|_|_| 6         |X|X|X|X|X|X|_|_| 6           \n|_|_|_|_|_|_|_|_| 1         |_|_|_|_|X|_|_|_| 1           \n|_|_|_|_|_|_|_|_| 2         |_|_|_|X|X|_|_|_| 2           \n 1 3 1 7 5 3 4 3             1 3 1 7 5 3 4 3              \n 2 1 5 1                     2 1 5 1\n```\nFor the example above, the problem can be stated as the two lists ``[[3],[2,1],[3,2],[2,2],[6],[1,5],[6],[1],[2]]`` and \n``[[1,2],[3,1],[1,5],[7,1],[5],[3],[4],[3]]`` which give the \"solid\" lengths of the rows and columns, top-to-bottom and left-to-right, \nrespectively. Published puzzles are larger than this example, e.g. ``25×20``, and always have unique solutions.\n\n### [P99][] (***) Crossword puzzle.\nGiven an empty (or almost empty) framework of a crossword puzzle and a set of words the problem is to place the words into the framework.\nThe particular crossword puzzle is specified in a text file which first lists the words (one word per line) in an arbitrary order. \nThen, after an empty line, the crossword framework is defined. In this framework specification, an empty character location is represented \nby a dot `.`. In order to make the solution easier, character locations can also contain predefined character values. \nThe crossword showed below is defined in the file [p99a.dat][], other examples are [p99b.dat][] and [p99d.dat][]. \nThere is also an example of a puzzle ([p99c.dat][]) which does not have a solution.\n\n![crossword][P99-crossword]\n\nContent of p99a.dat:\n```\nLINUX\nPROLOG\nPERL\nONLINE\nGNU\nXML\nNFS\nSQL\nEMACS\nWEB\nMAC\n\n......  .\n. .  .  .\n. ..... .\n. . . ...\n  . ... .\n ...\n```\n\nWords are strings of at least two characters. A horizontal or vertical sequence of character places in the crossword puzzle \nframework is called a site. Our problem is to find a compatible way of placing words onto sites.\n\n### [P100][] (*****) Write a high-level language or at least [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) for [SAT](https://en.wikipedia.org/wiki/Boolean_satisfiability_problem) solvers.\nE.g. something like [Sentient Language](http://sentient-lang.org/) :smile: \n\n\n[P01]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P01.kt\n[P02]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P02.kt\n[P03]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P03.kt\n[P04]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P04.kt\n[P05]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P05.kt\n[P06]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P06.kt\n[P07]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P07.kt\n[P08]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P08.kt\n[P09]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P09.kt\n[P10]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P10.kt\n[P11]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P11.kt\n[P12]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P12.kt\n[P13]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P13.kt\n[P14]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P14.kt\n[P15]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P15.kt\n[P16]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P16.kt\n[P17]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P17.kt\n[P18]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P18.kt\n[P19]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P19.kt\n[P20]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P20.kt\n[P21]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P21.kt\n[P22]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P22.kt\n[P23]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P23.kt\n[P24]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P24.kt\n[P25]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P25.kt\n[P26]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P26.kt\n[P27]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P27.kt\n[P28]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/lists/P28.kt\n\n[P31]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P31.kt\n[P32]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P32.kt\n[P33]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P33.kt\n[P34]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P34.kt\n[P35]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P35.kt\n[P36]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P36.kt\n[P37]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P37.kt\n[P38]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P38.kt\n[P39]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P39.kt\n[P40]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P40.kt\n[P41]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/arithmetic/P41.kt\n\n[P46]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/logic/P46.kt\n[P48]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/logic/P48.kt\n[P49]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/logic/P49.kt\n[P50]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/logic/P50.kt\n\n[P55]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P55.kt\n[P56]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P56.kt\n[P57]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P57.kt\n[P58]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P58.kt\n[P59]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P59.kt\n[P60]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P60.kt\n[P61]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P61.kt\n[P62]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P62.kt\n[P63]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P63.kt\n[P64]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P64.kt\n[P65]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P65.kt\n[P66]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P66.kt\n[P67]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P67.kt\n[P68]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P68.kt\n[P69]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/binarytrees/P69.kt\n\n[P70A]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/multiwaytrees/P70A.kt\n[P70B]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/multiwaytrees/P70B.kt\n[P71]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/multiwaytrees/P71.kt\n[P72]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/multiwaytrees/P72.kt\n[P73]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/multiwaytrees/P73.kt\n\n[P80]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P80.kt\n[P81]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P81.kt\n[P82]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P82.kt\n[P83]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P83.kt\n[P84]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P84.kt\n[P85]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P85.kt\n[P86]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P86.kt\n[P87]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P87.kt\n[P88]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P88.kt\n[P89]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/graphs/P89.kt\n\n[P90]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P90.kt\n[P91]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P91.kt\n[P92]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P92.kt\n[P93]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P93.kt\n[P94]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P94.kt\n[P95]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P95.kt\n[P96]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P96.kt\n[P97]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P97.kt\n[P98]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P98.kt\n[P99]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P99.kt\n[P100]: https://github.com/dkandalov/kotlin-99/blob/master/src/test/kotlin/org/kotlin99/misc/P100.kt\n\n\n[binary-tree]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p67.gif \"Binary tree\"\n[P64-layout]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p64.gif\n[P65-layout]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p65.gif\n[P66-layout]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p66.gif\n[P67-tree]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p67.gif\n[multiway-tree]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p70.gif\n[P73-s-expr]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p73.png\n[undirected-graph]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/graph1.gif\n[directed-graph]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/graph2.gif\n[directed-labeled-graph]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/graph3.gif\n[P83-graph]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p83.gif\n[P84-graph]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p84.gif\n[P92-tree1]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p92a.gif\n[P92-tree2]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p92b.gif\n[P99-crossword]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/images/p99.gif\n[P99a.dat]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/data/p99a.dat\n[P99b.dat]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/data/p99b.dat\n[P99c.dat]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/data/p99c.dat\n[P99d.dat]: https://raw.githubusercontent.com/dkandalov/kotlin-99/master/data/p99d.dat\n\n[Kotlin]: http://kotlinlang.org\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkandalov%2Fkotlin-99","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdkandalov%2Fkotlin-99","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkandalov%2Fkotlin-99/lists"}