Quay máy tính


16

Giới thiệu:

Chúng ta hãy xem một Máy tính tiêu chuẩn trong Windows: Đối với thử thách này, chúng ta sẽ chỉ nhìn vào các nút sau và bỏ qua mọi thứ khác:
nhập mô tả hình ảnh ở đây

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

Thử thách:

Đầu vào:
Bạn sẽ nhận được hai đầu vào:

  • Một là một cái gì đó để chỉ ra góc quay theo gia số 90 độ
  • Cái còn lại là một danh sách các tọa độ đại diện cho các nút được nhấn trên máy tính xoay.

Dựa trên đầu vào đầu tiên, chúng tôi xoay bố cục được đề cập ở trên theo chiều kim đồng hồ với bước tăng 90 độ. Vì vậy, nếu đầu vào là 0 degrees, nó vẫn như cũ; nhưng nếu đầu vào là 270 degrees, nó sẽ được quay ba lần theo chiều kim đồng hồ (hoặc một lần ngược chiều kim đồng hồ). Dưới đây là bốn cách bố trí có thể:

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

Các đầu vào thứ hai là danh sách các tọa độ trong bất kỳ định dạng hợp lý . Ví dụ: mảng số nguyên 2D 0 chỉ số):

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

Đầu ra:
Chúng tôi xuất cả tổng, cũng như kết quả (và dấu bằng =).

Ví dụ:
Vì vậy, nếu đầu vào là 270 degrees[[1,2],[2,3],[0,3],[1,0],[1,1]], đầu ra sẽ trở thành:

517*6=3102

Quy tắc thử thách:

  • Các đầu vào có thể ở bất kỳ định dạng hợp lý. Đầu vào đầu tiên có thể là 0-3,1-4 , A-D, 0,90,180,270, vv đầu vào thứ hai có thể là một 0-lập chỉ mục mảng 2D, 1-lập chỉ mục mảng 2D, một String, danh sách các điểm-đối tượng, vv Cuộc gọi của bạn. Thậm chí có thể hoán đổi tọa độ x và y so với các đầu vào ví dụ đã cho. Vui lòng cho biết các định dạng đầu vào bạn đã sử dụng trong câu trả lời của bạn!
  • Bạn được phép thêm khoảng trắng (tức là 517 * 6 = 3102) nếu bạn muốn.
  • Bạn được phép thêm các số 0 ở sau dấu phẩy, tối đa là ba (tức là 3102.0/ 3102.00/ 3102.000thay vì 3102hoặc0.430 thay vì 0.43).
  • Bạn không được phép thêm dấu ngoặc đơn trong đầu ra, vì vậy (((0.6+4)-0)/2)/4=0.575 không phải là đầu ra hợp lệ.
  • Bạn được phép sử dụng các ký hiệu toán hạng khác cho ngôn ngữ của mình. Vì vậy ×hoặc ·thay vì *; hoặc là÷ thay vì /; Vân vân.
  • Vì một máy tính tự động tính toán khi nhập toán hạng, bạn nên bỏ qua quyền ưu tiên của toán tử! Vì vậy, 10+5*3sẽ dẫn đến 45( (10+5)*3=45), không 25( 10+(5*3)=25)
    (tức là 10+5*(hiện tại nó sẽ hiển thị 15 trong màn hình) → 3=(bây giờ nó sẽ hiển thị câu trả lời 45)). Hãy ghi nhớ điều này khi sử dụng evalvà các chức năng tương tự trên tổng kết quả.
  • Sẽ không có trường hợp kiểm tra nào cho phép chia 0.
  • Kết quả sẽ không có bất kỳ trường hợp thử nghiệm nào có nhiều hơn ba chữ số thập phân, do đó không cần làm tròn kết quả.
  • Sẽ không có bất kỳ trường hợp thử nghiệm nào mà nhiều toán hạng theo nhau hoặc khi hai dấu chấm theo nhau.
  • Sẽ không có trường hợp kiểm tra nào cho số âm. Dấu trừ ( -) sẽ chỉ được sử dụng làm toán hạng, không âm.
  • Sẽ không có trường hợp kiểm tra nào .##mà không có số dẫn đầu trước dấu phẩy (nghĩa là 2+.7sẽ không phải là trường hợp kiểm tra hợp lệ, nhưng 2+0.7có thể).

Quy tắc chung:

  • Đây là , vì vậy câu trả lời ngắn nhất bằng byte thắng.
    Đừng để ngôn ngữ mã-golf ngăn cản bạn đăng câu trả lời với các ngôn ngữ không mã hóa. Cố gắng đưa ra một câu trả lời càng ngắn càng tốt cho ngôn ngữ lập trình 'bất kỳ'.
  • Các quy tắc chuẩn áp dụng cho câu trả lời của bạn, vì vậy bạn được phép sử dụng STDIN / STDOUT, các hàm / phương thức với các tham số thích hợp, các chương trình đầy đủ. Cuộc gọi của bạn.
  • Lỗ hổng mặc định bị cấm.
  • Nếu có thể, vui lòng thêm một liên kết với một bài kiểm tra cho mã của bạn.
  • Ngoài ra, xin vui lòng thêm một lời giải thích nếu cần thiết.

Các trường hợp thử nghiệm:

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
Các trường hợp thử nghiệm có nhiều lỗi (ví dụ: thứ 3 và thứ 4 có X và Y bị tráo đổi (thứ 1 không có) và tôi thậm chí không biết chuyện gì đã xảy ra với lần thứ 2)
dzaima

2
Chương trình có nên xử lý ấn nút lạ không? 1+-*/+-*/2sẽ cung cấp cho 0.5máy tính Windows (10).
dùng202729

1
trường hợp thử nghiệm thứ hai nên bắt đầu với[1,3],
Uriel

1
Chúng ta có phải xử lý số thập phân nhỏ hơn 1 mà không dẫn 0 không, như trong 2+.7?
Người hướng dẫn

4
Ưu tiên toán tử là lý do tại sao tôi không bao giờ sử dụng Máy tính Windows ở chế độ tiêu chuẩn.
Neil

Câu trả lời:


4

SOGL V0.12 , 70 69 67 byte

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

Dùng thử tại đây hoặc thử phiên bản nhận đầu vào như được đưa ra trong các trường hợp thử nghiệm

sử dụng Itoán tử SOGLs , làm quay mảng. Sau đó đọc một chuỗi dưới dạng một mảng JavaScript và sử dụng một thao tác, bao gồm kết quả trước đó trong ngoặc đơn, đánh giá là JavaScript và sau đó loại bỏ dấu ngoặc đơn.


3

Thuốc nhuộm APL, 94 88 86 85 byte

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

Hãy thử trực tuyến!

Lấy các phép quay làm đối số bên trái 0-3và các chỉ số dựa trên 1 làm đối số bên phải, dưới dạng danh sách y xtọa độ, như (1 1)(2 3)(4 5)v.v.

Điều này trở nên khá lộn xộn vì đánh giá các biểu thức thuận tay phải trong APL.


3

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

Tất cả các tối ưu hóa cần phải được tắt và chỉ hoạt động trên 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 nhờ @Orion!

Hãy thử trực tuyến!

Nguyên mẫu chức năng:

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

Định dạng đầu vào (như trên 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>

Phiên bản Ungolfed với ý kiến:

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

Mã có thể xử lý các trường hợp như 1+.7hoặc -8*4.

Rất buồn C không có eval😭.


Bạn thực sự có thể coi các trường hợp như 3*-5không hợp lệ. Tôi đã chỉ định điều này trong các quy tắc.
Kevin Cruijssen

Xem xét độ chính xác cần thiết trong các quy tắc chỉ có 3 vị trí, bạn có thể thay thế doublebằng floatmột byte miễn phí. Ngoài ra, không putc()giống hệt putchar()? Tôi có thể sai mặc dù.
Orion

@Orion Tôi nhớ putccần một đối số thứ hai để chỉ định luồng nào bạn đang viết?
Keyu Gan


2

JavaScript (ES6), 162 160 157 byte

Lấy đầu vào là định hướng ovà mảng của tọa độ (y, x)a theo cú pháp currying (o)(a).

Định hướng là một số nguyên trong [0..3] :

  • 0 = 0 °
  • 1 = 90 ° theo chiều kim đồng hồ
  • 2 = 180 ° theo chiều kim đồng hồ
  • 3 = 270 ° theo chiều kim đồng hồ
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`)`)

Các trường hợp thử nghiệm


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

Hãy thử trực tuyến!

Định hướng dưới dạng số nguyên: 0 cho 0 °, 1 cho 90 °, v.v.


1

Python 3, 235 234 230 byte

Bit xấu xí nhưng nó hoạt động cho tất cả các trường hợp thử nghiệm ngoại trừ trường hợp đầu tiên, dường như không khớp với máy tính mẫu. Tôi lấy số vòng quay là 0-3 (0-270) và nhân với 16 để bù.

eval() là một tích hợp trong đó cố gắng biên dịch chuỗi dưới dạng mã và xử lý chuyển đổi các ký hiệu văn bản thành toán tử.

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

Phương pháp thay thế, hóa ra lâu hơn một chút nhưng tôi thực sự thích mẹo SO này để xoay mảng.

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

Quyết định trả lời câu hỏi của riêng tôi là tốt. Tôi chắc chắn rằng nó có thể được đánh gôn thêm bằng cách sử dụng một cách tiếp cận khác.
Nhập dưới dạng int( 0-3) và int[][](0-index / giống như trong mô tả thử thách). Đầu ra như floatdẫn đầu .0nếu kết quả là một số nguyên thay vì số thập phân.

Giải trình:

Hãy thử nó ở đây.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.