Застосовуйте англійські пунктуаційні правила


11

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

Керівництво насправді не довіряє вам всією силою в проекті - вам відомо, що ви цілий день сидите навколо та гольф-код, замість того, щоб робити свою роботу, на жаль, - тому вони просто дають вам справді просте завдання для виконання: поверніть Речення з вписаними розділовими знаками в правильно відформатоване речення, де "правильне відформатування" визначено нижче.

  1. Речення - це рядок введення. Слово - це група непересічних символів, що не є космосом. Пунктуація - це слово, першим символом якого є ^.

  2. Слово пишеться з великої літери, якщо перша літера слова не є малою літерою (великі слова відповідають рівню /[^a-z].*/).

  3. Перше слово Речення має бути з великої літери.

  4. A ^COMMAє символом кома ,і має пробіл, що слідує, але не передує. aaa ^COMMA bbbстає aaa, bbb.

  5. A ^COLON- це кома, яка виглядає так :.

  6. A ^SEMICOLON- це кома, яка виглядає так ;.

  7. A ^PERIOD- це кома, яка виглядає так .. Слово, що йде за a, ^PERIODмає бути з великої літери.

  8. А ^BANG- це період, який виглядає так !.

  9. A ^DASH- тире -і має пробіл як перед, так і після нього.

  10. А ^HYPHENтакож є тире символом, -але не має місця після або перед ним.

  11. Ан ^EMDASH- це дефіс (не тире!), Що написано --.

  12. ^OPENQUOTEЦитата персонаж , "який має місце попереднє , але не такий. Слово, що йде за ^OPENQUOTEобов’язковим колом, має бути з великої літери. Якщо ^OPENQUOTEпередує слову, яке не є пунктуаційним знаком, додайте ^COMMAміж цим словом і знаком ^OPENQUOTE. Якщо ^OPENQUOTEпередує пунктуація, що робить наступне слово з великої літери, це переходить ^OPENQUOTEдо наступного слова.

  13. A ^CLOSEQUOTE- це диграф, ,"який має пробіл, що слідує, але не передує. Якщо ^CLOSEQUOTEпередує ^COMMA, ^PERIODабо ^BANG, що пунктуації зникає і ^CLOSEQUOTEпишеться ,", ."або !"відповідно. Якщо пунктуація, що зникає, вказала велику літери, ця величина все одно має відбуватися у наступному доступному слові.

  14. Початкові або кінцеві пробіли в повному кінцевому результаті повинні бути видалені, і будь-який рядок з двох або більше пробілів підряд повинен бути зведений в один пробільний символ.

  15. Будь-який випадок не поширюється вище (наприклад , ^COMMA ^COMMAчи , ^SEMICOLON ^CLOSEQUOTEабо ^UNDEFINEDPUNCTUATION) не виникатимуть в добре сформовану вхід і, таким чином , поведінка не визначено.

Команда розробників повідомляє про наступне:

  • Проект написаний мовою [ваша мова тут] і повинен бути якомога коротшим, щоб він займав якомога менше місця, коли це додаток для Android / iPhone. Ви намагаєтесь пояснити, що розробка додатків працює не так, але вони не слухають. Але ей, який збіг! Ти дивовижний гольфіст [тут твоєї мови] !

  • У додатку не буде жодних дозволів доступу до Інтернету, і не буде встановлено бібліотек, які роблять це форматування для вас. Ви, напевно, можете переконати команду керівника дозволити вам створити бібліотеку регулярних виразів, якщо така існує для вашої мови, хоча ви вважаєте, що вона потрібна.

  • Підтримка вкладених пропозицій, які належним чином використовують подвійні / одинарні лапки, планується для більш пізньої версії програми, але не для версії, над якою ви зараз працюєте, тому не хвилюйтеся про це.

  • Керівництво є величезним шанувальником тестових розробок, і тому команді розробників вже була якась невдала мавпа з клавіатури, яка написала кілька тестів для вашої частини програми: (додаються нові рядки для читабельності, трактуйте їх як пробіли)

    Вхід:

    hello ^COMMA   world ^BANG
    

    Вихід:

    Hello, world!
    

    Вхід:

    once upon a time ^COMMA there was a horse ^PERIOD that horse cost me $50
    ^PERIOD ^OPENQUOTE eat your stupid oats ^COMMA already ^BANG ^CLOSEQUOTE
    I told the horse ^PERIOD the horse neighed back ^OPENQUOTE no ^CLOSEQUOTE
    and died ^PERIOD THE END
    

    Вихід:

    Once upon a time, there was a horse. That horse cost me $50. "Eat your
    stupid oats, already!" I told the horse. The horse neighed back, "No,"
    and died. THE END
    

    Вхід:

    begin a ^PERIOD b ^COMMA c ^COLON d ^SEMICOLON e ^BANG f ^HYPHEN g ^DASH h
    ^EMDASH i ^OPENQUOTE j ^PERIOD ^OPENQUOTE k ^SEMICOLON ^OPENQUOTE l
    ^CLOSEQUOTE m ^BANG ^CLOSEQUOTE n ^PERIOD 0x6C6F6C end
    

    Вихід:

    Begin a. B, c: d; e! F-g - h--i, "j. "K; "l," m!" N. 0x6C6F6C end
    

Це кодовий гольф: виграє найнижчий бал. Ви можете записати функцію одного аргументу рядка або зчитувати програму з STDIN і записати в STDOUT.


Що робити, якщо я хочу використовувати javascript? Стандартного вводу в ньому немає. Чи можу я використовувати prompt()?
nicael

@nicael OP згадує, використовуючи один аргумент рядка, тому для мого прикладу JS я просто зробив функцію, яка бере один аргумент, і припустив, що аргумент - це рядок слів, схожий на STDIN
Eric Lagergren

1
Цікаво, чи є esolang з назвою "[ваша мова тут]"
Akangka

Відповіді:


4

JavaScript: 653 611 547 514 487 байт

О Боже. Брендан Ейч Мені так шкода за це.

PS: Я додав пробіл для читабельності, але позбавлення всього допустимого пробілу призводить до переліченого числа байтів.

Теоретично я міг би скоротити деякі частини, наприклад, -e-щось на кшталт -eабо -e, але це може спричинити проблему, якщо попереднє слово закінчується словом, або наступне слово починається з букви «е» (або те, яке слово я вирішив використовувати). Я думаю, я міг би використовувати символ ASCII. Я розберуся в цьому.

487 FF22 + Тільки

R = "replace", C = "charAt", U = "toUpperCase";
alert(a[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s)|(\-\e\-\s))/g, ((k, l, v, n, o, p, q, r, s) => v ? "." : n ? "!" : o ? "," : p ? ";" : q ? ":" : r ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s|$)/g, (t => t[C](0)[U]() + t.substr(1)))[R](/\"[a-z]/g, (u => u[C](0) + u[C](1)[U]())))

514 FF22 + Тільки

alert(function(z) {
    R = "replace", C = "charAt", U = "toUpperCase";
    return z[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s+((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s+)|(\-\e\-\s+))/g, ((k, l, v, n, o, p, q, r, s) => v ? "." : n ? "!" : o ? "," : p ? ";" : q ? ":" : r ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s+|$)/g, (t => t[C](0)[U]() + t.substr(1)))[R](/\"[a-z]/g, (u => u[C](0) + u[C](1)[U]()))
}(a))

547 FF22 + Тільки

alert(function(z) {
    R = "replace", C = "charAt", U = "toUpperCase";
    return z[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s+((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s+)|(\-\e\-\s+))/g, ((xx, __, k, l, m, n, o, p, q) => k ? "." : l ? "!" : m ? "," : n ? ";" : o ? ":" : p ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s+|$)/g, function(r) {
        return r[C](0)[U]() + r.substr(1)
    })[R](/\"[a-z]/g, function(s) {
        return s[C](0) + s[C](1)[U]()
    })
}(a))

Тільки 611 FF 22+

alert(function(c) {
    return c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((x, _, a, b, c, d, e, f, g, h, i) = > a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" ')).replace(/\s+\./g, ".").replace(/\s+\!/g, "!").replace(/\s+\,/g, ",").replace(/\s+\;/g, ";").replace(/\s+\:/g, ":").replace(/\s\-\h\-\s/g, "-").replace(/[^!,"'.]\"\s/g, '"').replace(/\s+\-\e-\s+/g, "--").replace(/.+?[\.\?\!](\s+|$)/g, function(b) {
        return b.charAt(0).toUpperCase() + b.substr(1)
    }).replace(/\"[a-z]/g, function(b) {
        return b.charAt(0) + b.charAt(1).toUpperCase()
    })
}(a))

653 крос-браузер

alert(function(c) {
    return c.replace(/\^COMMA/g, ",").replace(/\^SEMICOLON/g, ";").replace(/\^COLON/g, ":").replace(/\^PERIOD/g, ".").replace(/\^BANG/g, "!").replace(/\^DASH/g, "-").replace(/\^HYPHEN/g, "h-h").replace(/\^EMDASH/g, "-e-").replace(/\^OPENQUOTE/g, ' "').replace(/\^CLOSEQUOTE/g, '" ').replace(/\s+\./g, ".").replace(/\s+\!/g, "!").replace(/\s+\,/g, ",").replace(/\s+\;/g, ";").replace(/\s+\:/g, ":").replace(/\s\h\-\h\s/g, "-").replace(/[^!,"'.]\"\s/g, '"').replace(/\s+\-\e-\s+/g, "--").replace(/.+?[\.\?\!](\s|$)/g, function(b) {
        return b.charAt(0).toUpperCase() + b.substr(1)
    }).replace(/\"[a-z]/g, function(b) {
        return b.charAt(0) + b.charAt(1).toUpperCase()
    })
}(a))

Як це працює:

https://gist.github.com/ericlagergren/1a61b5d772ae49ab3aea

JSFiddle (для 653-байтного крос-браузерного рішення)

JSFiddle (для 595 FF 22+ тільки розчин)

JSFiddle (для 547 FF 22+ тільки розчин)

JSFiddle (для 514 FF 22+ тільки розчин)

JSFiddle (для 487 FF 22+ тільки розчин)

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

Я продовжу голити байти, наскільки зможу.


Ви можете скоротити свої перші заміни так: c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG))/g,(m,_,a,b,c,d,e)=>a?',':b?';':c?':':d?'.':'!'))... і так далі. Синтаксис стрілки короткий, але навіть "функція" повинна зберегти ті ж характеристики
edc65

Ти маєш рацію. Я протестував свій регекс з Chrome, і він не підтримує жирові стрілки. Я зараз працюю над тим, щоб виправити це з FF зараз, але я ненавиджу, як у regexps насправді немає оператора "та", як вони роблять "чи". @ edc65
Ерік

@ edc65, тому я думаю, що мені доведеться використовувати два =>s, щоб змусити його працювати, але за допомогою стрілок врятували мене 40 байт!
Ерік Лагергрен

Замініть заміну на R = 'заміна' ... [R] ;-)
edc65

Щойно це зробив :) Опустив це на 563 @ edc65
Ерік

1

PHP, 412 байт

(Тут ясність для нечіткості; див. Ідеон для версії для гольфу .)

Функція preg_replace () PHP прийме аргументи масиву, що тут дуже корисно. Я думаю, що наступний код робить все необхідне. Він проходить хоча б усі тестові справи.

function x($s) {
    $r='preg_replace';
    $s=$r('/ +/',' ',$s);
    $s=$r(array('/ \^COMMA/','/ \^COLON/','/ \^SEMICOLON/','/ \^PERIOD/','/ \^BANG/',
                '/\^DASH/','/ \^HYPHEN /','/ \^EMDASH /','/\^OPENQUOTE /','/ \^CLOSEQUOTE/'),
          array(',',':',';','.','!','-','-','--','"',',"'),
          $s);
    $s=$r('/(^\W*\w|([\.!]| ")\W+\w)/e','strtoupper("$0")',$s);
    $s=$r('/([,\.!]),/','\1',$s);
    $s=$r('/(\w)( "\w)/e','"$1,".strtoupper("$2")',$s);
    echo $s;
}

Працює чудово! ideone.com/AYtTiI Хоча те, що мене бентежить, це чи повинні у нас коми після відкритих цитат? Тому що, граматично кажучи, лапки - це більше, ніж мова, проте перед цитатами має лише кома. Я припустив, що з'явився ^ COMMA, який ми дозволимо користувачеві вводити кому
Ерік Лагергрен,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.