Новый заказ № 2: Поверни мой путь


15

Введение (может быть проигнорировано)

Размещать все положительные числа в обычном порядке (1, 2, 3, ...) немного скучно, не правда ли? Итак, вот серия проблем, связанных с перестановками (перестановками) всех положительных чисел. Это второй вызов в этой серии. Первый вызов можно найти здесь .

В этом вызове мы используем коды Грея, чтобы переставить натуральные числа. Код Грея или «отраженный двоичный код» - это двоичное кодирование таким образом, что два последовательных значения отличаются только одним битом. Практическое применение этого кодирования - использовать его в поворотных кодировщиках , поэтому я ссылаюсь на «Turn My Way» .

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

Обратите внимание, что эта кодировка оставляет некоторую степень свободы. Например, после бинарного 1100, существует четыре возможных следующие коды: 1101, 1110, 1000 и 0100. Поэтому я определим a(N) , как наименьший, а не ранее используемое значение , которое отличается только один символ в двоичной кодировке. Эта последовательность соответствует A163252 .

Поскольку это задача «чистой последовательности», задача состоит в том, чтобы вывести a(N) для заданного N качестве входных данных, где a(N) - это A163252 .

задача

Учитывая целочисленный ввод N , выведите a(N) в целочисленном формате ( не в двоичном формате).

a(N) определяется как наименее положительное целое число, не встречающееся ранее в последовательности, так чтоa(N-1) иa(N) отличаются только одним битом при записи в двоичном виде.

Примечание: здесь предполагается индексирование на основе 1; Вы можете использовать индексирование на основе 0, поэтому a(0)знак равно1;a(1)знак равно3 и т. д. Пожалуйста, укажите это в своем ответе, если вы решите использовать это.

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

Input | Output
--------------
1     | 1
5     | 4
20    | 18
50    | 48
123   | 121
1234  | 1333
3000  | 3030
9999  | 9997

правила

  • Вход и выход являются целыми числами (ваша программа должна по крайней мере поддерживать вход и выход в диапазоне от 1 до 32767)
  • Неверный ввод (0, значения с плавающей запятой, строки, отрицательные значения и т. Д.) Может привести к непредсказуемым результатам, ошибкам или (не) определенному поведению. В A163252 , ( 0 )a(0) определяется как 0. Для этой задачи мы будем игнорировать это.
  • Стандартные правила ввода / выводаПрименяются .
  • Лазейки по умолчанию запрещены.
  • Это , поэтому самые короткие ответы в байтах выигрывают

Конечная нота

Смотрите следующие связанные (но не равные) вопросы PP & CG:

Ответы:


1

Stax , 19 17 байт

êÑ{╚α8è╙mc┼σ▀»É▲ü

Запустите и отладьте его

Он перестает работать в какой-то момент после указанного домена из-за жестко закодированной битовой индексации. (32767)

Распакованный, размазанный и прокомментированный, это выглядит так.

z0,         push an empty array, literal zero, and the input, in that order
             - the zero represents the last calculated value in the sequence
             - the array contains all the previous ones
D           repeat the rest of the program n times (from input)
  +         append the last calculated value to the array
  17r       [0 .. 16] (these are the bit indices necessary to cover the input range)
  {|2nH|^m  calculate candidate values; previous value with each of these bits toggled 
  n-        remove all values previously calculated
  |m        keep the minimum candidate remaining

Запустите этот


Вы на 1 байт позади самого короткого ответа 05AB1E. Планируете ли вы оптимизировать это дальше? В противном случае я буду принимать ответ Кевина ...
agtoever

1
Если у меня будет такая возможность, я буду работать над ней сегодня, в ближайшие 14 часов.
рекурсивный

Все в порядке. Я буду держать его открытым еще один день. Удачи!
agtoever

@agtoever: Спасибо. Я сделал сейчас.
рекурсивный

Отлично сработано! Ты победил! Поздравляем!
agtoever

4

JavaScript (ES6), 65 байт

1-индексироваться.

n=>{for(o=p=[k=1];o[k]|~-(i=p^k)&i?k++:k=o[p=k]=!!n--;);return p}

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

комментарии

n => {                  // n = index of requested term
  for(                  // for loop:
    o =                 //   o = storage object for the terms of the sequence
    p =                 //   p = last term found in the sequence
      [k = 1];          //   k = current term
    o[k] |              //   if k was already encountered
    ~-(i = p ^ k) & i ? //   or (p XOR k) has more than 1 bit set:
      k++               //     increment k
    :                   //   else:
      k = o[p = k]      //     set o[k], set p to k
        = !!n--;        //     stop if n is equal to 0 or set k to 1; decrement n
  );                    // end of for()
  return p              // return p
}                       // end

На TIO я получаю переполнение стека для n> ~ 1024. Любые предложения о том, как бороться с этим в Абу в другой среде? Правило: « Ваша программа должна по крайней мере поддерживать ввод и вывод в диапазоне от 1 до 32767 »
всегда

1
@agtoever Я обновил его до нерекурсивной версии.
Арнаулд

4

Желе , 26 20 байт

ṀBLŻ2*^1ị$ḟ⁸Ṃ;
0Ç⁸¡Ḣ

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

Полная программа, которая принимает n в качестве единственного аргумента. Работает для всех тестовых случаев. Также обратите внимание, что, хотя и не обязательно, он обрабатывает n = 0.

объяснение

Вспомогательная ссылка: найти следующий термин и предварять

Ṁ              | maximum of list so far
 B             | convert to binary
  L            | number of binary digits
   Ż           | 0..above number
    2*         | 2 to the power of each of the above
      ^        | exclusive or with...
       1ị$     | ... the most recent term in the list so far
          ḟ⁸   | filter out anything used already
            Ṃ  | find the minimum
             ; | prepend to existing list

Главная ссылка

0              | start with zero
 Ç             | call the above link
  ⁸¡           | and repeat n times
    Ḣ          | take the last term added

3

Java (JDK) , 142 138 124 123 132 130 98 байт

  • увеличен для учета импорта, сохранен байт благодаря @ kevin-cruijssen
  • переключил коллекцию на массив int благодаря @ olivier-grégoire
n->{int s[]=new int[9*n],j,k=0;for(;n-->0;s[k=j]++)for(j=0;s[++j]>0|n.bitCount(j^k)>1;);return k;}

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


1
Я боюсь, что импорт должен быть включен в число байтов. Вы можете , однако гольф на import java.util.*;+ Set s=new HashSet();к var s=new java.util.HashSet();. Кроме того, остальные могут быть golfed к: Integer i=0,j,k=0;for(;i++<n;s.add(k=j))for(j=0;s.contains(++j)|i.bitCount(j^k)>1;);return k;. Хороший ответ тем не менее, так что +1 от меня. :)
Кевин Круйссен

1
Сохранено еще 2 байта, используя Stackвместо HashSet. Намного медленнее, но работает!
Даниэль Виддис

1
О(N)О(NN)

2
Вы все еще можете сыграть в гольф до 126 байт со вторым гольфом, который я предложил в своем первом комментарии. :)
Кевин Круйссен


2

Python 2 , 81 байт

Индексирование на основе 1

l=[0];p=0
exec"n=0\nwhile(p^n)&(p^n)-1or n in l:n+=1\np=n;l+=p,;"*input()
print p

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


Python 2 , 79 байт

Это занимает много времени (9999 не был закончен после локального запуска в течение 7 минут)

l={0};p=0;n=input()
exec'p=min({p^2**k for k in range(n)}-l);l|={p};'*n
print p

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


1
Максимальный ввод 32767 не поддерживается (глубина рекурсии по умолчанию не зависит от системы).
Эрик Outgolfer

Даже данный тестовый пример 9999 не поддерживается. :)
Даниэль Виддис

@EriktheOutgolfer Изменил его на итеративный подход, вероятно, все еще не завершается вовремя на TIO, но работает локально просто отлично.
овс

@ovs О, одни только тайм-ауты не имеют значения.
Эрик Outgolfer

Здорово! Я только что попробовал его для n = 9999, и он завершился успешно примерно через час. +1. Ура! ;-)
agtoever



1

Древесный уголь , 65 байт

≔⁰θFN«⊞υθ≔¹ηW¬‹θ⊗η≦⊗ηW∧›η¹∨¬&θη№υ⁻θη≧÷²ηW№υ⁻|θη&θη≦⊗η≔⁻|θη&θηθ»Iθ

Попробуйте онлайн!Ссылка на подробную версию кода. Объяснение:

≔⁰θ

Инициализируйте результат до 0.

FN«

петля n раз.

⊞υθ

Сохраните предыдущий результат, чтобы мы не использовали его снова.

≔¹ηW¬‹θ⊗η≦⊗η

Найти старший бит в предыдущем результате.

W∧›η¹∨¬&θη№υ⁻θη≧÷²η

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

W№υ⁻|θη&θη≦⊗η

Теперь попробуйте XORing этот бит с предыдущим результатом, удваивая бит, пока не будет найден невидимый результат. Это обрабатывает случаи, когда бит должен быть установлен, опять-таки в порядке возрастания значения, но также и случай, когда необходимо переключить младший бит, который предыдущий цикл не потрудит проверить (потому что он проверяет гольф что здесь). Если предыдущий цикл обнаружил невидимый результат, этот цикл никогда не запускается; если это не так, то этот цикл будет бесполезно повторно тестировать эти результаты.

≔⁻|θη&θηθ

Обновите результат, на самом деле XORing бит с ним.

»Iθ

Выведите окончательный результат в конце цикла.


1

05AB1E , 21 20 18 байт

ÎFˆ∞.Δ¯θy^bSO¯yå_*

Довольно неэффективно, поэтому чем больше ввод, тем больше времени требуется для получения результата. Работает ли для ввода 0, хотя.

Попробуйте онлайн или проверьте первыйNтермины .

Объяснение:

Î                # Push 0 and the input
 F               # Loop the input amount of times:
  ˆ              #  Pop the current number and add it to the global_array
  ∞.Δ            #  Inner loop starting at 1 to find the first number which is truthy for:
     ¯θy^        #   XOR the last number of the global_array with the loop-number `y`
         b       #   Convert it to binary
          SO     #   Sum it's binary digits
     ¯yå_        #   Check if the loop-number `y` is NOT in the global_array yet
            *    #   Multiply both (only if this is 1 (truthy), the inner loop will stop)
                 # (after the loops, output the top of the stack implicitly)

1

Haskell , 101 байт

import Data.Bits
(u!n)0=n
(u!n)m|q<-minimum[x|r<-[0..62],x<-[xor(2^r)n],notElem x u]=(n:u)!q$m-1
[]!0

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

Кажется, стыдно брать на себя импорт xor, но я пока не нашел хорошего обходного пути. Мне также интересно, есть ли лучший способ выразить цикл.


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