59
\$\begingroup\$

Challenge

Given a non-empty string S of length L consisting entirely of printable ASCII chars, output another string of length L that consists entirely of printable ASCII chars, but is not equal to S.

For the purposes of this challenge, a printable ASCII char is one between U+0020 and U+007E, inclusive; that is, from (space) to ~ (tilde). Newlines and tabs are not included.

For example, given "abcde", some valid outputs could be:

  • "11111"
  • "abcdf"
  • "edcba"

But these would be invalid:

  • "abcde"
  • "bcde"
  • "abcde0"

Test cases

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

Rules

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

Scoring

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

\$\endgroup\$
7
  • \$\begingroup\$ Note that "positive" excludes the empty string. For extra clarity, maybe replace "positive" with "nonzero"? \$\endgroup\$ – CalculatorFeline May 30 '17 at 20:30
  • 6
    \$\begingroup\$ @CalculatorFeline But that would include negative-length strings /s \$\endgroup\$ – ETHproductions May 30 '17 at 20:36
  • 1
    \$\begingroup\$ ...Those don't exist. \$\endgroup\$ – CalculatorFeline May 30 '17 at 20:38
  • \$\begingroup\$ @CalculatorFeline Better now? \$\endgroup\$ – ETHproductions May 30 '17 at 20:40
  • 3
    \$\begingroup\$ Another simple but not trivial challenge. \$\endgroup\$ – Weijun Zhou Apr 4 '18 at 15:03

71 Answers 71

2
\$\begingroup\$

Golfscript, 3 bytes

Try it online!

)5%

Take the last character's ASCII value modulo 5, and replace the last character with the result. This obviously works for non-digit characters, but if the last character is a digit, it also changes ("0" mod 5 = 3, "1" mod 5 = 4, etc).

This would also work with 7 or 9 while still keeping the same length.

Also, yay! I have a Golfscript solution as good as the best solutions here!

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

Funky, 26 22 bytes

s=>s::gsub("."a=>1&~a)

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

Try it online!

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

C/C++, 29 bytes

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

Code to test :

#include <iostream>
#include <string>
#include <cassert>

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

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

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

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

brainfuck, 35 27 bytes

Edit: switched to a better way of generating an odd number thanks to the brainfuck constants page

,[[[>]+<[-<]>]-[>+<---]>.,]

Try It Online

Prints out a string of semi-random Vs and Us. If the first character of the input is a V it will print out a U instead and vice versa.

How it Works

,[ Gets first inputted char 
  [[>]+<[-<]>] Converts the ASCII value to binary
  -[>+<---] Adds 85 to the last digit of that binary, which is the original value mod 2. 
            This converts a V (value 86) into a U (value 85) and vice versa
  >. Print the value
,] Get a new value and repeat. 
   Note that the binary of the previous value is still in memory, 
     so it no longer prints specific chars for odd or even values

Another version with the same bytecount:

,[[>]+<[-<]>]-[>+<---]>[.,]

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

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Great algorithm--it's tricky to find short algorithms to do things in BF. Don't think the second one works though; shouldn't the last bit be [.,]? \$\endgroup\$ – ETHproductions Dec 26 '17 at 19:50
2
\$\begingroup\$

Brain-Flak, 42 bytes

({}[((((()()()()){}){}){})]<>){{}}([]<>{})

Try it online!

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

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

Perl 6, 14 bytes

{.ord%7~.chop}

Try it online!

Bare block, implicit lambda with input $_. The ordinal of the first character .ord modulo 7 is a different character: Non-numeric first character becomes numeric, numeric first characters map to a different character. If we append the input sans the last character (~ $_.chop), we match the length. It can never match the input because the first character never matches.

Perl 6, 15 bytes

{S/./{.ord%7}/}

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

Try it online!

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

str, 2 bytes

XV

Try it online!

Explanation

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

Alternatively, YV to decrement instead of increment.

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

PowerShell, 37 26 bytes

Thanks Mazzy for -11 bytes

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

Try it online!

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

\$\endgroup\$
2
  • \$\begingroup\$ ? 6+3*($_-eq6) \$\endgroup\$ – mazzy Dec 28 '18 at 5:52
  • 1
    \$\begingroup\$ ? $_%9 :))))) \$\endgroup\$ – mazzy Dec 28 '18 at 7:52
1
\$\begingroup\$

JavaScript (ES6), 24 bytes

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

Changes the first character of the string according to this table:

1   0
2   3
3   2
4   5
5   4
6   7
7   6
8   9
9   8

Everything else becomes 1.

\$\endgroup\$
3
  • \$\begingroup\$ @RickHitchcock As I understand it, only one character needs to be different. \$\endgroup\$ – Neil May 30 '17 at 19:50
  • \$\begingroup\$ @RickHitchcock The very first rule states that the string can be assumed to only contain printable characters... \$\endgroup\$ – Neil May 30 '17 at 21:00
  • \$\begingroup\$ Head-slap, +1!! \$\endgroup\$ – Rick Hitchcock May 30 '17 at 21:05
1
\$\begingroup\$

><>, 11 bytes

i:0(?;'0'=n

Try it online!

Explanation

Like my MATL answer, this transforms character '0' into '1' and all other characters into '0'.

i       Input one char, or push -1 if there aren't any more chars
:       Duplicate
0(      Is it less than 0?
?;      If so, end program. Else:
'0'     Push character '0'
=       Is it equal? Gives 1 or 0
n       Output as a number. Go back to the beginning
\$\endgroup\$
2
  • \$\begingroup\$ 9 bytes if you just print the number modulo 5 \$\endgroup\$ – Jo King Dec 27 '17 at 10:17
  • \$\begingroup\$ @JoKing Thanks! But U think you should post that as a separate answer \$\endgroup\$ – Luis Mendo Dec 29 '17 at 16:16
1
\$\begingroup\$

Chip, 5 bytes

g*A~a

Try it online!

Maps all characters to either @ or A, so that the lowest bit always differs from the input:

0, @, ~, etc. map to A
1, a, A, etc. map to @

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

x86 Assembly, 19 bytes

Alternates the first character of the string between '@' and 'A'

_diffstr:
  00000000: 8B 54 24 04        mov         edx,dword ptr [esp+4]
  00000004: 8A 02              mov         al,byte ptr [edx]
  00000006: 3C 41              cmp         al,41h
  00000008: 75 04              jne         0000000E
  0000000A: B0 40              mov         al,40h
  0000000C: EB 02              jmp         00000010
  0000000E: B0 41              mov         al,41h
  00000010: 88 02              mov         byte ptr [edx],al
  00000012: C3                 ret
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 49 bytes

sub{$_="a"x length $_[0];$_++while $_ eq$_[0];$_}

Explanation:

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

Starting from "a"s was to avoid incrementing to point where Perl lengthens the string; with only one strings to avoid being same as, it couldn't overflow.

This is shamelessly cribbed (and simplified) from my answer to the "related" problem "The Third String".

Execute with:

perl -e '$s = ' -E 'sub{$_="a"x length $_[0];$_++while $_ eq$_[0];$_}' -E ';say $s->("z")'
\$\endgroup\$
1
  • \$\begingroup\$ How can it need to increment more than once? \$\endgroup\$ – Phil H Apr 4 '18 at 15:01
1
\$\begingroup\$

x86 opcode, 6 bytes

    and     byte [ecx], 0xF1
    inc     byte [ecx]
    ret     
\$\endgroup\$
1
\$\begingroup\$

Java 8, 39 38 bytes

s->(s.charAt(0)<49?9:0)+s.substring(1)

Try it online.

Explanation:

If the first character has a unicode value below 49 (space, or one of !"#$%&'()*+'-./0), change it to a '9', else change it to a '0'.

s->                 // Method with String as both parameter and return-type
  (s.charAt(0)<49?  //  If the first character has a unicode value below 49:
    9               //   Change the first character to a '9'
  :                 //  Else
   0)               //   Change the first character to a '0'
  +s.substring(1)   //  And return the rest of the input-String (if any)
\$\endgroup\$
1
\$\begingroup\$

Pyth, 9 bytes

*h-+QGhQl

Try it here

Explanation

*h-+QGhQl
   +QG      Stick the alphabet to the end of the input.
  -   hQ    Delete all instances of the first character.
 h          Take the first remaining character.
*       lQ  Multiply by the length of the (implicit) input.
\$\endgroup\$
1
\$\begingroup\$

Python 3, 29 26 bytes

lambda s:'a~'[s<'~']+s[1:]

Try it online!

  • Replacing first character with ~, if the first character is ~ already, it is replaced by a.
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 22 bytes

f(char*s){*s=~1&*s^2;}

Try it online!

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

SmileBASIC, 27 25 bytes

DEF D S
S[0]=@1[S>"2"]END

Creates a function named D that is called like:

STRING$="abcde"
D STRING$
'STRING$ is now "1bcde"

The first character is replaced with either @ or 1

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

MAWP, 11 bytes

0|[!5P5WA:]

Idea from Jo King's answer.

Prints the ASCII value of each letter modulo 5.

Try it!

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

Husk, 6 bytes

ṁ(s%5c

Try it online!

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

\$\endgroup\$
3
  • 1
    \$\begingroup\$ @Zgarb @Leo I wanted to also submit a (2-byte longer) version using the documented 'if2' usage of ? to make a bijection: m?→'~=' , but it doesn't seem to infer... any insight why not? \$\endgroup\$ – Dominic van Essen Nov 18 '20 at 10:38
  • \$\begingroup\$ You need to mention them on a thread they already commented on (or alternatively, one of their answers) \$\endgroup\$ – Razetime Nov 18 '20 at 11:24
  • \$\begingroup\$ @Razetime: Ok - thanks - finally starting to understand how to 'ping' now... \$\endgroup\$ – Dominic van Essen Nov 18 '20 at 11:26
0
\$\begingroup\$

Perl 6,  48  28 bytes

{(->{[~] (' '..'~').roll(.chars)}...*ne$_).tail}

Generates a sequence of random strings, stopping when one of them doesn't match the input. Returns the last string produced

Test it

{first *ne$_,(0,1 Xx.chars)}

Generates two strings one consisting of only 0s, the other of 1s. Returns the first that is not stringwise equal to (ne) the input ($_).

Test it

Expanded

{             # bare block lambda with implicit parameter 「$_」

  first       # return the first value where the following is true

    * ne $_,  # WhateverCode lambda ( 「*」 is the parameter )

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

Convex, 4 bytes

'0f=

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ This appears to fail (on TIO, at least) if the input is purely numeric: RuntimeException: Long Character f= not implemented \$\endgroup\$ – brhfl Dec 26 '17 at 21:53
0
\$\begingroup\$

Aceto, 16 12 9 bytes

=01`
,'pO

Run with -F to see immediate output (but works without).

Explanation:

We read a character, then push the character 0 on the stack and test for equality:

=0
,'

If equal, we push a 1.

  1`

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

  pO

This prints zeroes for any characters that aren't zeroes, and ones for zeroes, e.g.:

Input  |  Output
----------------
abcde  |  00000
11111  |  00000
10010  |  01101
\$\endgroup\$
0
\$\begingroup\$

Braingolf, 12 bytes

.#~e1-:1+|&@

Subtracts 1 from the last char's ordinal if it is a tilde, otherwise adds one.

Explanation:

.#~e1-:1+|&@  Implicit input of string, convert each char to ordinal and push to stack
.             Duplicate last item
 #~           Push tilde ordinal
   e          If last 2 items are equal (consumes last 2 items)
    1-        ..then subtract one
      :       else
       1+     ..add one
         |    endif
          &@  Print entire stack as chars
\$\endgroup\$
0
\$\begingroup\$

C#, 46 bytes

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

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

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

SAS, 34

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

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

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

T-SQL, 45 bytes

SELECT STUFF(S,1,1,CHAR(ASCII(S)%7+48))FROM t

Takes input from pre-existing table t with VARCHAR field S, per our IO standards.

Modifies the first character by taking the remainder MOD 7 of the ASCII value, then converting that back into a digit between 0 and 6. But ASCII(0)=48, which is 6 MOD 7, so the first character never maps back onto itself.

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

Cubically, 23 bytes

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

Converts the string into $s and -s.

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

Implicit, 15 14 bytes

'_._` !{+32}*-

Found about 10 interpreter bugs writing this. Try it online!

'_._` !{+32}*-
'                « read string                              »;
 _               « push last char onto stack                »;
  .              « increment                                »;
   _`            « mod by 127 (the "` " evaluates to 127)   »;
      !{...}     « if falsy (char was ~)                    »;
        +32      «  add 32 (make it a space)                »;
            *    « stick char at beginning of string        »;
             -   « pop last char off string                 »;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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