Alice , 14 12 bytes
/O
\i@/t&Yd&
Experimente online!
Função inversa (sem jogar golfe):
/o Q
\i@/~~\ /dt&Z
Experimente online!
Explicação
Alice possui uma bijeção interna entre ℤ e ℤ 2 , que pode ser calculada com Y
(descompactar) e seu inverso Z
(pacote). Aqui está um trecho dos documentos que explicam a bijeção:
Os detalhes da bijeção são provavelmente irrelevantes para a maioria dos casos de uso. O ponto principal é que ele permite que o usuário codifique dois números inteiros em um e extraia os dois inteiros novamente mais tarde. Aplicando o comando pack repetidamente, listas inteiras ou árvores de números inteiros podem ser armazenadas em um único número (embora não de maneira particularmente eficiente em termos de memória). O mapeamento calculado pela operação do pacote é uma função bijetiva ℤ 2 → ℤ (ou seja, um mapeamento individual). Primeiro, os números inteiros {..., -2, -1, 0, 1, 2, ...} são mapeados para os números naturais (incluindo zero), como {..., 3, 1, 0, 2, 4 , ...}(em outras palavras, números inteiros negativos são mapeados para naturais ímpares e números inteiros não negativos são mapeados para pares naturais). Os dois números naturais são mapeados para um através da função de emparelhamento Cantor , que grava os naturais ao longo das diagonais do primeiro quadrante da grade inteira. Especificamente, {(0,0), (1,0), (0,1), (2,0), (1,1), (0,2), (3,0), ...} são mapeado para {0, 1, 2, 3, 4, 5, 6, ...} . O número natural resultante é então mapeado de volta para os números inteiros usando o inverso da bijeção anterior. O comando descompactar calcula exatamente o inverso desse mapeamento.
Como mencionado acima, podemos utilizar esta operação descompactar para mapear ℤ para ℤ k bem. Depois de aplicá-lo ao número inteiro inicial, podemos descompactar o segundo número inteiro do resultado novamente, o que nos fornece uma lista de três números inteiros. Portanto , as aplicações k-1Y
nos fornecem k números inteiros como resultado.
Podemos calcular o inverso colocando a lista Z
no final.
Portanto, o próprio programa tem essa estrutura:
/O
\i@/...d&
Este é apenas um modelo básico para um programa que lê um número variável de números inteiros decimais como entrada e imprime um número variável como resultado. Portanto, o código real é realmente apenas:
t Decrement k.
& Repeat the next command k-1 times.
Y Unpack.
Uma coisa que eu gostaria de abordar é "por que Alice teria um built-in para uma bijeção ℤ → ℤ 2 , não é esse território da linguagem do golfe"? Como na maioria dos built-ins mais estranhos de Alice, o principal motivo é o princípio de design de Alice, de que todo comando tem dois significados, um para o modo Cardinal (inteiro) e outro para o modo Ordinal (string), e esses dois significados devem estar de alguma forma relacionados a dar Cardeal e Ordinal modificam a sensação de que são universos espelhos, onde as coisas são iguais, mas também diferentes. E muitas vezes eu tinha um comando para um dos dois modos que queria adicionar e, em seguida, tive que descobrir com qual outro comando o emparelharia.
No caso de Y
e Z
modo ordinal veio primeiro: Eu queria ter uma função para intercalar duas cadeias (zip) e separá-los novamente (unzip). A qualidade disso que eu queria capturar no modo Cardinal era formar um número inteiro de dois e ser capaz de extrair os dois inteiros mais tarde, o que torna essa bijeção a escolha natural.
Também imaginei que isso seria realmente muito útil fora do golfe, porque permite armazenar uma lista inteira ou até uma árvore de números inteiros em uma única unidade de memória (elemento de pilha, célula de fita ou célula de grade).
k
e emx
vez de números inteiros?