Перетворення конвенції конвенції


22

У цьому кодуванні Golf ви повинні перетворити одну умову кодування з TitleCase у нижню_виробничу_коротку. І навпаки!

Специфікація

Змініть кожух наступним чином:

  • Якщо символ підкреслення є роздільником, замініть кожух на Title Case без розмежувача.
  • Якщо є кілька слів без роздільника, змініть кожух на малі та додайте символ підкреслення як роздільник.
  • У випадку лише одного слова (або одного символу): замініть корпус на Title Case, якщо слово починається з малої літери; змінити корпус на нижній регістр, якщо слово починається з верхнього регістру.

Дозволені символи:

  • А до Я
  • від a до z
  • підкреслення ( _).

Введення із змішаними зворотними словами заборонено. Приклади заборонених випадків:

  • Coding_Convention_Conversion
  • a_BC

Приклади справ

Input                        | Expected Output
===========================================================
CodingConventionConversion   | coding_convention_conversion
coding_convention_conversion | CodingConventionConversion
abc                          | Abc
Abc                          | abc
ABC                          | a_b_c
a_b_c                        | ABC
a                            | A
A                            | a

Правила

  • Допускається використовувати ToUpper, ToLowerі ToTitleCaseфункції.
  • Використання регулярних виразів дозволено.
  • : найкоротший код у байтах виграє!

Чи ToTitleCaseдобре з функцією? Ви не вказали, тому я вважаю, що це нормально.
Джастін

@Justin: Справді, гарне питання. Давайте зробимо це веселішим і заборонимо функцію ToTitleCase :)
Даріуш Воняк

Дарн ... моє рішення покладається на це
Джастін

1
@Justin: Гаразд - на початку я цього не вказував, тож у такому випадку - давайте це все одно дозволимо.
Даріуш Воняк

Відповіді:


4

Pyth, 25 байт 29 33 35 40

Збережено 2 байти завдяки @Dennis

Збережено 4 байти завдяки @FryAmTheEggman

?rIz0smrd4cz\_tsXzrG1*\_G

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


Посилання потрібно оновити.
isaacg

Коли я намагаюся поставити "abc" як вхід, це дає "bc" як вихід. Помилка? :)
Даріуш Воняк

Щоб виправити те, що помітив @ DariuszWoźniak, ви можете змінити свій стан з /z\_на rIz0. Я також вважаю, що знайшов альтернативу додаткової підкреслювальної альтернативи: tsXzrG1_Mcj\_G2можливо, хтось може
пограти в

Ага, знайшли:tsXzrG1*\_G
FryAmTheEggman

8

Джолф, 35 байт

Заощаджує 1 байт завдяки @ Cᴏɴᴏʀ O'Bʀɪᴇɴ . Це закодовано в ISO 8859-7.

? hI'_ΜGI'_dpyH0pxRGIL0"(?=[A-Z])'_

Woohoo моя перша програма Jolf!

Пояснення

   // I = input
? hI'_                              // If input contains _
       GI'_                          // Split on _
      Μ    d                         // Loop, then join
            pyH0                     // Make the first character uppercase
                                    // ELSE...
                  RGIL0"(?=[A-Z])    // Split *after* all uppercase chars
                                 '_  // join with _ 
                px                   //Make lowercase

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


Ви можете використовувати розділення рядків в кінці, так це стає "(?=[A-Z])'_. Рядок закривається автоматично.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ о, здорово, спасибі!
Пуховик

7

Сітківка , 37

Дякуємо @ MartinBüttner за збереження 4 байтів!

^|[A-Z]
_$0
T`Ll`lL`_.
^_|_(?=[A-Z])

(Зверніть увагу на останній рядок.)

Спробуйте в Інтернеті. Зауважте, що це включає додаткове m`налаштування пари рядків для обробки кожного рядка входу окремо, щоб усі тестові корпуси могли працювати за один раз. Це не є вимогою запитання, тому вони не враховуються у балах.

  • Рядки 1 і 2 вставляють _або на початку введення, або перед великими літерами. Усі слова тепер _розділені, незалежно від випадку.
  • Рядок 3 замінює регістр першої літери в кожному слові.
  • Рядки 4 та 5 видаляються _або на початку введення, або після них з великої літери.

Це економить чотири байти: retina.tryitonline.net/…
Мартін Ендер

Також ви можете уникнути останнього порожнього рядка, опустивши останній ?=і замінивши цей етап на $1(хоча це не впливає на кількість байтів).
Мартін Ендер

@Martin Дуже добре - дякую!
Цифрова травма

5

GNU Sed, 46

Дякуємо @TobySpeight за збереження 2 байтів!

Оцінка включає +1 для -E(або -r) варіант до sed.

s/(^|_)([a-z])/\u\2/g
t
s/[A-Z]/_\l&/g
s/^_//

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

Досить прямо:

  • Рядок 1 заміщає початок рядка або _, за ним малу літеру з верхнього регістру цієї літери. gПрапор sвиконує цю заміну для кожного екземпляра знайдені
  • t стрибає на : неназваної етикетки, якщо були відповідні вищезазначені заміни. Ця мітка неявно в кінці.
  • Інакше всі великі літери замінені на _ нижчим регістром цієї літери
  • Це залишає ведучого _перед першою літерою. s/^_//видаляє це.

1
@Тобі спасибі -Eпрацює в моєму GNU sed 4.2.2 (Ubuntu 14.04.3), хоча його немає на сторінці man. Я десь прочитав [потрібне цитування], що -Eце новіший варіант Posix, який офіційно буде доданий до GNU Sed у новій версії, але вже є неофіційно. Незважаючи на те, -rчи правильно -Eробити, якщо не працює для вас.
Цифрова травма

@Тобі лінії 280-282 від sed / sed.c є /* Undocumented, for compatibility with BSD sed. */ case 'E': case 'r':.
Цифрова травма

@Digital - я помилився; мій СЕД дійсно приймає в -Eякості синоніма -r. Я неправильно пройшов мінімальну програму, наприкладsed -E -e Q
Toby Speight,

4

JavaScript (ES6), 87 байт

s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())

Пояснення

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

s.replace(
  /[A-Z]|(^|_)(.)/g,
  (c,_,l,i)=>
    l?
      (i?"_":"")+c.toLowerCase()
    :l.toUpperCase()
)

Тест

var solution = s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())
<input type="text" id="input" value="coding_convention_conversion" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>


2

Рубі, 101 87 75 байт

->s{s.gsub(/^.|[A-Z]/,'_\0').gsub(/_./,&:swapcase).gsub(/_(?=[A-Z])|^_/,'')}

На жаль, це робить саме те саме, що і рішення Retina, оскільки цей метод виявився коротшим за все, що я придумав.


2

Python 3, 130 байт

Швидка та брудна спроба за допомогою регексу розколотись на кришках. Досить груба сила: якщо хтось може придумати інший підхід, я впевнений, що це можна побити.

import re
lambda s:('_'.join(re.findall('[A-Z][a-z]*',s)).lower(),''.join([a[0].upper()+a[1:]for a in s.split('_')]))[s.islower()]

2

PHP 160 байт

не найкоротший, але для повноти тут моє рішення в PHP, $ s тримає рядок для перетворення:

trim(preg_replace_callback('/((^[a-z]|_[a-z])|([A-Z]))/',function($m){return empty($m[2])?'_'.strtolower($m[3]):strtoupper(str_replace('_','',$m[2]));},$s),'_')

1
Ласкаво просимо до головоломки програмування та обміну стека коду для гольфу. Молодці для того, щоб розмістити щось на тій мові, яку ви знали, що не виграєте. Проблеми з кодовим гольфом здебільшого знаходяться в межах мов, тому корисно використовувати мову, яка не використовується для гольфу. +1 d: -D
wizzwizz4

1

Perl 6 ,  73 72 71   68 байт

{.comb(/<:Lu><:Ll>*|<:Ll>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x?/<:Lu>/)} # 73
{.comb(/<:Lu><:Ll>*|<:L>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x?/<:Lu>/)}  # 72
{/<:Lu>/??S:g/(^)?(<:Lu>)/{$0||'_'}$1.lc()/!!S:g/[^|_](<:Ll>)/$0.tc()/}   # 71
{.comb(/<:Lu><:Ll>*|<:L>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x!/_/)}      # 68

Використання:

# give it a lexical name
my &code = {...}

for <CodingConventionConversion coding_convention_conversion abc Abc ABC a_b_c a A>
{ say .&code }
coding_convention_conversion
CodingConventionConversion
Abc
abc
a_b_c
ABC
A
a

Пояснення:

{
  .comb( / <:Lu><:Ll>* | <:L>+ / ) # grab the "words" only
  .map({
      /<:Lu>/ # if the word has uppercase
    ??
      .lc     # lowercase the whole word
    !!
      .tc     # otherwise titlecase the word
   })
  .join(  # join the words
    '_'   # with '_'
    x     # repeated
    !/_/  # zero times if it had a _, otherwise once
  )
}

Вам може бути цікаво, чому я використовував властивості Unicode ( <:Lu>, <:Ll>) замість просто класу символів. У Perl 6 вони більше не написані, [a-z]вони написані, <[a..z]>що в 1,6 рази більше. Дужки [ … ]використовуються для групування, що не фіксує, замість цього було написано, як (?: … )у Perl 5.


1

Japt, 40 байт

UfV="%A" ?UrV@'_s!Y +Xv} :Ur"^.|_."_sJ u

Перевірте це в Інтернеті!

Як це працює

           // Implicit: U = input string
UfV="%A"   // Set variable V to the string "\\A", and get all matches in U.
?          // If the list is not null:
UrV@     } //  Replace each match X and its index Y with this function:
'_s!Y +Xv  //   Return "_".slice(!Y) (1 for Y=0, 0 for anything else) + X.toLowerCase().
:          // Otherwise:
Ur"^.|_."  //  Replace the char at the beginning and each char following an underscore with:
_sJ u      //   The last char of the match (the letter) .toUpperCase().

1

Perl 5, 42 байти

40 байт плюс 2 за -p(спасибі, dev-null )

s/[A-Z]/_\l$&/g||s/(^|_)(.)/\u$2/g;s/_//

У Windows, використовуючи perl та MINGW32, я не отримую виводу, що мені не вистачає?
ChatterOne

@ChatterOne Я не знаю, що таке MINGW32, але це добре працювало для мене на полуничному Perl. Використовуйте -Eзамість -e.
msh210

1

𝔼𝕊𝕄𝕚𝕟 3, 15 символів / 32 байти (неконкурентоспроможний)

⟮ѨDZï⟯≠ï?Ⅰ:ѨȎѨƎï

Try it here (Firefox only).

v3 було випущено після цього виклику, з купою помилок та оновлень бібліотеки.

Пояснення

Це просто машу з вбудованих.

⟮ѨDZï⟯≠ï?Ⅰ:ѨȎѨƎï // implicit: ï=input
⟮ѨDZï⟯≠ï?        // check if ï is NOT in snake_case
       Ⅰ       // if so, then convert to snake_case
        :ѨȎѨƎï // otherwise, convert to camelCase and make the first letter UPPERCASE


1

Python 3 , 86 байт

lambda s,u='_':''.join([u[i>u:]+i.lower()for i in(s<u)*s]or[u]+s.title().split(u))[1:]

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

Також працює в Python 2 .

Скориставшись зручним фактом, що значення ascii для _(95) знаходиться між великими літерами (65-90) та малими літерами (97-122), що дозволяє легко порівняти рядки.


1

Четвертий (gforth) , 129 байт

: f bounds dup c@ 32 xor emit 1+ ?do i c@ '_ < if ." _"i c@ 32 + emit then i c@ '_ > if i 1- c@ '_ = 32 * i c@ + emit then loop ;

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

Пояснення коду

: f              \ start a new word definition
  bounds         \ convert string address and length to beginning and ending address
  dup c@         \ get the first character
  32 xor emit    \ convert to the opposite case and output
  1+             \ add 1 to beginning of string (skip starting char)
  ?do            \ begin counted loop over string character addresses
    i c@ '_ <    \ check if char is uppercase 
    if           \ if it is:
      ." _"      \ output underscore
      i c@       \ get current char
      32 + emit  \ convert to lowercase and output
    then         \ end if block
    i c@ '_ >    \ check if lowercase (not '_')
    if           \ if it is:
      i 1- c@    \ get the previous character
      '_ = 32 *  \ if it's an underscore, multiply by 32 (true = -1 in forth)
      i c@ +     \ add result to current char (make uppercase if previous was '_')
      emit       \ output resulting char
    then         \ end if block
  loop           \ end loop
;                \ end word definition
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.