走开!No-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程序,该程序通过将索引转换为二进制,将1替换为2,然后从三进制转换为十进制,来生成这些数字的前n个

我还注意到,通过取序列中两个数字的和(有时是数字本身)可以得到任何偶数。

挑战:

给定任何非负偶数作为输入,请按求和顺序输出两个数字的索引。(请注意,有时可能有多对。)

规则:

  • 指定使用0索引还是1索引。
  • 如果要以字符串形式输出,请在两个索引之间放置一个定界符。
  • 允许您输出为复数。
  • 如果您愿意,可以输出每个有效对。
  • Code Golf:最短答案胜出

测试用例

我使用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是的,没关系。
geokavel

斯隆先生 似乎真的很喜欢他的数字序列。“有一个序列”(TM)
法拉普

1
由于对于某些输入有多种解决方案,因此最好将所有解决方案都包含在测试用例中。该程序以与挑战文本相同的格式显示每个测试用例的所有解决方案对(从0开始,每对递增排序)
Luis Mendo

Answers:


10

外壳21 14 13字节

-7个字节,感谢@Neil的JS回答

-1字节受betaveros的Parradoc答案启发

使用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

看来您需要通过以下方式为零添加边缘情况处理:(
Jonathan Allan

看起来这是从1开始的;也许值得在答案中说明它
Luis Mendo


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. 从二进制转换这些列表

我们可以通过将0->0,1->1,2->1一个列表转换为(3)来进行拆分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 bb a视为不同的可能总和)。

从布尔矩阵转换为索引需要大量代码...

我也想删除左侧的叉子,所以我不必使用太多的括号和@-ats,但是我想不出一个好方法(我的替代方法不保存任何字节) )。

说明

为了说明和解囊,请考虑以下主要功能组件

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

valid_nums产生一个布尔矩阵,其中索引是总和的序列值的索引。如果这些索引处有一个数字,则表示这两个数字加起来等于输入值。

index_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

index_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

MATL22 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

OP表示在评论中表示可以生成所有解决方案
H.PWiz

@ H.PWiz谢谢!我没看过
Luis Mendo


2

Pyth,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

Paradoc(v0.2.10),11个字节(CP-1252)

½3B2>_B™2Bv

在线尝试!

从算法上讲,这非常类似于Neil的ES6答案。在较低的水平上,也与H.PWiz的Husk答案非常相似。我很高兴我们必须使用的所有三个重载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

Python 3122 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先生17年

1

Mathematica,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字节

通过在Wiki上查找模函数,可以得到-54字节,从而可以进行一些结构上的更改

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

在线尝试!

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为基数进行字符串化,以替换21,以2为基进行解析。

要获得两个数字,甚至每个数字,我们只需输入的一半-但是现在,1数字也可以出现。因此,在替换和分析步骤之前,我们用0一个数字替换为a ,另一个数字替换为a 2,这不会更改两个数字的和。这是我想出的(一步完成两个替换,即1-> 0-or-2和2-> 1):

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

当然这两个替换映射(字符串)仅在一个索引不同,所以我们应该能够通过仅更换缩短数组文本12d == 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"]版本开始(变量名也有所不同)
Neil

我认为.replace(/./g,d=>d>>1|x)可以节省2个字节。
尼尔

@Neil不幸的是,这不适用于d="0"并且x=1-数字应该保持0
Bergi

是的,在尝试了更多测试用例之后,我才得出结论。(而且我想出了另一个变体,但是恐怕我的回答是这样。)
Neil

1
哦,非常好,我认为我很聪明能击败您的先前版本...
Neil

0

Pyth,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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.