text:
Line editor (more text here)
In the misty years of yore, when fanfold terminals walked the earth, there lived a strange creature. Oddly crippled and yet oddly powerful, the line editor teemed across the programming landscape in untold numbers; covering the earth as far as the eye could see.
Now it is fallen on hard times. That vast population hunted, hounded, and driven to the brink of extinction. Only a few specimens remain, most in cramped and unembelished cages in the less enlightened kind of zoo, though a few stuffed and mounted examples can be seen in backwater museums. Oh, and there is ed.
Frankenstein-like, we shall resurrect the noble beast!
Commands
Our editor is fairly minimal and will support the following commands
Focus moving commands

<number>[,<number>] -- move the focus to the stated line and if the second argument is given to the state column. Excessive line number gets the last line. Excessive column number gets the end of the line.
,<number> -- move to column number on the current line
e -- move the focus to the end of the file but do not begin a new line.
b -- move the focus to the beginning of the file.

Informational commands

L -- Echo the current context. The five lines centered on the current line are printed. All five lines are indented by one character; the current line is marked with a ">", the others with a " ". Under these lines another line is printed consisting entirely of spaces except for a "^" in the current column (a total of six lines are printed).
l -- echo the current line
p [[<start>],[<end>]] -- Print the file from starting to ending address. These value default to 1 and 0 (the end of the file).

File altering commands

A [<text>] -- Move to the line beyond the end of the file (that is begin a new line) and (possibly) append text.
<return> (alone) -- Insert a newline. Thus a <return> <return> inserts a newline after the current one.
r <text> -- replaces everything from the focus to the end of the line with text.
i [<text>] -- inserts text followed by by newline at the current focus. Any portion of this line beyond the focus ends up on the next line.
I <text> -- inserts text at the current focus, preserving the rest of the line. Focus remains on this line.
d -- Delete the contents of the current line or if the current line is already empty, remove the line.
j -- join this line to the next

Of this last group the first four end with the focus moving to the next line, while I preserves the focus at the end of the added text. When deleting or joining focus remains at the same line and column number.
The Interpretation of line numbers in commands
Number beginning with '+' or '-' are interpreted as offsets from the current line number. Numbers without a sign are interpreted as absolute line numbers, except that '0' means the last line of the file.
Prompt and interaction
The editor functions as a shell, and the prompt has the form <line>','<column>'>' where line is the line number except that "end" is used when the focus is at the last character of the file.
Each command is accepted only when the user presses newline. And takes affect.
Readline support is allowed but not required.
No feedback is provided except the changing values of  and  in the prompt, unless explicitly stated in the commands description.
Scoring
This is code-golf, so the shortest answer in each language wins.
Special thanks to dmkee for making this in sandbox where I adopted it.

Sandbox

What if there are less than 5 lines and L is called?

@HyperNeutrino Everything borks

Actually you just A. Error. B do what you can with what you have, C do nothing, Choose any

Hello, I downvoted this challenge because personally I find it to not be extremely well defined, to not be extremely interesting, and also to have quite strict runtime requirements. For example, many languages are not able to perform I/O in that manner, such as almost all golfing languages. Additionally, the format for the entire challenge makes me wonder if this was designed to be good for a specific programming language. If you can explain to me why this challenge is especially interesting with these I/O requirements, I will gladly revert my downvote.

@HyperNeutrino I personally don't think a challenge is bad because golfing languages can't participate, but that's just my personal opinion, take it as you will. Also can you elaborate on the runtime requirements? I don't see anything pertaining to runtime in the question description

@HyperNeutrino Are you referring to the requirement that it be a REPL requiring reading from STDIN and writing to STDOUT in a loop?  Do you have a suggestion on how to fix this challenge?

@musicman523 I don't necessarily think that either; I was going more for the other points. Maybe I shouldn't have said that.

@JerryJeremiah My suggestion is to take a list of the commands and return the final result, or even just execute each step and print each result individually (because of L and l).

regarding p command what's an address? line number? byte offset?

@HyperNeutrino If you had issues you have had several years to raise them in sandbox.

@Christopher You say "several years" which seems to imply that it's a very old sandbox post. I wouldn't have seen it then because I only review things that are linked in chat by our Feeds. If you had linked it along for final feedback before posting I would have been glad to give feedback. Anyway, I see you have added some edits and I think it's significantly better now so if you edit it just to unlock my vote, I will upvote this challenge now also that I've taken a closer look at it. thanks :)

(    by the way, I did a blank edit so I could revert my downvote and upvote, in case you were wondering about the edit :)    )

I feel a gif showing the functionality of the line editor would be very useful.

@KritixiLithos yeah but I would have to make an answer first :/

@HyperNeutrino thanks that makes sense

@HyperNeutrino I don't know all that many golfing languages, but Pyth is perfectly capable of handling input in this way, and many golfing languages are able to call out to specialized functions at a high byte cost.

-1 because it would've been simple enough to have the program take a file and a list of commands, without requiring it to be an interactive shell.

@mbomb007 so you want your text editor to be not interactive? This challenge is based on real stuff.

"Based on real stuff" != "real stuff"

@mbomb007 but this is a actual piece of code that could be used irl. So practical language work better

Nothing about code-golf is practical.

I had the weird idea to implement this in 6502 assembly for a C64 :D Not sure whether I'll get somewhere, but the relation (old-fashioned tool for old-fashioned machine) is somehow funny. Won't be the greatest byte-count though ;)

@FelixPalmen if you do that that would be great

Hmm, 3767 bytes so far (in form of a BASIC loader, the pure machine program is 979 bytes, but that wouldn't count for golf g). prompt, command line parsing, the A command and movement commands implemented. This seems to work so far ;)

@FelixPalmen do it do it!

C (gcc), 1288 1212 1188 1171 1146 bytes
#define P printf(
#define A case
#define B break
#define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];}
#define R(m,o){return b<1|b>m?m o:b;}
#define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j)
r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];D(){L(r,>y,,-1,--)r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;c[y++]=strlen(l[o]);x=1;}U(){strcat(*L,l[y]);*C=strlen(*L);L(y+1,<r,-1,,++)--r;*l[r]=c[r]=0;}X(b)R(c[y-1],+1)Y(b)R(r,)main(){for(;;){z=i=y;L=l+--z;C=c+z;j=x;!r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);scanf("%[^\n]%*c",a)?a[2]*=!!a[1],N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:(*a=D(),scanf("%*c"));switch(*a){A'e':y=r;x=c[r-1]+1;B;A'b':y=1;x=1;B;A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ':'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;A'l':puts(*L);B;A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;A'i':D();--y;x=X(0);A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;A'j':y<r&&U();}}}

Demo
First time trying to do something like this, so there are probably some missed opportunities for making it smaller. (Thanks Jerry Jeremiah for pointing out some)
Here's a (slightly) more readable version:
// often used functions/keywords:
#define P printf(
#define A case
#define B break

// loops for copying rows upwards/downwards are similar -> macro
#define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];}

// range check for rows/columns is similar -> macro
#define R(m,o){return b<1|b>m?m o:b;}

// checking for numerical input is needed twice (move and print command):
#define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j)

// room for 999 rows with each 999 cols (not specified, should be enough)
// also declare "current line pointers" (*L for data, *C for line length),
// an input buffer (a) and scratch variables
r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];

// move rows down from current cursor position
D()
{
    L(r,>y,,-1,--)
    r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;
    c[y++]=strlen(l[o]);
    x=1;
}

// move rows up, appending uppermost to current line
U()
{
    strcat(*L,l[y]);
    *C=strlen(*L);
    L(y+1,<r,-1,,++)
    --r;
    *l[r]=c[r]=0;
}

// normalize positions, treat 0 as max
X(b)R(c[y-1],+1)
Y(b)R(r,)

main()
{
    for(;;)
    {
        // initialize z as current line index, the current line pointers,
        // i and j for default values of positioning
        z=i=y;L=l+--z;C=c+z;j=x;

        // prompt:
        !r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);

        // read a line of input (using scanf so we don't need an include)
        scanf("%[^\n]%*c",a)?

        // no command arguments -> make check easier:
        a[2]*=!!a[1],

        // numerical input -> have move command:
        // calculate new coordinates, checking for "relative"
        N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:

        // check for empty input, read single newline and perform <return> command:
        (*a=D(),scanf("%*c"));

        switch(*a)
        {
            A'e':y=r;x=c[r-1]+1;B;
            A'b':y=1;x=1;B;
            A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ':'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;
            A'l':puts(*L);B;
            A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;
            A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;
            A'i':D();--y;x=X(0);
            // Commands i and r are very similar -> fall through from i to r
            // after moving rows down and setting position at end of line:
            A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;
            A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;
            A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;
            A'j':y<r&&U();
        }
    }
}

This challenge leaves quite a lot of corner cases to explore -- I guess I fixed all bugs by now, but if somebody finds one more, please comment. Regarding the revisions, I removed byte counts for earlier versions that contained subtle bugs.

In the part of D after the loop, I think you can save bytes by replacing the references to o-1 and o with o ,--o, o, o, ++o. Also, you can do similar things with x in the same area.

@CalculatorFeline thanks for the hint, I have to check. I think a --o for the first o-1 here would be UB because it's unsequenced with another access of o :(

UB is allowed. Also, try this.

@CalculatorFeline sure, I thought so, just these sequencing issues might change even between compiler versions :o should I just add an explicit version? And for your link, thanks, but I don't think it supports interactive programs?

Unfortunately not. However, you can use prespecified sequences of input. May be convenient for testing.

in c global variables default to int so you should be able to change int r,v,n,i,j,k,n,o,z,x=1,y=1; to just r,v,n,i,j,k,n,o,z,x=1,y=1;

r,v,n,i,j,k,n,o,z,x=1,y=1; contains n twice.

Wow, stupit glitch, thanks

Hehe, so far I mostly focused on implementing the logic in a "clever" way .. these are good ideas, thank you! (and give me some time to improve this solution please)

And I don't think you need a space between your macro-function names and their definitions.

@ZacharyT indeed, thanks! With some other things I just spotted, another 17 bytes saved :)

Also, #define P printf => #define P printf( and change all P's accordingly.

There are some #defines you can make to get rid of duplication and make it shorter. One is #define Z b){return(b<1||b and another is #define W(t,u,v,w)for(o=t;o u;){strcpy(l[o v].d,l[o w].d);l[o v].c=l[ replaced with W(r,>y,,-1) and W(y+1,<r,-1,)

AWK, 747 807 829 807 bytes
func d(D){if(D>0){for(;D<NR;)f[D++]=f[D+1];NR--}else{for(c=NR;x>-D;x--)f[x+1]=f[x];NR++}}
{f[r=NR]=$0}
END{while(1){printf"%s,%d>",r==NR?"end":r,c
getline v<"-"
split("  >  ",l,"")
if(v=="e")r=NR
if(v=="b")r=1
if(v=="L"){for(i=-2;i<3;i++)print l[i+3] f[r+i];printf"%"c+1"s\n","^"}if(v=="l")print f[r]
if(v=="d")z=f[r]=""?d(r):f[r]=""
if(v=="j"){f[r]=f[r] f[r+1];d(r+1)}
S=index(v," ")
z=S?substr(v,S+1):v
a=substr(v,1,1)
n=split(z,N,",")
x=N[1]~/[-+].*/?r+N[1]:N[1]
y=N[2]~/[-+].*/?c+N[2]:N[2]
if(!S&&v~/[0-9+-,]+.*/){r=x?x>NR?NR:x:x=="0"?NR:r
C=length(f[r])
c=n>1?y>C?C:y:c}
if(a=="p")for(i=x?x:1;i<=(y?y:NR);)print f[i++]
if(a=="r"||a=="i"||a=="I"){k=substr(f[r],c)
if(a=="i"){if(c<length(f[r])){d(-r-1);f[r+1]=k}f[r]=substr(f[r],1,c) z (a=="I"?k:"")}if(a="a"||a=="A"){if(a=="A")r=NR;r=r+1;d(r);f[r]=z}}}}

Try it online!
Removing the elses makes the lines a bit shorter/readable but the cursor assignment is a bit more complicated.
Just for giggles, I created a version to add a bit more "functionality":
q quits the program
w <outfile[defaults to input file]> writes the changes.
Try it online!

Not getting a caret for column position with L command here...

Ah. I didn't see that requirement. Thanks for finding that @FelixPalmen

Working now! I also see some requirements interpreted differently from my solution, maybe the challenge should be more precise here...

Which ones? Perhaps some things are open to interpretation?

my character-index in a line is 1-based, you use 0-based. EOF position in my program is one after the last character of the last line, in your program its the first character of the line after the last line. My prompt shows only end> at the EOF position, yours shows end,[col]> in the last line. both aren't exactly what is specified I guess ...

Those were definitely left out of the spec.  Perhaps that was to on purpose to allow for simplifications in different languages?

I can't believe I forgot to include a write command when I first spec this thing. Good call.

6502 Assembly (C64, BASIC loader), 5761 5352 bytes
0fOa=49152to50573:rEb:pOa,b:nE:sY49152
1dA162,54,134,1,162,1,134,7,134,8,202,142,0,96,134,251,162,96,134,21,162,128
2dA142,145,2,162,23,142,24,208,166,8,169,0,160,253,32,98,194,32,126,195,32,173
3dA195,166,2,240,103,202,202,16,2,162,0,142,160,191,173,162,191,201,69,240,93
4dA201,66,240,95,201,204,240,97,201,76,240,96,201,80,240,100,201,193,240,99,201
5dA73,240,123,201,82,240,122,201,201,240,121,201,68,240,123,201,74,240,122,162
6dA0,32,108,196,165,34,166,251,32,81,194,201,255,240,10,133,8,170,169,0,160,253
7dA32,98,194,160,0,177,253,170,232,165,35,201,255,208,2,165,7,32,81,194,133,7
8dA16,134,32,156,194,76,30,192,169,0,133,35,240,204,169,1,133,35,208,198,76,76
9dA193,166,8,32,198,193,76,30,192,76,233,192,166,251,232,134,251,134,8,169,0
10dA160,253,32,98,194,169,0,168,145,253,200,132,7,32,244,193,76,30,192,76,153
11dA193,76,178,193,32,244,193,76,30,192,76,45,193,32,8,195,76,30,192,166,251
12dA240,249,162,1,134,34,202,134,35,162,2,173,160,191,240,3,32,49,196,165,34
13dA166,251,32,81,194,201,255,208,2,169,1,133,34,166,251,165,35,201,255,208,2
14dA169,0,32,81,194,141,37,193,166,34,32,198,193,166,34,224,255,240,190,232,134
15dA34,208,242,160,0,177,253,208,17,165,8,197,251,208,5,198,8,200,132,7,32,8
16dA195,76,30,192,152,145,253,200,132,7,208,245,166,251,240,70,166,8,160,3,202
17dA240,6,200,202,240,2,200,202,232,140,120,193,142,122,193,228,8,240,7,169,32
18dA32,210,255,208,5,169,62,32,210,255,32,198,193,160,255,162,255,136,240,4,228
19dA251,208,219,169,32,166,7,32,210,255,202,208,250,169,94,32,210,255,169,13,32
20dA210,255,76,30,192,32,156,194,198,8,160,0,177,253,133,7,230,7,32,244,193,230
21dA8,162,1,134,7,76,30,192,160,0,166,7,202,138,145,253,32,244,193,230,8,162,1
22dA134,7,76,30,192,169,193,160,219,32,98,194,174,219,193,232,142,229,193,174
23dA220,193,142,230,193,174,255,255,240,16,142,236,193,160,0,185,255,255,32,210
24dA255,200,192,255,208,245,169,13,76,210,255,165,253,24,101,7,141,38,194,141
25dA57,194,165,254,105,0,141,39,194,141,58,194,173,38,194,109,160,191,141,41
26dA194,173,39,194,105,0,141,42,194,160,0,177,253,56,229,7,48,11,170,24,189,255
27dA255,157,255,255,202,16,247,174,160,191,202,16,1,96,189,164,191,157,255,255
28dA202,16,247,160,0,177,253,24,109,160,191,145,253,165,7,24,109,160,191,133,7
29dA96,141,93,194,201,255,240,9,201,0,240,4,224,255,16,1,138,96,141,154,194,141
30dA146,194,140,153,194,200,140,145,194,202,138,41,7,168,138,74,74,74,170,169,0
31dA24,202,48,4,105,3,144,249,141,161,191,185,129,197,41,3,109,161,191,105,96
32dA141,255,255,185,129,197,41,240,141,255,255,96,166,251,232,134,251,142,172
33dA194,169,195,160,120,32,98,194,162,255,202,142,194,194,228,8,240,16,48,14
34dA169,195,160,117,32,98,194,32,101,195,162,255,16,220,173,120,195,141,244,194
35dA141,235,194,173,121,195,141,245,194,141,236,194,160,0,177,253,141,240,194
36dA198,7,56,229,7,72,165,7,145,253,104,170,142,255,255,240,11,160,255,177,253
37dA157,255,255,136,202,208,247,162,1,134,7,166,8,228,251,240,3,232,134,8,96
38dA166,8,228,251,240,86,232,169,195,160,53,32,98,194,173,53,195,141,39,195,173
39dA54,195,141,40,195,160,0,177,253,174,255,255,240,18,142,48,195,24,105,255
40dA145,253,168,189,255,255,145,253,136,202,208,247,166,8,232,228,251,240,30
41dA142,79,195,169,195,160,120,32,98,194,162,255,232,142,95,195,169,195,160,117
42dA32,98,194,32,101,195,162,255,208,222,198,251,96,173,117,195,141,114,195,173
43dA118,195,141,115,195,174,255,255,189,255,255,157,255,255,202,16,247,96,165,8
44dA197,251,144,22,160,0,177,253,197,7,16,14,162,0,189,137,197,32,210,255,232
45dA224,5,208,245,96,165,8,32,196,196,169,44,32,210,255,165,7,32,196,196,162,3
46dA208,225,162,0,134,2,134,204,32,228,255,240,251,36,21,240,17,166,2,224,30
47dA240,241,32,210,255,157,162,191,232,134,2,16,230,201,13,208,19,169,0,166,2
48dA157,162,191,230,204,169,32,32,210,255,169,13,76,210,255,201,20,208,203,166
49dA2,240,199,32,210,255,202,134,2,16,191,141,11,196,141,22,196,32,117,197,160
50dA0,189,162,191,240,44,201,43,208,7,169,1,133,255,232,208,9,201,45,208,8,169
51dA255,133,255,232,189,162,191,240,19,201,48,48,15,201,58,16,11,153,194,191
52dA232,200,192,3,16,2,48,232,96,142,69,196,160,0,132,25,132,32,136,132,34,132
53dA35,169,25,32,244,195,224,255,240,10,142,81,196,32,31,197,133,34,162,255,189
54dA162,191,201,44,208,18,232,142,99,196,169,32,32,244,195,224,255,240,5,32,31
55dA197,133,35,96,32,49,196,169,1,36,25,240,36,16,21,165,34,197,8,48,6,169,1
56dA133,34,208,22,165,8,56,229,34,133,34,208,13,165,8,24,101,34,133,34,144,4
57dA169,0,133,34,169,1,36,32,240,36,16,21,165,35,197,7,48,6,169,1,133,35,208,22
58dA165,7,56,229,35,133,35,208,13,165,7,24,101,35,133,35,144,4,169,0,133,35,96
59dA32,215,196,162,0,189,194,191,240,3,32,210,255,232,224,3,208,243,96,133,20
60dA32,117,197,162,8,160,2,185,194,191,201,5,48,5,105,2,153,194,191,136,16,241
61dA160,2,165,20,10,133,20,185,194,191,42,201,16,41,15,153,194,191,136,16,242
62dA202,208,215,173,196,191,9,48,141,196,191,160,1,185,194,191,240,8,9,48,153
63dA194,191,136,16,243,96,173,196,191,208,19,173,195,191,141,196,191,173,194
64dA191,141,195,191,169,0,141,194,191,240,232,160,2,185,194,191,240,5,41,207
65dA153,194,191,136,16,243,162,8,160,125,24,185,69,191,144,2,9,16,74,153,69,191
66dA200,16,242,165,20,106,202,208,1,96,133,20,160,2,185,194,191,201,8,48,5,233
67dA3,153,194,191,136,16,241,48,211,169,0,141,194,191,141,195,191,141,196,191
68dA96,0,96,192,33,129,225,66,162,69,78,68,62,32

Demo
This entry is just for fun and will probably never reach a decent byte count. It's just because the challenge is about some "ancient" tool, why not implement it for an ancient machine ;)

In the course of creating this thing, I was reminded once again that the C64 system doesn't provide any sensible way of converting between strings and integers -- only strings and floats are covered and this is ridiculous, so this piece of code contains own conversion routines. In fact, the only OS routines called are GETIN (read a single character from keyboard) and CHROUT (write a single character to the screen).
Now, assembly is probably the "least golfy" language ever. For how to "golf" this, my idea as seen here is a BASIC loader, writing the bytes of the final binary to some memory location and jumping there. It's a working BASIC program this way ;) If anyone has a better idea how to golf this, please leave a comment!
The text buffer is quite limited, using up the space between $6000 and $BFFF (BASIC ROM is turned off as it's not needed) and the program itself resides at $C000. All in all, there's room for 255 lines with 95 characters each, and the program doesn't do any bounds checking, so playing with it, make sure your lines don't grow too large ;)
Finally, look here for the readable source, including my "golfing tool".

As this is pretty limited stuff, and the C64 can do better, here comes the "deluxe edition" using 80 columns display. To do this, the Kernal must be deactivated, so basic things like a keyboard driver, a font, bitmap manipulation logic for output, interrupt handling etc must be included, therefore it's quite a challenge to fit all this in the 4K area $C000-$CFFF (and this is needed for loading the program from a BASIC program to work).
Some random facts about this version:

fits in the 4K, but narrowly ... got 6 "spare" bytes now 3686 3841 bytes ;)
the basic loader is 13743 13385 13963 bytes (used the saved bytes for new feature "line editing")
screen color and sprite data is hidden in the ram "below" the MMIO area $D000-$DFFF
The PC-style text cursor is a "hardware cursor", using a sprite
the bitmap uses the area $E000-$FF3F, freely accessible because the kernal is switched off
There's an additional command implemented: q exits the editor
Extra feature: command line editing using cursor RIGHT and LEFT, Pos1 (HOME), End (SHIFT + HOME) and backspace (DEL)

Demo
Program to type in yourself, if you want 80s computer mag feeling:
0fOa=49152to52992:rEb:pOa,b:nE:sY49152
1dA162,2,181,0,157,0,207,232,208,248,173,32,208,133,2,173,33,208,133,3,173,17
2dA208,133,5,120,169,0,141,21,208,169,52,133,1,169,15,162,0,32,67,196,32,96,196
3dA162,127,169,0,157,0,218,202,16,250,169,240,141,18,218,141,21,218,169,104,141
4dA248,223,169,53,133,1,169,25,141,0,208,169,50,141,1,208,169,0,141,16,208,141
5dA29,208,141,23,208,141,28,208,169,1,141,39,208,141,27,208,141,21,208,169,228
6dA141,250,255,169,195,141,251,255,169,0,141,14,221,141,4,221,141,5,221,169,129
7dA141,13,221,169,1,141,14,221,173,0,221,41,252,141,0,221,173,24,208,133,4,32
8dA241,195,32,39,196,169,0,133,6,133,7,141,32,208,88,162,1,134,46,32,156,196
9dA120,32,25,196,173,0,221,9,3,141,0,221,165,4,141,24,208,169,55,133,1,169,1
10dA141,13,221,173,13,221,165,5,141,17,208,165,2,141,32,208,165,3,141,33,208
11dA169,0,141,21,208,162,2,189,0,207,149,0,232,208,248,88,96,133,10,169,0,133
12dA11,165,10,10,38,11,10,38,11,10,38,11,133,10,169,1,24,101,10,133,10,169,203
13dA101,11,133,11,96,169,0,133,9,165,6,10,10,10,10,38,9,10,38,9,10,38,9,133,8
14dA165,9,101,6,105,224,133,9,165,12,10,10,10,144,3,230,9,24,101,8,144,2,230,9
15dA133,8,96,160,224,132,9,200,132,11,160,64,132,10,160,0,132,8,162,50,169,0
16dA168,224,3,48,2,177,10,145,8,200,192,160,208,243,202,240,23,169,159,101,8
17dA133,8,144,3,230,9,24,169,160,101,10,133,10,144,218,230,11,176,214,96,72,132
18dA21,76,199,193,72,132,21,201,13,240,15,201,17,240,30,32,241,193,230,7,160,80
19dA196,7,208,52,160,0,132,7,230,6,160,25,196,6,208,40,198,6,32,59,193,240,33
20dA169,32,164,7,240,5,136,132,7,16,19,160,79,132,7,164,6,240,5,136,132,6,16,6
21dA160,0,132,7,240,3,32,241,193,165,6,10,10,10,105,50,141,1,208,169,0,141,16
22dA208,165,7,10,10,144,4,238,16,208,24,105,24,144,3,238,16,208,141,0,208,32
23dA229,195,104,164,21,96,24,74,176,67,32,235,192,160,7,177,10,41,240,153,13,0
24dA136,16,246,165,7,74,133,12,176,18,32,12,193,160,7,177,8,41,15,25,13,0,145,8
25dA136,16,244,96,32,12,193,160,7,177,8,41,240,74,74,74,74,74,25,13,0,106,106
26dA106,106,145,8,136,16,235,96,32,235,192,160,7,177,10,41,15,153,13,0,136,16
27dA246,165,7,74,133,12,176,25,32,12,193,160,7,177,8,10,10,10,10,10,25,13,0,42
28dA42,42,42,145,8,136,16,237,96,32,12,193,160,7,177,8,41,240,25,13,0,145,8,136
29dA16,244,96,174,113,202,236,114,202,240,11,181,22,202,16,2,162,15,142,113,202
30dA24,96,169,0,133,43,133,38,133,40,169,127,141,0,220,173,1,220,73,255,240,25
31dA170,41,4,240,6,165,43,9,128,133,43,138,41,251,240,9,230,40,32,161,195,105
32dA56,133,38,169,191,141,0,220,173,1,220,73,255,240,25,170,41,16,240,6,165,43
33dA9,64,133,43,138,41,239,240,9,230,40,32,161,195,105,48,133,38,169,223,141,0
34dA220,173,1,220,73,255,240,9,230,40,32,161,195,105,40,133,38,169,239,141,0
35dA220,173,1,220,73,255,240,9,230,40,32,161,195,105,32,133,38,169,247,141,0
36dA220,173,1,220,73,255,240,9,230,40,32,161,195,105,24,133,38,169,251,141,0
37dA220,173,1,220,73,255,240,9,230,40,32,161,195,105,16,133,38,169,253,141,0
38dA220,173,1,220,73,255,240,25,170,41,128,240,6,165,43,9,64,133,43,138,41,127
39dA240,9,230,40,32,161,195,105,8,133,38,169,254,141,0,220,173,1,220,73,255,240
40dA7,230,40,32,161,195,133,38,165,40,208,5,169,128,133,39,96,165,38,197,39,240
41dA51,133,39,162,25,134,41,162,1,134,42,5,43,174,114,202,149,22,202,16,2,162
42dA15,142,114,202,236,113,202,208,8,202,16,2,162,15,142,113,202,96,162,7,74
43dA176,4,202,16,250,96,138,24,96,166,41,240,4,202,134,41,96,166,42,240,4,202
44dA134,42,96,162,1,134,42,76,132,195,133,44,134,45,198,46,208,12,169,24,133,46
45dA169,1,77,21,208,141,21,208,32,141,194,169,255,141,25,208,166,45,165,44,64
46dA120,160,1,140,21,208,160,24,132,46,88,96,169,127,141,13,220,173,13,220,169
47dA1,141,26,208,141,25,208,169,16,141,18,208,173,17,208,41,127,141,17,208,169
48dA196,141,254,255,169,195,141,255,255,96,169,0,141,26,208,141,25,208,169,131
49dA141,13,220,96,173,17,208,9,32,141,17,208,169,121,141,24,208,96,173,17,208
50dA41,223,141,17,208,169,114,141,24,208,96,134,47,10,10,10,10,101,47,162,220
51dA134,48,160,0,132,47,162,4,145,47,200,208,251,230,48,202,208,246,96,169,0
52dA168,133,47,162,224,134,48,162,31,145,47,200,208,251,230,48,202,208,246,160
53dA63,145,47,136,16,251,96,32,121,194,184,176,24,170,16,3,44,115,202,41,127
54dA170,189,116,202,80,2,9,128,201,31,176,3,44,115,202,24,96,162,1,134,56,134
55dA55,202,142,0,96,134,54,166,55,160,57,32,208,198,32,188,199,32,235,199,166
56dA65,240,108,202,202,16,2,162,0,134,49,165,128,201,69,240,99,201,66,240,101
57dA201,108,240,103,201,76,240,102,201,80,240,105,201,97,240,103,201,73,240,124
58dA201,82,240,122,201,105,240,120,201,68,240,121,201,74,240,119,201,81,208,1
59dA96,162,0,32,104,201,165,67,166,54,224,0,240,167,32,191,198,201,255,240,8
60dA133,55,170,160,57,32,208,198,160,0,177,57,170,232,165,68,201,255,208,2,165
61dA56,32,191,198,133,56,16,131,32,0,199,16,63,169,0,133,68,240,203,169,1,133
62dA68,208,197,76,10,198,166,55,32,87,198,80,41,240,42,166,54,232,134,54,134,55
63dA160,57,32,208,198,169,0,168,145,57,200,132,56,32,118,198,16,14,240,82,240
64dA104,32,118,198,16,5,240,122,32,94,199,76,168,196,166,54,240,249,162,1,134
65dA67,202,134,68,162,2,165,49,240,3,32,49,201,165,67,166,54,32,191,198,201,255
66dA208,2,169,1,133,67,166,54,165,68,201,255,208,2,169,0,32,191,198,141,167,197
67dA166,67,32,87,198,166,67,224,255,240,191,232,134,67,208,242,32,0,199,198,55
68dA160,0,177,57,133,56,230,56,32,118,198,230,55,162,1,134,56,208,162,160,0,166
69dA56,202,138,145,57,32,118,198,166,54,228,55,240,124,230,55,162,1,134,56,208
70dA116,160,0,196,54,240,110,177,57,208,24,165,55,197,54,208,5,198,55,200,132
71dA56,32,94,199,160,1,196,55,48,86,132,55,16,82,152,145,57,200,132,56,208,74
72dA166,54,240,70,166,55,160,3,202,240,6,200,202,240,2,200,202,232,140,54,198
73dA142,56,198,228,55,240,7,169,32,32,125,193,208,5,169,62,32,125,193,32,87,198
74dA160,255,162,255,136,240,4,228,54,208,219,169,32,166,56,32,125,193,202,208
75dA250,169,38,32,125,193,169,13,32,125,193,76,168,196,160,50,32,208,198,160,0
76dA177,50,240,15,141,110,198,230,50,177,50,32,125,193,200,192,255,208,246,169
77dA13,76,125,193,165,57,24,101,56,133,50,165,58,105,0,133,51,165,50,101,49,133
78dA52,165,51,105,0,133,53,160,0,177,57,56,229,56,48,8,168,177,50,145,52,136,16
79dA249,164,49,136,16,1,96,185,130,0,145,50,136,16,248,160,0,177,57,24,101,49
80dA145,57,165,56,24,101,49,133,56,96,141,203,198,201,255,240,9,201,0,240,4,224
81dA255,16,1,138,96,140,254,198,200,140,247,198,202,138,41,7,168,138,74,74,74
82dA170,169,0,24,202,48,4,105,3,144,249,133,63,185,244,202,41,3,101,63,105,96
83dA133,255,185,244,202,41,240,133,255,96,166,54,232,134,54,134,64,160,59,32
84dA208,198,198,64,166,64,228,55,240,14,48,12,160,61,32,208,198,32,175,199,166
85dA64,16,227,165,59,141,74,199,165,60,141,75,199,160,0,177,57,141,70,199,198
86dA56,56,229,56,72,165,56,145,57,104,160,0,145,59,170,240,11,160,255,177,57
87dA157,255,255,136,202,208,247,162,1,134,56,166,55,228,54,240,3,232,134,55,96
88dA166,55,228,54,240,74,232,160,61,32,208,198,165,61,141,134,199,165,62,141
89dA135,199,160,0,177,61,240,20,170,177,57,134,64,24,101,64,145,57,168,189,255
90dA255,145,57,136,202,208,247,166,55,232,134,64,228,54,240,21,160,59,32,208
91dA198,230,64,166,64,160,61,32,208,198,32,175,199,166,64,208,231,198,54,96,160
92dA0,177,61,168,177,61,145,59,136,16,249,96,165,55,197,54,144,22,160,0,177,57
93dA197,56,16,14,162,0,189,252,202,32,125,193,232,224,5,208,245,96,165,55,32
94dA192,201,169,44,32,125,193,165,56,32,192,201,162,3,208,225,166,7,134,74,166
95dA6,134,75,160,0,132,65,132,66,132,76,164,76,240,6,169,13,32,125,193,96,32
96dA125,196,176,241,112,86,164,65,192,80,240,233,196,66,240,7,182,127,150,128
97dA136,16,245,32,125,193,166,6,134,72,166,7,134,73,208,8,166,6,228,75,208,2
98dA198,75,153,128,0,200,132,66,230,65,196,65,240,23,185,128,0,32,125,193,165,7
99dA208,10,169,24,197,72,208,4,198,72,198,75,200,16,229,166,72,134,6,166,73,134
100dA7,32,119,193,16,153,201,13,208,4,230,76,208,40,201,11,208,10,166,66,228,65
101dA240,135,230,66,16,30,201,12,208,8,166,66,240,46,198,66,16,18,201,15,208,6
102dA162,0,134,66,16,8,201,16,208,31,166,65,134,66,166,75,134,6,24,165,74,101
103dA66,201,80,133,7,144,6,233,80,133,7,230,6,32,119,193,76,251,199,201,17,208
104dA249,164,66,240,245,136,198,65,132,66,196,65,240,7,182,129,150,128,200,16
105dA245,32,125,193,166,6,134,72,166,7,134,73,164,66,196,65,240,9,185,128,0,32
106dA125,193,200,16,243,169,32,32,125,193,166,72,134,6,166,73,134,7,32,119,193
107dA76,251,199,141,12,201,141,23,201,32,104,202,160,0,181,128,240,43,201,43
108dA208,7,169,1,133,255,232,208,9,201,45,208,7,169,255,133,255,232,181,128,240
109dA19,201,48,48,15,201,58,16,11,153,209,0,232,200,192,3,16,2,48,233,96,134,71
110dA160,0,132,69,132,70,136,132,67,132,68,169,69,32,246,200,228,71,240,9,134
111dA71,32,24,202,133,67,166,71,181,128,201,44,208,17,232,134,71,169,70,32,246
112dA200,228,71,240,5,32,24,202,133,68,96,32,49,201,169,1,36,69,240,36,16,21
113dA165,67,197,55,48,6,169,1,133,67,208,22,165,55,56,229,67,133,67,208,13,165
114dA55,24,101,67,133,67,144,4,169,0,133,67,169,1,36,70,240,36,16,21,165,68,197
115dA56,48,6,169,1,133,68,208,22,165,56,56,229,68,133,68,208,13,165,56,24,101
116dA68,133,68,144,4,169,0,133,68,96,32,210,201,162,0,181,209,240,3,32,125,193
117dA232,224,3,208,244,96,133,212,32,104,202,162,8,160,2,185,209,0,201,5,48,5
118dA105,2,153,209,0,136,16,241,160,2,165,212,10,133,212,185,209,0,42,201,16,41
119dA15,153,209,0,136,16,242,202,208,215,165,211,9,48,133,211,160,1,185,209,0
120dA240,8,9,48,153,209,0,136,16,243,96,165,211,208,14,165,210,133,211,165,209
121dA133,210,169,0,133,209,240,238,160,2,185,209,0,240,5,41,207,153,209,0,136
122dA16,243,162,8,160,125,24,185,84,0,144,2,9,16,74,153,84,0,200,16,242,165,212
123dA106,202,208,1,96,133,212,160,2,185,209,0,201,8,48,5,233,3,153,209,0,136,16
124dA241,48,211,169,0,133,209,133,210,133,211,96,15,15,127,9,5,3,1,7,11,13,17,0
125dA69,83,90,52,65,87,51,88,84,70,67,54,68,82,53,86,85,72,66,56,71,89,55,78,79
126dA75,77,48,74,73,57,44,64,58,46,45,76,80,43,47,94,61,0,15,59,42,124,21,81,19
127dA32,50,0,0,49,10,6,4,2,8,12,14,18,0,101,115,122,36,97,119,35,120,116,102,99
128dA38,100,114,37,118,117,104,98,40,103,121,39,110,111,107,109,48,106,105,41
129dA60,64,91,62,45,108,112,43,63,94,61,0,16,93,42,124,22,113,20,32,34,0,0,33,0
130dA96,192,33,129,225,66,162,69,78,68,62,32,34,20,34,85,119,85,85,0,82,5,34,85
131dA119,85,85,0,34,20,119,68,102,68,119,0,82,5,119,68,102,68,119,0,34,20,34,85
132dA85,85,34,0,82,5,34,85,85,85,34,0,65,34,85,85,85,85,34,0,82,5,80,85,85,85
133dA34,0,0,34,20,102,17,51,119,0,0,82,5,102,17,51,119,0,0,34,20,34,119,68,34,0
134dA0,82,5,34,119,68,34,0,0,34,20,34,85,85,34,0,0,82,5,34,85,85,34,0,0,65,34
135dA85,85,85,51,0,0,82,5,80,85,85,51,0,2,2,2,2,2,0,2,0,102,102,15,6,15,6,6,0
136dA37,113,66,98,18,100,37,0,34,82,4,0,0,0,0,0,36,66,66,66,66,66,36,0,0,82,34
137dA119,34,82,0,0,0,0,0,7,0,32,32,64,1,1,2,2,2,36,36,0,33,83,117,113,81,81,33
138dA0,34,85,17,34,33,69,114,0,23,52,86,113,17,21,18,0,39,65,65,98,82,82,34,0
139dA34,85,85,35,81,81,34,0,0,34,34,0,0,34,34,4,0,16,39,64,39,16,0,0,2,69,33,18
140dA34,64,2,0,32,80,118,81,115,69,39,0,64,64,99,84,84,84,99,0,16,16,50,85,87
141dA84,50,0,16,32,115,37,37,35,33,2,66,64,98,82,82,82,82,0,36,4,37,38,38,38,37
142dA64,32,32,38,39,37,37,37,0,0,0,98,85,85,85,82,0,0,0,99,85,85,99,65,65,0,0
143dA98,84,70,65,70,0,32,32,117,37,37,37,19,0,0,0,85,85,87,119,34,0,0,0,85,37
144dA37,34,82,4,1,2,114,36,34,66,113,0,36,34,34,33,34,34,36,0,82,165,5,6,5,5,6
145dA4,34,37,21,7,5,5,5,0,99,84,84,100,84,84,99,0,103,84,84,86,84,84,103,0,118
146dA69,68,103,69,69,71,0,87,82,82,114,82,82,87,0,21,21,22,22,22,85,37,0,69,71
147dA71,69,69,69,117,0,82,85,117,117,117,85,82,0,98,85,85,101,69,71,67,0,98,85
148dA84,98,97,85,82,0,117,37,37,37,37,37,34,0,85,85,85,85,87,119,37,0,85,85,37
149dA34,34,82,82,0,115,18,34,34,34,66,115,0,6,50,66,114,226,66,54,0,48,64,67,68
150dA68,51,17,34,221,235,221,170,136,170,170,255,173,250,221,170,136,170,170
151dA255,221,235,136,187,153,187,136,255,173,250,136,187,153,187,136,255,221
152dA235,221,170,170,170,221,255,173,250,221,170,170,170,221,255,190,221,170
153dA170,170,170,221,255,173,250,175,170,170,170,221,255,255,221,235,153,238
154dA204,136,255,255,173,250,153,238,204,136,255,255,221,235,221,136,187,221
155dA255,255,173,250,221,136,187,221,255,255,221,235,221,170,170,221,255,255
156dA173,250,221,170,170,221,255,255,190,221,170,170,170,204,255,255,173,250
157dA175,170,170,204,255,253,253,253,253,253,255,253,255,153,153,240,249,240
158dA249,249,255,218,142,189,157,237,155,218,255,221,173,251,255,255,255,255
159dA255,219,189,189,189,189,189,219,255,255,173,221,136,221,173,255,255,255
160dA255,255,248,255,223,223,191,254,254,253,253,253,219,219,255,222,172,138
161dA142,174,174,222,255,221,170,238,221,222,186,141,255,232,203,169,142,238
162dA234,237,255,216,190,190,157,173,173,221,255,221,170,170,220,174,174,221
163dA255,255,221,221,255,255,221,221,251,255,239,216,191,216,239,255,255,253
164dA186,222,237,221,191,253,255,223,175,137,174,140,186,216,255,191,191,156
165dA171,171,171,156,255,239,239,205,170,168,171,205,255,239,223,140,218,218
166dA220,222,253,189,191,157,173,173,173,173,255,219,251,218,217,217,217,218
167dA191,223,223,217,216,218,218,218,255,255,255,157,170,170,170,173,255,255
168dA255,156,170,170,156,190,190,255,255,157,171,185,190,185,255,223,223,138
169dA218,218,218,236,255,255,255,170,170,168,136,221,255,255,255,170,218,218
170dA221,173,251,254,253,141,219,221,189,142,255,219,221,221,222,221,221,219
171dA255,173,90,250,249,250,250,249,251,221,218,234,248,250,250,250,255,156,171
172dA171,155,171,171,156,255,152,171,171,169,171,171,152,255,137,186,187,152
173dA186,186,184,255,168,173,173,141,173,173,168,255,234,234,233,233,233,170
174dA218,255,186,184,184,186,186,186,138,255,173,170,138,138,138,170,173,255
175dA157,170,170,154,186,184,188,255,157,170,171,157,158,170,173,255,138,218
176dA218,218,218,218,221,255,170,170,170,170,168,136,218,255,170,170,218,221
177dA221,173,173,255,140,237,221,221,221,189,140,255,249,205,189,141,29,189,201
178dA255,207,191,188,187,187,204,238,221

Readable source code.

Holy crud you did it

Hehe yep, it's fun :) "deluxe edition" with 80col text mode coming soon, this is a challenge to fit in 4K (needs a font, a keyboard driver and handling a bitmapped mode for text display -- I think it can be done)

With now 259 bytes left for additional code and 2306 unused bytes below the I/O area, a command history comes to mind ... (would be enough to hold 28 lines of history) ... doing it in 259 bytes of code seems challenging ;)

Do it! Plez do it

I guess I misjudged the complexity of a good command history ;) You have to make sure there aren't two identical adjacent entries and you have to save the "current" line while browsing the history ... seems impossible  to implement this in 259 bytes, I'll have to find some other tricks to reduce size first ;)


text:
Fizz-Buzzify a String
You will be given a String that only contains letters of the English Alphabet, both lowercase and uppercase (ASCII 65-90 and 97-122). Your task is to output the Fizz-Buzzified version of the String.
How to Fizz-Buzzify a String?

Each letter that has an even index in the English alphabet (the alphabet must be 1-indexed: a->1,b->2,...,z->26) will be turned into fizz if it is lowercase and FIZZ if it is uppercase (f -> fizz, F -> FIZZ).
Each letter that has an odd index in the English alphabet will be turned into buzz if it is lowercase, and BUZZ if it is uppercase (e -> buzz, E -> BUZZ).
Let's have an example, to illustrate the algorithm, using the string CodeGolf (spaces added for clarity):
"C o d e G o l f" ->  "BUZZ buzz fizz buzz BUZZ buzz fizz fizz"
 ^ ^ ^ ^ ^ ^ ^ ^
 1 1 0 1 1 1 0 0       (1 is odd index, 0 is even index)

If it is more convenient for your language, you may also leave single spaces between the groups (fizz, buzz, FIZZ, BUZZ). Hence, a result like fizzBUZZbuzzbuzz can also be returned as fizz BUZZ buzz buzz. Other separators are not allowed.

Test Cases:

Input  ->  Output

"egg"          ->  "buzzbuzzbuzz"
"CodeGolf"     ->  "BUZZbuzzfizzbuzzBUZZbuzzfizzfizz"
"Reset"        ->  "FIZZbuzzbuzzbuzzfizz"
"ATOM"         ->  "BUZZFIZZBUZZBUZZ"
"yOuArEgReAt"  ->  "buzzBUZZbuzzBUZZfizzBUZZbuzzFIZZbuzzBUZZfizz"

Any standard method for I/O can be used.
Default Loopholes apply.
You are only allowed to take input in your language's native String type. The same applies for output.
You can assume that the input will not be empty.
Shortest code in bytes in every language wins. Good Luck and Fizz-Buzz!

Sandbox.

Charcoal, 26 24 bytes
ＦθＦ⎇﹪℅ι²buzz¦fizz⎇№αι↥κκ

Try it online! Originally inspired by @CarlosAlejo. Edit: Saved 2 bytes by looping over the letters of fizz/buzz instead of assigning to a temporary. Explanation:
Ｆθ          Loop over the input (i = loop variable)
  Ｆ         Choose and loop over the word (k = loop variable)
   ⎇        Ternary
    ﹪℅ι²    If i has an odd ASCII code
    buzz
    fizz
            Print (implicit)
  ⎇         Ternary
   №αι      If i is an uppercase letter
    ↥κ      Uppercase(k)
     κ      k

I finally got to understand your solution. I thought that Ordinal(i) returned the position of the i char in its original string, but it returns its ASCII value (character code). Very clever solution, I still need to improve a lot my Charcoal skills!

How you do this in Charcoal in only 24 bytes...

In which encoding is this 24 bytes?

@Ruslan In Charcoal's custom code page.

C#, 92 bytes
using System.Linq;a=>string.Concat(a.Select(x=>x%2<1?x<97?"FIZZ":"fizz":x<97?"BUZZ":"buzz"))

Posted at practically the same time but you saved a byte to my solution by ordering the ternary the shorter way +1

@TheLethalCoder ahh, sorry about that.

Nothing to be sorry about we posted 12 seconds apart! And yours is shorter!

Will C# let you use x%2 directly as a boolean, without needing the <1 part? If so, you may be able to save some bytes that way.

@BrianJ No it doesn't do it implicitly

Python 3, 73 69 bytes
4 bytes thanks to ovs.
lambda s:"".join("fbFBiuIUzzZZzzZZ"[(c<"a")*2+ord(c)%2::4]for c in s)

Try it online!

C (gcc), 75 bytes
f(char*s){for(;*s;++s)printf(*s>90?*s%2?"buzz":"fizz":*s%2?"BUZZ":"FIZZ");}

Try it online!

Java (OpenJDK 8), 105 100 94 91 90 bytes
s->{for(int i:s.getBytes())System.out.print(i%2<1?i>90?"fizz":"FIZZ":i>90?"buzz":"BUZZ");}

Try it online!
Much golfable, very bytes, so Java!
Very golfed by @KevinCruijssen by 9 bytes!

I thought that maybe streams would make this shorter, so I wrote one. s->s.join("",s.chars().mapToObj(i->i>90?i%2<1?"fizz":"buzz":i%2<1?"FIZZ":"BUZZ").toArray(String[]::new)); Alas, it's 105 chars long :( If only they could add the join directly on the stream or integrate a toList, actually, anything sensible would be good.

Printing directly instead of returning a String is 6 bytes shorter, and using getBytes() instead of toCharArray() is an additional 3 bytes shorter: s->{for(int i:s.getBytes())System.out.print(i>90?i%2<1?"fizz":"buzz":i%2<1?"FIZZ":"BUZZ");}

You forgot the additional 3 bytes by changing toCharArray() to getBytes(). :)

I clicked before your edit and didn't see it afterwards ;) Also, I just thought about it before seeing your comment xD

Plain English, 820 632 610 bytes
Mr. Xcoder suggested eliminating an unneeded error trap, which saved 22 bytes.
A fizzy string is a string.
To convert a s string to a z fizzy string:
Clear the z.
Slap a r rider on the s.
Loop.
If the r's source's first is greater than the r's source's last, exit.
Put the r's source's first's target in a b byte.
If the b is not any letter, bump the r; repeat.
Put "FIZZ" in a t string.
If the b is d, put "BUZZ" in the t.
If the b is _, lowercase the t.
Append the t to the z.
Bump the r.
Repeat.
To decide if a b byte is d:
Put the b in a n number.
If the n is odd, say yes.
Say no.
To decide if a b byte is _:
Put the b in a c byte.
Lowercase the c.
If the c is the b, say yes.
Say no.

Ungolfed code:
A fizzy string is a string.

To convert a string to a fizzy string:
  Clear the fizzy string.
  Slap a rider on the string.
  Loop.
    If the rider's source's first is greater than the rider's source's last, exit.
    Put the rider's source's first's target in a byte.
    If the byte is not any letter, bump the rider; repeat.
    Put "FIZZ" in another string.
    If the byte is odd, put "BUZZ" in the other string.
    If the byte is lower case, lowercase the other string.
    Append the other string to the fizzy string.
    Bump the rider.
  Repeat.

To decide if a byte is odd:
  Put the byte in a number.
  If the number is odd, say yes.
  Say no.

To decide if a byte is lower case:
  Privatize the byte.
  Lowercase the byte.
  If the byte is the original byte, say yes.
  Say no.

The Plain English IDE is available at github.com/Folds/english.  The IDE runs on Windows.  It compiles to 32-bit x86 code.

"You can assume that the input will not be empty." so I think you can drop If the s is "", exit.

@Mr.Xcoder -- Thank you.  It turns out that the trap was not needed even if s was empty.

Pyth, 23 21 bytes
smr<d\a@c"fizzbuzz"4C

Test suite.

O_o 3 minutes :)

C#, 97 bytes
using System.Linq;s=>string.Concat(s.Select(c=>"fizzbuzzFIZZBUZZ".Substring(c%2*4+(c>96?0:8),2)))

I don't know C#, but can't you use c%2>1?c>96?"fizz":"buzz":...

JavaScript (ES6), 79 77 bytes
s=>s.replace(/./g,c=>['BUZZ','buzz','FIZZ','fizz'][parseInt(c,36)%2*2|c>'Z'])

Test cases

let f =

s=>s.replace(/./g,c=>['BUZZ','buzz','FIZZ','fizz'][parseInt(c,36)%2*2|c>'Z'])

console.log(f("egg"        )) // "buzzbuzzbuzz"
console.log(f("CodeGolf"   )) // "BUZZbuzzfizzbuzzBUZZbuzzfizzfizz"
console.log(f("Reset"      )) // "FIZZbuzzbuzzbuzzfizz"
console.log(f("ATOM"       )) // "BUZZFIZZBUZZBUZZ"
console.log(f("yOuArEgReAt")) // "buzzBUZZbuzzBUZZfizzBUZZbuzzFIZZbuzzBUZZfizz"

Jelly, 21 bytes
“=%“Ƈ×»ẋ13Œu;$ɓØWiÐ€ị

Try it online!

><>, 68 bytes
<vv?("^"$%2:;?(0:i
v\?\"zzif"
v \\"zzub"
v \ "ZZIF"
v  \"ZZUB"
\oooo

Try it online, or watch it at the fish playground!
(But look at Aaron's answer which is 13 bytes shorter!)
If you're not familiar with ><>, there's a fish that swims through the code in 2D, and the edges wrap. The symbols >, <, ^ and v set the direction of the fish, / and \ are mirrors that reflect it, and ? means "do the next instruction if the top thing on the stack is non-zero, otherwise jump over the next instruction".
In the first line, the fish takes a character of input (i); if it's -1 for EOF, it halts (:0(?;); it gets the charcode mod 2 (:2%$); and it pushes a 1 or 0 on the stack depending on whether the charcode is less than or greater than the charcode of "^" ("^"(). The next three lines redirect the fish to the right fizz/buzz string, then the last line prints it (one o for each character) and sends the fish back to the start.

@Aaron, that's great! I did think of that idea but couldn't get it to work. Would you like to post that as your own solution?

@Aaron, you've also found a bug in either TIO or the online interpreter — in that interpreter, ! or ? followed by a space just skips the space, but TIO waits until the next non-space thing to skip…

@Aaron, your submission's much better than mine, so you can post it yourself and I'll delete this one.

! should skips spaces AFAIK, but the online interpreter pads its codespace with spaces, which is probably what you're seeing

Let us continue this discussion in chat.

><>, 55 bytes
Based on Not a tree's answer.
<v%2$)"^":;?(0:i
 \?v"ZZIF"
~v >"ZZUB"!
^>{:}" "*+ol1=?

Instead of representing the 4 possible output in the code, I only represent their capitalized versions and add 32 to the character code to get the small case equivalents.
Try it online !
Modified code for the online interpreter, which pads its codespace with empty cells :
<v%2$)"^":;?(0:i
 \?v"ZZIF"
~v >"ZZUB"     !
^>{:}" "*+o l1=?

Charcoal, 40 36 bytes
Ｆθ¿№αι¿﹪⌕αι²FIZZ¦BUZZ¿﹪⌕βι²fizz¦buzz

Try it online!
Explanation:
Ｆθ                                      for every char i in the input:
   ¿№αι                                    if i is found in the uppercase alphabet
       ¿﹪⌕αι²                             if i is an even uppercase char
              FIZZ¦BUZZ                    print "FIZZ" or else "BUZZ"
                       ¿﹪⌕βι²             if i is an even lowercase char
                              fizz¦buzz    print "fizz" or else "buzz"

An alternative with the same byte count:
ＡfizzφＡbuzzχＦθ¿№αι¿﹪⌕αι²↥φ↥χ¿﹪⌕βι²φχ

Try it online! (Verbose version)

4 bytes saved thanks to Neil!

Use Count or Ordinal respectively instead of Find to save you some bytes.

The entire if counts as a single statement so you don't need the {}s. I also saved a byte by moving the Uppercase inside a Ternary: Try it online!

Better still, Ｆθ«Ａ⎇﹪℅ι²buzz¦fizzχ⎇№αι↥χχ for 26 bytes. (Deverbosifier doesn't like this version.)

@Neil Thank you very much, but I can't even understand your last version, so I cannot take credit for it, I would feel as it is not my own answer. I'd be honored to be outgolfed by you if you write your own post. :-)

Perl5, 50+1 bytes
perl -nE'say+((FIZZ,BUZZ)x48,(fizz,buzz)x16)[unpack"C*",$_]'

Creates a 128-item list that maps ASCII chars to the proper code word.

Mathematica, 134 bytes
""<>{(s=Max@ToCharacterCode@#;If[96<s<123,If[EvenQ@s,c="fizz",c="buzz"]];If[64<s<91,If[EvenQ@s,c="FIZZ",c="BUZZ"]];c)&/@Characters@#}&

Java 8, 89 bytes
s->s.chars().mapToObj(i->i%2<1?i>90?"fizz":"FIZZ":i>90?"buzz":"BUZZ").collect(joining());

It assumes import static java.util.stream.Collectors.*;

Swift 4, 144 135 bytes
func f(s:String){print(s.map{let d=Int(UnicodeScalar("\($0)")!.value);return d%2<1 ?d>90 ?"fizz":"FIZZ":d>90 ?"buzz":"BUZZ"}.joined())}

Un-golfed:
func f(s:String){
    print(
        s.map{
            let d=Int(UnicodeScalar("\($0)")!.value)
            return d%2 < 1 ? d > 90 ? "fizz" : "FIZZ" : d > 90 ? "buzz" : "BUZZ"
        }.joined()
    )
}

What I am doing is looping over each character in the string. I convert each to its ASCII value, then check to see if it is even or odd, and then check to see if it is upper or lowercase and output the matching value from the loop. I then join all the elements of the resulting array into a single string and print it.
This solution uses Swift 4, so there is no way to easily test it online yet.
Thanks to @Mr.Xcoder for saving me 9 bytes!

error: value of type 'String' has no member 'map', because a String is not automatically converted to a list on runtime.

Also, that service is not free. You have to add a credit card in order to test your submission if I don't copy-paste it. Consider changing the test service.

In order to make it work, you must turn it into $0.characters.map{...}

@Mr.Xcoder Cloud 9 has a free tier, in which you only get one private workspace and unlimited public workspaces. You should be able to sign in through GitHub. I have never shared anything with it so I wasn't sure if it would work. Also, I should have mentioned I am using Swift 4, where String conforms to Collection. This mean it has a map function.

As I can see, the old function declaration is still valid in Swift 4, like func f(s:String){...}, hence you can save 9 bytes by using the following code, that uses print instead of return: https://pastebin.com/06kiiGaJ. If it doesn't work, let me know.

R, 150 123 108 bytes
i=ifelse
cat(i(sapply(el(strsplit(scan(,''),'')),utf8ToInt)>91,i(x%%2,'buzz','fizz'),i(x%%2,'BUZZ','FIZZ')))

Has to be shorter using ASCII? It was shorter. See edit history for old answer, which used letters.
Checks each letter for (1) whether it's capital or not (>91) and whether it's a fizz or a buzz.

q/kdb+, 48 bytes
Solution:
raze{@[($)`fizz`buzz x mod 2;(&)x<91;upper]}"i"$

Examples:
q)raze{@[($)`fizz`buzz x mod 2;(&)x<91;upper]}"i"$"egg"
"buzzbuzzbuzz"
q)raze{@[($)`fizz`buzz x mod 2;(&)x<91;upper]}"i"$"CodeGolf"
"BUZZbuzzfizzbuzzBUZZbuzzfizzfizz"
q)raze{@[($)`fizz`buzz x mod 2;(&)x<91;upper]}"i"$"Reset"
"FIZZbuzzbuzzbuzzfizz"
q)raze{@[($)`fizz`buzz x mod 2;(&)x<91;upper]}"i"$"ATOM"
"BUZZFIZZBUZZBUZZ"
q)raze{@[($)`fizz`buzz x mod 2;(&)x<91;upper]}"i"$"yOuArEgReAt"
"buzzBUZZbuzzBUZZfizzBUZZbuzzFIZZbuzzBUZZfizz"

Explanation:
Fairly straightforward, take the input string, cast into ASCII values, create a list of 1 or 0 depending whether it is odd or even (hint A=65=odd), then use this list to index into a list of fizz and buzz. Cast this to a string, and then for cases where the input is <91 (lower than a Z) we apply the upper function to get a FIZZ or a BUZZ.
q is interpreted right to left:
raze{@[string `fizz`buzz x mod 2;where x < 91;upper]}"i"$ / ungolfed version
                                                     "i"$ / cast input to ascii values
    {                                               }     / anonymous lambda
     @[                         ;            ;     ]      / apply
                                              upper       / upper-case
                                 where x < 91             / indices where input is less than 91 (ie uppercase)
                         x mod 2                          / returns 0 if even and 1 if odd
              `fizz`buzz                                  / 2 item list, which we are indexing into
       string                                             / cast symbols to strings `buzz -> "buzz"
raze                                                      / raze (merge) list into a single string

I don't know this language, but can you remove the space between mod and 2?

Unfortunately not, it could be written it as mod[x;2] if we didn't want any whitespace - but that winds up being 1 byte more!

05AB1E, 22 bytes
v‘FIZZÒÖ‘#yÇÉèAyåil}J?

Try it online!
Explanation
v                        # for each char y of input string
 ‘FIZZÒÖ‘#               # push the list ['FIZZ','BUZZ']
          yÇÉ            # check if y has an odd character code
             è           # use this to index into the list
              Ayåi       # if y is a member of the lowercase alphabet
                  l}     # convert to lowercase
                    J?   # unwrap from list and print

Alternative 22 byte solution
ÇÉAISå·+‘FIZZÒÖ‘#Dl«èJ

F#, 154 153 145 bytes
saved 1 9 bytes thanks to @Mr. Xcoder
let g s=
 Seq.map(fun c->match int c with
|x when x>64&&x<91->if x%2=0 then"FIZZ"else"BUZZ"
|x->if x%2=0 then"fizz"else"buzz")s
|>String.concat""

Try it online!

Save 1 byte by removing the space between concat and "" on the last line

150 bytes, although I don't know F#

145 bytes, remove the unnecessary whitespace

Thanks @Mr.Xcoder I'm still getting used to F# and when indentation is significant!

And BTW, Welcome to PPCG! I don't know F# at all, just removed stuff to see what happens :)

PHP, 67 bytes
for(;$c=$argn[$i++];)echo[FIZZ,BUZZ,fizz,buzz][ord($c)%2+2*($c>Z)];

Try it online!

Ruby, 61+1 = 62 bytes
Uses the -p flag.
gsub(/./){k=$&.ord%2*4;$&<?_?"FIZZBUZZ"[k,4]:"fizzbuzz"[k,4]}

Try it online!

source: Stack Exchange

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

sort: votes


text:
Time calculator
This challenge is related to a project I did last year (in Ruby). To make it more fun I decided to do it in as few bytes as possible. I didn't know about code golf back then so now that I found out about it and found this community I was wondering if anybody can beat me :)
The program should return the current time if no input is given
ruby time.rb
12:24

Or if you enter a time as a parameter it should return the time it will be in so many hours/minutes (pretend the time is 12:24) (the parts in [] are optional):
ruby time.rb [+]2[:12]
14:36

Or if the input starts with a - then subtract that time:
ruby time.rb -2[:12]
10:12

Of course if you don't include the :12 then it will only subtract the hours.
In Ruby I managed to get it at 144 bytes.
Of course you can do this in any language you like. However I would be happy to see if anybody can do any better in Ruby.
Edit:
Yes it is similar to this challenge. However I think it is different in a couple of ways.

The program has to get the date and it is not provided by the user
The input has many different formats 01:00, 1:00, 1, +1, -1, 1:23 etc.

I think these make it different enough but if you disagree then I will happily let go and allow it to be marked as duplicate.
Rules:

You must support all input formats I showed.
You are allowed to use any method to calculate the time (except for asking the user)
The output format must be HH:MM

Sorry for the confusion. I judged too quickly. I have reverted my edits.

@LeakyNun No worries. I was just about to message for clarification. Being new to the community I thought I misunderstood something :)

Can we output the seconds too or should it be only hours:minutes ?

@Dada Only hours and minutes. The output has to be exactly like I showed in my examples.

@BetaDecay Please see my edit concerning the duplicate question.

Do we have to support all the input formats or only a subset of them? For example, Can I force input to need to have a + on the front or do I have to support with a + and without?

@TheLethalCoder  Well, my project required me to support all of them so I am going to say all.

The output has to be exactly like I showed in my examples: Do we need leading zeroes for the output 01:11? Or can we use 1:11?

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


text:
Build me a city
Coders are always trying to flatten arrays into boring 1-dimensional entities and it makes me sad.
Your task is to unflatten an arbitrary string of characters, outputting a lovely city skyscape.
Consider the string: aaabbbbbccqrrssstttttttPPw
It looks much better like this:
            tt
            tt
  bb        tt
  bb        tt
aabb      sstt
aabbcc  rrssttPP
aabbccqqrrssttPPww

(Ok, yes, the letters are duplicated to make it look more city-skyline-ery).
Take an input string, duplicate each subsection of matching characters (not necessarily alphabetic letters) and build me a city!
Shortest code bytes win.
I actually thought I had the requirements nailed, but to answer some questions:

it must be on the ground
you can have extra sky if you want (leading blank lines, surrounding blank space) - but not between the buildings
letters can be reused inside the string (same architecture, different location)
the letters are assumed to be ASCII, but more flair will be given to those supporting additional encodings (UTF8, etc)

Can we output the cityscape rotated 90 degrees?

Will characters ever repeat again i.e. aaabbbbaa?

@Okx have you ever seen a city rotated 90 degrees, that would look very silly! ;)

@Tom maybe..?

Welcome on the site! For future challenges, I recommend posting them first in the Sandbox where you can get feedbacks from the community before posting it as a challenge.

Related. Related.

Can we have trailing and leading newlines?

What character can the input consist of?

@LiefdeWen Trailing newlines are allowed by default, afaik.

@Okx Actually asking for leading newlines

Are trailing spaces permitted?

Can we have trailing newlines or the buildings will float in mid-air?

I thought someone had taken my sandbox challenge XD

How do you construct buildings made out of newlines, carriage returns, or tab characters?

05AB1E, 6 bytes
γ€DζR»

Try it online!
In a version newer than the challenge, ζ has been added as a replacement fo .Bø
05AB1E, 8 bytes
γ€D.BøR»

Explanation:
γ            Convert into a list of consecutive equal elements
 €D          Duplicate each element
   .B        Squarify; pad each element with spaces so that they are the length of the longest element
     ø       Transpose
      R      Reverse (otherwise the city would be upside-down)
       »     Join by newlines

Try it online!

Interestingly, Jelly has z⁶ for .Bø...but it also has Œgx'2 for γ€D >_>

γ.BD)ø˜øR» was what I had without looking, €D is way better; I feel like we're both missing the 1-byte solution to inline duplication though.

@MagicOctopusUrn Wait, you solved the challenge without even looking at it?

@Okx Well, it's wise not to look at the answers before since the whole fun of golfing it yourself could be cut off.

@EriktheOutgolfer It was a joke, and what I mean was that he solved it without looking at the content of the challenge.

Try it online! - for 6 now.

@MagicOctopusUrn Thanks.

Jelly, 9 bytes
Œgx'2z⁶ṚY

Try it online!
Explanation:
Œgx'2z⁶ṚY  Main Link
Œg         Group runs of equal elements
  x        Repeat
   '              the lists
    2                       twice without wrapping
     z⁶    Zip (transpose), filling in blanks with spaces
       Ṛ   Reverse the whole thing so it's upside-down
        Y  Join by newlines

Could you add an explanation please milord? I can't understand what's happening here :o

@Nathan https://pastebin.com/DzaBSjd5

@HyperNeutrino Nice explanation...

Just to be sure, is it correct? :P

@HyperNeutrino Well, that wasn't entirely the intention for ', which was to repeat the lists themselves and not the items inside them, but overall it's good. :)

Ah okay. I didn't know exactly what "flat" meant. Thanks :) Also do you want to edit it into your answer? :P

@HyperNeutrino Yeah I'll edit it in.

"So that it's upside down"? Missing negative?

@cairdcoinheringaahing Nope, we turn it upside down to bring it to a correct state, since it's already upside-down according to physics laws.

In what character encoding is U+1E5A LATIN CAPITAL LETTER R WITH DOT BELOW a single byte?

@DanielH Jelly has a custom encoding.

@EriktheOutgolfer Oh, I see. I hadn’t heard of Jelly before and I saw a lot about UTF-8 on the GitHub page and missed the alternative of using its custom codepage.

CJam, 23 bytes
qe`::*:__:,:e>f{Se[}zN*

Try it online!
Explanation:
qe`::*:__:,:e>f{Se[}zN* Accepts (multi-line?) input
q                       Take all input
 e`::*                  Split into groups of equal elements
      :_                Duplicate each
        _:,:e>          Push maximal length without popping
              f{Se[}    Left-pad each to that length with space strings (NOT space chars, although not a problem here)
                    z   Zip
                     N* Join with newlines

Wow, a CJam answer >_>

Python 3, 155 136 134 132 bytes
-19 bytes thanks to @LeakyNun
-2 bytes thanks to @officialaimm
-1 byte thanks to @Wondercricket
s=input()+'+'
k=' '*len(s)
a=[]
c=b=''
while s:
 while c in b:b+=c;c,*s=s
 a+=b+k,b+k;b=c
for r in[*zip(*a)][:0:-1]:print(*r,sep='')

Try it online!

Japt -R, 19 18 15 13 12 9 bytes
Includes trailing spaces on each line.
ò¦ Õ®m²ÃÔ

Try it
ò¦ Õ®m²ÃÔ     :Implicit input of string
ò             :Partition by
 ¦            :  Inequality
   Õ          :Transpose
    ®         :Map
     m        :  Map
      ²       :    Duplicate
       Ã      :End map
        Ô     :Reverse
              :Implicit output joined with newlines

Python 2, 117 bytes
import re
s=input()
for l in zip(*[x+S*len(s)for x,_ in re.findall(r'((.)\2*)',s)for S in'  '])[::-1]:print''.join(l)

Try it online!

Java 8, 412 400 330 324 312 319 bytes
-6 bytes thanks to VisualMelon
-12 bytes thanks to Kevin Cruijssen
but +19 bytes because I forgot to include the imports in the byte count.
import java.util.*;x->{Map m=new HashMap(),n;int l=x.length(),i=l,v,y,h=0,d=1;char c,k;for(;i-->0;m.put(c,d=m.get(c)!=null?d+1:1),h=d>h?d:h)c=x.charAt(i);for(y=h;y>0;y--){n=new HashMap(m);for(i=0;i<l;i++)if(n.get(k=x.charAt(i))!=null){v=(int)m.get(k);System.out.print((y>v?"  ":k+""+k)+(i==l-1?"\n":""));n.remove(k);}}}

Try it online!

Golfing Java and C# (my department) is great fun! Keep at it! Not tested, but I think you can save a few bytes by rejigging the for loops: you can pre-assign i=0, or better, i=l, and count down for(;i-->0;h=d>h?d:h) (and stuff the h= bit in there). The same back-counting will work for the inner loop also. The inner if also has no need for the braces {}. And always be weary of <= or >=, you can turn the ternary around with > and save a byte.

Thanks, I could shave another 6 bytes off the code thanks to your tips. Well, I think I'm going to stay with Java Golfing since I actually like it ;).

Welcome to PPCG! I'm afraid you'll have to increase the byte-count to 329 (+19 bytes due to the required import java.util.*; for Map and HashMap, imports are part of the byte-count; and -1 by removing trailing semi-colon, which isn't part of the byte-count).

Having said that, you can still golf some parts like this: import java.util.*;x->{Map m=new HashMap(),n;int l=x.length(),i=l,v,y,h=0,d=1;char c,k;for(;i-->0;m.put(c,d=m.get(c)!=null?d+1:1),h=d>h?d:h)c=x.charAt(i);for(y=h;y>0;y--){n=new HashMap(m);for(i=0;i<l;i++)if(n.get(k=x.charAt(i))!=null){v=(int)m.get(k);System.out.print((y>v?"  ":k+""+k)+(i==l-1?"\n":""));n.remove(k);}}}

Summary of the changes: HashMap<> → HashMap; Map n= → ,n and n=; m.put(c,d=m.get(c)!=null?d+1:1); inside the for-loop to get rid of the brackets; k=x.charAt(i) inside the if(n.get(k)!=null) to get rid of the semi-colon and for-loop's brackets. Again, welcome and great answer! +1 from me. Also, in case you haven't seen it yet: Tips for golfing in Java and Tips for golfing in  might be interesting to read through.

Thank you for your support and the welcome :). I've applied all the changes and added the import to the byte count. Also, nice tips for golfing in Java, very helpful.

293 bytes

Mathematica, 150 bytes
(z=Characters[v=#];f=CharacterCounts[v][#]&/@(d=Union@z);Row[Column/@Map[PadLeft[#,Max@f,""]&,Table[Table[d[[i]]<>d[[i]],f[[i]]],{i,Length@d}],{1}]])&

R, 135 bytes
e=rle(sub('(.)','\\1\\1',strsplit(scan(,''),'')[[1]]));write(sapply(sum(e$l|1):1,function(x)ifelse(e$l>=x,e$v,'  ')),'',sum(e$l|1),,'')

Try it online!
reads from stdin, writes to stdout (with a trailing newline).
Explanation:

rle finds the lengths of the streaks of characters, the heights of each tower.
the sub expression replaces each character with its double (so I didn't have to muck about with setting adjacent indices together)
sapply returns an array (in this case a matrix):

sum(e$l|1) is the number of distinct characters; we go from top to bottom
ifelse( ... ) is a vectorized if...else allowing us to build a matrix of towers and double spaces
write writes to console, with a few options to format.

Pyth, 13 bytes
j_.tsC*2]*Mr8

Try it online!

49 minutes... way too slow

PHP, 138 bytes
for(;~$s=&$argn;$s=substr($s,$r++%2*$i))for($i=0;$i<strspn($s,$c=$s[0]);$f[$i++][$r]=$c)a&$f[$i]?:$f[$i]=" ";krsort($f);echo join("
",$f);

Try it online!

MATL, 15 bytes
'(.)\1*'XXtvc!P

Try it online!
Explanation
'(.)\1*' % Push string to be used as regexp pattern
XX       % Implicit input. Regexp matching. Pushes row cell array of matching substrings
t        % Duplicate
v        % Concatenate vertically
c        % Convert to char. This reads cells in column-major order (down, then across)
         % and produces a 2D char array, right-padding with spaces
!        % Transpose
P        % Flip vertically. Implicitly display

Charcoal, 40 bytes:
Ａ⟦⟦ω⟧⟧λＦθ¿⁼ι§§λ±¹¦⁰⊞§λ±¹ι⊞λ⟦ι⟧ＦλＦ²↑⁺⪫ιω¶

Try it online! Link is to verbose version of code. I originally tried a simple loop over the input string to print an oblong every time the letter changed, but I switched to this list-building method as it saved 5 bytes. Explanation: The variable l contains a nested list of the input letters. Characters that match the current last list elements get pushed onto the last list otherwise a new sublist is created for that character. It then remains to join the letters in each sublist so that they can be printed vertically twice.

QuadS, 15 + 1 = 16 bytes
+1 byte for the 1 flag.
⊖⍵
(.)\1*
2/⍪⍵M

Try it online!
⊖⍵ post-process by flipping upside down
(.)\1* runs of identical characters
2/⍪⍵M duplicate the columnified Match
The 1 flag causes the results to be merged together.

Ruby, 116 bytes
->s{a=s.scan(/(.)(\1*)/).map{|x,y|[x,y.size+1]}.to_h
m=a.values.max
m.times{|i|puts a.map{|k,v|v+i<m ?'  ':k*2}*''}}

Try it online!

puts a.map{...} can be replaced with p(a.map{})

p will output quote characters, so it's not fit here

oh, wow, thanks. You learn everyday - https://stackoverflow.com/a/1255362/2047418

C, 259 231 Bytes
Golfed Code
#define v a[1][i
i,k,l,x,h,w;main(char*s,char**a){for(;v];w+=2*!x,s=v++],h=x>h?x:h)x=(s==v])*(x+1);h++;s=malloc((x=h++*++w+1)+w);memset(s,32,h*w);for(i=k;v];s[x+1]=s[x]=k=v++],x=k==v]?x-w:(h-1)*w+l++*2+3)s[i*w]=10;printf("%s",s);}

Verbose Code
//Variable Explanations:
//i - increment through argument string, must beinitialized to 0
//k - increment through argument string, must be initialized to 0
//l - record x coordinate in return value, must be initialized to 0
//x - record the actual character position within the return string
//arrheight - the height of the return string
//arrwidth - the width of the return string
//arr - the return string
//argv - the string containing the arguments
#define v argv[1][i

i,k,l,x,arrheight,arrwidth;

main(char*arr,char**argv){
  for(;v];                                 //For Length of input
    arrwidth+=2*!x,                        //increment width by 2 if this char is not the same as the last
    arr=v++],                              //set arr to current char
    arrheight=x>arrheight?x:arrheight      //see if x is greater than the largest recorded height
  )x=(arr==v])*(x+1);                     //if this character is the same as the last, increment x (using arr to store previous char)
  arrheight++;                             //increment height by one since its 0 indexed
  arr=malloc((x=arrheight++*++arrwidth+1)+arrwidth); //create a flattened array widthxheight and set x to be the bottom left position
  memset(arr,32,arrheight*arrwidth);       //fill array with spaces
  for(i=k;v];                              //For Length of input
    arr[x+1]=arr[x]=k=v++],                //set x and x+1 positions to the current character, store current character in i
    x=k==v]?x-arrwidth:(arrheight-1)*arrwidth+l++*2+3 //if next char is same as current move vertically, else set x to bottom of next column
  )arr[i*arrwidth]=10;                     //Add new lines to string at end of width

  printf("%s",arr);                        //output string

}

Compiled with GCC, no special Flags
Edit
Saved 28 bytes thanks to adelphus. His change allowed me to create a define. And I made the while loops into for loops to save 2 bytes each by rearranging the loop. I also fixed an issue where the code would break when the last character in input wasn't singleton. The code will fail if there is only one unique letter but should work in all other cases.

Nice! But the golfed version doesn't seem to work with arbitrary input for some reason. Removing the final "w" from the sample input appears to lose the q's and repeat the string. Sure it's something small...

also while (i < strlen(argv[1])) can be shortened to while (argv[1][i]) - loop until null character

@adelphus Interesting, I'll try it out tomorrow when I get a chance. I did not test anything other than the given test case (lazy I know).

That actually helped a ton, I was able to fix the problem and reduce by almost 30 bytes!

Factor + grouping.extras sequences.repeating, 94 bytes
[ [ ] group-by values dup longest length '[ _ 32 pad-head ] map 2 repeat flip [ print ] each ]

Modern Factor doesn't require a conversion to string before printing a sequence of code points, so have a screenshot of running the quotation in the listener:

Here's a TIO link with the extra >string:
Try it online!
Explanation:
It's a quotation (anonymous function) that takes a string as input and outputs to standard output. Assuming "aaabbbbbccqrrssstttttttPPw" is on the data stack when this quotation is called...

[ ] group-by values Split into groups of equal elements.
Stack: { V{ 97 97 97 } V{ 98 98 98 98 98 } V{ 99 99 } V{ 113 } V{ 114 114 } V{ 115 115 115 } V{ 116 116 116 116 116 116 116 } V{ 80 80 } V{ 119 } }

dup longest length Keep the 'city' on the stack but also find the length of the longest 'building.'
Stack: ~city~ 7

'[ _ 32 pad-head ] map Pad the city with whitespace to be a rectangular matrix.
Stack: { V{ 32 32 32 32 97 97 97 } V{ 32 32 98 98 98 98 98 } V{ 32 32 32 32 32 99 99 } V{ 32 32 32 32 32 32 113 } V{ 32 32 32 32 32 114 114 } V{ 32 32 32 32 115 115 115 } V{ 116 116 116 116 116 116 116 } V{ 32 32 32 32 32 80 80 } V{ 32 32 32 32 32 32 119 } }

2 repeat Repeat each row twice.

flip Transpose the matrix.

[ print ] each Print each row to standard output.

J, 22 bytes
2|.@|:@#[[;.1~1,2~:/\]

Try it online!

Pip, 22 bytes
21 bytes of code, +1 for -l flag.
Ya@`(.)\1*`RV:yWVyZDs

Try it online!
Explanation
                       a is 1st cmdline arg; s is space (implicit)
 a@`(.)\1*`            Using regex, create list of runs of same character in a
Y                      Yank that into y variable
              yWVy     Weave (interleave) y with itself to duplicate each item
                  ZDs  Zip to transpose, with a default character of space filling gaps
           RV:         Reverse the resulting list (with the compute-and-assign
                        meta-operator : being abused to lower the precedence)
                       Auto-print, one sublist per line (implicit, -l flag)

Haskell, 144 bytes
f s=let x=groupBy(==)s;l=length;m=maximum(map l x)in concatMap(++"\n")$reverse$transpose$concat[[z,z]|z<-(map(\y->y++(replicate(m-(l y))' '))x)]

I'm pretty confident I can do better than this, but this is the best I can come up with for the time being.

Bad news first: you use functions from Data.List which is not in scope by default. You have to either add the import Data.List to the byte count or specify a Haskell environment which does include it by default (e.g. change the language from Haskell to Haskell (lambdabot). -- Some tips: a) use pattern guards to bind variables instead of let and/or declare helper functions directly: l=length;f s|x<-groupBy(==)s,m<-... =concatMap. b) map l x is l<$>x, c) concatMap("++\n" is unlines. d) groupBy(==) is just group. e) concat is id=<<. You use m only once, so inline it

... f) no need for () around l y, replicate ... ' ' and map ... x. All in all: import Data.List;l=length;f s|x<-group s=unlines$reverse$transpose$id=<<[[z,z]|z<-map(\y->y++replicate(maximum(l<$>x)-l y)' ')x].

groupBy(==)=group, altough I'm not sure whether one is in Prelude and the other isn't. concatMap can be written >>=, and map can be infixed as <$>, and concat[[z,z]|z<-…] might be (replicate 2)=<<… or (\z->[z,z])=<<…

You can shave off one more byte from @Bergi's excellent tip: (\z->[z,z]) is (:)<*>pure, i.e. ...transpose$(:)<*>pure=<<map(\y...)x

Stacked, 42 bytes
[rle toarr[...*chars]map FIX 2*tr rev out]

Try it online!

Ruby, 107 bytes
gets.gsub(/(.)(\1*)/,'\0
'*2).split('
').map{|x|x.ljust($_.size).chars}.transpose.reverse.map{|x|puts x*""}

Try it online!
a full program which assumes there will be no newlines in the string.

JavaScript (V8), 98 bytes
x=>x.replace(/(.)\1*/g,y=>s=s.replace(/$/mg,_=>y[i]+y[i--]||'  ',i=n),s=`
`.repeat(n=x.length))&&s

Try it online!
JavaScript (V8), 100 bytes
x=>x.replace(/(.)\1*/g,(y,c)=>s=s.replace(/$/mg,_=>y[i--]?c+c:'  ',i=n),s=`
`.repeat(n=x.length))&&s

Try it online!

APL (Dyalog), 37 bytes
{⊃,/⍵↑⍨¨-⌈/≢¨⍵}'(.)\1*'⎕S{2/⍪⍵.Match}

Try it online!

q/kdb+, 53 bytes
Solution:
{(|)(+)(,/)(max(#:)each c)$(+)2#(,)c:((&)differ x)_x}

Example:
 q){(|)(+)(,/)(max(#:)each c)$(+)2#(,)c:((&)differ x)_x}"BBPPPPxxGGGGKKKKKKKkkkkEEeeEEEeeEEEEEOOO8####xxXXX"
 "        KK                      "
 "        KK                      "
 "        KK          EE          "
 "  PP  GGKKkk        EE    ##    "
 "  PP  GGKKkk    EE  EEOO  ##  XX"
 "BBPPxxGGKKkkEEeeEEeeEEOO  ##xxXX"
 "BBPPxxGGKKkkEEeeEEeeEEOO88##xxXX"

Explanation:
{reverse flip raze (max count each c)$flip 2#enlist c:(where differ x)_x} / ungolfed function
{                                                                       } / lambda function
                                                      (where differ x)    / indices where x differs
                                                                      _   / cut at these points aabbbc -> "aa","bbb","c"
                                                    c:                    / save in variable c
                                             enlist                       / put this list in another list
                                           2#                             / take two from this list (duplicate)
                                      flip                                / rotate columns/rows
                   (max count each c)                                     / find the longest run of characters
                                     $                                    / whitespace pad lists to this length
              raze                                                        / reduce down lists
         flip                                                             / rotate columns/rows
 reverse                                                                  / invert so buildings are on the ground

Perl 5, 92 + 1 (-p) = 93 bytes
while(s/(.)\1*//){$a[$_].=($"x($i-length$a[$_])).$1x2for 1..length$&;$i+=2}say while$_=pop@a

Try it online!

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


text:
Those Greedy Romans!
Given a strictly positive integer, return the shortest possible Roman numeral using only the additive rule. Output must consist of zero or more of each of the characters MDCLXVI in that order. The number 14 must therefore give XIIII rather than XIV.
The characters' numeric values are M=1000, D=500, C=100, L=50, X=10, V=5, I=1.
Examples
3 → III
4 → IIII
9 → VIIII
42 → XXXXII
796 → DCCLXXXXVI
2017 → MMXVII
16807 → MMMMMMMMMMMMMMMMDCCCVII

You're a benevolent questioner to allow 4 -> IIII is 9 -> VIIII as well instead of IX?

Related: Convert to Roman Numeral

@MagicOctopusUrn VIIII is the only allowed output for 9.

@Adám was just pointing out that you may want to add that as an example too because the rule for 4 and 9 are the same.

@MagicOctopusUrn Added.

Related

Plain English, 1059 1025 678 641 451 399 bytes
Saved 34 bytes by removing an error trap.  Then saved 384 bytes by golfing.  Then saved 190 bytes by combining the division operation with the append operation ("z") into a new operation ("p").  Then saved 52 bytes by golfing.
A s is a string.
To p a r remainder a s a x string a n number:
If the x is "", exit.
Divide the r by the n giving a q quotient and the r.
Fill a t s with the x's first's target given the q.
Append the t to the s.
To convert a r number to a s:
p the r the s "M" 1000.
p the r the s "D" 500.
p the r the s "C" 100.
p the r the s "L" 50.
p the r the s "X" 10.
p the r the s "V" 5.
p the r the s "I" 1.

Here is the ungolfed version of the final code, plus an error trap for a negative number:
A roman numeral is a string.

To process a remainder given a roman numeral and a letter string is a number:
  If the letter is "", exit.
  Divide the remainder by the number giving a quotient and the remainder.
  Fill a temp string with the letter's first's target given the quotient.
  Append the temp string to the roman numeral.

To convert a number to a roman numeral:
  If the number is negative, exit.
  Put the number in a remainder.
  Process the remainder given the roman numeral and "M" is 1000.
  Process the remainder given the roman numeral and "D" is  500.
  Process the remainder given the roman numeral and "C" is  100.
  Process the remainder given the roman numeral and "L" is   50.
  Process the remainder given the roman numeral and "X" is   10.
  Process the remainder given the roman numeral and "V" is    5.
  Process the remainder given the roman numeral and "I" is    1.

Wait, is this a programming language?

@Adam -- Yes.  Plain English compiles, and runs, and everything.  The source code and IDE are available at https://github.com/Folds/english

Do golf it though - after all, this is code golf, not a language showcase.

So this is the language you use if you don't want your job outsourced I take it?

@corsiKa -- LOL!   Only if enough of us start using it (and adding to its libraries) that it achieves critical mass.

@corsiKa -- Lots of people know English (as a Second Language) well enough to use Plain English.  And the language is designed to be customized to the user's dialect or native language.  There is a professor in Argentina who has thought about using similar design principles to start a Plain Spanish language.  Perhaps Español Llano?

APL (Dyalog), 25 22 bytes
'MDCLXVI'/⍨(0,6⍴2 5)∘⊤

Try it online!

Nice, and basically the solution I had in mind. However, you can use replicate (/) instead of reshape (⍴) so you can cut out the each and the catenate-reduction (¨ and ,/).

Also, you can convert to tradfn body and take input (⎕) and use commute (⍨) to remove the parens and compose (∘).

Thanks, but what do you mean by your second comment? I can't think of a way to do that without increasing byte count

'MDCLXVI'/⍨⎕⊤⍨0,6⍴2 5

@Adám Unless we're talking about a REPL environment I don't think that matches any accepted output format

Try it online!

That would be a snippet unless you count the {} or ∇f∇ surrounding the function

No, plenty of answers contain just a tradfn body. The additional characters are just to name it. By "snippets" I mean just a piece of code which expects the input to be stored in a hardcoded variable and stores the output in another hardcoded variable, or prints it. Here you prompt for input. To name a function you do ⎕FX name body. The name doesn't add any functionality as long as it isn't a whole function header.

Retina, 57 42 bytes
Converts to unary, then greedily replaces bunches of Is with the higher denominations in order.
.*
$*I
I{5}
V
VV
X
X{5}
L
LL
C
C{5}
D
DD
M

Try it online
Saved 15 bytes thanks to Martin

That's very clever.

It's a lot shorter to go the other way: https://tio.run/##K0otycxL/K@q4Z7wX0@LS0XLk8uz2rSWK4wrLIwrgisCxPbh8vHhcuZyBrFduFxcuHz//zfmMuEyMeIytzTjMjIwNOcyNLMwMAcA

Couldn't you take input in unary using I as unit?

@Adám Considering that Retina can now easily handle integer input, I think it's kind of cheap to do that.

Python 2, 64 bytes
f=lambda n,d=5,r='IVXLCD':r and f(n/d,7-d,r[1:])+n%d*r[0]or'M'*n

Try it online!
Rather than creating the output string from the start by greedily taking the largest part, this creates it from the end. For instance, the number of I's is n%5, then the number of V's is n/5%2, and so on. This is mixed base conversion with successive ratios of 5 and 2 alternating.
Here's an iterative equivalent:
Python 2, 68 bytes
n=input();s='';d=5
for c in'IVXLCD':s=n%d*c+s;n/=d;d^=7
print'M'*n+s

Try it online!
The M's need to be handled separately because any number of them could be present as there's no larger digit. So, after the other place values have been assigned, the value remaining is converted to M's.
For comparison, a greedy strategy (69 bytes):
Python 2, 69 bytes
f=lambda n,d=1000,r='MDCLXVI':r and n/d*r[0]+f(n%d,d/(d%3*3-1),r[1:])

Try it online!
The current digit value d is divided by either 2 or 5 to produce the next digit. The value of d%3 tell us which one: if d%3==1, divide by 2; and if d%3==2, divide by 5.

Mathematica, 81 bytes
Table@@@Thread@{r=Characters@"MDCLXVI",#~NumberDecompose~FromRomanNumeral@r}<>""&

Explicitly using the values and deriving the corresponding numerals seems to be one byte longer:
Table@@@Thread@{RomanNumeral[n={1000,500,100,50,10,5,1}],#~NumberDecompose~n}<>""&

Nice!: FromRomanNumeral@r

Excel, 236 193 161 bytes
43 bytes saved thanks to @BradC
At this point, the answer really belongs totally to @BradC.  Another 32 bytes saved.
=REPT("M",A1/1E3)&REPT("D",MOD(A1,1E3)/500)&REPT("C",MOD(A1,500)/100)&REPT("L",MOD(A1,100)/50)&REPT("X",MOD(A1,50)/10)&REPT("V",MOD(A1,10)/5)&REPT("I",MOD(A1,5))

Formatted:
=REPT("M",A1/1E3)
    &REPT("D",MOD(A1,1E3)/500)
    &REPT("C",MOD(A1,500)/100)
    &REPT("L",MOD(A1,100)/50)
    &REPT("X",MOD(A1,50)/10)
    &REPT("V",MOD(A1,10)/5)
    &REPT("I",MOD(A1,5))

You'll save some by replacing CONCATENATE with & between each element, and QUOTIENT with INT(A/B).

2 more savings: turns out REPT already truncates the number if it isn't an integer, so you can save 30 more bytes by removing each INT(). Save 2 more by replacing both 1000 with 1E3 (although Excel doesn't seem to want to keep it that way once you hit enter).

Yeah, saw the 1E3 behaviour.  Answer updated.

05AB1E, 29 26 25 bytes
¸5n3×Rvćy‰ì}"MDCLXVI"Ss×J

Try it online!
Explanation
¸                           # wrap input in a list
 5n                         # push 5**2
   3×                       # repeat it 3 times
     Rv                     # for each digit y in its reverse
       ć                    # extract the head of the list
                            # (div result of the previous iteration, initially input)
        y‰                  # divmod with y
          ì                 # prepend to the list
           }                # end loop
            "MDCLXVI"S      # push a list of roman numerals
                      s×    # repeat each a number of times corresponding to the result
                            # of the modulus operations
                        J   # join to string

CJam, 35 28 bytes
-7 bytes thanks to Martin Ender
q~{5md\2md\}3*]W%"MDCLXVI".*

Try it online!
Explanation
q~         e# Read and eval input (push the input as an integer).
{          e# Open a block:
 5md\      e#  Divmod the top value by 5, and bring the quotient to the top.
 2md\      e#  Divmod that by 2, and bring the quotient to the top.
}3*        e# Run this block 3 times.
]W%        e# Wrap the stack in an array and reverse it. Now we've performed the mixed-base
           e# conversion.
"MDCLXVI"  e# Push this string.
.*         e# Element-wise repetition of each character by the numbers in the other array.
           e# Implicitly join and print.

Perl 5, 66 bytes
65 bytes of code + -p flag.
$s=1e3;for$@(MDCLXVI=~/./g){$\.=$@x($_/$s);$_%=$s;$s/=--$|?2:5}}{

Try it online!
Without changing the byte count, MDCLXVI=~/./g can be replaced by M,D,C,L,X,V,I; and --$|?2:5 by $|--*3+2.
Much longer (99 bytes), there is:
$_=M x($_/1e3).D x($_%1e3/500).C x($_%500/100).L x($_%100/50).X x($_%50/10).V x($_%10/5).I x($_%5)

C#, 127 bytes
f=n=>n>999?"M"+f(n-1000):n>499?"D"+f(n-500):n>99?"C"+f(n-100):n>49?"L"+f(n-50):n>9?"X"+f(n-10):n>4?"V"+f(n-5):n>0?"I"+f(n-1):""

A purely hard coded ternary statement using recursion.
Full/Formatted version:
using System;

class P
{
    static void Main()
    {
        Func<int, string> f = null;
        f = n => n > 999 ? "M" + f(n - 1000)
                         : n > 499 ? "D" + f(n - 500)
                                   : n > 99 ? "C" + f(n - 100)
                                            : n > 49 ? "L" + f(n - 50)
                                                     : n > 9 ? "X" + f(n - 10)
                                                             : n > 4 ? "V" + f(n - 5)
                                                                     : n > 0 ? "I" + f(n - 1)
                                                                             : "";

        Console.WriteLine(f(3));
        Console.WriteLine(f(4));
        Console.WriteLine(f(42));
        Console.WriteLine(f(796));
        Console.WriteLine(f(2017));
        Console.WriteLine(f(16807));

        Console.ReadLine();
    }
}

n>0 is just n.

@CalculatorFeline Not in C#, an int can't be implicitly cast to a bool.

That's unfortunate.

@CalculatorFeline Yeah, C# is too strongly typed for it's own good sometimes.

JavaScript (ES6), 81 75 69 Bytes
Saved 6 bytes thanks to @Neil for porting @Jörg Hülsermann's answer
Saved 6 bytes thanks to @Shaggy
n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)

Test cases:

f=
n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)

const testCases = [3, 4, 42, 796, 2017, 16807]
testCases.forEach(testCase => console.log(f(testCase)))

You should be able to move the n%=x within the repeat method to save a few bytes.

FYI a port of the PHP answer is only 69 bytes: n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)

Thanks @Neil, I've updated the post. Removes the hard coded array which I was wanting to revisit

Python 3, 100 97 96 94 93 91 90 bytes

saved 4+2 bytes: use of def; array as default parameter reduced an indentation space; unwanted variable declaration removed
@shooqie saved 1 byte a%= shorthand
saved 2 bytes: rearranged and braces in (a//i) got removed
@Wondercricket saved 1 byte: move the array from default parameter to within the function which removed [] at the cost of one indentation space, thus saving 1 byte.

def f(a):
 b=1000,500,100,50,10,5,1
 for i in b:print(end=a//i*'MDCLXVI'[b.index(i)]);a%=i

Try it online!

a%=i is a byte shorter :)

You can also save a byte by storing b as a variable within the
function. That removes the necessity of brackets - b=1000,500,100,50,10,5,1

///, 50 bytes
/1/I//IIIII/V//VV/X//XXXXX/L//LL/C//CCCCC/D//DD/M/

Try it online!
Takes input in unary, and I'm (ab)using the footer field on TIO for input so output is preceded by a newline.

Cubix, 69 74 80 bytes
/.UI,..N&..0\0&/52"IVXLCDM"U,r%ws;rr3tu;pw..u;qrUosv!s.u\psq,!@Us(0;U

Try it online!
        / . U I
        , . . N
        & . . 0
        \ 0 & /
5 2 " I V X L C D M " U , r % w
s ; r r 3 t u ; p w . . u ; q r
U o s v ! s . u \ p s q , ! @ U
s ( 0 ; U . . . . . . . . . . .
        . . . .
        . . . .
        . . . .
        . . . .

Watch It Running
I have managed to compress it a bit more, but there is still some pesky no-ops, especially on the top face.

52"IVXLCDM"U put the necessary divisors and characters on the stack.  The 5 and 2 will be used to reduce the div/mod value and the characters will be discarded after use.
UIN0/&0\&,/U u-turns onto the top face and starts a long tour to get the input and push 1000 onto the stack.  An initial divide is done and a u-turn onto the r of the next snippet.  This was an area I was looking at to make some savings.
,r%ws;rr beginning of the divmod loop.  integer divide, rotate the result away mod, then rearrange top of stack to be reduced input, current divisor and divide result.
3tus bring the current character to the top and swap it with the divide result.
!vsoUs(0;U this is the print loop.  while the div result is more than 0, swap with character output, swap back, decrement, push a 0 and drop it.  On 0 redirect over the pop stack (remove divide result) and around the cube.
\u;pwpsq,!@Urq;u with a bit of redirection, this removes the character from the stack, brings the 5 and 2 to the top, swaps them and pushes one back down.  The remaining is used to reduce the divisor.  Halt if it reduces to 0, otherwise push the 5 or 2 to the bottom and re-enter the loop.

Python 2, 109 90 bytes
lambda n,r=[1000,500,100,50,10,5,1]:''.join(n%a/b*c for a,b,c in zip([n+1]+r,r,'MDCLXVI'))

Try it online!

1000 can be 1e3 (if you don't mind it being a float which shouldn't be a problem)

@CalculatorFeline it would turn the result into a float, and you can't multiply a string by a float :c

Mathematica, 130 bytes
(f=#~NumberDecompose~{1000,500,100,50,10,5,1};""<>{Flatten@Table[Table[{"M","D","C","L","X","V","I"}[[i]],f[[i]]],{i,Length@f}]})&

PHP, 70 bytes
for($r=1e3;$a=&$argn;)$a/$r<1?$r/=++$i%2?2:5:$a-=$r*print MDCLXVI[$i];

Try it online!

T-SQL, 164 bytes
SELECT REPLICATE('M',n/1000)+IIF(n%1000>499,'D','')
      +REPLICATE('C',n%500/100)+IIF(n%100>49,'L','')
      +REPLICATE('X',n%50/10)+IIF(n%10>4,'V','')
      +REPLICATE('I',n%5)
FROM t

Line breaks added for readability only.
This version is a lot longer (230 characters), but feels much more "SQL-like":
DECLARE @ INT,@r varchar(99)=''SELECT @=n FROM t
SELECT'I's,1v INTO m
INSERT m VALUES('V',5),('X',10),('L',50),('C',100),('D',500),('M',1000)
L:
    SELECT @-=v,@r+=s
    FROM m WHERE v=(SELECT MAX(v)FROM m WHERE v<=@)
IF @>0GOTO L
SELECT @r

Makes a table m with all the char-value mappings, and then loops through finding the largest value <= the number, concatenating the matching character.

Japt, 34 bytes
"IVXLCD"£%(U/=Y=v *3+2Y)îXÃw i'MpU

Test it online!
"IVXLCD"£    %(U/=Y=v  *3+2Y )îXÃ w i'MpU
"IVXLCD"mXY{U%(U/=Y=Yv *3+2,Y)îX} w i'MpU : Ungolfed
                                          : Implicit: U = input number
"IVXLCD"mXY{                    }         : Map each char X and its index Y in this string to:
                  Y=Yv *3+2               :   Set Y to 5 for even indexes, 2 for odd.
               U/=                        :   Divide U by this amount.
            U%(            ,Y)            :   Modulate the old value of U by 5.
                              îX          :   Repeat the character that many times.
                                          : This returns e.g. "IIVCCCD" for 16807.
                                  w       : Reverse the entire string.
                                    i'MpU : Prepend U copies of 'M' (remember U is now the input / 1000).
                                          : Implicit: output result of last expression

JavaScript (ES6), 65 bytes
A recursive function.
f=(n,a=(i=0,1e3))=>n?a>n?f(n,a/=i++&1?5:2):'MDCLXVI'[i]+f(n-a):''

How?
The second recursive call f(n-a) really should be f(n-a,a). By omitting the 2nd parameter, a and i are reinitialized (to 1000 and 0 respectively) each time a new Roman digit is appended to the final result. This causes more recursion than needed but doesn't alter the outcome of the function and saves 2 bytes.
Test cases

f=(n,a=(i=0,1e3))=>n?a>n?f(n,a/=i++&1?5:2):'MDCLXVI'[i]+f(n-a):''

console.log(f(3))
console.log(f(4))
console.log(f(9))
console.log(f(42))
console.log(f(796))
console.log(f(2017))
console.log(f(16807))

J, 26 23 bytes
3 bytes saved thanks to Adám.
'MDCLXVI'#~(_,6$2 5)&#:

Try it online!
Similar to the APL answer basically the same thing.
'MDCLXVI'#~(_,6$2 5)&#:
           (       )&#:   mixed base conversion from decimal
              6$2 5       2 5 2 5 2 5
            _,            infinity 2 5 2 5 2 5
                          this gives us e.g. `0 0 0 0 1 0 4` for input `14`
'MDCLXVI'#~               shape each according to the number of times on the right
                          this is greedy roman numeral base conversion

Not that I know J, but why #.inv instead of #:?

@Adám Ah, good point. I customarily use #.inv instead of #:, since something like 2 #: 4 is 0, whilst 2 #.inv 4 is 1 0 0

Yeah, I do the same thing in APL. Now your solution is truly equivalent to the APL solution.

# is /; ~ is ⍨; $ is ⍴; & is ∘; #: is ⊤. The only difference is that you use infinity _ while you could use 0 like the APL answer.

@Adám Huh, cool.

Batch, 164 bytes
@set/pn=
@set s=
@for %%a in (1000.M 500.D 100.C 50.L 10.X 5.V 1.I)do @call:c %%~na %%~xa
@echo %s:.=%
@exit/b
:c
@if %n% geq %1 set s=%s%%2&set/an-=%1&goto c

Takes input on STDIN.

Oracle SQL, 456 bytes
select listagg((select listagg(l)within group(order by 1)from dual start with trunc((n-nvl(n-mod(n,p),0))/v)>0 connect by level<=trunc((n-nvl(n-mod(n,p),0))/v)))within group(order by v desc)from (select 2849n from dual)cross join(select 1000v,null p,'m'l from dual union select 500,1000,'d'from dual union select 100,500,'c'from dual union select 50,100,'l'from dual union select 10,50,'x'from dual union select 5,10,'v'from dual union select 1,5,'i'from dual)

Outputs:
mmdcccxxxxviiii

Please note the actual size of the line is 460bytes, because it includes the input number (2849).
Ungolfed:
select listagg(
            (select listagg(l, '') within group(order by 1)
             from dual
             start with trunc((n-nvl(p*trunc(n/p),0))/v) > 0
             connect by level <= trunc((n-nvl(p*trunc(n/p),0))/v) )
        ) within group(order by v desc)
from (select 2348 n
    from dual
) cross join (
    select 1000v, null p, 'm' l from dual union
    select 500, 1000, 'd' from dual union
    select 100, 500, 'c' from dual union
    select 50, 100, 'l' from dual union
    select 10, 50, 'x' from dual union
    select 5, 10, 'v' from dual union
    select 1, 5, 'i' from dual
)

How it works:
I calculate how many of each letter I need, by calculating the most I can get to with the higher value one (infinity for M), and then doing an integer division between the current letter's value and the result of that.
E.g. 2348, how many Cs do I need? trunc((2348-mod(2348,500))/100) = 3.
Then, I listagg that letter together 3 times (exploiting CONNECT BY to generate the 3 rows I need).
Finally, I listagg everything together.
Kinda bulky, but most of it is the select from duals in the conversion table and I can't really do much about that...

Charcoal, 61 50 46 bytes
ＮνＡ⁰χＷφ«Ｗ¬‹νφ«§MDCLXVIχＡ⁻νφν»Ａ⁺¹χχＡ÷φ⎇﹪χ²¦²¦⁵φ

Try it online!
Explanation:
Ｎν                   Take input as number and assign it to ν
Ａ⁰χ                  Let χ=0
Ｗφ«                  While φ>0 (φ has a predefined value of 1000)
    Ｗ¬‹νφ«               While v>=φ
        §MDCLXVIχ             Take the char from string "MDCLXVI" at position χ
        Ａ⁻νφν»               Let ν=ν-φ
    Ａ⁺¹χχ                Increment χ
    Ａ÷φ⎇﹪χ²¦²¦⁵φ        If χ is odd, divide φ by 5, else divide φ by 2

4 bytes saved thanks to Neil, while I am still trying to figure out how to proceed with the second part of his comment.

Ｎν is one byte shorter than ＡＮν, ¬‹ is one byte shorter than subtracting 1, and if you use ÷ (IntDivide) instead of ∕ (Divide) then you can use φ as the outer loop condition. However, I think you can get it down to 40 bytes by looping over MDCLXVI directly instead.

@Neil of course, silly me, trying to understand why there is no "greater or equal" operator when I could use "not less". Very clever trick the use of the integer division. Now allow me some time to think about the last part of your comment...

I improved my string loop idea and posted it as a seprate answer along with a port of @xnor's Python answer, which turned out to be the same length.

Java (OpenJDK 8), 119 118 bytes
n->{String s="";for(int v[]={1,5,10,50,100,500,1000},i=7;i-->0;)for(;n>=v[i];n-=v[i])s+="IVXLCDM".charAt(i);return s;}

Try it online!
Saved a byte thanks to @TheLethalCoder

Can you declare v and i in the first for loop to save a byte?

@TheLethalCoder Yes, most certainly. I was on a totally other idea at first that this didn't pass my internal review :p

Charcoal, 34 bytes
ＮςＡ²ξＦMDCLXVI«×ι÷ςφＡ﹪ςφςＡ÷φξφＡ÷χξξ

Originally based on @CarlosAlego's answer. A port of @xnor's Python solution is also 34 bytes:
ＮθＡ⁵ξＦIVXLCD«←×ι﹪θξＡ÷θξθＡ÷χξξ»←×Mθ

Edit: A port of @xnor's other Python solution turns out to be 33 bytes!
ＮθＦMDCLXVI«×ι÷θφＡ﹪θφθＡ÷φ⁺×³﹪φ³±¹φ

Try it online! Link is to verbose version of code. Note that I've used ⁺×³﹪φ³±¹ instead of ⁻×³﹪φ³¦¹ because the deverbosifier is currently failing to insert the separator.

Huh, that looks more Greek than Roman.

C++, 272 Bytes
#include <cstdio>
#include <map>
std::map<int,char> m = {{1000,'M'},{500,'D'},{100,'C'},{50,'L'},{10,'X'},{5,'V'},{1,'I'}};
int main(){unsigned long x;scanf("%d",&x);for(auto i=m.rbegin();i!=m.rend();++i)while(x>=i->first){printf("%c", i->second);x=x-i->first;}return 0;}

C, 183 Bytes
#include <stdio.h>
int v[]={1000,500,100,50,10,5,1};
char*c="MDCLXVI";
int main(){int x;scanf("%d",&x);for(int i=0;i<sizeof v/sizeof(int);i++)for(;x>=v[i];x-=v[i])putc(c[i],stdout);}

Same algorithm as before, just using plain c arrays instead of an std::map, partially inspired by @xnor's answer and using a string to store the letters.

98 bytes

Common Lisp, 113 bytes
This is an anonymous function, returning the result as a string.
(lambda(value)(setf(values a b)(floor v 1000))(concatenate 'string(format()"~v,,,v<~>"a #\M)(format nil"~@:r"b)))

Ungolfed, with descriptive variable names and comments:
(defun format-roman (value)
  ;; Get "value integer-divided by 1000" and "value mod 1000"
  (setf (values n_thousands remainder) (floor value 1000))
  (concatenate 'string
               ;; Pad the empty string n_thousands times, using "M" as the
               ;; padding character
               (format () "~v,,,v<~>" n_thousands #\M)
               ;; Format the remainder using "old-style" Roman numerals, i.e.
               ;; numerals with "IIII" instead of "IV"
               (format nil "~@:r" remainder)))

CL has built-in Roman numeral formatter. Sadly it doesn't work for numbers larger than 3999.