Konverter ternary-if

18

Di Java / .NET / C / JavaScript / dll. Anda dapat menggunakan ternary-ifs untuk mempersingkat jika-pernyataan.

Misalnya (di Jawa):

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

Dapat disingkat dengan ternary-if ke:

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

Tantangan:

Input: Suatu if-else reguler (mungkin dengan nesting) yang menetapkan variabel tunggal.

Keluaran: The ternary-if yang dikonversi.

Aturan tantangan:

  • Anda dapat mengasumsikan semua case if-else dimungkinkan tanpa tanda kurung (jadi setiap blok if / else-if / else memiliki satu tubuh)
  • Anda dapat mengasumsikan tidak akan ada spasi, tab, atau baris baru, kecuali satu spasi setelah masing-masing else(termasuk pada else if).
  • Anda dapat mengasumsikan nama variabel yang digunakan selalu berupa huruf kecil tunggal ( [a-z]).
  • Nilai yang diberikan ke variabel dapat berupa:
    • String (tanpa spasi / tab / new-garis), yang akan dikelilingi oleh tanda kutip ganda (yaitu "Test", "SomeString", "Example_string", dll). Anda dapat mengasumsikan bahwa string tidak akan pernah mengandung substring ifatau else, juga tidak akan mengandung spasi, tab, baris baru, tanda kutip ganda (lolos), atau karakter =. Ini dapat berisi karakter ><(){}[];?:!&|, tetapi hanya akan berada dalam kisaran ASCII yang dapat dicetak (['!' (33), '~' (126)] ).
    • Bilangan bulat (yaitu 0, 123, -55, dll)
    • Desimal (yaitu 0.0, 0.123, -55.55, dll)
  • Nilai tidak akan pernah dicampur. Jadi semua variabel yang ditugaskan adalah bilangan bulat, dan tidak ada yang bilangan bulat dan beberapa adalah string.
  • Kondisi di dalam kurung dapat berisi karakter berikut =<>!+-/*%&|[], a-z, 0-9. Anda dapat mengasumsikan tidak akan ada kurung dalam, dan Anda juga dapat mengasumsikan tidak akan ada bidang (membingungkan) lebih dari satu karakter yang digunakan (seperti if(if<0)).
  • Anda bisa berasumsi tidak akan ada jalan pintas seperti i*=10sebaliknya i=i*10.
  • Anda tidak harus menangani kasing else, jadi semuanya ifbisa dipasangkan dengan else. Yaitu if(a)if(b)r=0;else r=1;bukan kasus input yang mungkin. if(a)if(b)r=0;else r=1;else r=2;atau if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;bagaimanapun.
  • I / O fleksibel. Input dan Output dapat berupa string, daftar karakter, baca dari STDIN, output ke STDOUT, dll. Panggilan Anda.
  • Semua terner akan memiliki asosiativitas yang tepat, seperti standar dalam kebanyakan bahasa ( tetapi tidak dalam PHP misalnya ).

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 dan tipe pengembalian, program lengkap. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda.
  • Juga, silakan tambahkan penjelasan jika memungkinkan.

Kasus uji:

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;
Kevin Cruijssen
sumber
Secara teknis, dalam F # if ... then ... elseadalah operator ternary. Jadi jika Anda menulis let result = if 10 > 100 then 99 else -99maka nilainya resultakan menjadi -99.
Ciaran_McCarthy
1
@Ciaran_McCarthy Saya berharap itu akan menjadi masalah bagi sebagian besar, jika tidak semua bahasa condong fungsional yang memiliki ekspresi bersyarat sebagai default. Clojure, Scala, dan Haskell adalah sama.
Carcigenicate
@tsh Ups .. Saya tidak perlu menambahkan test case di sore hari setelah seharian bekerja .. Memperbaiki.
Kevin Cruijssen
2
JavaScript Compressor Closure Compiler bekerja sangat baik pada semua testcases ini. Yang ketika mengambil input yang diberikan hanya akan menghasilkan output yang diharapkan. Tapi sepertinya saya tidak bisa mengklaimnya sebagai jawaban. Jadi saya ingin berkomentar di sini.
tsh

Jawaban:

5

Retina 0.8.2 , 32 byte

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

Cobalah online! Penjelasan:

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

Tangani ifsegera sebelum penugasan dengan memindahkan penugasan sebelum kondisi dan menambahkan a ?. Panggung dicocokkan dari kanan ke kiri untuk memastikan kami mendapatkan jika terdekat dengan tugas, sementara panggung \)memastikan bahwa kami tidak cocok elsedengan kesalahan.

+

Ulangi tahap ini untuk merawat sarang if.

;.{6}=
:

Tugas yang tersisa adalah elsejadi ganti ;else ?=dengan a :.

Neil
sumber
@nwellnhof Terima kasih telah menunjukkan itu; Saya pikir saya sedang bermain golf byte di sana karena itu bekerja pada kasus uji.
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*

Cobalah online!


Diselamatkan:

  • -1 byte, terima kasih kepada Kevin Cruijssen
TFeld
sumber
@KevinCruijssen Terima kasih :)
TFeld
1
Mengapa definisi fungsi sebelum impor?
Skyler
@ Skyler Ini sebenarnya tidak masalah, tetapi lebih mudah untuk menempatkan tugas di header dengan cara ini
Jo King
6

Perl 5 -p, 50 49 48 byte

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

Cobalah online!

Versi 48 byte terinspirasi oleh jawaban Neil's Retina.

Penjelasan

# 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

Solusi 49 byte lama

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

Ruby , 72 71 byte

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

Cobalah online!

GB
sumber
Bisa ;elseatau else bisa .{5}untuk menyimpan byte.
Kevin Cruijssen
1
Terima kasih, saya menemukan sesuatu yang berbeda dengan efek yang sama.
GB
3

Java (JDK) , 119 116 byte

Solusi regex hampir seluruhnya murni, dicincang dan diubah sedikit dari beberapa jawaban lainnya.

-3 Bytes berkat beberapa tipu daya regex dari Kevin

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

Cobalah online!

Penjelasan

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
Luke Stevens
sumber
1
Saya suka yang ".*(.=).*","$1$0"Anda gunakan, 1 byte lebih pendek dari yang "^(.*)(.=)","$2$1"saya pikirkan. :) Bagaimanapun, Anda dapat menyimpan 2 byte yang berubah if\\(menjadi if.dan byte tambahan yang diubah (\\?| )menjadi ([? ]). Cobalah secara online 116 byte .
Kevin Cruijssen
@KevinCruijssen Cheers! Saya menghabiskan waktu lama mencoba mengurangi regex ke bawah, saya tidak percaya saya melewatkan itu!
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>

Penjelasan:

Kakoune adalah editor modal berbasis banyak pilihan, terinspirasi oleh Vim.

  1. x pilih seluruh baris

  2. s... <ret>filter pilihan dengan ekspresi reguler \w=(?!=), yang cocok dengan semua tugas variabel, dan tidak cocok dengan ==perbandingan

  3. d hapus setiap pilihan dan masukkan isinya ke register default

  4. <a-h> rentangkan semua pilihan ke awal baris mereka

  5. P rekatkan isi register default sebelum setiap pilihan

  6. s... <ret>filter pilihan dengan ekspresi regulerif.

  7. d hapus setiap pilihan

  8. f memperpanjang setiap pilihan maju ke depan )

  9. ; kurangi setiap pilihan ke kursornya

  10. r ganti setiap karakter dari setiap pilihan dengan ?

  11. x pilih seluruh baris

  12. s... <ret>saring pilihan dengan;else<space>

  13. c... <esc>hapus setiap pilihan dan ganti dengan:

animasi kode pada test case:

Kode Beraksi

Vaelus
sumber
1
Hmm, saya belum pernah mendengar tentang Kakoune sebelumnya. Saya kira tidak ada kompiler online untuk itu? Jika tidak, bisakah Anda menambahkan beberapa tangkapan layar dari beberapa kasus uji sehingga saya dapat memverifikasinya berfungsi sebagaimana dimaksud? Juga, jika ini adalah bahasa Anda, Anda dapat menghubungi Dennis di obrolan talk.tryitonline.net untuk menanyakan apakah ia dapat menambahkannya ke TIO .
Kevin Cruijssen
1
@KevinCruijssen Saya menambahkan gif dari salah satu kasus uji. Ini bekerja pada mereka semua, tetapi membuat gif tidak sepele.
Vaelus
Terima kasih atas penjelasannya dan gif, +1 dari saya. :) Selalu senang belajar tentang bahasa baru.
Kevin Cruijssen
2

Bersih , 386 375 216 196 189 byte

Lihat bu, jangan 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]

Cobalah online!

Suram
sumber
1

JavaScript (Node.js) , 80 byte

s=>(p=s.replace(/(?:if.(.*?)\)|;.*? )(.=)?/g,(_,t,v)=>(V=v||V,t)?t+'?':':'),V+p)

Cobalah online!

Berkat Kevin Cruijssen, 2 byte disimpan.

tsh
sumber
if\(dapat if.dan ;else dapat ;.{5}menghemat 2 byte
Kevin Cruijssen