Calculatrice d'opérations entières simples


28

Implémentez une calculatrice scriptable d'opération d'entier simple.

Concept

L'accumulateur démarre à 0 et des opérations y sont effectuées. A la fin du programme, sortir la valeur de l'accumulateur.

Opérations:

  • +ajoute 1à l'accumulateur
  • -soustrait 1de l'accumulateur
  • * multiplie l'accumulateur par 2
  • / divise l'accumulateur par 2

Exemple de script

L'entrée ++**--/doit donner la sortie 3.

Exemple d'implémentation

def calc(s)
    i = 0
    s.chars.each do |o|
        case o
            when '+'
                i += 1
            when '-'
                i -= 1
            when '*'
                i *= 2
            when '/'
                i /= 2
        end
    end
    return i
end

Règles

  • Il s'agit de , donc la réponse la plus basse en octets l'emporte, mais elle n'est pas sélectionnée.
  • Les implémentations créatives sont encouragées.
  • Les failles standard sont interdites.
  • Vous obtenez le programme via stdin ou des arguments, et vous pouvez sortir la réponse via la valeur de retour ou stdout.
  • S'amuser.
  • La division est tronquée car il s'agit d'une division entière.
  • Le programme -/revient -1.

Cas de test

*///*-*+-+
-1
/*+/*+++/*///*/+-+//*+-+-/----*-*-+++*+**+/*--///+*-/+//*//-+++--++/-**--/+--/*-/+*//*+-*-*/*+*+/+*-
-17 
+++-+--/-*/---++/-+*-//+/++-*--+*+/*/*/++--++-+//++--*/***-*+++--+-*//-*/+*/+-*++**+--*/*//-*--**-/-*+**-/*-**/*+*-*/--+/+/+//-+*/---///+**////-*//+-+-/+--/**///*+//+++/+*++**++//**+**+-*/+/*/*++-/+**+--+*++++/-*-/*+--/++*/-++/-**++++/-/+/--*/-/+---**//*///-//*+-*----+//--/-/+*/-+++-+*-*+*+-/-//*-//+/*-+//+/+/*-/-/+//+**/-****/-**-//+/+-+/*-+*++*/-/++*/-//*--+*--/-+-+/+/**/-***+/-/++-++*+*-+*+*-+-//+/-++*+/*//*-+/+*/-+/-/*/-/-+*+**/*//*+/+---+*+++*+/+-**/-+-/+*---/-*+/-++*//*/-+-*+--**/-////*/--/*--//-**/*++*+/*+/-+/--**/*-+*+/+-*+*+--*///+-++/+//+*/-+/**--//*/+++/*+*////+-*-//--*+/*/-+**/*//+*+-//+--+*-+/-**-*/+//*+---*+//*/+**/*--/--+/*-*+*++--*+//+*+-++--+-*-*-+--**+/+*-/+*+-/---+-*+-+-/++/+*///*/*-+-*//-+-++/++/*/-++/**--+-////-//+/*//+**/*+-+/+/+///*+*///*-/+/*/-//-*-**//-/-+--+/-*--+-++**++//*--/*++--*-/-///-+/+//--+*//-**-/*-*/+*/-*-*//--++*//-*/++//+/-++-+-*/*-+++**-/-*++++**+-+++-+-***-+//+-/**-+/*+****-*+++*/-*-/***/-/*+/*****++*+/-/-**-+-*-*-++**/*+-/*-+*++-/+/-++*-/*-****-*
18773342

2
Donc ... ce n'est pas strictement entier, car cela /peut donner des non-entiers.
Conor O'Brien

2
Vous devez ensuite le spécifier explicitement.
Conor O'Brien

5
Qu'est-ce qui devrait -/revenir?
Dennis

4
Je ne peux pas m'empêcher de remarquer que l'extrait de code présenté sur la page d'accueil de rust-lang résout ce défi.
Zwei

4
Veuillez ajouter d'autres cas de test.
Martin Ender

Réponses:


28

Python 2, 48 octets

i=0
for c in input():exec"i=i%s2&-2"%c
print i/2

Est-ce que +2, -2, *2ou /2. En faisant +2et -2plutôt que +1et -1, nous travaillons dans des unités doublées, donc la sortie finale doit être divisée par deux. Sauf que la division du sol /doit maintenant être arrondie à un multiple de 2, ce qui est fait avec &-2.


C'est génial! Si vous voulez le poster vous-même, un port CJam de ceci serait actuellement à la tête du défi: 0q{2\~-2&}/2/( 2\~évoque l'opérateur avec le deuxième opérande 2, -2&est le bit au niveau ET, 2/est la division finale par deux. q{...}/Est un foreach sur l'entrée et 0n'est que l'initial .)
Martin Ender

Vous pouvez le poster, je ne connais pas CJam.
xnor

Vraiment intelligent! Porté sur ES6, cela surpasserait facilement ma réponse
edc65

Utilisation brillante de python. J'ai appris quelque chose de nouveau de cela.
Jacobr365

12

Haskell, 51 octets

x#'+'=x+1
x#'-'=x-1
x#'*'=x*2
x#_=div x 2 
foldl(#)0

Exemple d'utilisation: foldl(#)0 $ "++**--/"-> 3.


12

Gelée , 18 17 octets

‘

’

:2
Ḥ
O0;ṛĿ/

Essayez-le en ligne!

Comment ça marche

Les six premières lignes définissent des liens auxiliaires avec des indices allant de 1 à 6 ; ils incrémentent, ne font rien, décrémentent, ne font rien, divisent par deux (revêtement de sol) et doublent.

Le lien principal - O0;ṛĿ/- convertit les caractères d'entrée en leurs points de code ( O), ajoute un 0 (valeur initiale) au tableau de points de code 0;, puis réduit le tableau généré comme suit.

La valeur initiale est le premier élément du tableau, c'est-à-dire le 0 ajouté . Le lien rapide ṛĿest appelé pour chaque élément suivant du tableau, avec la dernière valeur de retour comme argument de gauche et l'élément actuel comme argument de droite. Il inspecte son bon argument ( ) et évalue le lien avec cet index monadiquement ( Ŀ), appliquant ainsi l'opération souhaitée.


10
Cela ressemble à la réponse de la gelée avec le plus de nouvelles lignes
Conor O'Brien

10

Python 2, 54 octets

i=0
for c in input():exec"i=i"+c+`~ord(c)%5%3`
print i

L'entrée est prise comme un littéral de chaîne. ~ord(c)%5%3mappe les opérateurs aux opérandes de droite correspondants.

Auparavant, j'utilisais hash(c)%55%3ce qui ne donnait pas de résultats cohérents entre les différentes versions de Python. Cela m'a encouragé à explorer d'autres formules.


ne semble pas fonctionner ...
Destructible Lemon

55,3 et 65,4 sont les deux plus courts pour le double mod de hachage en python 2
Jonathan Allan

@DestructibleWatermelon fait pour moi: ideone
Jonathan Allan

Je pense que la hashversion Python est spécifique - ideone utilise 2.7.10 qui donne [1, 1, 2, 2]comme quatre mappages, alors que localement sur 2.7.12 je reçois[2, 0, 1, 0]
Sp3000

1
cela fonctionne sur ideone, mais pas sur mon ordinateur python. Probablement dépendante de la version, auquel cas la version doit être notée EDIT: ninja'd: /
Destructible Lemon

10

SILOS , 133 211 octets

:s
def : lbl G GOTO
readIO
i-46
if i a
i+2
if i b
i+2
if i c
i+1
if i d
G e
:a
G v
:p
a-1
a/2
G o
:v
a+1
if a p
a-1
j=a
j/2
k=j
k*2
k-a
a/2
if k t
G o
:t
a-1
:o
G s
:b
a-1
G s
:c
a+1
G s
:d
a*2
G s
:e
printInt a

Prend les codes ASCII des opérateurs.

Essayez-le en ligne avec des cas de test:
-/
++**--/
*///*-*+-+


est loadLine golfier?
Rohan Jhunjhunwala

Le PO a clarifié; -/devrait retourner -1 , pas 0 .
Dennis

@Dennis corrigé. Ajout de beaucoup d'octets cependant: /
betseg

9

Machine de Turing - 23 états (684 octets)

Essayez-le ici - permalien

0 * * r 0
0 _ . l 1
1 * * l 1
1 _ * l 2
2 * 0 r 3
3 _ * r 3
3 + _ l +
3 - _ l -
3 x _ l x
3 / _ l /
+ _ * l +
+ * * * 4
4 - * l 5
4 _ 1 r 6
4 0 1 l 7
4 1 0 l 4
- _ * l -
- * * * 5
5 - * l 4
5 _ * r 8
5 0 1 l 5
5 1 0 l 7
x * * l x
x 1 0 l 9
x 0 0 l a
9 _ 1 r 6
9 1 1 l 9
9 0 1 l a
a _ _ r 6
a 1 0 l 9
a 0 0 l a
/ _ * l /
/ * * l b
b * * l b
b _ * r c
c 0 0 r d
c 1 0 r e
d * * l 7 
d 0 0 r d
d 1 0 r e
e _ * l 7
e - * l 4
e 0 1 r d
e 1 1 r e
8 * * r 8
8 - _ r 3
8 _ - r 3
7 * * l 7
7 _ * r f
f 0 _ r f
f 1 * r 6
f * _ l g
g * 0 r 6
6 * * r 6
6 _ * r 3
3 . _ l h
h _ * l h
h - _ l i
h * * l halt
i * * l i
i _ - r halt

L'entrée ne doit pas contenir de '*' car il s'agit d'un caractère spécial dans le code machine Turing. Utilisez plutôt 'x'. Sort la réponse en binaire.

Code non obscurci

init2 * * r init2
init2 _ . l init0
init0 * * l init0
init0 _ * l init1
init1 * 0 r readop
readop _ * r readop
readop + _ l +
readop - _ l -
readop x _ l x
readop / _ l /
+ _ * l +
+ * * * inc
inc - * l dec
inc _ 1 r return
inc 0 1 l zero
inc 1 0 l inc
- _ * l -
- * * * dec
dec - * l inc
dec _ * r neg
dec 0 1 l dec
dec 1 0 l zero
x * * l x
x 1 0 l x1
x 0 0 l x0
x1 _ 1 r return
x1 1 1 l x1
x1 0 1 l x0
x0 _ _ r return
x0 1 0 l x1
x0 0 0 l x0
/ _ * l /
/ * * l //
// * * l //
// _ * r div
div 0 0 r div0
div 1 0 r div1
div0 * * l zero 
div0 0 0 r div0
div0 1 0 r div1
div1 _ * l zero
div1 - * l inc
div1 0 1 r div0
div1 1 1 r div1
neg * * r neg
neg - _ r readop
neg _ - r readop
zero * * l zero
zero _ * r zero1
zero1 0 _ r zero1
zero1 1 * r return
zero1 * _ l zero2
zero2 * 0 r return
return * * r return
return _ * r readop
readop . _ l fin
fin _ * l fin
fin - _ l min
fin * * l halt
min * * l min
min _ - r halt

Explication des états:

Initialisation:
Ces états sont visités une fois au début de chaque exécution, en commençant par init2

  • init2: déplacez-vous complètement vers la droite et mettez un ".". De cette façon, la MT sait quand s'arrêter. Passez à «init0».
  • init0: Déplacez tout le dos vers la gauche jusqu'à ce que la tête lise un espace. Déplacez ensuite une cellule vers la gauche. Passez à «init1».
  • init1: Mettez un zéro et déplacez une cellule vers la droite et changez en "readop".

Instructions de lecture:
Ces états seront visités plusieurs fois tout au long du programme

  • readop: se déplace complètement vers la droite jusqu'à ce qu'il lit un opérateur ou le '.'. S'il frappe un opérateur, passez à l'état correspondant (+, -, x, /). Si elle atteint un «.», Changez-la en état «fin».

  • return: renvoie la tête vers l'espace vide entre le total cumulé et les opérateurs. Passe ensuite à «readop».

Opérations:
ces opérations font le sale boulot

  • +: Déplacez-vous vers la gauche jusqu'à ce que la tête lise tout caractère non blanc. Si ce caractère est un «-», déplacez-vous vers la gauche et passez à «déc». Sinon, passez à «inc».

  • -: Similaire à '+', sauf changer en 'inc' s'il y a un '-' et 'dec' sinon.

  • inc: Si le chiffre sous la tête est un 0 (ou un espace), changez-le en 1 et changez en «zéro». Si le chiffre est un 1, changez-le en 0, puis répétez sur le chiffre suivant.

  • dec: Similaire à inc, sauf que 1 passe à 0, 0 à 1, et si la tête lit un espace, changez en «neg».

  • x, x0, x1: Déplacez le numéro un vers la gauche. Passez à «retour».

  • /, //, div, div0, div1: déplacez-vous complètement à droite du nombre, puis décalez-en un à droite. S'il y a un «-», changez en «inc». Cela simule l'arrondi des nombres négatifs. Sinon, passez à «zéro»

  • neg: Placez un '-' après le nombre puis changez en 'readop'

  • zéro, zéro1, zéro2: supprimez les zéros de tête et passez à «readop»

Nettoyage: rend la sortie présentable

  • fin, min: déplacez le «-» devant le numéro si nécessaire. Arrêt.

1
Je pensais que lire ce code était très très cool. Merci d'avoir égayé ma journée.
Jacobr365

8

Perl 6 , 53  52 octets

{([Ro] %(<+ - * />Z=>*+1,*-1,* *2,*div 2){.comb})(0)}

{[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}

Explication:

# bare block lambda that has one implicit parameter 「$_」
{
  (
    # reduce the code refs using ring operator 「∘」 in reverse 「R」
    [R[o]]

      # produce a hash from:
      %(

        # list of pairs of "operator" to code ref
        # ( similar to 「'+' => { $^a + 1 }」 )

          # keys
          < + - * / >

        # keys and values joined using infix zip operator 「Z」
        # combined with the infix Pair constructor operator 「=>」
        Z[=>]

          # values (Whatever lambdas)
          * + 1,
          * - 1,
          * × 2, # same as 「* * 2」
          * div 2,

      ){

        # split the block's argument into chars
        # and use them as keys to the hash
        # which will result in a list of code refs
        .comb

      }

  # call composed code ref with 0
  )(0)
}

Usage:

my $input = '++**--/'
my $output = {[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}.( $input );
say $output; # 3
say $output.^name; # Int

7

C, 63 62 57 octets

s,t;c(char*x){for(;*x;s+=t<4?t?2-t:s:-s>>1)t=*x++%6;s=s;}

Wandbox


6

05AB1E , 20 octets

Merci à Enigma d' avoir -/corrigé le bogue!

16 octets si elle n'a pas été entier division: Î"+-*/""><·;"‡.V.

Î…+-*"><·"‡'/"2÷":.V

Explication:

Î                      # Push 0, which is our starting variable, and input
 …+-*                  # Push the string "+-*"
     "><·"             # Push the string "><·"
          ‡            # Transliterate. The following changes:
                           "+" -> ">"
                           "-" -> "<"
                           "*" -> "·"
           '/"2÷":     # Replace "/" by "2÷"
                  .V   # Evaluate the code as 05AB1E code...
                           '>' is increment by 1
                           '<' is decrement by 1
                           '·' is multiply by 2
                           '2÷' is integer divide by two
                       # Implicitly output the result

Utilise l' encodage CP-1252 . Essayez-le en ligne!


Le PO a clarifié; -/devrait retourner -1 , pas 0 .
Dennis

Le problème de division de nombre négatif peut être résolu avec Î…+-*"><·"‡'/"2÷":.Vle même nombre d'octets.
Emigna

@Dennis Correction du problème.
Adnan

@Emigna Thanks :)
Adnan

5

JavaScript ES6, 80 68 octets

k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}‌​[o],0)

12 octets sauvés grâce à Neil!


La deuxième réponse serait plus lisible si vous supprimiez "c"+et écriviez "c+1 c-1 c*2 c/2|0".splitetc.
Neil

Pour la première réponse, pourquoi ne pas écrire o=>c=[c+1,c-1,c*2,c/2|0]["+-*/".indexOf(o)], ou je pense que vous pouvez ensuite enregistrer un octet supplémentaire en utilisant o=>c={"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o].
Neil

k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o],0)pourrait fonctionner encore plus court encore, mais j'ai perdu le compte ...
Neil

@Neil Ah, oui, j'ai oublié ça
Conor O'Brien

1
Vous avez en quelque sorte obtenu des caractères de largeur nulle entre }et [o], donc cela ne fait que 66 octets de long. En outre, le PO a clarifié; -/devrait retourner -1 , pas 0 .
Dennis

5

Rubis, 48 44 42 + 1 = 43 octets

+1 octet pour le -ndrapeau. Prend entrée sur STDIN.

i=0
gsub(/./){i=i.send$&,"+-"[$&]?1:2}
p i

Voir sur ideone (utilise $_depuis ideone ne prend pas les drapeaux de ligne de commande): http://ideone.com/3udQ3H



4

Python 2, 58 56 octets

-2 octets grâce à @Lynn

r=0
for c in input():exec'r=r'+c+`2-ord(c)%11%3`
print r

Les ordinaux des personnages +-*/sont 43,45,42,47modulo 11 ce sont 10,1,9,3modulo 3 ce sont 1,1,0,0, 2 moins ceux -ci sont 1,1,2,2donnant les montants dont nous avons besoin pour chaque opération: r=r+1, r=r-1, r=r*2etr=r/2


Précédent:

r=0
for c in input():exec'r=r'+c+`(ord(c)%5==2)+1`
print r

Et alors 2-ord(c)%11%3?
Lynn

@Lynn Eh bien, je le prendrai si ça te va? (mais pensez vraiment que c'est assez d'un changement que vous pourriez l'afficher)
Jonathan Allan

2
Allez-y :) ----
Lynn

4

Mathematica, 83 73 70 octets

10 octets enregistrés grâce à @MartinEnder .

(#/*##2&@@#/.Thread[{"+","-","*","/"}->{#+1&,#-1&,2#&,⌊#/2⌋&}])@0&

Fonction anonyme. Prend une liste de caractères en entrée et renvoie un nombre en sortie. Suggestions de golf bienvenues.


4

SILOS , 175 164 octets

loadLine
a=256
o=get a
lbla
a+1
o-42
p=o
p-1
p/p
p-1
r-p
s=o
s-3
s/s
s-1
r+s
m=o
m/m
m-2
m|
r*m
t=r
t%2
d=o
d-5
d/d
d-1
t*d
d-1
d|
r-t
r/d
o=get a
if o a
printInt r

Essayez-le en ligne!

Méthode d'entrée saine. Division entière correcte (arrondie vers l'infini).


4

C #, 87 81 octets

int f(string s){int i=0;foreach(var c in s)i=c<43?i*2:c<46?i+44-c:i>>1;return i;}

Non golfé:

int f(string s)
{
    int i = 0;

    foreach (var c in s)
        i = c < 43 ? i * 2
          : c < 46 ? i + 44 - c
          : i >> 1;

    return i;
}

L'entrée est supposée être valide. La division par deux se fait en décalant d'un bit vers la droite, car la division régulière arrondit toujours vers zéro, et le décalage de bits arrondit toujours vers le bas. L'incrémentation et la décrémentation font un usage pratique de la distance 1 entre les codes ASCII pour +et -.


Un peu d'amour pour la nouvelle syntaxe C # 6 et la méthode d'agrégation de Linq? int f(string s)=>s.Aggregate(0,(i,c)=>c<43?i*2:c<46?i+44-c:i>>1);(65 octets)
Cyril Gandon

@CyrilGandon pour autant que je sache, cela devrait inclure le "using System.Linq;", ce qui le rend 19 plus long et le met à 84 octets. C'est pourquoi je ne l'ai pas fait.
Scepheo

4

Javascript (ES6), 57 octets (tableau) / 60 octets (entier)

Renvoyer un tableau de tous les résultats intermédiaires:

o=>[...o].map(c=>x=[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],x=0)

Par exemple, la sortie de "++**--/"sera [1, 2, 4, 8, 7, 6, 3].

Renvoyer uniquement le résultat final:

o=>[...o].reduce((x,c)=>[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],0)

Comment ça marche

Les deux solutions sont basées sur la même idée: utiliser la fonction de hachage parfaite eval(2+c+3)&3pour mapper les différents caractères d'opérateur cdans [0, 3].

 operator | eval(2+c+3)  | eval(2+c+3)&3
----------+--------------+---------------
    +     |  2+3 = 5     |    5 & 3 = 1
    -     |  2-3 = -1    |   -1 & 3 = 3
    *     |  2*3 = 6     |    6 & 3 = 2
    /     |  2/3 ~= 0.67 | 0.67 & 3 = 0

3

JavaScript (ES6), 57

a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a

Remarque: la valeur initiale de l'accumulateur est la chaîne de programme, en utilisant les opérations sur les bits (~, >>, <<, |), elle est convertie en 0 à la première utilisation.

En remarque, la réponse intelligente de @xnor marquerait 40 portés en javascript:

a=>[...a].map(c=>a=eval(~~a+c+2))&&a>>1

(si vous aimez ça, votez pour lui)

Tester

f=a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a

function update() {
  O.textContent = f(I.value);
}

update()
<input value='++**--/' id=I oninput='update()'><pre id=O></pre>


3

Java, 77 octets

int f(String s){return s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);}

Utilise les flux java 8.


1
Belle réponse, et bienvenue sur le site! Je ne sais pas quoi que ce soit à propos de Java, mais pouvez - vous changer r >> 1pour r>>1et enregistrer 2 octets?
DJMcMayhem

Vous avez tout à fait raison, merci @DJMcMayhem
primodemus

1
Génial, heureux d'avoir pu aider! Encore une note, je compte 77 octets. Vous est-il arrivé d'inclure la nouvelle ligne dans votre nombre d'octets? Vous pouvez retirer un octet de plus car cela n'est pas nécessaire.
DJMcMayhem

Corrigez à nouveau @DJMcMayhem, de manière apparente, wc compte l'octet null-déterminanting ou quelque chose ...
primodemus

1
comme vous utilisez java8, pourquoi ne pas définir la fonction en utilisant lambda, s->s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);qui vous donnera 56 octets
user902383

3

GNU sed, 65 59 57 octets

Edit: 2 octets plus court grâce aux commentaires de Toby Speight

s/[+-]/1&/g
s/*/2&/g
s:/:d0>@2&:g
s/.*/dc -e"0[1-]s@&p"/e

Courir:

sed -f simple_calculator.sed <<< "*///*-*+-+"

Sortie:

-1

Le sedscript prépare l'entrée pour l' dcappel shell à la fin, ce dernier acceptant l'entrée en notation polonaise inversée . Sur division, si le nombre est négatif ( d0>), la [1-]commande de décrémentation stockée dans le registre @est appelée. Exemple de conversion: + - * /-> 1+ 1- 2* d0>@2/.


Vous n'avez pas besoin des guillemets autour de l'argument pour dc, s'il n'y a pas d'espaces et pas de fichiers correspondant au [1-]modèle ...
Toby Speight

@TobySpeight Dans mon esprit, j'ai changé le sens de savec S. J'ai oublié qu'il ne remplace pas la pile du registre, il pousse dessus, ayant l'effet contraire de ce que je voulais (puisque je l'ai utilisé pour tout /). Les guillemets sont toujours nécessaires car vous avez des /symboles qui rendent la chaîne interprétée comme un chemin de fichier :) J'ai rasé 1 octet de plus en supprimant l'espace après le -e.
seshoumara

1
dc n'interprétera pas l'argument de -ecomme nom de fichier, vous n'avez donc pas besoin de guillemets pour le /- essayez-le! Je pense qu'il est raisonnable pour un code-golf d'exiger que le répertoire de travail actuel ne contienne aucun fichier commençant par 01s@ou 0-s@.
Toby Speight

@TobySpeight vous aviez raison en -ece qui concerne /, mais les cours ne sont pas encore tenu que je viens de voir maintenant. Le >est interprété directement par le shell comme un opérateur de redirection, je pense, car j'ai eu cette erreur:cannot create @2/d0: Directory nonexistent
seshoumara

Ah, oui, je n'y ai pas pensé >. Vous avez besoin de devis, après tout. Toutes mes excuses pour (avoir tenté de) tromper! Et, bien que l'ajout d'une barre oblique inverse ressemble à un personnage, il doit être doublé dans un s///remplacement, donc aucun avantage là-bas ...
Toby Speight

3

PHP, 75 octets

Il utilise une version modifiée de la réponse de Jörg Hülsermann .

eval(preg_replace('~.~','$s=($s\0(2-ord("\0")%11%3))|0;',$argv[1]));echo$s;

Il s'appuie fortement sur la substitution de chaînes, en utilisant une simple expression régulière ( ~.~).

La variable $sest réaffectée avec la nouvelle valeur pour chaque caractère. À la fin, il produit le résultat.


Remarque : Ceci est destiné à être exécuté à l'aide du -rdrapeau.


Essayez-le ici:

Ou essayez: http://sandbox.onlinephpfunctions.com/code/7d2adc2a500268c011222d8d953d9b837f2312aa

Différences:

  • Au lieu de echo$s, j'utilise sprintf($s). Les deux effectuent la même action sur les nombres. Puisque c'est juste pour les tests, c'est très bien.
  • Dans le cas où il n'y a pas d'argument passé, il fonctionnera comme si vous aviez passé ++*+le premier argument, qui devrait s'afficher 5.

Yay! Le emodificateur est de retour! : D
Titus

@Titus, je ne comprends pas. Pouvez-vous élaborer un peu?
Ismael Miguel

PHP avant la version 7 avait un modificateur de modèlee , qui a été remplacé par preg_replace_callbacket pourrait être utilisé abusivement ... mais ce n'est pas tout à fait ça.
Titus

@Titus Ce modificateur de patern a été utilisé pour dire que la sortie serait du code PHP réel et pour essayer de garder la syntaxe correcte. Ici, ne l'utilise pas, mais remplacez chaque caractère par un morceau de code à exécuter, quelle que soit sa syntaxe. De mauvaises entrées entraîneront de graves problèmes de sécurité.
Ismael Miguel

Je sais. Mais ça ressemble.
Titus

2

Lot, 61 octets

@set n=
@for %%a in (%*)do @set/an=n%%a2^&-2
@cmd/cset/an/2

Traduction de la réponse xcellent xcellent Python de @ xnor.


2

Pyke, 24 22 octets

\*\}:\/\e:\+\h:\-\t:0E

Essayez-le ici!

Ou 12 octets (non compétitif)

~:"ht}e".:0E

Essayez-le ici!

Ajouter un translatenœud - essentiellement plusieurs recherches et remplacements.

~:           -   "+-*/"
        .:   -  input.translate(^, V)
  "ht}e"     -   "ht}e"
          0E - eval(^, stack=0)

2

PHP, 104 102 82 octets

Première version avec eval:

$i=0;while($c<9999)eval('$i'.['+'=>'++','-'=>'--','*'=>'*=2','/'=>'>>=1'][$argv[1]{$c++}].';');echo$i;

Deuxième version avec opérateurs ternaires:

while($o=ord($argv[1]{$c++}))$i=$o<43?$i*2:($o<44?$i+1:($o<46?$i-1:$i>>1));echo$i;

Prend la chaîne d'entrée comme premier argument de la ligne de commande.

Cela "ne fonctionne" que pour les chaînes d'entrée de moins de 10 000 caractères - ce qui devrait être suffisant. Testé avec tous les cas de test, malheureusement ne peut pas économiser sur l'initialisation au début. La deuxième version fonctionne avec des chaînes de n'importe quelle longueur et sans initialisation. :-)

L'élément principal est la fonction eval qui manipule $isur la base d'une carte des opérations arithmétiques, qui sont assez simples à l'exception de la division. PHP renvoie un flottant lors de l'utilisation /et intdivest trop d'octets, nous faisons donc un décalage vers la droite .

Mises à jour

  1. Enregistré 2 octets en raccourcissant $i=$i>>1à $i>>=1pour la division entière.
  2. Jeté eval en faveur des opérateurs ternaires.

2

Python 3, 98 66 60 octets

Merci Tukkax!

Pas aussi golfique que l'autre réponse, mais je ne peux pas rivaliser avec eux sans plagiat.

i=0
for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4]
print(i)

J'ai également une solution lambda récursive

73 67 octets (amélioré!)

s=lambda x,z=0:s(x[1:],z+[1,-z//2,-1,z][ord(x[0])%23%4])if x else z

En appliquant une partie de votre solution récursive à la version procédurale: 60 octets: i=0 for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4] print(i). (non formaté correctement bien sûr). Je pense également que vous devez mentionner que vous utilisez Python3. En Python2, input()serait évalué à int(raw_input()).
Yytsi

@TuukkaX ne fonctionne pas pour z = 0 ( +-fait 1)
Destructible Lemon

oh oui, mon erreur.
Yytsi

1
Ajoutez le titre Python3 s'il vous plaît.
Yytsi

2

R, 201 octets

Golfé

p=.Primitive;"-"="+"=function(x)p("+")(x,1);body(`-`)[[1]]=p("-");"*"="/"=function(x)p("*")(x,2);body(`/`)[[1]]=p("%/%");Reduce(function(f, ...)f(...),rev(mget(strsplit(scan(stdin(),""),"")[[1]])),0,T)

Commenté

p = .Primitive                       # Redefine
"-" = "+" = function(x)p("+")(x,1)   # Define - and +
body(`-`)[[1]] = p("-")              # Change the body, what we do to save a byte
"*" = "/" = function(x)p("*")(x,2)   # Same as above
body(`/`)[[1]] = p("%/%")            # Same as above
Reduce(function(f, ...)f(...),       # Function wrapper to evaluate list of func.  
  rev(mget(strsplit(scan(stdin(),""),"")[[1]])), # Strsplit input into list of functions
  init = 0,                                      # Starting Arg = 1
  right = T)                                     # Right to left = True 

La stratégie consiste à affiner les +, -, %opérateurs. Divisez la chaîne, puis analysez la chaîne en une longue liste de fonctions, à alimenter dans l' Reduce()'saccumulateur.

Je ne pouvais plus jouer au golf. Si quelqu'un peut se rendre b=body<-au travail, il pourrait y avoir quelques octets d'économies (affiner chaque fonction avec baprès "-"="+"="/"="*"). Initialement essayé de substituer et d'analyser eval, mais l'ordre des opérations et les parenthèses étaient terrifiants.


Ceci est un an plus tard, mais je réussi à faire descendre 10 octets en échangeant votre approche un peu - vous pouvez déposer 8 octets en supprimant l'espace entre f, ...dans la définition de la Reducefonction et de se débarrasser de stdin()dans , scanmais je viens d' essayer un naïf approche qui a laissé tomber deux octets de plus en définissant les fonctions un peu différemment. tio.run/##XcvLCsMgEAXQrwnO6Gge29B/…
Giuseppe

1

Lex + C, 78 , 74 , 73 octets

Le premier caractère est un espace.

 c;F(){yylex(c=0);return c;}
%%
\+ c++;
- c--;
\* c*=2;
\/ c=floor(c/2.);

Lit stdin, renvoie le résultat.

Compiler avec lex golfed.l && cc lex.yy.c main.c -lm -lfl, test principal:

int main() { printf("%d\n", F()); }

1

Javascript (ES5), 127 octets

function(b){for(a=c=0;a<b.length;++a)switch(b[a]){case"+":++c;break;case"-":--c;break;case"*":c*=2;break;case"/":c/=2}return c}

Non golfé:

function c(a){
  c=0;
  for(var i=0;i<a.length;++i){
    switch(a[i]){
      case "+":++c;break;
      case "-":--c;break;
      case "*":c*=2;break;
      case "/":c/=2;break;
    }
  }
  return c;
}

1

Pyth, 23 octets

FNQ=Z.v%".&%sZ2_2"N;/Z2

Un programme complet qui prend l'entrée sous forme de chaîne et imprime le résultat.

Il s'agit d'un portage de la réponse Python @ xnor .

Essayez-le en ligne

Comment ça marche

FNQ=Z.v%".&%sZ2_2"N;/Z2   Program. Input: Q. Z initialised as 0
FNQ                       For. For N in Q:
        ".&%sZ2_2"         String. Literal string ".&%sZ2_2"
       %          N        String format. Replace %s with the current operator N
           %sZ2            Operator. Yield Z*2, Z//2, Z+2, Z-2 as appropriate
         .&    _2          Bitwise and. Result of above & -2
     .v                    Evaluate. Yield the result of the expression
   =Z                      Assignment. Assign result of above to Z
                   ;      End. End for loop
                    /Z2   Integer division. Yield Z//2
                          Print. Print the above implicitly 

1
La conversion de Python en Pyth est surtout une mauvaise idée. u@[yGhG0tG0/G2)CHQ019 octets
Jakube

@Jakube Merci - Je suis très nouveau sur Pyth, donc tout conseil est apprécié. N'hésitez pas à poster cela comme une réponse distincte, car il s'agit d'une approche différente.
TheBikingViking

1

PHP, 79 octets

<?$i=0;switch($_POST['a']){case"+":$i+1;case"-":$i-1;case"/":$i/2;case"*":$i*2}

2
Incluez le bytecount dans votre en-tête, supprimez les espaces inutiles et utilisez des noms de variables à 1 lettre.
TuxCrafting

Est-ce même du golf?! :-D
YetiCGN

@ TùxCräftîñg Je l'ai fait.
Winnie The Pooh

Vous divisez et multipliez par 1; vous devez diviser et multiplier par2
TuxCrafting

@ TùxCräftîñg Je l'ai fait.
Winnie The Pooh
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.