Thanh tra chính thức của Ruby


30

Đây là một viên ruby nghệ thuật ASCII đơn giản :

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_\/

Là một thợ kim hoàn cho Tập đoàn Đá quý ASCII, công việc của bạn là kiểm tra những viên hồng ngọc mới mua và để lại một ghi chú về bất kỳ khiếm khuyết nào bạn tìm thấy.

May mắn thay, chỉ có 12 loại khiếm khuyết là có thể, và nhà cung cấp của bạn đảm bảo rằng không có viên ruby ​​nào có nhiều hơn một khuyết điểm.

12 khuyết điểm tương ứng với sự thay thế của một trong 12 nội _, /hoặc \nhân vật của ruby với một nhân vật không gian ( ). Chu vi bên ngoài của một viên hồng ngọc không bao giờ có khuyết điểm.

Các khiếm khuyết được đánh số theo đó nhân vật bên trong có một khoảng trống ở vị trí của nó:

số khiếm khuyết

Vì vậy, một viên hồng ngọc có khuyết điểm 1 trông như thế này:

  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/

Một viên hồng ngọc có khuyết tật 11 trông như thế này:

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/

Đó là cùng một ý tưởng cho tất cả các khiếm khuyết khác.

Thử thách

Viết chương trình hoặc hàm lấy chuỗi của một viên ruby ​​có khả năng bị lỗi. Số khiếm khuyết nên được in hoặc trả lại. Số khuyết tật là 0 nếu không có khuyết tật.

Lấy đầu vào từ tệp văn bản, stdin hoặc đối số hàm chuỗi. Trả lại số khiếm khuyết hoặc in nó ra thiết bị xuất chuẩn.

Bạn có thể cho rằng viên ruby ​​có dòng mới. Bạn không thể cho rằng nó có bất kỳ dấu cách hoặc dòng mới nào.

Mã ngắn nhất tính bằng byte thắng. ( Bộ đếm byte tiện dụng. )

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

13 loại hồng ngọc chính xác, tiếp theo là sản lượng dự kiến ​​của chúng:

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_\/
0
  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/
1
  ___
 /\ /\
/_/ \_\
\ \_/ /
 \/_\/
2
  ___
 /\_/\
/_  \_\
\ \_/ /
 \/_\/
3
  ___
 /\_/\
/_/ \_\
\  _/ /
 \/_\/
4
  ___
 /\_/\
/_/ \_\
\ \ / /
 \/_\/
5
  ___
 /\_/\
/_/ \_\
\ \_  /
 \/_\/
6
  ___
 /\_/\
/_/ \ \
\ \_/ /
 \/_\/
7
  ___
 /\_ \
/_/ \_\
\ \_/ /
 \/_\/
8
  ___
 / _/\
/_/ \_\
\ \_/ /
 \/_\/
9
  ___
 /\_/\
/ / \_\
\ \_/ /
 \/_\/
10
  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/
11
  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_ /
12

Để làm rõ, ruby không thể có bất kỳ dấu vết, phải không?
Tối ưu hóa

@Optimizer Đúng
Sở thích của Calvin

@ Calvin'sHob sở thích Chúng tôi cũng có thể giả sử đầu vào không có dòng mới?
orlp

@orlp Vâng. Đó là toàn bộ quan điểm của may .
Sở thích của Calvin

Những viên hồng ngọc đối xứng. Vì vậy, không nên lỗi # 7 giống như lỗi # 10 chẳng hạn?
DavidC

Câu trả lời:


13

CJam, 27 23 byte

F7EC5ZV4DI8G6]qBb67%J%#

Chuyển đổi cơ sở 11, lấy mod 67, lấy mod 19 của kết quả sau đó tìm chỉ mục của những gì bạn có trong mảng

[15, 7, 14, 12, 5, 3, 0, 4, 13, 18, 8, 16, 6]

Ma thuật!

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


34

Ruby 2.0, 69 byte

#!ruby -Kn0rdigest
p'×ñF<ìX‚ɲŸ_'.index Digest::MD5.digest(gets)[0]

Hexdump (hiển thị trung thực dữ liệu nhị phân trong chuỗi):

00000000  23 21 72 75 62 79 20 2d  4b 6e 30 72 64 69 67 65  |#!ruby -Kn0rdige|
00000010  73 74 0a 70 27 d7 f1 46  3c 1f ec 58 82 c9 b2 9f  |st.p'..F<..X....|
00000020  5f 02 27 2e 69 6e 64 65  78 20 44 69 67 65 73 74  |_.'.index Digest|
00000030  3a 3a 4d 44 35 2e 64 69  67 65 73 74 28 67 65 74  |::MD5.digest(get|
00000040  73 29 5b 30 5d                                    |s)[0]|

Giải trình:

  1. Các -Kntùy chọn đọc file nguồn như ASCII-8BIT(nhị phân).
  2. Các -0tùy chọn cho phép getsđể đọc trong cả đầu vào (và không chỉ một dòng).
  3. Các -rdigesttùy chọn tải các digestmodule, trong đó cung cấp Digest::MD5.
  4. Đoạn mã sau đó thực hiện MD5 của đầu vào, lấy byte đầu tiên của thông báo và lấy chỉ mục của nó trong chuỗi nhị phân đã cho.

May mắn rằng MD5 là duy nhất trên chính char đầu tiên
Trình tối ưu hóa

15
Không có may mắn là cần thiết. Mỗi byte có 256 khả năng, do đó, byte đầu tiên khác nhau trong 13 lần băm không phải là điều bất thường. Nhưng nếu chúng va chạm vì bất kỳ lý do gì, tôi chỉ cần sử dụng byte thứ hai của hàm băm.
Chris Jester-Young

14
Viết một thanh tra Ruby trong Ruby. Một cách tự nhiên!
Cột

Thử thách tiếp theo: Kiểm tra bài đăng này
Chương trình Redwolf

7

Julia, 90 59 byte

Chắc chắn không phải là ngắn nhất, nhưng cô gái công bằng Julia rất cẩn trọng trong việc kiểm tra các viên hồng ngọc của hoàng gia.

s->search(s[vec([18 10 16 24 25 26 19 11 9 15 32 34])],' ')

Điều này tạo ra một hàm lambda chấp nhận một chuỗi svà trả về số khiếm khuyết ruby ​​tương ứng. Để gọi nó, đặt tên cho nó, vd f=s->....

Ungolfed + giải thích:

function f(s)
    # Strings can be indexed like arrays, so we can define d to
    # be a vector of indices corresponding to potential defect
    # locations

    d = vec([18 10 16 24 25 26 19 11 9 15 32 34])

    # Check the specified locations for defects, returning the
    # defect number as the index where a space was found and
    # was not expected. If no spaces are found, 0 is returned.

    search(s[d], ' ')
end

Ví dụ:

julia> f("  ___
 /\\ /\\
/_/ \\_\\
\\ \\_/ \/
 \\/_\\/")
2

julia> f("  ___
 /\\_/\\
/_/ \\_\\
\\ \\_/ \/
 \\/_\\/")
0

Lưu ý rằng dấu gạch chéo ngược phải được thoát trong đầu vào. Tôi đã xác nhận với @ Calvin'sHob sở thích rằng nó ổn.

Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi hoặc đề nghị!


Chỉnh sửa: Đã lưu 31 byte với sự trợ giúp từ Andrew Piliser!


Bạn có thể thoát khỏi vòng lặp for searchvà lập chỉ mục mảng. s->(d=reshape([18 10 16 24 25 26 19 11 9 15 32 34],12);search(s[d],' ')). Tôi không thích việc định hình lại, nhưng tôi không thể nghĩ ra một cách ngắn hơn để có được mảng 1d.
Andrew nói Phục hồi

@AndrewPiliser: Cảm ơn, tôi thực sự đánh giá cao đầu vào của bạn! Tôi chỉnh sửa để sử dụng đề nghị của bạn. Ngoài ra, một cách ngắn hơn reshape()là sử dụng vec(). :)
Alex A.

7

> <> (Cá) , 177 byte

Đây là một giải pháp dài nhưng độc đáo. Chương trình không chứa số học hoặc phân nhánh ngoài việc chèn các ký tự đầu vào vào các vị trí cố định trong mã.

Lưu ý rằng tất cả các ký tự xây dựng ruby ​​được kiểm tra ( / \ _) có thể là "gương" trong mã> <> thay đổi hướng của con trỏ lệnh (IP).

Chúng ta có thể sử dụng các ký tự đầu vào này để xây dựng một mê cung từ chúng bằng hướng dẫn sửa đổi mã pvà tại mỗi lối ra (được tạo bởi một gương bị thiếu trong đầu vào), chúng ta có thể in số tương ứng.

iiiiiiiii19pi1cpi18piiii2bpi27pii28pi3apiiiii37pi49pi36piiiii00pi45pii46p

    ;
   ;n
  ;nb
 ;n6S    0n;
 n3SB   cn;
 8SB!  4n;
 SB!  1n;
>B! U9n;
 ! U5
  U7n
 Uan;
 2n;
 n;
 ;

Các S B Uchữ cái là những người thay đổi / \ _tương ứng. Nếu đầu vào là một viên ruby ​​đầy đủ, mã cuối cùng sẽ trở thành:

\iiiiiiii19pi1cpi18piiii2bpi27pii28pi3apiiiii37pi49pi36piiiii00pi45pii46p

    ;
   ;n
  ;nb
 ;n6/    0n;
 n3/\   cn;
 8/\!  4n;
 /\!  1n;
>\! _9n;
 ! _5
  _7n
 _an;
 2n;
 n;
 ;

Bạn có thể thử chương trình với trình thông dịch trực quan tuyệt vời này . Vì bạn không thể nhập các dòng mới ở đó, bạn phải sử dụng một số ký tự giả thay vào đó để bạn có thể nhập một viên ruby ​​đầy đủ, ví dụ như SS___LS/\_/\L/_/S\_\L\S\_/S/LS\/_\/. (Không gian cũng thay đổi thành S vì đánh dấu.)


5

CJam, 41 31 29 28 byte

"-RI)11a!"q103b1e3%A/c#

Như thường lệ, đối với các ký tự không in được, hãy theo liên kết này .

Dùng thử trực tuyến tại đây

Giải thích sớm


Cách tiếp cận trước:

Khá chắc chắn rằng điều này có thể được giảm bằng cách thay đổi các chữ số / logic chuyển đổi. Nhưng đây là nỗ lực đầu tiên:

"<KJ[]\"O=":iqN-"/\\_ "4,er4b1e3%A/#

Như thường lệ, sử dụng liên kết này cho các ký tự không thể in.

Logic khá đơn giản

  • "Hash for each defect":i - Điều này giúp tôi băm mỗi khiếm khuyết như chỉ mục
  • qN-"/\\_ "4,er - điều này chuyển đổi các ký tự thành số
  • 4b1e3%A/ - đây là số duy nhất trong số chuyển đổi cơ sở
  • # Sau đó, tôi chỉ cần tìm chỉ mục của số duy nhất trong hàm băm

Dùng thử trực tuyến tại đây


Rất gần, tôi ngắn hơn bạn 1 ký tự!
orlp

Ồ, tôi đã có 28. Quá bận để cập nhật
Trình tối ưu hóa

Tôi nghĩ rằng câu trả lời của tôi là tối ưu cho Pyth. Pyth thực sự cần một hàm băm ( .hngay bây giờ là vô dụng vì nó sử dụng tích hợp không đáng tin cậy và xấu hash()), cho đến lúc đó tôi không thể làm tốt hơn.
orlp

4

Trượt , 123 108 + 3 = 111 byte

^6 (`\\`_.?<?.?[ _]?|`_(`\.?(<.?|>)|`/.?.?>.?.?).?)| `_(`\.?<.?>?.?.?|`/(.?>.?.?.?|<`_))| `/\`_.?(.<.?>?.?)?

Chạy với nocờ, tức là

py -3 slip.py regex.txt input.txt no

Ngoài ra, hãy thử trực tuyến .


Trượt là một ngôn ngữ giống như regex, được thực hiện như một phần của thử thách khớp mẫu 2D . Trượt có thể phát hiện vị trí của khuyết tật với pcờ vị trí thông qua chương trình sau:

^6? `_[/\]|( `/|^6 `\)\`_

tìm kiếm một trong các mẫu sau (ở đây Sbiểu thị ở đây trận đấu bắt đầu):

S_/    S_\    /_S    \_S    S/      _
                              _      \S

Hãy thử trực tuyến - tọa độ được xuất ra dưới dạng một cặp (x, y). Mọi thứ đọc như một regex bình thường, ngoại trừ rằng:

  • ` được sử dụng để trốn thoát,
  • <> xoay con trỏ tương ứng sang trái / phải tương ứng,
  • ^6 đặt con trỏ khớp với mặt trái và
  • \ trượt con trỏ khớp một cách trực giao sang phải (ví dụ: nếu con trỏ quay sang phải thì nó đi xuống một hàng)

Nhưng thật không may, những gì chúng ta cần là một số duy nhất 0-12 câu nói đó khiếm khuyết đã được phát hiện, không phải nơi nó được phát hiện. Trượt chỉ có một phương thức xuất ra một số duy nhất - ncờ xuất ra số lượng kết quả tìm thấy.

Vì vậy, để làm điều này, chúng tôi mở rộng regex ở trên để khớp số lần chính xác cho mỗi lỗi, với sự trợ giúp của ochế độ khớp chồng chéo. Bị hỏng, các thành phần là:

1 11:    `_`\.?<.?>?.?.?
2 10:    `/\`_.?(.<.?>?.?)?
4 9:     `_`/(.?>.?.?.?|<`_)
3 12:   ^6 `_`/.?.?>.?.?.?
5 7:    ^6 `\\`_.?<?.?[ _]?
6 8:    ^6 `_`\.?(<.?|>).?

Vâng, đó là một cách sử dụng quá ?mức để có được các con số đúng: P


Haha, tuyệt vời Tôi cần thêm nhiều loại đầu ra cho ngôn ngữ của mình.
BMac

4

JavaScript (ES6), 67 72

Đơn giản chỉ cần tìm khoảng trống trong 12 vị trí đã cho

Chỉnh sửa đã lưu 5 byte, thx @apsillers

F=b=>[..."0h9fnopia8evx"].map((v,i)=>b[parseInt(v,34)]>' '?0:d=i)|d

Kiểm tra trong bảng điều khiển Firefox / FireBug

x='  ___\n /\\_/\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/' // no defects
;[...x].forEach((c,p,a)=>{
  a[p]=' ' // put a blank
  y=a.join('') // rebuild a string
  d=F(y) // check
  if (d) console.log('\n'+y+'\n'+d) // if defect, output
  a[p]=c // remove the blamk
})

Đầu ra

  ___
 / _/\
/_/ \_\
\ \_/ /
 \/_\/
9

  ___
 /\ /\
/_/ \_\
\ \_/ /
 \/_\/
2

  ___
 /\_ \
/_/ \_\
\ \_/ /
 \/_\/
8

  ___
 /\_/\
/ / \_\
\ \_/ /
 \/_\/
10

  ___
 /\_/\
/_  \_\
\ \_/ /
 \/_\/
3

  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/
1

  ___
 /\_/\
/_/ \ \
\ \_/ /
 \/_\/
7

  ___
 /\_/\
/_/ \_\
\  _/ /
 \/_\/
4

  ___
 /\_/\
/_/ \_\
\ \ / /
 \/_\/
5

  ___
 /\_/\
/_/ \_\
\ \_  /
 \/_\/
6

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/
11

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_ /
12

@apsillers nó tốt và thậm chí tốt hơn, cảm ơn. Vì chuỗi đầu vào luôn bắt đầu bằng '', số 0 đứng đầu buộc khởi tạo d thành i ở vòng lặp đầu tiên, do đó, 'd = 0' có thể được loại bỏ.
edc65

2

C, 98 84 byte

g(char*b){char*c="/'-5670(&,=?",*a=c;for(;*c&&!(*b=b[*c++-30]-32?0:c-a););return*b;}

CẬP NHẬT: Một chút khéo léo hơn về chuỗi và khắc phục sự cố với các viên hồng ngọc không bị lỗi.

Làm sáng tỏ:

g(char*b){
    char*c="/'-5670(&,=?",*a=c;
    for(;*c&&!(*b=b[*c++-30]-32?0:c-a);)
        ;
    return*b;
}

Khá đơn giản và chỉ dưới 100 byte.

Để thử nghiệm:

#include "stdio.h"
int main() {
    char b[100];
    scanf("%35c", b);
    printf("%d\n", g(b));
    return 0;
}

Nhập vào STDIN.

Làm thế nào nó hoạt động

Mỗi khiếm khuyết trong viên hồng ngọc nằm ở một nhân vật khác nhau. Danh sách này hiển thị nơi mỗi lỗi xảy ra trong chuỗi đầu vào:

Defect 1: 17
Defect 2: 9
Defect 3: 15
Defect 4: 23
Defect 5: 24
Defect 6: 25
Defect 7: 18
Defect 8: 10
Defect 9: 8
Defect 10: 14
Defect 11: 31
Defect 12: 33

Vì tạo ra một mảng {17,9,15,23,24,25,18,10,8,14,31,33}chi phí rất nhiều byte, chúng tôi tìm thấy một cách ngắn hơn để tạo danh sách này. Quan sát rằng việc thêm 30 vào mỗi số sẽ dẫn đến một danh sách các số nguyên có thể được biểu diễn dưới dạng các ký tự ASCII có thể in được. Danh sách này như sau : "/'-5670(&,=?". Do đó, chúng ta có thể đặt một mảng ký tự (trong mã c) cho chuỗi này và chỉ cần trừ 30 từ mọi giá trị chúng ta lấy từ danh sách này để lấy mảng số nguyên ban đầu. Chúng tôi xác định đến số khiếm khuyết và trả lại nó.a bằng cvới việc theo dõi khoảng cách dọc theo danh sách mà chúng tôi đã nhận được. Điều duy nhất còn lại trong mã là forvòng lặp. Nó kiểm tra để đảm bảo rằng chúng ta chưa chạm đến hết c, và sau đó kiểm tra xem ký tự của bhiện tại ccó phải là khoảng trắng không (ASCII 32). Nếu có, chúng tôi đặt phần tử đầu tiên, chưa sử dụng củab


2

Con trăn 2, 146 88 86 71 byte

Hàm fkiểm tra từng vị trí phân đoạn và trả về chỉ mục của phân đoạn lỗi. Một thử nghiệm trên byte đầu tiên trong chuỗi đầu vào đảm bảo rằng chúng tôi trả về 0nếu không tìm thấy lỗi.

Bây giờ chúng tôi đóng gói các phân đoạn thành một chuỗi nhỏ gọn và sử dụng ord()để khôi phục chúng:

f=lambda s:sum(n*(s[ord('ARJPXYZSKIO`b'[n])-65]<'!')for n in range(13))

Thử nghiệm với một viên hồng ngọc hoàn hảo:

f('  ___\n /\\_/\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/')
0

Thử nghiệm với phân khúc 2 được thay thế bằng khoảng trắng:

f('  ___\n /\\ /\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/')
2

EDIT: Cảm ơn @xnor vì sum(n*bool for n in...)kỹ thuật tốt đẹp .

EDIT2: Cảm ơn @ Sp3000 để biết thêm các mẹo chơi gôn.


2
Tôi nghĩ bạn có thể lưu ký tự bằng cách sử dụng tổng chỉ số sum(n*(s[...]==' ')for ...).
xnor

1
Xem xét rằng các ký tự thay thế là tất cả sau không gian, bạn có thể có thể làm một cái gì đó như <'!'thay vì ==' 'cho một byte. Bạn cũng có thể tạo danh sách với map(ord, ...), nhưng tôi không chắc bạn cảm thấy thế nào về những thứ không thể in được :)
Sp3000

1

Pyth, 35 31 28 byte

hx"*6#,54@"C%imCds.zT67

Yêu cầu một Pyth đã được vá , phiên bản mới nhất hiện tại của Pyth có một lỗi trong .zđó loại bỏ các ký tự dấu.

Phiên bản này không sử dụng hàm băm, nó lạm dụng chức năng chuyển đổi cơ sở trong Pyth để tính toán hàm băm rất ngu ngốc nhưng hoạt động. Sau đó, chúng tôi chuyển đổi hàm băm đó thành một ký tự và tìm chỉ mục của nó trong một chuỗi.

Câu trả lời chứa các ký tự không thể in được, hãy sử dụng mã Python3 này để tạo chương trình chính xác trên máy của bạn:

garbage = [42, 22, 54, 35, 44, 28, 31, 53, 52, 64, 16, 11]
prg = 'hx"' + "".join(chr(c) for c in garbage) +'"C%imCds.zT67'
open("golf_gen.pyth", "w").write(prg)
print(len(prg))

1

Haskell, 73 byte

f l=last[x|x<-[0..12],l!!([0,17,9,15,23,24,25,18,10,8,14,31,33]!!x)==' ']

Chiến lược giống như nhiều giải pháp khác: tìm kiếm không gian tại các địa điểm nhất định. Tra cứu trả về một danh sách các chỉ số mà tôi lấy phần tử cuối cùng, bởi vì luôn có một lần truy cập cho chỉ số 0.


0

05AB1E , 16 byte

•W)Ì3ô;4(•₆вèðk>

Dùng thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

W3ô;4(•        # Push compressed integer 2272064612422082397
          ₆в      # Converted to Base-36 as list: [17,9,15,23,24,25,18,10,8,14,31,33]
            è     # Index each into the (implicit) input-string
             ðk   # Get the 0-based index of the first space in the indexed characters
                  # (-1 if not found, which means the ruby had no defects)
               >  # And increase it by 1 (which is output implicitly as result)

Xem 05AB1E mẹo này của tôi (phần Làm thế nào để nén các số nguyên lớn?Làm thế nào để liệt kê số nguyên nén? ) Để hiểu tại sao •W)Ì3ô;4(•2272064612422082397•W)Ì3ô;4(•₆в[17,9,15,23,24,25,18,10,8,14,31,33].

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.