|
| 1 | +"""Kata - Sortable Shapes |
| 2 | +
|
| 3 | +completed at: 2024-04-21 09:39:38 |
| 4 | +by: Jakub Červinka |
| 5 | +
|
| 6 | +Although shapes can be very different by nature, they can be sorted by the size of their area. |
| 7 | +
|
| 8 | +<b style='font-size:16px'>Task:</b> |
| 9 | +
|
| 10 | +<ul> |
| 11 | +
|
| 12 | +<li>Create different shapes that can be part of a sortable list. The sort order is based on the size of their respective areas: |
| 13 | +<ul> |
| 14 | +<li>The area of a <i><b style="color:lightgreen">Square</b></i> is the square of its <i><b>side</b></i></li> |
| 15 | +<li>The area of a <i><b style="color:lightgreen">Rectangle</b></i> is <i><b>width</b></i> multiplied by <i><b>height</b></i></li> |
| 16 | +<li>The area of a <i><b style="color:lightgreen">Triangle</b></i> is <i><b>base</b></i> multiplied by <i><b>height</b></i> divided by 2</li> |
| 17 | +<li>The area of a <i><b style="color:lightgreen">Circle</b></i> is the square of its <i><b>radius</b></i> multiplied by π</li> |
| 18 | +<li>The <i><b>area</b></i> of a <i><b style="color:lightgreen">CustomShape</b></i> is given</li> |
| 19 | +</ul> |
| 20 | +</li> |
| 21 | +<br> |
| 22 | +<li>The default sort order of a list of shapes is ascending on area size:</li> |
| 23 | +
|
| 24 | +```python |
| 25 | +side = 1.1234 |
| 26 | +radius = 1.1234 |
| 27 | +base = 5 |
| 28 | +height = 2 |
| 29 | +
|
| 30 | +# All classes must be subclasses of the Shape class |
| 31 | +
|
| 32 | +shapes: List[Shape] = [Square(side), Circle(radius), Triangle(base, height)] |
| 33 | +shapes.sort() |
| 34 | +``` |
| 35 | +```csharp |
| 36 | +var side = 1.1234D; |
| 37 | +var radius = 1.1234D; |
| 38 | +var base = 5D; |
| 39 | +var height = 2D; |
| 40 | +
|
| 41 | +var shapes = new List<Shape>{ new Square(side), |
| 42 | + new Circle(radius), |
| 43 | + new Triangle(base, height) }; |
| 44 | +shapes.Sort(); |
| 45 | +``` |
| 46 | +```fsharp |
| 47 | +let side = 1.1234 |
| 48 | +let radius = 1.1234 |
| 49 | +let base = 5. |
| 50 | +let height = 2. |
| 51 | +
|
| 52 | +let shapes = [ Square(side); |
| 53 | + Circle(radius), |
| 54 | + Triangle(base, height) ] |
| 55 | +let sorted = Seq.sort shapes |
| 56 | +``` |
| 57 | +```java |
| 58 | +double side = 1.1234; |
| 59 | +double radius = 1.1234; |
| 60 | +double base = 5; |
| 61 | +double height = 2; |
| 62 | +
|
| 63 | +ArrayList<Shape> shapes = new ArrayList<Shape>(); |
| 64 | +shapes.add(new Square(side)); |
| 65 | +shapes.add(new Circle(radius)); |
| 66 | +shapes.add(new Triangle(base, height)); |
| 67 | +
|
| 68 | +Collections.sort(shapes); |
| 69 | +``` |
| 70 | +```haskell |
| 71 | +-- use record syntax |
| 72 | +Square { side :: Double } |
| 73 | +Rectangle { width :: Double, height :: Double } |
| 74 | +Triangle { base :: Double, height :: Double } |
| 75 | +Circle { radius :: Double } |
| 76 | +CustomShape { area :: Double } |
| 77 | +
|
| 78 | +-- your types have to implement Show |
| 79 | +
|
| 80 | +shapes :: [Shape] |
| 81 | +shapes = [Square 1.1234, Circle 1.1234, Triangle 5 2] |
| 82 | +``` |
| 83 | +```javascript |
| 84 | +let side = 1.1234; |
| 85 | +let radius = 1.1234; |
| 86 | +let base = 5; |
| 87 | +let height = 2; |
| 88 | +
|
| 89 | +let shapes = [ new Square(side) |
| 90 | + , new Circle(radius) |
| 91 | + , new Triangle(base, height) |
| 92 | + ]; |
| 93 | +shapes.sort( (a,b) => Number(a>b)-Number(a<b) ); // instead of the default lexicographical sort, natural sort will be used |
| 94 | +``` |
| 95 | +<li>Use the correct π constant for your circle area calculations:</li> |
| 96 | +
|
| 97 | +```python |
| 98 | +math.pi |
| 99 | +``` |
| 100 | +```csharp |
| 101 | +System.Math.PI |
| 102 | +``` |
| 103 | +```fsharp |
| 104 | +System.Math.PI |
| 105 | +``` |
| 106 | +```java |
| 107 | +Math.PI |
| 108 | +``` |
| 109 | +```haskell |
| 110 | +pi from Prelude |
| 111 | +``` |
| 112 | +```javascript |
| 113 | +Math.PI |
| 114 | +``` |
| 115 | +</ul> |
| 116 | +<br> |
| 117 | +""" |
| 118 | + |
| 119 | +from dataclasses import dataclass |
| 120 | +from typing import Union |
| 121 | +from abc import ABC, abstractmethod |
| 122 | +import math |
| 123 | + |
| 124 | +class Shape(ABC): |
| 125 | + @abstractmethod |
| 126 | + def area(self): |
| 127 | + pass |
| 128 | + |
| 129 | + def __lt__(self, other): |
| 130 | + return self.area() < other.area() |
| 131 | + |
| 132 | +@dataclass |
| 133 | +class Triangle(Shape): |
| 134 | + base: float |
| 135 | + height: float |
| 136 | + |
| 137 | + def area(self): |
| 138 | + return 0.5 * self.base * self.height |
| 139 | + |
| 140 | +@dataclass |
| 141 | +class Circle(Shape): |
| 142 | + radius: float |
| 143 | + |
| 144 | + def area(self): |
| 145 | + return math.pi * self.radius ** 2 |
| 146 | + |
| 147 | +@dataclass |
| 148 | +class Rectangle(Shape): |
| 149 | + width: float |
| 150 | + height: float |
| 151 | + |
| 152 | + def area(self): |
| 153 | + return self.width * self.height |
| 154 | + |
| 155 | +@dataclass |
| 156 | +class CustomShape(Shape): |
| 157 | + area_: float |
| 158 | + |
| 159 | + def area(self): |
| 160 | + return self.area_ |
| 161 | + |
| 162 | + |
| 163 | +@dataclass |
| 164 | +class Square(Shape): |
| 165 | + side: float |
| 166 | + |
| 167 | + def area(self): |
| 168 | + return self.side * self.side |
| 169 | + |
0 commit comments