Сквош-нечіткі лігатури


17

Ось перелік деяких поширених лігатур у Unicode (тих, які я міг би створити за допомогою мого клавіша Compose на Debian):

Orig  Ascii  Lig
ae    [ae]   æ
AE    [AE]   Æ
oe    [oe]   œ
OE    [OE]   Œ
ij    [ij]   ij
IJ    [IJ]   IJ
ff    [ff]   ff
fi    [fi]   fi
fl    [fl]   fl
ffi   [ffi]  ffi
ffl   [ffl]  ffl

У цьому виклику у вас є два варіанти: використовувати фактичні лігатури UTF-8 або використовувати варіант лише для ASCII. Якщо ви використовуєте фактичні варіанти лігатури UTF-8, ви отримуєте 20% бонус. Якщо ви використовуєте варіант, призначений лише для ASCII, ви можете припустити, що квадратні дужки ніколи не будуть задіяні, крім позначення лігатури.

Завдання: заданий рядок як вхідний, вивести той самий рядок

  • з усіма оригінальними лігатурами, заміненими їх розширеними аналогами.

    • жадібно відповідати: affibстає affib( a[ffi]b), не affib( a[ff]ib) чи affib( af[fi]b).
  • з усіма "розширеними" літерами послідовності замінені лігатурами.

    • наприклад, æOEfoo( [ae]OEfoo) стає aeŒfoo( ae[OE]foo).

Зробіть це повністю самостійно: ffi( [ff]i) стає ffi( ffi), а не ( [ffi]).

Звучить досить просто? Є улов: щоразу, коли дві нелігатури перетинаються рівно одним символом , обидві лігатури повинні бути вставлені в рядок. Ось кілька тестових випадків для демонстрації:

Input   Ascii-output      Output
fij     [fi][ij]          fiij
fIJ     f[IJ]             fIJ     * remember, capitalization matters!
fffi    [ff][ffi]         ffffi
fff     [ff][ff]          ffff
ffffi   [ff][ff][ffi]     ffffffi
ffffij  [ff][ff][ffi][ij] ffffffiij

Будьте уважні: застосовується така ж жадібна відповідність (особливо зверніть увагу на останні кілька тестових випадків).

, тому виграє найкоротший код у байтах.


7
@Mego У чому полягає велика справа? Якщо ваша обрана мова не може впорядковувати æ оригінально, просто надрукуйте 0xc3 0xa6, її кодування UTF-8.
Денніс

7
Якщо мова не може полегшити задану задачу, не використовуйте цю мову для цього завдання. Це не повинно бути великою справою.
Олексій А.

Відповіді:


3

JavaScript (ES6), 213 байт - 20% бонус = 170,4

s=>eval('for(p=o="";m=s.match(r="ffl|ffi|fl|fi|ff|IJ|ij|Œ|œ|Æ|æ|ffl|ffi|fl|fi|ff|IJ|ij|OE|oe|AE|ae",x=r.split`|`);s=s.slice(i+t.length-(p=t<"z")))o+=s.slice(p,i=m.index)+x[(x.indexOf(t=m[0])+11)%22];o+s.slice(p)')

Пояснення

s=>                           // s = input string
  eval(`                      // use eval to avoid writing {} or return
    for(                      // iterate over each ligature match
      p=                      // p = 1 if the last match was a non-unicode ligature
        o="";                 // o = output string
      m=s.match(              // find the next ligature

        // r = regex string for ligatures (unicode and non-unicode)
        r="ffl|ffi|fl|fi|ff|IJ|ij|Œ|œ|Æ|æ|ffl|ffi|fl|fi|ff|IJ|ij|OE|oe|AE|ae",
        x=r.split\`|\`        // x = arrray of r

      );
      s=s.slice(i+t.length    // remove the part that has been added to the output
        -(p=t<"z"))           // if we matched a non-unicode ligature, keep the last
    )                         //     character so it can be part of the next match
      o+=s.slice(p,i=m.index) // add the text before the match to the output
        +x[(x.indexOf(        // add the opposite type of the matched ligature
          t=m[0]              // t = matched text
        )+11)%22];            // (index + 11) % 22 returns the opposite index
    o+s.slice(p)              // return o + any remaining characters
  `)

Тест


Можна r="ffl|ffi|fl|fi|ff|IJ|ij|Œ|œ|Æ|æ|ffl|ffi|fl|fi|ff|IJ|ij|OE|oe|AE|ae",x=r.split`|`переписати як x="ffl|ffi|fl|fi|ff|IJ|ij|Œ|œ|Æ|æ|ffl|ffi|fl|fi|ff|IJ|ij|OE|oe|AE|ae".split`|`для -4 байт?
Дендробіум

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