電卓を回す


16

前書き:

Windowsの標準的な電卓を見てみましょう 。この課題では、次のボタンのみを見て、他のすべてを無視します。
ここに画像の説明を入力してください

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

チャレンジ:

入力:次の
2つの入力を受け取ります。

  • 1つは90度単位で回転を示すものです
  • もう1つは、回転した電卓で押されたボタンを表す座標のリストです。

最初の入力に基づいて、上記のレイアウトを時計回りに90度ずつ回転します。したがって、入力がの場合0 degrees、そのまま残ります。ただし、入力がの場合、270 degrees時計回りに3回(または反時計回りに1回)回転します。以下に4つの可能なレイアウトを示します。

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

2番目の入力は、妥当な形式の座標のリストです。例(0-index 2D integer-array):

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

出力:
合計と結果(および等号=)の両方を出力します。

例:
したがって、入力が270 degreesとの[[1,2],[2,3],[0,3],[1,0],[1,1]]場合、出力は次のようになります。

517*6=3102

チャレンジルール:

  • 入力は、任意の合理的な形式にすることができます。最初の入力があってもよい0-31-4A-D0,90,180,270、などの第2の入力は、等0インデックス2Dアレイ、1インデックス付きの2次元アレイ、ポイント・オブジェクトの文字列、リスト、あなたの通話であってもよいです。与えられた例の入力と比較して、x座標とy座標を入れ替えることも可能です。回答で使用した入力形式を明記してください!
  • 517 * 6 = 3102必要に応じて、スペースを追加できます(つまり、)。
  • あなたが3(すなわちの最大に、コンマの後に後続のゼロを追加することが許可されている3102.0/ 3102.00/ 3102.000の代わりに、3102または0.430代わりに0.43)。
  • 出力に括弧を追加することは許可されていないため(((0.6+4)-0)/2)/4=0.575、有効な出力ではありません。
  • あなたの言語で他のオペランド記号を使用することができます。そう×または·代わりに*; または÷代わりに/; 等
  • 電卓はオペランドの入力時に自動的に計算するため、演算子の優先順位を無視する必要があります!そう10+5*3になります45(10+5)*3=45ない、) (2510+(5*3)=25
    つまり、10+5*(それが今の表示に15を表示)→ 3=(それが今の答えを表示します45))。eval結果の合計で同様の関数を使用する場合は、このことに留意してください。
  • 0による除算のテストケースはありません。
  • 結果として小数点以下3桁以上のテストケースはないため、結果を丸める必要はありません。
  • 複数のオペランドが互いに続く、または2つのドットが互いに続くテストケースはありません。
  • 負の数のテストケースはありません。マイナス記号(-)はオペランドとしてのみ使用され、負としては使用されません。
  • 以下のための任意のテストケースがありません.##(つまり、コンマの前に大手番号なしで2+.7有効なテストケースではありませんが、2+0.7可能性があり)。

一般的なルール:

  • これはであるため、バイト単位の最短回答が優先されます。
    コードゴルフ言語では、非コードゴルフ言語で回答を投稿しないようにしてください。「任意の」プログラミング言語の可能な限り短い答えを考えてみてください。
  • 回答には標準的なルールが適用されるため、STDIN / STDOUT、適切なパラメーターを持つ関数/メソッド、完全なプログラムを使用できます。あなたの電話。
  • デフォルトの抜け穴は禁止されています。
  • 可能であれば、コードのテストへのリンクを追加してください。
  • また、必要に応じて説明を追加してください。

テストケース:

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

1
テストケースは、多くのエラーを持っている(たとえば、3番目と4番目は、XとYが入れ替わっている(第一にはない)と私も2回目に何が起こったのかわからない)
dzaima

2
プログラムは奇妙なボタンの押下を処理する必要がありますか?1+-*/+-*/2意志が与えられる0.5Windowsの(10)電卓に。
user202729

1
第二のテストケースを用いて開始する必要が[1,3],
ウリエル

1
のように、先行する0なしで1未満の小数を処理する必要があり2+.7ますか?
タトルマン

4
演算子の優先順位は、標準モードでWindows Calculatorを使用しない理由です。
ニール

回答:


4

SOGL V0.1270の 69 67 バイト

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

ここ試してみる、テストケースで与えられた入力を受け取るバージョンを試してください

SOGL I演算子を使用して、配列を回転させます。次に、文字列をJavaScript配列として読み取り、操作が使用される場所で、前の結果を括弧で囲み、JavaScriptとして評価してから括弧を削除します。


3

Dyalog APL、94 88 86 85バイト

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

オンラインでお試しください!

回転を左引数として0-3、1から始まるインデックスを右引数として、などのy x座標のリストとして受け取ります(1 1)(2 3)(4 5)

これは、APLの式の右利きの評価のために非常に面倒になりました。


3

C(gcc)、282294 295 296 300 304 306 310 バイト

すべての最適化をオフにする必要があり、32ビット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);}

@Orionのおかげで1バイト!

オンラインでお試しください!

関数のプロトタイプ:

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

入力形式(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>

コメント付きの未ゴルフバージョン:

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

コードは次のようなケースを扱うことができます1+.7-8*4

非常に悲しいCにはhaveがありませんeval


3*-5無効のようなケースを実際にみなすことができます。ルールでこれを指定しました。
ケビンCruijssen

ルールに必要な精度は3箇所しかないことを考慮するdoublefloat、1バイトに置き換えることができます。また、とputc()同一ではありませんputchar()か?しかし、私は間違っている可能性があります。
オリオン

@Orion putcは、書き込み先のストリームを指定するために2番目の引数が必要だと思いますか
キーガン


2

JavaScriptの(ES6)、162の 160 157バイト

入力をカリー化構文の方向o(y、x)座標の配列として受け取りaます(o)(a)

方向は[0..3]の整数です

  • 0 = 0°
  • 1 =時計回りに90°
  • 2 =時計回りに180°
  • 3 =時計回りに270°
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`)`)

テストケース



1

Python 3、235 234 230バイト

少しいですが、最初のテストケースを除くすべてのテストケースで機能します。回転を0〜3(0〜270)として、16を掛けてオフセットします。

eval() は、文字列をコードとしてコンパイルし、テキストシンボルの演算子への変換を処理する組み込み機能です。

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

別の方法、それは少し長くなりましたが、私はアレイを回転させるためのこのSOチップが本当に好きです。

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

1

Java 10、418 380バイト

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

私自身の質問にも答えることにしました。別のアプローチを使用すれば、もう少しゴルフができると確信しています。()および(0-indexed /チャレンジの説明と同じ)
として入力します。結果が10進数ではなく整数である場合、先頭と同様に出力します。int0-3int[][]float.0

説明:

ここで試してみてください。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.