Bộ chuyển đổi Ternary-if


18

Trong Java / .NET / C / JavaScript / v.v. bạn có thể sử dụng ternary-ifs để rút ngắn if-statement.

Ví dụ: (trong Java):

// there is a String `s` and an int `i`
if(i<0)s="Neg";else if(i>0)s="Pos";else s="Neut";

Có thể rút ngắn bằng một ternary-if to:

s=i<0?"Neg":i>0?"Pos":"Neut";

Thử thách:

Đầu vào: Một if-other thông thường (có thể với lồng nhau) đặt một biến duy nhất.

Đầu ra: The ternary-if.

Quy tắc thử thách:

  • Bạn có thể giả sử tất cả các trường hợp if-other đều có thể mà không có dấu ngoặc (vì vậy mỗi khối if / other-if / other có một thân).
  • Bạn có thể cho rằng sẽ không có bất kỳ khoảng trắng, tab hoặc dòng mới nào, ngoại trừ một khoảng trắng sau mỗi khoảng trống else(bao gồm tại else if).
  • Bạn có thể giả sử các tên biến được sử dụng luôn là một chữ cái viết thường ( [a-z]).
  • Các giá trị được cung cấp cho các biến có thể là một trong:
    • Strings (không có dấu cách / tab / new-lines), mà sẽ được bao quanh bởi hai dấu ngoặc kép (ví dụ "Test", "SomeString", "Example_string", vv). Bạn có thể giả sử các chuỗi sẽ không bao giờ chứa các chuỗi con ifhoặc elsecũng không chứa các khoảng trắng, tab, dòng mới, dấu ngoặc kép (thoát) hoặc ký tự =. Nó có thể chứa các ký tự ><(){}[];?:!&|, nhưng sẽ chỉ nằm trong phạm vi ASCII có thể in ( ['!' (33), '~' (126)]).
    • Số nguyên (ví dụ 0, 123, -55, vv)
    • Số thập phân (tức là 0.0, 0.123, -55.55, vv)
  • Các giá trị sẽ không bao giờ được trộn lẫn. Vì vậy, tất cả các biến được gán là số nguyên, và không phải một số là số nguyên và một số là chuỗi.
  • Các điều kiện trong ngoặc đơn có thể chứa các ký tự sau =<>!+-/*%&|[], a-z, 0-9. Bạn có thể cho rằng sẽ không có bất kỳ dấu ngoặc đơn bên trong nào và bạn cũng có thể cho rằng sẽ không có bất kỳ trường (khó hiểu) nào có nhiều hơn một ký tự được sử dụng (như if(if<0)).
  • Bạn có thể cho rằng sẽ không có bất kỳ lối tắt nào như i*=10thay vì i=i*10.
  • Bạn sẽ không phải xử lý elsecác trường hợp lơ lửng , vì vậy tất cả ifcó thể được ghép nối với một else. Tức if(a)if(b)r=0;else r=1;là không phải là một trường hợp đầu vào có thể. if(a)if(b)r=0;else r=1;else r=2;hoặc if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;là tuy nhiên.
  • I / O là linh hoạt. Đầu vào và đầu ra có thể là một chuỗi, danh sách các ký tự, đọc từ STDIN, đầu ra thành STDOUT, v.v. Cuộc gọi của bạn.
  • Tất cả các ternary sẽ có một sự kết hợp đúng, như là tiêu chuẩn trong hầu hết các ngôn ngữ ( nhưng không phải trong ví dụ PHP ).

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 và kiểu trả về, 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ó thể.

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

Input:   if(i<0)s="Neg";else if(i>0)s="Pos";else s="Neut";
Output:  s=i<0?"Neg":i>0?"Pos":"Neut";

Input:   if(i%2<1)r=10;else r=20;
Output:  r=i%2<1?10:20;

Input:   if(n<10)if(m<0)i=0;else i=10;else if(m<0)i=-1;else i=1;
Output:  i=n<10?m<0?0:10:m<0?-1:1;

Input:   if(i==1)i=0.0;else i=0.25;
Output:  i=i==1?0.0:0.25;

Input:   if(!a)if(b)r=0;else r=1;else r=2;
Output:  r=!a?b?0:1:2;

Input:   if(a)if(b)r=0;else r=1;else if(c)r=2;else r=3;
Output:  r=a?b?0:1:c?2:3;

Input:   if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;
Output:  r=a&&b?0:a&&!b?1:-1;

Input:   if(i[0]>0)if(j>0)if(q>0)r="q";else r="j";else r="i";else r="other";
Output:  r=i[0]>0?j>0?q>0?"q":"j":"i":"other";

Input:   if(i>0)r="i";else if(j>0)r="j";else if(q>0)r="q";else r="other";
Output:  r=i>0?"i":j>0?"j":q>0?"q":"other";

Input:   if(a>0)if(a<2)x="one";else if(a<3)x="two";else if(a<4)x="three";else x="other";else x="other";
Output:  x=a>0?a<2?"one":a<3?"two":a<4?"three":"other":"other";

Input:   if(b[0]<=b[1])q=5;else if(b[0]==null)q=0;else q=-10;
Output:  q=b[0]<=b[1]?5:b[0]==null?0:-10;

Về mặt kỹ thuật, trong F # if ... then ... elselà toán tử ternary. Vì vậy, nếu bạn viết let result = if 10 > 100 then 99 else -99thì giá trị của resultsẽ là -99.
Ciaran_McCarthy

1
@Ciaran_McCarthy Tôi hy vọng rằng đó là trường hợp của hầu hết, nếu không phải tất cả các ngôn ngữ nghiêng chức năng có biểu thức điều kiện là mặc định. Clojure, Scala và Haskell giống nhau.
Carcigenicate

@tsh Rất tiếc .. Tôi không nên thêm trường hợp kiểm tra vào buổi tối muộn sau một ngày làm việc .. Đã sửa.
Kevin Cruijssen

2
Trình biên dịch đóng cửa máy nén JavaScript hoạt động tuyệt vời trên tất cả các testcase này. Mà khi lấy các đầu vào đã cho sẽ chỉ tạo ra các đầu ra dự kiến. Nhưng dường như tôi không thể khẳng định nó như một câu trả lời. Vì vậy tôi muốn bình luận ở đây.
tsh

Câu trả lời:


5

Võng mạc 0.8.2 , 32 byte

+r`if.(.*?)\)(.=)
$2$1?
;.{6}=
:

Hãy thử trực tuyến! Giải trình:

r`if.(.*?)\)(.=)
$2$1?

Xử lý ifngay lập tức trước khi chuyển nhượng bằng cách di chuyển chuyển nhượng trước điều kiện và nối thêm a ?. Giai đoạn được khớp từ phải sang trái để đảm bảo chúng tôi nhận được nếu gần nhất với nhiệm vụ, trong khi \)đảm bảo rằng chúng tôi không khớp elsedo nhầm lẫn.

+

Lặp lại giai đoạn để chăm sóc ifs lồng nhau .

;.{6}=
:

Bất kỳ bài tập còn lại là elses vì vậy thay thế ;else ?=bằng a :.


@nwellnhof Cảm ơn bạn đã chỉ ra rằng; Tôi nghĩ rằng tôi đã chơi golf một byte ngoài đó vì nó hoạt động trên các trường hợp thử nghiệm.
Neil

6

Python 2 , 126 121 120 114 100 byte

lambda s:findall(' (.=)',s)[0]+sub('if.(.*?)\)(.=)?',r'\1?',sub('.{5} (.=)?',':',s))
from re import*

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


Đã lưu:

  • -1 byte, nhờ Kevin Cruijssen

@KevinCruijssen Cảm ơn :)
TFeld

1
Tại sao định nghĩa hàm trước khi nhập?
Skyler

@Skyler Điều đó không thực sự quan trọng, nhưng việc đặt nhiệm vụ vào tiêu đề theo cách này sẽ dễ dàng hơn
Jo King

6

Perl 5 -p, 50 49 48 byte

s/if.(.*?)\)(.=)/\2\1?/g;s/.if./?/g;s/;.{6}=/:/g

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

Phiên bản 48 byte được lấy cảm hứng từ câu trả lời Retina của Neil.

Giải trình

# Replace "if(e1)if(e2)x=" with "x=e1)if(e2?"
s/if.(.*?)\)(.=)/\2\1?/g;
# Replace ")if(" with "?"
s/.if./?/g;
# Replace ";else x=" with ":"
s/;.{6}=/:/g

Giải pháp 49 byte cũ

s/.{5} (.=)?/:/g;s/if.(.*?)\)(.=)?/\1?/g;$_=$2.$_

3

Ruby , 72 71 byte

->s{$a=$2while s.gsub!(/if.(.*?)\)(.=)?(.*?);\w* (.=)?/,'\1?\3:');$a+s}

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


Hoặc là ;elsehoặc else có thể .{5}để lưu một byte.
Kevin Cruijssen

1
Cảm ơn, tôi tìm thấy một cái gì đó khác nhau với cùng một hiệu ứng.
GB

3

Java (JDK) , 119 116 byte

Hầu như hoàn toàn là giải pháp regex thuần túy, cắt nhỏ và thay đổi một chút từ một vài câu trả lời khác.

-3 byte nhờ một số thủ thuật regex khác từ Kevin

s->s.replaceAll(".*(.=).*","$1$0").replaceAll("if.(.*?)\\)","$1?").replaceAll("([ ?]).=","$1").replace(";else ",":")

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

Giải trình

s->                                         // Lambda function taking a String
   s.replaceAll(".*(.=).*","$1$0")          // Find assigned variable and append to start of String
    .replaceAll("if.(.*?)\\)","$1?")        // Replace any 'if' statements with their condition
                                            // followed by '?'
    .replaceAll("([? ]).=","$1")            // Remove all assignments after a '?' or space
    .replace(";else ",":");                 // Simple replace (no regex) to remove 'else' statements

1
Tôi thích cái ".*(.=).*","$1$0"bạn đã sử dụng, nó ngắn hơn 1 byte so với cái "^(.*)(.=)","$2$1"tôi nghĩ. :) Dù sao, bạn có thể tiết kiệm 2 byte thay đổi if\\(để if.và một byte thêm thay đổi (\\?| )để ([? ]). Hãy thử trực tuyến 116 byte .
Kevin Cruijssen

@KevinCruijssen Chúc mừng! Tôi đã dành quá nhiều thời gian để cố gắng giảm bớt regex xuống, tôi không thể tin rằng tôi đã bỏ lỡ điều đó!
Luke Stevens

3

Kakoune v2018.09.04 , 43 38 37 byte

xs\w=(?!=)<ret>d<a-h>Psif.<ret>df);r?xs;else<space><ret>c:<esc>

Giải trình:

Kakoune là một trình biên tập theo chế độ, nhiều lựa chọn, lấy cảm hứng từ Vim.

  1. x chọn toàn bộ dòng

  2. s... <ret>lọc lựa chọn với biểu thức chính quy \w=(?!=), khớp với tất cả các phép gán biến và không khớp ==so sánh

  3. d xóa từng lựa chọn và đưa nội dung của nó vào thanh ghi mặc định

  4. <a-h> mở rộng tất cả các lựa chọn đến đầu dòng của họ

  5. P dán nội dung của thanh ghi mặc định trước mỗi lựa chọn

  6. s... <ret>lọc lựa chọn với biểu thức chính quyif.

  7. d xóa từng lựa chọn

  8. f mở rộng mỗi lựa chọn về phía trước để tiếp theo )

  9. ; giảm từng lựa chọn về con trỏ của nó

  10. r thay thế từng ký tự của mỗi lựa chọn bằng ?

  11. x chọn toàn bộ dòng

  12. s... <ret>lọc lựa chọn với;else<space>

  13. c... <esc>xóa từng lựa chọn và thay thế nó bằng:

hình ảnh động của mã trên một trường hợp thử nghiệm:

Mã đang hoạt động


1
Hmm, tôi chưa bao giờ nghe nói về Kakoune trước đây. Tôi đoán không có trình biên dịch trực tuyến nào cho nó? Nếu không, có lẽ bạn có thể thêm một số ảnh chụp màn hình của một số trường hợp thử nghiệm để tôi có thể xác minh nó hoạt động như dự định không? Ngoài ra, nếu đây là ngôn ngữ của bạn, bạn có thể liên hệ với Dennis trong cuộc trò chuyện talk.tryitonline.net để hỏi liệu anh ấy có thể thêm ngôn ngữ đó vào TIO không .
Kevin Cruijssen

1
@KevinCruijssen Tôi đã thêm một gif của một trong những trường hợp thử nghiệm. Nó hoạt động trên tất cả chúng, nhưng làm cho các gifs không tầm thường.
Vaelus

Cảm ơn lời giải thích và gif, +1 từ tôi. :) Luôn luôn tốt đẹp để tìm hiểu về một ngôn ngữ mới.
Kevin Cruijssen

2

Sạch sẽ , 386 375 216 196 189 byte

Nhìn ma, không có regex!

import StdEnv,Data.List
?[_,'=':b]= $b
?b= $b
$['if(':s]#(h,[_:t])=span((<>)')')s
=h++['?': ?t]
$[';else ':s]=[':': ?s]
$[a:b]|b>[]=[a: $b]=b
@s=hd[[v,e: $s]\\['else ',v,e=:'=':_]<-tails s]

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


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.