Йди геть! Ні-1 ось!


16

Я розігрувався з деякими номерами і знайшов послідовність, яка, звичайно, є на OEIS. Це A005823 : Числа, потрійна розширення яких не містить 1 . Це іде:

a (2n) = 3 * a (n) +2

a (2n + 1) = 3 * a (n + 1)

a (1) = 0

a = 0,2,6,8,18,20,24,26,54 ....

Я написав програму CJam, яка генерує першу n із цих чисел, перетворюючи індекс у двійковий, замінюючи 1-й на 2-х та перетворюючи з потрійного на десятковий.

Я також помітив, що будь-яке парне число можна отримати, взявши суму двох чисел у послідовності (іноді число з собою).

Змагання:

Враховуючи будь-яке невід'ємне парне число як вхідне, виведіть індекси двох чисел у послідовності, що підсумовує його. (Зверніть увагу, що іноді можливі кілька пар.)

Правила:

  • Вкажіть, чи використовуєте ви 0- або 1-індексацію.
  • Якщо ви виводите рядок як рядок, поставте роздільник між двома індексами.
  • Вам дозволяється виводити як складне число.
  • Якщо ви цього хочете, ви можете вивести кожну дійсну пару.
  • Код Гольф: виграє найкоротша відповідь

Випробування

Я використовую 0-індексацію. Тут я перелічую всі можливі результати для кожного входу, але вам потрібно лише один.

0:       [0 0]
 2:       [1 0]
 4:       [1 1]
 6:       [2 0]
 8:       [2 1] [3 0]
 10:      [3 1]
 12:      [2 2]
 14:      [3 2]
 16:      [3 3]
 18:      [4 0]
 30:      [6 2]
 32:      [6 3] [7 2]
 46:      [7 5]
 50:      [7 6]
 120:     [10 10]
 338:     [19 18]
 428:     [30 23] [31 22]
 712:     [33 27] [35 25] [41 19] [43 17] [49 11] [51 9] [57 3] [59 1]
 1016:    [38 37] [39 36]
Дякуємо @Luis Mendo за допомогу у тестовому випадку.

Пов’язано: чи це всередині набору кантора?


Чи можемо ми вивести складне число двох значень? Чи можемо ми надати дві функції, по одній надаючи кожне значення?
xnor

2
Чи можемо ми вивести всі можливі значення, чи це виходить за межі проблеми?
cole

@cole Так, це нормально.
geokavel

Схоже, містеру Слоану дуже подобаються його чисельні послідовності. "Існує послідовність для цього" (TM)
Pharap

1
Оскільки для деяких входів є кілька рішень, було б непогано включити всі рішення в тестові приклади. Ця програма показує всі пари рішення для кожного тестового випадку в тому ж форматі, що і в тексті виклику (на основі 0, кожна пара сортується все частіше)
Луїс Мендо

Відповіді:


10

Лушпиння , 21 14 13 байт

-7 байт, завдяки відповіді JS @ Ніла

-1 байт, натхненний відповіддю бетароса Паррадока

Використовує 0-індексацію

mḋTmMo±>ḋ2B3½

Спробуйте в Інтернеті!

Пояснення

            ½    Half the input
          B3     Convert to Base 3
   m             Map over the list
    Mo±>ḋ2       Function such that: 0 -> [0,0], 1 -> [0,1], 2 -> [1,1]
        ḋ2       Binary 2, [1,0]
    M            For each in that list
     o±>         check if the argument is greater than it
  T              Transpose
mḋ               Convert each from binary

Попередній 21 байт Рішення

Перший раз я бачив використання ».

mḋT»o%2+ȯ?´eḋε%3`-0B3

Спробуйте в Інтернеті!

Довше, як я мав справу з несе


8

JavaScript (ES6), 75 71 байт

f=
n=>[1,0].map(i=>parseInt((n/2).toString(3).replace(/./g,c=>+c+i>>1),2))
<input type=number min=0 step=2 oninput=o.textContent=this.value%2?``:f(this.value)><pre id=o>

Пояснення: Поділ вхідних даних та елементів A005823 на 2 не змінює проблему, однак це робить рішення простішим, оскільки потрійні подання тепер використовують лише 0 і 1, і тому немає ніякого розгляду. Це також економить крок при перетворенні від елемента до його індексу (потрійний елемент кожного вдвічі більший за його індекс). Приклади:

                 A005823
                  halved
            n in  values A005823
   n n/2  base 3  base 3 indices
   0   0       0   0   0   0   0  
   2   1       1   1   0   1   0
   4   2       2   1   1   1   1
   6   3      10  10   0   2   0
   8   4      11  11   0   3   0
  10   5      12  11   1   3   1
  12   6      20  10  10   2   2
  14   7      21  11  10   3   2
  16   8      22  11  11   3   3
  18   9     100 100   0   4   0
  30  15     120 110  10   6   2
  32  16     121 111  10   7   2
  46  23     212 111 101   7   5
  50  25     221 111 110   7   6

6

Желе , 26, 22 , 21 байт

ḶBḤḅ3
ÇŒcS=¥Ðf⁸ḢiЀÇT

Спробуйте в Інтернеті!

Один байт збережено завдяки @JonathanAllan!

Пояснення:

                # Helper link: A005823 to *N* terms
Ḷ               # Lowered range(N)
 B              # Converted to binary
  Ḥ             # Double each digit
   ḅ3           # Converted from base 3 to decimal
                # Main link
Ç               # Last link
 Œc             # All combinations of 2 items (with replacement)
      Ðf        # Remove every combination where this isn't true:
   S=¥          #   The sum of the two items is equal to N
        ⁸Ḣ      # Take the first combination left
          i     # Index of
           Ѐ   # Each element of the combination
             Ç  # In the sequence
              T # Return the truthy indices

1
@JonathanAllan О, приємно знати Œc. І так, Денніс пояснив S=¥мені проблему .
DJMcMayhem

Схоже, вам потрібно до речі додати обробку крайових корпусів для нуля :(
Джонатан Аллан

Схоже, це 1-базова; можливо, варто було б сказати це у відповіді
Луїс Мендо


3

Python 2 , 51 байт

f=lambda n:[n and(n/2%3>r)+2*f(n/3)[r]for r in 0,1]

Спробуйте в Інтернеті!

Завдання можна зробити так:

  1. Половину введення
  2. Перетворити на потрійний список
  3. Розділіть це на два двійкові списки, що порівнюють його по елементах
  4. Перетворити ці списки з двійкових

Ми можемо зробити розщеплення в (3), перетворивши 0->0,1->1,2->1для одного списку і0->0,1->0,2->1 для іншого. Тобто, перевіряючи, чи є значення вище порогового значення 0 або 1.

Два значення можуть бути знайдені відповідними рекурсивними функціями:

p=lambda n:n and(n/2%3>0)+2*p(n/3)
q=lambda n:n and(n/2%3>1)+2*q(n/3)

Функція f поєднує в списку два з них. Це робить його неефективним через експоненціальне розгалуження.

Якщо можна вивести складні числа, ми могли б зберегти 10 байт за допомогою:

f=lambda n:n and(n%6>1)+n%6/4*1j+2*f(n/3)

Я думаю, складні числа добре.
geokavel

3

J, 35 32 байти

($#:I.@,)@(=[:+/~3#.+:@#:@i.@>:)

Спробуйте в Інтернеті!

0-індексується і вводиться монадично. Повертає всі можливі підсумки до значення (воно трактує a bі b aяк різні можливі підсумки).

Перетворення булевої матриці в індекси вимагає багато коду ...

Я також хотів би вийняти вилку зліва, щоб мені не довелося використовувати стільки круглих дужок і @-ats, але я не можу знайти хороший спосіб це зробити (мій альтернативний підхід не зберігає жодних байт ).

Пояснення

З метою пояснення та відміни від гольфу розглянемо наступні компоненти основної функції

valid_nums      =. = [: +/~ 3 #. +:@#:@i.@>:
indices_of_ones =. $ #: I.@,

valid_nums дає булеву матрицю, де індекси є індексами підсумованих значень послідовностей. Якщо в цих індексах є одне, це означає, що два числа дорівнюють вхідному значенню.

indices_of_ones - ідіома J для надання координат одиниць в довільній ранговій булевій матриці

Основна функція складається досить просто як

indices_of_ones@valid_nums

valid_nums

= [: +/~ 3 #. +:@#:@i.@>:  Input is n
                 #:@i.@>:  Binary numbers in range [0,n]
              +:           Doubled
         3 #.              Interpreted as ternary
     +/~                   Addition table with self (sum all possible pairs)
=                          Equate to n

indices_of_ones

$ #: I.@,
        ,  Ravel matrix into a single list
     I.    Find the indices of ones in that list
  #:       Convert to the base given by
$          The shape of the matrix

,-ravel працює в цьому випадку, приєднуючи кожен рядок до наступного.

   i.3 3
0 1 2
3 4 5
6 7 8
   , i.3 3
0 1 2 3 4 5 6 7 8

Ми можемо бачити, що якби це була булева матриця, координати їх можна знайти, інтерпретуючи індекси шаленої матриці як числа в основі форми цієї матриці, використовуючи якомога більше фраз, що дозволяють заплутати бідного читача .


1
ваші зайві результати нормально.
geokavel

3

MATL , 22 21 19 17 байт

tQ:qBEI_ZA&+=R&fh

Результат 1-базований. Програма виробляє всі пари рішення. Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

t      % Implicit input: n. Duplicate
Q:q    % Range [0 1 ... n]
B      % Convert to binary. Gives a matrix where each row corresponds to a number
E      % Multiply each entry by 2
I_ZA   % Convert each row from ternary to a number
&+     % Matrix of all pair-wise additions
=      % Does each entry equal n?
R      % Upper triangular matrix
&f     % Push row and column indices of nonzero entries
h      % Concatenate horizontally. Implicit didsplay

ОП заявила, що виготовлення всіх рішень було нормально у коментарях
H.PWiz

@ H.PWiz Дякую! Я цього не бачив
Луїс Мендо


2

Піт , 29 байт

Цей повертає всі можливі пари індексів.

fqQ+@Kmi:.Bd\1\23QhT@KeT.cUQ2

Спробуйте тут.

Pyth , 30 байт

hfqQ+@Kmi:.Bd\1\23QhT@KeT.cUQ2

Спробуйте тут.

Це повертає пари індексів як [LowerIndex, HigherIndex].


Як це працює?

hfqQ+@Kmi:.Bd\1\23QhT@KeT.cUQ2   Full Program. Q means input throughout the whole explanation.

       m          Q               Map over the range [0, Q) with a variable d.
          .Bd                     Convert to binary.
         :   \1\2                 Replace 1 with 2.
        i        3                Convert it from base 3 to integer.
      K                           Assign the mapped range to a variable K.
                         .cUQ2    All possible two-element combinations of the range [0...Q).
    +@             hT@KeT         Sum of the integers on positions in K of the two-element
                                  combination.
 fqQ                              Filter those that equal the input.
h                                 Optional: Head. Take the first element.
                                  Print the result, implicitly. 

2

Парадок (v0.2.10), 11 байт (CP-1252)

½3B2>_B™2Bv

Спробуйте в Інтернеті!

Алгоритмічно це дуже схоже на відповідь Ніла ES6 . На нижчому рівні, також вражаюче схожий на відповідь Х.Ш. Віза . Мені цікаво, що ми повинні використати всі три перевантаженняB .

Бере ціле число на стеку, залишає список двох цілих чисел на стеку.

Пояснення:

½           .. Halve input
 3B         .. Convert to ternary
   2        .. 2, which will get implicitly coerced to [0,1]
    >_      .. Greater than, as a block
      B     .. "Bimap": take the block and map it over the Cartesian
            .. product of the last two lists to get a matrix
       ™    .. Transpose
        2Bv .. Convert each row from binary

1

Пітон 3 , 122 120 байт

-2 байти дякую містеру Xcoder!

0-індексований

def f(a):r=range(a);s=[int(bin(x)[2:].replace(*'12'),3)for x in r];return[(i,j)for i in r for j in r if s[i]+s[j]==a][0]

Безголівки:

def f(a):
    r=range(a)
    s=[int(bin(x)[2:].replace(*'12'),3)for x in r]
    return[(i,j)for i in r for j in r if s[i]+s[j]==a][0]

Спробуйте в Інтернеті!


1
Сподіваюся, ви не проти. Я додав посилання TiO.
Містер Xcoder

1

Математика, 94 байти

(w=#;Position[s,#]&/@#&@@(k=Select)[Tuples[s=k[Range@w,DigitCount[#,3,1]==0&],{2}],Tr@#==w&])& 


1-індексований


1

JavaScript, 120 101 байт

n=>[(A=[...Array(n+1)].map(Z=(a,b=a)=>b&&3*Z(b/2|0)+b%2*2))[F='findIndex'](a=>z=~A[F](b=>a+b==n)),~z]

Спробуйте в Інтернеті!

0-індексований.
Він повертає пару індексів, де один індекс є найменшим можливим (наприклад, у випадку 428його повернення 22,31).


1

Мозок-Флак , 220 166 байт

-54 байти, шукаючи модульну функцію на wiki, дозволяючи деякі структурні зміни

({()<({}[()()])>}{}){({}(<>))<>(()()())({()<(({})){({}[()])<>}{}>}{}<><([{}()]{})>[()])}([]){{}<>(({}){})<>(({}){}{()<({}[()]){<>({}())<>(<{}>)}>}{})([][()])}({}{}<>)

Спробуйте в Інтернеті!

0-індексований.

Пояснення

Як і багато інших рішень, це обчислює потрійне розширення n/2 та перетворює це на два двійкові числа.

Крок 1: Ділимо введення на 2

({()<({}[()()])>}{})

 {              }     until number becomes zero:
     ({}[()()])       subtract two
( ()<          > {})  push number of iterations

Крок 2: обчислити потрійне розширення

{({}(<>))<>(()()())({()<(({})){({}[()])<>}{}>}{}<><([{}()]{})>[()])}

 ({}(<>))<>         {   (({})){({}[()])<>}{} }{}<> ([{}()]{})         modulo (from wiki)
           (()()())                                                   use 3 as base
                     ()<                    >                         evaluate as 1 every time the 3 rolls over
                   (                              <          >[()])   push number of rollovers (function is now division with remainder)
{                                                                  }  repeat until quotient is zero, leaving all remainders on stack

Крок 3: Перетворення на рішення

([]){{}<>(({}){})<>(({}){}{()<({}[()]){<>({}())<>(<{}>)}>}{})([][()])}({}{}<>)

([]){{}                                                      ([][()])}           repeat while stack height > 1:
                                                                                 (loop happens once when initial stack height is 1, but that's fine)
       <>(({}){})                                                                double smaller output number
                 <>(({}){}                                  )                    double larger output number
                          {                              }{}                     if digit in ternary expansion is nonzero:
                           ()<                          >                        add 1 to larger output number
                              ({}[()]){                }                         if digit is 2:
                                       <>({}())<>(<{}>)                          add 1 to smaller output number

0

JavaScript (ES6), 70 72 байт

n=>[6,4].map(x=>parseInt((n/2).toString(3).replace(/./g,d=>x>>d&1),2)) // thanks @Neil
n=>[0,1].map(x=>parseInt((n/2).toString(3).replace(/1|2/g,d=>~-d||x),2))

(Індексовано 0, і, мабуть, майже те саме рішення, що і @Neil, навіть якщо б я не бачив його відповіді)

Я почав із повернення індексу з числа, використовуючи зворотний процес: укажіть на базу 3, замініть кожен 2на1 , синтаксичного аналізу з основою 2.

Щоб отримати два числа, і що за кожне парне, ми лише наполовину вводимо - але тепер також 1можуть відбуватися цифри. Таким чином, ми замінюємо його 0на одне число і 2на інше число, яке не змінює суму двох, перед кроком заміни та розбору. Ось що я придумав (робив дві заміни,1 -> 0-або-2 і 2-> 1за один крок):

n=>["001","011"].map(x=>parseInt((n/2).toString(3).replace(/./g,d=>x[d]),2))

Звичайно, дві замінні карти (рядки) відрізняються лише одним індексом, тому ми повинні мати можливість скоротити літерал масиву, лише замінивши 1 і 2з d == 2 ? 1 : x. Або d-1 || x. Звідки -1те саме, що і два одинарні оператори - але вони виглядають страшніше :-)

Намагаючись уникнути прямолінійного масиву та круглих дужок навколо n/2 я також придумав

n=>Array.from(parseInt,(h=n/2,i)=>parseInt(h.toString(3).replace(/1|2/g,d=>~-d||i),2))

але це не вийшло плідним.


Я теж почав з ["001","011"]версії (добре, що мої імена змінних були різними)
Ніл

Я думаю, .replace(/./g,d=>d>>1|x)економить 2 байти.
Ніл

@Neil На жаль, це не працює d="0"і x=1- цифра повинна залишитися0
Бергі

Так, я просто це розробив, перепробувавши ще кілька тестових випадків. (І я з тих пір придумав інший варіант, але, боюся, це відповідає моїй відповіді.)
Ніл

1
О, дуже добре, і я думав, що я розумний, щоб перемогти вашу попередню версію ...
Ніл

0

Піт, 22 байти

J.m}1jb3hQxLJhfqsTQ^J2

Спробуйте в Інтернеті: Демонстрація

Пояснення:

J.m}1jb3hQxLJhfqsTQ^J2
        hQ                input + 1 
 .m                       find all values of [0, 1, 2, ..., input], where
     jb3                     value converted to base 3
   }1                        check if it contains the digit 1
                          this boolean ^ is false
J                         store this list in variable J

                   ^J2    every pair of J
              f           filter for pairs with
                sT           sum of pair
               q             equal
                  Q          the input
             h            take the first of these pairs
          xLJ             and find the corresponding indices of J
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.