Den Rechner drehen

16

Einführung:

Werfen wir einen Blick auf einen Standardrechner in Windows: Bei dieser Herausforderung werden nur die folgenden Schaltflächen betrachtet und alles andere ignoriert:
Bildbeschreibung hier eingeben

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

Herausforderung:

Input:
Sie erhalten zwei Inputs:

  • Eines ist etwas, um die Drehung in Schritten von 90 Grad anzuzeigen
  • Die andere ist eine Liste von Koordinaten, die die auf dem gedrehten Rechner gedrückten Tasten darstellen.

Basierend auf der ersten Eingabe drehen wir das oben erwähnte Layout im Uhrzeigersinn in Schritten von 90 Grad. Wenn die Eingabe also ist 0 degrees, bleibt sie wie sie ist. Ist 270 degreesdies jedoch der Fall, wird der Eingang dreimal im Uhrzeigersinn (oder einmal gegen den Uhrzeigersinn) gedreht. Hier sind die vier möglichen Layouts:

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

Die zweite Eingabe ist eine Liste von Koordinaten in jedem vernünftigen Format . Zum Beispiel (0-Index 2D Integer-Array):

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

Ausgabe:
Wir geben sowohl die Summe als auch das Ergebnis (und ein Gleichheitszeichen =) aus.

Beispiel:
Wenn also die Eingabe 270 degreesund ist [[1,2],[2,3],[0,3],[1,0],[1,1]], wird die Ausgabe zu:

517*6=3102

Herausforderungsregeln:

  • Die Eingaben können in jedem vernünftigen Format erfolgen. Der erste Eingang kann sein 0-3, 1-4, A-D, 0,90,180,270etc. Der zweite Eingang ein 0-indiziert 2D - Array sein kann, 1-indiziert 2D - Array, ein String, Liste von Point-Objekten usw. Ihrem Anruf. Es ist sogar möglich, die x- und y-Koordinaten im Vergleich zu den angegebenen Beispieleingaben zu vertauschen. Bitte geben Sie an, welche Eingabeformate Sie in Ihrer Antwort verwendet haben!
  • Sie können Leerzeichen hinzufügen, 517 * 6 = 3102wenn Sie möchten.
  • Sie dürfen nachfolgende Nullen nach dem Komma hinzufügen, zu einem Maximum von drei (dh 3102.0/ 3102.00/ 3102.000anstelle von 3102oder 0.430statt 0.43).
  • Sie dürfen der Ausgabe keine Klammern hinzufügen, es (((0.6+4)-0)/2)/4=0.575handelt sich also nicht um eine gültige Ausgabe.
  • Sie dürfen andere Operandensymbole für Ihre Sprache verwenden. Also ×oder ·statt *; oder ÷statt /; etc.
  • Da ein Taschenrechner bei der Eingabe eines Operanden automatisch rechnet, sollten Sie die Operator-Priorität ignorieren! Das 10+5*3Ergebnis ist also 45( (10+5)*3=45), nicht 25( 10+(5*3)=25)
    (dh 10+5*(es wird jetzt 15 im Display angezeigt) → 3=(es wird jetzt die Antwort angezeigt 45)). Beachten Sie dies, wenn Sie evalund ähnliche Funktionen für die resultierende Summe verwenden.
  • Es gibt keine Testfälle für die Division durch 0.
  • Es werden keine Testfälle mit mehr als drei Dezimalstellen als Ergebnis angezeigt, sodass das Ergebnis nicht gerundet werden muss.
  • Es wird keine Testfälle geben, in denen mehrere Operanden aufeinander folgen oder zwei Punkte aufeinander folgen.
  • Es wird keine Testfälle für negative Zahlen geben. Das Minuszeichen ( -) wird nur als Operand verwendet, nicht als negativer.
  • Es werden keine Testfälle .##ohne vorangestellte Nummer vor dem Komma angezeigt (dh es 2+.7wird kein gültiger Testfall angezeigt, dies 2+0.7könnte aber der Fall sein).

Allgemeine Regeln:

  • Das ist , also gewinnt die kürzeste Antwort in Bytes.
    Lassen Sie sich von Code-Golf-Sprachen nicht davon abhalten, Antworten mit Nicht-Codegolf-Sprachen zu veröffentlichen. Versuchen Sie, für jede Programmiersprache eine möglichst kurze Antwort zu finden.
  • Für Ihre Antwort gelten Standardregeln. Daher dürfen Sie STDIN / STDOUT, Funktionen / Methode mit den richtigen Parametern und vollständige Programme verwenden. Ihr Anruf.
  • Standardlücken sind verboten.
  • Fügen Sie nach Möglichkeit einen Link mit einem Test für Ihren Code hinzu.
  • Fügen Sie ggf. auch eine Erklärung hinzu.

Testfälle:

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
quelle
1
Die Testfälle haben viele Fehler (zB der 3. und 4. hat X und Y getauscht (1. nicht) und ich weiß nicht einmal, was mit dem 2. passiert ist)
dzaima
2
Sollte das Programm mit seltsamen Tastendrücken umgehen? 1+-*/+-*/2Will gibt 0.5auf Windows (10) Rechner.
user202729
1
Der zweite Testfall sollte beginnen mit[1,3],
Uriel
1
Müssen wir Dezimalstellen kleiner als 1 ohne führende Nullen wie in behandeln 2+.7?
Tutleman
4
Der Operator hat Vorrang, weshalb ich Windows Calculator nie im Standardmodus verwende.
Neil

Antworten:

4

SOGL V0.12 , 70 69 67 Bytes

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

Probieren Sie es hier aus oder probieren Sie eine Version aus, die die in den Testfällen angegebenen Eingaben akzeptiert

Verwendet den SOGLs- IOperator, der das Array dreht. Liest dann eine Zeichenfolge als JavaScript-Array und setzt bei Verwendung einer Operation das vorherige Ergebnis in Klammern, wertet es als JavaScript aus und entfernt die Klammern.

dzaima
quelle
3

Dyalog APL, 94 88 86 85 Bytes

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

Probieren Sie es online!

Nimmt die Rotationen als linkes Argument 0-3und die auf 1 basierenden Indizes als rechtes Argument als eine Liste von y xKoordinaten (1 1)(2 3)(4 5)usw.

Dies wurde aufgrund der rechtshändigen Auswertung von Ausdrücken in APL ziemlich chaotisch.

Uriel
quelle
3

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

Alle Optimierungen müssen deaktiviert sein und funktionieren nur mit 32-Bit-GCC.

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 Byte danke an @Orion!

Probieren Sie es online!

Funktionsprototyp:

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

Eingabeformat (wie bei 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>

Ungolfed-Version mit Kommentaren:

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);
}

Der Code kann mit Fällen wie 1+.7oder umgehen -8*4.

Sehr traurig, dass C kein eval😭 hat.

Keyu Gan
quelle
Sie können Fälle tatsächlich für 3*-5ungültig halten. Ich habe dies in den Regeln festgelegt.
Kevin Cruijssen
Unter Berücksichtigung der erforderlichen Genauigkeit in den Regeln ist nur 3 Plätze, könnten Sie ersetzen doublemit floatfür ein freies Byte. Auch ist nicht putc()identisch mit putchar()? Ich könnte mich jedoch irren.
Orion
Ich erinnere mich, dass @Orion putcein zweites Argument benötigt, um anzugeben, in welchen Stream Sie schreiben.
Keyu Gan
292 Bytes
Ceilingcat
2

JavaScript (ES6), 162 160 157 Byte

Nimmt Eingaben als Ausrichtung ound Array von (y, x) -Koordinaten ain der aktuellen Syntax an (o)(a).

Die Orientierung ist eine ganze Zahl in [0..3] :

  • 0 = 0 °
  • 1 = 90 ° im Uhrzeigersinn
  • 2 = 180 ° im Uhrzeigersinn
  • 3 = 270 ° im Uhrzeigersinn
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`)`)

Testfälle

Arnauld
quelle
2

Ruby , 135 133 132 Bytes

->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}"}

Probieren Sie es online!

Ausrichtung als Ganzzahl: 0 für 0 °, 1 für 90 ° und so weiter.

GB
quelle
1

Python 3, 235 234 230 Bytes

Etwas hässlich, aber es funktioniert für alle Testfälle mit Ausnahme des ersten, der nicht mit dem Beispielrechner übereinstimmt. Ich nehme die Drehung als 0-3 (0-270) und multipliziere mit 16, um sie zu versetzen.

eval() ist eine integrierte Funktion, die versucht, Zeichenfolgen als Code zu kompilieren und die Textsymbole in Operatoren umzuwandeln.

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

Alternative Methode, es stellte sich ein bisschen länger heraus, aber ich mag diesen SO-Tipp zum Drehen des Arrays wirklich .

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
quelle
1

Java 10, 418 380 Bytes

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;}

Beschlossen, meine eigene Frage zu beantworten. Ich bin sicher, dass man mit einem anderen Ansatz noch mehr Golf spielen kann.
Eingabe wie int( 0-3) und int[][](0-indiziert / wie in der Challenge-Beschreibung). Ausgabe wie floatmit führend, .0wenn das Ergebnis eine Ganzzahl anstelle einer Dezimalzahl ist.

Erläuterung:

Probieren Sie es hier aus.

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
quelle