Сделать одну последовательность


12

Последовательность целых чисел является одной последовательностью, если разница между любыми двумя последовательными числами в этой последовательности равна -1 или 1, а ее первый элемент равен 0.

Точнее: a1, a2, ..., an является однопоследовательностью, если:

For any k (1 ≤  k < n): |a[k] - a[k+1]|=1, 
a[1]=0

вход

  • n - количество элементов в последовательности
  • s - сумма элементов в последовательности

Выход

  • набор из одной последовательности / list / array / etc длины nс суммой элементов s, если это возможно
  • пустой набор / список / массив / и т.д., если это невозможно

Примеры

Для ввода 8 4, вывода может быть [0 1 2 1 0 -1 0 1]или [0 -1 0 1 0 1 2 1]. Могут быть и другие возможности.

Для ввода 3 5вывод пустой [], так как это невозможно сделать.

правила

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


Кстати, у меня есть доказательство того, что все числа, представимые в виде одной последовательности длины l, являются всеми числами между ними (l-1)*l/2и -(l-1)*l/2имеют ту же четность, что и (l-1)*l/2.
гордый haskeller

это можно использовать для создания эффективного алгоритма (O (n)) для создания желаемой последовательности
гордый haskeller

Ответы:


7

CJam, 56 47 44 34 байта

Здесь много возможностей для улучшения, но здесь идет первая попытка:

L0aa{{[~_(]_)2++}%}l~:N;(*{:+N=}=p

Кредиты Деннису за эффективный способ выполнения роли { ... }%.

Печатает представление массива, если это возможно, в противном случае ""

Попробуйте онлайн здесь


Я в замешательстве: {}%часть вашего кода не похожа на мою (это просто код @ PeterTaylor, заменяющий точки подчеркиванием). Если я добавлю что-нибудь в твой код, это {}=оператор ...
Деннис

Первоначально у меня было, _{_W=)+}%\{_W=(+}%+что сначала делали две копии, добавив 1 к первой, вычитая 1 из других. Ваш пример заставил меня понять, как сделать это в одном { ... }%блоке. Что касается { ... }=, я уже уменьшил это так сильно в моих экспериментах, хотя еще не опубликовал.
Оптимизатор

Я понимаю из вопроса, что с учетом входных данных 3 5вывод должен быть, []а не""
Питер Тейлор

1
@PeterTaylor «пустой набор / список / массив / и т. Д., Если это невозможно» - поэтому я думаю, что мне просто нужно прояснить это ...
Optimizer

Плюс []pв CJam просто выводится "". Так что, как язык представляет пустые массивы.
Оптимизатор

6

JavaScript (E6) 79 82

F=(n,t,
  d=n+n*~-n/4-t/2,
  l=1,
  q=[for(x of Array(n))d<n--?++l:(d+=~n,--l)]
)=>d?[]:q

Не нужно грубой силы или перечисления всех кортежей.

Посмотрите последовательность длины n как n -1 шагов, каждый шаг - увеличение или уменьшение.
Обратите внимание, что вы можете поменять местами только приращение, сумма изменяется на 2, поэтому для любой заданной длины сумма всегда четная или всегда нечетная.
При всех приращениях последовательность равна 0, 1, 2, 3, ..., n-1, и мы знаем, что сумма равна (n-1) * n / 2. При
изменении последнего шага сумма изменяется на 2, поэтому последний шаг весит 2. При
переходе от последнего к последнему шагу сумма меняется на 4, поэтому последний шаг весит 4. Это потому, что последовательный шаг до сих пор основывается на частичной сумме.
При изменении предыдущего шага сумма изменяется на 6, поэтому последний шаг весит 6 (не 8, это не двоичные числа).
...
Изменение веса первой ступени (n-1) * 2

Алгоритм

Find the max sum (all increments)  
Find the difference with the target sum (if it's not even, no solution)  
Seq[0] is 0  
For each step  
  Compare current difference with the step weight
  if is less 
     we have an increment here, seq[i] = seq[i-1]+1 
  else 
     we have a decrement here, seq[i] = seq[i-1]-1.  
     Subtract we current weight from the current diff.
If remaining diff == 0, solution is Seq[]. Else no solution

Код без правил

F=(len,target)=>{
  max=(len-1)*len/2
  delta = max-target
  seq = [last=0]
  sum = 0
  weight=(len-1)*2
  while (--len > 0)
  {
    if (delta >= weight)
    {
      --last
      delta -= weight;
    }
    else
    {
      ++last
    }  
    sum += last
    seq.push(last);
    weight -= 2;
  }  
  if (delta) return [];
  console.log(sum) // to verify

  return seq
}

Тест в консоли Firefox / FireBug

F(8,4)

Выход

[0, -1, 0, -1, 0, 1, 2, 3]

5

GolfScript ( 41 39 байт)

[][1,]@~:^;({{.-1=(+.)))+}%}*{{+}*^=}?`

Онлайн демо

Спасибо Деннису за 41-> 39.


Вы можете сократить ,0=до ?. Прямой порт в CJam будет на 5 байт короче:L1,al~:S;({{_W=(+_)))+}%}*{:+S=}=p
Деннис

@ Денис, ооо, это удобный способ проехать два {}% блока. Не возражаешь, если я это использую?
Оптимизатор

@ Оптимизатор: нет, но это не совсем моя работа.
Деннис

Я говорил о { ... }%блоке. В моем коде у меня было два, я пытался уменьшить его до 1. Как и в случае с настоящим алгоритмом, я думаю, что и Питер, и я выложили один и тот же алгоритм почти в одно и то же время.
Оптимизатор

3

Mathematica, 73 байта

f=FirstCase[{0}~Join~Accumulate@#&/@Tuples[{-1,1},#-1],l_/;Tr@l==#2,{}]&;

Простое решение грубой силы.

Я генерирую все варианты шагов. Затем я превращаю их в накопленные списки, чтобы получить однопоследовательность. И тогда я ищу первый, чья сумма равна второму параметру. Если есть не, значение по умолчанию {}.


Mathematica просто освещает проблемы математики / комбинаций, не так ли? ;)
Оптимизатор

@Optimizer Я уверен, что CJam все равно победит. ;) На самом деле этот же алгоритм не должен быть сложным в CJam.
Мартин Эндер

1
Это определенно побьет это, но только из-за коротких имен методов. Алгоритм не будет таким простым.
Оптимизатор

@ Оптимизатор, а? Я думаю, что это более просто с простым циклом и фильтром, чем эта композиция функций.
Питер Тейлор,

3

Haskell, 56 байт

n%s=[x|x<-scanl(+)0`map`mapM(\_->[1,-1])[2..n],s==sum x]

Объяснение:

  • Создайте список с перестановками 1,-1и длиной n-1: replicateM n-1[-1,1]
    Пример: replicateM 2 [-1,1]==[[-1,-1],[-1,1],[1,-1],[1,1]]
  • Создайте одну последовательность из этого. scanlимеет низкую производительность, но он делает правильную работу здесь.
  • Отфильтруйте все возможные одно-последовательности с длиной, nгде суммаs

1
простое улучшение состоит в том, чтобы изменить инфиксную функцию. Вот подсказка для более неинтуитивного улучшения: импорт Control.Monadтолько для использования, replicateMкоторый уже слишком длинный. какую другую монадическую функцию вы можете использовать для симуляции replicateM?
гордый haskeller

Кстати, вы должны вернуть только одно решение, поэтому вы должны добавить head$к своему решению.
гордый haskeller

headне возвращается []за [] :: [[a]]- и я ненавижу ошибки.
Йоханнес Кун

1
потому что прошло некоторое время, я скажу вам, что я имел в виду. Вы можете использовать mapM(\x->[1,-1])[2..n]вместо sequenceи replicate.
гордый haskeller

Интересный. Это еще короче: P
Йоханнес Кун


0

CJam, 65 58 54 байта

Чуть короче, чем у моего решения Mathematica, но в основном я виноват в том, что все еще неправильно использую CJam:

0]]l~:S;({{_1+\W+}%}*{0\{+_}%);}%_{:+S=}#_@\i=\0>\[]?p

Это в буквальном смысле тот же алгоритм: получить все n-1наборы {1, -1}. Найдите первого, чье накопление такое же, как s, добавьте a 0. Выведите пустой массив, если ничего не найдено.



0

Рубин (136)

def one_sequences(n)
  n.to_s.chars.map(&:to_i).each_cons(2).to_a.select{|x|x[0] == 0 && (x[1] == 1 || x[1]
  == -1)}.count
end

0

J, 47 символов

Проверяет каждую последовательность, как и многие другие ответы. Постараюсь сделать более короткое решение O (n).

   f=.4 :'(<:@#}.])(|:#~y=+/)+/\0,|:<:2*#:i.2^<:x'

   8 f 4
0 1 2 1 0 1 0 _1

   3 f 5
[nothing]

0

APL 38

{⊃(↓a⌿⍨⍺=+/a←+\0,⍉1↓¯1*(⍵⍴2)⊤⍳2*⍵),⊂⍬}

Пример:

     4 {⊃(↓a⌿⍨⍺=+/a←+\0,⍉1↓¯1*(⍵⍴2)⊤⍳2*⍵),⊂⍬}8
0 1 2 1 0 1 0 ¯1

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.