text:
Golf my Shakespeare quote references
While writing my essay for Shakespeare, I realized that I needed to shorten my quote references to more manageable lengths. I had previously been writing this:
(Act 1, Scene 2, Lines 345-346)

But I've now been told to write them like this:
(I.ii.345-6)

Clearly, I need some golfed code to golf my Shakespeare quote references down a bit.
The Task
Write a program or function that, given a string input following Template 1 or 2, print or return a string following Template 3 or 4, respectively. You only have to support Acts 1 through 5 and Scenes 1 through 9.
Templates
Template 1
(Act x, Scene y, Lines a-b)

You may assume that x never exceeds 5, y never exceeds 9, a and b are always positive integers not exceeding your language's maximum positive standard integer value, and a is always exclusively less than b.
Template 2
(Act x, Scene y, Line a)

Same conditions as Template 1, excluding information about b.
Template 3
(x.y.a-b)

Where x is a capital roman numeral, y is a lowercase roman numeral, a and b are numbers, and b is shortened to only the digits less than the first differing digit of equal significance from a.
Template 4
(x.y.a)

Same conditions as Template 3, excluding information about b.
Test Cases
Let f(s) be the function defined in the Task. "" denotes a string value.
>>> f("(Act 1, Scene 2, Lines 345-346)")
"(I.ii.345-6)"

>>> f("(Act 3, Scene 4, Lines 34-349)")
"(III.iv.34-349)"

>>> f("(Act 5, Scene 9, Lines 123-234)")
"(V.ix.123-234)"

>>> f("(Act 3, Scene 4, Line 72)")
"(III.iv.72)"

>>> f("(Act 2, Scene 3, Lines 123-133)")
"(II.iii.123-33)"

>>> f("(Act 4, Scene 8, Lines 124-133)")
"(IV.viii.124-33)"

For the purposes of this challenge, the following arabic to roman numeral translations must be supported:
1 i     I
2 ii    II
3 iii   III
4 iv    IV
5 v     V
6 vi    (you do not have to support past 5)
7 vii
8 viii
9 ix

Are text files allowed?

@Dat In what sense? Input, output, both?

Text file as an input.

@Dat Absolutely fine. If you need a text file output, that's fine, too. Found it in the defaults for I/O.

And do bytes from text file count?

Second test case is wrong. It should be  "(V.ix.123-234)"

@Dat Not if they're just your input. If they're more than just your input, no.

@Luke Typo. Thanks. :D

I'm really hoping for an answer in SPL.

Test case: (Act 1, Scene 2, Lines 345-3499)

@dzaima Ooh. Good point, magnitude check.

Who´s up for an answer in Shakespeare?

@Titus Are you nominating yourself?

The last two test cases do not match any of the templates. They should use Lines instead of Line.

“b is shortened to only the digits less than the first differing digit from a”: I interpret this as meaning that 34-349 should be shortened to 34-9 (9 being the first differing digit), but the test case contradicts that. A clarification would be great.

@Grimy Fixed #1, is #2 good?

Yep, they’re both good, now. Great question, btw!

Somebody likes Shakespeare.

The Shakespeare Programming Language (non-competing)
I really liked this question, and as there was some interest in a Shakespeare-language answer, here is one.
A Tale of Two Cites (sic).

Julius Caesar, the first citizen of the Roman Republic.
Brutus, a traitor -- member of the Fifth Column.
Cicero, the greatest Roman orator.
Cleopatra, a proud queen, whom the Romans want to make one of their own.
Romeo, a man who's sometimes there.
Juliet, a maiden who can follow Romeo or stand on her own.

           Act I: Imperium Romanum.

           Scene I: Cleopatra puts men in their place.

[Enter Cleopatra and Julius Caesar]

Julius Caesar:
    Thou art as lovely as the sum of an amazing delicious gentle blossoming warm angel and a charming noble reddest rose.
    Speak your mind. Open your mind. Open your mind. Open your mind! Open your mind!

Cleopatra:
    You are as stuffed as the sum of a hard old green horse and the sum of a grandmother and
    a normal tiny bottomless furry small purple roman.

[Exit Julius Caesar]
[Enter Brutus]

Cleopatra:
    You are as sorry as the difference between a rich morning and a leech.
    You are as smelly as the difference between yourself and a sunny rural blue bold uncle.
    You are as vile as the difference between Julius Caesar and yourself.

[Exit Brutus]
[Enter Cicero]

Cleopatra:
    You are as half-witted as the difference between Brutus and the bluest death.

           Scene II: How do you solve a problem like Cleopatra?

[Exeunt]
[Enter Cleopatra and Julius Caesar]

Julius Caesar:
    Listen to your heart!

[Exit Cleopatra]
[Enter Brutus]

Julius Caesar:
    Is Cleopatra more pretty than a fair charming noble angel?

Brutus:
    If so, we must proceed to Scene IV. Is Cleopatra not worse than the sweetest small aunt?

Julius Caesar:
    If so, let us proceed to Scene III.

Brutus:
    Speak your mind.

Julius Caesar:
    Is Cleopatra nicer than the moon?

Brutus:
    If so, speak your mind.

Julius Caesar:
    Is Cleopatra better than a golden King?

Brutus:
    If so, speak your mind.

Julius Caesar:
    We shall proceed to Scene V.

          Scene III: Brutus and his friends.
Julius Caesar:
    Is Cleopatra as fair as the blossoming smooth sky?

Brutus:
    If so, speak your mind!

Julius Caesar:
    Speak your mind!

Julius Caesar:
    Is Cleopatra jollier than the sum of a yellow sweet road and a summer's day?

Brutus:
    If so, speak your mind!

Julius Caesar:
    Is Cleopatra friendlier than the sum of a sweet large angel and a white cow?

Brutus:
    If so, speak your mind!

Julius Caesar:
    Is Cleopatra as furry as a rich handsome huge mistletoe?

Brutus:
    If so, speak your mind!

Julius Caesar:
    We shall proceed to Scene V.

          Scene IV: Cicero is asked to speak.
[Exit Brutus]
[Enter Cicero]

Julius Caesar:
    Is Cleopatra as beautiful as the sum of a small furry white angel and a summer's day?

Cicero:
    If so, speak your mind!

Julius Caesar:
    Speak YOUR mind!

          Scene V: A period piece -- Cleopatra's reprisal.
[Exeunt]
[Enter Cleopatra and Julius Caesar]

Julius Caesar:
    You are as beautiful as the sum of a embroidered sweetest sunny delicious trustworthy Lord
    and a reddest charming mighty honest King.
    You are as healthy as the difference between yourself and a embroidered Lord. Speak your mind!
    Open your mind! Open your mind! Open your mind! Open your mind! Open your mind! Open your mind!

Cleopatra:
    Are you jollier than the sum of a little rural white bottomless blue blue sky and a rural furry white green old morning?

Julius Caesar:
    If so, we must proceed to Act II. Open your mind! Open your mind!

Cleopatra:
    You are as damned as the difference between yourself and a half-witted dusty snotty rotten oozing death.

[Exit Julius Caesar]
[Enter Brutus]

Cleopatra:
    You are as rotten as the difference between yourself and a rural rotten bottomless evil miserable famine.

[Exit Brutus]
[Enter Cicero]

Cleopatra:
    You are as fatherless as the difference between Brutus and a normal pig. Let us return to Scene II.

          Act II: Lovers' arithmetick.

          Scene I: Our lovers discuss what they have in common.

[Exeunt]
[Enter Romeo and Juliet]

Romeo:
    Thou art as bold as a curse. Listen to your heart!

Juliet:
    Am I better than nothing? If so, let us proceed to Scene III.

Romeo:
    Open your mind. Open your mind.

Juliet:
    Listen to your heart! Open your heart!

Romeo:
    Thou art as amazing as the product of the difference between a handsome white proud white grandfather and an aunt
    and the sum of a loving niece and the Heaven. Speak your mind! Open your mind.
    Listen to your heart. Is the quotient between yourself and the sum of the sum of
    a noble noble mighty blossoming embroidered good father
    and a gentle large large normal old joy and an old happy squirrel as yellow as the quotient between
    myself and the sum of the sum of a pretty beautiful yellow green bold charming kingdom and
    a beautiful blue normal cute large nephew and a pretty big cousin?

Juliet:
    If not, we shall proceed to Scene II.

Romeo:
    You are as sweet as the remainder of the quotient between yourself and the sum of the sum of
    a blossoming bottomless golden peaceful noble healthy nose and
    a happy honest sunny green healthy hero and a hard blue fellow.

Juliet:
    YOU are as sweet as the remainder of the quotient between yourself and the sum of the sum of
    a blossoming bottomless golden peaceful noble healthy nose and
    a happy honest sunny green healthy hero and a hard blue fellow.

          Scene II: Tense times.
Juliet:
    Is the quotient between yourself and the sum of a good beautiful delicious grandmother
    and a noble wind as amazing as the quotient between myself and the sum of
    a smooth furry embroidered roman and a honest sister?

Romeo:
    If so, you are as amazing as the remainder of the quotient between
    yourself and the sum of a cute healthy smooth kingdom and a normal mother.

          Scene III: Parting is such sweet sorrow.
Romeo:
    Open your heart! You are as noble as the sum of a honest charming smooth peaceful fine rose and the sum of
    a cute amazing trustworthy summer's day and an angel. Speak your mind!

(It's over 6000 bytes long.) There are some tricks in there but I have not tried to golf it much, because: (1) I already contributed my share of golfing on another answer, and (2) changing all characters to "Page" and "Puck", or all phrases to "big big big big big cat", seems to spoil the fun. Instead for the part that deals with Roman numerals I have used characters who are Romans, etc. I did reuse characters and instructions to save some typing. :-)
The program should be mostly straightforward but one wrinkle worth mentioning is that when I wrote this I assumed that reading an integer would work like scanf: (1) consume only as many characters from the input as corresponds to an integer, and (2) in case of failure, leave the variable unchanged. (I used this second property to distinguish between Template 1 and 2 in Act II, by reading up to "Line" and attempting to read an integer.) Unfortunately it turns out that there's (what I consider) a bug in the original implementation of the language where reading an integer consumes everything up to the end of the line and throws an error if it fails, so it needs a patch to libspl.c to make int_input behave more like scanf.
And with that, it works:
% spl2c < good.spl > good.c
% gcc -lspl -o good good.c
% for f in in-*; do cat $f; echo "->"; ./good < $f; echo "\n"; done
(Act 1, Scene 2, Lines 345-346)
->
(I.ii.345-6)

(Act 3, Scene 4, Lines 34-349)
->
(III.iv.34-349)

(Act 5, Scene 9, Lines 123-234)
->
(V.ix.123-234)

(Act 3, Scene 4, Line 72)
->
(III.iv.72)

(Act 2, Scene 3, Lines 123-133)
->
(II.iii.123-33)

(Act 4, Scene 8, Lines 124-133)
->
(IV.viii.124-33)

Slightly higher-level pseudocode that I worked off of, to help anyone trying to understand:
Print `(`=40
Read 5 chars
Read Int A
Output A in Roman
Output `.`=46
Read 8 chars
Read Int S
Output S in roman
Output `.`=46
Read 6 chars
Set N to -1
Read Int N
If N ≠ -1 goto finish
Read 2 chars
Read Int M
Output Int M
Output `-`=45
Read 1 char
Read Int N
Reduce N wrt M
finish:
Output N
Print `)`=41

Relating the above to the final code is left as an exercise. :-) Note that ShakespearePL has arithmetic and stacks and gotos but no pointers (only labels), so implementing "subroutines" like the conversion to Roman is a bit… interesting.

Wow, that's beautiful. Thank you! :)

slaps the upvote button repeatedly

LaTeX, 513 364 259 226 215 178 159  Bytes
Good essays should always be written in LaTeX.
\documentclass{tui}\makeatletter\input{xstring}\def~#1 #2, #3 #4, #5 #6){(\@Roman#2.\@roman#4.\StrCut{#6}-\A\B\A\if\B\else-\fi\StrCompare\A\B[\P]\StrMid\B\P9)}

This uses the xstring package as there isn't exactly a lot of string handling built in.  On the plus side the upper limit for the built-in \Roman formatting is larger than we'll ever need (even for the sonnets) at 2^31-1. I've included \documentclass{ecv} in the count, but none of the test code:
\begin{document}
\t(Act 1, Scene 2, Lines 345-346)

\t(Act 3, Scene 4, Lines 34-349)

\t(Act 5, Scene 9, Lines 123-234)

\t(Act 3, Scene 4, Line 72)

\t(Act 2, Scene 3, Lines 123-133)

\t(Act 4, Scene 8, Lines 124-133)
\end{document}

(If you were crazy enough to actually use this, you'd have to ungolf the macro names at least.  Overwriting single character macros is bad practice)
Ungolfed and commented:
\documentclass{ecv}%We have to have a documentclass
\makeatletter %treat the @ sign as a normal character (it's used in "internal" macro names)
\input{xstring} %use the xstring package
\def\shortref#1 #2, #3 #4, #5 #6){ %macro with 6 positional arguments searated by spaces and commas
    (%print the open bracket
    \@Roman#2 %arg 2 is the Act,  print uppercase Roman
    .%print the full stop
    \roman#4 %arg 4 is the Scene, lowercase roman
    .%print the full stop
    \StrCut{#6}{-}{\A}{\B}%split arg 6 (Lines) at the hyphen, into macros \A and \B
    \A %print the bit before the hyphen
    \ifx\B\empty%if \B has nothing in it do nothing
    \else %otherwise
        - %we need to print a hyphen
    \fi%endif
    \StrCompare{\A}{\B}[\P] %returns (in macro \P) the position at which \A and \B first differ
    \StrMid{\B}{\P}{9}%print \B starting from position \P (9 > the number of remaining characters)
)}%print the closing bracket

Note that in this version the comments are required otherwise the newline is interpreted as whitespace and expands to a space.

You could save three bytes by using ~ as your macro name instead of \s. But actually you don't need \s (\stripcomma in the ungolfed version) at all: you can just \def\t#1 #2, #3 #4, #5 #6 and TeX will take care of stripping the commas. (So you could use the ~ trick on \t instead, saving 1 byte.)

@ShreevatsaR thank you.  You figured out how to get the comma rejection inline and it was simpler than anything I tried.  The trick with the active ~ is a bit nasty but I like it here. It meant I had to change the documentclass (to one of the other 3-letter .cls files I had installed)

Actually there seems to be a bug: I see 345-346 for the first one (instead of 345-6), and 124-133 for the last one (instead of 124-33).

@ShreevatsaR I've introduced that at some point.  I wonder how. \ifx\B\empty\else saved a few as well

@ShreevatsaR got it: I needed to terminate the defintion of ~ with #6) to ensure the whole last value got picked up. But in debugging I noticed where I could save another 4B: \StrCut doesn't need braces around the macros it assigns to.

And now better than Python!

Nice! You can also save quite a few more bytes with \makeatletter (aka \catcode\@=11but that's the same length) and then using@Roman{#2}and@roman{#4}— you don't need the counterz` at all. The code actually becomes cleaner :D

@ShreevatsaR that's great. Thank you. I'll have a look tomorrow when I'm in front of a computer again but it looks like it's worth around 30B

Yes I count 182 bytes, which beats not just the Python answer but also Ruby, PHP and one of the Perl answers :-)

@ShreevatsaR better still: 178 as \@roman  and \@Roman don't need braces around the argument.

So cool. Looks like some more can go too (all except the one for \def and the one after \StrCut), bringing it down to 166 bytes (if I'm counting correctly). Would beat the Javascript answer and match the R answer :-)

Also the \ifx can be just \if I think… or even \ifx\B\empty\else-\fi can be just \if\B\else-\fi it looks like (not sure I understand this yet). If this is correct, this would make it 159.

@ShreevatsaR \if\B\else-\fi works, so 159 as you say.  I reckon next time there's a challenge suitable for LaTeX you'll have an entry -- and beat me.

All the main xstring ideas were yours :-) It was fun golfing this together!

In fact xstring isn't even needed for this! You don't have to split anything, just gobble the "Lines " and you're good, no need to even process the line numbers: \documentclass{tui}\makeatletter\def~#1 #2, #3 #4, #5 {(\@Roman#2.\@roman#4.}

@Skillmon that doesn't seem to compress the line ranges when I test it.  "345-346" should become "345-6"

@ChrisH oh, didn't realise that that was an objective as well :) You're right then.

@ChrisH you could still save a byte using \catcode\@11instead of\makeatletter`.

@Skillmon that;'s a good point, though I won't edit a 3-year-old answer just for that

@ChrisH you could save another few bytes by instead of using \A using ~ in the definition (saves 3 bytes) at the cost of having to use a token more for the original macro (netting 2 bytes less).

JavaScript (ES6), 210 183 178 177 171 bytes
Saved 27 bytes by unrolling rest parameters (thanks to ETHproductions)
Saved 5 bytes by not matching the opening paren and by tweaking the roman numeral generation
Saved 1 byte by adjusting the final ternary expression
Saved 6 bytes by combining two matching groups
s=>s.replace(/Act (\d)\D*(\d)\D*(\d*)(\d*-?)\3(\d*)/,(_,a,b,c,d,e)=>'IIIV'.slice(a>3&&a-2,a)+'.'+'iiiviiix'.slice('233336'[b-4],b-(b>4))+'.'+c+d+(d.length>e.length?e:c+e))

Test Cases:

let f = s=>s.replace(/Act (\d)\D*(\d)\D*(\d*)(\d*-?)\3(\d*)/,(_,a,b,c,d,e)=>'IIIV'.slice(a>3&&a-2,a)+'.'+'iiiviiix'.slice('233336'[b-4],b-(b>4))+'.'+c+d+(d.length>e.length?e:c+e))

;[
  ["(Act 1, Scene 2, Lines 345-346)", "(I.ii.345-6)"],
  ["(Act 3, Scene 4, Lines 34-349)", "(III.iv.34-349)"],
  ["(Act 5, Scene 9, Lines 123-234)", "(V.ix.123-234)"],
  ["(Act 3, Scene 4, Line 72)", "(III.iv.72)"],
  ["(Act 2, Scene 3, Line 123-133)", "(II.iii.123-33)"],
  ["(Act 4, Scene 8, Line 124-133)", "(IV.viii.124-33)"],
  ["(Act 1, Scene 2, Lines 345-3499)", "(I.ii.345-3499)"]
].map(([a,b]) => console.log(`${a} => ${f(a)} (${f(a) == b ? 'Pass' : 'Fail'})`))
.as-console-wrapper { min-height: 100% }

I can't test right now, but does it still work if you replace Act  and each \D* with .*?

It might; I was hesitant to try because JavaScript employs greedy matching by default. I'll test it later today and let you know if it works.

Jelly,  87 86  85 bytes
DµU=/œr1LCṫ@Ṫ
Ṗ,Çj”-µ⁸L’$?W
⁾-,yḲḊm2Ṗ€Vµ“¬Q:’ṃ⁾IV;”X“¤|ʂ’BṚ¤œṗị@µ1,2¦Œl2¦µ;ṪÇ$“(..)”ż

Try it online! or see a test suite
How?
DµU=/œr1LCṫ@Ṫ - Link 1, toPageShort: list of numbers [fromPage, toPage]  e.g.  [345,365]
D             - cast to decimal lists                                 [[3,4,5],[3,6,5]]
 µ            - monadic chain separation (call that d)
  U           - reverse each                                          [[5,4,3],[5,6,3]]
   =/         - reduce by equality                                              [1,0,1]
     œr1      - strip any 1s from the right                                       [1,0]
        L     - length                                                                2
         C    - complement (1-z)                                                     -1
            Ṫ - tail d                                                          [3,6,5]
          ṫ@  - tail from index (swap @rguments)                                  [6,5]

Ṗ,Çj”-µ⁸L’$?W - Link 2, format page number(s): number or list of two numbers
           ?  - if:
          $   -   last two links as a monad:
        L     -     length
         ’    -     decremented (0 for a number, 1 for a list of two numbers)
      µ       - then:
Ṗ             -   pop (list without the last item, i.e. just the from page)
  Ç           -   call the last link (1) as a monad with the list as its argument
 ,            -   pair
    ”-        -   literal '-'
   j          -   join
              - else:
       ⁸      -   link's left argument (the single page number)
            W - wrap the result in a list (for ease of post-formatting in Main)

⁾-,yḲḊm2Ṗ€Vµ ... µ1,2¦Œl2¦µ;ṪÇ$“(..)”ż - Main link: string s
⁾-,                                    - literal ['-',',']
   y                                   - map (change '-' to ',')
    Ḳ                                  - split at spaces
     Ḋ                                 - dequeue (get all but 1st)
      m2                               - mod-index-2 (1st,3rd,5th)
        Ṗ€                             - pop €ach (ditch last char)
          V                            - evaluate - list of numbers
                                       -   either [act,scene,page] or
                                       -   [act,scene,[from,to]]
           µ     µ   ¦                 - apply to indexes:
                  1,2                  - [1,2]
             ...                       -   see monadic chain " ... ", below
                        2¦             - apply to index 2:
                      Œl               -   lowercase
                          µ            - monadic chain separation
                              $        - last 2 links as a monad:
                            Ṫ          -   tail (page(s))
                             Ç         -   call last link (2) as a monad
                           ;           - concatenate
                               “(..)”  - literal ['(','.','.',')']
                                     ż - zip together
                                       - implicit print

“¬Q:’ṃ⁾IV;”X“¤|ʂ’BṚ¤œṗị@ - monadic chain " ... " from Main
                         -   Get Roman numeral: number n (n>0, n<10) (act or scene)
“¬Q:’                    - base 250 literal 520559
      ⁾IV                - literal ['I','V']
     ṃ                   - base decompression -> "IIIIIIIVVVIVIIVIIII"
          ”X             - literal 'X'
         ;               - concatenate -> "IIIIIIIVVVIVIIVIIIIX"
                   ¤     - nilad followed by link(s) as a nilad:
            “¤|ʂ’        -   base 250 literal 281418
                 B       -   convert to a binary list
                  Ṛ      -   reverse
                    œṗ   -   split at truthy indexes i.e: I II III IV V VI VII VIII IX
                      ị@ -   index into (swap @arguments) using n

That's got to be some sort of record for a Jelly script

@MickyT Nope I have longer out there...

This induces headache. Don't read it 0/10. :P

@EriktheOutgolfer Sorry!!

Jokes aside, I can see some really unique stuff in that code, like œr, Ṗ,Ç, Ṗ€V, ṪÇ$, W as the last link on a helper link, possibly others too, nice effort! This isn't your usual 80-something Jelly submission, this deserves special recognition among Jelly people.

R, 94 126 112 166 bytes
And now it's wordier than before :(, back to trying to golf it further.
Regex for reducing the page reference shamelessly stolen borrowed from @FryAmTheEggman.
Now I really need to do some work to get back the bytes, but it works for the second case now.
R=as.roman;i=sub(',','',scan(,''));sprintf('(%s.%s.%s',R(i[2]),tolower(R(i[4])),`if`(!diff(c(nchar(el(strsplit(i[6],'-'))),0))-1,sub('((.+).*-)\\2','\\1',i[6]),i[6]))

Try it online! - Note that el doesn't work on TIO and has been replaced with unlist
R=as.roman;                              # Used to convert to roman numeral class
i=sub(',','',scan(,''));                 # Get input, splits on spaces, remove ,'s
sprintf('(%s.%s.%s',                     # Use sprintf to format the output.
    R(i[2]),                             # Convert to roman numeral
    tolower(R(i[4])),                    # Convert to roman numeral and lowercase
    `if`(                                #
       !diff(                            # Test if the lengths of the last string
       c(nchar(el(strsplit(i[6],'-'))),0)# split on the hyphen are different (extra 0 to appease diff)
       )-1,                              # taking into account the trailing )
       sub('((.+).*-)\\2','\\1',i[6]),   # on true use regex to reduce range
       i[6]                              # else output as is
    )
)

Retina, 89 88 bytes
T`, lL`._
2`(\d+)
$*i
i{5}
v
i{4}
iv
viv
ix
1T`l`L`\w+
(\b(.+)(.)*-)\2((?<-3>.)*)\b
$1$4

Try it online!
Saved 3 bytes thanks to Neil.
Strips away the unnecessary characters before replacing the first two numbers with blocks of i characters. Then it matches chunks of these is to form the appropriate roman numerals. Then we capitalise the first roman numeral. Finally we match as many numbers as we can before the hyphen and after the hyphen such that the number of digits in the number is the same. We then remove that prefix from the second number.

Replacing iiiii with v, iiii with iv and viv with ix seems to save a couple of bytes.

However, your line number shortening seems to be getting it wrong for 345-356 - I was expecting 345-56.

@Neil Whoops, forgot the kleene expansion. Anyway thanks for the tip!

Can you use \b at the end of the last replacement to avoid having to repeat the ) in the substitution?

@Neil I didn't  think that would work since I thought I'd need to use \d but it does seem to work since there isn't another word boundary. Thanks!

PHP>=7.1, 195 Bytes
preg_match_all("#\d+#",$argn,$t);[[$a,$s,$b,$e]]=$t;for(;$e&&~$c=$e[$k-=1];$p="-".substr($e,$i))$c>$b[$k]&&$i=$k;echo"(",strtoupper(($r=[_,i,ii,iii,iv,v,vi,vii,viii,ix])[$a]),".$r[$s].$b",$p,")";

Testcases
Expanded
preg_match_all("#\d+#",$argn,$t); # match for all groups of digits
[[$a,$s,$b,$e]]=$t; # shorter variables names for these groups
for(;$e&&~$c=$e[$k-=1];$p="-".substr($e,$i)) # prepare the seceond line if exists
  $c>$b[$k]&&$i=$k;
echo"(" # print the char (
,strtoupper(($r=[_,i,ii,iii,iv,v,vi,vii,viii,ix])[$a]) # print the upper roman digit for Act
,".$r[$s].$b" # print the lower roman digit for Scene and the first line with trailing "."
,$p # print shorted second Line
,")"; #Print the closing )

preg_match_all("#\d+#",$argn,$m);[$a,$s,$b,$e]=$m[0]; saves two bytes. if($e){for(;$b[$i]==$e[$i];$i++);echo"-",substr($e,$i);}echo")"; should save 46. (you do not have to support past 5) saves 15 bytes.

".$r[$s].$b" saves another 5 bytes; and [[$a,$s,$b,$e]]=$m; another one. Unfortunately, array assignments don´t work by reference (yet).

if($e&&$e-$b){for($x=str_pad($b,strlen($e),0,0);$x[$i]==$e[$i];$i++);echo"-",substr($e,$i);} saves 10 bytes and might work.

Looks ok to me. And &&$e-$b is unnecessary for the test cases; so it saves 17 bytes, not 10. Btw. you still don´t need roman 6 to 9. ;)

@Titus I need the roman number about 5 for the testcases with scene over 5

You could replace for(;str_pad($b,strlen($e),0,0)[$i]==$e[$i];)$i++; with for(;$e&&~$c=$e[-++$k];)$c>$b[-$k]&&$i=-$k;.

@Christoph Thank You after an own shorter approach that not work, I have reduced your idea

Perl 5, 185 + 1 = 186 bytes
1 byte penalty for the required -n flag.
May fail for some test cases where the scene has more than 10^11 lines, but AFAIK no Shakespeare scenes are quite that long ;)
y/A-z //d;while($x++<9){s/,(\d+)(\d{$x})-\g1(\d{$x}\))/,$1$2-$3/};@F=split/,/;for($F[0],$F[1]){$_.='i'while(y/2-91/1-8/d);s/i{5}/v/g;s/i{4}/iv/;s/v(i)?v/$1x/;s/$/,/};$F[0]=uc$F[0];say@F

In readable form:
y/A-z //d; #Delete all characters besides numbers, parenthesis, and comma
while($x++<9){s/,(\d+)(\d{$x})-\g1(\d{$x}\))/,$1$2-$3/}; #Shortens the line numbers. Super ugly, but my simpler code broke on test case 2- that fix added 26 bytes :( I'll revisit this later, perhaps...
@F=split/,/; #Splits the input into an array so we can mess with the act and scene without messing with the lines
for($F[0],$F[1]){ #For loop over the act and scene
    $_.='i'while(y/2-91/1-8/d); #Recursively turn numbers into naive Roman numerals (i.e. 9 would be iiiiiiiii)
    s/i{5}/v/g;s/i{4}/iv/;s/v(i)?v/$1x/;s/$/,/ #Substitution rules to convert naive Roman numerals into real Roman numerals and add a comma to the end
}
$F[0]=uc$F[0]; #Convert act to uppercase
say@F #Output

Python 2, 301 259 252 221 bytes
A whopping -31 bytes thanks to Chas Brown.
So, uh, this is... extremely long... I think I can golf this but I've been wracking my brain for a while.
import re
def f(s):s,r=re.match(r'.*?(\d),.*?(\d), .*? (\d*)(\d*-?)\3(\d*)',s),'0 i ii iii iv v vi vii viii ix'.split();b,c,d,e,f=s.groups();print'(%s.%s.%s)'%(r[int(b)].upper(),r[int(c)],d+e+(f if len(e)>len(f)else d+f))

Try it online!
Breakdown
import re                     # re module for regex stuff

def f(s):                     # function that accepts one argument

    s, r = (re.match(r'.*?(\d),.*?(\d), .*? (\d*)(\d*-?)\3(\d*)', s),
           # match the string and capture the important parts using regex

           '0 i ii iii iv v vi vii viii ix'.split()
           # array that stores roman numerals

    b, c, d, e, f = s.groups()
                    # all the numbers from the match to variables

    print '(%s.%s.%s)' % (
                              r[int(b)].upper(),
                              # get the respective roman numeral and make it uppercase

                              r[int(c)],
                              # get the respective roman numeral

                              d + e + (f if len(e) > len(f) else d + f)
                              # shorten the second number if it's shorter than the first number
                         )

You can save a bit by using b,c,d,e,f=s.groups() instead of a,b,c,d,e,f=[s.group(n) for n in range(6)]

And another 5 by using [0]+'i,ii,iii,iv,v,vi,vii,viii,ix'.split(',') instead of [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].

Amended - And another 8 by using [0]+'i ii iii iv v vi vii viii ix'.split() instead of [s,'i','ii','iii','iv','v','vi','vii','viii','ix'].

Oh, huh, didn't know you could do that. Thanks!

Nice tweak putting the 0 inside the quotes. One last minor tweak I can see: you are using: s,r=XXX,YYY;b,c,d,e,f=s.groups(); you can save another 4 bytes by instead equivalently saying: b,c,d,e,f=XXX.groups();r=YYY;. So you end up with 81 bytes less than my submission! :)

Perl, 99 bytes
/(.+)(-\1|.(?2).)\b/;@r=(s/-$1/-/,I,II,III,IV,V,VI,VII,VIII,IX);s/Act(.+)(.,).+ /$r[$1].\L$r[$2]./

Run with perl -pe. 98 bytes (source) + 1 byte (p flag) = 99.

At the time of this posting, there is another Perl answer (https://codegolf.stackexchange.com/a/123400/6484), but it is 186 bytes long and uses very different ideas, so I felt making a separate answer was appropriate.

This seems to be wasteful as it takes provisions for roman numerals beyond 5

@HagenvonEitzen the challenge specifies that you have to support roman numerals up to 9. Test case 3 has “Scene 9”, and test case 6 has “Scene 8”; both would fail if I only supported roman numerals up to 5.

Ruby, 204+1 = 205 bytes
Uses the -p flag.
d=[r=%w"i ii iii iv v vi vii viii ix",r.map(&:upcase)]
i=-1
gsub(/\w+ ([\d-]+)/){(a=d.pop)?a[$1.hex]:(a,b=$1.split ?-;b ?(a="%0#{b.size}d"%a;b[0]=""while b[0]==a[i+=1];a.sub(/^0*/){}+?-+b):a)}
gsub", ",?.

Try it online!

Python 2.7 298 bytes
import re
r=lambda n:'iiiviiix'[2*(n>3)+(n>4)+3*(n>8):n-(n>4)]
o=lambda x,y,n=0:n*(len(x)==len(y))if not x or x[0]!=y[0]else o(x[1:],y[1:],n+1)
q=lambda a,s,g,h:(r(int(a)).upper(),r(int(s)),g+'-'+h[o(g,h):]if h else g)
f=lambda p:'(%s.%s.%s)'%q(*re.match('\D*(\d)\D*(\d)\D*(\d+).(\d*)',p).groups())

q/kdb+, 200 187 bytes
Solution:
f:{R:(($:)N:(!)11)!($:)``i`ii`iii`iv`v`vi`vii`viii`ix`x;S:","vs x inter .Q.n,",-";L:"-"vs P:S 2;"(",("."sv(upper R S 0;R S 1;$[{x[y]=x z}[#:;F:L 0;T:L 1];F,"-",((*:)N(&:)F<>T)_T;P])),")"}

Examples:
q)f "(Act 1, Scene 2, Lines 345-346)"
"(I.ii.345-6)"
q)f "(Act 3, Scene 4, Lines 34-349)"
"(III.iv.34-349)"
q)f "(Act 5, Scene 9, Lines 123-234)"
"(V.ix.123-234)"
q)f "(Act 3, Scene 4, Line 72)"
"(III.iv.72)"
q)f "(Act 2, Scene 3, Lines 123-133)"
"(II.iii.123-33)"
q)f "(Act 4, Scene 8, Lines 124-133)"
"(IV.viii.124-33)"

Explanation: (slightly ungolfed)
f:{
  // create map of 0->10 to roman numerals, e.g. "5" -> "v"
  R:(($:)N:(!)11)!($:)``i`ii`iii`iv`v`vi`vii`viii`ix`x;
  // remove everything from the input string except -, then split on ,
  S:","vs x inter .Q.n,",-";
  // split the final field on '-', also save final field in variable P
  L:"-"vs P:S 2;
  // if the length of from/to lines are the same then find the first character
  // where they differ, and cut this many characters from the 'to' string
  M:$[{x[y]=x z}[#:;F:L 0;T:L 1];F,"-",((*:)N(&:)F<>T)_T;P];
  // join everything together, use act/scene to index into
  // the roman numeral map, uppercase the act
  "(",("."sv(upper R S 0;R S 1;M)),")"
  }

Notes:
Technically it can be 2 bytes shorter (no need for the f:) but makes it easier to show examples this way.
Edits:

-13 bytes; replaced string with $:, count with #:, til with (!) and first with (*:), cast the indices of R to strings so we dont have to cast act/scene into ints


text:
Github Messenger
Goal: This goal to take a string and output how many contributions should be made on which days in order to display a message.

Specification

Input

Support letters plus space (i.e. [A-Za-z ] )
Space is a blank 3X7
The letters are defined in this 5x7 DOT Matrix font provided below
The size of each letter is the minimum bounding rectangle (e.g. l = 3x7, e = 5x5)

Coloring

There are 5 colors C0, C1, C2, C3, C4
CX requires Y contributions with 3X <= y < 3(X+1)
Letters should alternate between C1 and C2
Spaces have no color
Each letter size should overlap exactly 1 column with adjacent letters
If a cell has more than 1 color then use C3

Dot Matrix

The dot matrix is Github's contribution history graph
If today is Monday, May 1st, 2017:

 4-30    5-07    5-15
[5-01]   5-08    5-16
 5-02    5-09     .
 5-03    5-10     .
 5-04    5-12     .
 5-05    5-13
 5-06    5-14

Output

Flexible on how this is given
(x, y) pairs
x is a date greater than or equal to the current date
y is the number of contributions to be made on the date, x
Should be in chronological order (so I can fill in my calendar)
If for each date, x, the given y contributions are made, the input message should show up on the Github graph (with correct coloring)
The first date should the earliest possible

Scoring

Shortest program/function in bytes wins

Alphabet
Created by sylvan.black under CC

Test Cases
For these test cases, assume the current date is May 25th, 2017.
Input -> Output
-----    ------
l        5-28-17, 3
         6-3-17, 3
         6-4-17, 3
         6-5-17, 3
         6-6-17, 3
         6-7-17, 3
         6-8-17, 3
         6-9-17, 3
         6-10-17, 3
         6-17-17, 3

He       5-28-17, 3
         5-29-17, 3
         5-30-17, 3
         5-31-17, 3
         6-1-17, 3
         6-2-17, 3
         6-3-17, 3
         6-7-17, 3
         6-14-17, 3
         6-21-17, 3
         6-25-17, 3
         6-26-17, 3
         6-27-17, 3
         6-28-17, 9
         6-29-17, 9
         6-30-17, 9
         7-1-17, 3
         7-4-17, 6
         7-6-17, 6
         7-8-17, 6
         7-11-17, 6
         7-13-17, 6
         7-15-17, 6
         7-18-17, 6
         7-20-17, 6
         7-22-17, 6
         7-26-17, 6
         7-27-17, 6

o W      5-31-17, 3
         6-1-17, 3
         6-2-17, 3
         6-6-17, 3
         6-10-17, 3
         6-13-17, 3
         6-17-17, 3
         6-20-17, 3
         6-24-17, 3
         6-28-17, 3
         6-29-17, 3
         6-30-17, 3
         7-9-17, 6
         7-10-17, 6
         7-11-17, 6
         7-12-17, 6
         7-13-17, 6
         7-14-17, 6
         7-22-17, 6
         7-26-17, 6
         7-27-17, 6
         7-28-17, 6
         8-5-17, 6
         8-6-17, 6
         8-7-17, 6
         8-8-17, 6
         8-9-17, 6
         8-10-17, 6
         8-11-17, 6

Is C4 ever used?

@FryAmTheEggman It is not, but I included it to avoid confusion because Github displays 5 colors in the legend.

How strict/loose are you on date output format?

@StephenS It is flexible, as long as it is human readable (e.g. May 20th, 2017: 3, (3,"20/5/17") )

Where did you find that contribution table?

@EriktheOutgolfer It is on the Overview tab of a user's profile, beneath their pinned repos.

@EriktheOutgolfer If you meant this specific "Hello World" example, I took a screen shot and doctored it.

@NonlinearFruit Oh I knew it why did everyone think of something else...

JavaScript (ES6), 743 bytes
s=>(n=y=>d.setDate(d.getDate()+y),d=new Date,(h=d.getDay())&&n(7-h),r={},i=0,[...s].map(c=>{c<"!"?n(14):([...parseInt("jn4x733nx8gjw6nhricv6nx8dpz2vilui81vikl7b4nhridnzvgc1svznx8dji8g16fkg0vgc6341vg38oe9vh669ofvgm1dvjnhricvyvikl7aonhrjrjxvikmm29m0rqqp2nqmi6o0vbnf6dav2t14e4vbnjqpqs0g34o3tlqqwdso43oixtg1uyt8vvgddxn2hizrn2ahizrmdbhj4suq4gtytq8wgshvtzyvgc4mq7gzhwhz4g15ymf4vg72q9snx7r2f4jmffjm7jm5gavjhizrn2mjmkh3wogsgmianjm5gavcgwxpc3mhvni2kijhgqujjj8mcsgsjhgslnihw2cx75iqyv1cuhwdrh5d".substr((c.charCodeAt()-(c>"`"?71:65))*7,7),36).toString(2).slice(1).replace(/(0{7})+$/,"")].map(b=>(+b&&(r[+d]=r[+d]?9:i%2?6:3),n(1))),i++,n(-7))}),Object.keys(r).map(k=>[k,r[k]]).sort((i,j)=>i[0]-j[0]>0?1:-1).map(i=>[(new Date(+i[0])+"").slice(4,15),i[1]]))

Output is an array of 2-item arrays in the form [dateString, contribs]. The snippet below shows how that can be formatted into being more readable.
Un-Golfed
s=>(
    n=y=>d.setDate(d.getDate()+y),
    d=new Date,
    (h=d.getDay()) && n(7-h),
    r={},
    i=0,
    [...s].map(c=>{
        c<"!" ? n(14) : (
            [...parseInt("<...>".substr((c.charCodeAt()-(c>"`"?71:65))*7,7),36).toString(2).slice(1).replace(/(0{7})+$/,"")].map(b=>(
                +b && (r[+d] = r[+d] ? 9 : i%2?6:3),
                n(1)
            )),
            i++,
            n(-7)
        )
    }),
    Object.keys(r)
        .map(k=>[k,r[k]])
        .sort((i,j)=>i[0]-j[0] > 0 ? 1 : -1)
        .map(i => [ (new Date(+i[0])+"").slice(4,15), i[1] ])
)

Where <...> represents the 364-byte string of characters that I created to encode each letter's dot matrix form.
Explanation
The encoded string:
jn4x733nx8gjw6nhricv6nx8dpz2vilui81vikl7b4nhridnzvgc1svznx8dji8g16fkg0vgc6341vg38oe9vh669ofvgm1dvjnhricvyvikl7aonhrjrjxvikmm29m0rqqp2nqmi6o0vbnf6dav2t14e4vbnjqpqs0g34o3tlqqwdso43oixtg1uyt8vvgddxn2hizrn2ahizrmdbhj4suq4gtytq8wgshvtzyvgc4mq7gzhwhz4g15ymf4vg72q9snx7r2f4jmffjm7jm5gavjhizrn2mjmkh3wogsgmianjm5gavcgwxpc3mhvni2kijhgqujjj8mcsgsjhgslnihw2cx75iqyv1cuhwdrh5d

Each 7 characters is a base-36 encoded binary number that contains the mapping for the character at that index. The binary form always has a leading 1 in order to preserve the leading 0s. For example, an uppercase T maps to nqmi6o0, which converts to 1100 00001000 00011111 11100000 01000000. Skipping the leading 1, each bit is one day. Most numbers have 5 columns/weeks, so the numbers with less than 5 columns have one or two sets of 7 trailing zeros that are later removed before parsing (.replace(/(0{7})+$/,"")). This keeps all encoded strings the same length, removing the need for delimiters.
There's probably still more ways to improve upon this, especially with compressing the letter mappings further, so feel free to share any ideas.
Binary format of the letter mappings (JS syntax, prefixed with 0b), can be found here.
Basic Snippet

f=
s=>(n=y=>d.setDate(d.getDate()+y),d=new Date,(h=d.getDay())&&n(7-h),r={},i=0,[...s].map(c=>{c<"!"?n(14):([...parseInt("jn4x733nx8gjw6nhricv6nx8dpz2vilui81vikl7b4nhridnzvgc1svznx8dji8g16fkg0vgc6341vg38oe9vh669ofvgm1dvjnhricvyvikl7aonhrjrjxvikmm29m0rqqp2nqmi6o0vbnf6dav2t14e4vbnjqpqs0g34o3tlqqwdso43oixtg1uyt8vvgddxn2hizrn2ahizrmdbhj4suq4gtytq8wgshvtzyvgc4mq7gzhwhz4g15ymf4vg72q9snx7r2f4jmffjm7jm5gavjhizrn2mjmkh3wogsgmianjm5gavcgwxpc3mhvni2kijhgqujjj8mcsgsjhgslnihw2cx75iqyv1cuhwdrh5d".substr((c.charCodeAt()-(c>"`"?71:65))*7,7),36).toString(2).slice(1).replace(/(0{7})+$/,"")].map(b=>(+b&&(r[+d]=r[+d]?9:i%2?6:3),n(1))),i++,n(-7))}),Object.keys(r).map(k=>[k,r[k]]).sort((i,j)=>i[0]-j[0]>0?1:-1).map(i=>[(new Date(+i[0])+"").slice(4,15),i[1]]))

I.value="Hello World";
(I.oninput=_=>O.innerHTML = f(I.value).map(e=>e.join(": ")).join("\n"))();
<input id="I">
<pre id="O">

Interactive example
Using the library cal-heatmap, I created an interactive heatmap of the dates that are output. This was used to test everything while working, and it just looks plain neat.

The interactive example is really awesome. Nice job!

Oh god, someone actually did this! Nice!

Thanks guys! This was a really cool challenge, I wish more people would come attempt it. I've edited my answer to include the dot matrix letters in binary so that others can use the same idea.

@JustinMariner I popped this onto my profile, hope you don't mind. Nice answer, glad someone completed this challenge :)

@StephenS Nice, glad you liked it!

It takes 523 days to spell 'Drink Your Ovaltine'.  Time to get to work..

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
What is this date format?
For Gregorian calendars, the date format varies from a country to another. There are three main formats recognized:

YY-MM-DD (big-endian)
DD-MM-YY (little-endian)
MM-DD-YY (middle-endian)

Your task is to write a program which, given an input string representing a date, output all the possible date formats by which this string can be interpreted as a date.
Rules

The input date is in the format xx-xx-xx, where each field is two digits and zero-padded.
The date is always valid (so you cannot get things like 14-13-17)
The date is always at least one of the formats above (so you cannot get things like 17-14-11)
Because we are in fact in a parallel world, there are 31 days for every month of the year, and consequently no leap years
The date is between January 01, 2001 and December 31, 2099
If there is only one format for the date, the code must print only it (only trailing newlines are allowed)
If there are several formats for the date, they must be either separated by a comma, a space, a newline, or a combination of those
You must output the exact name(s) of the format(s). Using distinct arbitrary values is not allowed.
No leading or trailing characters others than a trailing space are allowed
The output must be lowercase
You are not allowed to use any built-in date or calendar functions
The output formats do not have to be sorted

Examples
Input      Output
30-05-17   big-endian, little-endian
05-15-11   middle-endian
99-01-02   big-endian
12-11-31   big-endian, little-endian, middle-endian
02-31-33   middle-endian

This is code-golf so the shortest code in bytes wins. Explanations are encouraged.

You should probably add a test-case using February 31st to make sure answers support that weird case :P

Can we output any three distinct values for the three valid formats, or must it be those three exact strings?

there are 31 days for every month of the year, and consequently no leap years So this means any date library is effectively useless for this then?

@TheLethalCoder Yes, most date libraries are probably unusable.

Since the year is 01-99, does this mean no number in the date will ever be 0?

@ETHproductions It must be these three exact strings. I have updated the rules.

@BusinessCat Indeed, no number in the date will ever be zero.

Does the output have to be a string or can it be an array of the values or similar?

@TheLethalCoder It has to be a string, you are not permitted to display square brackets or similar. I updated the answer to make that clearer.

Does the output then have to be comma and space separated values or can I have only space separated? Can I also have leading and trailing spaces?

Related

There are many more formats out there.

05AB1E, 40 bytes
'-¡©2£13‹`®Á2£32‹*)˜“Œ±„¥„ê“#Ï’-„–ian’«»

Try it online!
Explanation
'-¡©                                      # split on "-" and store a copy in register
    2£13‹                                 # compare the first 2 elements to 13
         `                                # split as separate to stack
                                          # the bottom element is true if it is middle endian
                                          # the top value is true if it can be big/little
          ®Á                              # retrieve the list from register and rotate right
            2£32‹                         # compare the first 2 elements to 32
                 *                        # multiply with the result of the comparison to 13
                  )˜                      # wrap in a flattened list
                    “Œ±„¥„ê“#             # push the list ['middle', 'big', 'little']
                             Ï            # index into this with the flattened list
                                          # this leaves the types the date could be
                              ’-„–ian’«   # append "-endian" to each
                                       »  # join on newlines

Python 2, 123 bytes
a,b,c=map(int,input().split('-'))
for a,b,c in[[b,c,'big'],[b,a,'little'],[a,b,'middle']]:print(c+'-endian')*(a<13)*(b<32),

Try it online!

Python 2, less input parsing, 123 bytes
d=input()
for a,b,c in[[3,6,'big'],[3,0,'little'],[0,3,'middle']]:print(c+'-endian')*(int(d[a:a+2])<13)*(int(d[b:b+2])<32),

Try it online!

You're allowed to separate with newlines, so can remove the trailing ,.

JavaScript (ES6), 121 119 118 112 bytes
Returns a space-delimited string with a trailing space.
s=>['big','little','middle'].map((v,i)=>[b<13&c<32,b<13&a<32,a<13][i]?v+'-endian ':'',[a,b,c]=s.split`-`).join``

How?
We split the input into a, b and c. Because the date is guaranteed to be valid, we know for sure that b is less than 32. Therefore, it's enough to test whether a is less than 13 to validate the middle-endian format. Little-endian and big-endian formats require b to be less than 13 and another test on a and c respectively to validate the day.
Hence the 3 tests:

Big-endian: b < 13 & c < 32
Little-endian: b < 13 & a < 32
Middle-endian: a < 13

Test cases

let f =

s=>['big','little','middle'].map((v,i)=>[b<13&c<32,b<13&a<32,a<13][i]?v+'-endian ':'',[a,b,c]=s.split`-`).join``

console.log(f("30-05-17")) // big-endian, little-endian
console.log(f("05-15-11")) // middle-endian
console.log(f("99-01-02")) // big-endian
console.log(f("12-11-31")) // big-endian, little-endian, middle-endian
console.log(f("02-31-33")) // middle-endian

Bash, 240 125 116 112 bytes
IFS=- read a b c<<<$1
d=-endian
((b<13))&&(((a<32))&&echo little$d;((c<32))&&echo big$d);((a<13))&&echo middle$d

Golfed.
Thanks to manatwork for some tips
Saved 9 bytes removing the verification for less than 32 in the middle-endian follwing Arnauld answer
Saved 4 bytes by using different variables instead of an array
Test it!

There are a couple of arithmetic related tips in Tips for golfing in Bash. You could reduce it a bit:
Try it online!

Thank you @manatwork I have that question bookmarked is very useful, will golf it by it

C#, 180 bytes
t=(n,m)=>int.Parse(n)<13&int.Parse(m)<32;s=>{var a=s.Split('-');return$"{(t(a[1],a[2])?"big-endian":"")} {(t(a[1],a[0])?"little-endian":"")} {(t(a[0],a[1])?"middle-endian":"")}";};

Outputs with only space separated values, can also have leading and trailing spaces. Will update when the OP has clarified on that point if needed.
Full/Formatted version:
Func<string, string, bool> t = (n, m) => int.Parse(n) < 13 & int.Parse(m) < 32;

Func<string, string> f = s =>
{
    var a = s.Split('-');

    return $"{(t(a[1], a[2]) ? "big-endian" : "")} {(t(a[1], a[0]) ? "little-endian" : "")} {(t(a[0], a[1]) ? "middle-endian" : "")}";
};

I made the rule more clear: No leading or trailing characters others than a trailing space are allowed

Java 232 bytes
(String s)=>{String[]i=s.split("-");String e="-endian",b="big"+e,m="middle"+e,l="little"+e;int p=Integer.valueOf(i[0]);System.out.print(p<13?Integer.valueOf(i[1])<13?Integer.valueOf(i[2])<32?b+","+m+","+l:m+","+l:m:p<32?b+","+l:b);}

Here's a nicer version
String[] i = s.split("-");

String e = "-endian",
       b = "big" + e,
       m = "middle" + e,
       l = "little" + e;

int p = Integer.valueOf(i[0]);

I didn't really know how to format this part...
System.out.print(
        p < 13 ? Integer.valueOf(I[1]) < 13 ? Integer.valueOf(I[2]) < 32 ? b + "," + m + "," + l
                                                                         : m + "," + l
                                            : m

               : p < 32 ? b + "," + l
                        : b
);

Too many endians: String e="-endian",b="big"+e,m="middle"+e,l="little"+e;.

Good point, when I decided not to do that I was including an extra "String " in my byte count. @manatwork

PHP, 151 Bytes
[$a,$b,$c]=sscanf($argn,"%d-%d-%d");$z="-endian ";echo($m=$b&&$b<13)&&$c&&$c<32?big.$z:"",$m&&$a&&$a<32?little.$z:"",$a&&$a<13&&$b&&$b<32?middle.$z:"";

Testcases

Batch, 138 bytes
@echo off
set/ps=
call:l little %s:-= %
exit/b
:l
call:e big %4 %3
call:e middle %3 %2
:e
if %2 leq 31 if %3 leq 12 echo %1-endian

Vaguely based on @ovs's answer.

PHP, 131 bytes
[$a,$b,$c]=explode('-',$argn);foreach([[big,b,c],[little,b,a],[middle,a,b]]as[$t,$x,$y])echo$$x*$$y&&$$x<13&$$y<32?"$t-endian ":"";

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Same length, different string
Challenge
Given a non-empty string S of length L consisting entirely of printable ASCII chars, output another string of length L that consists entirely of printable ASCII chars, but is not equal to S.
For the purposes of this challenge, a printable ASCII char is one between U+0020 and U+007E, inclusive; that is, from   (space) to ~ (tilde). Newlines and tabs are not included.
For example, given "abcde", some valid outputs could be:

"11111"
"abcdf"
"edcba"

But these would be invalid:

"abcde"
"bcde"
"abcde0"

Test cases
"asdf"
"1111"
"       "
"~~~~~"
"abcba"
"1"
" "
"~"
" ~"
"~ "
"  0"
"!@#$%^&*()ABCDEFGhijklmnop1234567890"
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"

Rules

You may assume the input consists entirely of printable ASCII chars.
You may not assume that the input does not contain all 95 printable chars.
You may assume the input contains at least one character and is less than 256 chars long.
The output must also consist entirely of printable ASCII chars. You could not, for example, output the byte \x7F for input "~".
The output must be different than the input with probability 1; that is, you may generate random strings until one is different than the input, but you can't just output L random characters and hope it's different.
Newlines are disallowed in the output, but you may output one trailing newline which is not counted toward the string.

Scoring
This is code-golf, so the shortest code in bytes in each language wins.

Note that "positive" excludes the empty string. For extra clarity, maybe replace "positive" with "nonzero"?

@CalculatorFeline But that would include negative-length strings /s

...Those don't exist.

@CalculatorFeline Better now?

....really? -_- Also yes.

Related

Another simple but not trivial challenge.

Python 2, 21 bytes
lambda s:`s`[:len(s)]

Try it online!
Takes the string representation of the input string and truncates it to the length of the input string. For a typical string, this puts it in ' quotes and chops off the end:
abc  ->   'abc'  ->  'ab
     rep        chop

Note that the new string starts with '. Let's show that the output always differs from the input.

If the input has no ', then the output starts with ' and the input does not.
If the input contains a ' and but no ", then Python will use " for the outer quotes, giving a first character " that's not in the input string.
If the input has both ' and ", then the outer quotes are ' and each ' is escaped as \'. Wherever the first " appears in the input, it's shifted right by the initial ' in the output and by any possible escaping. This means it cannot match with a " in the corresponding position in the output.

Finally, note that quoting the input and possibly escaping characters always increases the number of characters, so truncating the output makes it the same length as the input.
Note that it was crucial that Python adaptively switches to " in the second case. If it didn't do so, it would fail on the three-character input '\'. Or, any longer prefix of the fix show string using '. So, this method won't work for most languages.

What's the reasoning for indexing 'til len(s) rather than -2?

@JulianWolf For an input containing both ' and ", more than 2 characters will have been added because the quotes need to be escaped.

Makes sense; hadn't considered that. Thanks!

You can use [2:] instead of [:len(s)] to get down to 16 chars.

@xbarbie That doesn't always give the same length, if there are characters needing escaping.

@xnor Oh, I see now, '\"\'' is such example... Thank you!

05AB1E, 3 bytes
ÇÈJ

Try it online!
Ç   # Convert to ASCII values
 È  # is even? (0 is 48 and 1 is 49 therefore 0 -> 1 and 1 -> 0)
  J # Join

Nice, very clever

JavaScript (ES6), 37 33 36 29 26 18 21 19 bytes
s=>s.slice(1)+ +!+s

Try it online!
-4 bytes thanks to ETHProductions
-7 + -5 + -2 bytes thanks to CalculatorFeline
-3 bytes thanks to Rick Hitchcock
Moves the first character to the end and sets it to 0 if it's numeric and non-zero, and 1 otherwise.
Explanation
s=>                    anonymous function with parameter s
                 +s    convert s to a number
                !      not (converts to boolean; relevant: 0->true,1->false)
               +       convert !+s back to number (true->1, false->0)
   s.slice(1)+         prefix the rest of the string
              ␣        needed to avoid the +s combining

Proof
Because the second char becomes the first, the third char becomes the second, etc. all chars would have to be identical. The last remaining char can only be a 0 or a 1, so the repeated char would have to be either 0 or 1. But any string of 0s produces a 1 at the end, and vice-versa; therefore, it is impossible to create an input that is equal to its output. -ETHProductions
See edits for former versions and explanations.

f=
s=>s.slice(1)+ +!+s

console.log(f("000"))
console.log(f("111"))
console.log(f("001"))
console.log(f("110"))
console.log(f("~"))
console.log(f("111111111111111111111111111111111111111111111111111"))
console.log(f("Hello world!"))
console.log(f("23"))
console.log(f(" "))
console.log(f("1x"))

Jelly, 3 bytes
~Ṿṁ

Output is a string of digits, commas and hypen-minus characters, whose first character will differ from the first character of the input string.
Try it online!
How it works
~Ṿṁ  Main link. Argument: s (string)

~    Map bitwise NOT over the characters c in s.
     This attempts to cast c to int and then apply bitwise NOT, mapping
     '0', ..., '9' to 0, ..., 9 (before ~), then -1, ..., -10 (after ~).
     For non-digits, the attempt fails, mapping c to 0.
 Ṿ   Uneval, yielding a comma-separated string of integers in [-10, ..., 0].
     The first character will be '-' if s starts with a digit and '0' if not.
  ṁ  Mold; truncate the result to the length of s.

Haskell, 20 bytes
map$head.show.(<'M')

Try it online!
Converts to a string of F and T. What matters is that the characters F and T converts to each other. This is done by checking if the character is less than M to get True or False, then taking the first character of the string representation.

Haskell, 23 bytes
q '~'=' '
q _='~'
map q

Try it online
Replaces every character with ~, except ~ becomes a space.

What is the significance of the space in q '~'? Why can't it be removed?

@Cyoce Haskell permits ' as a character in identifiers, so q'~'=' ' would be parsed as q' ~ '=' ' (reporting a lexical error because the last ' is unmatched.)

MATL, 6 5 bytes
Qo!V!

Try it online!
Explanation
Q     % Implicitly input a string. Add 1 to each code point.
o     % Parity: 0 if odd, 1 if even. Note that '0' has ASCII code 48, so after
      % having added 1 it now gives 1. Similarly. '1' has ASCII code 49, so it
      % now gives 0. All other chars give 0 or 1.
!V!   % Convert each number to the corresponding char. Implicitly display

That's 5 in CJam: l'0f= (if it does what I think it does)

@MartinEnder Yes, it's exactly that :-) I've just added an explanation

Whitespace, 59 bytes
Visible representation
NSSNSSSTSSSSSNSNSSNSSNSTNTSTTTTSSTNTTSNSNSTSSSNSSSNTNSSNSNN

What it does:
For every character it reads it prints a space, except when it's a space, then it prints a @.
Disassembly:
loop:
    push 32
     dup
      dup
       dup
        ichr
       get
       sub
      jn not_32
     dup
      add
not_32:
     pchr
    jmp loop

Always nice to see a solution in Whitespace. Especially when you normally are unable to actually see it. +1

Haskell, 19 bytes
An anonymous function which takes and returns a String. Use as (map$(!!1).show.succ) "1111".
map$(!!1).show.succ

Try it online! (Using @xnor's testing harness.)

For each character in the input string, increments the character, then converts that to character literal format, then takes the second character of the literal, which is the character just after the starting ' quote.
For nearly all printable characters, this results in simply the incremented character. The exceptions are & and ~, which instead give \, because their successors ' and \DEL get escaped in character literals.

pretty sure head can be used in place of (!!1) for an extra byte

No, head is (!!0), not (!!1). It would fail on the character '.

Ah, right. I'd just been reading the python answer and forgot that quotes usually needed special treatment.

><>, 9 3 bytes
5%n

Try it online!
Takes input through the -s flag. Mods each digit with 5 and prints the integer, ending when the stack is empty. This results in only 5 possible output characters, 0-4. Each of those numbers when inputted will produce themselves plus 3, as the ASCII value of 0 is 48, which mod 5 is 3. While the output is reversed, no number is equivalent to another.
Both 7, 9 and a(10) also work as they are not factors of 48 and print single digits.

05AB1E, 5 bytes
žQDÀ‡

Try it online!
Explanation
Replaces each char with the next printable ascii char, wrapping from tilde to space.
žQ     # push a string of printable acsii chars (space to tilde)
  D    # duplicate
   À   # rotate left
    ‡  # translate

Python 2, 25 bytes
lambda s:`s<'T'`[0]+s[1:]

Try it online!
Anders Kaseorg saved a byte by extracting the first character from True or False.

I'd suggest changing '?' to a 2 digit charcode, but Python isn't one of those languages where you can do that :(

Variants saving a byte (but dropping Python 3 compatibility): lambda s:`+(s<'1')`+s[1:] or lambda s:`s<'T'`[0]+s[1:]

V, 7 bytes
íÁ/a
g?

Try it online! or Verify all test cases!
How does it work?
Consider all strings consisting of printable ASCII. Every string must either 1) Contain alphabetic characters, or 2) Contain no alphabetic characters.
So the way this program works is by first converting one non-alphabetic character into 'a', and then performing ROT13 on the input string.
í       " Substitute:
 Á      "   A non-alphabetic character ([^a-zA-Z])
  /     "   with
   a    "   the letter 'a'
g?      " Perform ROT13 on...
        "   (Implicit) the current line.

This breaks if you have a number like 9 alone, where incrementing it adds another character to the string

@nmjcman101 Ah, that's a good point. I've reverted

I like the ROT13 thing though, I didn't know V(im) could do that

Bash + coreutils, 13
tr \ -~ ~\ -}

Transliterates the characters   to ~ (0x20 - 0x7e) with ~, then   to } (0x7e, 0x20 - 0x7d).
Try it online.

C (gcc), 22 bytes
f(char*s){*s=65+*s%2;}

Takes a string pointer and modies the first char in place.
Try it online!

Shorter: *s=159-*s. Always changes the last bit, therefore never gives the same character. Note that 159 = ' ' + '~'

I think you mean 158 = ' ' + '~'.  159-32 = 127, which would be a character out of scope.  But good idea.

@celtschk Involutions cannot work, as there's an odd amount (95) of printable chraracters, so at least one of them will map to itself.

@Computronium: Oops, you're right, I got the character code of ~ wrong.

C (gcc), 20 bytes
Saw Dennis's answer, thought of a 2 byte essential improvement.
f(char*s){*s^=*s/3;}

Try it online! (Footer by Dennis.)
Like the original, modifies the first character of the string in place, but xors it with its value divided by 3 (the smallest number that works. 2 fails on the single character 'U' which gives 127, not printable.)

Retina, 10 6 bytes
4 bytes golfed thanks to @Neil
T`p`~p

Try it online!
This transliterates  to ~, ! to , " to !, ..., ~ to }.

Octave, 19 18 bytes
@(s)['',(s<66)+65]

Try it online!
Explanation:
@(s)                 % Anonymous function taking a string s as input
         s<66        % A boolean vector with `1` for all characters below ASCII-66.
        (s<66)+65    % Add 65 to this, so that all elements that are 32-65 are now 66.
                     % All other elements are 65
    ['',         ]   % Implicitly convert the list of 65 and 66 to the letters A and B

Haskell, 30 26 bytes
f ' '='~'
f c=pred c
map f

Try it online!
Replaces each char with its predecessor and space with tilde.

CJam, 5 bytes
l)iA%

Try it online!
Converts the last character to its code point and takes that modulo 10. This is clearly different for non-digit characters in the last position. But the digits start at code point 48, so taking those mod 10 will shift them left cyclically and hence the last character is always changed.

Japt, 4 bytes
®c v

Try it online!
Explanation:
®c v
®    At each char:
 c     Convert to its ASCII value
   v   Return 1 if divisible by 2, otherwise return 0

Cubix, 10 bytes
..@|i?2%)O

Try it online! or Watch it run!
For each char, prints 1 if the char has an even code point, 2 otherwise; 1 has an odd code point and 2 an even, so the output will never equal the input.
Explanation
This code corresponds to the following cube net:
    . .
    @ |
i ? 2 % ) O . .
. . . . . . . .
    . .
    . .

The IP (instruction pointer) starts at the top-left corner of the far-left face, heading east. It follows this series of instructions:
i     Grab a char-code from STDIN and push it to the stack (-1 if there is no more input).
?     If the top item is negative, turn left and hit @ which ends the program.
      If it's positive (any printable ASCII char), turn right. The IP runs through a bunch
        of no-ops, then hits:
)     Increment the top item.
|     Mirror the IP's direction horizontally (turns it around).
)     Increment the top item again. The IP then wraps around again until it hits:
?     The top item is positive, so turn right.
2     Push a 2 to the stack.
%     Push the modulus of the top two items (0 for even char-code, 1 for odd).
)     Increment the result (now 1 for even char-code, 2 for odd).
O     Output as a number. The IP wraps back around to the i and the process starts again.

Alice, 9 bytes
#oi/
t i@

Try it online!
Explanation
The idea was taken from Martin Ender's CJam submission.  The first character is taken as a code point, reduced mod 10, and moved to the end of the output.  Since exactly one character was changed, permuting the characters cannot result in getting the same string back.
#   skip next command
o   (skipped)
i   push first byte onto stack
    STACK: [97]
/   reflect to SE, switch to ordinal mode (implicit reflect to SW)
i   push remaining input onto stack as string (implicit reflect to NW)
    STACK: [97, "sdf"]
o   output top of stack (implicit reflect to SW)
    STACK: [97]
t   implicitly convert code point to decimal string, and extract last character
    (implicit reflect to NE)
    STACK: ["9", "7"]
o   output this last digit (implicit reflect to SE)
i   push empty string, since there is no more input to take (implicit reflect to NE)
/   reflect to S, switch to cardinal mode
@   terminate

Using t for mod 10 is really clever, nice. :)

Pushy, 1 byte
Q

Try it online!
This converts the given string into list of ASCII character codes, indexes them (modular indexing) into the uppercase alphabet, then prints the result. Essentially, each character n is mapped to chr(ord(n) % 26 + 65). You can use this program to see how the mapping works.
The output:

Will always be the same length as the input, as the characters are directly mapped into new ones.
Will always comprise only printable ASCII characters (as it only contains uppercase letters)
Will always be different to the input, as there is no possible input character n such that chr(ord(n) % 26 + 65) == n, as for this to be true there must be an integer x such that 26x = 65, for which there is no solution.

1 byte
q

Try it online!
This answer is exactly the same, except that it maps to lowercase alphabet characters rather than uppercase alphabet characters. This is still valid as there is no possible input character n such that chr(ord(n) % 26 + 97) == n.

R, 40 bytes
function(s)substr(shQuote(s),1,nchar(s))
This uses the shell quoting function shQuote to place appropriate quotes around a string and escape quotes within the string (similar to @xnor's answer).  Then take a substring that's as long as the original string (because the string might have multiple escaped characters, we need to take a substring of the correct length, so we can't just use substring(...,3)).  sQuote is shorter, but converts ‘ to ‘‘’.
Another approach, using more 'core' R stuff is 46 bytes:
function(s)sub(".",letters[grepl("^a",s)+1],s)
Substitute the first character with 'a', unless it is 'a', then substitute it for 'b'.  sub only substitutes the first match, so we don't need ^.  letters is constant and a slightly shorter way of doing c("a","b").  grepl returns a boolean, and adding 1 converts it to a number that indexes letters.  The ^ is needed to correctly convert "ba".
Code to test
x = function(s)substr(shQuote(s),1,nchar(s))

test = function(t){
  t2 = x(t)
  t2!=t & nchar(t)==nchar(t2)
}

testStrings = c("a","b","ab","ba","aa",
                "'","'\"","\\\\",'"','""',
                '‘','’',"~","asdf",
                "1111","       ","~~~~~","abcba",
                "1"," ","~"," ~","~ ","  0",
                "!@#$%^&*()ABCDEFGhijklmnop1234567890",
                " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~")

all(sapply(testStrings,test))

Welcome to PPCG! This answer is not, at the moment, valid, because it assumes input is given as a hard-coded variable s. You can either submit this as an anonymous function, function(s)substr(shQuote(s),1,nchar(s)), or take input via scan(,""), readLines() or similar. I've upvoted this to give you enough rep to post in the R golfing chatroom; feel free to ping me there if you have any questions! This is a very well-explained answer :)

@Giuseppe A ha, thanks! I've edited the answer.

Brain-Flak, 53 bytes
Includes +1 for -c
([(((()()()()){}){}){}()]({}())){{}(<({}[()()])>)}{}

This will decrement the first character unless it is a space, in that case it will increment the first character.
Try it online!
([(((()()()()){}){}){}()]      )                     # Push: input + 1 != 33 on top of...
                         ({}())                      #    input + 1
                                {{}(<          >)}{} # If (input + 1 != 33)
                                     ({}[()()])      #   Push: (input + 1) - 2

PHP<7.1, 31 Bytes
for(;~$c=$argn[$i++];)echo$c^1;

Try it online!

@CalculatorFeline "1"=>0, "10"=>01, "101"=>010 Where fails it?

for(;a&$c=$argn[$i++];)echo$c^"\1"; btw this has different output but also works.

@Christoph Take this as your own approach and I can upvote it

I'm trying to make an answer without loop. If I fail I might post it :)

I did it 30 bytes.

@Christoph I have improve you idea

Yeah I saw it sadly it doesn't work for my own approach because "101"^1 would be 100 while "101"^"\1" is "0".

PHP 7.1 yields A non-numeric value encountered. And You can use ~ instead of a&.

@Christoph ^"\1" fails for ~ in the input; ^"1" would fail for N. That´d better be "\2", "\4" or "\8".

@Titus I have added the PHP Version must be under 7.1 . Thank You

Jelly, 4 bytes
^1Ṿ€

Outputs a digit string. No output character will be equal to the corresponding input character.
Try it online!
How it works
^1Ṿ€  Main link. Argument: s (string)

^1    XOR each character c in with 1.
      This attempts to cast c to int, mapping '0', ..., '9' to 0, ..., 9.
      For non-digits, the attempt fails, mapping c to 0.
      After XORing with 1, we get 1, 0, 3, 2, 5, 4, 7, 6, 9, 8 for '0', ..., '9',
      and 1 for all non-digits.
  Ṿ€  Uneval each; mapping 0, ..., 9 to '0', ..., '9'. This yields a character
      array, which is Jelly's string type.
      Note that no character is mapped to itself.

PHP, 30 27
<?=strtr($a=$argn,$a,$a^1);

Changes every each char equal to the first char with the char that has the least significant bit flipped.

Does "~" work?.

It doesn't actually flip the least significant bit of the first char; it converts it to an integer and flips the least significant bit of that. So yes, @CalculatorFeline, ~ does work, outputting 1.

Oh. Does !$a or ~$a work?

@ETHproductions I did the last edit shortly before going to bed and didn't have the time to update it. Of course your right it first converts to integer and therefore might not even change the first char but maybe the second e.g. "12" becomes "13".

@CalculatorFeline sadly both fail !$a turns "12" into "12" because false is converted to an empty string so that nothing gets replaced and ~$a turns everything into unprintables because ~"12" doesn't convert to int first but literally flips all bits in the string.

Ruby, 20+1 = 21 bytes
Uses the -p flag.
sub(/./){$&=~/1/||1}

Try it online!
Replaces the first character in the input with a 0 if it is 1, or 1 otherwise.

Brachylog, 9 bytes
{¬Ṣ|∧Ịh}ᵐ

Try it online!
Explanation
This replaces all chars by a space, except spaces which it replaces with "0".
{      }ᵐ      Map on each char of the Input
 ¬Ṣ              The Input char is not " ", and the Output char is " "
   |             Or
    ∧Ịh          The Output char is "0"

Golfscript, 3 bytes
Try it online!
)5%

Take the last character's ASCII value modulo 5, and replace the last character with the result. This obviously works for non-digit characters, but if the last character is a digit, it also changes ("0" mod 5 = 3, "1" mod 5 = 4, etc).
This would also work with 7 or 9 while still keeping the same length.
Also, yay! I have a Golfscript solution as good as the best solutions here!

Funky, 26 22 bytes
s=>s::gsub("."a=>1&~a)

Calculates ~a which for non-digits will return NaN. Then 1& limits it to either 0 or 1, for the digit 0, this will be 1, and for 1 this will be 0. So this string is always unique.
Try it online!

C/C++, 29 bytes
void m(char*s){(*s%=26)+=65;}

Code to test :
#include <iostream>
#include <string>
#include <cassert>

#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif

void m(char*s){(*s%=26)+=65;}

int main() {
    std::initializer_list<std::string> test{
        "asdf",
        "1111",
        "       ",
        "~~~~~",
        "abcba",
        "1",
        " ",
        "~",
        " ~",
        "~ ",
        "  0",
        "!@#$%^&*()ABCDEFGhijklmnop1234567890",
        " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
    };

    for (auto&a : test) {
        char* t = new char[a.size() + 1];
        std::strcpy(t, a.c_str());
        m(t);
        assert(a != t);
        std::cout << a << " => " << t << '\n';
        delete[] t;
    }
}

brainfuck, 35 27 bytes
Edit: switched to a better way of generating an odd number thanks to the brainfuck constants page
,[[[>]+<[-<]>]-[>+<---]>.,]

Try It Online
Prints out a string of semi-random Vs and Us. If the first character of the input is a V it will print out a U instead and vice versa.
How it Works
,[ Gets first inputted char
  [[>]+<[-<]>] Converts the ASCII value to binary
  -[>+<---] Adds 85 to the last digit of that binary, which is the original value mod 2.
            This converts a V (value 86) into a U (value 85) and vice versa
  >. Print the value
,] Get a new value and repeat.
   Note that the binary of the previous value is still in memory,
     so it no longer prints specific chars for odd or even values

Another version with the same bytecount:
,[[>]+<[-<]>]-[>+<---]>[.,]

Only changes the first character to a V or a U, but doesn’t handle empty input (which is still valid)

Great algorithm--it's tricky to find short algorithms to do things in BF. Don't think the second one works though; shouldn't the last bit be [.,]?

Brain-Flak, 42 bytes
({}[((((()()()()){}){}){})]<>){{}}([]<>{})

Try it online!
Replaces the first character of the string with a space, or a ! if the first character is already a space.

Perl 6, 14 bytes
{.ord%7~.chop}

Try it online!
Bare block, implicit lambda with input $_. The ordinal of the first character .ord modulo 7 is a different character: Non-numeric first character becomes numeric, numeric first characters map to a different character. If we append the input sans the last character (~ $_.chop), we match the length. It can never match the input because the first character never matches.
 Perl 6, 15 bytes
{S/./{.ord%7}/}

Performs S/// substitution (which returns the result of substituting on $_), matching . (any character) once, and replacing it with the ordinal of the first character in $_ - the same character - modulo 7. Non-numeric first character becomes numeric, numeric first characters map to a different character.
Try it online!

str, 2 bytes
XV

Try it online!
Explanation
XV
       over each character:
X         increment it  ("~" becomes "\x7f" and "@" becomes "A")
 V        wrap to printable ascii ("\x7f" becomes " ")

Alternatively, YV to decrement instead of increment.

PowerShell, 37 26 bytes
Thanks Mazzy for -11 bytes

-join($args|% t*y|%{$_%9})

Try it online!
Does alright. Uses the ToCharArray trick to save some bytes. Through a conversion chain, mods the ASCII value of each character by 9 then joins up the value.

? 6+3*($_-eq6)

? $_%9 :)))))

><>, 11 bytes
i:0(?;'0'=n

Try it online!
Explanation
Like my MATL answer, this transforms character '0' into '1' and all other characters into '0'.
i       Input one char, or push -1 if there aren't any more chars
:       Duplicate
0(      Is it less than 0?
?;      If so, end program. Else:
'0'     Push character '0'
=       Is it equal? Gives 1 or 0
n       Output as a number. Go back to the beginning

9 bytes if you just print the number modulo 5

@JoKing Thanks! But U think you should post that as a separate answer

JavaScript (ES6), 24 bytes

f=
s=>s.replace(/./,s[0]^1)
<input oninput=o.textContent=f(this.value)><pre id=o>

Changes the first character of the string according to this table:
1   0
2   3
3   2
4   5
5   4
6   7
7   6
8   9
9   8

Everything else becomes 1.

@RickHitchcock As I understand it, only one character needs to be different.

@RickHitchcock The very first rule states that the string can be assumed to only contain printable characters...

Head-slap, +1!!

Chip, 5 bytes
g*A~a

Try it online!
Maps all characters to either @ or A, so that the lowest bit always differs from the input:
0, @, ~, etc. map to A
1, a, A, etc. map to @

x86 Assembly, 19 bytes
Alternates the first character of the string between '@' and 'A'
_diffstr:
  00000000: 8B 54 24 04        mov         edx,dword ptr [esp+4]
  00000004: 8A 02              mov         al,byte ptr [edx]
  00000006: 3C 41              cmp         al,41h
  00000008: 75 04              jne         0000000E
  0000000A: B0 40              mov         al,40h
  0000000C: EB 02              jmp         00000010
  0000000E: B0 41              mov         al,41h
  00000010: 88 02              mov         byte ptr [edx],al
  00000012: C3                 ret

Perl 5, 49 bytes
sub{$_="a"x length $_[0];$_++while $_ eq$_[0];$_}

Explanation:

starts with string of letter "a" as long as input
keeps incrementing that until it's different from input

Starting from "a"s was to avoid incrementing to point where Perl lengthens the string; with only one strings to avoid being same as, it couldn't overflow.
This is shamelessly cribbed (and simplified) from my answer to the "related" problem "The Third String".
Execute with:
perl -e '$s = ' -E 'sub{$_="a"x length $_[0];$_++while $_ eq$_[0];$_}' -E ';say $s->("z")'

How can it need to increment more than once?

x86 opcode, 6 bytes
    and     byte [ecx], 0xF1
    inc     byte [ecx]
    ret

Julia 0.6, 26 bytes
s->map(x->x<'b'?'b':'a',s)

Try it online!

Java 8, 39 38 bytes
s->(s.charAt(0)<49?9:0)+s.substring(1)

Try it online.
Explanation:
If the first character has a unicode value below 49 (space, or one of !"#$%&'()*+'-./0), change it to a '9', else change it to a '0'.
s->                 // Method with String as both parameter and return-type
  (s.charAt(0)<49?  //  If the first character has a unicode value below 49:
    9               //   Change the first character to a '9'
  :                 //  Else
   0)               //   Change the first character to a '0'
  +s.substring(1)   //  And return the rest of the input-String (if any)

Python 3, 29 26 bytes
lambda s:'a~'[s<'~']+s[1:]

Try it online!

Replacing first character with ~, if the first character is ~ already, it is replaced by a.

Pyth, 9 bytes
*h-+QGhQl

Try it here
Explanation
*h-+QGhQl
   +QG      Stick the alphabet to the end of the input.
  -   hQ    Delete all instances of the first character.
 h          Take the first remaining character.
*       lQ  Multiply by the length of the (implicit) input.

SmileBASIC, 27 25 bytes
DEF D S
S[0]=@1[S>"2"]END

Creates a function named D that is called like:
STRING$="abcde"
D STRING$
'STRING$ is now "1bcde"

The first character is replaced with either @ or 1

Gol><>, 6 bytes
iE;5%n

Try it online!
Direct translation of Jo King's ><> answer.

C (gcc), 22 bytes
f(char*s){*s=~1&*s^2;}

Try it online!

MAWP, 11 bytes
0|[!5P5WA:]

Idea from Jo King's answer.
Prints the ASCII value of each letter modulo 5.
Try it!

Husk, 6 bytes
ṁ(s%5c

Try it online!
Port of Jo King's answer - upvote it!
Outputs ASCII values MOD 5.

@Zgarb @Leo I wanted to also submit a (2-byte longer) version using the documented 'if2' usage of ? to make a bijection: m?→'~=' , but it doesn't seem to infer...  any insight why not?

You need to mention them on a thread they already commented on (or alternatively, one of their answers)

@Razetime: Ok - thanks - finally starting to understand how to 'ping' now...

Vyxal, 3 bytes
C∷ṅ

Try it Online!
05AB1E port, go read that.

APL (Dyalog Extended), 11 8 bytes
∊⍕¨'0'=⎕

Try it online!
-3 thanks to @Adám
Explanation
∊⍕¨'0'=⎕
   '0'=⎕        For each character: 1 if it's '0', 0 otherwise
 ⍕¨             Convert each to string
∊               Flatten into a single string

~2|⎕UCS can be written as '0'=

@Adám thanks, updated.

Perl 6,  48  28 bytes
{(->{[~] (' '..'~').roll(.chars)}...*ne$_).tail}

Generates a sequence of random strings, stopping when one of them doesn't match the input. Returns the last string produced
Test it
{first *ne$_,(0,1 Xx.chars)}

Generates two strings one consisting of only 0s, the other of 1s. Returns the first that is not stringwise equal to (ne) the input ($_).
Test it
Expanded
{             # bare block lambda with implicit parameter ｢$_｣

  first       # return the first value where the following is true

    * ne $_,  # WhateverCode lambda ( ｢*｣ is the parameter )

    (
      0, 1    # list of 0 and 1
      X[x]    # cross ｢X｣ that using the string repetition operator ｢x｣
      .chars  # with the number of characters in ｢$_｣
    )
}

Convex, 4 bytes
'0f=

Try it online!

This appears to fail (on TIO, at least) if the input is purely numeric: RuntimeException: Long Character f= not implemented

Aceto, 16 12 9 bytes
=01`
,'pO

Run with -F to see immediate output (but works without).
Explanation:
We read a character, then push the character 0 on the stack and test for equality:
=0
,'

If equal, we push a 1.
  1`

We now print the top element (either a one or an implicit zero), and go back to the start:
  pO

This prints zeroes for any characters that aren't zeroes, and ones for zeroes, e.g.:
Input  |  Output
----------------
abcde  |  00000
11111  |  00000
10010  |  01101

Charcoal, 8 bytes
ＦＳＩＸ⁰⁼ι1

Try it online! Link is to verbose version of code. Works by comparing each character to 1, then taking the result as the exponent of zero, then converting to string. This results in an output 0 for each 1 in the input and a 1 for each other character. Edit: Changes in Charcoal now mean that I can directly cast the result of Equals saving 2 bytes: ＦＳＩ⁼ι0 Try it online! Link is to verbose version of code. Edit: Actually there was a 6-byte solution all along: ＦＳ§α℅ι Try it online! Link is to verbose version of code. Port of @FlipTack's Pushy answer. (Also works with lower case of course.)

Braingolf, 12 bytes
.#~e1-:1+|&@

Subtracts 1 from the last char's ordinal if it is a tilde, otherwise adds one.
Explanation:
.#~e1-:1+|&@  Implicit input of string, convert each char to ordinal and push to stack
.             Duplicate last item
 #~           Push tilde ordinal
   e          If last 2 items are equal (consumes last 2 items)
    1-        ..then subtract one
      :       else
       1+     ..add one
         |    endif
          &@  Print entire stack as chars

C#, 46 bytes
_=>(char)(_[0]>32?_[0]-1:_[0]+1)+_.Remove(0,1)

Changes first letter to next to previous letter on ASCII table unless it is the first letter, in which case it takes the next one.

SAS, 34
substr(s,1,1)=ifc(s=:'z','a','z');

If the first character of the string s is z, change it to a, otherwise change it to z. Rubbish compared to the proper golfing languages, but at least it beats C#!

T-SQL, 45 bytes
SELECT STUFF(S,1,1,CHAR(ASCII(S)%7+48))FROM t

Takes input from pre-existing table t with VARCHAR field S, per our IO standards.
Modifies the first character by taking the remainder MOD 7 of the ASCII value, then converting that back into a digit between 0 and 6. But ASCII(0)=48, which is 6 MOD 7, so the first character never maps back onto itself.

Cubically, 23 bytes
(~-61/1=7&6:7>4?6@4!@5)

Converts the string into $s and -s.

Implicit, 15 14 bytes
'_._` !{+32}*-

Found about 10 interpreter bugs writing this. Try it online!
'_._` !{+32}*-
'                « read string                              »;
 _               « push last char onto stack                »;
  .              « increment                                »;
   _`            « mod by 127 (the "` " evaluates to 127)   »;
      !{...}     « if falsy (char was ~)                    »;
        +32      «  add 32 (make it a space)                »;
            *    « stick char at beginning of string        »;
             -   « pop last char off string                 »;

BrainFuck, 49 47 Bytes
,>++++[-<-------->]++[<]++++[->++++++++<]>-[.,]
x           0   (x-32) 2                (x-32||2)+31
^           ^(x>32) ^(x==32)

Assuming EOF as zero

You can cut out the first set of ., and just go straight into the loop

Thanks

Perl 5, 23 + 1 (-p) = 24 bytes
s/./chr 65+ord($&)%26/e

Try it online!
Blatantly steals @FlipTack's method to change the first character to a different upper case letter.

You can drop one of the digits in 26, at least.

Swift 3, 76 68 bytes
let s=readLine()!;print(s.characters.map{$0=="a" ?"b":"a"}.joined())

Try it online!

Fortran (GFortran), 77 bytes
CHARACTER(256)A
READ*,A
A(1:1)=CHAR(MOD(IACHAR(A(1:1))+1,94)+33)
PRINT*,A
END

Try it online!
It does what was required... well, with some issues...
1) If the first character is "or <space>, they will be ignored;
2) If there is /, it will be understood as something like "end of transmission";
3) There will be a leading space (which is not part of the output (so do I think), because Fortran always prints a leading space if the output is not formated) and up to 255 trailing spaces. This last problem (i.e., the trailing spaces) can be solved using no more then six bytes.

SNOBOL4 (CSNOBOL4), 71 bytes
	INPUT LEN(1) . X REM . S
	X =IDENT(X) 1	:S(O)
	X =0
O	OUTPUT =X S
END

Try it online!
Replaces the first character of S with a 0 unless it's already, 0 in which case it swaps it with 1.

Pyth, 12 bytes
+C+%ChQlG32t

Test suite
Python 3 translation:
Q=eval(input())
print(chr(ord(Q[0])%26+32)+Q[1:])

Tcl, 56 bytes
proc C s {join [lmap x [split $s ""] {expr {$x==0}}] ""}

Try it online!
Approach very similar to last one: replaces every non-zero by a zero and every zero by one.

Tcl, 62 bytes
proc C s {puts [expr {[string in $s 0]==0}][string ra $s 1 e]}

Try it online!
Approach replaces first character by 1 if it is a 0, else it replaces anything else by a 0.

Tcl, 83 bytes
proc C s {scan [string in $s 0] %c f
puts "[format %c [incr f]][string ra $s 1 e]"}

Try it online!

naz, 36 bytes
2a2x1v1x1f1r3x1v2e5p1o1f0x1x2f0a0x1f

Works for any input string terminated with the control character STX (U+0002).
Explanation (with 0x commands removed)
2a2x1v             # Set variable 1 equal to 2
1x1f               # Function 1
    1r             # Read a byte of input
      3x1v2e       # Jump to function 2 if it equals variable 1
            5p1o   # Otherwise, output it modulo 5
                1f # Jump back to the start of function 1
1x2f               # Function 2
    0a             # Add 0 to the register
1f                 # Call function 1

Thunno J, \$ 5 \log_{256}(96) \approx \$ 4.12 bytes
O2%1_

Attempt This Online!
Port of Riley's 05AB1E answer.
Explanation
O2%1_  # Implicit input
O      # Ordinals of input
 2%    # Mod 2 (vectorised)
   1_  # Not (vectorised)
       # J flag joins the list
       # Implicit output

MathGolf, 4 bytes
É1░¡

Converts 1 to 0 and every other character to 1.
Try it online.
Explanation:
É     # Foreach over each character of the (implicit) input-string,
      # using 3 characters as inner code-block:
 1░   #  Push 1, and convert it to a string: "1"
   ¡  #  Check whether it's NOT equal to the current character
      # (after which the entire stack is joined together and output implicitly)

Thunno 2 JB, 1 byte
E

Attempt This Online!
Thunno 2, 3 bytes
CEJ

Attempt This Online!
Port of Riley's 05AB1E answer. Converts to charcodes and checks if even. Then, joins the resulting list.

(,) N, 116 108 Chars or \$108\log_{256}(3)\approx21.4\$ Bytes
((),()()()()()()())(,,,,(()(),((()()())))(()(),(),(),,(()()),()((),,,,(),,(())))(()(),(),()(),,(()()),()()))

Try It Online!
Or, without flags, for 138 chars or 27.34 Bytes
((),()()()()()()()()()())(,,,,(()(),((()()())))(()(),(),,(())(())(())()(),(()()),(())(())(())(()))(()(),(),,(())(())(())(()),(()()),()()))

Try It Online!
Basically, it outputs 1 (with flags) or \32 (without flags) if the char code is greater than or equal to that of \50 (with flags) or
\40 (without flags), and outputs 2 (with flags) or \40 (without flags) otherwise.
The reason 1 and 2 are written as 1 and 2 rather than as \49 and \50 is because they are outputted numerically, hence the need for the N flag to remove seperators. All others are encoded in the code by char code.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/