Найдите кодовые войны выбросов четности (Scala)

Недавно я выполнял некоторые задания CodeWars, и у меня возникла проблема с этим.

«Вам дан массив (длина которого будет не менее 3, но может быть очень большим), содержащий целые числа. Массив либо полностью состоит из нечетных целых чисел, либо полностью состоит из четных целых чисел, за исключением одного целого числа N. Напишите метод, который принимает массив в качестве аргумента и возвращает этот «выброс» N».

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

Основная проблема в моем коде, по-видимому, заключается в том, что он игнорирует отрицательные числа, хотя я реализовал метод Math.abs() в scala.

Если у вас есть идея, как обойти это, это более чем приветствуется.

Большое спасибо

object Parity {

  var even = 0
  var odd = 0
  var result = 0

  def findOutlier(integers: List[Int]): Int = {

    for (y <- 0 until integers.length) {
      if (Math.abs(integers(y)) % 2 == 0)
        even += 1
      else
        odd += 1
    }

    if (even == 1) {
      for (y <- 0 until integers.length) {
        if (Math.abs(integers(y)) % 2 == 0)
          result = integers(y)
      }
    } else {
      for (y <- 0 until integers.length) {
        if (Math.abs(integers(y)) % 2 != 0)
          result = integers(y)
      }
    }
    result
  }

person Mateusz Woś    schedule 13.06.2019    source источник
comment
Основная проблема с вашим кодом — использование изменяемых переменных (vars) и тот факт, что вы несколько раз проходите всю коллекцию. Очень неэффективно и совершенно не нужно. (И вы можете попытаться отформатировать код, чтобы сделать его более читаемым.)   -  person jwvh    schedule 13.06.2019
comment
В чем проблема с кодом? Это не удается на определенном входе? Если да - укажите это в вопросе. Или он вылетает или истекает время?   -  person simpadjo    schedule 13.06.2019
comment
Зачем нужно брать абсолютное значение? x%2==0 по-прежнему дает правильные результаты четности для отрицательных чисел. Можете ли вы предоставить нам конкретные тестовые примеры и результаты, в которых ваш код дает сбой?   -  person Ethan    schedule 13.06.2019
comment
да вот тесты   -  person Mateusz Woś    schedule 13.06.2019
comment
Вот образец:   -  person Mateusz Woś    schedule 13.06.2019
comment
import org.scalest._ class ParityTest расширяет FlatSpec с помощью Matchers { val testings = List((List(2, 4, 6, 8, 10, 3), 3), (List(2, 4, 0, 100, 4, 11, 2602, 36), 11), (Список(160, 3, 1719, 19, 11, 13, -21), 160) ) test.foreach { case (input, expect) => sfindOutlier($input) должен sreturn $expected in { Parity.findOutlier(input) должен быть (ожидаемый) } } }   -  person Mateusz Woś    schedule 13.06.2019
comment
И вот результаты: ParityTest findOutlier(List(2, 6, 8, 10, 3)) должен вернуть 3 findOutlier(List(2, 6, 8, 200, 700, 1, 84, 10, 4)) должен вернуть 1 findOutlier(List(17, 6, 8, 10, 6, 12, 24, 36)) должен возвращать 17 findOutlier(List(2, 1, 7, 17, 19, 211, 7)) должен возвращать 2 Test Failed Some (Даже впереди) 7 не равно 2 Трассировка стека завершена за 20 мс findOutlier(List(1, 1, 1, 1, 1, 44, 7, 7, 7, 7, 7, 7, 7, 7)) должен вернуть 44 Test Failed Some(Даже в середине) 7 не был равен 44   -  person Mateusz Woś    schedule 13.06.2019
comment
Есть еще, но, очевидно, я не могу включить их все, так как они слишком длинные.   -  person Mateusz Woś    schedule 13.06.2019
comment
Кроме того, ребята, я новичок в SO, поэтому приветствуются любые советы, как форматировать следующие вопросы, что можно сделать лучше.   -  person Mateusz Woś    schedule 13.06.2019
comment
основная претензия к вашему форматированию - это несовместимый стиль с самим кодом. Как правило, у вас должны быть строки с отступом в зависимости от того, насколько глубоко вы находитесь в структуре. Ознакомьтесь с записями Руководства по стилю Scala, посвященными отступам, вложенности и структуре элементов управления, чтобы узнать, как это лучше форматировать: docs.scala-lang.org/style   -  person Ethan    schedule 13.06.2019
comment
Вы можете нажать кнопку редактирования под вопросом, чтобы немного почистить свой код, и добавить свои тесты к вопросу.   -  person Ethan    schedule 13.06.2019
comment
Подсказка: вы можете работать с первыми тремя числами, если вы ищете нечетное или четное. Вот почему он имеет длину не менее 3   -  person The Archetypal Paul    schedule 14.06.2019


Ответы (1)


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

val l = List(1,3,5,6,7)
println(Parity.findOutlier(l)) //6
println(Parity.findOutlier(l)) //7
println(Parity.findOutlier(l)) //7

Первый запуск правильный. Однако, когда вы запускаете его во второй раз, even, odd и result все еще имеют значения из вашего предыдущего запуска. Если вы определяете их внутри своего метода findOutlier, а не в объекте Parity, тогда ваш код дает правильные результаты.

Кроме того, я настоятельно рекомендую ознакомиться с методами, доступными для Scala List. Вам почти никогда не придется зацикливаться на подобном List, и есть ряд гораздо более кратких решений проблемы. Изменяемые var также являются довольно большим красным флагом в коде Scala, как и избыточные операторы if.

person Ethan    schedule 13.06.2019