Тесты для алгоритмов
От: e.thrash  
Дата: 12.05.21 16:15
Оценка:
Привет

решаю задачи на хакерранке. на простых данных все проходит, на больших наборах данных не проходит.
Как найти что не так?
я правильно понимаю тут нет простого решения, может тестами как-то можно найти косяк в алгоритме?
Re: Тесты для алгоритмов
От: Dziman США http://github.com/Dziman
Дата: 12.05.21 16:24
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>Привет


ET>решаю задачи на хакерранке. на простых данных все проходит, на больших наборах данных не проходит.

ET>Как найти что не так?
ET>я правильно понимаю тут нет простого решения, может тестами как-то можно найти косяк в алгоритме?
Не проходит с неверным результатом или по лимиту времени? Во втором случае надо научится считать сложность алгоритма и находить решения с необходимо сложностью.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Re[2]: Тесты для алгоритмов
От: e.thrash  
Дата: 12.05.21 16:48
Оценка:
Здравствуйте, Dziman, Вы писали:

D>Здравствуйте, e.thrash, Вы писали:


ET>>Привет


ET>>решаю задачи на хакерранке. на простых данных все проходит, на больших наборах данных не проходит.

ET>>Как найти что не так?
ET>>я правильно понимаю тут нет простого решения, может тестами как-то можно найти косяк в алгоритме?
D>Не проходит с неверным результатом или по лимиту времени? Во втором случае надо научится считать сложность алгоритма и находить решения с необходимо сложностью.

по результатам не проходит на большом наборе. а там задача еще не так просто найти на каком шаге ошибке
задача
по таймату все прошли.

зы. а как искать нужный алгоритм для неизвестной для себя задачи?
Re: Тесты для алгоритмов
От: Sharov Россия  
Дата: 12.05.21 18:11
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>решаю задачи на хакерранке. на простых данных все проходит, на больших наборах данных не проходит.

ET>Как найти что не так?
ET>я правильно понимаю тут нет простого решения, может тестами как-то можно найти косяк в алгоритме?

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

ЗЫ: я бы тему в алгоритмы перенес.
Кодом людям нужно помогать!
Re[3]: Тесты для алгоритмов
От: Sharov Россия  
Дата: 12.05.21 18:13
Оценка: 1 (1)
Здравствуйте, e.thrash, Вы писали:

ET>зы. а как искать нужный алгоритм для неизвестной для себя задачи?


Так это знать, т.е. понимать к какому классу задач данная задача относится. Хотя еще важнее знать
основные алгоритмы и уже исходя из этих знаний прикидывать как штурмовать задачу.
Кодом людям нужно помогать!
Re[3]: Тесты для алгоритмов
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.05.21 18:45
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>зы. а как искать нужный алгоритм для неизвестной для себя задачи?


Ну видимо, путем творческого сведения его к решению известных тебе задач.

В данном случае мне на ум приходят такие слова, как "локальный минимум", и "диапазон монотонного возрастания".
Re[3]: Тесты для алгоритмов
От: scf  
Дата: 12.05.21 18:56
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>зы. а как искать нужный алгоритм для неизвестной для себя задачи?


Да, сводить к известным задачам, для которых уже есть решение. У Стивена Скиена есть отличная книжка про алгоритмы, где подробно разбирается такой подход.
Re[4]: Тесты для алгоритмов
От: e.thrash  
Дата: 12.05.21 19:15
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, e.thrash, Вы писали:


ET>>зы. а как искать нужный алгоритм для неизвестной для себя задачи?


Pzz>Ну видимо, путем творческого сведения его к решению известных тебе задач.


Pzz>В данном случае мне на ум приходят такие слова, как "локальный минимум", и "диапазон монотонного возрастания".


у меня 5 кейсов проходят, остальные падают не по таймауту а по логике, но на большом объеме данных это как иголку искать в стоге
Re[5]: Тесты для алгоритмов
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.05.21 19:16
Оценка:
Здравствуйте, e.thrash, Вы писали:

Pzz>>В данном случае мне на ум приходят такие слова, как "локальный минимум", и "диапазон монотонного возрастания".


ET>у меня 5 кейсов проходят, остальные падают не по таймауту а по логике, но на большом объеме данных это как иголку искать в стоге


Тесты, это круто, конечно, но у тебя должно быть какое-то логическое обоснование, почему твой алкогоритм работает. Оно у тебя есть?
Re[6]: Тесты для алгоритмов
От: e.thrash  
Дата: 12.05.21 19:30
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, e.thrash, Вы писали:


Pzz>>>В данном случае мне на ум приходят такие слова, как "локальный минимум", и "диапазон монотонного возрастания".


ET>>у меня 5 кейсов проходят, остальные падают не по таймауту а по логике, но на большом объеме данных это как иголку искать в стоге


Pzz>Тесты, это круто, конечно, но у тебя должно быть какое-то логическое обоснование, почему твой алкогоритм работает. Оно у тебя есть?


потому что конкретно в этой задаче как мне кажется конечное число автоматов

1 рост всегда
2 падение всегда
3 рост — падение
4 падение падение (4 3 2 4 3 2)
5 рост рост (2 3 4 2 3 4)
6 все цифры одинаковы
и дальше вставляем пункт 6 в кейсы 1-5 вначале в середине и в конце

сейчас понял что наверное надо все эти кейсы подготовить и прогнать, а я где-то половину прогнал
Re[7]: Тесты для алгоритмов
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.05.21 19:45
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>сейчас понял что наверное надо все эти кейсы подготовить и прогнать, а я где-то половину прогнал


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

Все это должно делаться за время O(n), потому что локальные минимумы находятся за O(n), а общая длинна повторных проходов не превышает длинну масива, и требовать памяти O(1).

При этом надо быть аккуратным на краях массива, потому что там соседи есть не со всех сторон.
Re[8]: Тесты для алгоритмов
От: e.thrash  
Дата: 12.05.21 19:55
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, e.thrash, Вы писали:


ET>>сейчас понял что наверное надо все эти кейсы подготовить и прогнать, а я где-то половину прогнал


Pzz>Мне навскидку кажется, что надо дать по одной конфетке каждому ребенку, у который находится на локальном минимуме или на плато, а дальше двигаясь от тех, кто на локальном минимуме, давать на одну конфетку больше каждому его соседу по возрастанию.


если я правильно понял задачу то эта логика не будет работать на кейсе
4 3 2 4 3 2

первая двойка локальный минимум, а резульат должен быть 3 2 1 3 2 1


Pzz>Все это должно делаться за время O(n), потому что локальные минимумы находятся за O(n), а общая длинна повторных проходов не превышает длинну масива, и требовать памяти O(1).


а O(n) это разве не один проход массива?
насколько я понял тут за первый проход мы находим минимумы, а на втором уже конфетки раздаем
Re[9]: Тесты для алгоритмов
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.05.21 20:06
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>если я правильно понял задачу то эта логика не будет работать на кейсе

ET>4 3 2 4 3 2

ET>первая двойка локальный минимум, а резульат должен быть 3 2 1 3 2 1


Да, согласен. Ну значит, надо выделять локальные экстремуму (минимуми и максимуми), и двигаться от минимумов к соседним экстримумам или краям массива, двигаясь только по возрастанию.

В принципе, можно и не двигаться никуда вовсе, а только длинну диапазона возрастания/убывания подсчитывать. Это можно сделать в один проход, заодно с поиском экстримумов, но алгоритм более путанный получится; можно погрязнуть в деталях.

Pzz>>Все это должно делаться за время O(n), потому что локальные минимумы находятся за O(n), а общая длинна повторных проходов не превышает длинну масива, и требовать памяти O(1).


ET>а O(n) это разве не один проход массива?

ET>насколько я понял тут за первый проход мы находим минимумы, а на втором уже конфетки раздаем

Два прохода — это тоже O(n). Любое константное количество проходов — это O(n). Вот если бы количество проходов зависило от n, было бы не O(n)
Re[5]: Тесты для алгоритмов
От: Sharov Россия  
Дата: 12.05.21 20:14
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>у меня 5 кейсов проходят, остальные падают не по таймауту а по логике, но на большом объеме данных это как иголку искать в стоге


Они же выдают желаемое число, соотв. можно поставить условный брейкопоинт где-нибудь и посмотреть что происходит.
Кодом людям нужно помогать!
Re[10]: Тесты для алгоритмов
От: e.thrash  
Дата: 12.05.21 20:14
Оценка: :)
Здравствуйте, Pzz, Вы писали:

Pzz>Да, согласен. Ну значит, надо выделять локальные экстремуму (минимуми и максимуми), и двигаться от минимумов к соседним экстримумам или краям массива, двигаясь только по возрастанию.


Pzz>В принципе, можно и не двигаться никуда вовсе, а только длинну диапазона возрастания/убывания подсчитывать. Это можно сделать в один проход, заодно с поиском экстримумов, но алгоритм более путанный получится; можно погрязнуть в деталях.


я именно так и сделал за один проход, но детали и в итоге каждый кейс новый иф.
ок. спасибо за наводку про минимумы

Pzz>Два прохода — это тоже O(n). Любое константное количество проходов — это O(n). Вот если бы количество проходов зависило от n, было бы не O(n)


офигеть, прям открытие.
т.е. массив в 100К элементов если 10 раз прогнать тоже будет O(n)??
Re[11]: Тесты для алгоритмов
От: Pzz Россия https://github.com/alexpevzner
Дата: 12.05.21 20:40
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>офигеть, прям открытие.

ET>т.е. массив в 100К элементов если 10 раз прогнать тоже будет O(n)??

Да. И даже если из 100М элементов.
Re[3]: Тесты для алгоритмов
От: Буравчик Россия  
Дата: 14.05.21 07:32
Оценка: 6 (1)
Здравствуйте, e.thrash, Вы писали:

ET>по результатам не проходит на большом наборе. а там задача еще не так просто найти на каком шаге ошибке

ET>задача

Данная задача аналогична задаче топологической сортировки.
Решается с помощью поиска в глубину (DFS) за O(N).

  Решение
def candies(n, arr):
    count = [None] * len(arr)
    
    # we use Depth-first search
    stack = list(range(len(arr)))
    while len(stack) > 0:
        i = stack[-1]
        # out of array or already known
        if i < 0 or i >= len(arr) or count[i] is not None:
            stack.pop()
        # left unknown value
        elif i >= 1 and arr[i] > arr[i-1] and count[i-1] is None:
            stack.append(i-1)
        # right unknown value
        elif i < len(arr) - 1 and arr[i] > arr[i+1] and count[i+1] is None:
            stack.append(i+1)
        # we know left and right value
        else:
            left = count[i-1] if i >= 1 and arr[i] > arr[i-1] else 0
            right = count[i+1] if i < len(arr) - 1 and arr[i] > arr[i+1] else 0
            count[i] = max(left, right) + 1
            stack.pop()

    return sum(count)
Best regards, Буравчик
Отредактировано 14.05.2021 7:44 Буравчик . Предыдущая версия .
Re[4]: Тесты для алгоритмов
От: maxkar  
Дата: 17.05.21 20:42
Оценка: 12 (1)
Здравствуйте, Буравчик, Вы писали:

Б>Данная задача аналогична задаче топологической сортировки.

Б>Решается с помощью поиска в глубину (DFS) за O(N).

Интересно! А если не секрет, сколько времени ушло на решение с такой ассимптоматикой? Просто по формулировке и ограничению эта задача решается максимум за 15 минут. Там же прямо после прочтения жадный алгоритм напрашивается. Отсортировали по рейтингу а дальше даем конфетки по минимуму (смотрим только на соседних). Это O(N*log(N)), в time limit укладывается с запасом. А на дальнейшие раздумия смысла время тратить нет. Я вижу, что ваше решение тоже пишется прекрасно за 10 минут. Поэтому и интересно, насколько сразу вы его нашли

Мое решение ниже. 12 минут, считая от момента когда я пошел открывать sbt в проекте до accepted, я еще с отладкой сильно локально тормозил (невнимательность в формулах) на олимпиаде со всем готовым минут 10 было бы.

  Решение
import java.io._

object Solution {
  def main(args: Array[String]): Unit = {
    val s = new java.util.Scanner(System.in)
    //val printWriter = System.out
    val printWriter = new PrintWriter(sys.env("OUTPUT_PATH"))

    val iarr = Array.fill(s.nextInt) { s.nextInt }
    val arr = (Integer.MAX_VALUE +: iarr) :+ Integer.MAX_VALUE

    val idx = Array.tabulate(iarr.length) {x => x + 1 }

    val c = new Array[Int](arr.length)

    val poses = idx.sortBy(x => arr(x))
    var res = 0L

    for {
      pos <- poses
    } {
      var w = 1
      if (arr(pos) > arr(pos-1))
        w = Math.max(w, c(pos-1) + 1)
      if (arr(pos) > arr(pos+1))
        w = Math.max(w, c(pos+1) + 1)
      c(pos) = w
      res += w
    }


    //printWriter.println(res)
    printWriter.close()
  }
}
Re: Тесты для алгоритмов
От: maxkar  
Дата: 17.05.21 20:54
Оценка:
Здравствуйте, e.thrash, Вы писали:

ET>Как найти что не так?


Перебором и зависит от алгоритма. Вариантов не слишком много:


Есть еще особые классы задач (на хакерранке пока не видел) на "посчитать floating point с минимальной потерей точности". Там для алгоритмов желательно уметь оценивать потецниальные погрешности математики.

Есть и хардкорные методы "посмотреть на тесты" (не точно, дает только качественную оценку "есть или нет какое-то явление") путем side channel. У нас же есть разные результаты запуска теста — time limit, wrong answer, crash и т.п. Поэтому можно вычислять свои предикаты на входных условиях и падать (или не падать) с соответствующей ошибкой. Но это тактика на случаи, когда заняться совсем нечем.

ET>я правильно понимаю тут нет простого решения, может тестами как-то можно найти косяк в алгоритме?


Вот как раз на хакерранке есть простое решение! Там же можно посмотреть на падающий тест за hackos. Потом скопировать и протестировать алгоритм на этом входе.
Re[5]: Тесты для алгоритмов
От: Буравчик Россия  
Дата: 18.05.21 06:24
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Интересно! А если не секрет, сколько времени ушло на решение с такой ассимптоматикой? Просто по формулировке и ограничению эта задача решается максимум за 15 минут. Там же прямо после прочтения жадный алгоритм напрашивается. Отсортировали по рейтингу а дальше даем конфетки по минимуму (смотрим только на соседних). Это O(N*log(N)), в time limit укладывается с запасом. А на дальнейшие раздумия смысла время тратить нет. Я вижу, что ваше решение тоже пишется прекрасно за 10 минут. Поэтому и интересно, насколько сразу вы его нашли


Трудно оценить время, потому что я не сделал задачу за один подход. В первом подходе я попробовал сделать через сортировку, но ошибся — вместо "дальше даем конфетки по минимуму" индивидуально, я давал одинаковое количество конфет всем ученикам, имеющим одинаковый рейтинг. Отложил. Позже, в фоновом режиме, осознал, что надо давать всем индивидуально. А после этого появился алгоритм с DFS.

Я не использовал IDE (а надо было бы!). В первый раз потратил минут 30, но так и не решил, во второй потратил минут 20. Плюс время на раздумья в фоне — не сильно много, но не знаю как оценить

M>Мое решение ниже. 12 минут, считая от момента когда я пошел открывать sbt в проекте до accepted, я еще с отладкой сильно локально тормозил (невнимательность в формулах) на олимпиаде со всем готовым минут 10 было бы.


Круто, имхо это очень быстро. У меня сильно больше
Best regards, Буравчик
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.