Обратный Инженер последовательности N-Боначчи [s]

15

РЕДАКТИРОВАТЬ: я буду принимать ответ понедельник, 15.02.2016. Пусть байты всегда будут в твою пользу!

В своем задании «Распечатать последовательность N-Боначчи» @DJMcGoathem описывает последовательности N-Боначчи, в которых предыдущие N чисел суммируются вместо традиционных 2 последовательности Фибоначчи ( называемой «последовательность дуэт- nacci»). Затем он попросил взять два входа, X и N, а затем вывести X- й номер N- nacci.

Я предлагаю обратное.
Для заданной последовательности выведите, какой N- последовательностью она является подмножеством. Я говорю "подмножество", потому что:

  • А) эти последовательности бесконечны
  • Б) если дано начало последовательности, вы можете просто посчитать количество ведущих 1

В случае, если он может принадлежать нескольким последовательностям N- nacci, выберите самую низкую.
В случае, если он не принадлежит ни к какой последовательности N-nacci , ваша программа может сделать что-либо, кроме печати чего-то, что может быть ошибочно принято за вывод. Эти поведения включают (но не ограничиваются ими): бесконечный цикл, ошибку, сбой, удаление самого себя (* кашель * бдение * кашель кашель *) или создание черной дыры (до тех пор, пока эта черная дыра не производит ничего, что могло бы ошибочно принять за верный вывод).
Ради этого вызова эти последовательности начинаются с 1. Это означает, что любая последовательность N- nacci начинается с N единиц. Кроме того, Nдолжно быть положительным целым числом. Так что без -1 -нач и т. Д.

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

1,1,1 -> 1
49, 97 -> 7
55, 89, 144 -> 2
1 -> 1
6765 -> 2
12, 23, 45, 89 -> 12
100, 199 -> 100
Cyoce
источник
1
create a black hole (as long as this black hole does not produce anything that could be mistaken for valid output).О, спирали черной дыры сходятся к золотому сечению! Это должен быть действительный вывод для последовательности duoacci!
Конор О'Брайен
1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Это может быть прекрасное золотое сечение, но НЕ приближайтесь к черной дыре! youtube.com/watch?v=TTUQyEr-sg0
Уровень Река Сент
1
О боже, это намного сложнее, чем я первоначально думал ...
GamrCorps
@ mbomb007 В чем разница между натуральными числами и натуральными числами?
Не то чтобы Чарльз
1
@ mbomb007 ах. Я думал, что 1 был первым натуральным числом. Должно быть, я думал о подсчете чисел
не то, что Чарльз

Ответы:

7

Руби, 94

Я очень удивлен, насколько далеко я смог сыграть в гольф в рамках того же алгоритма! Я начал с более чем 200!

->a{1.step.find{|s|x=[1]*(s+z=a.size)
x<<x[-s,s].inject(:+)while x.max<a.max&&s>1
x[-z,z]==a}}

Ungolfed:

l=->a{
    # ooh! a built-in infinite incrementer!
    1.step.find{|s|
        # if n == 1, z is important, otherwise s.
        x=[1]*(s+z=a.size)
        ## add the next nacci number until we hit or overshot max. 
        ## if s == 1, we don't increment, so don't bother
        x<<x[-s,s].inject(:+)while x.max<g&&s>1
        # eval to true if there's a match, false if not
        x[-z,z]==a
    }
}
Не тот Чарльз
источник
Как x=[1]*(s+z=a.size)именно работает?
Cyoce
@Cyoce Если n == 1, то мы никогда не будем увеличивать, поэтому нам нужен массив из 1, как бы долго ни был вход. Если n > 1, тогда нам нужно по крайней мере n1 для последовательности. Так что s+a.sizeохватывает n == 1любую длину a, и это охватывает начало любой другой последовательности, поэтому мы можем просто начать добавлять sцифры от батареи. Имеет ли это смысл?
Не то, что Чарльз
@Cyoce и, если вы задаете другой вопрос, в Ruby [1]*numberвыдает массив из 1 с длиной number. Так x=[1]*(s+z=a.size)правопреемников a.sizeк z, затем присваивает xмассив длины 1 в s+z.
Не то, что Чарльз
3

Python 2, 176 байт

def r(n,x):i,f=n,[1]*n;exec"f+=sum(f[i-n:]),;i+=1;"*(x-n);return f
l=input()
m=max(l)+len(l)
for i in range(1,m):
 if any(l==r(i,m)[b:b+len(l)]for b in range(m)):print i;break;

Обратите внимание, что это требует ввода в следующем формате:

[1, 1, 2, 3...]

скорее, чем

1, 1, 2, 3...

Довольно простое решение, просто для того, чтобы все заработало. Я буду больше работать над игрой в гольф, как только кто-нибудь ответит. При этом используется слегка измененная версия генератора N-Bonnaci из ответа @ Data , так что подпирайте его. Затем для каждого N-Bonnaci в диапазоне ввода, проверяет, является ли вход подпоследовательности этого.

DJMcMayhem
источник
попробуйте те же самые предложения, которые я ему дал: смените f.appendнаf+=
Cyoce
@ Кайос, о, черт. Я не могу поверить, что пропустил что-то такое основное. fp
DJMcMayhem
Нужен ли трейлинг ;?
Cyoce
1

Луа, 324 323 байта

Когда я вижу другое представление, я чувствую, что с моим кодом что-то не так ... Но потом я помню, что это Lua, и не все эти причудливые функции: '(

Это было очень весело, заняло у меня некоторое время.

Редактировать: 1 байт сохранен простым трюком: вместо него используется ::label::+ goto labelбесконечный цикл while''.

function f(l)c=2 y,z=table.remove,os.exit while(l[1]<2)do y(l,1)if(#l<1)then print(1)z()end end ::q:: a={}for i=1,c do a[i]=1 end b={}for i=1,#l do b[i]=l[i]end while(a[#a]<b[1])do x=0 for i=(#a-c+1>0 and #a-c+1 or 1),#a do x=x+a[i]end a[#a+1]=x if a[#a]==b[1]then y(b,1)end if #b<1 then print(c)z()end end c=c+1 goto q end

Ungolfed и объяснения

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

  function f(l)
  c=2
  y,z=table.remove,os.exit           -- Create pointers on table.remove and os.exit
                                     -- saves a total of 9 bytes
  while(l[1]<2)                      -- loop used to remove leading 1
  do 
    y(l,1)
    if(#l<1)                         -- we also check if it was a 1-only array
    then 
      print(1)                       -- if so, we print 1 and exit
      z()
    end 
  end

  ::q::                              -- label q, start of the infinite loop
    a={}for i=1,c do a[i]=1 end      -- fill an array with c 1s
    b={}for i=1,#l do b[i]=l[i]end   -- copy the sequence array
    while(a[#a]<b[1])                -- while max(a)<min(b)
    do
      x=0 for i=(#a-c+1>0            -- iterate from index a.length-c to
                    and #a-c+1       -- to a.length
                    or 1),#a 
      do 
        x=x+a[i]                     -- summing a's elements
      end
      a[#a+1]=x                      -- append x to a
      if a[#a]==b[1]then y(b,1)end   -- if x is equal ot a member of the sequence
                                     -- remove it
      if #b<1 then print(c)z()end    -- if b is empty, it means the subset is in a
                                     -- we print c and exit
    end                              -- else we loop again
    c=c+1                            -- with c+1
  goto q                             -- return to the start of this block
end

Вы можете попробовать Lua онлайн и скопировать / вставить следующий пример кода для запуска некоторых тестов. Когда эта функция завершит работу, когда найдет ответ (в противном случае - бесконечный цикл), вам придется изменить индекс test[]используемых (не забывайте, что lua индексируется 1) :).

function f(l)c=2 y,z=table.remove,os.exit while(l[1]<2)do y(l,1)if(#l<1)then print(1)z()end end ::q:: a={}for i=1,c do a[i]=1 end b={}for i=1,#l do b[i]=l[i]end while(a[#a]<b[1])do x=0 for i=(#a-c+1>0 and #a-c+1 or 1),#a do x=x+a[i]end a[#a+1]=x if a[#a]==b[1]then y(b,1)end if #b<1 then print(c)z()end end c=c+1 goto q end

test={{1,1,1},
{49, 97},
{55, 89, 144},
{1},
{6765},
{12, 23, 45, 89},
{100, 199}}

print(f(test[1]))
Katenkyo
источник