Дублікат і перемикач корпусу


34

Мета полягає в тому, що, взявши рядок як вхідний, дублювати кожну латинську букву і "перемикати" її регістр (тобто великі регістри стають малими літерами і навпаки).

Приклади входів та виходів:

Input      Output
bad        bBaAdD
Nice       NniIcCeE
T e S t    Tt eE Ss tT
s E t      sS Ee tT
1!1!1st!   1!1!1sStT!
n00b       nN00bB     
(e.g.)     (eE.gG.)
H3l|@!     Hh3lL|@!

Вхід складається з символів для друку ASCII.

Не слід дублювати не латинські літери, цифри, спеціальні символи.


17
Це дуже приємне, просте, але не тривіальне завдання.
— Mego

Відповіді:


10

Jelly, 5 bytes

żŒsQ€

Try it online!

How it works

żŒsQ€  Main link. Argument: s (string)

 Œs    Yield s with swapped case.
ż      Zip s with the result.
   Q€  Unique each; deduplicate each pair of characters.

17

Python, 56 54 bytes

lambda s:''.join(c+c.swapcase()*c.isalpha()for c in s)

Test it on Ideone.


Dang! Out golfed me by 4 bytes...
— R. Kap

How does this maintain the non-letter characters? I'd think they'd show up as empty strings.
— atlasologist

@atlasologist As you can see on Ideone, they do not. * has higher precedence than +, so it only affects the c with swapped case.
— Dennis

Ohh, okay, I didn't think of it like that. Nice.
— atlasologist

16

JavaScript ES6, 70 68 66 64 bytes

Saved 2 bytes thanks to @Kevin Lau - not Kenny

Saved 2 bytes thanks to @Cᴏɴᴏʀ O'Bʀɪᴇɴ

s=>s.replace(/[A-Z]/gi,l=>l+l[`to${l<"a"?"Low":"Upp"}erCase`]())

Explanation

This uses a really hacky:

l[`to${l<"a"?"Low":"Upp"}erCase`]()

which ungolfed is:

l[`to${
   l < "a" ?
   "Low" : 
   "Upp"
}erCase`]()

Basically l < "a" checks if the code point of the letter is less then the code point of a (therefore being an uppercase letter). If it is it'll do to + Low + erCase which becomed l['toLowerCase']() and makes the character lowercase. ` quotes allow string formatting so essentially you can think of:

`to${l < "a" ?"Low" : "Upp"}erCase`

as: "to" + (l<"a" ? "Low" : "Upp") + "erCase" which generates the function to call (make the string upper or lower case). We put this in square brackets [ ... ] which lets us access a property given its name as a string. This returns the appropriate function and then we just call it.


3
/[A-Z]/gi is a shorter regex :3
— Value Ink

@KevinLau-notKenny oh nice catch, thanks!
— Downgoat

1
to${l<"a"?"Lower":"Upper"}Case to to${l<"a"?"Low":"Upp"}erCase
— Conor O'Brien

@CᴏɴᴏʀO'Bʀɪᴇɴ oh nice, thanks!
— Downgoat

4
l[`to${l<"a"?"Low":"Upp"}erCase`]() I think we have a new definition of evil.
— gcampbell

10

Ruby, 37 33 (30 + -p flag) bytes

swapcase to the rescue! Sort of. -4 bytes from @Lynn.

gsub(/[a-z]/i){$&+$&.swapcase}

gsub(/[a-z]/i){$&+$&.swapcase} plus the p flag is 31 bytes.
— Lynn

1
@Lynn I believe consensus was edit difference needed from default script, so the p flag is (space)-p aka 3 bytes.
— Value Ink

8

C, 63 60 bytes

f(char*s){for(;*s;s++)isalpha(putchar(*s))&&putchar(32^*s);}

Uses the fact that 'a' XOR 32 == 'A', etc.

Three bytes saved thanks to FryAmTheEggman.


you can move the s++ in the last putchar (&&putchar(32^*s++)) to save one byte
— Giacomo Garabello

I think you can replace && with *, can't you?
— aloisdg says Reinstate Monica

1
I’m pretty sure both of those don’t work, if I think about how &&’s short-circuiting behaviour works.
— Lynn

f(char*s){isalpha(putchar(*s))&&putchar(32^*s);*s&&f(1+s);} recursive?
— l4m2

1
f(char*s){*s&&f(1+s,isalpha(putchar(*s))&&putchar(32^*s));} recursive?
— l4m2

6

CJam, 11 bytes

l_el_eu.+.|

Test it here.

Explanation

l      e# Read input.
_el    e# Duplicate, convert to lower case.
_eu    e# Duplicate, convert to upper case.
.+     e# Concatenate the two characters in matching positions from those two
       e# strings. E.g. "ab!" "AB!" would give ["aA" "bB" "!!"].
       e# For each character from the original string and the corresponding 
.|     e# string from this list, take the set union (which eliminates duplicates
       e# and keeps the order the values appear in from left to right, so that
       e# the original case of each letter comes first).

5

Pyth, 7 bytes

sm{+dr2

Test suite.

sm{+dr2    input: Q
sm{+dr2dQ  implicit arguments

        Q  input
 m         for each character as d:
     r2d       swapcase
   +d          prepend d
  {            deduplicate
s          join as string

Haha, that's really fast :D
— nicael


5

Haskell, 73 bytes

l=['a'..'z']
u=['A'..]
(>>= \c->c:maybe""pure(lookup c$zip l u++zip u l))

5

Cheddar, 118 104 bytes

(s)->s.chars.map((i)->{if String.letters has i.lower{if i<"a"{i+i.lower}else{i+i.upper}}else{i}}).join()

First real Cheddar answer!!! This is a lot less climactic than I thought it would be... ;_;

Works with release 1.0.0-beta.9, non-competing.


As you can tell I didn't design cheddar to be golfy :/

Ungolfed:

(str) -> str.chars.map(
    (i) -> {
        if String.letters has i {
            if i < "a" { // Check char code, meaning it's upper case if true
                i+i.lower
            }
            else {
                i+i.upper
            }
        } else {
            i
        }
    }
).join()

Usage:

var doThing = <code here>;
doThing("input...");

Update: 7/14/16 I've finished ternaries making this come down to 84 bytes

Cheddar, 84 bytes

(s)->s.chars.map((i)->String.letters has i.lower?i<"a"?i+i.lower:i+i.upper:i).join()

works as of version v1.0.0-beta.14


4
Yay! We've been waiting for this moment for a long time!
— DJMcMayhem

With one or two method name changes, is also valid Sidef
— cat

@cat o_o the similarity is unsettling
— Downgoat

Well, they're both influenced by Perl, Perl 6, Ruby, Python, etc, so it's not that surprising :P
— cat

1
@cat oh no no no no no, cheddar was not influenced by python
— Downgoat

4

Retina, 28 27 21 bytes

Those are tabs, not spaces.

.
$&  $&
T`lL    p`Ll_`  .

Try it online

Thanks for the suggestions everyone.


The spaces are eaten by SE.
— Conor O'Brien

[A-Za-z] -> i`[A-Z]
— Downgoat

Martin and I were talking in chat, and we came up with: retina.tryitonline.net/…
— FryAmTheEggman

@FryAmTheEggman Ah, I forgot about _. I'm going to use tabs so I can test all test cases at once, though.
— mbomb007

1
But the test suite doesn't have to be golfed :P Just leaving a note saying "the first line makes it run separately on each line" is usually good enough. Here, it would save you the craziness of tab characters.
— FryAmTheEggman


4

sed, 30 bytes

29 bytes code + 1 byte parameter -r

s/([a-z])|([A-Z])/&\u\1\l\2/g

Usage:

echo -e 'bad\nNice\nT e S t\ns E t\n1!1!1st!\nn00b\n(e.g.)\nH3l|@!' |\
sed -r 's/([a-z])|([A-Z])/&\u\1\l\2/g'

4

J, 31 29 bytes

[:;]<@~."1@,.tolower,.toupper

Explanation

[:;]<@~."1@,.tolower,.toupper  Input: s
                      toupper  Convert s to all uppercase
             tolower           Convert s to all lowercase
                    ,.         Join them as columns in a 2d array
   ]                           Identity function, get s
           ,.                  Prepend s as a column to the 2d array
      ~."1@                    Take the unique chars on each row
    <@                         Box them
[:;                            Unbox the list of boxes and join their contents and return

4

Haskell, 121, 101, 85, 82

import Data.Char
g n|isLower n=toUpper n|1<2=toLower n
(>>= \x->x:[g x|isAlpha x])

3
By replacing the if-then-else by guards, you can save 15 bytes or so. And isLower is shorter than the construct with elem, for 5 bytes more.
— arjanen

1
>>= is concatMap (or concat.map) with arguments flipped: f n = n >>= (\x->if isAlpha x then[x,r x]else[x]). You can go pointfree and omit the function name and replace the definition of f with (>>= \x->if isAlpha x then[x,r x]else[x]).
— nimi

1
Instead of otherwise you can use any expression that evaluates to True, e.g. 1<2. You can replace the if .. then .. else with a list comprehension: \x->[x]++[g x|isAlpha x]. Oh, and there's a bug: the second toUpper in g must be a toLower.
— nimi

1
Oh, one more: [x]++ is x:.
— nimi

4

Perl, 36 bytes (35 + -n flag)

s/[a-z]/$&.(ord$&<97?lc$&:uc$&)/ige

(-p tag needed)

(-2 bytes thanks to @Dom Hasting)

Short explanation:
ord returns the numeric value of a char. ord(any lower case) >= 97, and ord(any upper case) <= 90).

Run with :

perl -pe 's/[a-z]/$&.(ord$&<97?lc$&:uc$&)/ige'

You still need to use /i or your regexp will match several codepoints between letters.
— Oleg V. Volkov

@OlegV.Volkov oh right, thanks, answer edited.
— Dada

Got it down one more byte, using your method: Try it online!
— Xcali

4

Ruby, 31+1=32 30+1=31 bytes

With the -p flag, run

gsub(/(?<=(.))/){$1.swapcase!}

Takes advantage of the fact that swapcase! will return nil on anything but an ASCII letter, which translates to an empty string when returned out of the gsub block. @Jordan saved a byte by capturing the previous character in a look-behind.


Matching with // and then using $`[-1] is clever.
— Jordan

1
I managed to shave off six bytes with lookbehind: gsub(/(?<=(.))/){$1.swapcase!}. Same basic concept, though, so feel free to use it.
— Jordan

Cool! That looks one byte shorter to me.
— histocrat

Er, yes, one byte. I think I had some extra code in there to test that I accidentally counted.
— Jordan

There is no need to use the self-modifying version of .swapcase!. (I mean, remove the !.)
— manatwork

4

R, 191 187 168 156 98 99 bytes

99 bytes due to improvements fro Giuseppe and MickyT.

paste0(x<-unlist(strsplit(readline(),"")),gsub("[^A-Za-z]","",chartr("a-zA-Z","A-Za-z",x)),collapse="")

98 bytes -- maybe sometime next year, we can find another golf of this, hahaha.
— Giuseppe

1
I hate to be the bearer of bad new, but it fails on test cases with spaces. readline() can be used, but it will cost a byte
— MickyT

@MickyT thanks, fixed now.
— rturnbull

@MickyT scan will work with input given wrapped in quotes (as is often the case for command-line arguments in other languages)
— Giuseppe

@Giuseppe Sorry I didn't realise that. I just thought it automatically split on whitespace unless you specify a non whitespace character. Sorry rturnbull
— MickyT

3

05AB1E, 7 bytes

Code:

vyyš«Ù?

Explanation:

v       # For each in input.
 yyš    # Push y and y swapcased.
    «Ù  # Concatentate and uniquify.
      ? # Print without a newline.

Uses the CP-1252 encoding. Try it online!


Maybe you could provide a link to the interpreter?
— nicael

2
@nicael It IS linked... It's right there on github.
— mbomb007

So no online interpreter? :(
— nicael

@nicael Then download it, and run it. There doesn't have to be an online interpreter, just an interpreter.
— mbomb007

1
@nicael Yeah, there is no online interpreter available yet :(. The offline version should work though.
— Adnan



3

Actually, 8 bytes

`;Öo╔`MΣ

Try it online!

Explanation:

`;Öo╔`MΣ
`;Öo╔`M   for each character in input:
 ;          duplicate the character
  Ö         swap case
   o        append to original character
    ╔       remove duplicated characters
       Σ  concatenate

3

MATL, 11 9 bytes

tYov"@uv!

Try it Online

Explanation

        % Implicitly grab input as string
t       % Duplicate the input
Yo      % Swap case of all characters
v       % Vertically concatenate the original and swap-cased versions
"       % For each column (letter in the original)
  @u    % Compute the unique values (without sorting)
  v!    % Vertically concatenate with the existing output and transpose
        % Implicit end of for loop and implicit display

3

Perl, 28 22 21 bytes (20 + -p flag)

s/[a-z]/$&.$&^$"/ige

I imagine you can save a byte by using $" instead of ' ', but I haven't tested.
— msh210

@msh210, nice! How could I forget to check perlvar for default strings? Thanks!
— Oleg V. Volkov

3

Stax, 7 6 bytes

Thanks to @recursive for a byte saved!

┤§ÆP♦■

Run and debug it at staxlang.xyz! (link is to unpacked version)

Unpacked (7 bytes):

c:~\{um

Explanation:

c:~\{um
c          Copy the top element of the stack (the input, in this case).
 :~        Switch case of each letter in the copy.
   \       Zip. This produces an array of two-character strings.
    { m    Map a block over this array of two-character strings.
     u       Get all unique elements.
           Implicit concatenate and print.

Thanks for giving stax a try. One easy improvement you can make is to use u instead of :g. It will get all the unique elements in an array, which is exactly what you want in this case. Other than that, this looks well golfed.
— recursive

@recursive Thanks! Forgot about that one :/ Will edit in soon.
— Khuldraeseth na'Barya

Doesn't work for 123. You may need to change the format for all inputs (i.e. quote them). The link is also broken. You need to replace m=11 with m=2. There is a PPCG post generating button on staxlang.xyz so you may want to use that one.
— Weijun Zhou

@WeijunZhou Thanks, fixed!
— Khuldraeseth na'Barya

2

Python, 59 bytes

lambda s:''.join((x,x+x.swapcase())[x.isalpha()]for x in s)

Edited to fix repeating non-alphabetic characters



2

PHP 4.1, 57 bytes

This code assumes access through a web server (Apache, for example), using the default configuration.

You can pass the string by sending the key S by any means (POST, GET, COOKIE, SESSION...).

<?for($i=0;$c=$S[$i++];)echo$c,ctype_alpha($c)?$c^' ':'';


2

Common Lisp (Lispworks), 262 bytes

(defun f(s)(let((b""))(dotimes(i(length s))(if(lower-case-p(elt s i))(progn #1=(setf b(concatenate 'string b(string #2=(elt s i))))(setf b(concatenate 'string b(string(char-upcase #2#)))))(progn #1#(setf b(concatenate 'string b(string(char-downcase #2#)))))))b))

ungolfed:

(defun f (s)
  (let ((b ""))
    (dotimes (i (length s))
      (if (lower-case-p (elt s i))
          (progn
           #1=(setf b (concatenate 'string b (string #2=(elt s i))))
           (setf b (concatenate 'string b (string (char-upcase #2#)))))
        (progn
          #1#
          (setf b (concatenate 'string b (string (char-downcase #2#)))))))
    b))

Usage:

CL-USER 1 > (f "abc")
"aAbBcC"

CL-USER 2 > (f "bad")
"bBaAdD"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.