Sequências femininas e masculinas


20

Essa pergunta é provavelmente mais difícil do que todas as tarefas "geram uma sequência de números", porque isso exige DUAS sequências trabalhando em uníssono.

Realmente ansioso pelas respostas!

Em seu livro " Gödel, Escher, Bach: uma eterna trança de ouro ", Douglas Hofstadter tem algumas seqüências de números, todas elas de alguma forma dependem do termo anterior. Para informações sobre todas as seqüências, consulte esta página da Wikipedia .

Um par de sequências que é realmente interessante são as sequências Feminino e Masculino, que são definidas assim:

para n > 0.

Aqui está a sequência feminina e a sequência masculina .

Sua tarefa é, ao receber um número inteiro ncomo entrada, retornar uma lista da sequência Feminino e da sequência Masculino, com a quantidade de termos igual a n, em duas linhas de saída, com a sequência Feminino na primeira linha e a sequência Masculino em o segundo.

Entradas e saídas de amostra: Input: 5 Output:[1, 1, 2, 2, 3] [0, 0, 1, 2, 2]

Entrada: 10 Saída:[1, 1, 2, 2, 3, 3, 4, 5, 5, 6] [0, 0, 1, 2, 2, 3, 4, 4, 5, 6]

NOTA: A separação entre listas significa uma quebra de linha.

Isso é código-golfe, então o código mais curto em bytes vence. Além disso, insira uma explicação para o seu código.

Entre os melhores


5
Podemos retornar um par de listas de uma função, em vez de imprimir as listas?
Zgarb 25/05

Outros desafios que envolvem seqüências de Hofstadter: seqüência Q , figura-figura seqüência
Martin Ender

@ Zgarb Você pode, desde que as duas listas estejam em linhas diferentes.
Clismique 26/05

2
@DerpfacePython Não há linhas em um par de listas; se uma função retornar um par de listas, você poderá imprimi-las como quiser. Dito isto, não sou muito fã do requisito de linhas, mesmo ao imprimir a saída. Os formatos pesados ​​de E / S são uma das coisas a evitar ao escrever desafios.
Dennis

4
Não é grande coisa para algumas abordagens / idiomas, mas pode fazer uma grande diferença para outras. Em C, muitos bytes podem ser salvos imprimindo as seqüências em colunas, em vez de linhas. Em Python, a abordagem mais curta que consigo pensar é um lambda recursivo semelhante à minha resposta recursiva Julia, que retorna um par de listas, mas ter que convertê-lo em uma string com avanço de linha o torna muito mais longo, ainda mais longo que o programa completo enviado por Sp3000. Outras abordagens, como uma solução recursiva que faz a contagem regressiva em vez de cima, são completamente descartadas, pois é impossível adicionar a nova linha.
Dennis

Respostas:


3

Geléia , 22 20 bytes

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

Experimente online!

Como funciona

çƓḤ¤Ð¡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
E é nessa parte que me orgulho de fazer um desafio que faz com que Jelly use mais de 10 bytes.
Clismique 26/05

13

Julia, 52 48 bytes

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

Experimente online!

fundo

Nas funções casadas de Hofstadter , o autor mostra que

Fórmula F / M

onde φ denota a proporção áurea ,

fórmula delta / epsilon

e F n indica o n th número de Fibonacci .

Além disso, em Advanced Problems and Solutions, H-187: Fibonacci é um quadrado , o proponente mostra que

Identidade de Fibonacci / Lucas

em que L n indica o n th número Lucas , e que - por outro lado - se

inverso Identidade Fibonacci / Lucas

então n é um número de Fibonacci e m é um número de Lucas.

A partir disso, deduzimos que

teorema delta / epsilon

sempre que n> 0 .

Como funciona

Dada a entrada x , construímos uma matriz 2 por x , onde | é adição na primeira coluna e subtração na segunda e n itera sobre os números inteiros entre 1 e x nas linhas.

O primeiro termo de F (n - 1) e M (n - 1) é simples n÷φ.

Computamos δ (n) e ε (n) calculando 5n² | 4 e testando se o resultado pertence à matriz de quadrados dos números inteiros entre 2 e 3n . Isso testa a esquadria e, como 1 não está no intervalo, para n> 1 se | é subtração.

Finalmente, adicionamos ou subtraímos o Booleano resultante de 5n^2|4∈(2:3n).^2ou para o número inteiro previamente calculado.


isso pode ser expresso de maneira não-recursiva / iterativa ?, qual é a forma fechada para isso?
Abr001am

Eu adicionei uma explicação.
Dennis

11

Python 2, 79 70 bytes

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

Iterativo em vez de recursivo, porque porque não. A primeira linha tem um espaço à direita - se isso não for bom, pode ser corrigido por um byte extra. -9 bytes graças a @Dennis.

Aqui estão algumas lambdas combinadas que realmente não ajudaram:

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]]

Ambos tomam ne um parâmetro k0 ou 1, especificando masculino / feminino. O primeiro lambda retorna o enésimo elemento e o segundo lambda retorna os primeiros n elementos (com tempo de execução exponencial).


9

MATL , 23 bytes

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

Experimente online!

Explicação

Isso funciona iterativamente. Cada sequência é mantida em uma matriz. Para cada índice n, o novo termo de cada sequência é calculado e anexado à matriz correspondente. Um forloop com termos N- 1 é usado, onde N é o número de entrada.

A atualização para a sequência M precisa ser feita primeiro. Isso ocorre porque a sequência F é sempre maior ou igual à sequência M para o mesmo índice, portanto, se tentarmos atualizar F primeiro, precisaríamos de um termo de M ainda não computado.

As duas equações de atualização são as mesmas que trocam F e M. Portanto, o código para atualização é reutilizado aplicando um forloop com duas iterações e trocando as seqüências na pilha.

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 bytes

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

Usa a definição recursiva. As duas primeiras linhas definem os verbos fe mque representam as funções feminina e masculina, respectivamente. A última linha é um verbo que usa um único argumento ne gera os primeiros ntermos das seqüências feminina e masculina.

Uso

   (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 bytes

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

Eu poderia salvar 2 bytes se tivesse permissão para retornar a sequência Male primeiro:

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 bytes

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

Exemplo de uso: (<$>[v,w]).take $ 5->[[1,1,2,2,3],[0,0,1,2,2]]

A função auxiliar #cria uma lista infinita com valor inicial se uma lista lpara procurar todos os outros elementos (no índice do valor anterior). v = w#1é a w = v#0sequência feminina e masculina. Na função principal, pegamos os primeiros nelementos de ambos ve w.


4

Python 2, 107 bytes

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)

Experimente online

Valores de entrada maiores causam um RuntimeError (muita recursão). Se isso for um problema, posso escrever uma versão em que o erro não ocorra.



3

Pitão, 24 bytes

Provavelmente é impossível usar reducepara reduzir a contagem de bytes.

Implementação direta.

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

Experimente online!

Como funciona

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)

Incluo o nome anagramatizado ou o nome original no placar? Além disso, esse código é muito longo para um programa Pyth.
Clismique 25/05

Há quanto tempo você está aqui ... como você sabe que eu mudei meu nome? Coloque meu novo nome lá.
Freira Furada

1
Estou aqui há tempo suficiente para saber que você mudou seu nome.
Clismique 25/05

@DerpfacePython Vendo que outras respostas têm quase quatro vezes mais ... Eu diria que minha solução não é muito longa.
Leaky Nun

Isso é verdade, mas ainda é longo em comparação com outros programas Pyth para outras perguntas.
Clismique 25/05

3

Braquilog , 65 bytes

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

Minha tentativa de combinar os dois predicados masculino e feminino em um só tornou o código mais longo.

Você pode usar o seguinte liner com o mesmo número de bytes:

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

Nota : Isso funciona com o transpilador Prolog, não com o antigo Java.

Explicação

Predicado principal:

:{: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

Predicado 2 (feminino):

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

Predicado 3 (masculino):

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

Espere ... qual é o predicado 3?
Clismique 25/05

@DerpfacePython whoops, corrigido. Observe também que o predicado 1 é {:1-:0re.}usado para criar a lista de intervalos.
Fatalize 25/05

3

Clojure, 132 131 bytes

(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)))))

Simplesmente constrói as seqüências iterativamente de zero a n.

Versão ungolfed

(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)))))

Boa resposta, bem-vindo ao site! É necessário um espaço à direita ou nova linha? Estou contando 131 + um espaço em branco à direita.
DJMcMayhem

Não, não há necessidade de um espaço em branco à direita. Sneaky vim adicionou uma nova linha no final para wc contar.
marque

3

Pitão, 23 bytes

jCuaG-LHtPs@LGeGr1Q],1Z

Experimente online: Demonstração

Explicação:

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

Solução alternativa que usa uma função em vez de reduzir (também 23 bytes):

L?>b1-LbtPsyMytb,1ZjCyM

Agradável. Muito bom mesmo.
Freira vazando 26/05

3

Ruby, 104 92 97 82 bytes

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]}}}

Edit: f e magora são uma função graças a HopfullyHelpful . Eu mudei a segunda função para imprimir fentão m. O espaço em branco depois pé significativo, caso contrário, a função é impressa em (0...n)vez do resultado de map.

A terceira função imprime primeiro uma matriz dos primeiros n termos de f, seguida por uma matriz dos primeiros n termos dem

Essas funções são chamadas assim:

> 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]

você pode soltar op e parens. Não é necessário imprimir a saída. Além disso, você pode dorp parens ao redor do intervalo.
Não que Charles seja

você pode substituir a função 2 com 1 que tem 2 argumentos nei n>0?n-f(f(n-1,i),-i):i>0?1:0
HopefullyHelpful

Graças @HopefullyHelpful um bando: D
Sherlock9

@NotthatCharles Não é necessário imprimir a saída? No Ruby, se eu quiser que a linha quebre entre fe m, preciso imprimi-la. Caso contrário, eu apenas recebo uma matriz como[[1, 1, 2, 2, 3, 3, 4, 5, 5, 6], [0, 0, 1, 2, 2, 3, 4, 4, 5, 6]]
Sherlock9 /

oh, diz "quebra de linha". Que pena.
Não que Charles seja

3

APL (Dyalog Unicode) , 45 25 bytes

Função tácita anônima. Requer ⎕IO←0, que é padrão em muitos sistemas APL.

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

Experimente online!

Isso funciona combinando F e M em uma única função diádica com um argumento à esquerda booleano que seleciona a função a ser aplicada. Usamos 1 para F e 0 para M, para que possamos usar esse seletor como valor de retorno para F  (0) e M  (0). Observamos então que ambas as funções precisam se chamar primeiro (no argumento menos um) e depois a outra função no resultado disso; portanto, primeiro recorremos ao seletor fornecido e depois ao seletor logicamente negado.

d ndices; zero através do argumento menos um

1 0∘.{} "Produto" externo (cartesiano) (mas com a função abaixo em vez de multiplicação) usando [1,0]como argumentos à esquerda ( ) e os índices como argumentos à direita ( ):

×⍵ se o argumento correto for estritamente positivo (lit. o sinal do argumento correto):

  ⍵-1 subtrair um do argumento certo

  ⍺∇ chamar self com isso como argumento certo e o argumento esquerdo como argumento esquerdo

  (~⍺)∇ chame self com isso como arg direito e a negação lógica do arg esquerdo como arg esquerdo

  ⍵- subtraia isso do argumento correto e retorne o resultado

 outro:

   retornar o argumento esquerdo


Isso funciona bem, mas assumindo que a entrada é armazenada em uma variável é desabilitada por padrão.
Dennis

@ Dennis Na verdade, não. É um corpo tfn. Quando eu era novo aqui, o ngn me disse que não precisava contar o cabeçalho tfn (que seria de dois bytes, um nome de caractere único + uma nova linha, assim como o nome do arquivo de origem não é contado, e o fns anônimo é permitido . Assim, também aqui, onde o cabeçalho é um nome 1-char + espaço + nome de argumento 1-char ( n) + além de uma nova linha.
Adám

O que exatamente é um tfn?
267 Dennis

@ Dennis NDT são a representação APL tradicional de funções. Consistem em linhas de código com quase nenhuma das restrições do dfns . Por exemplo, você pode ter estruturas de controle adequadas e expressões sem resultado. A linha "0" é um cabeçalho que indica a sintaxe do fn .
Adám

2

ES6, 89 85 83 bytes

2 bytes salvos graças a @ Bálint

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]}

Implementação ingênua.

Explicação:

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];
}

Eu acho que você pode torná-lo uma função Anonymus, e substituir o && - s com &
Bálint

Você não pode, &&curto-circuitos, que é procurado, mas eu removido de qualquer maneira porque a sintaxe cinta é igualmente curta de qualquer maneira
ASCII-only

Então você poderia fazer`F = [n = 1]
Bálint

2

Mathematica, 69 62 bytes

Agradecemos ao Sp3000 por sugerir um formulário funcional que salvou 14 bytes.

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

Isso define uma função auxiliar nomeada fe avalia como uma função não nomeada que resolve a tarefa real de imprimir as duas seqüências.


2

Perl 5.10, 85 80 bytes

Meh, não sei se eu tenho mais idéias para jogar isso ...

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

Experimente online!

Eu tive que adicionar o use 5.10.0Ideone para que ele aceitasse a sayfunção, mas ela não conta para a contagem de bytes.

É uma implementação ingênua do algoritmo, @asendo a lista "feminina" e @ba lista "masculina".

85 riscado ainda é 85?


Explicação, por favor?
Clismique 25/05

Praticamente o mesmo que a minha resposta JS
ASCII-only

@DerpfacePython Na verdade, é uma implementação ingênua. :)
Paul Picard

Eu não testei, mas acho que você não precisa dos parênteses em torno de cada pushtermo ed, nem do ponto e vírgula final antes da chave.
Msh210

@ msh210 De fato, esqueci isso. Economiza 5 bytes no total, obrigado!
Paul Picard

2

Java, total de 169 bytes

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;
}

impressão recursiva para loop e impressão 77 bytes

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

saída das listas em duas linhas diferentes 37 bytes

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

entrada: p ( 10)
saída:

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));}

Uso:

main()
{
    c(10);
}

Saída:

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

Sem Golfe (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

8o , 195 bytes

Código

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 ;

Uso

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 

Explicação

Esse código usa recursão e palavra adiada

defer: M- A palavra Mé declarada para ser definida posteriormente. Esta é uma palavra adiada

: F dup not if 1 nip else dup n:1- recurse M n:- then ;- Defina F recursivamente para gerar números femininos de acordo com a definição. Observe que Mainda não foi definido

( dup not if 0 nip else dup n:1- recurse F n:- then ) is M- Definir M recursivamente para gerar números masculinos de acordo com a definição

: FM n:1- dup ( F . space ) 0 rot loop cr ( M . space ) 0 rot loop cr ; - Palavra usada para imprimir sequências de números femininos e masculinos

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.