Inverta uma string enquanto mantém a capitalização nos mesmos lugares


28

O objetivo aqui é simplesmente reverter uma string, com um toque:
mantenha a capitalização nos mesmos lugares.

Exemplo de entrada 1: Hello, Midnightas
Exemplo de saída 1:SathginDim ,olleh

Exemplo de entrada 2: .Q
Exemplo 2 de saída:q.

Regras :

  • Saída para STDOUT, entrada de STDIN
  • O vencedor será escolhido no dia 13 de julho no horário GMT + 3 12:00 (uma semana)
  • A entrada pode consistir apenas em símbolos ASCII, facilitando para programas que não usam nenhuma codificação que contenha caracteres não ASCII.
  • Qualquer pontuação que termina em uma posição em que havia uma letra maiúscula deve ser ignorada.

Isso ocorre com ou sem a impressão externa? Isso é com ou sem a corda?

"Qualquer pontuação que termina em uma posição em que há uma letra maiúscula deve ser ignorada." , o segundo exemplo não é inconsistente com esta regra?
Stefano Sanfilippo

É consistente com a regra porque as pontuações não têm uma variação em maiúsculas.

Respostas:


7

TCC - 4 bytes

<>ci

Experimente online!

Explicação:

     - output is implicit in TCC
<>   - reverse string
  c  - preserve capitalization
   i - get input

9
Isso funcionou com uma versão tcc.luaanterior ao lançamento do desafio? Como você adicionou recentemente comandos para resolver três outros desafios, presumo que não. Se sua resposta exigir uma versão do idioma que pós-desafio, você deve rotulá-la como não concorrente no cabeçalho. Eu removerei meu voto negativo quando você adicionar o rótulo ou fornecer uma prova de que seu código funcionou em uma versão anterior.
Dennis

16

Python, 71 bytes

lambda s:''.join((z*2).title()[c.isupper()-1]for c,z in zip(s,s[::-1]))

Try it online

-3 bytes de Ruud, mais a inspiração para mais 2.

-4 bytes a mais de FryAmTheEggman


lambda s:''.join([z.lower(),z.upper()][c.isupper()]for c,z in zip(s,s[::-1]))é três bytes mais curto
Arfie

1
@Ruud Thanks! Mover a chamada de função para fora da seleção da lista economiza mais 2!
Mego

2
(z*2).title()[c.isupper()-1]Deveria trabalhar.
FryAmTheEggman

6
Você pode ganhar outro byte com, em ~c.isupper()vez dec.isupper()-1
Lulhum 6/07/2016

Isso não obter a entrada de stdin ou saída para stdout ...
ArtOfWarfare

13

Python 2, 73 bytes

Como as regras especificam, a entrada é ascii:

lambda s:''.join([z.lower,z.upper]['@'<c<'[']()for c,z in zip(s,s[::-1]))

Todo o crédito é para @Mego, mas eu não tinha a reputação de comentar sua resposta.


Você pode usar o valor ascii de '@' e '[' para obter 2 bytes?
Aloisdg diz Reinstate Monica

Infelizmente não, eu teria que usar ord (c), integer e comparação de string não lidar muito bem em Python
Lulhum

Praticamente o que eu consegui, mas você foi o primeiro +1
orlp 06/07

13

Perl, 31 + 2 ( -lp) = 33 bytes

Esta solução é do @Ton Hospel (13 bytes mais curto que o meu).

s%.%(lc$&gt$&?u:l)."c chop"%eeg

Mas você precisará le pliga. Para executá-lo:

perl -lpe 's%.%(lc$&gt$&?u:l)."c chop"%eeg'

5
Olá, e bem-vindo ao PPCG! Isso é ótimo!
NoOneIsHere

Muito bom mesmo! Eu nunca usei a -adivisão automática, acho que poderia ter usado isso muitas vezes no passado! Eu preciso me lembrar disso! Eu acho que você pode salvar outro byte usando em map...,...vez de map{...}...como você fez $Fno início! :)
Dom Hastings

Código mais curto (31 + 2 bytes):perl -lpe 's%.%(lc$&gt$&?u:l)."c chop"%eeg
Ton Hospel 17/08

Observe que -aestá implícito por-F
Ton Hospel 17/08/16

@ TonHospel uau, muito obrigado e muito bem, esse é um código muito bom! Sobre -a(e -n) estar implícito -F, li isso há algum tempo no perlrun, tentei, mas não funcionou; mas tentei novamente agora e funciona bem, então acho que fiz algo errado naquela época. Obrigado.
Dada

9

Pitão, 13 11 10 9 bytes

Obrigado a @FryAmTheEggman por me lembrar Ve @LeakyNun por outro byte.

srV_Qm!/G

Experimente online! agora no celular, atualizando o link daqui a pouco


srV_Qm!rId0é 11, mas eu acho que pode ser possível reduzir o referido mapa ...
FryAmTheEggman

@FryAmTheEggman Remova o de você salvou um byte.
Freira vazando

srV_Qm!/Gdeve salvar um byte
Leaky Nun

8

Python, 66 bytes

f=lambda s,i=0:s[i:]and(s[~i]*2).title()[~('@'<s[i]<'[')]+f(s,i+1)

Repete-se pelos índices i, levando o caracteres[~i] pelas costas e o caso des[i] frente. Ser capital é verificado como estando na faixa contígua @ABC...XYZ[. Crédito para FryAmTheEggman do (_*2).title()truque.


5

Retina , 75 67 65 bytes

A contagem de bytes assume a codificação ISO 8859-1.

$
±·$`
O$^`\G[^·]

s{T`L`l`±.
T01`l`L`±.*·[A-Z]
±·

±(.)
$1±
·.
·

Experimente online! (A primeira linha permite um conjunto de testes com vários casos de teste separados por avanço de linha.)


5

JavaScript (ES6), 95 83 bytes

s=>[...t=s.toLowerCase()].reverse().map((c,i)=>s[i]==t[i]?c:c.toUpperCase()).join``

Editar: salvou 12 bytes enormes graças a @ edc65.


s => r = [... l = s.toLowerCase ()]. ​​reverse (). map ((c, i) => s [i]! = l [i]? c.toUpperCase (): c) .join`` -10
edc65

@ edc65 Obrigado! (Nota: o r=é desnecessário.)
Neil

5

Pyke, 11 10 9 bytes

_FQo@UhAl

Experimente aqui!

_         -   reversed(input)
 F        -  for i in ^
   o      -      o+=1
  Q @     -     input[^]
     Uh   -    ^.is_upper()+1
       Al -   [len, str.lower, str.upper, ...][^](i)
          - "".join(^)

Primeiro, deu-me um erro e, ao mesmo tempo, a resposta correta. i.imgur.com/uTcH27F.png

Isso sempre acontece, você pode clicar em desativar avisos para desativá-lo.
Azul

Ah, tudo bem. Desculpe, eu não sou bom com Pyke

Pode ser porque eu sou o único cara a usá-lo #
Blue

4

05AB1E , 19 16 15 13 bytes

Graças a Emigna por salvar 3 bytes!

Provavelmente vai ser derrotado por Jelly ...

Âuvy¹Nè.lil}?

Usa a codificação CP-1252 . Experimente online! .


S.l_v¹lRNèyiu}?é 1 byte menor
Emigna 06/07

@Emigna Wow obrigado! Isso é muito inteligente.
6116 Adnan

Âuvy¹Nè.lilë}?é 14. Apenas feliz que eu possa ajudá-lo pela primeira vez :)
Emigna

@ Emigna Isso é incrível! Muito bom uso de bifurcado :).
Adnan

Ruvy¹Nè.lil}?na realidade. Eu não usei a bifurcação e esqueci de remover o resto. Então 13.
Emigna 06/07

4

MATL , 13 bytes

PktGtk<)Xk5M(

Experimente online!

Pk      % Implicit inpput. Flip, lowercase
t       % Duplicate
Gtk<    % Logical index of uppercase letters in the input string
)       % Get letters at those positions in the flipped string
Xk      % Make them uppercase
5M(     % Assign them to the indicated positions. Implicit display

3

J , 30 bytes

(={"_1 toupper@]|.@,.])tolower

Não suporta não ASCII


"toupper" "tolower" você não pode usar pontos de código para reduzi-lo?
Freira vazando 06/07

@LeakyNun Talvez, mas eu realmente não posso dizer com certeza
milhas

3

Braquilog , 28 bytes

@lr:?z:1ac.
h@u.,@A@um~t?|h.

Explicação

  • Predicado principal:

    @lr                 Reverse the lowercase version of the Input
       :?z              Zip that reversed string with the Input
          :1a           Apply predicate 1 to each couple [char i of reverse, char i of Input]
             c.         Output is the concatenation of the result
    
  • Predicado 1:

    h@u.,               Output is the uppercase version of the first char of Input
         @A@um~t?       The second char of Input is an uppercase letter
                 |      Or
                  h.    Output is the first char of Input
    

3

TSQL, 175 bytes

Golfe:

DECLARE @ varchar(99)='Hello, Midnightas'

,@o varchar(99)='',@i INT=0WHILE @i<LEN(@)SELECT
@i+=1,@o+=IIF(ascii(x)=ascii(lower(x)),lower(y),upper(y))FROM(SELECT
SUBSTRING(@,@i+1,1)x,SUBSTRING(@,len(@)-@i,1)y)z
PRINT @o

Ungolfed

DECLARE @ varchar(99)='Hello, Midnightas'

,@o varchar(99)=''
,@i INT=0

WHILE @i<LEN(@)
  SELECT @i+=1,@o+=IIF(ascii(x)=ascii(lower(x)),lower(y),upper(y))
  FROM
    (SELECT SUBSTRING(@,@i+1,1)x,SUBSTRING(@,len(@)-@i,1)y)z

PRINT @o

Violino


codificar a entrada?
cat

@cat é o único caminho. No sql, não há STDIN ou comando de entrada. Se você olhar para stackoverflow é assim que todas as questões são resolvidas - você também pode olhar para as minhas outras respostas em codegolf
t-clausen.dk

Ah, sim, eu definitivamente lembro de ter conversado com um usuário SQL antes (você, talvez). Isso é estranho, mas deve ficar bem.
cat

1
@cat não tivemos essa conversa antes, mas você fez me ajuda com uma contagem de bytes anteriormente
t-clausen.dk

3

Na verdade, 25 bytes

;`úíuY"ùû"E£`M@ùRZ`i@ƒ`MΣ

Experimente online!

Explicação:

;`úíuY"ùû"E£`M@ùRZ`i@ƒ`MΣ
;                          create a copy of the input
 `úíuY"ùû"E£`M             for each character in input:
  úíuY                       0-based index in lowercase English letters, or -1 if not found, increment, boolean negate (1 if uppercase else 0)
      "ùû"E£                 `û` if the character is lowercase else `ù` (str.lower vs str.upper)
              @ùRZ         make the other copy of the input lowercase, reverse it, and zip it with the map result
                  `i@ƒ`M   for each (string, function) pair:
                   i@ƒ       flatten, swap, apply (apply the function to the string)
                        Σ  concatenate the strings

3

Haskell, 83 80 75 71 bytes

A maneira mais direta que eu conseguia pensar.

import Data.Char
f a|isUpper a=toUpper|1>0=toLower
zipWith f<*>reverse

Se você trocar os parâmetros (#), kpode ser reescrita em estilo free-ponto: k=reverse>>=zipWith(#), que salva um par de bytes :)
Flonk

A segunda linha pode ser isenta de pontos bcomo f a|isUpper a=toUpper|1>0=toLower, embora isso conflite com a melhoria de Flonk.
xnor

Você pode usar a versão do fxnor e reescrever o Flonk kpara zipWith f<*>reverse.
nimi

Você não precisa eliminar o parâmetro s?
Lynn

Sim, e você também pode cortar o arquivo k=.
Xnor

3

PowerShell, 154 , 152 , 99 , 86 bytes

Obrigado, @TimmyD, por me salvar 47 bytes (também guardei outros 6)

Obrigado ao @TessellatingHeckler por salvar 13 bytes adicionais.

Mais recentes:

param($a)-join($a[$a.length..0]|%{("$_".ToLower(),"$_".ToUpper())[$a[$i++]-in65..90]})

Original:

param($a);$x=0;(($a[-1..-$a.length])|%{$_=$_.tostring().tolower();if([regex]::matches($a,"[A-Z]").index-contains$x){$_.toupper()}else{$_};$x++})-join''

Formatação normal:

Mais recente (parece melhor como duas linhas na minha opinião):

param($a)
-join($a[$a.length..0] | %{("$_".ToLower(), "$_".ToUpper())[$a[$i++] -in 65..90]})

Explicação:

param($a)-join($a[$a.length..0]|%{("$_".ToLower(),"$_".ToUpper())[$a[$i++]-in65..90]})
param($a)
# Sets the first passed parameter to variable $a
         -join(                                                                      )
# Converts a char array to a string
               $a[$a.length..0]
# Reverses $a as a char array
                               |%{                                                  }
# Shorthand pipe to foreach loop
                                  ("$_".ToLower(),"$_".ToUpper())
# Creates an array of the looped char in lower and upper cases
                                                                 [$a[$i++]-in65..90]
# Resolves to 1 if the current index of $a is upper, which would output "$_".ToUpper() which is index 1 of the previous array

Original:

param($a)
$x = 0
(($a[-1..-$a.length]) | %{
    $_ = $_.tostring().tolower()
    if([regex]::matches($a,"[A-Z]").index -contains $x){
            $_.toupper()
        }else{
            $_
        }
        $x++
    }
) -join ''

O primeiro pôster aqui foi motivado porque raramente vejo o PowerShell, mas com 154 152 bytes neste aqui ... posso ver o porquê!Todas as sugestões apreciadas.

Aprendi que devo mudar completamente minha maneira de pensar para jogar golfe no código e é divertido!


Olá, e bem-vindo ao PPCG! Isso é ótimo!
NoOneIsHere

Bem-vindo ao PPCG! É bom ver outro usuário do PowerShell por aqui. Você pode cortar um pouco substituindo as .tostring()aspas por e usando manipulação de número inteiro ASCII em vez de regex. Tente o seguinte, para 105 bytes - param($a)-join($a[$a.length..0]|%{if(($x=$a[$i++])-le90-and$x-ge65){"$_".ToUpper()}else{"$_".ToLower()}}).
AdmBorkBork

Brilhante! Nós podemos fazer isso ainda mais curto usando um intervalo em vez de -le e -ge:param($a)-join($a[$a.length..0]|%{if(65..90-contains$a[$i++]){"$_".ToUpper()}else{"$_".ToLower()}})
ThePoShWolf

X-inYé menor do que Y-containsX, e você pode mudar o seu ifpara o operador falso ternário para obter 86 bytes -param($a)-join($a[$a.length..0]|%{("$_".ToLower(),"$_".ToUpper())[$a[$i++]-in65..90]})
TessellatingHeckler

Cara, eu sinto que perdi muitos truques que nunca tinham jogado golfe antes. É quase como aprender a codificar tudo de novo!
ThePoShWolf

2

Dyalog APL , 12 bytes

⌽f¨⍨⊢≠f←819⌶

819⌶ é a função de dobrar estojo

f←porque seu nome é longo, atribuímos a f

⊢≠f Booleano em que o texto difere do texto em minúsculas

f¨⍨ use isso (1 significa maiúsculas, 0 significa minúsculas) para dobrar cada letra ...

... do texto invertido

Manipula não ASCII de acordo com as regras do Unicode Consortium.



2

Raquete, 146 bytes

(λ(s)(build-string(string-length s)(λ(n)((if(char-upper-case?(string-ref s n))char-upcase char-downcase)(list-ref(reverse(string->list s))n)))))

A raquete é ruim nessa coisa toda de "jogar golfe".

Encolher os ombros Como sempre, qualquer ajuda para encurtar isso seria muito apreciada.



2

Jolf, 21 bytes

Experimente aqui!

Μid?&γ._pXiS=pxHHpxγγ

Explicação

Μid?&γ._pXiS=pxHHpxγγ
Μid                   (Μ)ap (i)nput with (d)is fucntion:
   ?        =pxHH     (H is current element) if H = lowercase(H)
    &γ._pXiS          and set γ to the uppercase entity in the reversed string
                 pxγ  lowercase γ
                    γ else, return γ

(d)is function... Sacrifique a ortografia por uma questão de golfe!
Steven H.


2

C #, 86 85 bytes

s=>string.Concat(s.Reverse().Select((c,i)=>s[i]>96?char.ToLower(c):char.ToUpper(c)));

AC # lambda onde a entrada e a saída são uma sequência. Você pode experimentá-lo no .NetFiddle .


Eu estou lutando para entender por que eu não posso conseguir converter char.ToLower(c)para c+32. Espero consertar!

12 bytes salvos graças a @PeterTaylor ( c|32para adicionar 32 ao valor ascii ce c&~32ao subtrair 32). O resultado seria 72 bytes (mas pode falhar em caracteres não alfabéticos).

s=>string.Join("",s.Reverse().Select((c,i)=>(char)(s[i]>96?c|32:c&~32)));

1
Seria em c|32vez de c+32, mas não funcionará com caracteres não-alfa.
Peter Taylor

@PeterTaylor Funciona muito bem! Obrigado!
Aloisdg diz Reinstate Monica

1

PHP, 128 bytes

$s=$argv[1];$l=strrev($s);for($i=0;$i<strlen($s);++$i){echo(strtolower($s[$i])!==$s[$i]?strtoupper($l[$i]):strtolower($l[$i]));}

Posso tentar otimizar ainda mais isso, mas vou deixar como está por enquanto.


1

Oitava, 51 50 bytes

@(s)merge(isupper(s),b=flip(toupper(s)),tolower(b))

@(s)merge(s>64&s<91,b=flip(toupper(s)),tolower(b))

1

VIM, 46 bytes

Seriam três bytes g~Gse não precisássemos ler de stdin ou escrever para stdout, mas tudo bem ...

vim -es '+normal! g~G' '+%print|q!' /dev/stdin

Para testar isso, execute

echo "testString" | vim -es '+normal! g~G' '+%print|q!' /dev/stdin

Este é o meu primeiro envio aqui, não tenho certeza se esse tipo de envio é aceitável.


Bom, adoro jogar golfe no vim! No entanto, este programa não inverte realmente a string, apenas alterna a capitalização. Você pode reverter a string com, :se ri<cr>C<C-r>"mas então precisará descobrir como colocar as letras certas em maiúsculas.
DJMcMayhem

@DrGreenEggsandIronMan Oh cara, eu perdi completamente isso! De volta à prancheta!
DoYouEvenCodeBro 07/07/16

1

Javascript (usando biblioteca externa) (224 bytes)

(s)=>{t=_.From(s);var cnt=t.Count();var caps=t.Select(x=>{return x.toUpperCase()===x&&x.toLowerCase()!==x}).ToArray(),i=-1;return t.AggregateRight((a,b)=>{i++;var c=caps[i];return c?a+b.toUpperCase():a+b.toLowerCase()},"");}

Isenção de responsabilidade: Usando uma biblioteca que escrevi para trazer o LINQ do C # para Javascript

Imagem 1


Chamando a pessoa que votou contra isso sem uma explicação. Alguma razão para isso?
applejacks01

É provável que eles desejassem que você contasse a biblioteca também, embora o uso de uma biblioteca externa esteja totalmente dentro dos limites da política padrão.
Addison Crump

1
Eu não sou contra, mas se você estiver usando uma biblioteca externa, mencione pelo menos o nome na sua resposta e, para uma biblioteca obscura, forneça um link para o repositório.
ǹ̷̰ĥ̷̳h̷͉̃a̷̭̿h̸̡̅ẗ̵̷̨̰́̀ĥ̷̳

1

Sed, 113 + 1 = 114 bytes

Por quê? Porque é divertido usar a ferramenta errada para fazer as coisas: P

Uso: Execute sed -rf file, digite o texto e pressione Ctrl+ D(enviar EOF).

Golfe:

s/[A-Z]/\a\l&/g;s/^.*$/\f&\v/;:x;s/\f\a/\a\f/;s/\a\v/\v\a/;s/\f(.)(.*)(.)\v/\3\f\2\v\1/;tx;s/\f|\v//g;s/\a./\U&/g

Ungolfed:

s/[A-Z]/\a\l&/g #Prepend all upper-case letters with a 
                #BEL ASCII character and make them lowercase
s/^.*$/\f&\v/   #Wrap text between a from feed (\f) and a vertical tab (\v)
                #These are used as markers

:x #Define a label named x

s/\f\a/\a\f/;s/\a\v/\v\a/ #Move BEL characters outside of the boundary, so they're not moved later
s/\f(.)(.*)(.)\v/\3\2\1/  #This part does the switching itself
                          #It grabs a character preceded by a form feed and another 
                          #one followed by a vertical tab and swaps them, while keeping the text in-between
                          #and replaces the marker \f and \v

tx             #Conditional jump (t) to label x
               #Jumps to the label x if the last substitution (s command) was successful 
s/\f|\v//g     #Delete markers
s/\a(.)/\u\1/g #Make letters preceded by a BEL upper-case

1

Java 7, 221 217 180 bytes

void c(char[]s){int x=0,y=s.length-1;for(char t;x<y;s[x]=s(t,s[y]),s[y]=s(s[y],t),x++,y--)t=s[x];}char s(char a,char b){return(char)(64<a&a<91?96<b&b<123?b-32:b:64<b&b<91?b+32:b);}

Cargas de bytes salvos graças à abordagem do @LeakuNun .

Casos não testados e de teste:

Experimente aqui.

class Main{
  void c(char[] s){
    int x = 0,
        y = s.length-1;
    for(char t; x < y; s[x] = s(t, s[y]),
                       s[y] = s(s[y], t),
                       x++,
                       y--){
       t = s[x];
    }
  }

  char s(char a, char b){
    return (char)(64 < a & a < 91
                    ? 96 < b & b < 123
                        ? b-32
                        : b
                    : 64 < b & b < 91
                        ? b+32
                        : b);
  }

  public static void main(String[] a){
    print("Hello, Midnightas");
    print("TEST");
    print("test");
    print("Test");
    print(".,..,,!@");
    print("ABCDefgHijklMNOPqrsTuVWxyz");
    print("AbCdEfGHIJKlmnop123");
  }

  static void print(String s){
    char[] t = s.toCharArray();
    c(t);
    System.out.println(t);
  }
}

Saída:

SathginDim ,olleh
q.
TSET
tset
Tset
@!,,..,.
ZYXWvutSrqpoNMLKjihGfEDcba
321pOnMLKJIhgfedcba

Você pode entrada e saída char[].
Freira vazando

@LeakyNun Na verdade eu (acredito que) não posso em menos quantidade de bytes. Permitiria a remoção String a="";e a alteração o+=para 0[i]=salvar bytes, mas o Java não possui um caractere .toUpperCase()/ .toLowerCase()método e a conversão de char para String, usa o método superior / inferior e, em seguida, voltar ao char exigiria (muito) mais bytes. Mas fique à vontade para dividir o ideone vinculado e criar algo que char[]funcione em menos bytes.
Kevin Cruijssen

1
180 bytes que podem ser jogados ainda mais (por não modificá-lo no lugar).
Leaky Nun

0

C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
  char *a,*b,*c;

  a=c=strdup(argv[1]);
  b=&argv[1][strlen(a)-1];
  for(;*a;a++,b--){
    *a=(*a>='A'&&*a<='Z')?((*b>='a'&&*b<='z')?*b-32:*b):((*b>='A'&&*b<='Z')?*b+32:*b);
  }
  puts(c);
  free(c);
  return 0;
}

A entrada deve ser retirada do stdin.
Anmol Singh Jaggi

Como este é o código-golf, por favor, digite o número de bytes que este programa custaria.

Eu poderia reduzi-lo significativamente, dependendo das regras, mas não consigo encontrar nenhuma regra.
user56095
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.