Пропустить, как лягушка!

12

Учитывая массив неотрицательных целых чисел, ваша задача - сохранить только некоторые его элементы, как описано ниже.

  • Допустим, массив есть [1, 3, 2, 4, 11, 5, 2, 0, 13, 10, 1].

  • Сначала получите первый элемент массива n. Сохраните первые nэлементы и откажитесь от следующих (откажитесь n+1). Новый массив есть [1, 2, 4, 11, 5, 2, 0, 13, 10, 1].

  • Затем вы берете элемент, следующий за удаленным, и делаете то же самое. Повторно применяя процесс, мы получаем[1, 2, 11, 5, 2, 0, 13, 10, 1]

  • Вы повторяете процесс, пока не достигнете границ массива / в нем не останется элементов. Мы останавливаемся, потому что 11он превышает длину массива.

  • Теперь вы должны вывести результат.

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

Это поэтому выигрывает самый короткий код в байтах!


Тестовые случаи

Вход -> Выход

[1, 2, 3, 4, 5] -> [1, 3, 4]

[6, 1, 0, 5, 6] -> [6, 1, 0, 5, 6]

[1, 3, 2, 4, 11, 5, 2, 0, 13, 10, 1] -> [1, 2, 11, 5, 2, 0, 13, 10, 1]

[2, 2, 2, 2, 2, 2] -> [2, 2]

[1, 2, 3, 1, 2, 3, 1, 2, 3] -> [1, 2]

[3, 1, 2, 4, 0] -> [] *

* Последний контрольный пример включает в себя 0, поэтому я решил опубликовать процесс так, чтобы он был более понятным:

[3, 1, 2, 4, 0] --> [3, 1, 2, 0] --> [1, 2, 0] --> [1, 0] --> [0] --> [] )

( Вдохновленный этим вызовом со стороны Эрик Outgolfer )


источник
Я написал все тестовые примеры полностью вручную, пожалуйста, сообщите мне, если вы считаете, что произошла ошибка!
1
Почему 2удаляется на первом шаге вместо 3?
Утренняя монахиня
@ LeakyNun Моя ошибка. Исправление. Пинг мне, если я сделал какие-либо другие ошибки
Предлагаемый тестовый пример:[1, 2, 3, 1, 2, 3, 1, 2, 3]
Прут
1
Таким образом, чтобы уточнить, когда вы переходите к своему новому « n», вы всегда начинаете с начала массива, чтобы сохранить nэлементы? Не (как я думал на первый взгляд) хранить nэлементы там, где первый элемент - это nто, что вы оцениваете?
Брайан Дж.

Ответы:

1

Pyth, 18 байт

#IgZlQB .(Q=Z@QZ)Q

Попробуй это здесь.

Эрик Outgolfer
источник
Неа .
Утренняя монахиня
@LeakyNun И я подумал, что достаточно протестировал! штопать
Эрик Outgolfer
По крайней мере, проверьте данные тесты.
Утренняя монахиня
@LeakyNun, иногда я думаю, что код дает мне результаты, отличные от того, что он на самом деле делает, хотя ... исправление ... исправлено (о, кстати, я немного ленив, чтобы убрать форматирование из тестовых случаев tbf)
Эрик, Outgolfer,
5

JavaScript (ES6), 45 байт

f=(a,k=0,x=a[k])=>1/x?f(a.splice(x,1)&&a,x):a

Контрольные примеры

Arnauld
источник
4

Haskell , 50 байтов

g.pure.(0:)является анонимной функцией, принимающей и возвращающей список Ints, используйте как (g.pure.(0:))[1,2,3,4,5].

g.pure.(0:)
g(a,_:b:c)=g$splitAt b$a++b:c
g(a,_)=a

Попробуйте онлайн!

Как это устроено

  • Функция gпринимает аргумент кортежа, представляющий разделенный список. aсписок начальных элементов, сохраненных на предыдущем шаге, _элемент, который должен быть отброшен, bследующий элемент, который будет использоваться в качестве длины, и cостальные элементы.
    • Если во второй части кортежа достаточно элементов, чтобы выбрать a b, то выполняется новое разбиение и выполняется gрекурсивный анализ. В противном случае он останавливается aв результате.
  • Анонимная функция g.pure.(0:)запускает все это, вызывая gкортеж ([],0:l), где lнаходится вход, и 0немедленно отбрасывается g.
    • pureздесь используется Applicativeэкземпляр для (двоичных) кортежей, а с типом результата ([Int],[Int])удобно помещать свой аргумент в качестве второго элемента в кортеже с []первым элементом.
Орджан Йохансен
источник
2

Java 8, 68 байт

Эта лямбда принимает изменяемый List<Integer>(поддерживает remove(int), например ArrayList). Выход является мутированным входом. Присвоить Consumer<List<Integer>>.

l->{for(int i=0,f=0;i<l.size();f^=1)i=f>0?l.remove(i)*0+i:l.get(i);}

Попробуйте онлайн

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

Jakob
источник
1

APL (Dyalog Classic) , 32 байта

1∘{n∇⍣(n≤≢w)⊢w←⍵/⍨(n1+⍺⊃⍵)≠⍳≢⍵}

объяснение

1∘{                             } bind 1 as starting left argument (⍺)
                             ⍳≢⍵  generate indexes for right argument (⍵)
                   (n1+⍺⊃⍵)      n is 1+item at position  
              w←⍵/⍨              w is  with item at n removed
   n∇⍣(n≤≢w)⊢                     recurse with n as left and w as right arg if n <= length of w

Попробуйте онлайн!

Гил
источник
1

Haskell, 99 байт (88 без отступа)

f x y
 |y>=l=f x$l-1
 |e>=l=x
 |True=f (take e x ++ drop (1+e) x) e
 where e=x!!y
       l=length x
Джакомо Тейя Пигани
источник
Я мог бы, вероятно, сохранить 1 байт, используя «1 = 1» вместо «True», также, возможно, можно было бы удалить два пробела рядом с «++»
Giacomo Tecya Pigani
1

VI, 31 25 байт

O@0kdd<C-v><C-a>Y<C-v><C-x>gg@a<Esc>"add<C-a>Y<C-x>@a

<C-?>соответствует Control + ?, и <Esc>к Escapeочевидно. Каждый из них считается за 1 байт (см. Мета ).

вход

Входной файл должен содержать 1 целое число в строке + 1 пустую строку в конце, например:

1
2
3
4
5
⁣

Мы можем видеть каждую строку входного файла как элемент массива, например 1 :: 2 :: 3 :: 4 :: 5 :: [], как в некоторых языках (например, caml).

запуск

Вы можете запустить vi с помощью следующей команды и набрать штрих решения по штриху:

vi -u NONE input

Вы также можете использовать этот однострочник:

vi -u NONE -c ':exec "norm O@0kdd\<C-v>\<C-a>Y\<C-v>\<C-x>gg@a\<Esc>\"add\<C-a>Y\<C-x>@a"' -c ":w output" -c ':q' input

Это должно создать файл outputс правильным результатом из входного файла input.

Пояснения

Чтобы представить решение, я сначала представлю 19-байтовое решение, работающее только для массивов без 0. Это решение использует рекурсивный макрос, используемый с небольшими изменениями в конечном решении:

Yqa@0ddYgg@aquggY@a

Объяснение частичного решения

Y                       # yank first line (first integer + line break) to "0 register
 qa                     # start recording a macro ("a register)
   @0                   # jump n lines, where n is the content of the "0 register
     dd                 # delete the current line (n+1th line)
       Y                # yank current line (integer after the previously deleted line)
        gg              # go back to the first line
          @a            # recurse on macro "a"
            q           # finish recording the macro
             u          # cancel modifications done by the execution of the macro
              gg        # go back to the first line
                Y@a     # apply the recorded macro with first parameter equal to the first integer

Хитрость здесь в том, чтобы использовать "0регистр для хранения текущего целого числа (и очень важен разрыв строки). Поэтому команда @0позволяет переходить по nстрокам (вызывать nзначение "0). Если переход превышает количество строк в файле, макрос завершится ошибкой, поэтому программа остановится (за пределами границ массива, как требуется).

Но это решение не работает, если вход содержит 0. Действительно, если "0значение регистра равно 0, то @0будет переходить на одну строку (из-за разрыва строки), 0а не так, как нам понравилось. Поэтому следующая команда ( dd) не будет удалять 0-е целое число, а 1-е (не правильно).

Правильное решение для обработки 0- всегда увеличивать целое число перед его восстановлением и уменьшать его сразу после. Таким образом, @0команда будет переходить по n+1строкам ( nтекущее целое число, которое было увеличено). kКоманда Затем необходимо перейти к линии n(предыдущей строке). Используя этот трюк, в конце входного файла требуется пустая строка, чтобы избежать выпрыгивания за пределы массива (таким образом, завершая программу), поскольку теперь мы всегда переходим n+1строки перед переходом к предыдущей строке.

Объяснение окончательного решения

O                                                       # insert a new line at the beginning of the file, enter insert mode to write the macro content
 @0                                                     # jump n lines                                                       
   k                                                    # go to the previous line
    dd                                                  # delete this line
      <C-v><C-a>                                        # type Control+A (C-v is needed because we are in insert mode) to increment the current integer
                Y                                       # yank the incremented integer
                 <C-v><C-x>                             # decrement the current integer
                           gg                           # go to the first line
                             @a                         # recurse on macro "a"
                               <Esc>                    # exit insert mode : at this step, the first line of the file contains the macro content @0kdd^AY^Xgg@a
                                    "add                # copy @0kdd^AY^Xgg@a line to the register "a and delete the line
                                        <C-a>           # increment the first integer
                                             Y          # yank it (into "0)
                                              <C-x>     # decrement the first integer
                                                   @a   # apply macro in a" (initial @0 will jump n+1 lines, since we incremented the first integer before calling the macro)

Запись содержимого макроса в файл перед его регистрацией позволяет сохранить несколько байтов:

  • избегает записи qa...qи отмены всех изменений после регистрации
  • избегает :let @a="...")

Правки

# 1

  • записать содержимое макроса в первой строке (вместо последней)
  • изменить ввод (1 пустая строка в конце)
  • добавить однострочник для проверки в командной строке
norbjd
источник
0

Pyth, 32 байта

VlQIgNlQBK@QNI!K=QYBIgKlQB.(QK;Q

Попробуйте онлайн

Каран Елангован
источник
Pyth может быть намного более элегантным, чем это :) #VlQ.(Q@QN;Qделает работу в 12 байтов, и я уверен, что это может быть сделано еще лучше
Дейв
Сохраняя подход старой школы Pythonic, вы можете сделать W<Zl=Q+<Q@QZ>Qh@QZ=Z@QZ)Q(25). подход pizzakingme гораздо лучше, хотя.
4
@KaranElangovan не за что извиняться, они просто пытаются вам помочь.
Утренняя монахиня
1
Фиксированный для окончательного теста, он выходит на 15 байт: #VlQ .(Q@QN)%;Q. Обратная связь от игроков в гольф Pyth будет приветствоваться, я все еще учусь!
Дейв
2
Этот подход неверен. Мало того, что он не печатает только результат, но он также не проходит тестовые случаи (по крайней мере, второй последний). Можете ли вы удалить этот ответ / исправить это?
0

C # (.NET Core) , 74 байта

n=>{for(int i=n[0];i<n.Count;){n.RemoveAt(i);i=i<n.Count?n[i]:n.Count+1;}}

Попробуйте онлайн!

Это берет список целых и изменяет его. Я видел некоторые ответы на Java, которые обходят импорт, используя полное имя в определении аргумента Lambda. Если это не разрешено, я могу удалить этот ответ.

jkelm
источник
Если вы имеете в виду упущение типов параметров в лямбда-определениях, это разрешено .
Якоб
@ Якоб, я понимаю это. Я просто чувствую себя немного грязным System.Collections.Generic.List<int>вместо того using System.Collections.Generic, чтобы добавить это к количеству байтов. Но я думаю, это не отличается от использования массива.
jkelm
А ну понятно. Ну, вы можете использовать, usingесли хотите; до тех пор, пока сама лямбда не полагается на утверждение, вам не нужно будет включать его в число байтов. Лично я всегда использую полностью квалифицированные имена в тестовом коде просто для того, чтобы было понятно и легко проверить, какой импорт использует лямбда.
Якоб
0

R , 64 53 байта

f=function(a,i=1,d=a[i]+1)"if"(is.na(d),a,f(a[-d],d))

Рекурсивная функция. Имеет один обязательный ввод, aсписок для пропуска. iявляется индексом количества элементов, через которые необходимо перейти (по умолчанию 1), и dиндексом следующего элемента после удаления требуемого значения, который также является индексом элемента, подлежащего удалению. Возвращает numeric(0)пустой вектор для пустого вывода.

Попробуйте онлайн!

Ungolfed:

f <- function(a, i = 1, d = a[i] + 1) {
  if(is.na(d)) {   # d is NA if and only if a[i] is out of bounds
    a
  } else {
    f( a[-d], d, a[d] + 1 )   # a[-d] is a with the item at index d removed
  }
}
Giuseppe
источник