Ternary-if конвертер


18

У Java / .NET / C / JavaScript / тощо. ви можете використовувати ternar-ifs для скорочення if-заяви.

Наприклад (на Java):

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

Можна скоротити з потрійним, якщо:

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

Виклик:

Введення: звичайний if-else (можливо з вкладкою), який встановлює єдину змінну.

Вихід: перетворений потрійний, якщо.

Правила виклику:

  • Ви можете припустити, що всі випадки if-else можливі без дужок (тому кожен блок if / else-if / else має одне тіло).
  • Можна припустити, що між ними не буде пробілів, вкладок чи нових рядків, за винятком одного пробілу після кожного else(включаючи в else if).
  • Ви можете припустити, що імена змінних завжди є однією малою літерою ( [a-z]).
  • Значення, надані змінним, можуть бути одним із:
    • Рядки (без пробілів / вкладки / новий рядок), які будуть оточені подвійними лапками (наприклад "Test", "SomeString", "Example_string"і т.д.). Ви можете припустити, що рядки ніколи не будуть містити підрядки ifабо else, а також не містити пробілів, вкладок, нових рядків, (уникнутих) подвійних лапок чи символу =. Він може містити символи ><(){}[];?:!&|, але буде лише в діапазоні для друку ASCII ( ['!' (33), '~' (126)]).
    • Цілі (тобто 0, 123, -55і т.д.)
    • Десяткові (тобто 0.0, 0.123, -55.55і т.д.)
  • Ці значення ніколи не будуть змішуватися. Отже, всі призначені змінні є цілими числами, а не деякі цілими числами, а деякі - рядками.
  • Умови в круглих дужках може містити наступні символи =<>!+-/*%&|[], a-z, 0-9. Ви можете припустити, що внутрішніх дужок не буде, і ви також можете припустити, що не буде використаних (заплутаних) полів з більш ніж одного символу (наприклад if(if<0)).
  • Ви можете припустити, що i*=10замість них не буде таких скорочень i=i*10.
  • Вам не доведеться обробляти звисаючі elseвипадки, тому всі ifможна поєднати з else. Тобто if(a)if(b)r=0;else r=1;не можливий вхідний випадок. if(a)if(b)r=0;else r=1;else r=2;або if(a&&b)r=0;else if(a&&!b)r=1;else r=-1;, однак, є.
  • Введення / виведення гнучко. Введення та вихід можуть бути рядком, списком символів, прочитаним з STDIN, виведенням в STDOUT тощо. Ваш дзвінок.
  • Усі тернарі матимуть правильну асоціативність, як це є стандартом у більшості мов ( але не для, наприклад, PHP ).

Загальні правила:

  • Це , тому найкоротша відповідь у байтах виграє.
    Не дозволяйте мовам коду-гольфу відштовхувати вас від публікації відповідей з не кодовими гольф-мовами. Спробуйте придумати якомога коротшу відповідь на "будь-яку" мову програмування.
  • Стандартні правила застосовуються до вашої відповіді, тому вам дозволяється використовувати STDIN / STDOUT, функції / метод із відповідними параметрами та повним програмами типу "повернення". Твій дзвінок.
  • Лазівки за замовчуванням заборонені.
  • Якщо можливо, додайте посилання з тестом для вашого коду.
  • Також, будь ласка, додайте пояснення, якщо це можливо.

Тестові приклади:

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;

Технічно у F # if ... then ... elseє потрійний оператор. Тож якщо ви пишете, let result = if 10 > 100 then 99 else -99то значення resultбуло б -99.
Ciaran_McCarthy

1
@Ciaran_McCarthy Я б очікував, що це стосується більшості, якщо не всіх функціональних мов, які мають умовні вирази за замовчуванням. Clojure, Scala і Haskell - те саме.
Carcigenicate

@tsh На жаль, я не повинен додавати тестові справи пізно ввечері після робочого дня. Виправлено.
Кевін Кройсейсен

2
Компілятор закриття компресорів JavaScript чудово працює на всіх цих тестах. Що при прийнятті даних входів просто генерує очікувані результати. Але здається, що я не можу стверджувати це як відповідь. Тому я хотів би тут прокоментувати.
tsh

Відповіді:


5

Сітківка 0,8,2 , 32 байти

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

Спробуйте в Інтернеті! Пояснення:

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

Обробляйте ifбезпосередньо перед завданням, переміщуючи завдання перед умовою та додаючи a ?. Етап узгоджується справа наліво, щоб гарантувати, що ми отримаємо, якщо найближче до завдання, тоді як \)гарантує, що ми не збігаємося elseпомилково.

+

Повторіть етап, щоб подбати про вкладені ifs.

;.{6}=
:

Всі інші присвоєння elseїй так замінити ;else ?=з :.


@nwellnhof Дякую, що вказав на це; Я подумав, що там займаю байт, тому що це працювало на тестових випадках.
Ніл

6

Python 2 , 126 121 120 114 100 байт

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

Спробуйте в Інтернеті!


Збережено:

  • -1 байт, завдяки Kevin Cruijssen

@KevinCruijssen Дякую :)
TFeld

1
Чому визначається функція перед імпортом?
Skyler

@Skyler Це насправді не має значення, але простіше поставити завдання таким чином у шапку
Jo King

6

Perl 5 -p, 50 49 48 байт

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

Спробуйте в Інтернеті!

48-байтна версія натхненна відповіддю Ніта на Сітківку.

Пояснення

# 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

Старий 49-байтний розчин

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


3

Ява (JDK) , 119 116 байт

Майже цілком чистий розчин для регулярного генерування, нарізаний та трохи змінений із пари інших відповідей.

-3 байти завдяки ще одній хитрості регексу від Кевіна

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

Спробуйте в Інтернеті!

Пояснення

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
Мені подобається, що ".*(.=).*","$1$0"ти використовував, це на 1 байт коротше, ніж "^(.*)(.=)","$2$1"я мав на увазі. :) В будь-якому випадку, ви можете зберегти 2 байти зміни if\\(в if.і додаткові байтах зміна (\\?| )в ([? ]). Спробуйте в Інтернеті 116 байт .
Kevin Cruijssen

@KevinCruijssen Привіт! Я так довго намагався збити регекс вниз, я не можу повірити, що пропустив це!
Люк Стівенс

3

Kakoune v2018.09.04 , 43 38 37 байт

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

Пояснення:

Kakoune - модальний редактор, заснований на декількох виборах, натхненний Vim.

  1. x виберіть весь рядок

  2. s... <ret>відфільтруйте виділення за регулярним виразом \w=(?!=), який відповідає всім призначенню змінних і не відповідає ==порівнянням

  3. d видаліть кожен вибір і помістіть його вміст у регістр за замовчуванням

  4. <a-h> розширити всі виділення до початку рядка

  5. P вставити вміст регістра за замовчуванням перед кожним вибором

  6. s... <ret>фільтруйте виділення за регулярним виразомif.

  7. d видалити кожен вибір

  8. f розширити кожен вибір вперед до наступного )

  9. ; зменшити кожен вибір до його курсору

  10. r замініть кожен символ кожного вибору на ?

  11. x виберіть весь рядок

  12. s... <ret>фільтруйте виділення за допомогою;else<space>

  13. c... <esc>очистити кожен вибір і замінити його:

анімація коду на тестовому випадку:

Кодекс в дії


1
Хм, я ніколи раніше не чув про Какун. Я думаю, немає для нього жодного онлайн-компілятора? Якщо ні, чи не могли б ви додати скріншоти деяких тестових випадків, щоб я міг переконатися, що він працює за призначенням? Крім того, якщо це ваша мова, ви можете зв’язатися з Денісом у чаті talk.tryitonline.net, щоб запитати, чи може він додати його до TIO .
Kevin Cruijssen

1
@KevinCruijssen Я додав gif одного з тестових випадків. Він працює на всіх них, але зробити gif-карти не тривіально.
Ваелюс

Дякую за пояснення та gif, +1 від мене. :) Завжди приємно дізнаватися про нову мову.
Kevin Cruijssen


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.