# Учебная практика. Среда 07.07.2021. Чачко Натан Леонидович
## 1. Задача [Pascal's Triangle](https://www.codewars.com/kata/5226eb40316b56c8d500030f), сложность 6 kyu
In mathematics, Pascal's triangle is a triangular array of the binomial coefficients expressed with formula
$({n \atop k}) = \frac {n!} {k!(n-k)!}$,
where `n` denotes a row of the triangle, and `k` is a position of a term in the row.

Write a function that, given a depth `n`, returns `n` top rows of Pascal's Triangle flattened into a one-dimensional list/array.
### Example:
```
n = 1: [1]
n = 2: [1, 1, 1]
n = 4: [1, 1, 1, 1, 2, 1, 1, 3, 3, 1]
```
В математике треугольник Паскаля представляет собой треугольный массив биномиальных коэффициентов, выраженных формулой
$({n \atop k}) = \frac {n!} {k!(n-k)!}$,
где `n` обозначает строку треугольника, а `k` - позицию числа в строке.

Напишите функцию, которая, учитывая глубину `n`, возвращает `n` верхних строк треугольника Паскаля, сведенного в одномерный список/массив.
### Пример:
```
n = 1: [1]
n = 2: [1, 1, 1]
n = 4: [1, 1, 1, 1, 2, 1, 1, 3, 3, 1]
```
### Решение на языке **С++**.
```c=
#include <vector>
using namespace std;
std::vector<long long> pascalsTriangle(int n){
vector<long long> res;
for (int i = 0; i < n; i++){
long long num = 1;
for (int j = 0; j <= i; j++){
res.push_back(num);
num = (num * (i - j)) / (j + 1);
}
}
return res;
}
```
### Решение на языке **Java**.
```java=
import java.util.*;
public class PascalsTriangle {
public static long[] generate(int n) {
final List<Long> res = new ArrayList<Long>();
for (int i = 0; i < n; i++) {
long num = 1;
for (int j = 0; j <= i; j++) {
res.add(num);
num = (num * (i - j)) / (j + 1);
}
}
return res.stream().mapToLong(i -> i).toArray();
}
}
```
В данном случае `i` -- это номер строки треугольника Паскаля, а `j` -- номер элемента строки. И расчет идет по циклу, используя [известную формулу](https://ru.wikipedia.org/wiki/%D0%91%D0%B8%D0%BD%D0%BE%D0%BC%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D1%8D%D1%84%D1%84%D0%B8%D1%86%D0%B8%D0%B5%D0%BD%D1%82) для рассчтеа биномиального коэффициента $C(n, k+1) = C(n, k) {(n-k) \over (k+1)}$
## 2. Задача [Casino chips](https://www.codewars.com/kata/5e0b72d2d772160011133654), сложность 6 kyu
Each day you take exactly two chips of different colors and head to the casino. You can choose any color, but you are not allowed to take two chips of the same color in a day.
You will be given an array representing the number of chips of each color and your task is to return the maximum number of days you can pick the chips. Each day you need to take exactly two chips.
```
solve([1,1,1]) // = 1, because after you pick on day one, there will be only one chip left
solve([1,2,1]) // = 2, you can pick twice; you pick two chips on day one then on day two
solve([4,1,1]) // = 2
```
Каждый день вы берете ровно две фишки разного цвета и отправляетесь в казино. Вы можете выбрать любой цвет, но вы не можете брать две фишки одного цвета в день.
Вам будет предоставлен массив, представляющий количество фишек каждого цвета, и ваша задача - вернуть максимальное количество дней, в течение которых вы можете выбирать фишки. Каждый день нужно брать ровно две фишки.
### Решение на языке **С++**.
```c=
int solve(std::vector<int> v){
sort (v.begin(), v.end());
if (v[0] + v[1] <= v[2]) return v[0] + v[1];
return (v[0] + v[1] + v[2]) / 2;
}
```
### Решение на языке **Java**.
```java=
import java.util.Arrays;
class Solution{
public static int solve(int [] arr){
Arrays.sort(arr);
if((arr[0] + arr[1]) <= arr[2]) return (arr[0] + arr[1]);
return ((arr[0] + arr[1]) + arr[2]) / 2;
}
}
```

## 3. Задача [Double Cola](https://www.codewars.com/kata/551dd1f424b7a4cdae0001f0), сложность 5 kyu
Sheldon, Leonard, Penny, Rajesh and Howard are in the queue for a "Double Cola" drink vending machine; there are no other people in the queue. The first one in the queue (Sheldon) buys a can, drinks it and doubles! The resulting two Sheldons go to the end of the queue. Then the next in the queue (Leonard) buys a can, drinks it and gets to the end of the queue as two Leonards, and so on.
For example, Penny drinks the third can of cola and the queue will look like this:
`Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard, Penny, Penny`
Write a program that will return the name of the person who will drink the `n`-th cola.
**Input:**
The input data consist of an array which contains at least 1 name, and single integer n which may go as high as the biggest number your language of choice supports (if there's such limit, of course).
**Output / Examples:**
Return the single line — the name of the person who drinks the `n`-th can of cola. The cans are numbered starting from 1.
```
let names = &vec![Name::Sheldon, Name::Leonard, Name::Penny, Name::Rajesh, Name::Howard];
assert_eq!(who_is_next(names, 1), Name::Sheldon);
assert_eq!(who_is_next(names, 6), Name::Sheldon);
assert_eq!(who_is_next(names, 52), Name::Penny);
assert_eq!(who_is_next(names, 7230702951), Name::Leonard);
```
Шелдон, Леонард, Пенни, Раджеш и Ховард стоят в очереди за автоматом по продаже напитков «Двойная кола»; в очереди нет других людей. Первый в очереди (Шелдон) покупает банку, выпивает и удваивается! Получившиеся два Шелдона уходят в конец очереди. Затем следующий в очереди (Леонард) покупает банку, выпивает ее и добирается до конца очереди как два Леонарда, и так далее.
Например, Пенни выпьет третью банку колы, и очередь будет выглядеть так:
`Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard, Penny, Penny`
Напишите программу, которая вернет имя человека, который выпьет n-ю колу.
**Входные данные:**
Входные данные состоят из массива, который содержит как минимум 1 имя и одно целое число `n`, которое может достигать максимального значения, поддерживаемого вашим языком по выбору (если, конечно, есть такой предел).
**Вывод / примеры:**
Верните единственную строку - имя человека, выпившего `n`-ю банку колы. Нумерация банок начинается с 1.
### Решение на языке **С++**.
```c=
public class Line {
public static String WhoIsNext(String[] names, int n){
while (n > 5){
n = (n - 4) / 2; //по условию человек "раздваивается",
} //и для компенсации этого нужно поделить на 2
return names[n-1];
}
}
```
### Решение на языке **Java**.
```java=
public class Line {
public static String WhoIsNext(String[] names, int n){
while (n > 5){
n = (n - 4) / 2;
}
return names[n-1];
}
}
```
## 4. Задача [Sorting on planet Twisted-3-7](https://www.codewars.com/kata/58068479c27998b11900056e), сложность 6 kyu
There is a planet... in a galaxy far far away. It is exactly like our planet, but it has one difference: #The values of the digits 3 and 7 are twisted. Our 3 means 7 on the planet Twisted-3-7. And 7 means 3.
Your task is to create a method, that can sort an array the way it would be sorted on Twisted-3-7.
7 Examples from a friend from Twisted-3-7:
```
[1,2,3,4,5,6,7,8,9] -> [1,2,7,4,5,6,3,8,9]
[12,13,14] -> [12,14,13]
[9,2,4,7,3] -> [2,7,4,3,9]
```
There is no need for a precheck. The array will always be not null and will always contain at least one number.
Есть планета ... в далекой галактике. Он в точности похож на нашу планету, но с одним отличием:
Значения цифр 3 и 7 поменяны местами. Наша 3 означает 7 на планете Twisted-3-7. А 7 означает 3.
Ваша задача - создать метод, который мог бы отсортировать массив так, как он был бы отсортирован на Twisted-3-7.
7 примеров от друга из Twisted-3-7:
```
[1,2,3,4,5,6,7,8,9] -> [1,2,7,4,5,6,3,8,9]
[12,13,14] -> [12,14,13]
[9,2,4,7,3] -> [2,7,4,3,9]
```
Нет необходимости в предварительной проверке. Массив всегда не будет нулевым и всегда будет содержать хотя бы одно число.
### Решение на языке **С++**.
```c=
int strange_sub(int n) {
std::string tmp = std::to_string(n);
for (char &ch : tmp) {
if (ch == '7') ch = '3';
else if (ch == '3') ch = '7';
}
return std::stoi(tmp);
}
std::vector<int> sortTwisted37 (const std::vector<int> &numbers) {
std::vector<int> tmp(numbers.size());
std::transform(numbers.cbegin(), numbers.cend(), tmp.begin(), strange_sub);
std::sort(tmp.begin(), tmp.end());
std::transform(tmp.cbegin(), tmp.cend(), tmp.begin(), strange_sub);
return tmp;
}
```
### Решение на языке **Java**.
```java=
import java.util.Arrays;
public class Kata {
private static Integer swap(Integer i) {
return Integer.valueOf(i.toString()
.replace("7", "*")
.replace("3", "7")
.replace("*", "3")
);
}
public static Integer[] sortTwisted37(Integer[] array) {
return Arrays.stream(array)
.map(Kata::swap)
.sorted(Integer::compare)
.map(Kata::swap)
.toArray(Integer[]::new);
}
}
```
Была создана функция, которая меняет местами 3 и 7 во всех числах строки.
**Алгоритм решения:** делаем замену 3 и 7 ---> сортируем числа по порядку ---> делаем замену 3 и 7 снова ---> выводим ответ.
## 5. Задача [Cartesian neighbors distance](https://www.codewars.com/kata/59cd39a7a25c8c117d00020c), сложность 6 kyu
In previous kata we have been searching for all the neighboring points in a Cartesian coordinate system. As we know each point in a coordinate system has eight neighboring points when we search it by range equal to 1, but now we will change range by third argument of our function (range is always greater than zero). For example if range `= 2`, count of neighboring points `= 24`. In this kata grid step is the same (`= 1`).
It is necessary to write a function that returns array of `unique` distances between given point and all neighboring points. You can round up the distance to 10 decimal places (as shown in the example). Distances inside list don't have to been sorted (any order is valid).
### For Example:
```
cartesianNeighborsDistance(3, 2, 1) -> {1.4142135624, 1.0}
cartesianNeighborsDistance(0, 0, 2) -> {1.0, 1.4142135624, 2.0, 2.2360679775, 2.8284271247}
```
В предыдущих ката мы искали все соседние точки в декартовой системе координат. Как мы знаем, каждая точка в системе координат имеет восемь соседних точек, когда мы ищем ее по диапазону, равному 1, но теперь мы изменим диапазон с помощью третьего аргумента нашей функции (диапазон всегда больше нуля). Например, если диапазон `= 2`, количество соседних точек `= 24`. В этом сетке ката шаг такой же (`= 1)`.
Необходимо написать функцию, возвращающую массив «уникальных» расстояний между заданной точкой и всеми соседними точками. Вы можете округлить расстояние до 10 десятичных знаков (как показано в примере). Расстояния внутри списка сортировать не нужно (допустим любой порядок).
Нет необходимости в предварительной проверке. Массив всегда не будет нулевым и всегда будет содержать хотя бы одно число.
### Например:
```
cartesianNeighborsDistance(3, 2, 1) -> {1.4142135624, 1.0}
cartesianNeighborsDistance(0, 0, 2) -> {1.0, 1.4142135624, 2.0, 2.2360679775, 2.8284271247}
```
### Решение на языке **С++**.
```c=
#include <vector>
vector<double> cartesianNeighborsDistance(int x, int y, int range) {
std::set<double> distances;
for (auto i = 1; i <= range; i ++){
for (auto j = 0; j <= i; j ++){ distances.insert(sqrt(i * i + j * j));
}
}
return {cbegin(distances), cend(distances)};
}
```
### Решение на языке **Java**.
```java=
import static java.lang.Math.sqrt;
import java.util.*;
public class Kata {
public static double[] cartesianNeighborsDistance(int x, int y, int range){
SortedSet<Double> distances = new TreeSet<>();
for(int i = 1; i <= range; i++) {
for(int j = 0; j <= i; j++) {
distances.add(sqrt(i * i + j * j));
}
}
return distances.stream().mapToDouble(Double::doubleValue).toArray();
}
}
```