Troque a paridade


22

Tarefa

Dado um número inteiro positivo n, a saída n+1se né ímpar e a saída n-1se né par.

Entrada

Um número inteiro positivo. Você pode assumir que o número inteiro está dentro da capacidade de manipulação do idioma.

Saída

Um número inteiro positivo, especificado acima.

Casos de teste

input output
    1      2
    2      1
    3      4
    4      3
    5      6
    6      5
    7      8
    8      7
  313    314
  314    313

Pontuação

Isso é , então a resposta mais curta em bytes vence.

Aplicam-se brechas padrão .

Referências


Podemos considerar a entrada como unária?
Kritixi Lithos

2
Surpreendentemente, isso seria muito mais fácil se fosse o contrário em alguns idiomas
MildlyMilquetoast

3
@MistahFiggins Isso é bem conhecido o suficiente para que eu tenha certeza de que o OP fez isso de propósito.
Ørjan Johansen

Respostas:


24

C, 20 bytes

f(x){return-(-x^1);}

Experimente online .


7
@LeakyNun Não estou escrevendo uma função sem uma declaração de retorno.
feersum

18
@EriktheOutgolfer Não. Não. Nuh-uh. Não.
feersum 4/17

10
@ Sisyphus Mas isso é código-golfe , e funciona no meu link TIO, por isso é válido.
Erik the Outgolfer

7
@EriktheOutgolfer O que estou dizendo é que sua declaração ("atribuir ao primeiro argumento é equivalente a uma declaração de retorno") é factualmente incorreta. Se esse código pode gerar uma resposta de trabalho sob certas circunstâncias é outra questão (que abordamos no meu primeiro comentário, afirmando que pretendo não publicar esse código).
feersum

8
@EriktheOutgolfer Se uma resposta se basear no comportamento específico da implementação, ela deverá especificar uma implementação. Esta resposta não, portanto esse código seria inválido.
Sísifo 04/04

17

Stack Cats , 3 + 3 ( -n) = 6 bytes

-*-

Experimente online!

Precisa do -nsinalizador para trabalhar com entrada e saída numéricas.

Explicação

O Stack Cats geralmente está longe de ser competitivo, por causa de seu conjunto limitado de comandos (todos eles são injeções e a maioria são involuções) e porque todo programa precisa ter simetria de espelho. No entanto, uma das involuções é alternar o bit menos significativo de um número, e podemos compensar o valor com negação unária que também existe. Felizmente, isso nos dá um programa simétrico, portanto não precisamos nos preocupar com mais nada:

-   Multiply the input by -1.
*   Toggle the least significant bit of the value (i.e. take it XOR 1).
-   Multiply the result by -1.

Entrada e saída estão implícitas no início e no final do programa, porque receber e produzir saída não é uma operação reversível, portanto, não podem ser comandos.


1
As bandeiras sempre contam com o espaço adicional, acho que não vi outras respostas usando bandeiras (como Perl) fazer isso? EDIT: Ok nvm, encontrou o meta post relevante . " Eu os considero como uma diferença na contagem de caracteres até a menor chamada equivalente sem eles. " ... " perl -nle 'stuff'tem mais 2 caracteres do que perl -e 'stuff', portanto, conta com mais 2 caracteres ". O mesmo (space)-nacontece com 3 bytes a mais do que sem a bandeira.
Kevin Cruijssen

@KevinCruijssen Depende de quantos bytes você realmente precisa adicionar a uma invocação normal. No Perl e em muitas outras linguagens de produção, você pode chamar o código com -e "code"e depois inserir sinalizadores adicionais antes do e, por exemplo -pe "code". Em seguida, o -psinalizador é de apenas um byte. No entanto, o Stack Cats não possui esse -eargumento; portanto, você sempre precisa adicionar o total <sp>-nao comando e, portanto, tem três bytes.
Martin Ender

12

Montagem x86, 9 bytes (para entrada concorrente)

Todo mundo que está tentando esse desafio em idiomas de alto nível está perdendo a verdadeira diversão de manipular bits brutos. Há tantas variações sutis nas maneiras de fazer isso, é insano - e muito divertido de se pensar. Aqui estão algumas soluções que eu criei na linguagem assembly x86 de 32 bits.

Peço desculpas antecipadamente por não ser a resposta típica do código-golfe. Vou falar muito sobre o processo de otimização iterativa (por tamanho). Espero que seja interessante e educativo para um público maior, mas se você é do tipo TL; DR, não ficarei ofendido se você pular para o final.

A solução óbvia e eficiente é testar se o valor é ímpar ou par (o que pode ser feito com eficiência observando o bit menos significativo) e depois selecionar entre n + 1 ou n-1 de acordo. Supondo que a entrada seja passada como um parâmetro no ECXregistro e o resultado seja retornado no EAXregistro, obtemos a seguinte função:

F6 C1 01  |  test  cl, 1                      ; test last bit to see if odd or even
8D 41 01  |  lea   eax, DWORD PTR [ecx + 1]   ; set EAX to n+1 (without clobbering flags)
8D 49 FF  |  lea   ecx, DWORD PTR [ecx - 1]   ; set ECX to n-1 (without clobbering flags)
0F 44 C1  |  cmovz eax, ecx                   ; move in different result if input was even
C3        |  ret

(13 bytes)

Mas, para fins de código-golfe, essas LEAinstruções não são boas, pois levam 3 bytes para codificar. Um simples DECarranjo de ECXseria muito menor (apenas um byte), mas isso afeta os sinalizadores, por isso temos que ser um pouco inteligentes na maneira como organizamos o código. Podemos fazer o decremento primeiro e o teste impar / par em segundo , mas depois temos que inverter o resultado do teste ímpar / par.

Além disso, podemos alterar a instrução de movimentação condicional para uma ramificação, o que pode tornar o código mais lento (dependendo da previsibilidade da ramificação - se a entrada alternar inconsistentemente entre ímpar e par, uma ramificação será mais lenta; se houver uma padrão, será mais rápido), o que nos salvará outro byte.

De fato, com esta revisão, toda a operação pode ser realizada no local, usando apenas um único registro. Isso é ótimo se você estiver incorporando esse código em algum lugar (e as chances são de que você seria, pois é muito curto).

    48     |  dec  eax          ; decrement first
    A8 01  |  test al, 1        ; test last bit to see if odd or even
    75 02  |  jnz  InputWasEven ; (decrement means test result is inverted)
    40     |  inc  eax          ; undo the decrement...
    40     |  inc  eax          ; ...and add 1
  InputWasEven:                 ; (two 1-byte INCs are shorter than one 3-byte ADD with 2)

(embutido: 7 bytes; como uma função: 10 bytes)

Mas e se você quisesse tornar isso uma função? Nenhuma convenção de chamada padrão usa o mesmo registro para passar parâmetros como para o valor de retorno; portanto, você precisa adicionar uma MOVinstrução de registro no início ou no final da função. Isso praticamente não tem custo em velocidade, mas adiciona 2 bytes. (A RETinstrução também adiciona um byte e há alguma sobrecarga introduzida pela necessidade de fazer e retornar de uma chamada de função, o que significa que este é um exemplo em que o inlining produz um benefício de velocidade e tamanho, em vez de ser apenas uma velocidade clássica - no comércio). No total, escrito como uma função, esse código aumenta para 10 bytes.

O que mais podemos fazer em 10 bytes? Se nos preocupamos com o desempenho (pelo menos, o desempenho previsível ), seria bom nos livrar desse ramo. Aqui está uma solução sem ramificação, com variação de bits do mesmo tamanho em bytes. A premissa básica é simples: usamos um XOR bit a bit para virar o último bit, convertendo um valor ímpar em um par e vice-versa. Mas há uma niggle - para entradas ímpares, que nos dá n-1 , enquanto para entradas pares, nos dá n + 1 - exatamente o oposto do que queremos. Portanto, para corrigir isso, executamos a operação com um valor negativo, lançando efetivamente o sinal.

8B C1     |  mov eax, ecx   ; copy parameter (ECX) to return register (EAX)
          |
F7 D8     |  neg eax        ; two's-complement negation
83 F0 01  |  xor eax, 1     ; XOR last bit to invert odd/even
F7 D8     |  neg eax        ; two's-complement negation
          |
C3        |  ret            ; return from function

(embutido: 7 bytes; como uma função: 10 bytes)

Muito liso; é difícil ver como isso pode ser melhorado. Uma coisa me chama a atenção, no entanto: essas duas NEGinstruções de 2 bytes . Francamente, dois bytes parecem um byte a mais para codificar uma simples negação, mas é com esse conjunto de instruções que temos que trabalhar. Existem soluções alternativas? Certo! Se XORpor -2, podemos substituir a segunda NEGação por um INCrement:

8B C1     |  mov eax, ecx
          |
F7 D8     |  neg eax
83 F0 FE  |  xor eax, -2
40        |  inc eax
          |
C3        |  ret

(embutido: 6 bytes; em função de 9 bytes)

Outra das peculiaridades do conjunto de instruções x86 é a LEAinstrução multiuso , que pode executar um movimento de registro e registro, uma adição de registro e registro, compensando uma constante e dimensionando tudo em uma única instrução!

8B C1        |  mov eax, ecx
83 E0 01     |  and eax, 1        ; set EAX to 1 if even, or 0 if odd
8D 44 41 FF  |  lea eax, DWORD PTR [ecx + eax*2 - 1]
C3           |  ret

(10 bytes)

A ANDinstrução é como a TESTinstrução que usamos anteriormente, em que ambos fazem AND e bit a bit de acordo, mas ANDna verdade atualizam o operando de destino. A LEAinstrução então dimensiona isso em 2, adiciona o valor original de entrada e diminui em 1. Se o valor de entrada for ímpar, isso subtrai 1 (2 × 0 - 1 = -1) dele; se o valor de entrada for par, isso adiciona 1 (2 × 1 - 1 = 1) a ele.

Essa é uma maneira muito rápida e eficiente de escrever o código, já que grande parte da execução pode ser feita no front-end, mas não nos compra muito na forma de bytes, pois são necessárias muitas para codificar um complexo LEAinstrução. Esta versão também não funciona tão bem para fins de inclusão, pois requer que o valor da entrada original seja preservado como uma entrada da LEAinstrução. Portanto, com essa última tentativa de otimização, voltamos ao passado, sugerindo que talvez seja hora de parar.


Portanto, para a entrada final competitiva, temos uma função de 9 bytes que pega o valor de entrada no ECXregistro (uma convenção de chamada semi-padrão baseada em registro em x86 de 32 bits) e retorna o resultado no EAXregistro (como em todas as convenções de chamada x86):

           SwapParity PROC
8B C1         mov eax, ecx
F7 D8         neg eax
83 F0 FE      xor eax, -2
40            inc eax
C3            ret
           SwapParity ENDP

Pronto para montar com MASM; chamada de C como:

extern int __fastcall SwapParity(int value);                 // MSVC
extern int __attribute__((fastcall)) SwapParity(int value);  // GNU   

Não dec eax; xor eax, 1; inc eaxfuncionaria e economizaria mais um byte?
Ilmari Karonen


11

Python3, 20 18 bytes

lambda n:n-1+n%2*2

Bem simples. Primeiro calculamos n-1 e decidimos se devemos adicionar 2 ou não.

Se n for par -> n mod 2 será 0, adicionaremos 2 * 0 a n-1 , resultando em n-1 .

Se n for ímpar -> n mod 2 será 1, adicionaremos 2 * 1 a n-1 , resultando em n + 1 .

Prefiro uma explicação que fiz com o MS paint e um touchpad para laptop ... Explicação visual


10

Python, 16 bytes

lambda x:-(-x^1)

Experimente online!


3
A força bruta não encontra nenhuma solução mais curta usando caracteres "x+-012~|&^()*/%".
xnor

@xnor Ainda bem que entendi!
sagiksp

1
E parece que não há outras soluções do mesmo tamanho, exceto o rearranjo trivial -(1^-x).
Xnor

8

MATL , 7 bytes

Q:HePG)

Isso evita qualquer operação aritmética. Experimente online!

Explicação

Considere a entrada 4como um exemplo.

Q    % Implicit input. Add 1
     % STACK: 5
:    % Range
     % STACK: [1 2 3 4 5]
He   % Reshape with 2 rows in column-major order. Pads with a zero if needed
     % STACK: [1 3 5;
               2 4 0]
P    % Flip vertically
     % STACK: [2 4 0;
               1 3 5]
G    % Push input again
     % STACK: [2 4 0;
               1 3 5], 4
)    % Index, 1-based, in column major order. Implicitly display
     % STACK: 3

1
Agradável! Gosto disso !
Stewie Griffin

6

Braingolf v0.1 , 11 10 bytes

.1>2,%?+:-

Experimente online! (O segundo argumento é o código de Braingolf, o terceiro argumento é a entrada)

Guardou um byte graças a Neil

Primeira resposta braingolf:

Explicação:

.            Duplicate the top of the stack
 1>          Push 1 to the bottom of the stack
   2         Push 2 to stack
    ,%       Pop last 2 items, mod them and push result
      ?      If last item > 0
       +     Add the 1 to the input
        :    Else
         -   Subtract the 1 from the input

             No semicolon in code so print last item

Braingolf v0.2 , 9 bytes [não concorrente]

.2%?1+:1-

Experimente online! (O segundo argumento é o código de Braingolf, o terceiro argumento é a entrada)

Veja acima a explicação. A única diferença está no Braingolf v0.2, o comportamento padrão dos operadores diádicos e a função do ,modificador são revertidos, o que significa que as 2 vírgulas na resposta da v0.1 não são mais necessárias.

No entanto, a v0.2 foi lançada após o desafio, portanto esta não é competitiva


5
Parabéns pelo seu novo idioma!
Leaky Nun

Faz o .1<2,%?+:-que eu acho que faz?
Neil

@Neil não completamente, você precisará de uma vírgula antes do -para torná-lo executar a operação a maneira correta ao redor, caso em que ele ainda seria o mesmo comprimento que a minha resposta
Skidsdev

@ Mayube Eu estava esperando o <rodar 1abaixo da entrada, para que ele já estivesse no lugar correto.
Neil

@ Neil se a entrada for um número par, no momento em que atinge a -pilha, fica assim: os [n,1]operadores braingolf são revertidos, portanto, eles executariam 1 - n, o que resultaria em -(n-1), onde o resultado desejado é simplesmenten-1
Skidsdev

5

Cubix , 10 9 bytes

cO1)I(//@

Experimente online

Explicação

Versão líquida

    c O
    1 )
I ( / / @ . . .
. . . . . . . .
    . .
    . .

Os caracteres executados são

I(1c)O@
I          Input
 (         Decrement
  1c       XOR with 1
    )      Increment
     O@    Output and exit

4

Python, 68 bytes

lambda x:[m.floor(x-m.cos(m.pi*x)) for m in [__import__('math')]][0]

No espírito de uma abordagem única. O gráfico a seguir mostra a função (com pontos roxos representando os 10 primeiros casos). Em teoria, seria possível construir uma solução para essa questão com base na maioria (todas?) Das funções periódicas (por exemplo, sin, tan, sec). De fato, substituir cos por sec no código como está deve funcionar.

Função demonstrativa de gráfico


3

PHP, 15 bytes

<?=-(-$argn^1);

2
Como eu executo isso? Estou tentando testar se ;é necessário e tentei usar um .phparquivo e também ecoar diretamente no php (php7 cli.) Cada vez que me dizem que $argné uma variável indefinida.
Andrakis 4/17/17

2
@Andrakis Com a Fbandeira e um gasoduto: echo 42 | php -F script.php.
User63956 4/04

3

Javascript, 17 12 bytes

x=>x-(-1)**x

f=x=>x-(-1)**x;
<input id=i oninput=o.innerText=f(this.value) type=number><pre id=o>

Outra abordagem, 10 bytes roubados da resposta C (sssshhh)

x=>-(-x^1)

f=x=>-(-x^1)
<input id=i oninput=o.innerText=f(this.value) type=number><pre id=o>


1. você não precisa incluir o ponto e vírgula; 2.x=>x-(-1)**x
Leaky Nun

Por que o |0? As duas soluções parecem converter automaticamente seqüências de caracteres em números. (Para a primeira solução, se você quiser decimais evitar, uso <input type=number>.)
Neil

@ Neil Obrigado por me avisar!
Matthew Roh

3

JavaScript (ES6), 14 13 12 10 bytes

n=>-(-n^1)
  • 1 byte economizado graças a Luke .
  • 2 bytes salvos ao portar a solução C do feersum . (Se isso for desaprovado, entre em contato e retornaremos à minha solução anterior abaixo)

Tente

f=
n=>-(-n^1)
i.addEventListener("input",_=>o.innerText=f(+i.value))
<input id=i type=number><pre id=o>


Original, 12 bytes

n=>n-1+n%2*2

2

Python, 20 bytes

lambda n:n+(n%2or-1)

n%2or-1 retornará 1 se for ímpar, mas se for par, n%2 for "false" (0); portanto, retornará -1. Então simplesmente adicionamos isso a n.

Solução anterior, 23 bytes

lambda n:[n-1,n+1][n%2]

n%2calcula o restante quando né dividido por 2. Se for par, isso retornará 0 e o elemento 0 nesta lista será n-1. Se for ímpar, isso retornará 1 e o elemento 1 nesta lista será n+1.


1
Use um lambda:lambda n:[n-1,n+1][n%2]
Leaky Nun

Ah sim, então foi mais curto neste caso. Feito, obrigado!
Numbermaniac #

2

Retina , 21 bytes

.+
$*
^11(?=(11)*$)


Experimente online! Minha primeira resposta Retina com duas novas linhas à direita! Explicação: As duas primeiras linhas convertem de decimal em unário. A terceira e quarta linhas subtraem duas dos números pares. A última linha é convertida novamente em decimal, mas adiciona uma também.



2

Cubix , 11 bytes

u%2!I(/+@O<

Experimente online!

Explicação

Versão líquida:

    u %
    2 !
I ( / + @ O < .
. . . . . . . .
    . .
    . .

Os caracteres são executados na seguinte ordem:

I(2%!+O@
I        # Take a number as input
 (       # Decrement it
  2%     # Take the parity of the decremented number
         # (0 if the input is odd, 1 if it's even)
    !    # If that number is zero:
     +   #   Add 2
      O  # Output the number
       @ # Terminate the program

2

Brain-Flak , 36 bytes

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

Experimente online!

Pessoalmente, estou muito feliz com esta resposta, porque é muito mais curta do que eu consideraria um método tradicional de resolver esse problema.

Explicação

O primeiro bit de código

(({})(()))

converte a pilha de apenas npara

n + 1
  1
  n

Então, enquanto o topo da pilha é diferente de zero, diminuímos e mostramos o sinal do número abaixo

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

Nós removemos o zero e adicionamos os dois números restantes

{}({}{})

2

Mathematica, 22 19 bytes

Economizou 3 bytes graças a Greg Martin!

#-1[-1][[#~Mod~2]]&

Resposta anterior, 22 bytes

#+{-1,1}[[#~Mod~2+1]]&

Explicação (para resposta anterior)

O Mathematica possui o recurso interessante de que operações como aritmética passam automaticamente por listas.

Nesse caso, consideramos Mod[#,2]que retornará 0 ou 1, mas precisamos adicionar 1 porque as listas do Mathematica são indexadas em 1. Se for par , isso sai para 1, então #-1é retornado. Se for estranho , esse valor é 2, então #+1é retornado.


2
Você pode salvar três bytes por abusar do Mathematica [[0]]capacidade: #-1[-1][[#~Mod~2]]&.
Greg Martin

Isso é loucura, nunca teria pensado nisso. Feito, obrigado!
Numbermaniac #

2

Sábio , 8 bytes

-::^~-^-

Experimente online!

Explicação

Se fosse o contrário, (decréscimo se ímpar, incremento se par), seria bem fácil fazer isso.

Nós viraríamos a última parte.

::^~-^

A correção aqui é que lançamos o último bit enquanto negativo. Os números negativos estão 1 fora da negação dos números, ~portanto, isso cria um deslocamento para resolver o problema.

Então, nós apenas pegamos o programa e o envolvemos -.

-::^~-^-

1

Java 8, 16 10 bytes

n->-(-n^1)

Java 7, 34 28 bytes

int c(int n){return-(-n^1);}

Boring ports of @feersum's amazing C answer.
Try it here.


Old answers:

Java 8, 16 bytes

n->n%2<1?n-1:n+1

Java 7, 34 bytes

int c(int n){return--n%2>0?n:n+2;}

Explanation (of old Java 7 answer):

Try it here.

The answer above is a shorter variant of int c(int n){return n%2<1?n-1:n+1;} by getting rid of the space.

int c(int n){     // Method with integer parameter and integer return-type
  return--n%2>0?  //  If n-1 mod-2 is 1:
    n             //   Return n-1
   :              //  Else:
    n+2;          //   Return n+1
}                 // End of method



1

Befunge 93, 18 bytes

&:2%#v_1+.@
@.-1 <

I am not done golfing this yet (I hope).


Golfing tips: Befunge 98 has the ability to use kv (or jv if it is strictly 1 or 0) instead of #v_. Also, if you are using Try it online (and I recommend it), you can end the program with another & (although it will take 60 seconds), so you can get rid of the @ on the first line if you use that. here is the full list of commands for Befunge-98, although they might not all be correctly implemented in TIO, like & ending the program instead of reversing on EOF.
MildlyMilquetoast

Also, It looks like you're using befunge 93 instead of 98, which has fewer commands. You might want to fix your link name if it is indeed 93 and not 98
MildlyMilquetoast

@MistahFiggins, ah yes you are correct I was using 93.
Daniel


1

R, 17 bytes

(n=scan())-(-1)^n

where n=scan() takes the digit value.


I think you need -(-1)^n rather than +(-1)^n since we need to return n-1 if n is even
Giuseppe

@Giuseppe oh, yes, of course, foolish mistake
Nutle

1

Casio-Basic, 27 bytes

piecewise(mod(n,2),1,-1)+n

26 bytes for the function, +1 to enter n in the parameters box.




0

Batch, 20 bytes

@cmd/cset/a"-(1^-%1)

Independently rediscovered @feersum's algorithm, honest!

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.