Intercambia la paridad

22

Tarea

Dado un entero positivo n, la salida n+1si nes impar y la salida n-1si nes par.

Entrada

Un entero positivo. Puede suponer que el número entero está dentro de la capacidad de manejo del lenguaje.

Salida

Un entero positivo, especificado anteriormente.

Casos de prueba

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

Tanteo

Este es el , por lo que la respuesta más corta en bytes gana.

Se aplican lagunas estándar .

Referencias

Monja permeable
fuente
¿Podemos tomar la entrada como unario?
Kritixi Lithos
2
Sorprendentemente, esto sería mucho más fácil si fuera al revés en algunos idiomas
MildlyMilquetoast
3
@MistahFiggins Eso es lo suficientemente conocido como para estar bastante seguro de que OP lo hizo a propósito.
Ørjan Johansen

Respuestas:

24

C, 20 bytes

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

Pruébalo en línea .

Feersum
fuente
77
@LeakyNun No estoy escribiendo una función que carece de una declaración de devolución.
fiesta
18
@EriktheOutgolfer No. No. Nuh-uh No.
feersum
10
@Sisyphus Pero este es el código de golf , y funciona en mi enlace TIO, por lo que es válido.
Erik the Outgolfer
77
@EriktheOutgolfer Lo que estoy diciendo es que su declaración ("asignar al primer argumento es equivalente a una declaración de retorno") es objetivamente incorrecta. Si dicho código puede generar una respuesta funcional bajo ciertas circunstancias es otra pregunta (que he abordado en mi primer comentario al afirmar que planeo no publicar dicho código).
fiesta
8
@EriktheOutgolfer Si una respuesta se basa en el comportamiento específico de la implementación, debe especificar una implementación. Esta respuesta no lo hace, por lo que ese código sería inválido.
Sísifo
17

Apilar gatos , 3 + 3 ( -n) = 6 bytes

-*-

Pruébalo en línea!

Necesita que la -nbandera funcione con entradas y salidas numéricas.

Explicación

Stack Cats generalmente está lejos de ser competitivo, debido a su conjunto limitado de comandos (todos los cuales son inyecciones, y la mayoría de ellos son involuciones) y porque cada programa necesita tener simetría espejo. Sin embargo, una de las involuciones es alternar el bit menos significativo de un número, y podemos compensar el valor con la negación unaria que también existe. Afortunadamente, eso nos da un programa simétrico, por lo que no debemos preocuparnos por nada más:

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

La entrada y la salida están implícitas al principio y al final del programa, porque tomar entrada y producir salida no es una operación reversible, por lo que no pueden ser comandos.

Martin Ender
fuente
1
¿Las banderas siempre cuentan con el espacio adicional, no creo que haya visto otras respuestas usando banderas (como Perl) para hacer eso? EDITAR: Ok nvm, encontré la meta publicación relevante . " Cuento aquellos como una diferencia en la cuenta de carácter equivalente a la invocación más corto sin ellos. " ... " perl -nle 'stuff'es de 2 caracteres más perl -e 'stuff', para que cuente para 2 personajes más ". Entonces (space)-nson 3 bytes más que sin la bandera.
Kevin Cruijssen
@KevinCruijssen Depende de cuántos bytes realmente necesite agregar a una invocación habitual. En Perl y en muchos otros lenguajes de producción, puede invocar el código -e "code"y luego insertar banderas adicionales antes de e, por ejemplo -pe "code". Entonces la -pbandera es solo un byte. Sin embargo, Stack Cats no tiene ese -eargumento, por lo que siempre debe agregar <sp>-nel comando completo al comando y, por lo tanto, son tres bytes.
Martin Ender
12

Asamblea x86, 9 bytes (para entrada competitiva)

Todos los que intentan este desafío en lenguajes de alto nivel se están perdiendo la verdadera diversión de manipular bits sin procesar. Hay tantas variaciones sutiles en las formas de hacer esto, es una locura, y es muy divertido pensar en ello. Aquí hay algunas soluciones que ideé en lenguaje ensamblador x86 de 32 bits.

Me disculpo de antemano porque esta no es la típica respuesta de código de golf. Voy a divagar mucho sobre el proceso de pensamiento de la optimización iterativa (para el tamaño). Espero que sea interesante y educativo para un público más amplio, pero si eres del tipo TL; DR, no me ofenderé si saltas hasta el final.

La solución obvia y eficiente es probar si el valor es par o impar (lo que se puede hacer de manera eficiente mirando el bit menos significativo), y luego seleccionar entre n + 1 o n − 1 en consecuencia. Suponiendo que la entrada se pasa como un parámetro en el ECXregistro, y el resultado se devuelve en el EAXregistro, obtenemos la siguiente función:

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)

Pero para propósitos de código de golf, esas LEAinstrucciones no son excelentes, ya que toman 3 bytes para codificar. Un DECcomentario simple de ECXsería mucho más corto (solo un byte), pero esto afecta a las banderas, por lo que debemos ser un poco inteligentes en la forma en que organizamos el código. Podemos hacer el decremento primera , y la prueba de par / impar segundos , pero luego tenemos que invertir el resultado de la prueba de par / impar.

Además, podemos cambiar la instrucción de movimiento condicional a una bifurcación, lo que puede hacer que el código se ejecute más lentamente (dependiendo de cuán predecible sea la bifurcación; si la entrada alterna inconsistentemente entre pares e impares, una bifurcación será más lenta; si hay un patrón, será más rápido), lo que nos ahorrará otro byte.

De hecho, con esta revisión, toda la operación se puede realizar en el lugar, utilizando solo un único registro. Esto es genial si está incorporando este código en alguna parte (y es probable que lo sea, ya que es muy corto).

    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)

(en línea: 7 bytes; como una función: 10 bytes)

Pero, ¿y si quisieras que fuera una función? Ninguna convención de llamada estándar utiliza el mismo registro para pasar parámetros que para el valor de retorno, por lo que deberá agregar una MOVinstrucción de registro-registro al principio o al final de la función. Esto prácticamente no tiene costo en velocidad, pero agrega 2 bytes. (La RETinstrucción también agrega un byte, y hay una sobrecarga introducida por la necesidad de realizar y regresar de una llamada de función, lo que significa que este es un ejemplo en el que la alineación produce un beneficio de velocidad y tamaño, en lugar de ser simplemente una velocidad clásica -por-espacio de compensación.) En total, escrito como una función, este código se hincha a 10 bytes.

¿Qué más podemos hacer en 10 bytes? Si nos preocupamos por el rendimiento (al menos, el rendimiento predecible ), sería bueno deshacerse de esa rama. Aquí hay una solución de ramificación de bits sin ramas que tiene el mismo tamaño en bytes. La premisa básica es simple: usamos un XOR bit a bit para voltear el último bit, convirtiendo un valor impar en uno par, y viceversa. Pero hay un inconveniente: para las entradas impares, que nos da n-1 , mientras que para las entradas pares, nos da n + 1 , exactamente opuesto a lo que queremos. Entonces, para arreglar eso, realizamos la operación en un valor negativo, volteando el signo de manera efectiva.

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

(en línea: 7 bytes; como una función: 10 bytes)

Bastante hábil; Es difícil ver cómo se puede mejorar. Sin embargo, una cosa me llama la atención: esas dos NEGinstrucciones de 2 bytes . Francamente, dos bytes parecen un byte demasiado para codificar una simple negación, pero ese es el conjunto de instrucciones con el que tenemos que trabajar. ¿Hay alguna solución? ¡Seguro! Si tenemos XOR-2, podemos reemplazar la segunda NEGacción con un INCcomentario:

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

(en línea: 6 bytes; como función: 9 bytes)

¡Otra de las rarezas del conjunto de instrucciones x86 es la LEAinstrucción multipropósito , que puede hacer un movimiento de registro-registro, una adición de registro-registro, compensación por una constante y escalar todo en una sola instrucción!

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)

La ANDinstrucción es como la TESTinstrucción que usamos anteriormente, ya que ambos hacen un AND a nivel de bit y establecen indicadores en consecuencia, pero en ANDrealidad actualizan el operando de destino. La LEAinstrucción luego escala esto en 2, agrega el valor de entrada original y disminuye en 1. Si el valor de entrada era impar, esto resta 1 (2 × 0 - 1 = −1) de él; si el valor de entrada fue par, esto le agrega 1 (2 × 1 - 1 = 1).

Esta es una forma muy rápida y eficiente de escribir el código, ya que gran parte de la ejecución se puede hacer en el front-end, pero no nos compra mucho en forma de bytes, ya que se necesitan muchos para codificar un complejo LEAinstrucción. Esta versión tampoco funciona tan bien para fines de alineación, ya que requiere que el valor de entrada original se conserve como entrada de la LEAinstrucción. Entonces, con este último intento de optimización, hemos retrocedido, sugiriendo que podría ser el momento de detenerse.


Por lo tanto, para la entrada competitiva final, tenemos una función de 9 bytes que toma el valor de entrada en el ECXregistro (una convención de llamada basada en un registro semi-estándar en x86 de 32 bits), y devuelve el resultado en el EAXregistro (como con todas las convenciones de llamadas 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

Listo para armar con MASM; llamar desde C como:

extern int __fastcall SwapParity(int value);                 // MSVC
extern int __attribute__((fastcall)) SwapParity(int value);  // GNU   
Cody Gray
fuente
¿No dec eax; xor eax, 1; inc eaxfuncionaría y ahorraría un byte más?
Ilmari Karonen
11

Jalea , 3 bytes

-*ạ

Pruébalo en línea!

Pseudocódigo: abs((-1)**n - n)

Monja permeable
fuente
En realidad estaba planeando usar (ab) -1.
Erik the Outgolfer
Lo siento por eso.
Leaky Nun
No hay perdón, ¡bien hecho! No descubrí cómo hacerlo lo suficientemente rápido ...
Erik the Outgolfer
11

Python3, 20 18 bytes

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

Bastante simple. Primero calculamos n-1 y decidimos si agregarle 2 o no.

Si n es par -> n mod 2 será 0, por lo tanto agregaremos 2 * 0 a n-1 , dando como resultado n-1 .

Si n es impar -> n mod 2 será 1, por lo tanto agregaremos 2 * 1 a n-1 , resultando en n + 1 .

Prefiero una explicación que hice con MS Paint y un touchpad portátil ... Explicación visual

Yytsi
fuente
10

Python, 16 bytes

lambda x:-(-x^1)

Pruébalo en línea!

sagiksp
fuente
3
El forzamiento bruto no encuentra una solución más corta usando caracteres "x+-012~|&^()*/%".
xnor
@xnor ¡Qué bueno que lo tengo entonces!
sagiksp
1
Y parece que no hay otras soluciones de la misma longitud, excepto la reorganización trivial -(1^-x).
xnor
8

MATL , 7 bytes

Q:HePG)

Esto evita cualquier operación aritmética. Pruébalo en línea!

Explicación

Considere la entrada 4como un ejemplo.

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
Luis Mendo
fuente
1
¡Agradable! Gusta !
Stewie Griffin
6

Braingolf v0.1 , 11 10 bytes

.1>2,%?+:-

Pruébalo en línea! (El segundo argumento es el código Braingolf, el tercer argumento es la entrada)

Salvó un byte gracias a Neil

Primera respuesta de Braingolf en competencia: D

Explicación:

.            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 [no competidor]

.2%?1+:1-

Pruébalo en línea! (El segundo argumento es el código Braingolf, el tercer argumento es la entrada)

Ver arriba para explicación. La única diferencia está en Braingolf v0.2, el comportamiento predeterminado de los operadores diádicos y la función del ,modificador se invierten, lo que significa que las 2 comas en la respuesta v0.1 ya no son necesarias.

Sin embargo, v0.2 se lanzó después del desafío, por lo que este no compite

Skidsdev
fuente
55
¡Felicitaciones por tu nuevo idioma!
Leaky Nun
¿Hace .1<2,%?+:-lo que creo que hace?
Neil
@Neil no del todo, necesitarías una coma antes del -para que realice la operación de la manera correcta, en cuyo caso aún tendría la misma longitud que mi respuesta
Skidsdev
@Mayube Esperaba <que girara 1debajo de la entrada, para que ya estuviera en el lugar correcto.
Neil
@Neil si la entrada es un número par, para cuando llega a la -pila se ve así: los [n,1]operadores de braingolf se invierten, por lo que funcionaría 1 - n, lo que daría como resultado -(n-1), si el resultado deseado es simplementen-1
Skidsdev
5

Cubix , 10 9 bytes

cO1)I(//@

Pruébalo en línea

Explicación

Versión neta

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

Los caracteres ejecutados son

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

fuente
4

Python, 68 bytes

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

En el espíritu de un enfoque único. El siguiente gráfico muestra la función (con puntos morados que representan los primeros 10 casos). En teoría, debería ser posible construir una solución para esta pregunta basada en la mayoría de las funciones periódicas (¿todas?) (Por ejemplo, sin, tan, sec). De hecho, sustituir cos por sec en el código tal como debería funcionar.

Función de demostración gráfica

penalosa
fuente
3

PHP, 15 bytes

<?=-(-$argn^1);
usuario63956
fuente
2
¿Cómo ejecuto esto? Estoy tratando de probar si ;es necesario, y he intentado usar un .phparchivo y también hacer eco directamente en php (php7 cli.) Cada vez que me dicen que $argnes una variable indefinida.
Andrakis
2
@Andrakis Con la Fbandera y una tubería: echo 42 | php -F script.php.
user63956
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>

Otro enfoque, 10 bytes robados de la respuesta C (sssshhh)

x=>-(-x^1)

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

Matthew Roh
fuente
1. no necesita incluir el punto y coma; 2.x=>x-(-1)**x
Leaky Nun
¿Por qué el |0? Parece que ambas soluciones deberían convertir automáticamente las cadenas a números. (Para la primera solución, si desea evitar decimales, use <input type=number>.)
Neil
@Neil ¡Gracias por avisarme!
Matthew Roh
3

JavaScript (ES6), 14 13 12 10 bytes

n=>-(-n^1)
  • 1 byte guardado gracias a Luke .
  • 2 bytes guardados al portar la solución C de feersum . (Si eso está mal visto, hágamelo saber y volveré a mi solución anterior a continuación)

Intentalo

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
Lanudo
fuente
2

Python, 20 bytes

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

n%2or-1 devolverá 1 si es impar, pero si es par, n%2 es "falso" (0), por lo que devuelve -1. Luego simplemente agregamos eso a n.

Solución anterior, 23 bytes

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

n%2calcula el resto cuando nse divide entre 2. Si es par, esto devuelve 0 y el elemento 0 en esta lista es n-1. Si es impar, esto devuelve 1, y el elemento 1 en esta lista es n+1.

numbermaniac
fuente
1
Use una lambda:lambda n:[n-1,n+1][n%2]
Leaky Nun
Ah sí, así que fue más corto en este caso. ¡Hecho, gracias!
numbermaniac
2

Retina , 21 bytes

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


Pruébalo en línea! ¡Mi primera respuesta de Retina con dos líneas nuevas! Explicación: Las dos primeras líneas se convierten de decimal a unario. Las líneas tercera y cuarta restan dos de los números pares. La última línea se convierte de nuevo a decimal, pero también agrega uno.

Neil
fuente
2

Cubix , 11 bytes

u%2!I(/+@O<

Pruébalo en línea!

Explicación

Versión neta:

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

Los caracteres se ejecutan en el siguiente orden:

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
Luke
fuente
2

Brain-Flak , 36 bytes

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

Pruébalo en línea!

Personalmente estoy muy contento con esta respuesta porque es mucho más corta de lo que consideraría un método tradicional para resolver este problema.

Explicación

El primer bit de código

(({})(()))

convierte la pila de solo na

n + 1
  1
  n

Luego, mientras la parte superior de la pila no es cero, la disminuimos y volteamos el signo del número debajo de ella

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

Luego eliminamos el cero y sumamos los dos números restantes

{}({}{})
Asistente de trigo
fuente
2

Mathematica, 22 19 bytes

¡Guardado 3 bytes gracias a Greg Martin!

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

Respuesta anterior, 22 bytes

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

Explicación (para la respuesta anterior)

Mathematica tiene la buena característica de que operaciones como la aritmética se enhebran automáticamente en las listas.

En este caso, tomamos Mod[#,2]cuál devolverá 0 o 1, pero necesitamos agregar 1 porque las listas de Mathematica están indexadas en 1. Si es par , esto sale a 1, por lo que #-1se devuelve. Si es extraño , sale 2, por lo que #+1se devuelve.

numbermaniac
fuente
2
Puede guardar tres bytes por abusar de Mathematica [[0]]capacidad: #-1[-1][[#~Mod~2]]&.
Greg Martin
Eso es una locura, nunca habría pensado en eso. ¡Hecho, gracias!
numbermaniac
2

Sabio , 8 bytes

-::^~-^-

Pruébalo en línea!

Explicación

Si esto fuera al revés (disminuir si es impar, aumentar si es par), sería bastante fácil hacer esto.

Simplemente voltearíamos el último bit.

::^~-^

La solución aquí es que volteamos el último bit mientras somos negativos. Los números negativos son 1 fuera de la negación de los números, ~por lo que esto crea un desplazamiento para resolver el problema.

Así que solo sacamos el programa y lo envolvemos -.

-::^~-^-
Asistente de trigo
fuente
1

Java 8, 16 10 bytes

n->-(-n^1)

Java 7, 34 28 bytes

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

Puertos aburridos de la sorprendente respuesta C de @feersum .
Pruébalo aquí.


Viejas respuestas:

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

Explicación (de la antigua respuesta de Java 7):

Pruébalo aquí

La respuesta anterior es una variante más corta de int c(int n){return n%2<1?n-1:n+1;}deshacerse del espacio.

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
Kevin Cruijssen
fuente
1

Python, 20 bytes

lambda n:n+(n&1)*2-1
Wondercricket
fuente
1

Befunge 93 , 18 bytes

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

Todavía no he terminado de jugar esto (espero).

Daniel
fuente
Consejos de golf: Befunge 98 tiene la capacidad de usar kv(o jvsi es estrictamente 1 o 0) en lugar de #v_. Además, si está utilizando Pruébelo en línea (y lo recomiendo), puede finalizar el programa con otro &(aunque tomará 60 segundos), por lo que puede deshacerse de él @en la primera línea si lo usa. Aquí está la lista completa de comandos para Befunge-98 , aunque es posible que no todos se implementen correctamente en TIO, como &finalizar el programa en lugar de invertirlo en EOF.
MildlyMilquetoast
Además, parece que estás usando befunge 93 en lugar de 98, que tiene menos comandos. Es posible que desee corregir el nombre de su enlace si es 93 y no 98
MildlyMilquetoast
@MistahFiggins, ah sí, tienes razón, estaba usando 93.
Daniel
1

Rubí, 12 bytes.

->n{-(-n^1)}
Cyoce
fuente
1

R, 17 bytes

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

donde n=scan()toma el valor del dígito.

Tuerca
fuente
Creo que es necesario, en -(-1)^nlugar de hacerlo, +(-1)^nya que tenemos que volver n-1si nes par
Giuseppe
@Giuseppe oh, sí, por supuesto, error tonto
Nutle
1

Casio-Basic, 27 bytes

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

26 bytes para la función, +1 para ingresar nen el cuadro de parámetros.

numbermaniac
fuente
0

C, 29 bytes

a(int b){return b%2?b+1:b-1;}
Skynet
fuente
0

Lote, 20 bytes

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

Redescubierto independientemente el algoritmo de @ feersum, ¡honesto!

Neil
fuente