Échangez la parité


22

Tâche

Étant donné un entier positif n, la sortie n+1if nest impaire et la sortie n-1if nest paire.

Contribution

Un entier positif. Vous pouvez supposer que l'entier est dans la capacité de traitement de la langue.

Sortie

Un entier positif, spécifié ci-dessus.

Cas de test

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

Notation

C'est le , donc la réponse la plus courte en octets l'emporte.

Des échappatoires standard s'appliquent.

Les références


Pouvons-nous prendre l'avis comme unaire?
Kritixi Lithos

2
Ce serait, étonnamment, beaucoup plus facile si c'était l'inverse dans certaines langues
MildlyMilquetoast

3
@MistahFiggins C'est assez bien connu pour que je sois presque sûr qu'OP l'a fait comme ça exprès.
Ørjan Johansen

Réponses:


24

C, 20 octets

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

Essayez-le en ligne .


7
@LeakyNun Je n'écris pas une fonction sans déclaration de retour.
feersum

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

10
@Sisyphus Mais c'est du code-golf , et ça marche sur mon lien TIO, donc c'est valable.
Erik the Outgolfer

7
@EriktheOutgolfer Ce que je dis, c'est que votre déclaration ("l'affectation au premier argument équivaut à une déclaration de retour") est en fait incorrecte. La question de savoir si un tel code peut générer une réponse fonctionnelle dans certaines circonstances est une autre question (que j'ai abordée dans mon premier commentaire en déclarant que je prévois de ne pas publier un tel code).
feersum

8
@EriktheOutgolfer Si une réponse repose sur un comportement spécifique à l'implémentation, elle doit spécifier une implémentation. Cette réponse ne fait pas, donc ce code serait invalide.
Sisyphe

17

Chats empilés , 3 + 3 ( -n) = 6 octets

-*-

Essayez-le en ligne!

A besoin de -n indicateur pour fonctionner avec l'entrée et la sortie numériques.

Explication

Stack Cats est généralement loin d'être compétitif, en raison de son ensemble limité de commandes (qui sont toutes des injections, et la plupart sont des involutions) et parce que chaque programme doit avoir une symétrie miroir. Cependant, l'une des involutions est de basculer le bit le moins significatif d'un nombre, et nous pouvons compenser la valeur avec une négation unaire qui existe également. Heureusement, cela nous donne un programme symétrique, nous n'avons donc pas à nous soucier d'autre chose:

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

L'entrée et la sortie sont implicites au début et à la fin du programme, car prendre des entrées et produire des sorties n'est pas une opération réversible, donc elles ne peuvent pas être des commandes.


1
Les drapeaux sont-ils toujours comptés avec l'espace supplémentaire, je ne pense pas avoir vu d'autres réponses utilisant des drapeaux (comme Perl) faire cela? EDIT: Ok nvm, a trouvé le meta post pertinent . " Je compte ceux-ci comme une différence dans le nombre de caractères jusqu'à l'invocation équivalente la plus courte sans eux. " ... " perl -nle 'stuff'est 2 caractères de plus que perl -e 'stuff', donc il compte pour 2 caractères supplémentaires ". (space)-nEst donc 3 octets de plus que sans le drapeau.
Kevin Cruijssen

@KevinCruijssen Cela dépend du nombre d'octets que vous devez réellement ajouter à une invocation habituelle. En Perl et dans de nombreux autres langages de production, vous pouvez appeler le code avec -e "code"puis insérer des drapeaux supplémentaires avant e, par exemple -pe "code". Ensuite, le -pdrapeau n'est qu'un octet. Cependant, Stack Cats n'a pas un tel -eargument, vous devez donc toujours ajouter le plein <sp>-nà la commande, et donc c'est trois octets.
Martin Ender

12

Assemblage x86, 9 octets (pour entrée concurrente)

Tous ceux qui tentent ce défi dans des langages de haut niveau passent à côté du vrai plaisir de manipuler des bits bruts. Il y a tellement de variations subtiles sur les façons de le faire, c'est fou - et beaucoup de plaisir à penser. Voici quelques solutions que j'ai conçues en langage d'assemblage x86 32 bits.

Je m'excuse à l'avance que ce n'est pas la réponse typique de code-golf. Je vais beaucoup divaguer sur le processus de réflexion de l'optimisation itérative (pour la taille). J'espère que c'est intéressant et éducatif pour un public plus large, mais si vous êtes du type TL; DR, je ne serai pas offensé si vous sautez à la fin.

La solution évidente et efficace consiste à tester si la valeur est impaire ou paire (ce qui peut être fait efficacement en regardant le bit le moins significatif), puis à choisir entre n + 1 ou n − 1 en conséquence. En supposant que l'entrée est passée en tant que paramètre dans le ECXregistre et que le résultat est retourné dans le EAXregistre, nous obtenons la fonction suivante:

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

Mais à des fins de code-golf, ces LEAinstructions ne sont pas géniales, car elles nécessitent 3 octets pour être codées. Un simple DECélément de ECXserait beaucoup plus court (un seul octet), mais cela affecte les indicateurs, nous devons donc être un peu intelligents dans la façon dont nous organisons le code. Nous pouvons faire le décrément en premier et le test impair / pair en second , mais ensuite nous devons inverser le résultat du test impair / pair.

De plus, nous pouvons changer l'instruction de déplacement conditionnel en une branche, ce qui peut ralentir le code (selon la prévisibilité de la branche - si l'entrée alterne de manière incohérente entre impair et pair, une branche sera plus lente; s'il y a un modèle, il sera plus rapide), ce qui nous fera économiser un autre octet.

En fait, avec cette révision, toute l'opération peut être effectuée sur place, en utilisant un seul registre. C'est génial si vous insérez ce code quelque part (et les chances sont, vous le seriez, car il est si court).

    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 ligne: 7 octets; en fonction: 10 octets)

Et si vous vouliez en faire une fonction? Aucune convention d'appel standard n'utilise le même registre pour transmettre les paramètres que pour la valeur de retour, vous devez donc ajouter une MOVinstruction registre-registre au début ou à la fin de la fonction. Cela n'a pratiquement aucun coût en vitesse, mais cela ajoute 2 octets. (L' RETinstruction ajoute également un octet, et il y a un certain surcoût introduit par la nécessité de faire et de revenir à partir d'un appel de fonction, ce qui signifie que c'est un exemple où l'inline produit à la fois un avantage de vitesse et de taille, plutôt que d'être simplement une vitesse classique -pour l'espace.) En tout, écrit en fonction, ce code gonfle à 10 octets.

Que pouvons-nous faire d'autre en 10 octets? Si nous nous soucions des performances (au moins, des performances prévisibles ), ce serait bien de se débarrasser de cette branche. Voici une solution de branchement de bits sans branche qui a la même taille en octets. Le principe de base est simple: nous utilisons un XOR au niveau du bit pour inverser le dernier bit, en convertissant une valeur impaire en paire, et vice versa. Mais il y a un inconvénient - pour les entrées impaires, qui nous donne n-1 , tandis que pour les entrées paires, il nous donne n + 1 - exactement à l'opposé de ce que nous voulons. Donc, pour résoudre ce problème, nous effectuons l'opération sur une valeur négative, inversant efficacement le signe.

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 ligne: 7 octets; en fonction: 10 octets)

Assez lisse; il est difficile de voir comment cela peut être amélioré. Une chose attire mon attention, cependant: ces deux NEGinstructions de 2 octets . Franchement, deux octets semblent être un octet de trop pour encoder une simple négation, mais c'est l'ensemble d'instructions avec lequel nous devons travailler. Existe-t-il des solutions de contournement? Sûr! Si on XORpar -2, on peut remplacer la deuxième NEGation par un INCrement:

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

(en ligne: 6 octets; en fonction: 9 octets)

Une autre des bizarreries du jeu d'instructions x86 est l' LEAinstruction polyvalente , qui peut effectuer un déplacement registre-registre, une addition registre-registre, un décalage par une constante et une mise à l'échelle en une seule instruction!

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

L' ANDinstruction est semblable à l' TESTinstruction que nous avons utilisée précédemment, dans la mesure où les deux effectuent un ET au niveau du bit et définissent les indicateurs en conséquence, mais ANDmettent à jour l'opérande de destination. L' LEAinstruction les met ensuite à l'échelle 2, ajoute la valeur d'entrée d'origine et diminue de 1. Si la valeur d'entrée était impaire, cela en soustrait 1 (2 × 0 - 1 = -1); si la valeur d'entrée était paire, cela ajoute 1 (2 × 1 - 1 = 1).

C'est un moyen très rapide et efficace d'écrire le code, car une grande partie de l'exécution peut être effectuée dans le front-end, mais cela n'achète pas beaucoup d'octets, car il en faut tellement pour coder un complexe LEAinstruction. Cette version ne fonctionne pas aussi bien à des fins d'inline, car elle nécessite que la valeur d'entrée d'origine soit préservée en tant qu'entrée de l' LEAinstruction. Donc, avec cette dernière tentative d'optimisation, nous avons en fait reculé, ce qui suggère qu'il pourrait être temps de s'arrêter.


Ainsi, pour l'entrée finale en compétition, nous avons une fonction de 9 octets qui prend la valeur d'entrée dans le ECXregistre (une convention d'appel basée sur un registre semi-standard sur 32 bits x86), et renvoie le résultat dans le EAXregistre (comme avec toutes les conventions d'appel 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

Prêt à assembler avec MASM; appeler de C comme:

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

Ne fonctionnerait pas simplement dec eax; xor eax, 1; inc eaxet économiserait-il un octet de plus?
Ilmari Karonen


11

Python3, 20 18 octets

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

Assez simple. Nous calculons d'abord n-1 et décidons d'ajouter ou non 2.

Si n est pair -> n mod 2 sera 0, donc nous ajouterons 2 * 0 à n-1 , résultant en n-1 .

Si n est impair -> n mod 2 sera 1, donc nous ajouterons 2 * 1 à n-1 , résultant en n + 1 .

Je préfère une explication que j'ai faite avec de la peinture MS et un pavé tactile d'ordinateur portable ... Visual explanation


10

Python, 16 octets

lambda x:-(-x^1)

Essayez-le en ligne!


3
Le forçage brutal ne trouve pas de solution plus courte en utilisant des caractères dans "x+-012~|&^()*/%".
2017

@xnor Heureusement que je l'ai eu alors!
sagiksp

1
Et il semble qu'il n'y ait pas d'autres solutions de même longueur, sauf le réarrangement trivial -(1^-x).
xnor

8

MATL , 7 octets

Q:HePG)

Cela évite toute opération arithmétique. Essayez-le en ligne!

Explication

Considérez la saisie 4comme exemple.

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
Agréable! J'aime ça !
Stewie Griffin

6

Braingolf v0.1 , 11 10 octets

.1>2,%?+:-

Essayez-le en ligne! (Le deuxième argument est le code Braingolf, le troisième argument est l'entrée)

Un octet enregistré grâce à Neil

Première réponse de braingolf en compétition: D

Explication:

.            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 octets [non concurrent]

.2%?1+:1-

Essayez-le en ligne! (Le deuxième argument est le code Braingolf, le troisième argument est l'entrée)

Voir ci-dessus pour l'explication. Seule différence dans Braingolf v0.2, le comportement par défaut des opérateurs diadiques et la fonction du ,modificateur sont inversés, ce qui signifie que les 2 virgules dans la réponse v0.1 ne sont plus nécessaires.

Cependant la v0.2 a été publiée après le défi, donc celui-ci n'est pas en compétition


5
Félicitations pour votre nouvelle langue!
Leaky Nun

Fait .1<2,%?+:-ce que je pense qu'il fait?
Neil

@Neil pas tout à fait, vous auriez besoin d'une virgule avant le -pour que l'opération soit effectuée dans le bon sens, auquel cas ce serait toujours la même longueur que ma réponse
Skidsdev

@ Mayube Je m'attendais <à 1ce que le fasse pivoter sous l'entrée, de sorte qu'il soit déjà au bon endroit.
Neil

@Neil si l'entrée est un nombre pair, au moment où elle atteint la -pile, cela ressemble à ceci: les [n,1]opérateurs braingolf sont inversés, donc cela fonctionnerait 1 - n, ce qui se traduirait par -(n-1), alors que le résultat souhaité est simplementn-1
Skidsdev

5

Cubix , 10 9 octets

cO1)I(//@

Essayez-le en ligne

Explication

Version nette

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

Les caractères exécutés sont

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

4

Python, 68 octets

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

Dans l'esprit d'une approche unique. Le graphique suivant montre la fonction (avec des points violets représentant les 10 premiers cas). Il devrait en théorie être possible de construire une solution pour cette question basée sur la plupart (toutes?) Des fonctions périodiques (par exemple sin, tan, sec). En fait, remplacer cos pour sec dans le code tel quel devrait fonctionner.

Graph demonstrating function


3

PHP, 15 octets

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

2
Comment puis-je exécuter cela? J'essaie de tester si le ;est requis, et j'ai essayé d'utiliser un .phpfichier et aussi d'écho directement dans php (php7 cli.) Chaque fois, on me dit que $argnc'est une variable non définie.
Andrakis

2
@Andrakis Avec le Fdrapeau et d' un pipeline: echo 42 | php -F script.php.
user63956

3

Javascript, 17 12 octets

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

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

Une autre approche, 10 octets volés de la réponse C (sssshhh)

x=>-(-x^1)

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


1. vous n'avez pas besoin d'inclure le point-virgule; 2.x=>x-(-1)**x
Leaky Nun

Pourquoi |0? Les deux solutions semblent devoir convertir automatiquement les chaînes en nombres. (Pour la première solution, si vous voulez éviter les décimales, utilisez <input type=number>.)
Neil

@Neil Merci de m'avoir prévenu!
Matthew Roh

3

JavaScript (ES6), 14 13 12 10 octets

n=>-(-n^1)
  • 1 octet économisé grâce à Luke .
  • 2 octets économisés en portant la solution C de feersum . (Si cela est mal vu, faites-le moi savoir et je reviendrai à ma solution précédente ci-dessous)

Essayez-le

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


Original, 12 octets

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

2

Python, 20 octets

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

n%2or-1renverra 1 s'il est impair, mais s'il est pair, n%2est "faux" (0), donc il renvoie plutôt -1. Ensuite, nous ajoutons simplement cela à n.

Solution précédente, 23 octets

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

n%2calcule le reste lorsque nest divisé par 2. S'il est pair, cela renvoie 0, et l'élément 0 dans cette liste est n-1. Si c'est impair, cela renvoie 1, et l'élément 1 de cette liste est n+1.


1
Utilisez un lambda:lambda n:[n-1,n+1][n%2]
Leaky Nun

Ah oui, donc c'était plus court dans ce cas. Fini merci!
numbermaniac

2

Rétine , 21 octets

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


Essayez-le en ligne! Ma première réponse Retina avec deux nouvelles lignes de queue! Explication: Les deux premières lignes sont converties de décimales en unaires. Les troisième et quatrième lignes soustraient deux des nombres pairs. La dernière ligne redevient décimale, mais en ajoute une aussi.



2

Cubix , 11 octets

u%2!I(/+@O<

Essayez-le en ligne!

Explication

Version nette:

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

Les caractères sont exécutés dans l'ordre suivant:

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 octets

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

Essayez-le en ligne!

Personnellement, je suis vraiment satisfait de cette réponse car elle est beaucoup plus courte que ce que je considérerais comme une méthode traditionnelle pour résoudre ce problème.

Explication

Le premier morceau de code

(({})(()))

convertit la pile de juste nen

n + 1
  1
  n

Ensuite, alors que le haut de la pile est non nul, nous le décrémentons et retournons le signe du nombre en dessous

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

Nous supprimons le zéro et ajoutons les deux nombres restants

{}({}{})

2

Mathematica, 22 19 octets

Enregistré 3 octets grâce à Greg Martin!

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

Réponse précédente, 22 octets

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

Explication (pour la réponse précédente)

Mathematica a la fonctionnalité intéressante que les opérations telles que l'arithmétique passent automatiquement sur les listes.

Dans ce cas, nous prenons Mod[#,2]qui retournera 0 ou 1, mais nous devons ajouter 1 car les listes Mathematica sont indexées sur 1. Si c'est pair , cela revient à 1, donc #-1est retourné. Si c'est étrange , cela revient à 2, donc #+1est retourné.


2
Vous pouvez enregistrer trois octets en abusant de Mathematica [[0]]capacité: #-1[-1][[#~Mod~2]]&.
Greg Martin

C'est fou, je n'aurais jamais pensé à ça. Fini merci!
numbermaniac

2

Sage , 8 octets

-::^~-^-

Essayez-le en ligne!

Explication

Si c'était l'inverse, (décrémenter si impair, incrémenter si pair), ce serait assez facile à faire.

Nous retournerions simplement le dernier morceau.

::^~-^

Le correctif ici est que nous inversons le dernier bit tout en étant négatif. Les nombres négatifs sont à 1 de la négation des nombres~ , ce qui crée un décalage résolvant le problème.

Nous retirons donc le programme et l'enveloppons -.

-::^~-^-

1

Java 8, 16 10 octets

n->-(-n^1)

Java 7, 34 28 octets

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

Ports ennuyeux de la réponse C étonnante de @feersum .
Essayez-le ici.


Anciennes réponses:

Java 8, 16 octets

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

Java 7, 34 octets

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

Explication (de l'ancienne réponse Java 7):

Essayez-le ici.

La réponse ci-dessus est une variante plus courte de int c(int n){return n%2<1?n-1:n+1;}l'élimination de l'espace.

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 octets

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

Je n'ai pas encore fini de jouer au golf (j'espère).


Conseils de golf: Befunge 98 a la possibilité d'utiliser kv(ou jvs'il est strictement 1 ou 0) au lieu de #v_. De plus, si vous utilisez Try it online (et je le recommande), vous pouvez terminer le programme avec un autre &(bien que cela prenne 60 secondes), vous pouvez donc vous débarrasser de la @sur la première ligne si vous l'utilisez. voici la liste complète des commandes pour Befunge-98 , bien qu'elles ne soient pas toutes correctement implémentées dans TIO, comme &mettre fin au programme au lieu d'inverser sur EOF.
MildlyMilquetoast

De plus, il semble que vous utilisiez befunge 93 au lieu de 98, qui a moins de commandes. Vous voudrez peut-être corriger le nom de votre lien s'il est en effet 93 et ​​non 98
MildlyMilquetoast

@MistahFiggins, ah oui vous avez raison j'utilisais 93.
Daniel


1

R, 17 octets

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

n=scan()prend la valeur numérique.


Je pense que vous avez besoin -(-1)^nplutôt que +(-1)^npuisque nous devons revenir n-1si nc'est pair
Giuseppe

@Giuseppe oh, oui, bien sûr, erreur stupide
Nutle

1

Casio-Basic, 27 octets

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

26 octets pour la fonction, +1 à saisir ndans la case des paramètres.




0

Lot, 20 octets

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

Redécouvert indépendamment l'algorithme de @ feersum, honnête!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.