Inverter a polaridade


12

O objetivo deste desafio é escrever um programa que atenda às seguintes condições:

  • O programa não é palíndrico ou essencialmente palíndrico (o que significa que é possível remover caracteres para torná-lo um palíndromo sem alterar os efeitos do programa).

  • O programa não é uma involução (o que significa que ele não produz sua entrada original quando executado em sua saída)

  • O programa de polaridade reversa é o inverso do programa normal; portanto, quando o programa invertido é executado na saída do programa normal, ele retorna a entrada original.

O que significa polaridade reversa ? Bem, difere entre os idiomas.

  • Para a maioria dos não-esolangs, isso significa reverter a ordem das sub-operações em uma única operação, reverter a ordem dos argumentos e reverter o conteúdo de listas / matrizes / matrizes / tuplas / dicionários / pilhas / filas / etc como reverter a ordem dos blocos de código e linhas independentes (mas não as linhas dentro dos blocos)

Exemplos:

Haskell : x`mod`y-> y`mod`x; zipWith ((*3).(+)) [1,2,3] [4,5,6]->zipWith ((+).(*3)) [6,5,4] [3,2,1]

Python : 2**3-> 3**2; for x,y in [(1,2),(3,4),(5,6)]->for y,x in [(6,5),(4,3),(2,1)]

  • Para idiomas que possuem funções de 1 caractere (como Pyth, APL), basta inverter a sequência de instruções

  • Para esolangs unidimensionais como BF, inverta as instruções ou troque a polaridade; os swaps de polaridade são []-> {}, +-> -, --> +, >-> <, <-> >, .-> ,e ,-> .(mas não ambos)

  • Para esolangs bidimensionais como o Befunge, você pode realizar uma reflexão nos eixos x ou y ou uma diagonal, girar 180 graus ou fazer uma combinação de reflexão e rotação

As operações comutativas são permitidas, mas as palindrômicas não: 2*xsão boas, mas x+xsão ruins. A definição de inversão de polaridade é bastante vaga, mas use seu julgamento quanto ao que faz sentido; o objetivo não é encontrar a brecha mais inteligente, mas encontrar a solução mais inteligente.

Este é um concurso de popularidade; portanto, uma brecha muito inteligente pode ser popular, mas tente manter o espírito desse desafio. O vencedor será anunciado assim que houver pelo menos 10 soluções com pelo menos 1 voto positivo e houver pelo menos uma solução com mais votos positivos do que os envios com pelo menos 1 voto positivo; ou em um mês, o que ocorrer primeiro. Este é o meu primeiro desafio, portanto, tente ser justo e me dê um feedback construtivo, mas também deixe-me saber se esse é um desafio irracional ou se é de alguma forma miscategorizado ou ambíguo. Se você tiver perguntas sobre um idioma que não se encaixa em nenhum dos pombos que estabeleci aqui, comente e me inclinarei à vontade da comunidade se houver um forte clamor por algum esclarecimento ou alteração de regra em particular.

ATUALIZAR

Faz exatamente 1 mês desde que o concurso foi iniciado (por acaso, eu o verifiquei por acaso, sem saber que estava na hora certa). Como este é um concurso de popularidade, o vencedor (por um deslizamento de terra) é Pietu1998-Befunge . Mesmo que os componentes inferiores (o inversor de texto e o alfabeto reverso) sejam involuções, o codificador / decodificador não é, portanto não há problema nisso. Pontos de bônus (em minha mente) por conseguir escrever "BEFUNGE" no meio. Pessoalmente, gostei da novidade da solução Theseus de Zgarb , porque o idioma parece legal (se restrito). Agradeço a todos pela participação e, embora o vencedor tenha sido escolhido, deixo este concurso completamente aberto e recebo inscrições futuras.


1
O que você quer dizer com programa de polaridade reversa é o inverso do programa normal? A saída difere de alguma forma?
Sp3000 18/11/2014

Realiza a operação inversa; quando o programa invertido é executado na saída do programa normal, ele retorna a entrada original.
Archaephyrryx

Desculpe pelo erro; Eu nunca tinha ouvido falar disso antes, e me pareceu um pouco grotesco, então devo ter assumido que era um Esolang; Eu vou mudar isso.
Archaephyrryx

1
Apenas algo que provavelmente deveria ser especificado - é ()palindrômico? Tecnicamente, o inverso é )(.
Sp3000

1
No exemplo de Haskell, por que o argumento da função não é embaralhado até o fim? Os reversos são escolhidos de forma a preservar a segurança do tipo? Podemos escolher alguns detalhes da operação de inversão de polaridade?
John Dvorak

Respostas:


41

Befunge

Uau, isso foi um trabalho, mesmo com o editor que fiz para esse desafio. Aqui está o que eu recebi, um bom bloco 11x12:

v$,g6<6g,$v
v,$ _^_ $,v
1W>v\B\v>L1
~T+:1E1:-O~
+F00-F-02L+
>:|6gUg6|:>
{a@>^N^>@z`
>1+|@G$| +>
:^9< E<  ^1
~>7^@_,#:>:
 xD>65 ^=P~
v,-\+**<  v

Faz algumas coisas, infelizmente apenas para letras minúsculas.

O que faz

Quando executado normalmente, ele executa uma cifra de César na entrada.

abcxyz      -> bcdyza
exampletext -> fybnqmfufyu

Quando invertido horizontalmente, inverte a referida cifra. Este é o requisito para o desafio, mas não termina aqui.

bcdyza      -> abcxyz
fybnqmfufyu -> exampletext

Quando invertida na vertical , codifica a entrada com um alfabeto reverso. Isso pode ser considerado a abordagem oposta à cifra de César.

abcxyz      -> zyxcba
exampletext -> vcznkovgvcg

Finalmente, quando girado em 180 graus, ele reverte a entrada. Tenho a sensação de que tem que ser o inverso de alguma coisa (dica: a entrada).

abcxyz      -> zyxcba
exampletext -> txetelpmaxe

Como funciona

O bloco consiste basicamente em quatro algoritmos semi-sobrepostos.

Codificador de cifras Caesar

v$,g6<
v,$ _^
1 >v\
~ +:1
+ 00-
>:|6g
{a@>^

Decodificador de cifras de César (invertido horizontalmente)

v$,g6<
v,$ _^
1 >v\
~ -:1
+ 20-
>:|6g
`z@>^

Cifra reversa do alfabeto (invertida verticalmente)

v,-\+**<
   >65 ^
~>7^
:^9<
>1+|@
   >^

Reversor de texto (girado 180 graus)

v  <
~      
:>:#,_@
1^  <
>+ |$
   >^

2
Suponho que o Befunge tenha uma pequena vantagem aqui, porque você sempre pode usar o quadrante superior esquerdo e ignorar completamente o que está no restante do código. Bom trabalho!
Martin Ender

1
Uau! TENHO que aprovar isso, mesmo que isso signifique que eu caia para o terceiro lugar.
Level River St

18

Brainfuck, 5

,+.-,

Possivelmente pela primeira vez, Brainfuck produz uma resposta que é competitiva no tamanho do código. Pena que não é uma questão de código de golfe.

Insere um byte (caractere), incrementa e gera o resultado. A vírgula no final está aguardando outra entrada que, se fornecida, será ignorada. Não há nada na especificação sobre o término adequado: -) *

* (ou sobre fazer algo útil com todo o código nas duas direções)

Resultados típicos (o segundo caractere, se dado, é ignorado).

Avançado: B->C

Reverso: B-> Aou C->B


11

Marbelous

Aqui é simples para começar. Ele lê um caractere de STDIN, incrementa e imprime.

--
]]
00
]]
++

Se girarmos isso em 180 ° (sem trocar parênteses) ou espelhá-lo no eixo x, obteremos

++
]]
00
]]
--

que lê um byte de STDIN e o diminui.

Você pode testá-lo aqui .

Talvez eu veja alguns programas Marbelous mais complicados, mas tenho certeza de que o es1024 vai me levar a sério. ;)

Explicação

O 00é um mármore com valor 0 (que é arbitrário). Os ]]dispositivos leem um byte de STDIN - ou seja, se um mármore cair através deles, o valor do mármore será alterado para o byte de leitura. Os dispositivos ++e --simplesmente aumentam ou diminuem o valor de uma bola de gude (mod 256) e a deixam cair. Quando um mármore cai do quadro, o byte é gravado em STDOUT.

Portanto, os dois dispositivos na parte superior são simplesmente ignorados porque o fluxo de controle nunca os atinge.


Como alternativa, você pode substituir suas três linhas do meio por um único dispositivo de entrada.
overactor

@overactor Ou você quer dizer }0e usá-lo como subboard?
Martin Ender

}0como uma entrada de linha de comando para ser mais preciso.
overactor

5

Marbelous

Este fórum pega um argumento ( x) e retorna (101 * x) mod 256.

.. @5 .. }0 }0 @1 .. @0 .. @2 .. 
.. /\ Dp << \\ .. &0 >0 &1 .. .. 
!! @3 .. << }0 .. \/ -- \/ .. }0 
@4 .. .. &0 @1 /\ &0 65 &1 /\ @2 
/\ Dp .. @4 .. .. @3 @0 @5 !! \\

O espelhamento das células ao longo do eixo y resultará em uma placa que recebe um argumento ( y) e retorna (101 * y + 8 * y) mod 256, que é o inverso da primeira placa.

.. @2 .. @0 .. @1 }0 }0 .. @5 ..
.. .. &1 >0 &0 .. \\ << Dp /\ ..
}0 .. \/ -- \/ .. }0 << .. @3 !!
@2 /\ &1 65 &0 /\ @1 &0 .. .. @4
\\ !! @5 @0 @3 .. .. @4 .. Dp /\

Teste isso aqui . Placas cilíndricas e bibliotecas de inclusão devem ser verificadas.

Exemplo de entrada / saída :

Original Board:      Mirrored Board:
Input   Output       Input    Output
025     221          221      025
042     146          146      042
226     042          042      226

Observe que o Marbelous apenas permite a passagem de números inteiros positivos como argumentos, e esses números inteiros são passados ​​para o módulo módulo 256 pelo intérprete.

101foi escolhido por duas razões: é primo (e todas as entradas possíveis para este programa resultam em uma saída única) e a operação inversa envolvida 109, que fica a uma distância conveniente de 8 de distância 101.

Breve explicação

A coluna que contém as células (de cima para baixo) @0 >0 -- 65 @0executa o mesmo em ambas as placas e faz um loop dos 101tempos antes de ir para a direita. Nos dois lados da >0ramificação há um sincronizador diferente; qual é escolhido depende se o quadro é espelhado ou não.

Em cada lado, em sincronia com o loop central, a entrada é somada repetidamente, obtendo-se assim 101*x mod 256. Na placa invertida, duas cópias da entrada também são deslocadas um pouco duas vezes para a esquerda ( input * 4), somadas e deixadas em um sincronizador.

Depois que o loop central termina, as bolinhas somadas são enviadas para impressão, que fica ao lado do quadro (esquerda para o quadro original, direita para espelhado). Após a impressão, uma !!célula é atingida, finalizando o quadro. Observe que o loop fornecido 101 * xcontinua sendo executado sozinho até que a placa seja finalizada.

Dp simplesmente imprime o resultado como um número decimal.


5

Teseu

Isso pode ser considerado uma brecha, mas eu gosto do idioma, então aqui vai. Este programa define uma função fem números naturais que mapeia 3n a 3n + 1 , 3n + 1 a 3n + 2 e 3n + 2 a 3n , para cada n .

data Num = Zero | Succ Num

iso f :: Num <-> Num
  | n                          <-> iter $ Zero, n
  | iter $ m, Succ Succ Succ n <-> iter $ Succ m, n
  | iter $ m, Succ Succ Zero   <-> back $ m, Zero
  | iter $ m, Succ Zero        <-> back $ m, Succ Succ Zero
  | iter $ m, Zero             <-> back $ m, Succ Zero
  | back $ Succ m, n           <-> back $ m, Succ Succ Succ n
  | back $ Zero, n             <-> n
  where iter :: Num * Num
        back :: Num * Num

Theseus é uma linguagem reversível com uma sintaxe semelhante a Haskell, onde todas as funções são invertíveis (descontando problemas com a não terminação). É altamente experimental e projetado para fins de pesquisa. O código acima define um tipo de dados para números naturais e a função f. Dado um número de entrada, você faz a correspondência padrão no lado esquerdo (ele sempre corresponde n). Então você olha para o padrão à direita. Se esse padrão tiver um rótulo (aquiiter), prossiga para a correspondência de padrões no lado esquerdo e, novamente, pegue o valor correspondente no lado direito. Isso se repete até que você tenha um valor não marcado à direita, e essa é a sua saída. Os padrões à esquerda e à direita devem ser exaustivos e sem sobreposição (separadamente para cada etiqueta). Agora, para "reverter a polaridade" de f, faço o seguinte.

  • Troque os dois valores de cada rótulo. Isso não altera a semântica de f.
  • Troque os lados direito e esquerdo do corpo da função. Isso define a função inversa de f por design .

O resultado:

iso f :: Num <-> Num
  | iter $ n, Zero             <-> n
  | iter $ n, Succ m           <-> iter $ Succ Succ Succ n, m
  | back $ Zero, m             <-> iter $ Succ Succ Zero, m
  | back $ Succ Succ Zero, m   <-> iter $ Succ Zero, m
  | back $ Succ Zero, m        <-> iter $ Zero, m
  | back $ Succ Succ Succ n, m <-> back $ n, Succ m
  | n                          <-> back $ n, Zero
  where iter :: Num * Num
        back :: Num * Num

3

tr

a b

Exemplo:

$ echo "apple" | tr a b
bpple
$ echo "bpple" | tr b a
apple

Somente um verdadeiro inverso no domínio de strings que não inclui 'a' e 'b'.


Você realmente precisa restringir o domínio um pouco mais do que isso. Por exemplo, se você começar com "bog", seu programa e seu inverso fornecerão "bog" -> "bog" -> "aog". Portanto, qualquer string contendo 'b' é um problema (ou contém 'a', se você aplicar o programa inverso primeiro).
precisa saber é o seguinte

Você pode usar tr abc bcacom a versão de polaridade reversa tr acb cba.
Christian Sievers

2

Outra resposta Marbelous

A direita original muda a entrada da linha de comando (um valor de 8 bits), adicionando uma inicial se um 1 for perdido pela mudança. ( 0000 0001 -> 1000 0000)

{0 ..
~~ ..
>> {0
-2 =0
.. ^0
\/ }0
}0 Sb
<< ..
\\ ..
:Sb
// ..
Sb >>
}0 ..
^7 }0
{0 \/

Girando esta placa em 180 ° (mas deixando o conteúdo de cada célula igual) Altera o programa para que fique à esquerda ( 1000 0000 -> 0000 0001)

\/ {0
}0 ^7
.. }0
>> Sb
.. //
:Sb
.. \\
.. <<
Sb }0
}0 \/
^0 ..
=0 -2
{0 >>
.. ~~
.. {0

Você pode testá-lo aqui . (você precisará ativar 'Exibir saída como números decimais')

Explicação

Ambos os programas consistem em duas placas, a placa principal (que recebe a entrada da linha de comando) e Sb. Vamos dar uma olhada nas duas versões da placa principal, observando apenas as células que podem ser alcançadas em suas respectivas orientações (já que os mármores normalmente não podem subir e os dispositivos de entrada não estão no topo):

original:      flipped:
   }0          }0
}0 Sb          .. }0
<< ..          >> Sb
\\ ..          .. //

Essas são placas bem diretas, ambas pegam duas cópias da entrada (que substituem as }0células. O original alimenta uma versão em um dispositivo de mudança à esquerda, <<a versão invertida o coloca em um dispositivo de mudança à direita. >>Eles executam um deslocamento de bits, mas infelizmente descartam qualquer que é onde as Sbplacas entram, eles verificam se a mudança de bits do valor que eles alimentam resultará na perda de um pouco e retornará um valor a ser adicionado ao resultado para neutralizar o bit perdido.

Aqui está a parte relevante da Sbplaca original para o programa original:

}0
^7
{0

Este é incrivelmente fácil, `^ 7 'verifica o valor do bit mais significativo. Se este for 1, executar um deslocamento para a esquerda causaria a perda desse bit. Portanto, esta placa gera o valor desse bit como um valor de 8 bits a ser adicionado ao resultado do deslocamento de bits.

Para a versão invertida, Sbé necessário olhar o bit menos significativo e retornar 128ou 0, isso é um pouco mais complicado:

}0
^0 ..
=0 -2
{0 >>
.. ~~
.. {0

Se o bit menos significativo (conforme testado por ^0) for 0, ele retornará 0. Se for um, ^0será exibido 1. Isso falhará no teste de igualdade 0 =0e, portanto, será empurrado para a direita. Em seguida, subtraímos 2 -2para obter 255, shift >>para esquerda para 127 e executamos um binário ~~para não obter 128 (também poderíamos simplesmente adicionar um ++para obter 128, mas qual é a graça nisso?)

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.