Putar Kalkulator

16

Pengantar:

Mari kita lihat Kalkulator standar di Windows: Untuk tantangan ini, kita hanya akan melihat tombol-tombol berikut, dan mengabaikan yang lainnya:
masukkan deskripsi gambar di sini

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

Tantangan:

Input:
Anda akan menerima dua input:

  • Salah satunya adalah sesuatu untuk menunjukkan rotasi dengan peningkatan 90 derajat
  • Yang lainnya adalah daftar koordinat yang mewakili tombol yang ditekan pada kalkulator yang diputar.

Berdasarkan input pertama, kami memutar tata letak yang disebutkan di atas searah jarum jam dengan peningkatan 90 derajat. Jadi, jika inputnya 0 degrees, tetap apa adanya; tetapi jika inputnya adalah 270 degrees, ia akan diputar tiga kali searah jarum jam (atau sekali berlawanan arah jarum jam). Berikut adalah empat kemungkinan tata letak:

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

Input kedua adalah daftar koordinat dalam format wajar . Sebagai contoh (0-index 2D integer-array):

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

Output:
Kami menampilkan jumlah, serta hasilnya (dan tanda yang sama =).

Contoh:
Jadi jika inputnya adalah 270 degreesdan [[1,2],[2,3],[0,3],[1,0],[1,1]], outputnya akan menjadi:

517*6=3102

Aturan tantangan:

  • Input dapat dalam format apa pun yang wajar. Input pertama bisa 0-3, 1-4, A-D, 0,90,180,270, dll input kedua bisa menjadi 0-diindeks array 2D, 1-diindeks array 2D, String, daftar Point-benda, dll panggilan Anda. Bahkan mungkin untuk menukar koordinat x dan y dibandingkan dengan contoh input yang diberikan. Harap sebutkan format input mana yang Anda gunakan dalam jawaban Anda!
  • Anda diizinkan menambahkan spasi (yaitu 517 * 6 = 3102) jika Anda mau.
  • Anda diijinkan untuk menambahkan tertinggal angka nol setelah koma, untuk max tiga (yaitu 3102.0/ 3102.00/ 3102.000bukan 3102atau 0.430bukan 0.43).
  • Anda tidak diizinkan untuk menambahkan tanda kurung di output, jadi (((0.6+4)-0)/2)/4=0.575bukan output yang valid.
  • Anda diizinkan menggunakan simbol-simbol operan lain untuk bahasa Anda. Jadi ×atau ·bukannya *; atau ÷bukannya /; dll.
  • Karena kalkulator secara otomatis menghitung ketika memasukkan operan, Anda harus mengabaikan prioritas operator! Jadi 10+5*3akan menghasilkan 45( (10+5)*3=45), bukan 25( 10+(5*3)=25)
    (yaitu 10+5*(sekarang menampilkan 15 di layar) → 3=(sekarang menampilkan jawabannya 45)). Ingatlah ini saat menggunakan evaldan fungsi serupa pada jumlah yang dihasilkan.
  • Tidak akan ada uji kasus untuk pembagian dengan 0.
  • Tidak akan ada kasus uji dengan lebih dari tiga digit desimal sebagai hasilnya, jadi tidak perlu membulatkan hasilnya.
  • Tidak akan ada kasus uji di mana beberapa operan saling mengikuti, atau di mana dua titik saling mengikuti.
  • Tidak akan ada kasus uji untuk angka negatif. Tanda minus ( -) hanya akan digunakan sebagai operan, bukan sebagai negatif.
  • Tidak akan ada kasus uji untuk .##tanpa nomor utama sebelum koma (yaitu 2+.7tidak akan menjadi kasus uji yang valid, tetapi 2+0.7bisa jadi).

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa saja'.
  • Aturan standar berlaku untuk jawaban Anda, jadi Anda diperbolehkan menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat, program lengkap. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, tambahkan link dengan tes untuk kode Anda.
  • Juga, silakan tambahkan penjelasan jika perlu.

Kasus uji:

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
sumber
1
Kasus uji memiliki banyak kesalahan (mis. Ke-3 dan ke-4 bertukar X dan Y (ke-1 tidak) dan saya bahkan tidak tahu apa yang terjadi dengan ke-2)
dzaima
2
Haruskah program menangani penekanan tombol aneh? 1+-*/+-*/2akan memberikan 0.5pada Windows (10) kalkulator.
user202729
1
test case kedua harus dimulai dengan[1,3],
Uriel
1
Apakah kita harus menangani desimal kurang dari 1 tanpa memimpin 0s, seperti di 2+.7?
Tutleman
4
Diutamakan operator mengapa saya tidak pernah menggunakan Kalkulator Windows dalam mode standar.
Neil

Jawaban:

3

Dyalog APL, 94 88 86 85 byte

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

Cobalah online!

Mengambil rotasi sebagai argumen kiri 0-3,, dan indeks berbasis 1 sebagai argumen benar, sebagai daftar y xkoordinat, seperti (1 1)(2 3)(4 5)dll.

Ini menjadi cukup berantakan karena evaluasi ekspresi tangan kanan di APL.

Uriel
sumber
3

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

Semua optimasi harus dimatikan dan hanya bekerja pada GCC 32-bit.

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 berkat @Orion!

Cobalah online!

Prototipe fungsi:

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

Format input (seperti pada 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>

Versi tidak dikoleksi dengan komentar:

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

Kode dapat menangani kasus seperti 1+.7atau -8*4.

Sangat sedih C tidak memiliki eval😭.

Keyu Gan
sumber
Anda memang dapat menganggap kasus seperti 3*-5tidak valid. Saya sudah menentukan ini dalam aturan.
Kevin Cruijssen
Mengingat presisi yang diperlukan dalam aturan hanya 3 tempat, Anda dapat menggantinya doubledengan floatbyte gratis. Juga, tidak putc()identik dengan putchar()? Tapi aku bisa saja salah.
Orion
@Orion Saya ingat putcperlu argumen kedua untuk menentukan aliran yang Anda tulis?
Keyu Gan
292 bytes
ceilingcat
2

JavaScript (ES6), 162 160 157 byte

Mengambil input sebagai orientasi odan larik koordinat (y, x)a dalam sintaks currying (o)(a).

Orientasinya adalah bilangan bulat dalam [0..3] :

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

Uji kasus

Arnauld
sumber
2

Ruby , 135 133 132 byte

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

Cobalah online!

Orientasi sebagai bilangan bulat: 0 untuk 0 °, 1 untuk 90 ° dan seterusnya.

GB
sumber
1

Python 3, 235 234 230 byte

Agak jelek tapi berfungsi untuk semua test case kecuali yang pertama, yang sepertinya tidak cocok dengan contoh kalkulator. Saya mengambil rotasi sebagai 0-3 (0-270) dan kalikan dengan 16 untuk mengimbangi.

eval() adalah built-in yang mencoba mengkompilasi string sebagai kode dan menangani pengubahan simbol teks menjadi operator.

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

Metode alternatif, ternyata sedikit lebih lama tapi saya sangat suka tip SO ini untuk memutar array.

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

Java 10, 418 380 byte

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

Memutuskan untuk menjawab pertanyaan saya sendiri juga. Saya yakin itu bisa bermain golf lagi dengan menggunakan pendekatan yang berbeda.
Masukan sebagai int(0-3 ) dan int[][](0-diindeks / sama seperti dalam deskripsi tantangan). Output sebagai floatmemimpin .0jika hasilnya adalah bilangan bulat bukan angka desimal.

Penjelasan:

Coba di sini.

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
sumber