!I!n!s!e!r!t! !n!b!e!t!w!e!e!n!Cc M23u Eeno P1 Yy u袋D R Ju
Posted from here.
This challenge is highly "distilled" from this question. Special thanks to @Akababa!
In this task, you should insert an exclamation mark at the start of the string and after every character.
Rules
- There will always be a non-empty-string input. The input will not contain tabs either. You can assume that the input only contain non-extended ASCII printable characters and newlines.
- The input will not contain trailing newlines as long as your language can't detect a newline.
- This is a code-golf contest; the shortest answer should win.
Examples
- 4 newlines result in 5 newline-delimited exclamation marks. It is very hard to put this as a Markdown text, so this is stated instead.
1 2 3 4 5 6 129591 129012 129127 129582 0
Outputs
!1! !2! !3! !4! !5! !6! !1!2!9!5!9!1! !1!2!9!0!1!2! !1!2!9!1!2!7! !1!2!9!5!8!2! ! !0!
asd afjoK ak:e
kPrLd
fOJOE;
KFO
KFkepjgop sgpaoj faj
Outputs
!a!s!d! !a!f!j!o!K! !a!k!:!e! !k!P!r!L!d! ! ! ! ! !f!O!J!O!E!;! ! ! ! ! !K!F!O! !K!F!k!e!p!j!g!o!p! !s!g!p!a!o!j! ! ! !f!a!j!
A base test case with only one character:
a
Outputs
!a!
(Auto-completion! Just kidding, there is no such thing.) Contains exclamation marks:
!! !! !! !! !!
Outputs:
!!!!! !!!!! !!!!! !!!!! !!!!!
-
4\\$\\begingroup\\$ very similar question \\$\\endgroup\\$ – Giuseppe yesterday
-
\\$\\begingroup\\$ I didn't encounter this in the Sandbox though. (Also, that question takes one line of input.) \\$\\endgroup\\$ – A__ yesterday
-
\\$\\begingroup\\$ Downvoting without stating the reason is not a good idea. "The purpose of the policy is that I shouldn't be able to reuse the same answer to multiple questions." \\$\\endgroup\\$ – A__ yesterday
-
6\\$\\begingroup\\$ I really don't understand the downvote - this is a clear and well written challenge. Re: being a duplicate - it's not (preceding '!' makes for a big difference), and I don't believe anyone has suggested so (no close votes). \\$\\endgroup\\$ – Jonathan Allan yesterday
-
5\\$\\begingroup\\$ Downvotes are inserted between every upvote, just like what the challege describes. \\$\\endgroup\\$ – A__ 23 hours ago
41 Answers
QuadR, 1 byte
Thanks to A__ for halving the byte count!
!
Try it online!
Replaces nothing with !
Retina 0.8.2, 2 bytes
!
Try it online! At last, a challenge where Retina has a built-in!
-
1\\$\\begingroup\\$ Actually, I created this challenge based on this Retina built-in. \\$\\endgroup\\$ – A__ yesterday
-
\\$\\begingroup\\$ Works in QuadR too. \\$\\endgroup\\$ – Adám 23 hours ago
-
\\$\\begingroup\\$ -1 bytes in QuadR. \\$\\endgroup\\$ – A__ 22 hours ago
-
2\\$\\begingroup\\$ @A__ Right, I forgot about that feature (If there is only one non-function line…). You may want to re-consider your check-mark. \\$\\endgroup\\$ – Adám 19 hours ago
Python 3, 27 bytes
lambda s:f"!{'!'.join(s)}!"
Try it online!
Honestly, I hope someone can show me a cool way to do this with a smaller byte count.
-
\\$\\begingroup\\$ This doesnt handle the empty line case correctly \\$\\endgroup\\$ – flakes 9 hours ago
-
\\$\\begingroup\\$ @flakes What do you mean? If you mean an empty string: we do not need to handle an empty string (and regardless this outputs
!!in that case, which is what makes sense to me). If you mean the string\\n: it does, since the correct output is!\\n!. \\$\\endgroup\\$ – Jonathan Allan 4 hours ago -
3\\$\\begingroup\\$ @JAD As far as I can see, it doesn't have an empty string in the examples. Not only that, but the first rule literally states "there will always be a non-empty string input." \\$\\endgroup\\$ – squid 2 hours ago
-
1\\$\\begingroup\\$ Ah I was incorrect. The first example has an empty line in the middle of the input. But this answer will handle placing the exclamation point in the middle of that,
!\\n!\\n!. nice work. \\$\\endgroup\\$ – flakes 47 mins ago
Python 2, 27 bytes
lambda s:'!%s!'%'!'.join(s)
Try it online!
Haskell, 18 bytes
('!':).(>>=(:"!"))
-1 byte thanks to @nimi
Try it online!
-
1\\$\\begingroup\\$
('!':).saves a byte. \\$\\endgroup\\$ – nimi 22 hours ago
brainfuck, 24 bytes
>-[-[-<]>>+<]>.>,[.<.>,]
Try it online!
-
\\$\\begingroup\\$ 22 bytes \\$\\endgroup\\$ – Jo King 16 hours ago
Pepe, 47 bytes
REREEeRErEErREeeEeeeeEREEeeREEeereeREEEEeeEReee
Try it online!
Explanation:
REREEeRE # Push 0,then input (str),then 0 -> (R)
# The zeroes are pushed to correct the inserting
rEE # Begin loop labelled 0 -> (r)
rREeeEeeeeE # Push "!" -> (R)
# r flag inserts it instead of pushing
REEeeREEee # Move pointer pos 2 steps forward -> (R)
ree # Loop while (R) != 0
REEEEeeE # Remove characters of (R) that are in stack of (r)
# Removes the 0 in (R)
Reee # Output (R)
Perl 6, 16 bytes
{S:g/<![\\t]>/!/}
Try it online!
Replaces all zero width matches of non-tabs (i.e. every gap between characters) with exclamation marks. There may be a shorter way of doing zero-width assertions, though null regexes are not allowed.
Labyrinth, 19 11 10 9 bytes
33
..
",@
Try it online!
How?
We enter the Labyrinth at the top-left facing right with an infinite stack of zeros...
I / O stack
0,0,0,...
3 - pop * 10 + 3 3,0,0,0,...
- 2 neighbours, forward
3 - pop * 10 + 3 33,0,0,0,...
- 2 neighbours, forward
. - pop & print chr ! 0,0,0,...
- T junction from the side
- TOS==0, forward
, - read chr or -1 L 76,0,0,0,... or -1,0,0,0
- T junction from the base
- if TOS > 0 right:
" - no-op 76,0,0,0,...
- 2 neighbours, forward
. - pop & print chr L 0,0,0,...
- T junction from the side
- TOS==0, forward
3 - ...back to the start
- elif TOS == -1 left:
@ - exit we're out!
* right, but on the first occasion (from above) we hit the wall and turn
around, so that's like a left
Luckily we don't need to handle un-printables, otherwise the first zero-byte would turn us around at , and play havoc.
05AB1E, 4 bytes
€'!Ć
I/O as a list of characters.
Try it online.
Explanation:
€'! '# Prepend a "!"-item before each character in the (implicit) input-list
Ć # Enclose (append the first character of the list at the end of it)
# (after which the result is output implicitly)
Gema, 11 characters
\\A=\\!
?=?\\!
Unfortunately ! starts a comment in Gema, so must be escaped.
Sample run:
bash-5.0$ echo -ne '1 2 3 4 5 6\\n129591 129012 129127 129582\\n\\n0' | gema '\\A=\\!;?=?\\!'
!1! !2! !3! !4! !5! !6!
!1!2!9!5!9!1! !1!2!9!0!1!2! !1!2!9!1!2!7! !1!2!9!5!8!2!
!
!0!
Try it online!
Jelly, 5 bytes
Ż”!ṁż
A full program accepting a string, which prints the result.
Try it online!
How?
Ż”!ṁż - Main Link: list of characters, s e.g. "abc"
”! - character '!' '!'
ṁ - mould like:
Ż - s with a zero prepended "!!!!"
ż - zip together with s ["!a","!b","!c",'!']
- implicit (smashing) print !a!b!c!
Japt, 4 bytes
rP'!
Try it
Japt -P, 7 bytes
Unfortunately ! is a reserved character, necessitating the quotation marks.
ï'! i'!
Try it
Not much to explain: ï is Cartesian product and i prepends.
JavaScript (ES6), 19 bytes
Takes input as an array of characters.
s=>`!${s.join`!`}!`
Try it online!
JavaScript (ES6), 22 bytes
Suggested by @tjjfvi
Takes input as a string.
s=>s.replace(/|/g,"!")
Try it online!
JavaScript (ES6), 23 bytes
Takes input as a string.
s=>['',...s,''].join`!`
Try it online!
-
1\\$\\begingroup\\$ Alternative with
.replace, 22 bytes \\$\\endgroup\\$ – tjjfvi 18 hours ago -
\\$\\begingroup\\$ @tjjfvi Nifty one! \\$\\endgroup\\$ – Arnauld 18 hours ago
-
\\$\\begingroup\\$ I've got a 20 for your 23:
s=>[,...s,,].join`!`\\$\\endgroup\\$ – Shieru Asakoto 24 mins ago
R, 25 bytes
function(x)gsub("","!",x)
Try it online!
A function accepting and returning a character vector.
-
\\$\\begingroup\\$ Can shave 3 bytes by switching the function form to
scan(,''), like so tio.run/##K/r/P724NElDSUlHSVFJpzg5MU9DR11dU/O/… \\$\\endgroup\\$ – Sumner18 29 mins ago
J, 12 bytes
'!',,@,.&'!'
Try it online!
05AB1E, 6 bytes
-1 thanks to Kevin Cruijssen. Takes input as a list of characters.
õ.ø'!ý
Try it online! or Try it online! (with input as a string)
-
1\\$\\begingroup\\$ Are you a bit rusty golfing in 05AB1E? ;p \\$\\endgroup\\$ – Kevin Cruijssen 6 hours ago
-
1\\$\\begingroup\\$ @KevinCruijssen Perhaps (now that I think about it I kinda am) :(. But I never actually knew how to exploit
€so I guess I'm fine. \\$\\endgroup\\$ – Mr. Xcoder 6 hours ago -
1\\$\\begingroup\\$ Yeah, it's something new this version.. The regular map
εworks the same as in the legacy, but the€keeps all values on the stack. So€Dwould duplicate each character for example, while still keeping a 1D list. Not sure who's idea that was (probably Adnan), but it's useful in some cases. :) In other cases it can be pretty annoying as well, though. \\$\\endgroup\\$ – Kevin Cruijssen 6 hours ago -
1\\$\\begingroup\\$ @KevinCruijssen Interesting, thanks for the info (ahem ahem I do see it's useful sometimes :P) \\$\\endgroup\\$ – Mr. Xcoder 6 hours ago
-
\\$\\begingroup\\$ -1 byte for your approach:
õ.ø'!ý(surrounding with an empty string before joining). \\$\\endgroup\\$ – Kevin Cruijssen 6 hours ago
MathGolf, 6 bytes
É'!\\'!
Try it online!
Explanation
Nothing fancy here, just a loop
É for each character do the next 3 operations
'! push single character "!"
\\ swap top elements
'! push single character "!"
Befunge-98 (PyFunge), 7 bytes
'!,#@~,
Try it online!
Charcoal, 6 bytes
⭆S⁺!ι!
Try it online! Link is to verbose version of code. Works on empty strings too. Input format is somewhat cumbersome due to Charcoal's lack of EOF. Works by preceding each character with a ! and then suffixing a final ! on the end. Alternative version, also 6 bytes:
⪫!!⪫S!
Try it online! Link is to verbose version of code. Works by joining the characters on ! and then wrapping them in !!.
Zsh, 32 bytes
for c ('' ${(s::)1})echo -nE $c!
Try it online!
(s::) splits into characters, '' adds an empty element to the start, and then echo -nE $c! echoes each followed by an !.
SNOBOL4 (CSNOBOL4), 94 bytes
I I =INPUT :F(END)
S I LEN(1) . X REM . I :F(O)
O ='!' O X :(S)
O OUTPUT =O '!'
O = :(I)
END
Try it online!
Prints with an additional trailing newline (as SNOBOL always prints a line break). The way input is consumed, there is no way of distinguishing between a final line ending in \\n or not.
Stax, 6 5 bytes
_z'!R
Run and debug it
Replace "" with "!" using regex replacement. I don't exactly understand why this works.
Edit: Found it in the Ecma spec: 15.5.4.10
If there is a match with an emptystring (in other words, if the value of regexp.lastIndex is left unchanged), increment regexp.lastIndex by 1.
Old Stuff:
I would have been able to get to 5 bytes in either of two scenarios.
- If input was provided in an escaped literal e.g.
"line1\\nline2". But I opted against that for the sake of "usability". - If there was not a
bugfeature in stax's zip implementation when encountering empty strings/arrays.
Perl 5 + -p, 11 bytes
s/^|.\\K/!/g
Try it online!
Pyth, 8 bytes
+\\!s+R\\!
Try it online!
Code | Explanation
----------+-------------------------------------
+\\!s+R\\! | Code
+\\!s+R\\!Q | with implicit variables filled
----------+-------------------------------------
R Q | For each d in input, replace d with:
+R\\! | d+"!"
s | Join results on empty string
+\\! | Add "!" to beginning
| Print (implicit)
Java 8, 20 bytes
A lambda function from String to String.
s->s.replace("","!")
Try It Online
Aheui (esotope), 61 bytes
붖다따삭바사빠맣삭붛
밙봆@뫃선차희져썬뻐
Try it online!
Nice small aheui code.
8086 machine code, .COM format (MS-DOS 2+), 32 bytes
(-1 depending on emulator: see below)
For best results redirect standard input from a file, as typing gives odd-looking output due to no buffering; also, newlines look a little weird because they are stored as CR LF, and the CR part messes up the output.
This program behaves fine in an actual MS-DOS emulation (e.g. PCjs) but DOSBox seemed to have issues with Ctrl+Z EOF (see comments in the assembly listing), so DON'T try to enter input using the console in DOSBox unless you add the extra check!
BB 01 00 53 59 BA 0B 01 B4 40 CD 21 4A 4B B4 3F CD 21 85 C0 74 09 B4 40 43 41 CD 21 49 EB EE C3
Some interesting bits:
I saved some data space by reusing memory that had already been executed (the
21HinINT 21Hhappens to be!)I was almost able to use an interesting trick that I found on the page "The Hidden Power of BCD Instructions" which would have allowed me to use
AAAinstead of a standardTESTto compareALto 0, saving one byte. Unfortunately, this is not fully documented so I couldn't rely on it: for example, PCjs doesn't adjust anything but the carry and auxiliary carry flags. :-(
Assembly code (TASM ideal mode):
IDEAL
MODEL TINY
CODESEG
ORG 100H
;; DOSBox (tested with 0.74-2) didn't seem to handle Ctrl-Z as EOF
;; so uncomment the ";;" lines to run it there.
MAIN:
MOV BX,1
PUSH BX
POP CX
MOV DX,OFFSET MAIN_1+1 ; The 21H in INT 21H
MOV AH,40H
MAIN_1:
INT 21H
DEC DX
;;PUSH DX
;;POP SI
IO_LOOP:
DEC BX
MOV AH,3FH
INT 21H
;;; This should work on an non-emulated PC.
;;;AAA ; AL=0?
TEST AX,AX
JZ DONE
;;CMP [BYTE PTR SI],1AH
;;JZ DONE
MOV AH,40H
INC BX
INC CX
INT 21H
DEC CX
JMP IO_LOOP
DONE:
RET
ENDS
END MAIN
Whitespace, 79 bytes
[N
S S N
_Create_Label_LOOP][S S S N
_Push_0][S N
S _Duplicate_0][T N
T S _Read_STDIN_as_character][T T T _Retrieve_input][S N
S _Duplicate_input][S S S T S S T N
_Push_9_tab][T S S T _Subtract][N
T S S N
_If_0_jump_to_Label_END][S S S T S S S S T N
_Push_33_!][T N
S S _Print_as_character][T N
S S _Print_as_character][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_END][S S S T S S S S T N
_Push_33_!][T N
S S _Print_as_character]
Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.
Since Whitespace inputs one character at a time, the input should contain a trailing tab (\\t) so it knows when to stop reading characters and the input is done.
Try it online (with raw spaces, tabs and new-lines only).
Explanation in pseudo-code:
Start LOOP:
Character c = STDIN as character
If(c == '\\t'):
Call function END
Print '!'
Print c
Go to next iteration of loop
function END:
print '!'
PHP, 65 52 bytes
-13 bytes by using a function and dropping the need to handle multi-line inputs from STDIN.
function($s){return'!'.join('!',str_split($s)).'!';}
Try it online!