Scambia la parità


22

Compito

Dato un numero intero positivo n, output n+1if nè dispari e output n-1if nè pari.

Ingresso

Un numero intero positivo. Si può presumere che l'intero sia all'interno della capacità di gestione della lingua.

Produzione

Un numero intero positivo, specificato sopra.

Casi test

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

punteggio

Questo è , quindi vince la risposta più breve in byte.

Si applicano scappatoie standard .

Riferimenti


Possiamo prendere l'input come unario?
Kritixi Lithos,

2
Questo sarebbe, sorprendentemente, molto più facile se fosse il contrario in alcune lingue
MildlyMilquetoast

3
@MistahFiggins È abbastanza noto che sono abbastanza sicuro che OP lo abbia fatto di proposito.
Ørjan Johansen,

Risposte:


24

C, 20 byte

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

Provalo online .


7
@LeakyNun Non sto scrivendo una funzione mancante di una dichiarazione di ritorno.
feersum

18
@EriktheOutgolfer No. No. Nuh-uh. No.
feersum

10
@Sisyphus Ma questo è code-golf , e funziona sul mio link TIO, quindi è valido.
Erik the Outgolfer,

7
@EriktheOutgolfer Quello che sto dicendo è che la tua affermazione ("assegnare al primo argomento equivale a una dichiarazione di ritorno") è effettivamente errata. Se tale codice possa generare una risposta funzionante in determinate circostanze è un'altra domanda (che ho affrontato nel mio primo commento affermando che ho intenzione di non pubblicare tale codice).
feersum

8
@EriktheOutgolfer Se una risposta si basa su un comportamento specifico dell'implementazione, dovrebbe specificare un'implementazione. Questa risposta no, quindi quel codice non sarebbe valido.
Sisifo,

17

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

-*-

Provalo online!

Ha bisogno che il -nflag funzioni con input e output numerici.

Spiegazione

Stack Cats è di solito tutt'altro che competitivo, a causa della sua serie limitata di comandi (che sono tutti iniezioni e la maggior parte sono involuzioni) e perché ogni programma deve avere una simmetria speculare. Tuttavia, una delle implicazioni è alternare il bit meno significativo di un numero e possiamo compensare il valore con negazione unaria che esiste anche. Fortunatamente, questo ci dà un programma simmetrico, quindi non dobbiamo preoccuparci di nient'altro:

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

Input e output sono impliciti all'inizio e alla fine del programma, perché prendere input e produrre output non è un'operazione reversibile, quindi non possono essere comandi.


1
Le bandiere vengono sempre conteggiate con lo spazio aggiuntivo, non penso di aver visto altre risposte usando le bandiere (come Perl) farlo? EDIT: Ok nvm, ho trovato il relativo meta post . " Li considero una differenza nel conteggio dei caratteri nell'invocazione equivalente più breve senza di loro. " ... " perl -nle 'stuff'è 2 caratteri in più di perl -e 'stuff', quindi conta per altri 2 caratteri ". Quindi (space)-nè 3 byte in più rispetto a senza la bandiera.
Kevin Cruijssen,

@KevinCruijssen Dipende da quanti byte è effettivamente necessario aggiungere a una normale chiamata. In Perl e in molti altri linguaggi di produzione, è possibile richiamare il codice con -e "code"e quindi inserire flag aggiuntivi prima di e, ad es -pe "code". Quindi il -pflag è solo un byte. Tuttavia, Stack Cats non ha questo -eargomento, quindi è sempre necessario aggiungere l'intero <sp>-nal comando, e quindi sono tre byte.
Martin Ender,

12

x86 Assembly, 9 byte (per accesso concorrente)

Chiunque stia tentando questa sfida in linguaggi di alto livello si sta perdendo il vero divertimento di manipolare i bit grezzi. Ci sono così tante sottili variazioni sui modi per farlo, è pazzesco e molto divertente a cui pensare. Ecco alcune soluzioni che ho ideato in linguaggio assembly x86 a 32 bit.

Mi scuso in anticipo che questa non è la tipica risposta da golf a codice. Vado in giro molto sul processo di pensiero dell'ottimizzazione iterativa (per dimensioni). Spero che sia interessante ed educativo per un pubblico più vasto, ma se sei il tipo TL; DR, non mi offenderò se salti alla fine.

La soluzione ovvia ed efficiente è verificare se il valore è pari o dispari (cosa che può essere eseguita in modo efficiente osservando il bit meno significativo), quindi selezionare tra n + 1 o n − 1 di conseguenza. Supponendo che l'ingresso sia passato come parametro nel ECXregistro e che il risultato sia restituito nel EAXregistro, otteniamo la seguente funzione:

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

Ma ai fini del code-golf, queste LEAistruzioni non sono grandiose, poiché richiedono 3 byte per codificare. Un semplice DECrement di ECXsarebbe molto più breve (solo un byte), ma questo influisce sui flag, quindi dobbiamo essere un po 'intelligenti nel modo in cui organizziamo il codice. Possiamo fare il decremento prima , e il pari / dispari di prova secondo , ma poi dobbiamo invertire il risultato del test pari / dispari.

Inoltre, possiamo cambiare l'istruzione di spostamento condizionale in un ramo, il che può far funzionare il codice più lentamente (a seconda di quanto sia prevedibile il ramo - se l'input si alterna in modo incoerente tra pari e dispari, un ramo sarà più lento; se c'è un modello, sarà più veloce), che ci farà risparmiare un altro byte.

In effetti, con questa revisione, l'intera operazione può essere eseguita sul posto, utilizzando un solo registro. Questo è fantastico se stai inserendo questo codice da qualche parte (e probabilmente lo sarai, dato che è così breve).

    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)

(in linea: 7 byte; in funzione: 10 byte)

E se volessi renderlo una funzione? Nessuna convenzione di chiamata standard utilizza lo stesso registro per passare i parametri come per il valore restituito, quindi è necessario aggiungere MOVun'istruzione registro-registro all'inizio o alla fine della funzione. Questo non ha praticamente alcun costo in termini di velocità, ma aggiunge 2 byte. (L' RETistruzione aggiunge anche un byte e c'è un certo sovraccarico introdotto dalla necessità di effettuare e tornare da una chiamata di funzione, il che significa che questo è un esempio in cui l'allineamento produce sia un vantaggio di velocità che di dimensione, piuttosto che essere solo una velocità classica -per-spazio tradeoff.) In tutto, scritto come una funzione, questo codice si gonfia a 10 byte.

Cos'altro possiamo fare in 10 byte? Se ci preoccupiamo per le prestazioni (almeno, prestazioni prevedibili ), sarebbe bello sbarazzarsi di quel ramo. Ecco una soluzione priva di ramificazioni di bit che ha la stessa dimensione in byte. La premessa di base è semplice: usiamo un XOR bit a bit per capovolgere l'ultimo bit, convertendo un valore dispari in uno pari e viceversa. Ma c'è un inconveniente - per gli input dispari, che ci dà n-1 , mentre per gli input pari, ci dà n + 1 - esattamente l'opposto di ciò che vogliamo. Quindi, per risolverlo, eseguiamo l'operazione su un valore negativo, capovolgendo efficacemente il segno.

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

(in linea: 7 byte; in funzione: 10 byte)

Abbastanza lucido; è difficile capire come migliorarlo. Una cosa attira la mia attenzione, però: quelle due NEGistruzioni a 2 byte . Francamente, due byte sembrano troppi byte per codificare una semplice negazione, ma questa è l'insieme di istruzioni con cui dobbiamo lavorare. Ci sono soluzioni alternative? Sicuro! Se XORcon -2, possiamo sostituire la seconda NEGazione con un INCrement:

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

(in linea: 6 byte; in funzione: 9 byte)

Un'altra delle stranezze dell'insieme di istruzioni x86 è l' LEAistruzione multiuso , che può fare una mossa di registro-registro, un'aggiunta di registro-registro, compensare da una costante e ridimensionare il tutto in una singola istruzione!

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

L' ANDistruzione è come l' TESTistruzione che abbiamo usato in precedenza, in quanto entrambi eseguono un bit-AND e impostano i flag di conseguenza, ma in ANDrealtà aggiornano l'operando di destinazione. L' LEAistruzione quindi lo ridimensiona di 2, aggiunge il valore di input originale e decrementa di 1. Se il valore di input era dispari, questo sottrae 1 (2 × 0 - 1 = −1) da esso; se il valore di input era pari, questo aggiunge 1 (2 × 1 - 1 = 1) ad esso.

Questo è un modo molto veloce ed efficiente per scrivere il codice, poiché gran parte dell'esecuzione può essere eseguita nel front-end, ma non ci compra molto in termini di byte, dal momento che ci vogliono così tanti per codificare un complesso LEAistruzioni. Questa versione non funziona altrettanto bene per scopi di allineamento, poiché richiede che il valore di input originale sia preservato come input LEAdell'istruzione. Quindi, con questo ultimo tentativo di ottimizzazione, siamo effettivamente tornati indietro, suggerendo che potrebbe essere il momento di smettere.


Pertanto, per la voce finale concorrente, abbiamo una funzione a 9 byte che accetta il valore di input nel ECXregistro (una convenzione di chiamata semi-standard basata su registro su x86 a 32 bit) e restituisce il risultato nel EAXregistro (come con tutte le convenzioni di chiamata 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 per il montaggio con MASM; chiama da C come:

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

Non dec eax; xor eax, 1; inc eaxfunzionerebbe e risparmierebbe un byte in più?
Ilmari Karonen,


11

Python3, 20 18 byte

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

Abbastanza semplice. Per prima cosa calcoliamo n-1 e decidiamo se aggiungere 2 o meno.

Se n è pari -> n mod 2 sarà 0, quindi aggiungeremo 2 * 0 a n-1 , risultando in n-1 .

Se n è dispari -> n mod 2 sarà 1, quindi aggiungeremo 2 * 1 a n-1 , risultando in n + 1 .

Preferisco una spiegazione che ho fatto con MS Paint e un touchpad per laptop ... Spiegazione visiva


10

Python, 16 byte

lambda x:-(-x^1)

Provalo online!


3
La forza bruta non trova alcuna soluzione più breve usando i caratteri in "x+-012~|&^()*/%".
xnor

@xnor Meno male che l'ho preso allora!
sagiksp,

1
E sembra che non ci siano altre soluzioni della stessa lunghezza tranne il banale riarrangiamento -(1^-x).
xnor

8

MATL , 7 byte

Q:HePG)

Questo evita qualsiasi operazione aritmetica. Provalo online!

Spiegazione

Considera l'input 4come esempio.

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
Bello! Mi piace !
Stewie Griffin,

6

Braingolf v0.1 , 11 10 byte

.1>2,%?+:-

Provalo online! (Il secondo argomento è il codice Braingolf, il terzo argomento è l'input)

Salvataggio di un byte grazie a Neil

Prima risposta di Braingolf in competizione: D

Spiegazione:

.            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 byte [non competitivo]

.2%?1+:1-

Provalo online! (Il secondo argomento è il codice Braingolf, il terzo argomento è l'input)

Vedi sopra per una spiegazione. L'unica differenza è in Braingolf v0.2, il comportamento predefinito degli operatori diadici e la funzione del ,modificatore sono invertiti, il che significa che le 2 virgole nella risposta v0.1 non sono più necessarie.

Comunque v0.2 è stato rilasciato dopo la sfida, quindi questo non è in competizione


5
Congratulazioni per la tua nuova lingua!
Leaky Nun,

Fa .1<2,%?+:-quello che penso che faccia?
Neil,

@Neil non del tutto, avresti bisogno di una virgola prima -di farlo eseguire l'operazione nel modo corretto, nel qual caso sarebbe ancora della stessa lunghezza della mia risposta
Skidsdev

@Mayube Mi aspettavo <che ruotasse 1sotto l'input, in modo che fosse già nella posizione corretta.
Neil,

@Neil se l'ingresso è un numero pari, quando raggiunge lo -stack appare così: [n,1]gli operatori braingolf sono invertiti, quindi si esibirebbe, il che comporterebbe 1 - n, dove il risultato -(n-1)desiderato è semplicementen-1
Skidsdev

5

Cubix , 10 9 byte

cO1)I(//@

Provalo online

Spiegazione

Versione netta

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

I personaggi eseguiti sono

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

4

Python, 68 byte

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

Nello spirito di un approccio unico. Il grafico seguente mostra la funzione (con punti viola che rappresentano i primi 10 casi). In teoria dovrebbe essere possibile costruire una soluzione per questa domanda basata sulla maggior parte (tutte?) Delle funzioni periodiche (es. Sin, tan, sec). In effetti, sostituendo cos per sec nel codice come dovrebbe funzionare.

Grafico che dimostra la funzione


3

PHP, 15 byte

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

2
Come eseguo questo? Sto provando a verificare se ;è necessario, e ho provato a usare un .phpfile e anche a riecheggiare direttamente in php (php7 cli.) Ogni volta che mi viene detto che $argnè una variabile indefinita.
Andrakis,

2
@Andrakis Con la Fbandiera e una pipeline: echo 42 | php -F script.php.
user63956,

3

Javascript, 17 12 byte

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

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

Un altro approccio, 10 byte rubati dalla risposta C (sssshhh)

x=>-(-x^1)

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


1. non è necessario includere il punto e virgola; 2.x=>x-(-1)**x
Leaky Nun,

Perché il |0? Entrambe le soluzioni sembrano convertire automaticamente le stringhe in numeri. (Per la prima soluzione, se vuoi evitare i decimali, usa <input type=number>.)
Neil

@Neil Grazie per avermelo avvisato!
Matthew Roh,

3

JavaScript (ES6), 14 13 12 10 byte

n=>-(-n^1)

Provalo

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


Originale, 12 byte

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

2

Python, 20 byte

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

n%2or-1 restituirà 1 se è dispari, ma se è pari, n%2 è "false" (0), quindi restituisce -1. Quindi lo aggiungiamo semplicemente a n.

Soluzione precedente, 23 byte

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

n%2calcola il resto quando nè diviso per 2. Se è pari, questo restituisce 0 e l'elemento 0 in questo elenco è n-1. Se è dispari, questo restituisce 1 e l'elemento 1 in questo elenco è n+1.


1
Usa una lambda:lambda n:[n-1,n+1][n%2]
Leaky Nun,

Ah sì, quindi è stato più breve in questo caso. Fatto, grazie!
numbermaniac,

2

Retina , 21 byte

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


Provalo online! La mia prima risposta Retina con due nuove righe finali! Spiegazione: Le prime due righe vengono convertite da decimale a unario. La terza e la quarta riga sottraggono due dai numeri pari. L'ultima riga si converte in decimale, ma ne aggiunge anche una.



2

Cubix , 11 byte

u%2!I(/+@O<

Provalo online!

Spiegazione

Versione netta:

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

I personaggi vengono eseguiti nel seguente ordine:

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 byte

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

Provalo online!

Personalmente sono davvero contento di questa risposta perché è molto più breve di quanto riterrei un metodo tradizionale per risolvere questo problema.

Spiegazione

Il primo bit di codice

(({})(()))

converte lo stack da solo na

n + 1
  1
  n

Quindi, mentre la parte superiore della pila è diversa da zero, la diminuiamo e capovolgiamo il segno del numero sotto di essa

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

Rimuoviamo lo zero e aggiungiamo i due numeri rimanenti

{}({}{})

2

Mathematica, 22 19 byte

Salvato 3 byte grazie a Greg Martin!

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

Risposta precedente, 22 byte

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

Spiegazione (per risposta precedente)

Mathematica ha la bella caratteristica che operazioni come l'aritmetica passano automaticamente attraverso gli elenchi.

In questo caso, prendiamo Mod[#,2]che restituirà 0 o 1, ma dobbiamo aggiungere 1 perché gli elenchi Mathematica sono 1 indicizzati. Se è pari , questo risulta pari a 1, quindi #-1viene restituito. Se è strano , questo risulta pari a 2, quindi #+1viene restituito.


2
È possibile salvare i tre byte abusando di Mathematica [[0]]capacità: #-1[-1][[#~Mod~2]]&.
Greg Martin,

È folle, non ci avrei mai pensato. Fatto, grazie!
numbermaniac

2

Saggio , 8 byte

-::^~-^-

Provalo online!

Spiegazione

Se questo fosse il contrario, (decrementa se dispari, incrementa se pari), sarebbe abbastanza facile farlo.

Vorremmo solo capovolgere l'ultimo bit.

::^~-^

La soluzione qui è che capovolgiamo l'ultimo bit mentre siamo negativi. I numeri negativi sono 1 fuori dalla negazione dei numeri, ~quindi questo crea un offset che risolve il problema.

Quindi prendiamo semplicemente il programma e lo avvolgiamo -.

-::^~-^-

1

Java 8, 16 10 byte

n->-(-n^1)

Java 7, 34 28 byte

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

Porte noiose della sorprendente risposta C di @feersum .
Provalo qui.


Vecchie risposte:

Java 8, 16 byte

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

Java 7, 34 byte

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

Spiegazione (della vecchia risposta Java 7):

Provalo qui.

La risposta sopra è una variante più breve di int c(int n){return n%2<1?n-1:n+1;}sbarazzarsi dello spazio.

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 byte

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

Non ho ancora finito di giocare a golf (spero).


Suggerimenti sul golf: Befunge 98 ha la capacità di usare kv(o jvse è strettamente 1 o 0) invece di #v_. Inoltre, se lo stai usando Provalo online (e lo consiglio), puoi terminare il programma con un altro &(anche se ci vorranno 60 secondi), quindi puoi sbarazzarti di @sulla prima riga se lo usi. ecco l'elenco completo dei comandi per Befunge-98 , anche se potrebbero non essere tutti correttamente implementati in TIO, come &terminare il programma invece di invertire su EOF.
MildlyMilquetoast,

Inoltre, sembra che tu stia usando befunge 93 anziché 98, che ha meno comandi. Potresti voler correggere il nome del tuo link se è effettivamente 93 e non 98
MildlyMilquetoast

@MistahFiggins, ah sì, hai ragione, stavo usando 93.
Daniel,


1

R, 17 byte

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

dove n=scan()prende il valore della cifra.


Penso che tu abbia bisogno -(-1)^npiuttosto che da +(-1)^nquando dobbiamo tornare n-1se nè pari
Giuseppe,

@Giuseppe oh, sì, certo, errore folle
Nutle

1

Casio-Basic, 27 byte

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

26 byte per la funzione, +1 per entrare n nella casella dei parametri.




0

Lotto, 20 byte

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

Algoritmo riscoperto in modo indipendente @ feersum, onesto!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.