Skip to content
This repository was archived by the owner on Sep 6, 2018. It is now read-only.

Need help with 7'th last. Lesson 8 #40

Closed
wants to merge 28 commits into from

Conversation

tiger31
Copy link

@tiger31 tiger31 commented Sep 10, 2016

Check out 1st, 2nd, 3rd lessons, 4th in progress


/**
* Тривиальная
*
* Пользователь задает угол в градусах, минутах и секундах (например, 36 градусов 14 минут 35 секунд).
* Вывести значение того же угла в радианах (например, 0.63256).
*/
fun angleInRadian(grad: Int, min: Int, sec: Int): Double = TODO()
fun angleInRadian(grad: Int, min: Int, sec: Int): Double {
var value: Double = grad + min.toDouble()/60 + sec.toDouble()/3600;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Данная переменная может быть объявлена как val
  • Система типов Котлина выведет тип переменной автоматически

@tiger31 tiger31 changed the title lesson 6 is done lesson 7 almost Nov 26, 2016
@tiger31
Copy link
Author

tiger31 commented Nov 26, 2016

Как я понял последня задача седьмого урока решается графом + A*? Или есть другие пути её решения?

@ice-phoenix ice-phoenix added wontfix and removed stale labels Nov 28, 2016
@ice-phoenix
Copy link
Contributor

Вы бы лучше сперва все замечания исправили, перед тем, как решать последнюю задачу седьмого урока. В целом, эту задачу можно решать поиском на неявно заданном графе, да. Вот только что у вас будет эвристикой для A*?

@tiger31
Copy link
Author

tiger31 commented Nov 28, 2016

Исправлениями я займусь, а эвристикой будет что-то вроде f(x)=(количество перестановок до текущего состояния + количество ячеек не на своём месте)

@tiger31
Copy link
Author

tiger31 commented Dec 1, 2016

recheck all

@tiger31
Copy link
Author

tiger31 commented Dec 1, 2016

Изменил эвристику и пуллинг новых вершин, но алгоритм все еще решает только простые задачи с небольшим количество ходов. Что не так в алгоритме?

@tiger31
Copy link
Author

tiger31 commented Dec 1, 2016

Я знаю, что он и не вернет список ходов, но он даже не может найти конечную вершину(решение)

@tiger31 tiger31 changed the title lesson 7 almost Need help with 7'th last. Lesson 8 Dec 1, 2016
Copy link
Contributor

@mglukhikh mglukhikh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я взял на себя смелость поревьюить fifteenGameSolution (и только её), поскольку вы первый из студентов, кто пытается решить эту задачу. Ответ на ваш вопрос в ревью содержится. Дерзайте. Эта задача, по-видимому, самая сложная во всём проекте, так что не огорчайтесь, если не получится решить её быстро. Если у моих коллег есть дополнительные замечания к решению, они напишут их отдельно.

NB: не считайте, пожалуйста, что вначале надо заставить всё работать, а потом решение причёсывать и приводить в порядок стиль. В нормальном случае эти процессы идут параллельно, поскольку заставить работать аккуратно написанное решение проще. Многократно проверено.

listOf(9, 10, 11, 12),
listOf(13, 15, 14, 0)))

fun h(matrix: Matrix<Int>): Int {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Старайтесь не называть так функции. Насколько я понимаю, эта функция возвращает некоторую оценку, насколько далеко данная позиция от исходной. В соответствии с этим придумайте название. Простой идеей может быть, например, evaluation (оценка)


fun h(matrix: Matrix<Int>): Int {
var n = 0
for (i in 0..3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В таких конструкциях лучше ставить фигурные скобки везде, иначе их тяжелее читать. Кроме этого, есть смысл назвать в данном случае переменные цикла row и column -- так понятнее.

var n = 0
for (i in 0..3)
for (j in 0..3)
if (matrix[i,j] != 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вот здесь я не уверен в разумности этой проверки. Интуиция подсказывает, что расстояние пустой ячейки от её оригинальной позиции тоже имеет некоторое значение. Но здесь, конечно, нужна проверка на практике.

for (j in 0..3)
if (matrix[i,j] != 0)
if (matrix[i,j] != i * 4 + j + 1) {
n += abs(matrix[i, j] / 4 - i) + abs(matrix[i, j] % 4 - j - 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Насколько я понимаю, здесь вы пытаетесь посчитать сумму расстояний по горизонтали и вертикали от оригинальной позиции. Если это так, то использованная формула кажется мне неверной.

for (j in 0..i - 1)
if (list[j] > list[i])
N++
} else N += 1 + i / 4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вы уверены, что этот кусок формулы, касающийся пустой клетки, справедлив? (спрашиваю потому, что первую часть этого мини-алгоритма в математических книгах я видел, а вторую -- нет)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кроме этого, это определение чётности позиции стоило бы вынести в отдельную функцию

val solution = if (N % 2 == 0) solution1 else solution2
println("Solution: \r\n $solution")

// Попытка A* + поиск в шиину
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Всё начиная отсюда стоило бы вытащить в отдельную функцию. Кроме этого, A* пока не виден

println("Solution: \r\n $solution")

// Попытка A* + поиск в шиину
data class State(val m: Matrix<Int>, val priority: Int) : Comparable<State> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m --> matrix. Такие короткие имена почти не используются для свойств

queue.add(State(matrix, h(matrix)))

val visited = mutableMapOf(matrix to 0)
while (queue.isNotEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я боюсь, что с подобной идеей алгоритма исправление ошибок (например, не учитывается приоритет, не запоминаются ходы, может быть, я ещё чего-либо не вижу) не поможет. Дело в том, что у игры в 15 всего имеется 16! позиций, чёт / нечёт уменьшает это число вдвое. Такой вот полный поиск в ширину будет вынужден обойти весьма существенную часть от этого количества, а оно измеряется триллионами. То есть шансов получить решение за обозримое время таким способом вроде как не имеется (IMHO).

Что можно рекомендовать:

  • в данной задаче DFS должен быть лучше BFS, хотя бы за счёт того, что можно избежать постоянного копирования матриц
  • независимо от того, используете вы DFS или BFS, поиск необходимо ограничивать, то есть не искать дальше, чем на какое-то ограниченное количество ходов вперёд; вы при этом не достигнете завершающей позиции, но сможете найти позицию с лучшей оценкой и ход, ведущий в неё; найденный ход следует запомнить в списке, сделать и повторить всю процедуру поиска уже с новой позиции для поиска лучшего второго хода; процедура повторяется до тех пор, пока сделанный ход не приведёт вас в solution.

@ice-phoenix
Copy link
Contributor

Очень много неисправленных ранее замечаний. Давайте вы сперва исправите их все (да, скучно, да, нудно, да, не приближает вас к получению зачета напрямую), а потом уже будем смотреть, что вы наделали дальше.

@kotlin-polytech-bot
Copy link

author

tiger31 [[email protected]]

owner

tiger31 []

Copy link
Contributor

@ice-phoenix ice-phoenix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Чего-то посмотрел и пописал в задачке про 15

n += abs(matrix[i, j] / 4 - i) + abs(matrix[i, j] % 4 - j - 1)
class State(val matrix: Matrix<Int>, val moved: Int?) {

object companion {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще-то, companion object задается несколько не так


// Все задачи в этом файле требуют наличия реализации интерфейса "Матрица" в Matrix.kt

//Extensions of Cell data class
// По-нормальноу это должен быть статический параметр класса, но са класс Cell я менять не могу
val NOT_EXISTS = Cell(-1, -1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вы не поверите, но можно сделать extension value у класса =)

val NOT_EXISTS = Cell(-1, -1)

fun Cell.near(other: Cell): Boolean {
if (this == other) throw IllegalArgumentException("Cells are the same")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно в виде one-liner


fun <E> Matrix<E>.subMatrix(height: Int, width: Int, heightShift: Int, widthShift: Int): Matrix<E> {
if (this.height < height + heightShift || this.width < width + widthShift)
throw IllegalArgumentException("Sub Matrix is out of bounds of original")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Раз уж мы все проверяем, то я бы проверил границы и в другую сторону

fun <E> Matrix<E>.contains(cell: Cell): Boolean = this.contains(cell.row, cell.column)

fun <E> Matrix<E>.subMatrix(height: Int, width: Int, heightShift: Int, widthShift: Int): Matrix<E> {
if (this.height < height + heightShift || this.width < width + widthShift)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут у вас клэш по именам, лучше его избегать --- я бы переименовал аргументы функции как-нибудь по другому

}
}
}
state.matrix.swap(zero, move)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кажется, что во всем этом деле (см. выше) вы слишком много раз копируете матрицу там, где можно было бы обойтись и без этого

var solved = false

if (state.matrix == State.companion.SOLUTION)
return listOf()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вы уж разберитесь в коде, либо через ==, либо через solved

println("$count searches are complete, pathes = $finished, current depth = $limit, visited = ${visited.size}")
limit += 2
visited.clear()
moves.clear()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем перезапускать поиск с нуля?


fun fifteenGameSolution(matrix: Matrix<Int>): List<Int> {

State.companion.START = matrix
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

По хорошему, вам надо завести класс Solver, который будет заниматься хранением всей нужной вам для решения одного экземпляра задачи информации, а не жонглировать статическими переменными налево и направо

} else {

if (!visited.contains(state.matrix.copyN())) {
if (state.estimate() + path + 1 > limit) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем вы вообще ограничиваете глубину поиска, чтобы потом (если не получилось) перезапускать все с нуля и снова проходить все те же самые позиции?

@ice-phoenix
Copy link
Contributor

recheck all

@ice-phoenix
Copy link
Contributor

Несмотря на большое количество замечаний и не очень чистый код, по совокупной статистике решения задач и результатам тестирования у вас "Отлично"! Так держать!

@ice-phoenix
Copy link
Contributor

PS: Но тесты все же лучше, чтобы завершались =)

@kotlin-polytech-bot
Copy link

author

tiger31 [[email protected]]

owner

tiger31 []

@tiger31
Copy link
Author

tiger31 commented Dec 18, 2016

Я сейчас несколько исправлений еще добавляю. Очень хотелось бы увидеть правильное решение последней задачи в седьмом, потому что пока это единственная задача, которая меня "сломала" :)

@kotlin-polytech-bot
Copy link

author

tiger31 [[email protected]]

lesson7.task2

Author: tiger31 [[email protected]]

Owner: tiger31 []

Total: 14 / 15

Example: 2 / 2
Easy: 1 / 1
Normal: 5 / 5
Hard: 6 / 6
Impossible: 0 / 1

Succeeded:

  • [Example] lesson7.task2/plus
  • [Example] lesson7.task2/transpose
  • [Hard] lesson7.task2/generateSpiral
  • [Hard] lesson7.task2/generateRectangles
  • [Hard] lesson7.task2/generateSnake
  • [Hard] lesson7.task2/isLatinSquare
  • [Normal] lesson7.task2/sumNeighbours
  • [Normal] lesson7.task2/findHoles
  • [Normal] lesson7.task2/sumSubMatrix
  • [Hard] lesson7.task2/canOpenLock
  • [Easy] lesson7.task2/unaryMinus
  • [Normal] lesson7.task2/times
  • [Hard] lesson7.task2/fifteenGameMoves
  • [Normal] lesson7.task2/rotate

Seed: 4571634249296578062

lesson8.task1

Author: tiger31 [[email protected]]

Owner: tiger31 []

Total: 4 / 13

Example: 1 / 1
Normal: 3 / 7
Hard: 0 / 3
Impossible: 0 / 2

Succeeded:

  • [Example] lesson8.task1/alignFile
  • [Normal] lesson8.task1/countSubstrings
  • [Normal] lesson8.task1/sibilants
  • [Normal] lesson8.task1/top20Words

Failed:

  • [Normal] lesson8.task1/centerFile
    • Expected:
      АЙАВ -- АЭВЖБВХЧБЗБАЙ / бАбОбвваб -- бббччбяб бббччбяб  вабтбажбббю / ВБВАЫУВЛВБАЬУВЮБ: ебвавшдббаоу баятбббвюввшатюарозб; бэфбб / ювХввьбатвЬавбйСбЙрЦ: АЭВЖБВХЧБЗБАЙ --- ВААЭВШББЕАРББЪАВЗВЧГ -- ййщдёв ВБВАЫУВЛВБАЬУВЮБ - ЙЙЩДЁВ - ацпавбжъааутб - ебвавшдббаоу; ЙБАШББЛНЙА / ЩИбЕёбвбаХабб - лгвббвжббебмыарбааб  ебвАвШдббаОу --- двавввачвямбрвббацаб: ввввжбйббвд --- РБББВЕВВБВЧБВТДВЗ - БАЯТБББВЮВВШАТЮАРОЗБ / ДВАВВВАЧВЯМБРВББАЦАБ; быбб  ЩИбЕёбвбаХабб  вЬббаЕбвИабцбИвЕвм / ббХбб - ЙбАШбблНЙа ДвавввачвЯмбРвббаЦаб, аббе, вЬббаЕбвИабцбИвЕвм / ШвббТабщёва --
      
    • Actual:
      АЙАВ -- АЭВЖБВХЧБЗБАЙ / бАбОбвваб -- бббччбяб бббччбяб  вабтбажбббю / ВБВАЫУВЛВБАЬУВЮБ: ебвавшдббаоу баятбббвюввшатюарозб; бэфбб / ювХввьбатвЬавбйСбЙрЦ: АЭВЖБВХЧБЗБАЙ --- ВААЭВШББЕАРББЪАВЗВЧГ -- ййщдёв ВБВАЫУВЛВБАЬУВЮБ - ЙЙЩДЁВ - ацпавбжъааутб - ебвавшдббаоу; ЙБАШББЛНЙА / ЩИбЕёбвбаХабб - лгвббвжббебмыарбааб  ебвАвШдббаОу --- двавввачвямбрвббацаб: ввввжбйббвд --- РБББВЕВВБВЧБВТДВЗ - БАЯТБББВЮВВШАТЮАРОЗБ / ДВАВВВАЧВЯМБРВББАЦАБ; быбб  ЩИбЕёбвбаХабб  вЬббаЕбвИабцбИвЕвм / ббХбб - ЙбАШбблНЙа ДвавввачвЯмбРвббаЦаб, аббе, вЬббаЕбвИабцбИвЕвм / ШвббТабщёва --
      
      
    • Inputs:
      • text ->
        АЙАВ -- АЭВЖБВХЧБЗБАЙ / бАбОбвваб -- бббччбяб бббччбяб  вабтбажбббю / ВБВАЫУВЛВБАЬУВЮБ: ебвавшдббаоу баятбббвюввшатюарозб; бэфбб / ювХввьбатвЬавбйСбЙрЦ: АЭВЖБВХЧБЗБАЙ --- ВААЭВШББЕАРББЪАВЗВЧГ -- ййщдёв ВБВАЫУВЛВБАЬУВЮБ - ЙЙЩДЁВ - ацпавбжъааутб - ебвавшдббаоу; ЙБАШББЛНЙА / ЩИбЕёбвбаХабб - лгвббвжббебмыарбааб  ебвАвШдббаОу --- двавввачвямбрвббацаб: ввввжбйббвд --- РБББВЕВВБВЧБВТДВЗ - БАЯТБББВЮВВШАТЮАРОЗБ / ДВАВВВАЧВЯМБРВББАЦАБ; быбб  ЩИбЕёбвбаХабб  вЬббаЕбвИабцбИвЕвм / ббХбб - ЙбАШбблНЙа ДвавввачвЯмбРвббаЦаб, аббе, вЬббаЕбвИабцбИвЕвм / ШвббТабщёва -- 
        
    • Exception: null
  • [Hard] lesson8.task1/alignFileByWidth
    • Expected:
      ЬбжбблфявЬ ЬбжбблфявЬ -
      
    • Actual:
      ЬбжбблфявЬ ЬбжбблфявЬ -
      
      
    • Inputs:
      • text ->
        ЬбжбблфявЬ ЬбжбблфявЬ -
        
    • Exception: null

Seed: 4571634249296578062

owner

tiger31 []

total

Author: tiger31 [[email protected]]

Owner: tiger31 []

Total: 18 / 28

Example: 3 / 3
Easy: 1 / 1
Normal: 8 / 12
Hard: 6 / 9
Impossible: 0 / 3

@mglukhikh mglukhikh closed this Jul 26, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants