46
\$\begingroup\$

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 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:

!!!!!
!!!!!
!!!!!
!!!!!
!!!!!
\$\endgroup\$
12
  • 7
    \$\begingroup\$ very similar question \$\endgroup\$
    – Giuseppe
    Aug 18, 2019 at 11:06
  • 9
    \$\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\$ Aug 18, 2019 at 13:45
  • 1
    \$\begingroup\$ if a language can't tell the difference between a\n and a, can we require that there are no trailing newlines? \$\endgroup\$
    – Giuseppe
    Aug 18, 2019 at 14:29
  • 31
    \$\begingroup\$ Downvotes are inserted between every upvote, just like what the challege describes. \$\endgroup\$
    – user85052
    Aug 18, 2019 at 14:34
  • 1
    \$\begingroup\$ Is the case of a single space input " ", is the output supposed to be "!" or "! !" \$\endgroup\$
    – Kai
    Aug 19, 2019 at 3:52

97 Answers 97

2
\$\begingroup\$

K (ngn/k), 13 12 bytes

-1 byte from @ngn's savings

{x,/y,'x}"!"

Try it online!

Creates a function projection, with x fixed to "!".

  • y,'x pair-wise append an exclamation mark to each character in the input
  • x,/ flatten the list, using "!" as the seed (to prepend the leading "!")
\$\endgroup\$
1
  • 1
    \$\begingroup\$ save a byte by turning "!" into a curried argument: f:{x,/y,'x}"!" \$\endgroup\$
    – ngn
    Feb 12, 2021 at 19:05
2
\$\begingroup\$

C (gcc), 48 45 39 bytes

f(char*s){printf("!%.1s",s++)>1&&f(s);}

Try it online!

-3 thanks to ceilingcat

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

AWK, 11 bytes

gsub(_,"!")
 echo '
1 2 3 4 5 6
129591 129012 129127 129582

0
asd afjoK ak:e
kPrLd
    fOJOE;
    KFO
KFkepjgop sgpaoj   faj
!!
!!
!!
!!
!!' | awk 'gsub(_,"!")'

!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!
!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!
!!!!!
!!!!!
!!!!!
!!!!!
!!!!!
\$\endgroup\$
7
  • \$\begingroup\$ It doesn’t work \$\endgroup\$ May 29 at 9:15
  • 1
    \$\begingroup\$ i've cleaned up your answer formatting. In the future, please try to make it clear which part of your submission is your actual answer. (side note: this is almost identical to a previous answer) \$\endgroup\$
    – Jo King
    May 30 at 13:22
  • \$\begingroup\$ @Hippopotomonstrosesquipedalian This seems to work fine, why do you think it doesn't? \$\endgroup\$
    – mousetail
    May 30 at 15:03
  • \$\begingroup\$ @mousetail it works now, but it didn’t before with the word “awk” in front of it. \$\endgroup\$ May 30 at 15:38
  • \$\begingroup\$ @Hippopotomonstrosesquipedalian Copy pasting the code before the edit in bash already gave the correct solution even before the edit \$\endgroup\$
    – mousetail
    May 30 at 15:40
2
\$\begingroup\$

Python, 30 Bytes

lambda x:'!%s!'%'!'.join([*x])

It feels like these methods were designed for the challenge!

-1 from Jacob (now noodle man) by using the cursed % (Dun dun dun!)

-3 from Glorfindel for using a starred method for conversion!

!T!r!y! !r!u!n!n!i!n!g! !i!t! !o!n!l!i!n!e!

\$\endgroup\$
3
  • \$\begingroup\$ Here's 33, I don't know much python so it can likely be golfed further \$\endgroup\$
    – noodle man
    May 29 at 14:07
  • \$\begingroup\$ list(...) can always be [*...] instead \$\endgroup\$
    – Jo King
    May 30 at 13:24
  • 1
    \$\begingroup\$ 27 bytes - you don't even need to convert it to a list, since any iterable will work. \$\endgroup\$
    – The Thonnu
    May 30 at 14:53
2
\$\begingroup\$

Rockstar, 67 bytes

listen to S
while S
cut S
join S with "!"
say "!"+S+"!"
listen to S

Try it here (Code will need to be pasted in)

\$\endgroup\$
2
\$\begingroup\$

Python 3, 29 Bytes

print('',*input(),'',sep="!")

Try It Online

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

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 !!.

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

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.

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

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.

  1. If input was provided in an escaped literal e.g. "line1\nline2". But I opted against that for the sake of "usability".
  2. If there was not a bug feature in stax's zip implementation when encountering empty strings/arrays.
\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 49 48 42 bytes

#~StringSplit~""~StringRiffle~{a="!",a,a}&

Try it online!

-6 bytes thanks to @attinat

\$\endgroup\$
2
  • \$\begingroup\$ The code in the Header, Code, and Footer sections is run. You can use infix notation and drop the { } in StringSplit for 42 bytes \$\endgroup\$
    – att
    Aug 19, 2019 at 23:24
  • \$\begingroup\$ @attinat Thanks that helps a lot! \$\endgroup\$
    – Kai
    Aug 20, 2019 at 19:50
1
\$\begingroup\$

Elvish, 32 bytes

use re;re:replace "" "!" (slurp)

Copy and paste into the Live Environment to try it out!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Welcome to the site! Would it be possible to edit in a link to an online interpreter, such as Try it online! so that other users can verify your program? \$\endgroup\$ Aug 22, 2019 at 12:04
  • \$\begingroup\$ @cairdcoinheringaahing I added a link to the provided live environment. \$\endgroup\$
    – kon
    Aug 22, 2019 at 13:36
1
\$\begingroup\$

Ahead, 12 bytes

~irj!'~
@Wu<

Try it online!

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

Lua, 31 bytes

print((io.read():gsub("","!")))
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 32 bytes

f(s){printf("!%s",s)-1&&f(s+4);}

Try it online!

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

Red, 47 bytes

func[s][parse s[insert"!"any[skip insert"!"]]s]

Try it online!

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

C#, 142 bytes

public class P{public static void Main(string[]a){System.Console.Write("!");foreach(char c in a[0]){System.Console.Write(c.ToString()+"!");}}}
\$\endgroup\$
0
1
\$\begingroup\$

Pip, 5 bytes

aJW'!

Try it online!

The JW builtin was made for challenges like this.

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

Zsh, 12 bytes

<<<${1///!}!

Try it online!

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

Branch, 11 bytes

33.,[.33.,]

Try it on the online Branch interpreter!

Put 33 on the tree and output (!). Then, grab input. Finally, while that value is not EOF, output it, output 33 (!), and grab input again.

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

Vim, 13 bytes

:%s/\_./!&/g

Works by putting a ! before every character, including newline characters. The TIO version doesn't work properly for the 4 newline testcase, but it does work in Vim.

Try it online!

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

BRASCA, 14 13 bytes

-1 byte thanks to RezNesX

,![$'!oo{]'!o

Try it online!

Explanation

,               - Reverse stack
 ![$    {]      - Loop stack length:
    '!oo        -     Print "!" followed by the next letter
          '!o   - Print the last "!"
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 13 bytes: ,![$'!oo{]'!o \$\endgroup\$
    – RezNesX
    May 12, 2021 at 11:20
1
\$\begingroup\$

Subleq (8-bit), 1211 bytes

-1 byte for removing last 0

2 -1 33
-1 8 -1
8 -1 0
8 8 

Subleq emulator

Explanation

0:  2 -1 33 ' Output 2: (char(33)); 3rd argument is not used for output so use it for memory
3: -1  8 -1 ' Read input to 8:, exit if null
6:  8 -1  0 ' Output 8:
9:  8  8    ' 8: = 0 goto 0
\$\endgroup\$
1
\$\begingroup\$

Go, 105 bytes

import."regexp"
func f(s[]byte)[]byte{return append(MustCompile(`(?s).`).ReplaceAll(s,[]byte(`!$0`)),33)}

Attempt This Online!

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

Excel, 44 bytes

="!"&CONCAT(MID(A1,SEQUENCE(LEN(A1)),1)&"!")
  • "!" is just the first !.
  • CONCAT(MID(A1,SEQUENCE(LEN(A1)),1)&"!")
    • SEQUENCE(LEN(A1)) creates an array 1, 2, ... X where X is the length of the input.
    • MID(A1,SEQUENCE(~),1) pulls the nth character from the input.
    • MID(~)&"!" adds ! after every one of those characters.
    • CONCAT(MID(~)&"!") combines all those nth character + ! into one string.

Screenshot

Note: The line breaks are there with or without Word Wrap turned on but it won't look right until you turn it on. The screenshot has Word Wrap turned on.

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

Factor,  31  28 bytes

[ 33 interleaved [I !${}!I]]

Attempt This Online!

  • 33 interleaved Insert an exclamation point between each character of the input.

  • [I !${}!I] Interpolate the above string into the ${}, adding exclamation points to the beginning and end, and print.

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

BQN, 11 bytes

'!'⊸(⊣∾´∾¨)

Anonymous tacit function that takes and returns a string. Try it at BQN online!

Explanation

'!'⊸(⊣∾´∾¨)
    (      )  Call the following function with the original argument on the right
'!'⊸          and '!' on the left:
         ∾¨     Concatenate each (prepends '!' to each character, resulting
                in a list of two-character strings)
       ∾´       Right-fold that list on concatenation
     ⊣          with a starting value of the left argument (i.e. '!')

A port of Sʨɠɠan's APL solution is also 11 bytes:

(∾⊢∾∾¨)⟜'!'

Try it!

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

C, 42 bytes

f(char *s){printf("!%c",*s);if(*s++)f(s);}

Essentially to not have to have two printf statments I have the printf run on the null byte of the string which prints the '!' but the null byte is ignored.

Easier to read

f(char *s){
  // Prints ! and char of string
  printf("!%c", *s);
 
  // If more string than recurse for next char
  if(*s != 0) f(s+1);
}
\$\endgroup\$
1
  • \$\begingroup\$ I don't know much C, would removing that space be valid? \$\endgroup\$ Jun 9 at 5:27
1
\$\begingroup\$

(,) 111 91 Chars or \$91\log_{256}(3)\approx18.03\$ Bytes

((),()()()()()()()())((),(())(())(())(())())(,,,(()()),(,(()(),((()()())),,(())))(()()),())

TIO

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

Husk, 10 8 bytes

-2 bytes thanks to Razetime!

`:'!ṁe'!

Try it online!

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

x86-16 machine code, 8 bytes

00000000: b021 aaa4 aae2 fcc3                      .!......

Listing:

B0 21       MOV  AL, '!'        ; character to insert
AA          STOSB               ; write first ! to output string  
        CLOOP: 
A4          MOVSB               ; copy input char to output string 
AA          STOSB               ; write ! to output string 
E2 FC       LOOP CLOOP          ; loop until end of input 
C3          RET                 ; return to caller

Callable function, input at SI, length in CX. Output to string at DI.

Test runs:

enter image description here

enter image description here

enter image description here

\$\endgroup\$

Your Answer

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