1. Ruby / Говнокод #22351

    −99

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    def rotate_array(arr, i)
      i = i%arr.size
      return arr if i == 0
    
      left = arr[0...i].reverse
      right = arr[i..arr.size].reverse
      arr = left + right
    
      arr.reverse
    end

    https://knaidu.gitbooks.io/problem-solving/content/arrays/rotate_array.html
    вообще не понял зачем reverse

    http://ideone.com/9fVLsq

    Запостил: pushkoff, 17 Февраля 2017

    Комментарии (8) RSS

    • судя по документации ruby-2.2 (https://ruby-doc.org/core-2.2.0/Array.html#method-i-reverse) reverse работает так
      static VALUE
      rb_ary_reverse_m(VALUE ary)
      {
          long len = RARRAY_LEN(ary);
          VALUE dup = rb_ary_new2(len);
      
          if (len > 0) {
              const VALUE *p1 = RARRAY_CONST_PTR(ary);
              VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;
              do *p2-- = *p1++; while (--len > 0);
          }
          ARY_SET_LEN(dup, RARRAY_LEN(ary));
          return dup;
      }
      Ответить
    • Там же написано - это чтоб inplace, т.е. без затрат памяти. Правда автор видимо где-то на собеседовании слышал про разворот и inplace, но что это значит не понял и поэтому написал как обычно, просто reverse добавил.
      Ответить
    • > Space: No additional space used
      > arr = left + right

      Возможно, я что-то не понимаю в ваших рубях, но на первый взгляд тут противоречие.
      Ответить
    • Кстати, тут ещё и типичная проблема алиасинга имеется.
      Автор кода вроде как хочет поиграть в иммутабельность и вернуть новый массив, но его мега оптимизация с if i == 0 ломает всю семантику: вернётся не новый массив, а ссылка на входной аргумент. Последующие модификации результата rotate могут менять (или не менять) оригинальный массив в зависимости от того, чему равнялось i. Удачной отладки.
      Ответить
    • > зачем reverse
      1 2 3 4 5 6 7 // надо повернуть вправо на 3
      1 2 3 4|5 6 7 // переворачиваем половинки
      4 3 2 1|7 6 5 // теперь переворачиваем весь массив
      5 6 7 1 2 3 4 // и получаем то что надо :)
      Ответить
      • Про что я и написал. Автор явно слышал про это решение - нагуглил или на собеседовании сказали, но как типичный рубишник понял его не смог, поэтому в тексте написал правильно, а в коде - говно. Ну либо он руби второй раз в жизни видел, но это кажется маловероятным, там же по ссылке еще десятки этих задач.
        Ответить
    • http://govnokod.ru/22346#comment371703
      Ответить
    • какой-то напёрсточник код писал
      Ответить

    Добавить комментарий