男女序列


20

这个问题可能比所有这些“生成数字序列”任务都困难,因为这需要两个序列一致地工作。

真的很期待答案!

道格拉斯·霍夫施塔特(Douglas Hofstadter)在他的《哥德尔,埃舍尔,巴赫:永恒的金色辫子》一书中里面有很多数字序列,所有这些序列都以某种方式依赖上一个术语。有关所有序列的信息,请参见Wikipedia页面

一对真正有趣的序列是雌性和雄性序列,它们的定义如下:

n > 0

这是女性序列男性序列

您的任务是,在给定整数n作为输入的情况下n,在输出的两行中返回母序列和母序列的列表,其项的数量等于,第一行是母序列,母序列为第二。

输入和输出示例:输入:5 输出:[1, 1, 2, 2, 3] [0, 0, 1, 2, 2]

输入:10 输出:[1, 1, 2, 2, 3, 3, 4, 5, 5, 6] [0, 0, 1, 2, 2, 3, 4, 4, 5, 6]

注意:列表之间的分隔表示换行符。

这是代码高尔夫球,因此以字节为单位的最短代码获胜。另外,还要为您的代码添加解释。

排行榜


5
我们可以从函数中返回一对列表,而不是打印列表吗?
Zgarb '16

涉及霍夫施塔特序列的其他挑战:Q序列图形序列
Martin Ender

@Zgarb您可以,只要两个列表位于不同的行中即可。
clismique

2
@DerpfacePython 一对列表中没有;如果函数返回一对列表,则可以根据需要打印它们。话虽如此,即使打印输出,我也不是行要求的忠实拥护者。繁琐的I / O格式是编写挑战时应避免的事情之一。
丹尼斯

4
对于某些方法/语言来说,这没什么大不了的,但是对于其他方法/语言却可以有很大的不同。在C语言中,通过按列而不是行打印序列可以节省很多字节。在Python中,我能想到的最短的方法是类似于我的递归Julia答案的递归lambda,它返回一对列表,但是必须通过换行将其转换为字符串,这会使它更长,甚至比完整程序更长由Sp3000发布。由于无法添加换行符,因此完全排除了其他方法,例如递归解决方案,该方法递减计数而不是递增计数。
丹尼斯

Answers:


3

果冻22 20 字节

ṙṪḢạL}ṭ
çƓḤ¤Ð¡1ṫ-Ṗ€G

在线尝试!

怎么运行的

çƓḤ¤Ð¡1ṫ-Ṗ€G  Main link. No user arguments. Left argument defaults to 0.
   ¤          Combine the two links to the left into a niladic chain.
 Ɠ              Read an integer from STDIN.
  Ḥ             Unhalve/double it.
ç   С1       Call the helper link that many times. Return all results.
              In the first call, the left and right argument are 0 and 1 resp.
              After each iteration, the left argument is set to the return value
              and the right argument to the prior value of the left one.
       ṫ-     Tail -1; keep the last two items of the list of results.
         Ṗ€   Discard the last item of each list.
           G  Grid; format the pair of lists.


ṙṪḢạL}ṭ       Helper link. Arguments: x, y (lists)

ṙ             Rotate x k units to the left, for each k in y.
 Ṫ            Tail; extract the last rotation.
  Ḣ           Head; extract the last element.
              This essentially computes x[y[-1]] (Python notation), avoiding
              Jelly's 1-based indexing.
    L}        Yield the length of y.
   ạ          Take the absolute difference of the results to both sides.
      ṭ       Tack; append the difference to y and return the result.

5
在这一部分,我为自己感到自豪而感到自豪,因为他做出了使Jelly使用超过10个字节的挑战。
clismique

13

朱莉娅,52 48字节

x->[n÷φ|(5n^2|4∈(2:3n).^2)for| =(+,-),n=1:x]

在线尝试!

背景

关于霍夫施塔特的已婚函数中,作者表明

F/M formula

其中φ表示黄金分割率

delta/epsilon formula

˚F Ñ表示Ñ 斐波那契数

此外,在“ 高级问题和解决方案”中,H-187:斐波那契是一个正方形,提议者表明

Fibonacci/Lucas identity

其中L n表示第n 卢卡斯数,反之,如果

converse Fibonacci/Lucas identity

那么n是斐波那契数,m是卢卡斯数。

据此,我们推断

delta/epsilon theorem

每当n> 0时

怎么运行的

给定输入X,我们构造了一个2通过X矩阵,其中| 是除了在第二的第一列和减法,以及Ñ遍历之间整数1行中 x

F(n-1)M(n-1)的第一项很简单n÷φ

我们通过计算5n²|来计算δ(n)ε(n)。4并测试结果是否属于23n之间的整数的平方数组。这既为矩形,并且由于试验1不在范围内,n> 1时,如果| 是减法。

最后,我们5n^2|4∈(2:3n).^2对先前计算出的整数进行加法或减法运算得到的布尔值。


可以用非递归/迭代的方式表示吗?封闭形式是什么?
2016年

我添加了一个解释。
丹尼斯

11

Python 2,79 70字节

a=0,;b=1,
exec"a,b=b,a+(len(a)-b[a[-1]],);"*~-input()*2
print b,'\n',a

迭代而不是递归,因为为什么不这样做。第一行有一个尾随空格-如果不行的话,可以固定一个额外的字节。-9个字节感谢@Dennis。

以下是一些合并的lambda并没有真正帮助:

f=lambda n,k:n and n-f(f(n-1,k),k^1)or k
f=lambda n,k:[k][n:]or f(n-1,k)+[n-f(f(n-1,k)[-1],k^1)[-1]]

两者都使用n和一个参数k(0或1),指定了男性/女性。第一个lambda返回第n个元素,第二个lambda返回前n个元素(具有指数运行时间)。


9

MATL,23字节

1Oiq:"@XJth"yy0)Q)_J+hw

在线尝试!

说明

这迭代地工作。每个序列都保存在一个数组中。对于每个索引n,将计算每个序列的新项并将其附加到相应的数组。使用for具有N -1个项的循环,其中N是输入数。

序列M的更新需要首先完成。这是因为对于相同的索引,序列F始终大于或等于序列M,因此,如果我们首先尝试更新F,则需要尚未计算的M项。

两个更新方程式在F和M上是相同的。因此,通过应用for带有两次迭代的循环并交换堆栈中的序列,可以重用用于更新的代码。

1        % Push 1: seed for F sequence
O        % Push 0: seed for M sequence
iq:      % Input N. Generate range [1 2 ... N-1]
"        % For each (i.e. iterate N-1 times)
  @      %   Push current index, n (starting at 1 and ending at N-1)
  XJ     %   Copy to clipboard J
  th     %   Duplicate and concatenate. This generates a length-2 array
  "      %   For each (i.e. iterate twice)
    yy   %   Duplicate top two elements, i.e. F and M sequences
    0)   %     In the *first* iteration: get last entry of M, i.e M(n-1)
    Q)   %     Add 1 and index into F. This is F(M(n-1))
    _J+  %     Negate and add n. This is n-F(M(n-1)), that is, M(n)
    h    %     Concatenate to update M
    w    %     Swap top two elements, to bring F to top.
         %     In the *second* iteration the procedure is repeated to update F,
         %     and then the top two elements are swapped to bring M to top again,
         %     ready for the next iteration of the outer loop
         %   End for implicitly
         % End for implicitly
         % Display implicitly from bottom to top: first line is F, second is M

6

J,47个字节

f=:1:`(-m@f@<:)@.*
m=:0:`(-f@m@<:)@.*
(f,:m)@i.

使用递归定义。前两行定义动词fm分别代表女性和男性功能。最后一行是动词,它带有一个参数n并输出第一行n雌性和雄性序列项。

用法

   (f,:m)@i. 5
1 1 2 2 3
0 0 1 2 2
   (f,:m)@i. 10
1 1 2 2 3 3 4 5 5 6
0 0 1 2 2 3 4 4 5 6

6

JavaScript(ES6),75个字节

g=n=>--n?([f,m]=g(n),m=[...m,n-f[m[n-1]]],[[...f,n-m[f[n-1]]],m]):[[1],[[0]]

如果允许我首先返回Male序列,则可以节省2个字节:

g=n=>--n?([f,m]=g(n),[m=[...m,n-f[m[n-1]]],[...f,n-m[f[n-1]]]]):[[1],[[0]]

6

Haskell,57个字节

l#s=scanl(\a b->b-l!!a)s[1..]
v=w#1
w=v#0
(<$>[v,w]).take

用法示例:(<$>[v,w]).take $ 5->[[1,1,2,2,3],[0,0,1,2,2]]

辅助函数#将构建一个包含起始值的无限列表s和一个l用于查找所有其他元素的列表(位于前一个值的索引处)。v = w#1是男性和w = v#0女性序列。在主函数中,我们采取的第一个n两元素vw


4

Python 2,107个字节

F=lambda n:n and n-M(F(n-1))or 1
M=lambda n:n and n-F(M(n-1))
n=range(input())
print map(F,n),'\n',map(M,n)

在线尝试

输入值较大会导致RuntimeError(递归过多)。如果这是一个问题,我可以编写一个不会发生错误的版本。



3

Pyth,24个字节

reduce减少字节数可能是不可能的。

简单实施。

L&b-b'ytbL?b-by'tb1'MQyM

在线尝试!

怎么运行的

L&b-b'ytb  defines a function y, which is actually the male sequence.

L          def male(b):
 &b            if not b: return b
   -b          else: return b-
     'ytb            female(male(b-1))


L?b-by'tb1 defines a function ', which is actually the female sequence.

L          def female(b):
 ?b            if b:
   -by'tb          return b-male(female(b-1))
         1     else: return 1


'MQ        print(female(i) for i from 0 to input)
yMQ        print(male(i) for i from 0 to input)

我是否在排行榜中包含字母缩写的名称或您的原始姓名?而且,对于Pyth程序,此代码非常长。
clismique '16

你来这里多久了...你怎么知道我改了名字?把我的新名字放在那里。
Leaky Nun

1
我到这里已经足够长的时间了,知道你改了名字。
clismique '16

@DerpfacePython看到其他答案的时间几乎是原来的4倍...我想说我的解决方案不是很长。
Leaky Nun

的确是这样,但是与其他Pyth程序相比,它还有其他问题。
clismique '16

3

Brachylog,65个字节

:{:1-:0re.}fL:2aw,@Nw,L:3aw
0,1.|:1-:2&:3&:?--.
0.|:1-:3&:2&:?--.

我尝试将男性和女性谓词组合为一个,实际上使代码更长了。

您可以使用以下具有相同字节数的衬纸:

:{:1-:0re.}fL:{0,1.|:1-:2&:3&:?--.}aw,@Nw,L:{0.|:1-:3&:2&:?--.}aw

注意:这适用于Prolog编译器,而不是旧的Java。

说明

主要谓词:

:{:1-:0re.}fL                Build a list L of integers from 0 to Input - 1
             :2aw            Apply predicate 2 to each element of L, write the resulting list
                 ,@Nw        Write a line break
                     ,L:3aw  Apply predicate 3 to each element of L, write the resulting list

谓词2(女):

0,1.                         If Input = 0, unify Output with 1
    |                        Else
     :1-                     Subtract 1 from Input
        :2&                  Call predicate 2 with Input - 1 as argument
           :3&               Call predicate 3 with the Output of the previous predicate 2
              :?-            Subtract Input from the Output of the previous predicate 3
                 -.          Unify the Output with the opposite of the subtraction

谓词3(男):

0.                           If Input = 0, unify Output with 0
  |                          Else
   :1-                       Subtract 1 from Input
      :3&                    Call predicate 3 with Input - 1 as argument
         :2&                 Call predicate 2 with the Output of the previous predicate 3
            :?-              Subtract Input from the Output of the previous predicate 3
               -.            Unify the Output with the opposite of the subtraction

等等...哪个谓词3?
clismique '16

@DerpfacePython糟糕,已修复。另请注意,谓词一个是{:1-:0re.},用于创建范围列表。
致命

3

Clojure中,132个 131字节

(fn [n](loop[N 1 M[0]F[1]](if(< N n)(let[M(conj M(- N(F(peek M))))F(conj F(- N(M(peek F))))](recur(inc N)M F))(do(prn F)(prn M)))))

只需从零到n迭代地构建序列即可。

非高尔夫版本

(fn [n]
  (loop [N 1 M [0] F [1]]
    (if (< N n)
      (let [M (conj M (- N (F (peek M))))
            F (conj F (- N (M (peek F))))]
        (recur (inc N) M F))
      (do
        (prn F)
        (prn M)))))

很好的答案,欢迎光临本站!是否需要尾随空格或换行符?我指的是131 +尾随空格。
DJMcMayhem

不,不需要尾随空格。偷偷摸摸的vim在末尾添加了换行符,以便wc计数。
2016年

3

Pyth,23个字节

jCuaG-LHtPs@LGeGr1Q],1Z

在线尝试:演示

说明:

jCuaG-LHtPs@LGeGr1Q],1Z

  u                ],1Z    start with G = [[1, 0]]
                           (this will be the list of F-M pairs)
  u             r1Q        for each H in [1, 2, ..., Q-1]:
              eG              take the last pair of G [F(H-1), M(H-1)]
           @LG                lookup the pairs of these values:
                              [[F(F(H-1)), M(F(H-1))], [F(M(H-1)), M(M(H-1))]]
          s                   join them:
                              [F(F(H-1)), M(F(H-1)), F(M(H-1)), M(M(H-1))]
        tP                    get rid of the first and last element:
                              [M(F(H-1)), F(M(H-1))]
     -LH                      subtract these values from H
                              [H - M(F(H-1)), H - F(M(H-1))]
   aG                         and append this new pair to G
jC                         at the end: zip G and print each list on a line

使用函数而不是reduce的替代解决方案(也是23个字节):

L?>b1-LbtPsyMytb,1ZjCyM

真好 的确很好。
Leaky Nun

3

Ruby,104 92 97 82字节

f=->n,i{n>0?n-f[f[n-1,i],-i]:i>0?1:0}
->n{[1,-1].map{|k|p (0...n).map{|i|f[i,k]}}}

编辑: f并且m现在是其中一项功能,这归功于HopefullyHelpful。我改变了第二功能打印f,然后m。之后的空白p很重要,否则将打印函数(0...n)而不是结果map

第三个函数首先打印的前n个项f的数组,然后打印的前n个项的数组m

这些函数的调用方式如下:

> f=->n,i{n>0?n-f[f[n-1,i],-i]:i>0?1:0}
> s=->n{[1,-1].map{|k|p (0...n).map{|i|f[i,k]}}}
> s[10]
[1, 1, 2, 2, 3, 3, 4, 5, 5, 6]
[0, 0, 1, 2, 2, 3, 4, 4, 5, 6]

您可以删除p和parens。不需要打印输出。另外,您可以在范围内进行dorp parens。
并不是说查理

您可以将2函数替换为具有2个参数的1 ni n>0?n-f(f(n-1,i),-i):i>0?1:0
HopefulHelpful

@HopefullyHelpful感谢一堆:D
Sherlock9

@NotthatCharles是否不需要打印输出?在Ruby中,如果要在f和之间换行m,则需要打印它。否则,我将得到一个像[[1, 1, 2, 2, 3, 3, 4, 5, 5, 6], [0, 0, 1, 2, 2, 3, 4, 4, 5, 6]]
Sherlock9

哦,它确实说“换行”。太糟糕了。
并不是说查理

3

APL(Dyalog Unicode)45 25字节

匿名默认功能。Requires ⎕IO←0,这是许多APL系统上的标准配置。

1 0∘.{×⍵:⍵-(~⍺)∇⍺∇⍵-1⋄⍺}⍳

在线尝试!

这是通过将FM组合成一个带有二元布尔型左参数的二元函数来进行工作的,该布尔左参数选择要应用的函数。我们为F使用1,为M使用0,以便可以将此选择器用作F  (0)和M  (0)的返回值。然后,我们观察到两个函数都需要先调用它们(在参数减去一个时),然后再在其结果上调用另一个函数,因此首先我们使用给定的选择器,然后使用逻辑取反的选择器进行递归。

ɩ ndices; 通过参数减零减一

1 0∘.{} 外部(笛卡尔)“乘积”(但使用下面的函数代替乘法),将其[1,0]用作左参数(),将索引用作右参数():

×⍵ 如果正确的论点严格为正(照亮正确的论点的符号):

  ⍵-1 从正确的参数中减去1

  ⍺∇ 调用self,将其作为右参数,将左参数作为左参数

  (~⍺)∇ 调用self作为右arg,将左arg的逻辑取反作为左arg

  ⍵- 从正确的参数中减去该值并返回结果

 其他:

   返回左参数


效果很好,但是默认情况下不允许输入存储在变量中。
丹尼斯,

@丹尼斯这不是真的。它是一个tfn主体。当我刚来这里时,ngn告诉我我不必计算tfn标头(这将是两个字节,一个单字符名称+一个换行符,就像不计算源文件名一样,并且允许匿名fns所以太这里,这里头有1名字符+空格+ 1-char参数名称(n)+加一个换行符。
亚当

tfn到底是什么?
丹尼斯

@Dennis Tfns是功能的传统APL表示。由几乎没有dfns限制的代码行组成。例如,您可以具有适当的控制结构和表达式,但没有结果。行“ 0”是指示fn 语法的标头。
阿达姆,2013年

2

ES6,89 85 83字节

@Bálint节省了2个字节

x=>{F=[n=1],M=[0];while(n<x){M.push(n-F[M[n-1]]);F.push(n-M[F[n++-1]])}return[F,M]}

天真的实现。

说明:

x => {
    F = [n = 1], //female and term number
    M = [0]; //male
    while (n < x) {
        M.push(n - F[M[n - 1]]); //naïve
        F.push(n - M[F[n++ - 1]]); //post-decrement means n++ acts as n in the calculation
    }
    return [F, M];
}

I think you can make it an anonymus function, and replace the &&-s with &
Bálint

You can't, && short-circuits, which is wanted, but I removed it anyway because brace syntax is equally short anyway
ASCII-only

Then you could do`F=[n=1]
Bálint

2

Mathematica, 69 62 bytes

Thanks to Sp3000 for suggesting a functional form which saved 14 bytes.

k_~f~0=1-k
k_~f~n_:=n-f[1-k,f[k,n-1]]
Print/@Array[f,{2,#},0]&

This defines a named helper function f and then evaluates to an unnamed function which solves the actual task of printing both sequences.


2

Perl 5.10, 85 80 bytes

Meh, dunno if I have more ideas to golf this down...

@a=1;@b=0;for(1..<>-1){push@a,$_-$b[$a[$_-1]];push@b,$_-$a[$b[$_-1]]}say"@a\n@b"

Try it online !

I had to add use 5.10.0 on Ideone in order for it to accept the say function, but it doesn't count towards the byte count.

It's a naive implementation of the algorithm, @a being the "female" list and @b the "male" list.

Crossed-out 85 is still 85 ?


Explanation, please?
clismique

Pretty much the same as my JS answer
ASCII-only

@DerpfacePython It's a naive implementation actually. :)
Paul Picard

I haven't tested, but I don't think you should need the parentheses around each pushed term, nor the final semicolon before the close-brace.
msh210

@msh210 Indeed, forgot about this. Saves 5 bytes in total, thanks!
Paul Picard

2

Java, 169 bytes total

int f(int n,int i){return n>0?n-f(f(n-1,i),-i):i>0?1:0;}void p(int n,int i){if(n>0)p(n-1,i);System.out.print(i==0?"\n":f(n,i)+" ");}void p(int n){p(n,1);p(0,0);p(n,-1);}

F(), M() 56 bytes

int f(int n,int i){
    return n>0?n-f(f(n-1,i),-i):i>0?1:0;
}

recursive-for-loop and printing 77 Bytes

void p(int n,int i) {
    if(n>0) {
        p(n-1,i);
    }
    System.out.print(i==0?"\n":f(n,i)+" ");
}

outputting the lists in two different lines 37 Bytes

void p(int n) {
    p(n,1);
    p(0,0);
    p(n,-1);
}

input : p(10)
output :

1 1 2 2 3 3 4 5 5 6 6 7 8 8 9 9 
0 0 1 2 2 3 4 4 5 6 6 7 7 8 9 9

1

C, 166 Bytes

#define P printf
#define L for(i=0;i<a;i++)
f(x);m(x);i;c(a){L P("%d ",f(i));P("\n");L P("%d ",m(i));}f(x){return x==0?1:x-m(f(x-1));}m(x){return x==0?0:x-f(m(x-1));}

Usage:

main()
{
    c(10);
}

Output:

1 1 2 2 3 3 4 5 5 6
0 0 1 2 2 3 4 4 5 6

Ungolfed (331 Bytes)

#include <stdio.h>

int female(int x);
int male(int x);
int i;
int count(a){
    for(i=0;i<a;i++){
        printf("%d ",female(i));
    }
    printf("\n");
    for(i=0;i<a;i++){
        printf("%d ",male(i));
    }
}
int female (int x){
    return x==0?1:x-male(female(x-1));
}
int male(x){
    return x==0?0:x-female(male(x-1));
}
int main()
{
    count(10);
}

0

8th, 195 bytes

Code

defer: M
: F dup not if 1 nip else dup n:1- recurse M n:- then ;
( dup not if 0 nip else dup n:1- recurse F n:- then ) is M
: FM n:1- dup ( F . space ) 0 rot loop cr ( M . space ) 0 rot loop cr ;

Usage

ok> 5 FM
1 1 2 2 3 
0 0 1 2 2 

ok> 10 FM
1 1 2 2 3 3 4 5 5 6 
0 0 1 2 2 3 4 4 5 6 

Explanation

This code uses recursion and deferred word

defer: M - The word M is declared to be defined later. This is a deferred word

: F dup not if 1 nip else dup n:1- recurse M n:- then ; - Define F recursively to generate female numbers according definition. Please note that M has not yet been defined

( dup not if 0 nip else dup n:1- recurse F n:- then ) is M - Define M recursively to generate male numbers according definition

: FM n:1- dup ( F . space ) 0 rot loop cr ( M . space ) 0 rot loop cr ; - Word used to print sequences of female and male numbers

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.