Moins, Plus, Temps, Exponentiation?

26

Ceci est un CMC (mini défi de chat) que j'ai publié dans notre salon de discussion, The Ninteenth Byte , il y a un peu.

Le défi

Étant donné un entier positif x, en fonction des 2 derniers bits de x, procédez comme suit:

x & 3 == 0: 0
x & 3 == 1: x + x
x & 3 == 2: x * x
x & 3 == 3: x ^ x (exponentiation)

Entrée sortie

Single Integer -> Single Integer  

Une nouvelle ligne de fin est autorisée dans la sortie. Aucun autre espace n'est autorisé.

Cas de test

input       output
    1            2
    2            4
    3           27
    4            0
    5           10
    6           36
    7       823543
    8            0
    9           18
   10          100
   11 285311670611
   12            0

C'est un défi de , donc le code le plus court gagne!

HyperNeutrino
la source
8
Ne devrait pas le 0cas être x + 2, car comment les autres sont x * 2, x ^ 2et x ^^ 2(tétration)? : P
ETHproductions
Quelle est la plus grande production que nous devrions soutenir (concernant x ^ x)? 32 bits ne sont déjà pas suffisants pour le scénario de test 11et 64 bits ne sont pas suffisants pour le scénario de test 19.
Kevin Cruijssen
@KevinCruijssen Je dirai que vous n'avez à gérer que les cas où l'entrée et la sortie sont dans la portée de votre langage, tant que votre programme fonctionnerait théoriquement avec une taille de nombre infinie.
HyperNeutrino
@HyperNeutrino Ok, dans ce cas, j'ai corrigé mon code (Java 7) (pour +72 octets .. xD)
Kevin Cruijssen

Réponses:

13

Gelée , 8 octets

ị“+×*_”v

Essayez-le en ligne!

Comment ça marche

Tout d'abord, notez que x&3c'est équivalent à x%4, où %est modulo. Ensuite, puisque Jelly utilise l'indexation modulaire (a[n] == a[n+len(a)] ), nous n'avons donc même pas besoin de gérer cela.

Ensuite:

  • Si x%4==0, retourx_x (soustraction) (pour cohérence);
  • Si x%4==1, retourx+x ;
  • Si x%4==2, retourx×x (multiplication);
  • Si x%4==3, retour x*x(exponentiation)

Notez que Jelly utilise l'indexation 1, donc la soustraction "_"est déplacée à la fin.

ị“+×*_”v  example input: 10
ị“+×*_”   index 10 of the string “+×*_”, which gives "×"
       v  evaluate the above as a Jelly expression,
          with 10 as the argument, meaning "10×" is the
          expression evaluated. The dyad "×" takes the
          second argument from the only argument, effectively
          performing the function to itself.
Leaky Nun
la source
2
@andrybak AFAIK Jelly a son propre encodage - voir ici , mais je sais que tous ses caractères font 1 octet.
Stephen
"8 octets". Comment les octets doivent-ils être comptés? Cette réponse se compose de huit caractères, mais au moins dans l'encodage stackexchange sert cette page, elle prend 15 octets (comptés à l'aide wc --bytes).
andrybak
Si le langage l'interprète dans un codage, cela n'a pas de sens d'utiliser un autre codage pour le nombre d'octets (imo)
Mackenzie McClane
@andrybak Le code encodé dans un encodage pour que le navigateur le montre correctement est de 15 octets. Le code dans un encodage que Jelly comprend est de 8 octets. Regardez github.com/DennisMitchell/jelly/wiki/Code-page si vous voulez savoir comment il est encodé.
Etoplay
13

Python , 30 octets

lambda x:[0,x+x,x*x,x**x][x%4]

Essayez-le en ligne!

Mego
la source
2
Version alternative sur python 2: 'lambda x: [0,2, x, x ** x / x] [x% 4] * x'.
TLW
9

CJam , 12 octets

ri__"-+*#"=~

Essayez-le en ligne!

Explication

ri            e# Read an int from input (call it x).
  __          e# Duplicate x twice.
    "-+*#"    e# Push this string.
          =   e# Get the character from the string at index x (mod 4).
           ~  e# Eval that char, using the two copies of x from before.

Exécute l'une des opérations suivantes en fonction de xla valeur de mod 4 (le mod 4 est équivalent à AND 3).

0:  -  Subtraction
1:  +  Addition
2:  *  Multiplication
3:  #  Exponentiation
Chat d'affaires
la source
6

Mathematica 25 octets

0[2#,#*#,#^#][[#~Mod~4]]&

4 octets enregistrés grâce à @MartinEnder

Kelly Lowder
la source
4

Pyth, 8 octets

.v@"0y*^

Interprète

Erik le Outgolfer
la source
Oui, je l'ai testé et cela fonctionne. Et non, je ne peux pas utiliser à la vplace de .v.
Erik the Outgolfer
Je pensais que la portée était locale ... Je pensais que je .vne pouvais pas y accéder Q... Apparemment, je me suis fait déjouer en Pyth. +1 pour vous.
Leaky Nun
@LeakyNun Non, c'est ce vqui a une portée locale, .vjuste une expression.
Erik the Outgolfer
J'ai beaucoup à apprendre ...
Leaky Nun
3
C'est beau! C'est absolument incroyable! Je ne savais même pas que c'était possible. Pour les points de style, "0y*^pourrait l'être "-+*^.
isaacg
3

Haskell, 28 27 octets

f x=cycle[0,x+x,x*x,x^x]!!x

Essayez-le en ligne!

Edit: Merci à @ Ørjan Johansen pour 1 octet.

nimi
la source
Hm je suis très en retard, mais vous pouvez raccourcir cet octet avec cycle.
Ørjan Johansen
@ ØrjanJohansen: mieux vaut tard que jamais. Merci!
nimi
2

C, 63 ou 62 octets

#include<math.h>
f(x){return(int[]){0,x+x,x*x,pow(x,x)}[x&3];}

-1 octet si les macros sont autorisées, en supposant que ce xn'est pas une expression comme 3+5(car cela gâcherait la priorité):

#include<math.h>
#define f(x)(int[]){0,x+x,x*x,pow(x,x)}[x&3]
Tim Čas
la source
@ceilingcat Oui, j'ai oublié ça.
Tim Čas
ne compile pas sur MSVS2015; Intellisense a dit que le cast to incomplete array type "int[]" is not allowedcompilateur a dit error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax; ÉGALEMENT! où est int f (int x)? le code est en fait au moins 8 octets plus long; il est également très lent et inefficace, car il évalue tout - ne le répétez pas IRL)
@ xakepp35 Quoi? 1) il doit compiler dans un compilateur C. La plupart (lire: à peu près tous sauf MSVC) des compilateurs C prennent en charge cette (int[])syntaxe pour cette situation. 2) f(x)est parfaitement légal C89. Je n'ai pas précisé la norme. 3) Il s'agit de la taille du code, pas de l'efficacité. Et 4) Si vous allez être condescendant, utilisez au moins un vrai compilateur et / ou vérifiez vos faits.
Tim Čas
@Tim Čas Ah oui, excusez-moi! J'essayais de le compiler en code C ++. C'est ma faute) Il compile et fonctionne très bien!
2

Java 7, 75 octets

long c(int n){int x=n%4;return x<1?0:x<2?n+n:x<3?n*n:(long)Math.pow(n,n);}

Même s'il est valide selon les règles, il longest de 64 bits, il échoue donc pour les cas de test d'exponentiation de 19^19et au-dessus. Pour résoudre ce problème, nous pouvons utiliser une BigDecimalapproche:

148 146 octets

import java.math.*;BigDecimal c(int n){int x=n%4;BigDecimal m=new BigDecimal(n);return x<1?m.subtract(m):x<2?m.add(m):x<3?m.multiply(m):m.pow(n);}

Explication (de l'approche BigDecimal):

import java.math.*;                // Import required for BigDecimal
BigDecimal c(int n){               // Method with integer parameter and BigDecimal return-type
  int x=n%4;                       //  Input modulo-4
  BigDecimal m=new BigDecimal(n);  //  Convert input integer to BigDecimal
  return x<1?                      //  If the input mod-4 is 0:
    m.subtract(m)                  //   Return input - input (shorter than BigDecimal.ZERO)
   :x<2?                           //  Else if the input mod-4 is 1:
    m.add(m)                       //   Return input + input
   :x<3?                           //  Else if the input mod-4 is 2:
    m.multiply(m)                  //   Return input * input
   :                               //  Else:
    m.pow(n);                      //   Return input ^ input
}                                  // End of method

Code de test:

Essayez-le ici.

import java.math.*;
class M{
  static BigDecimal c(int n){int x=n%4;BigDecimal m=new BigDecimal(n);return x<1?m.subtract(m):x<2?m.add(m):x<3?m.multiply(m):m.pow(n);}

  public static void main(String[] a){
    for (int i = 1; i <= 25; i++) {
      System.out.print(c(i) + "; ");
    }
  }
}

Sortie:

2; 4; 27; 0; 10; 36; 823543; 0; 18; 100; 285311670611; 0; 26; 196; 437893890380859375; 0; 34; 324; 1978419655660313589123979; 0; 42; 484; 20880467999847912034355032910567; 0; 50; 
Kevin Cruijssen
la source
Vous n'avez pas besoin de corriger le programme de cette façon: P L'ancienne réponse fonctionnerait si les nombres avaient une taille infinie; le premier programme aurait été valide selon mes spécifications. : P
HyperNeutrino
@HyperNeutrino Ensuite, je précise que dans la réponse .. Eh bien, Java ne remportera aucun défi de code-golf de toute façon. ;)
Kevin Cruijssen
1
Oui, je préciserais. Et oui, c'est Java, ça ne va pas gagner. : D
HyperNeutrino
2
" Et oui, c'est Java, ça ne va pas gagner.: D " J'y suis habitué. : P Même ma réponse Java la plus courte de 8 octets est trop longue par rapport aux réponses de golf. xD Bien que c'était la première fois que je battais une réponse Python avec ma réponse Java, qui doit compter pour quelque chose que je suppose. ;)
Kevin Cruijssen
2

Assembleur x86, syntaxe Intel, 192 octets

.data
f dw @q,@w,@e,@r
.code
mov ecx, eax
and ecx, 3
mov edx,dword ptr f[ecx*4]
call [edx]
ret
q:
xor eax,eax
ret
w:
add eax,eax
ret
e:
mul eax,eax
ret
r:
mov ecx,eax
t:
mul eax,eax
loop t
ret

L'exemple prétend la vitesse de travail la plus rapide. Is est un programme ou une partie de programme qui utilise la convention fastcall. Il suppose une variable d'entréex dans le registreeax et renvoie le résultat également danseax . L'idée de base est d'éviter d'utiliser des sauts conditionnels, comme dans certains exemples ici. En outre, il ne s'agit pas de tout évaluer (comme dans l'exemple C avec des tableaux), mais d'utiliser un tableau de pointeurs vers des fonctons et de faire des sauts inconditionnels plus rapides (jmp / call) comme un analogique "C language switch () - case .." optimisé. Cette technique pourrait également être utile dans des types d'automates finis, comme les émulateurs de processeurs, les exécuteurs, etc.

Mise à jour: pour x64, utilisez "r" dans les noms de registres, au lieu de "e" (par exemple raxau lieu de eax, rcxau lieu de ecx). La taille ne sera pas modifiée et elle utilisera des mots non signés 64 bits.


la source
Bienvenue chez PPCG! L'objectif de ce challenge est de rendre votre code le plus court possible. Dans ce cas, votre code pourrait facilement être raccourci en combinant toutes ces déclarations de fonction. Vous pouvez également supprimer certains espaces.
HyperNeutrino
@HyperNeutrino asm lui-même est un peu "long" langage :) donc je n'ai aucune idée sur la façon de raccourcir cela. des exemples de conseils?
Eh, désolé, je dois avoir copié mon commentaire sur votre réponse C dans ce post. Je ne sais pas comment programmer dans ASM mais pourriez-vous potentiellement supprimer des espaces?
HyperNeutrino
@HyperNeutrino, désolé .. mais semble non) il doit être le code le plus long parmi d'autres, je peux simplement tronquer les fenêtres crlf au format linux donc 209-> 192 octets, les changements ne sont pas visibles)
Aw. C'est dommage. Mais belle soumission malgré tout! :)
HyperNeutrino
2

C #, 39 octets

x=>new[]{0,2,x,Math.Pow(x,x-1)}[x&3]*x;

Explication

Observe ceci:

(xx, x + x, x * x, x ^ x) == (0, 2, x, x ^ (x-1)) * x

La solution crée un tableau, y indexe puis multiplie le résultat par x:

x => new[] { 0, 2, x, Math.Pow(x,x-1) }[x&3] * x;

Versions alternatives:

x=>new[]{0,x+x,x*x,Math.Pow(x,x)}[x%4];

(39B, toute multiplication effectuée dans le tableau, x%4remplace x&3)

x=>x%4<2?x%2*2*x:Math.Pow(x,x%4<3?2:x);

(39B, identique à la réponse de @ MetaColon mais x%2*2*xremplaçant x*x%4<1?0:2)

user1655772
la source
1

En fait , 12 octets

;;3&"-+*ⁿ"Eƒ

Essayez-le en ligne!

Explication:

;;3&"-+*ⁿ"Eƒ
;;            two copies of input (so 3 total)
  3&          bitwise AND with 3
    "-+*ⁿ"E   index into this string
           ƒ  call the respective function
Mego
la source
1

J , 14 octets

4&|{0,+:,*:,^~

Essayez-le en ligne!

Leaky Nun
la source
(4&|{-,+,*,^)~fonctionne aussi bien mais c'est le même nombre d'octets en raison des parens, bien que ce soit un peu plus évident.
Cyoce
1

Oasis , 25 octets

mn4%3Q*nkn4%2Q*nxn4%1Q*++

Essayez-le en ligne!

Comment ça marche

Notez que cela x&3équivaut à x%4, où %est modulo.

mn4%3Q*nkn4%2Q*nxn4%1Q*++  input is n
mn4%3Q*                    (n**n)*((n%4)==3)
       nkn4%2Q*            (n**2)*((n%4)==2)
               nxn4%1Q*    (n*2)*((n%4)==1)
                       +   add the above two
                        +  add the above two

Oasis est un langage basé sur la pile où chaque personnage est une commande.

Leaky Nun
la source
1

C #, 42 octets

x=>x%4<2?x*x%4<1?0:2:Math.Pow(x,x%4<3?2:x)

En fait, c'est C # normal, mais comme vous ne pouvez pas l'exécuter comme un programme entier et que vous devez le taper dans l'interactif, je suppose que vous pouvez l'appeler C # interactif .

Explication :

x => (x % 4) < 2     //If the bits are smaller than 2 (1 or 0)
? x *           //multiply x with
    (x % 4) < 1 //if the bits are 0
    ? 0         //0 (results in 0)
    : 2         //or else with 2 (results in 2*x or x+x)
: Math.Pow(x,   //otherwise power x by
    (x % 4) < 3 //if the bits are 2
    ? 2         //2 (results in x^2 or x*x)
    : x);       //or else x (results in x^x)

Je ne peux pas dire si c'est la variante la plus courte, toutes les suggestions sont appréciées.

MetaColon
la source
Je ne pense pas que ce soit valable. Vous devez généralement soumettre un programme ou une fonction . Les extraits de code ne sont pas autorisés par défaut.
Cyoce
@Cyoce C'est un programme. Il vous suffit de l'exécuter via l'interactif, qui interprétera le programme.
MetaColon
Lorsque j'exécute ceci en interactif, j'obtiens une erreur car il xn'est pas défini. Cela en fait un extrait, pas un programme complet.
Cyoce
@Cyoce Dans le défi qu'il a dit, il y aurait une variable x définie.
MetaColon
Ce n'est pas ce que cela signifie. « Etant donné un entier positif x» signifie que vous êtes donnés x par un procédé d'entrée standard ( par exemple, de la fonction ou du programme).
Cyoce
1

PHP, 36 octets

<?=[0,2,$x=$argn,$x**~-$x][$x&3]*$x;
user63956
la source
1

dc, 27

Je n'ai jamais eu l'occasion d'utiliser des tableaux en DC auparavant:

[+]1:r[*]2:r[^]3:r?dd4%;rxp

Essayez-le en ligne .

Traumatisme numérique
la source
1

C, 115 octets

#include<math.h>
#define D(K,L)K(x){return L;}
D(q,0)D(w,x+x)D(e,x*x)D(r,pow(x,x))(*g[])()={q,w,e,r};D(f,g[x%4](x))

L'exemple est une fonction int f(int x)

Il prétend la vitesse de travail la plus rapide car il empêche le CPU d'utiliser des sauts conditionnels. Et ce n'est que la manière correcte d'optimiser la vitesse pour cette tâche. En outre, il essaie de ne pas tout évaluer, comme dans l'exemple du tableau C, return(int[]){0,x+x,x*x,pow(x,x)}[x%4];mais d'utiliser judicieusement le tableau de pointeurs vers les fonctons, afin de faire des sauts inconditionnels beaucoup plus rapides (jmp / call) avec une arithmétique d'adresse beaucoup plus rapide, comme une version optimisée de " switch () - case .. ". Cette technique pourrait également être utile dans plusieurs types d'automates finis - comme les émulateurs de processeur, les exécuteurs, les analyseurs de flux de commandes, etc. - où la vitesse est importante et le code comme switch(x%4) case(0):... case(1):... ne convient pas car elle produit plusieurs instructions cmp / jnz; et ce sont des opérations coûteuses pour le CPU

Le programme de test le plus simple et le plus court (dans les conditions par défaut) pour le cas sera le suivant:

D(main,f(x))

Il ajoutera seulement 12 octets de charge utile et totalisera notre taille à 127 octets;

Mais il vaut mieux dire à l'éditeur de liens d'utiliser la ffonction comme point d'entrée au lieu de main. C'est le moyen, si nous visons à obtenir le binaire de travail le plus rapide possible pour cette tâche à partir du code le plus court ;-) Cela se produit car la bibliothèque C ajoute du code init / shutdown supplémentaire avant d'appeler votre fonction main ().

Le code se compile sur MSVS Community 2015 sans trucs et problèmes et produit des résultats corrects. Je ne l'ai pas testé avec gcc, mais je suis sûr que cela fonctionnera aussi bien.


la source
1
Bienvenue chez PPCG! L'objectif de ce challenge est de rendre votre code le plus court possible. Dans ce cas, votre code pourrait facilement être raccourci en combinant toutes ces déclarations de fonction. Vous pouvez également supprimer certains espaces.
HyperNeutrino
J'aime l'idée d'utiliser des pointeurs vers des fonctions
RosLuP
@RosLuP oui, mais c'est presque deux fois plus long que votre version à 60 octets. mais ça marche beaucoup plus vite, ça vaut sa taille.
@Hyper Neutrino Okay. Je l'ai plus compressé. Semble, c'est la version finale! Il n'y a pas de bugs, tous les tests ont réussi 8-)
@ xakepp35 avez-vous mesuré votre est plus rapide que le mien?
RosLuP
1

R, 47 42 octets

x=scan();c(`-`,`+`,`*`,`^`)[[x%%4+1]](x,x)

Applique la fonction -, +, *, ou ^sur la base du module xde xet x.

- est la seule chose (un peu) intelligente, car x-x est toujours 0.

R, 33 octets

pryr::f(c(0,2*x,x^2,x^x)[x%%4+1])

Même méthode que les autres utilisent. Bien qu'il soit plus court, je ne l'aime pas autant.

JAD
la source
0

Pyth , 12 octets

.vjd,+@"-+*^

Essayez-le en ligne!

Comment ça marche

Tout d'abord, notez que x&3c'est équivalent à x%4, où %est modulo. Ensuite, puisque Pyth utilise l'indexation modulaire ( a[n] == a[n+len(a)]), nous n'avons donc même pas besoin de gérer cela.

Ensuite:

  • Si x%4==0, retournez x-x(pour cohérence);
  • Si x%4==1, revenezx+x ;
  • Si x%4==2, revenezx*x ;
  • Si x%4==3, revenez x^x.

.vjd,+@"-+*^  example input: 10
      @"-+*^  "-+*^"[10], which is "*"
     +        "*10"
    ,         ["*10","10"]
  jd          "*10 10"
.v            evaluate as Pyth expression
              (Pyth uses Polish notation)

En savoir plus sur la notation polonaise: Wikipedia (tant pis si vous êtes en Turquie).

Leaky Nun
la source
Huh? This just seems too much to me. See my answer for details.
Erik the Outgolfer
0

Japt, 13 bytes

Ov"^+*p"gU +U

Try it online!

This uses the same method as the other eval answers, except the program -U just negates U, so we use ^ (bitwise XOR) instead.

ETHproductions
la source
0

Vim, 50 bytes

y$o^R"A-+*^^V^[0^R"lx0"_Dp^[0D@"kJ0"ad$:r!echo ^R"^R0|bc^<Enter>

Here, ^V represents a Ctrl+V, ^R represents Ctrl-R and ^[ represents the esc key

Works by first building up the expression and then letting bc evaluate it. Expects the input on the first line in an otherwise empty buffer.

Explanation:

y$o^R"                                                          Copies the input into register " and pastes it on the second line
      A-+*^^V^[0^R"lx0"_Dp                                      Enters that text after the input on the second line
                          ^[0D@"                                Executes the second line as a Vim command.
                                                                For example, if the input is 12, the second line would be 12A-+*^^[012lx0"_Dp, which means:
                                                                  12A-+*^^[           Insert the text -+*^ 12 times
                                                                           012lx0"_Dp Go 12 chars to the right and remove everything except for that.
                                                                If effect, this basically just selects the appropriate operation.
                                kJ0"ad$                         Put the operator after the number, cut it into register a
                                       :r!                      Execute the following shell command and put the result into the buffer:
                                          echo ^R"^R0|bc<Enter> The shell command "echo [contents of register a][contents of registers 0]|bc. As said above, register a contains the input and the operator, and register 0 contains the input. The <enter> then executes this command.
Loovjo
la source
When I type ^V it just pastes what I have in my clipboard, instead of the number...
Leaky Nun
1
Try it online! Also, You can do D instead of d$
DJMcMayhem
0

Pyth, 9 bytes

@[0yQ*QQ^

Test suite

Nothing fancy going on here, just calculate the four values, and select one with modular indexing.

@[0yQ*QQ^
@[0yQ*QQ^QQ)Q    Implicit variable introduction
@           Q    Modularly index into the following list
 [0        )     0
   yQ            Q*2
     *QQ         Q*Q
        ^QQ      Q^Q
isaacg
la source
0

Batch, 135 bytes

@set/an=%1*2^&6
@goto %n%
:6
@set n=1
@for /l %%i in (1,1,%1)do @set/an*=%1
@goto 0
:4
@set n=%1
:2
@set/an*=%1
:0
@echo %n%

I was hoping to create the exponentiation by building up and evaluating a string of the form [0+...+0, 2+...+2, x+...+x, x*...*x] depending on the last two bits of x but unfortunately the code to select the operation took too long to express because I couldn't use * as a for parameter, but I was at least able to use some fall-though trickery to golf away some bytes.

Neil
la source
0

Retina, 87 bytes

.+
$*1;$&$*
;((1111)*)(1?)$
;$3$3
1(?=1.*;((1111)*111)$)
$1;
+`\G1(?=.*;(1*))|;1*$
$1
1

Try it online! (Link includes test suite.)

Explanation: The first two lines convert the input into unary and duplicate it (so we now have x;x). The next two lines look for an x&3 of either 0 or 1 and change x;x into x;0 or x;2 appropriately. The next two lines look for x&3==3 and change x;x into x;x;x;...;x;1;x (x xs). This means that we have either x;0, x;2, x;x, or x;...;x and it remains to multiply everything together and convert back to decimal. (The multiplication code is based on that in the Retina wiki but amended to handle multiplication by zero.)

Neil
la source