Skip to content

Commit

Permalink
Complete up to P69
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhijit Sarkar committed Dec 25, 2024
1 parent 2b96bae commit 005b66e
Show file tree
Hide file tree
Showing 126 changed files with 814 additions and 153 deletions.
8 changes: 4 additions & 4 deletions .github/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ done
if (( no_test == 0 )); then
if [[ -z "$1" ]]; then
./mill __.test
elif ./mill resolve problems["$1"].__.test &>/dev/null; then
./mill problems["$1"].__.test
elif ./mill resolve modules["$1"].__.test &>/dev/null; then
./mill modules["$1"].__.test
else
red='\033[0;31m'
no_color='\033[0m'
Expand All @@ -45,8 +45,8 @@ fi

if (( no_lint == 0 )); then
if [[ -z "${CI}" ]]; then
./mill mill.scalalib.scalafmt.ScalafmtModule/reformatAll problems[_].sources
./mill mill.scalalib.scalafmt.ScalafmtModule/reformatAll modules[_].__.sources
else
./mill mill.scalalib.scalafmt.ScalafmtModule/checkFormatAll problems[_].sources
./mill mill.scalalib.scalafmt.ScalafmtModule/checkFormatAll modules[_].__.sources
fi
fi
5 changes: 4 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ version = "3.8.3"
align.preset = more
maxColumn = 120
runner.dialect = scala3
assumeStandardLibraryStripMargin = true
assumeStandardLibraryStripMargin = true
project.excludePaths = [
"glob:**/bintree/test/src/package.scala",
]
114 changes: 57 additions & 57 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,135 +4,135 @@

## Working with lists

[P01](src/main/scala/list/P01.scala) (*) Find the last element of a list.
[P01](list/P01.scala) (*) Find the last element of a list.

[P02](src/main/scala/list/P02.scala) (*) Find the last but one element of a list.
[P02](list/P02.scala) (*) Find the last but one element of a list.

[P03](src/main/scala/list/P03.scala) (*) Find the Kth element of a list.
[P03](list/P03.scala) (*) Find the Kth element of a list.

[P04](src/main/scala/list/P04.scala) (*) Find the number of elements of a list.
[P04](list/P04.scala) (*) Find the number of elements of a list.

[P05](src/main/scala/list/P05.scala) (*) Reverse a list.
[P05](list/P05.scala) (*) Reverse a list.

[P06](src/main/scala/list/P06.scala) (*) Find out whether a list is a palindrome.
[P06](list/P06.scala) (*) Find out whether a list is a palindrome.

[P07](src/main/scala/list/P07.scala) (**) Flatten a nested list structure.
[P07](list/P07.scala) (**) Flatten a nested list structure.

[P08](src/main/scala/list/P08.scala) (**) Eliminate consecutive duplicates of list elements.
[P08](list/P08.scala) (**) Eliminate consecutive duplicates of list elements.

[P09](src/main/scala/list/P09.scala) (**) Pack consecutive duplicates of list elements into sublists.
[P09](list/P09.scala) (**) Pack consecutive duplicates of list elements into sublists.

[P10](src/main/scala/list/P10.scala) (*) Run-length encoding of a list.
[P10](list/P10.scala) (*) Run-length encoding of a list.

[P11](src/main/scala/list/P11.scala) (*) Modified run-length encoding.
[P11](list/P11.scala) (*) Modified run-length encoding.

[P12](src/main/scala/list/P12.scala) (**) Decode a run-length encoded list.
[P12](list/P12.scala) (**) Decode a run-length encoded list.

[P13](src/main/scala/list/P13.scala) (**) Run-length encoding of a list (direct solution).
[P13](list/P13.scala) (**) Run-length encoding of a list (direct solution).

[P14](src/main/scala/list/P14.scala) (*) Duplicate the elements of a list.
[P14](list/P14.scala) (*) Duplicate the elements of a list.

[P15](src/main/scala/list/P15.scala) (**) Duplicate the elements of a list a given number of times.
[P15](list/P15.scala) (**) Duplicate the elements of a list a given number of times.

[P16](src/main/scala/list/P16.scala) (**) Drop every Nth element from a list.
[P16](list/P16.scala) (**) Drop every Nth element from a list.

[P17](src/main/scala/list/P17.scala) (*) Split a list into two parts.
[P17](list/P17.scala) (*) Split a list into two parts.

[P18](src/main/scala/list/P18.scala) (**) Extract a slice from a list.
[P18](list/P18.scala) (**) Extract a slice from a list.

[P19](src/main/scala/list/P19.scala) (**) Rotate a list N places to the left.
[P19](list/P19.scala) (**) Rotate a list N places to the left.

[P20](src/main/scala/list/P20.scala) (*) Remove the Kth element from a list.
[P20](list/P20.scala) (*) Remove the Kth element from a list.

[P21](src/main/scala/list/P21.scala) (*) Insert an element at a given position into a list.
[P21](list/P21.scala) (*) Insert an element at a given position into a list.

[P22](src/main/scala/list/P22.scala) (*) Create a list containing all integers within a given range.
[P22](list/P22.scala) (*) Create a list containing all integers within a given range.

[P23](src/main/scala/list/P23.scala) (**) Extract a given number of randomly selected elements from a list.
[P23](list/P23.scala) (**) Extract a given number of randomly selected elements from a list.

[P24](src/main/scala/list/P24.scala) (*) Lotto: Draw N different random numbers from the set 1..M.
[P24](list/P24.scala) (*) Lotto: Draw N different random numbers from the set 1..M.

[P25](src/main/scala/list/P25.scala) (*) Generate a random permutation of the elements of a list.
[P25](list/P25.scala) (*) Generate a random permutation of the elements of a list.

[P26](src/main/scala/list/P26.scala) (**) Generate the combinations of K distinct objects chosen from the N elements of a list.
[P26](list/P26.scala) (**) Generate the combinations of K distinct objects chosen from the N elements of a list.

[P27](src/main/scala/list/P27.scala) (**) Group the elements of a set into disjoint subsets.
[P27](list/P27.scala) (**) Group the elements of a set into disjoint subsets.

[P28](src/main/scala/list/P28.scala) (**) Sorting a list of lists according to length of sublists.
[P28](list/P28.scala) (**) Sorting a list of lists according to length of sublists.

## Arithmetic

[P31](src/main/scala/arithmetic/P31.scala) (**) Determine whether a given integer number is prime.
[P31](arithmetic/P31.scala) (**) Determine whether a given integer number is prime.

[P32](src/main/scala/arithmetic/P32.scala) (**) Determine the greatest common divisor of two positive integer numbers.
[P32](arithmetic/P32.scala) (**) Determine the greatest common divisor of two positive integer numbers.

[P33](src/main/scala/arithmetic/P33.scala) (*) Determine whether two positive integer numbers are coprime.
[P33](arithmetic/P33.scala) (*) Determine whether two positive integer numbers are coprime.

[P34](src/main/scala/arithmetic/P34.scala) (**) Calculate Euler’s totient function ϕ(m).
[P34](arithmetic/P34.scala) (**) Calculate Euler’s totient function ϕ(m).

[P35](src/main/scala/arithmetic/P35.scala) (**) Determine the prime factors of a given positive integer.
[P35](arithmetic/P35.scala) (**) Determine the prime factors of a given positive integer.

[P36](src/main/scala/arithmetic/P36.scala) (**) Determine the prime factors of a given positive integer (2).
[P36](arithmetic/P36.scala) (**) Determine the prime factors of a given positive integer (2).

P37 (**) Calculate Euler’s totient function ϕ(m) (improved).

P38 (*) Compare the two methods of calculating Euler’s totient function.

[P39](src/main/scala/arithmetic/P39.scala) (*) A list of prime numbers.
[P39](arithmetic/P39.scala) (*) A list of prime numbers.

[P40](src/main/scala/arithmetic/P40.scala) (**) Goldbach's conjecture.
[P40](arithmetic/P40.scala) (**) Goldbach's conjecture.

[P41](src/main/scala/arithmetic/P41.scala) (**) A list of Goldbach compositions.
[P41](arithmetic/P41.scala) (**) A list of Goldbach compositions.

## Logic and Codes

[P46](src/main/scala/logic/P46.scala) (**) Truth tables for logical expressions.
[P46](logic/P46.scala) (**) Truth tables for logical expressions.

[P47](src/main/scala/logic/P47.scala) (*) Truth tables for logical expressions (2).
[P47](logic/P47.scala) (*) Truth tables for logical expressions (2).

P48 (**) Truth tables for logical expressions (3).

[P49](src/main/scala/logic/P49.scala) (**) Gray code.
[P49](logic/P49.scala) (**) Gray code.

[P50](src/main/scala/logic/P50.scala) (***) Huffman code.
[P50](logic/P50.scala) (***) Huffman code.

## Binary Trees

P54 Omitted; our tree representation will only allow well-formed trees.

[P55](src/main/scala/bintree/P55.scala) (**) Construct completely balanced binary trees.
[P55](bintree/P55.scala) (**) Construct completely balanced binary trees.

[P56](src/main/scala/bintree/P56.scala) (**) Symmetric binary trees.
[P56](bintree/P56.scala) (**) Symmetric binary trees.

[P57](src/main/scala/bintree/P57.scala) (**) Binary search trees (dictionaries).
[P57](bintree/P57.scala) (**) Binary search trees (dictionaries).

[P58](src/main/scala/bintree/P58.scala) (**) Generate-and-test paradigm.
[P58](bintree/P58.scala) (**) Generate-and-test paradigm.

[P59](src/main/scala/bintree/P59.scala) (**) Construct height-balanced binary trees.
[P59](bintree/P59.scala) (**) Construct height-balanced binary trees.

P60 (**) Construct height-balanced binary trees with a given number of nodes.
[P60](bintree/P60.scala) (**) Construct height-balanced binary trees with a given number of nodes.

P61 (*) Count the leaves of a binary tree.
[P61](bintree/P61.scala) (*) Count the leaves of a binary tree.

P61A (*) Collect the leaves of a binary tree in a list.
[P61A](bintree/P61A.scala) (*) Collect the leaves of a binary tree in a list.

P62 (*) Collect the internal nodes of a binary tree in a list.
[P62](bintree/P62.scala) (*) Collect the internal nodes of a binary tree in a list.

P62B (*) Collect the nodes at a given level in a list.
[P62B](bintree/P62B.scala) (*) Collect the nodes at a given level in a list.

P63 (**) Construct a complete binary tree.
[P63](bintree/P63.scala) (**) Construct a complete binary tree.

P64 (**) Layout a binary tree (1).
[P64](bintree/P64.scala) (**) Layout a binary tree (1).

P65 (**) Layout a binary tree (2).
[P65](bintree/P65.scala) (**) Layout a binary tree (2).

P66 (***) Layout a binary tree (3).

P67 (**) A string representation of binary trees.
[P67](bintree/P67.scala) (**) A string representation of binary trees.

P68 (**) Preorder and inorder sequences of binary trees.
[P68](bintree/P68.scala) (**) Preorder and inorder sequences of binary trees.

P69 (**) Dotstring representation of binary trees.
[P69](bintree/P69.scala) (**) Dotstring representation of binary trees.

## Multiway Trees

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
18 changes: 18 additions & 0 deletions bintree/src/DList.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package bintree

final case class DList[A](run: List[A] => List[A]):
// O(1)
infix def ++(xs: DList[A]): DList[A] = DList(xs.run.andThen(run))

// O(1)
def toList: List[A] = run(List.empty[A])

object DList:
// O(1)
def empty[A]: DList[A] = DList(identity)

// O(1)
def singleton[A]: (A => DList[A]) = a => DList(a :: _)

// O(n)
def fromList[A]: (List[A] => DList[A]) = xs => DList(xs ++ _)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 10 additions & 0 deletions bintree/src/P61.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package bintree

import Tree.*

object P61:
extension [A](t: Tree[A])
def leafCount: Int = t match
case Empty => 0
case Node(_, Empty, Empty) => 1
case Node(_, left, right) => left.leafCount + right.leafCount
16 changes: 16 additions & 0 deletions bintree/src/P61A.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package bintree

import Tree.*

// P61A (*) Collect the leaves of a binary tree in a list.
// A leaf is a node with no successors.  Write a method leafList to collect them in a list.
//
// scala> Node('a', Node('b'), Node('c', Node('d'), Node('e'))).leafList
// res0: List[Char] = List(b, d, e)

object P61A:
extension [A](t: Tree[A])
def leafList: List[A] = t match
case Empty => List.empty
case Node(value, Empty, Empty) => List(value)
case Node(_, left, right) => left.leafList ++ right.leafList
17 changes: 17 additions & 0 deletions bintree/src/P62.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package bintree

import Tree.*

// P62 (*) Collect the internal nodes of a binary tree in a list.
// An internal node of a binary tree has either one or two non-empty successors.
// Write a method internalList to collect them in a list.
//
// scala> Node('a', Node('b'), Node('c', Node('d'), Node('e'))).internalList
// res0: List[Char] = List(a, c)

object P62:
extension [A](t: Tree[A])
def internalList: List[A] = t match
case Empty => List.empty
case Node(_, Empty, Empty) => List.empty
case Node(value, left, right) => left.internalList ++ (value :: right.internalList)
18 changes: 18 additions & 0 deletions bintree/src/P62B.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package bintree

import Tree.*

// P62B (*) Collect the nodes at a given level in a list.
// A node of a binary tree is at level N if the path from the root to the node has length N-1.
// The root node is at level 1.
// Write a method atLevel to collect all nodes at a given level in a list.

// scala> Node('a', Node('b'), Node('c', Node('d'), Node('e'))).atLevel(2)
// res0: List[Char] = List(b, c)

object P62B:
extension [A](t: Tree[A])
def atLevel(level: Int, tree: Tree[A] = t, currLevel: Int = 1): List[A] = tree match
case Node(value, _, _) if currLevel == level => List(value)
case Node(_, left, right) => atLevel(level, left, currLevel + 1) ++ atLevel(level, right, currLevel + 1)
case Empty => List.empty
19 changes: 19 additions & 0 deletions bintree/src/P63.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package bintree

import Tree.*

// P63 (**) Construct a complete binary tree.
// A complete binary tree with height H is defined as follows: The levels
// 1,2,3,...,H-1 contain the maximum number of nodes (i.e. 2^(i-1) at the
// level i, note that we start counting the levels from 1 at the root).
// In level H, which may contain less than the maximum possible number of nodes,
// all the nodes are "left-adjusted".
// Write a method completeBinaryTree that takes as parameters the number of
// nodes and the value to put in each node.
//
// scala> Tree.completeBinaryTree(6, "x")
// res0: Node[String] = T(x T(x T(x . .) T(x . .)) T(x T(x . .) .))
object P63:
def completeBinaryTree[A](n: Int, a: A, i: Int = 1): Tree[A] =
if i > n then Empty
else Node(a, completeBinaryTree(n, a, 2 * i), completeBinaryTree(n, a, 2 * i + 1))
32 changes: 32 additions & 0 deletions bintree/src/P64.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package bintree

import Tree.*

// Problem 64: (**) Layout algorithm for displaying trees.
// In this layout strategy, the position of a node v is obtained by the following two rules:
//
// - x(v) is equal to the position of the node v in the inorder sequence
// - y(v) is equal to the depth of the node v in the tree

// Write a function to annotate each node of the tree with a position,
// where (1,1) in the top left corner or the rectangle bounding the drawn tree.
//
// scala> Node('a', Node('b', End, Node('c')), Node('d')).layoutBinaryTree
// res0: PositionedNode[Char] = T[3,1](a T[1,2](b . T[2,3](c . .)) T[4,2](d . .))
object P64:
type Pos = (Int, Int)
type AnnotatedTree[A] = Tree[(A, Pos)]

extension [A](t: Tree[A])
def layoutBinaryTree: AnnotatedTree[A] =
def loop[A](pos: Int, depth: Int, tree: Tree[A]): (AnnotatedTree[A], Int) =
tree match
case Empty => (Empty, 0)
case Node(value, l, r) =>
val (left, lSize) = loop(pos, depth + 1, l)
val pos1 = lSize + pos + 1
val (right, rSize) = loop(pos1, depth + 1, r)
val node = Node((value, (pos1, depth)), left, right)
(node, lSize + rSize + 1)

loop(0, 1, t)._1
Loading

0 comments on commit 005b66e

Please sign in to comment.