Faites tourner la calculatrice

16

Introduction:

Jetons un coup d'œil à une calculatrice standard dans Windows: pour ce défi, nous ne regarderons que les boutons suivants et ignorerons tout le reste:
entrez la description de l'image ici

7 8 9 /
4 5 6 *
1 2 3 -
0 0 . +

Défi:

Entrée:
vous recevrez deux entrées:

  • L'un est quelque chose pour indiquer la rotation par incréments de 90 degrés
  • L'autre est une liste de coordonnées représentant les boutons appuyés sur la calculatrice pivotée.

Sur la base de la première entrée, nous faisons pivoter la disposition mentionnée ci-dessus dans le sens horaire par incréments de 90 degrés. Donc, si l'entrée est 0 degrees, elle reste telle quelle; mais si l'entrée est 270 degrees, elle sera tournée trois fois dans le sens horaire (ou une fois dans le sens antihoraire). Voici les quatre dispositions possibles:

Default / 0 degrees:
7 8 9 /
4 5 6 *
1 2 3 -
0 0 . +

90 degrees clockwise:
0 1 4 7
0 2 5 8
. 3 6 9
+ - * /

180 degrees:
+ . 0 0
- 3 2 1
* 6 5 4
/ 9 8 7

270 degrees clockwise / 90 degrees counterclockwise:
/ * - +
9 6 3 .
8 5 2 0
7 4 1 0

La deuxième entrée est une liste de coordonnées dans n'importe quel format raisonnable . Par exemple (tableau entier 2D à 0 index):

[[1,2],[2,3],[0,3],[1,0],[1,1]]

Sortie:
Nous sortons à la fois la somme, ainsi que le résultat (et un signe égal =).

Exemple:
Donc si l'entrée est 270 degreeset [[1,2],[2,3],[0,3],[1,0],[1,1]], la sortie deviendra:

517*6=3102

Règles du défi:

  • Les entrées peuvent être dans n'importe quel format raisonnable. La première entrée peut être 0-3, 1-4, A-D, 0,90,180,270, etc. La seconde entrée peut être un 0 indexé tableau 2D, 1 indexé tableau 2D, une chaîne, la liste des points d' objets, etc. Votre appel. Il est même possible d'échanger les coordonnées x et y par rapport aux exemples d'entrées donnés. Veuillez indiquer les formats d'entrée que vous avez utilisés dans votre réponse!
  • Vous êtes autorisé à ajouter des espaces (c'est-à-dire 517 * 6 = 3102) si vous le souhaitez.
  • Vous êtes autorisé à ajouter des zéros de fin après la virgule, jusqu'à un maximum de trois (c'est 3102.0-à- dire / 3102.00/ 3102.000au lieu de 3102ou 0.430au lieu de 0.43).
  • Vous n'êtes pas autorisé à ajouter des parenthèses dans la sortie, ce (((0.6+4)-0)/2)/4=0.575n'est donc pas une sortie valide.
  • Vous êtes autorisé à utiliser d'autres symboles d'opérande pour votre langue. Alors ×ou ·au lieu de *; ou ÷au lieu de /; etc.
  • Puisqu'une calculatrice calcule automatiquement lors de la saisie d'un opérande, vous devez ignorer la priorité de l'opérateur! Il 10+5*3en résultera donc 45( (10+5)*3=45), pas 25( 10+(5*3)=25)
    (c'est-à-dire 10+5*(il affiche maintenant 15 à l'écran) → 3=(il affiche maintenant la réponse 45)). Gardez cela à l'esprit lors de l'utilisation evalet des fonctions similaires sur la somme résultante.
  • Il n'y aura pas de cas de test pour la division par 0.
  • Il n'y aura aucun cas de test avec plus de trois chiffres décimaux comme résultat, donc pas besoin d'arrondir le résultat.
  • Il n'y aura pas de cas de test où plusieurs opérandes se suivent ou où deux points se suivent.
  • Il n'y aura pas de cas de test pour les nombres négatifs. Le signe moins ( -) ne sera utilisé que comme opérande, pas comme négatif.
  • Il n'y aura pas de cas de test pour .##sans numéro de tête avant la virgule (c'est 2+.7-à- dire qu'il ne s'agira pas d'un cas de test valide, mais il 2+0.7pourrait l'être).

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues autres que le golf de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse, vous êtes donc autorisé à utiliser STDIN / STDOUT, des fonctions / méthodes avec les paramètres appropriés, des programmes complets. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code.
  • Veuillez également ajouter une explication si nécessaire.

Cas de test:

Input:   270 degrees & [[1,2],[2,3],[0,3],[1,0],[1,1]]
Output:  517*6=3102

Input:   90 degrees & [[3,1],[0,0],[0,1],[3,3],[2,0],[0,3],[0,0],[0,2],[3,0],[2,1]]
Output:  800/4+0.75=200.75

Input:   0 degrees & [[0,0],[1,0],[2,0],[3,0],[1,2],[2,1],[2,2]]
Output:  789/263=3

Input:   180 degrees & [[3,0],[1,0],[1,2],[0,0],[3,2],[0,1],[2,0],[0,3],[2,1],[0,3],[3,2]]
Output:  0.6+4-0/2/4=0.575
Kevin Cruijssen
la source
1
Les cas de test contiennent de nombreuses erreurs (par exemple, le 3ème et le 4ème ont échangé X et Y (le 1er pas) et je ne sais même pas ce qui est arrivé au 2ème)
dzaima
2
Le programme doit-il gérer des pressions de boutons étranges? 1+-*/+-*/2donne 0.5sur la calculatrice Windows (10).
user202729
1
le deuxième [1,3],
Uriel
1
Faut-il gérer les décimales inférieures à 1 sans les 0 de tête, comme dans 2+.7?
Tutleman
4
La priorité des opérateurs est la raison pour laquelle je n'utilise jamais la calculatrice Windows en mode standard.
Neil

Réponses:

4

SOGL V0.12 , 70 69 67 octets

i⅛⁸Νο;⌡░▼Y6γj±²‘1n4n.⌡Iø,→{_≤whwιh:"/*-+”;W? )Κ; (Κ;}+}:Ƨ)(čøŗoļ=→p

Essayez-le ici , ou essayez une version qui prend les entrées comme indiqué dans les cas de test

utilise l' Iopérateur SOGLs , qui fait tourner le tableau. Lit ensuite une chaîne sous forme de tableau JavaScript et, lorsqu'une opération est utilisée, encapsule le résultat précédent entre parenthèses, évalue en JavaScript et supprime ensuite les parenthèses.

dzaima
la source
3

Dyalog APL, 94 88 86 85 octets

{o,'=',⍎('('\⍨+/'+-×÷'∊⍨o),'[×÷+-]'⎕R')&'⊢o←(((⌽∘⍉⍣⍺)4 4⍴'789÷456×123-00.+')⊃⍨⊂∘⊢)¨⍵}

Essayez-le en ligne!

Prend les rotations comme argument de gauche, 0-3 , et les indices basés sur 1 comme argument droit, comme une liste de y xcoordonnées, comme (1 1)(2 3)(4 5)etc.

Cela est devenu assez compliqué à cause de l'évaluation à droite des expressions dans APL.

Uriel
la source
3

C (gcc) , 282294 295 296 300 304 306 310 octets

Toutes les optimisations doivent être désactivées et ne fonctionnent que sur GCC 32 bits.

float r,s;k,p,l,i;g(d,x,y){int w[]={y,x,3-y,3-x,y};d=w[d+1]*4+w[d];}f(x,y,z)int**z;{for(i=0;i<=y;i++)putchar(k=i-y?"789/456*123-00.+"[g(x,z[i][0],z[i][1])]:61),57/k*k/48?p?r+=(k-48)*pow(10,p--):(r=10*r+k-48):k-46?s=l?l%2?l%5?l&4?s/r:s+r:s-r:s*r:r,r=p=0,l=k:(p=-1);printf("%.3f",s);}

1 octet grâce à @Orion!

Essayez-le en ligne!

Prototype de fonction:

f(<Direction 0-3>, <Number of entries>, <a int** typed array in [N][2]>)

Format d'entrée (comme sur TIO):

<Direction 0~3> <Number of entries>
<Entries 0 Row> <Entries 0 Column>
<Entries 1 Row> <Entries 1 Column>
....
<Entries N Row> <Entries N Column>

Version non golfée avec commentaires:

float r, s;
k, p, l, i;
g(d, x, y) {
  int w[] = {
    y,
    x,
    3 - y,
    3 - x,
    y
  };
  d = w[d + 1] * 4 + w[d];
}
f(x, y, z) int **z; {
  for (i = 0; i <= y; i++)
  {
      putchar(k = i - y ? 
      "789/456*123-00.+"[g(x, z[i][0], z[i][1])] : 61),     // Print character, otherwise, '='
      57 / k * k / 48 ?                                     // If the character is from '0'~'9'
        p ?                                                 // If it is after or before a dot
            r += (k - 48) * pow(10., p--)                   // +k*10^-p
        :
            (r = 10 * r + k - 48)                           // *10+k
      :
          k - 46 ?                                          // If the character is not '.', that is, an operator, + - * / =
            s = l ?                                         // Calculate the result of previous step (if exist)
                    l % 2 ?                                 // If + - /
                        l % 5 ?                             // If + /
                            l & 4 ?
                                s / r
                            :
                                s + r
                        :
                            s - r
                    :
                        s * r
                 :
                    r,
                    r = p = 0, l = k                        // Reset all bits
          :
            (p = -1);                                       // Reverse the dot bit
  }
  printf("%.3f", s);
}

Le code peut gérer des cas tels que 1+.7ou -8*4.

C très triste n'a pas de eval😭.

Keyu Gan
la source
Vous pouvez en effet considérer les cas comme 3*-5invalides. Je l'ai spécifié dans les règles.
Kevin Cruijssen
Étant donné que la précision requise dans les règles n'est que de 3 emplacements, vous pouvez remplacer doublepar floatun octet libre. En outre, n'est-il pas putc()identique à putchar()? Je pourrais toutefois avoir tord.
Orion
@Orion Je me souviens avoir putcbesoin d'un deuxième argument pour spécifier dans quel flux vous écrivez?
Keyu Gan
292 octets
plafond
2

JavaScript (ES6), 162 160 157 octets

Prend l'entrée comme orientation oet tableau de coordonnées (y, x)a dans la syntaxe de curry (o)(a).

L'orientation est un entier dans [0..3] :

  • 0 = 0 °
  • 1 = 90 ° dans le sens horaire
  • 2 = 180 ° dans le sens horaire
  • 3 = 270 ° dans le sens horaire
o=>a=>(s=a.map(([y,x])=>'789/456*123-00.+'[[p=y*4+x,12+(y-=x*4),15-p,3-y][o]]).join``)+'='+eval([...x=`0)+${s}`.split(/(.[\d.]+)/)].fill`(`.join``+x.join`)`)

Cas de test

Arnauld
la source
2

Ruby , 135 133 132 octets

->r,c{a="";c.map{|x,y|a=((w="789/456*123-00.+"[[y*4+x,12-x*4+y,15-y*4-x,x*4+3-y][r]])=~/[0-9.]/?a:"#{eval a}")+w;w}*""+"=#{eval a}"}

Essayez-le en ligne!

Orientation sous forme d'entier: 0 pour 0 °, 1 pour 90 ° et ainsi de suite.

GB
la source
1

Python 3, 235 234 230 octets

Un peu moche mais cela fonctionne pour tous les cas de test sauf le premier, qui ne semble pas correspondre à l'exemple de calculatrice. Je prends la rotation comme 0-3 (0-270) et je multiplie par 16 pour compenser.

eval() est une fonction intégrée qui tente de compiler des chaînes sous forme de code et gère la conversion des symboles de texte en opérateurs.

import re
def f(r,c,J=''.join):
 b='789/456*123-00.+01470258.369+-*/+.00-321*654/987/*-+963.85207410'
 s=t=J([b[r*16+x*4+y]for y,x in c]);t=re.split('([\+\-\/\*])',s)
 while len(t)>2:t=[str(eval(J(t[0:3])))]+t[3:]
 print(s+'='+t[0])

Autre méthode, cela s'est avéré un peu plus long mais j'aime vraiment cette astuce SO pour faire tourner le tableau.

import re
def f(r,c):
 L=list;b=L(map(L,['789/','456*','123-','00.+']))
 while r:b=L(zip(*b[::-1]));r-=1
 s=''.join([b[x][y]for y,x in c]);t=re.split('([\+\-\/\*])',s)
 while len(t)>2:t=[str(eval(''.join(t[0:3])))]+t[3:]
 print(s+'='+t[0])
nocturama
la source
1

Java 10, 418 380 octets

d->a->{String r="",g=d>2?"/*-+963.85207410":d>1?"+.00-321*654/987":d>0?"01470258.369+-*/":"789/456*123-00.+",n[],o[];for(var i:a)r+=g.charAt(i[1]*4+i[0]);n=r.split("[-/\\+\\*]");o=r.split("[[0-9]\\.]");float s=new Float(n[0]),t;for(int i=1,O,j=0;++j<o.length;O=o[j].isEmpty()?99:o[j].charAt(0),s=O<43?s*t:O<44?s+t:O<46?s-t:O<48?s/t:s,i+=O>98?0:1)t=new Float(n[i]);return r+"="+s;}

Décidé de répondre également à ma propre question. Je suis sûr qu'il peut être joué un peu plus en utilisant une approche différente.
Saisissez int( 0-3) et int[][](indexé 0 / le même que dans la description du défi). Afficher comme floatavec interligne .0si le résultat est un entier au lieu d'un nombre décimal.

Explication:

Essayez-le ici.

d->a->{                       // Method with int & 2D int-array parameters and String return
  String r="",                //  Result-String, starting empty
    g=d>2?                    //  If the input is 3:
       "/*-+963.85207410"     //   Use 270 degree rotated String
      :d>1?                   //  Else if it's 2:
       "+.00-321*654/987"     //   Use 180 degree rotated String
      :d>0?                   //  Else if it's 1:
       "01470258.369+-*/"     //   Use 90 degree rotated String
      :                       //  Else (it's 0):
       "789/456*123-00.+",    //   Use default String
    n[],o[];                  //  Two temp String-arrays
  for(var i:a)                //  Loop over the coordinates:
    r+=g.charAt(i[1]*4+i[0]); //   Append the result-String with the next char
  n=r.split("[-/\\+\\*]");    //  String-array of all numbers
  o=r.split("[[0-9]\\.]");    //  String-array of all operands (including empty values unfortunately)
  float s=new Float(n[0]),    //  Start the sum at the first number
        t;                    //  A temp decimal
  for(int i=0,                //  Index-integer `i`, starting at 0
      O,                      //  A temp integer
      j=0;++j<o.length        //  Loop `j` over the operands
      ;                       //    After every iteration:
       O=o[j].isEmpty()?      //     If the current operand is an empty String
          99                  //      Set `O` to 99
         :                    //     Else:
          o[j].charAt(0),     //      Set it to the current operand character
       s=O<43?                //     If the operand is '*':
          s*t                 //      Multiply the sum with the next number
         :O<44?               //     Else-if the operand is '+':
          s+t                 //      Add the next number to the sum
         :O<46?               //     Else-if the operand is '-':
          s-t                 //      Subtract the next number from the sum 
         :O<48?               //     Else-if the operand is '/':
          s/t                 //      Divide the sum by the next number
         :                    //     Else (the operand is empty):
          s,                  //      Leave the sum the same
       i+=O>98?0:1)           //     Increase `i` if we've encountered a non-empty operand
    t=new Float(n[i]);        //   Set `t`  to the next number in line
  return r+"="+s;}            //  Return the sum + sum-result
Kevin Cruijssen
la source