9
\$\begingroup\$

Task

Your task is to convert a text into medieval orthography.

Details

  1. j is converted to i and J to I.
  2. u and U at the beginning of words are converted to v and V respectively.
  3. v and V at anywhere except the beginning of words are converted to u and U respectively.
  4. s is converted to ſ (U+017F) unless at the end of the word or preceded by another s.

Specs

  • A word is defined as a sequence of letters in abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.
  • All words will have at least two letters.
  • The input will only consist of printable ASCII characters (U+0020 - U+007E).
  • There will be no occurrences of more than two consecutive s. That is, sss will not be a substring of the input.

Testcases

Individual words:

Input       Output
------------------------
Joy         Ioy
joy         ioy
Universe    Vniuerſe
universe    vniuerſe
Success     Succeſs
successfull ſucceſsfull
Supervise   Superuiſe
supervise   ſuperuiſe
Super-vise  Super-viſe
I've        I've
majors      maiors
UNIVERSE    VNIUERSE
0universe   0vniuerſe
0verify     0verify
I0ve        I0ve
_UU_          _VU_
_VV_          _VU_
ss_         ſs_

Whole paragraph:

Input:  Christian Reader, I have for thy use collected this small Concordance, with no small labour. For being to comprise much in little roome, I was to make choyse of the most principall and usefull places, and to rank them under such words as I thought most essentiall and materiall in the sentence, because the scant roome allotted unto me, would not permit that I should expresse them under every word in the verse, as it is the manner in large Concordances.

Output: Chriſtian Reader, I haue for thy vſe collected this ſmall Concordance, with no ſmall labour. For being to compriſe much in little roome, I was to make choyſe of the moſt principall and vſefull places, and to rank them vnder ſuch words as I thought moſt eſsentiall and materiall in the ſentence, becauſe the ſcant roome allotted vnto me, would not permit that I ſhould expreſse them vnder euery word in the verſe, as it is the manner in large Concordances.

The SHA-256 hash of the output of the last testcase is:

5641899e7d55e6d1fc6e9aa4804f2710e883146bac0e757308afc58521621644

Disclaimer

Medievall orthographie is not that conſtante. Pleaſe do not complayne if you ſhall ſee olde bookes with a different orthographie.

\$\endgroup\$
12
  • 1
    \$\begingroup\$ "You are allowed to use f instead of ſ in the output." So there's basically no incentive to use ſ since it takes more bytes. \$\endgroup\$
    – Fatalize
    Commented Aug 6, 2016 at 8:13
  • 1
    \$\begingroup\$ @Fatalize Fair point. Removed that one. \$\endgroup\$
    – Leaky Nun
    Commented Aug 6, 2016 at 8:17
  • \$\begingroup\$ @LeakyNun Can we then count ſ as 1 byte? \$\endgroup\$
    – R. Kap
    Commented Aug 6, 2016 at 8:18
  • \$\begingroup\$ there is actually incentive in the form of ff being changed to fs in some algorithms if ſ was not used \$\endgroup\$ Commented Aug 6, 2016 at 8:20
  • 1
    \$\begingroup\$ Shouldn't Super-vise become Super-viſe? \$\endgroup\$
    – R. Kap
    Commented Aug 6, 2016 at 8:59

8 Answers 8

3
\$\begingroup\$

SED, 144 140 111 Bytes

saved 29 bytes thanks to NoOneIsHere

-r -e'y/j/i/g;y/J/I/g;s/ u/ v/g;s/ U/ V/g;s/^u/v/g;s/^U/V/g;s/([^s])s(\w)/\1ſ\2/g;s/(\w)v/\1u/g;s/(\w)V/\1U/g'
\$\endgroup\$
3
  • 1
    \$\begingroup\$ You brave, brave soul. \$\endgroup\$
    – Alexander
    Commented Aug 10, 2016 at 22:21
  • \$\begingroup\$ You can cut many bytes by using only 1 -e. Use ;s inbetween statements. \$\endgroup\$ Commented Aug 12, 2016 at 14:32
  • \$\begingroup\$ I didn't know you could do that. Thanks!! \$\endgroup\$
    – Riley
    Commented Aug 12, 2016 at 16:03
2
\$\begingroup\$

Python 3 (128 126 bytes)

import re;lambda k:re.sub("(?<!s)s(?=[a-zA-Z])",'ſ',re.sub("(?i)j|(?<![a-z])u|(?<=[a-z])v",lambda c:chr(ord(c.group())^3),k))

chr(ord(c.group())^3) feels excessive to xor a single-character string, but maybe a real Pythonista can suggest a golf. However, it's very convenient that ^3 suffices to interchange i <-> j and u <-> v.

NB The only thing here which requires Python 3 is the Unicode character: Python 2 complains Non-ASCII character '\xc5' <snip> but no encoding declared.

\$\endgroup\$
13
  • \$\begingroup\$ You shouldn't use \b since \b uses the definition of a word which includes digits and underscores. \$\endgroup\$
    – Leaky Nun
    Commented Aug 6, 2016 at 9:21
  • \$\begingroup\$ @LeakyNun, hmm. While I'm looking for a fix, could you please add some test cases? \$\endgroup\$ Commented Aug 6, 2016 at 9:24
  • \$\begingroup\$ @R.Kap. (?i). \$\endgroup\$ Commented Aug 6, 2016 at 9:45
  • \$\begingroup\$ @PeterTaylor Wait, what does that do? \$\endgroup\$
    – R. Kap
    Commented Aug 6, 2016 at 9:47
  • \$\begingroup\$ @R.Kap, it makes the regex case-insensitive. \$\endgroup\$ Commented Aug 6, 2016 at 9:48
2
\$\begingroup\$

Retina, 55 54 50 bytes

T`jJvV`iIuU
Ti01`uUp`vVp`[a-z]+
s(s*[a-zA-Z])
ſ$1

Try it online! (The first line enables a linefeed-separate test suite.)

\$\endgroup\$
1
\$\begingroup\$

Python 3.5, 124 116 111 118 125 144 142 bytes:

import re;lambda k:re.sub("J|j|(?<![a-zA-Z])[uU]|(?<=[a-zA-Z])[Vv]|(?<!s)s(?=[a-zA-Z])",lambda g:dict(zip('jJuUvVs','iIvVuUſ'))[g.group()],k)

Well, this seems like the perfect job for regular expressions!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can use J|j instead of [Jj] \$\endgroup\$
    – Leaky Nun
    Commented Aug 6, 2016 at 10:05
1
\$\begingroup\$

JavaScript (ES6), 154

Using parseInt to identify alphabetic characters. Note: casually but luckily parseInt('undefined',36)|0 is < 0

s=>[...s].map((c,i)=>((n=v(c))-19?n==31&p>9?'uU':n!=30|p>9?c=='s'&s[i-1]!=c&v(s[i+1])>9?'?':c+c:'vV':'iI')[p=n,c<'a'|0],p=0,v=c=>parseInt(c,36)|0).join``

Less golfed

s=>
  [...s].map(
  (c,i)=>
  ((n=v(c))-19
  ?n==31&p>9
    ?'uU'
    :n!=30|p>9
      ?c=='s'&s[i-1]!=c&v(s[i+1])>9
        ?'ſ'
        :c+c
      :'vV'
  :'iI')[p=n,c<'a'|0],
  p=0,
  v=c=>parseInt(c,36)|0
).join``

Test

F=
s=>[...s].map((c,i)=>((n=v(c))-19?n==31&p>9?'uU':n!=30|p>9?c=='s'&s[i-1]!=c&v(s[i+1])>9?'ſ':c+c:'vV':'iI')[p=n,c<'a'|0],p=0,v=c=>parseInt(c,36)|0).join``

out=(a,b,c)=>O.textContent+=a+'\n'+b+'\n'+c+'\n\n'

ti='Christian Reader, I have for thy use collected this small Concordance, with no small labour. For being to comprise much in little roome, I was to make choyse of the most principall and usefull places, and to rank them under such words as I thought most essentiall and materiall in the sentence, because the scant roome allotted unto me, would not permit that I should expresse them under every word in the verse, as it is the manner in large Concordances.'
to='Chriſtian Reader, I haue for thy vſe collected this ſmall Concordance, with no ſmall labour. For being to compriſe much in little roome, I was to make choyſe of the moſt principall and vſefull places, and to rank them vnder ſuch words as I thought moſt eſsentiall and materiall in the ſentence, becauſe the ſcant roome allotted vnto me, would not permit that I ſhould expreſse them vnder euery word in the verſe, as it is the manner in large Concordances.'
r=F(ti)
out(to==r?'OK':'KO',ti,r)

test=`Joy         Ioy
joy         ioy
Universe    Vniuerſe
universe    vniuerſe
Success     Succeſs
successfull ſucceſsfull
Supervise   Superuiſe
supervise   ſuperuiſe
Super-vise  Super-viſe
I've        I've
majors      maiors
UNIVERSE    VNIUERSE
0universe   0vniuerſe
0verify     0verify
I0ve        I0ve
_UU_          _VU_
_VV_          _VU_
ss_         ſs_`
.split('\n').map(t=>{
  var [i,o]=t.split(/\s+/),r=F(i)
  out(o==r?'OK':'KO',i,r)
})
#O {width:90%; overflow:auto; white-space: pre-wrap}
<pre id=O></pre>

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 111 bytes

s=>s.replace(/[a-z]+/gi,w=>w.replace(/j|J|^u|^U|\Bv|\BV|ss|s(?!$)/g,c=>"iIvVuUſ"["jJuUvVs".search(c)]||"ſs"))

Explanation: Because JavaScript regexp has no lookbehind, I instead break up the string into words, which then allows me to use ^ and \B as negative and positive letter lookbehinds. ss is dealt with by matching separately, with the slightly awkward replacement expression which takes fewer bytes than either replacing only the first character of c or adding an extra s to both strings and using the matching substring.

\$\endgroup\$
1
  • \$\begingroup\$ c=>"iIvVuUſ"["jJuUvVs".search(c)]||"ſs" is nice. 👍🏻 \$\endgroup\$
    – Jordan
    Commented Aug 6, 2016 at 18:47
0
\$\begingroup\$

CJam (89 88 bytes)

{32|_'`>\'{<*}:A;SqS++3ew{_1="jJuUvVs"#[-4_{_0=A!3*}_{_0=A3*}_{_)A\0='s=>268*}W]=~f^1=}%

Online demo

I never understood why CJam doesn't have regexes, but since it doesn't here's a solution which doesn't use them.

\$\endgroup\$
0
\$\begingroup\$

Ruby, 85 + 1 = 86 bytes

Run with ruby -p (+1 byte for p flag). Takes input on stdin.

gsub(/j|(?<=^|[^a-z])u|(?<=[a-z])v|(?<=^|[^s])s(?=[a-z])/i){$&.tr"jJsUuVv","iIfVvUu"}

Run the tests on ideone (wrapped in a lambda there because you can't give flags to ideone): http://ideone.com/AaZ8ya

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.