Рассчитать A190810


27

Ваша задача довольно проста, рассчитайте n-й элемент A190810 .

Элементы A190810 рассчитываются по следующим правилам:

  1. Первый элемент 1
  2. Последовательность увеличивается
  3. Если xпроисходит в последовательности, а затем 2x+1и 3x-1сделать

Вы можете использовать индексацию на основе 1 или 0, но если вы используете индексацию на основе 0, скажите это в ответе.

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

a(1) = 1
a(2) = 2
a(3) = 3
a(4) = 5
a(5) = 7
a(10) = 17
a(20) = 50
a(30) = 95
a(55) = 255

Поскольку это код-гольф, выигрывает самый короткий ответ в байтах!


2
Вы должны добавить более крупные тестовые случаи.
mbomb007

7
Можете ли вы объяснить это немного яснее? Я являюсь носителем английского языка, и я понятия не имею, что "... и если x в a, то 2x + 1 и 3x-1 в". должен означать.
кот

1
@cat x ϵ A → (2*x) + 1 ϵ Aи x ϵ A → (3*x)-1 ϵ A, где ϵозначает «является членом» и может пониматься как «подразумевает».
Стивен Х.

3
Подразумеваемое условие: последовательность не содержит чисел, не требуемых другими правилами. (В противном случае $ a (i) = i $ будет правильной последовательностью)
Стиг Хеммер

1
И вы получите бесплатные ответы Mathematica и Haskell, чтобы начать с :)
Стоп Harming Monica

Ответы:


9

Желе , 16 байт

×3’;Ḥ‘$;
1Ç¡ṢQ³ị

Очень неэффективно. Попробуйте онлайн!

Как это работает

1Ç¡ṢQ³ị   Main link. Argument: n (integer)

1         Set the return value to 1.
 Ç¡       Execute the helper link n times.
   Ṣ      Sort the resulting array.
    Q     Unique; deduplicate the sorted array.
     ³ị   Retrieve its n-th element.


×3’;Ḥ‘$;  Helper link. Argument: A (array)

×3        Multiply all elements of A by 3.
  ’       Decrement the resulting products.
      $   Combine the two links to the left into a monadic chain.
    Ḥ     Unhalve; multiply all elements of A by 2.
     ‘    Increment the resulting products.
   ;      Concatenate 3A-1 and 2A+1.
       ;  Concatenate the result with A.

1
Это может быть 16 символов , но я не знаю ни одной кодировки, которая представляет это менее чем в 30 байтах .
богатый ремер

18
У желе есть своя собственная кодовая страница, которая позволяет этим символам занимать 1 байт каждый.

15

Python 2, 88 83 72 байта

Вы можете прочитать программы в этом ответе в обратном порядке ...

Еще медленнее и короче, благодаря Деннису:

L=1,;exec'L+=2*L[0]+1,3*L[0]-1;L=sorted(set(L))[1:];'*input()
print L[0]

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


Это не так быстро, но короче ( 83 байта ). Сортируя и удаляя дубликаты на каждой итерации, а также удаляя первый элемент, я убираю потребность в индексе в списке. Результатом является просто первый элемент после nитераций.

Возможно, я переиграл Денниса. : D

L=[1]
n=input()
while n:L+=[2*L[0]+1,3*L[0]-1];n-=1;L=sorted(set(L))[1:]
print L[0]

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


Эта версия ниже ( 88 байт ) работает очень быстро, находя 500000-й элемент примерно за две секунды.

Это довольно просто. Вычислять элементы списка до тех пор, пока элементов не будет в три раза больше n, поскольку каждый добавленный элемент может добавить не более 2 уникальных элементов. Затем удалите дубликаты, отсортируйте и напечатайте nэлемент th (с нулевым индексом.)

L=[1]
i=0
n=input()
while len(L)<3*n:L+=[2*L[i]+1,3*L[i]-1];i+=1
print sorted(set(L))[n]

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


8

Python 2, 59 байт

t={1}
exec'm=min(t);t=t-{m}|{2*m+1,3*m-1};'*input()
print m

Основано на ответе Python @ mbomb007 . Проверьте это на Ideone .


«Деннис просто не обгоняет» ... Хотелось бы подумать об использовании заданных литералов. Это кажется таким очевидным сейчас. Является ли этот ответ даже быстрее, чем моя «быстрая» программа, если вы переходите от выполнения строки к реальному коду?
mbomb007

Нет. Это медленнее. Операции над множествами стоят дороже.
mbomb007

Да, minэто O (п) , а список индексации O (1) , так что это решение, по крайней мере O (n²) ...
Dennis

8

Haskell, 76 73 69 байт

a#b=mod a b<1&&t(div a b)
t x=x<2||(x-1)#2||(x+1)#3
(filter t[1..]!!)

Использует индекс на основе 0. Пример использования: (filter t[1..]!!) 54-> 255.

Вместо того, чтобы строить список путем многократной вставки 2x+1и, 3x-1как видно из большинства других ответов, я просматриваю все целые числа и проверяю, можно ли их уменьшить до 1повторного применения (x-1) / 2или (x+1) / 3деления.


Это действительно не определяет функцию или допустимый фрагмент кода, не так ли?
Зета

@Zeta Последняя строка оценивается как безымянная функция.
Згарб

@Zgarb. Это ошибка в файле на Haskell, и ни один из известных мне переводчиков не поддерживает такую ​​функцию. Итак, пожалуйста, просветите меня, как пользователь должен использовать это, не изменяя код выше в любом случае? Или вы могли бы указать мне на мета-пост, который разрешает такой код?
Зета

2
@ Zgarb Я думаю, что для последней строки назначьте привязку (например f=filter t[1..]!!), потому что я не думаю, что это правильно.
TuxCrafting

1
@ TùxCräftîñg В этом посте Meta было определено, что в этой ситуации по умолчанию допустимы дополнительные вспомогательные функции. Это также формат, который я обычно вижу здесь для ответов на Haskell. Конечно, вы, как автор конкурса, обладаете окончательными полномочиями.
Згарб

7

Haskell, 77 74 байта

import Data.List
i=insert
f(x:y)=x:f(i(2*x+1)$i(3*x-1)y)
a=(!!)(nub$f[1])

Это обеспечивает функцию aдля n-й записи. Это нулевой индекс. Как вариант, a=nub$f[1]создаст весь список (лениво).

Это вариант списка Setкода Рейнхарда Цумкеллера .


Почему бы не yвместо того, xsчтобы сохранить два байта? Кроме того, я полагаю, что вы можете сократить последнюю строку до чего-то вроде(!!)$nub.f[1]
Майкл Кляйн

@MichaelKlein: я просто слишком привык (x:xs), совсем забыл об этом, спасибо.
Зета

6

Python 2, 88 84 байта

g=lambda k:g(k%2*k/2)|g(k%3/2*-~k/3)if k>1else k
f=lambda n,k=1:n and-~f(n-g(k),k+1)

Проверьте это на Ideone .


13
Вы профессионал в превращении чего-то простого в нечто нечитаемое.
mbomb007


5

Брахилог , 45 байт

:1-I,?:?*:1ydo:Im.
1.|:1-:1&I(:3*:1-.;I*:1+.)

Вычисляет N = 1000около 6 секунд на моей машине.

Это 1-индексированный, например,

run_from_file('code.brachylog',1000,Z).
Z = 13961 .

объяснение

  • Основной предикат:

    :1-I,               I = Input - 1
         ?:?*           Square the Input
             :1y        Find the first Input*Input valid outputs of predicate 1
                do      Remove duplicates and order
                  :Im.  Output is the Ith element
    
  • Предикат 1:

    1.                  Input = Output = 1
    |                   Or
    :1-:1&I             I is the output of predicate 1 called with Input - 1 as input
           (            
             :3*:1-.      Output is 3*I-1
           ;            Or
             I*:1+.       Output is 2*I+1
           )
    

Вы можете заметить, что мы не передаем входные данные предикату 1 при вызове y - Yield. Из-за распространения ограничений он найдет правильный ввод, как только достигнет 1.предложения, который будет распространять правильные входные значения.


4

MATL, 19, 18 17 байт

1w:"tEQy3*qvSu]G)

Это крайне неэффективный алгоритм. Онлайн-интерпретатору не хватает памяти для входов больше 13.

Один байт сохранен, благодаря Луису Мендо!

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

Эта версия длиннее, но эффективнее (21 байт)

1`tEQy3*qvSutnG3*<]G)

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

Объяснение:

Логический способ сделать это - добавить элементы в массив, пока он не станет достаточно длинным, чтобы захватить i-й элемент. Вот как работает эффективный. Golfy (и неэффективный) способ сделать это, чтобы просто увеличить размер массива я раз.

Таким образом , во- первых, мы определяем массив запуска: 1. Затем мы меняем два верхних элемента, так что ввод идет сверху. w, Теперь мы перебираем ввод с помощью :". Итак, я раз:

t             %Duplicate our starting (or current) array.
 EQ           %Double it and increment
   y          %Push our starting array again
    3*q       %Multiply by 3 and decrement
       v      %Concatenate these two arrays and the starting array
        Su    %Sort them and remove all duplicate elements.

Теперь у нас есть гигантский массив последовательности. (Намного больше, чем необходимо для вычисления). Итак, мы прекращаем цикл ]и извлекаем i-е число из этого массива с помощью G)(1-indexed)


@ LuisMendo Спасибо за совет! Как бы вы переписали это с циклом while вместо цикла for? (Может быть, это был бы лучший вопрос для чата MATL)
DJMcMayhem

Это может быть сделано таким образом: 1`tEQy3*qvuStnG<]G). Условие цикла tnG<(выход, когда массив уже имеет требуемый размер)
Луис Мендо

Не уверен, сколько это читерства, но в forверсии -loop вы можете взять ввод в унарном виде в виде строки и удалить:
Luis Mendo

4

JavaScript (ES6), 63 байта

 f=(n,a=[1],i=0)=>a[i++]?--n?f(n,a,a[i*2]=a[i*3-2]=1):i:f(n,a,i)

Вероятно, быстро сдается из-за рекурсии.


4

Сетчатка, 57

^.+
$*¶¶1
¶¶(1(1*))
¶1$1$1¶$2$1$1
O`
}`(¶1+)\1\b
$1
G2`
1

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

0 индексированные. Следует часто используемому алгоритму: удалить минимальное значение из текущего набора, вызвать его x, добавить 2x+1и3x-1 к набору число раз, равное входному , тогда в качестве результата следует начальное число. «Набор» в Retina - это просто список, который многократно сортируется и состоит только из уникальных элементов. В алгоритм игры в гольф добавлены некоторые хитрые кусочки, которые я объясню, как только у меня будет больше времени.

Огромное спасибо Мартину за то, что он занял около 20 байтов


4

Clojure, 114 108 байт

#(loop[a(sorted-set 1)n 1](let[x(first a)](if(= n %)x(recur(conj(disj a x)(+(* 2 x)1)(-(* 3 x)1))(inc n)))))

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

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

Версия с пробелами:

#(loop [a (sorted-set 1)
        n 1]
  (let [x (first a)]
    (if (= n %)
      x
      (recur (conj (disj a x) (+ (* 2 x) 1) (- (* 3 x) 1)) (inc n))
      )))

4

05AB1E, 18 17 байт

Использует кодировку CP-1252 .

$Fз>s3*<)˜Ù}ï{¹è

объяснение

$                  # initialize with 1
 F          }      # input number of times do
  Ð                # triplicate current list/number
   ·>              # double one copy and add 1
     s3*<          # multiply one copy by 3 and subtract 1
         )˜Ù       # combine the 3 lists to 1 list and remove duplicates
             ï{    # convert list to int and sort
               ¹è  # take the element from the list at index input

Попробуйте онлайн для небольших номеров

Очень медленно.
Использует индексирование на основе 0.


3

C ++, 102 байта

[](int i){int t;map<int,int>k;for(k[1];i--;k.erase(t))t=k.begin()->first,k[t*2+1],k[t*3-1];return t;};

Эта лямбда-функция требует #include <map>и using std::map.

mapЗдесь это просто набор ключей; их значения игнорируются. Я использую mapдля того, чтобы извлечь выгоду из краткого кода для вставки:

k[1]; // inserts the key 1 into the map

Благодаря отсортированному порядку map, самый маленький элемент извлекается с помощью k.begin()->first.


1
Чуть короче (97) с использованием setи инициализатор списков: [](int i){int t;set<int>k{1};for(;i--;k.erase(t))t=*k.begin(),k.insert({t*2+1,t*3-1});return t;};.
Ноя

3

На самом деле, 27 байтов

╗1#╜`;;2*1+)3*1@-#++╔S`n╜@E

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

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

Объяснение:

╗1#╜`;;2*1+)3*1@-#++╔S`n╜@E
╗                            save input (n) in register 0
 1#                          push [1]
   ╜                         push n
    `;;2*1+)3*1@-#++╔S`n     do the following n times:
     ;;                        make two copies of the list
       2*1+                    apply 2x+1 to each element in one copy
           )3*1@-              and 3x-1 to each element in the other copy
                 #             workaround for a weird list bug
                  ++           append those two lists to the original list
                    ╔S         uniquify and sort
                        ╜@E  get the nth element (0-indexed)

2

CJam (25 байт)

ri1a1${{_2*)1$3*(}%_&}*$=

Демо онлайн . Обратите внимание, что здесь используется индексация с нуля.

Это использует аналогичный подход для большинства: применить время преобразования, nа затем отсортировать и извлечь этот nэлемент. В качестве указания на эффективность дедупликация применяется внутри цикла, а сортировка применяется вне цикла.


2
22: 1ari{(_2*)\3*(@||$}*0=(Также намного более эффективный.)
Мартин Эндер

2

Сетчатка , 48 байт

.+
$*
+1`^(((!*)!(!|\3)(?=\3!1))*!)1|\b
!$1
-2`.

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

Вдохновленный ответом Ними я подумал, что попробую другой подход к Retina, используя обратное отслеживание движка regex, чтобы выяснить, есть ли какое-либо заданное (унарное) число в последовательности или нет. Оказывается, это можно определить с помощью 27-байтового регулярного выражения, но его использование стоит несколько дороже, но все же в конечном итоге оказывается короче, чем генеративный подход.

Вот альтернативное 48-байтовое решение:

.+
$*
{`1\b
1!
}T`1``1((!*)!(!|\2)(?=!\2$))*!$
!

И используя унарный ввод / вывод, мы можем сделать 42 байта, но я пытаюсь избежать этого, и другой ответ Retina также использует десятичную дробь:

1\b
1!
}T`1``1((!*)!(!|\2)(?=!\2$))*!$
!
1

2

Рубин, 70 байт

->n{a=*1
n.times{a<<a.map{|i|([2*i+1,3*i-1]-a).min||1.0/0}.min}
a[-2]}

объяснение

->n{
    # Magical, golfy way of initializing an array. Equivalent to a = [1].
    a=*1
    n.times{
        # Generate the next element in the sequence, by...
        a<<
            # ... finding the minimal term that will appear at some point.
            a.map{|i|
                ([2*i+1,3*i-1]-a).min||1.0/0
            }.min
    }
    # We generated n+1 elements, so we'll take the *second* to last one.
    a[-2]
}

1
Этот *1трюк
изящен

1

J, 31 байт

{1(]]/:~@~.@,3&*,&:<:2*>:)^:[~]

Используется индексирование с нуля. Очень мало памяти.

объяснение

{1(]]/:~@~.@,3&*,&:<:2*>:)^:[~]  Input: n
                              ]  Identity function, gets n
 1                               The constant 1
  (                      )^:[~   Repeat n times with an initial array a = [1]
                       >:          Increment each in a
                     2*            Multiply by 2 to get 2a+2
             3&*                   Multiply each in a by 3 to get 3a
                 &:<:              Decrement both x and y to get 2a+1 and 3a-1
                ,                  Join them
    ]                              Identity function, gets a
            ,                      Join a with 2a+1 and 3a-1
         ~.@                       Take the distinct values
     /:~@                          Sort up
   ]                               Return the sorted list
{                                Select the value from the list at index n and return it

1

Октава, 68 байт

function r=a(n)s=1;for(i=1:n)r=s(i);s=union(s,[r*2+1 r*3-1]);end;end

Вы можете удалить финал;end
Луис Мендо

На версии, которую я использую, по крайней мере (4.0.0) вы не можете ...
dcsohl

1

Perl, 173 132 байта +1 для -n = 133

sub c{my$a=pop;return($a==1||($a%2&&c(($a-1)/2))?1:$a%3!=2?0:$a%3==2?c(($a+1)/3):1)}while($#b<$_){$i++;@b=(@b,$i)if c$i}say$b[$_-1];

Ungolfed:

my @array = ();
my $n = <>;
sub chk {
    my $a = shift;
    return 1 if ($a == 1);
    if ($a % 2 == 0) {
        if ($a % 3 != 2) {
            return 0;
        } else {
            return chk(($a + 1) / 3);
        }
    } else {
        if (chk(($a - 1) / 2) == 0) {
            if ($a % 3 != 2) {
                return 0;
            } else {
                return chk(($a + 1) / 3);
            }
        } else {
            return 1
        }
    }
}
my $i = 1;
while ($#array < $n-1) {
    push(@array,$i) if (chk($i) == 1);
    $i++;
}
print $array[$n];

Возможно, я мог бы добиться большего, если бы больше думал об этом, но это то, что я придумал через несколько минут. Я впервые играл в гольф, так что это было довольно весело!

Благодаря @Dada и @ TùxCräftîñg (и куче незначительных оптимизаций байтов) для -40 байтов


1
Я думаю, что вы можете отбросить пробелы после mys, the returnи print(не могу проверить, у меня нет perl)
TuxCrafting

1
@ TùxCräftîñg прав насчет return. То printможно заменить собой say. Большинство из myних не нужны (вам нужен только предыдущий $aв функции, я думаю. Не инициализируйте и не объявляйте @b. Вероятно, вы можете отбросить инициализацию, $iесли делаете это $i++в начале while, а не в конце. popIs короче, чем shift. Имейте в виду, что Perl-гольф намного больше, чем просто удаление пробелов и новых строк ...
Dada

0

JavaScript (ES6), 58

n=>(a=>{for(;n;)a[++i]?a[i-~i]=a[3*i-1]=--n:0})([i=0,1])|i

Меньше гольфа

n=>{
  a=[];
  a[1] = 1;
  for(i = 0; n;)
  {
    ++i
    if (a[i])
    {
      a[2*i+1] = 1;
      a[3*i-1] = 1;
      --n;
    }
  }
  return i
}

Тест

О времени и памяти: элемент 500000 в ~ 20 секунд и 300 МБ, используемый 64-битной альфа-версией FireFox

F=
n=>(a=>{for(;n;)a[++i]?a[i-~i]=a[3*i-1]=--n:0})([i=0,1])|i

function test() {
  var n=+I.value, t0=+new Date
  O.textContent = F(n)
  console.log((+new Date-t0)/1000,'sec')
}  

test()
#I { width:5em}
<input id=I type=number value=10 oninput="test()"> 
<span id=O></span>

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