ALTeRnAdo CaSe


42

Para o desafio de hoje, você deve escrever um programa ou função que alterne o caso de uma string. No entanto, você deve ignorar caracteres não alfabéticos. Isso significa que todo caractere alfabético deve ter um caso diferente do caractere alfabético anterior e seguinte. Isso é um pouco mais complexo do que colocar em maiúsculas todas as outras letras, por exemplo. Se você usar uma string como

hello world

e converter todos os outros caracteres para maiúsculas, você receberá:

hElLo wOrLd

Como você pode ver, a minúscula oé seguida por uma minúscula w. Isto é inválido. Em vez disso, você deve ignorar o espaço, fornecendo-nos este resultado:

hElLo WoRlD

Todos os caracteres não alfabéticos devem ser iguais. A saída pode começar com maiúsculas ou minúsculas, desde que alternadamente. Isso significa que o seguinte também seria uma saída aceitável:

HeLlO wOrLd

Seu programa deve funcionar independentemente do caso da entrada.

A string de entrada sempre conterá apenas ASCII imprimível , para que você não precise se preocupar com caracteres não imprimíveis, novas linhas ou unicode. Seu envio pode ser um programa completo ou uma função, e você pode receber e enviar as informações em qualquer formato razoável. Por exemplo, argumentos da função / valor de retorno, STDIN / STDOUT, leitura / gravação de um arquivo, etc.

Exemplos:

ASCII                                   ->  AsCiI
42                                      ->  42
#include <iostream>                     ->  #InClUdE <iOsTrEaM>
LEAVE_my_symbols#!#&^%_ALONE!!!         ->  lEaVe_My_SyMbOlS#!#&^%_aLoNe!!!
PPCG Rocks!!! For realz.                ->  PpCg RoCkS!!! fOr ReAlZ.
This example will start with lowercase  ->  tHiS eXaMpLe WiLl StArT wItH lOwErCaSe
This example will start with uppercase  ->  ThIs ExAmPlE wIlL sTaRt WiTh UpPeRcAsE
A1B2                                    ->  A1b2

Como se trata de , as brechas padrão se aplicam e a resposta mais curta em bytes vence!


33
Ugh, eu só acabei de perceber que era esse meme xD
Decay Beta

@BetaDecay Hahaha, essa não era minha intenção. Mais tempo infeliz. Eu pensei nisso como um mini-desafio de bate-papo , e eu gosto da ideia por trás disso, porque é sutilmente mais difícil do que parece.
DJMcMayhem

4
O próximo desafio é imprimir um bob esponja ascii à lacowsay
Frambot 25/05

11
Droga! Eu apenas escrevi um script CJam para isso (como ontem) e excluiu.
Esolanging Fruit

2
Existe algum potencial perdido para o título ou pelo menos os exemplos usando pinguim da destruição ou sporks.
Ian

Respostas:


19

JavaScript (ES6), 66 63 bytes

Começa com maiúsculas.

s=>s.replace(/[a-z]/gi,c=>c[`to${(s=!s)?'Low':'Upp'}erCase`]())

Casos de teste


Exatamente como eu faria isso. Eu acho que eu posso ver onde você pode salvar um par de bytes, mas eu estou no meu telefone para que não pode testar adequadamente.
Shaggy

Sim, usar um ternário é o que eu ia sugerir.
Shaggy

11
Como funciona o s=!struque?
Kritixi Lithos

7
@KritixiLithos Como sé a string de entrada, !sprimeiro é avaliada como false(a menos que a string de entrada esteja vazia; nesse caso, ela seria avaliada como true- mas uma string vazia não gerará nenhuma correspondência). Depois disso, ele se torna uma operação booleana padrão, alternando entre falsee true. Além disso, não nos importamos de perder o conteúdo sdeste momento, porque ele já estava sendo usado para alimentar .replace().
Arnauld 25/05

3
@MayorMonty Infelizmente, isso corresponderia a alguns símbolos. Uma entrada como "A[I"falharia.
Arnauld

12

05AB1E , 11 8 bytes

Código:

lvyJ¤aiš

Usa a codificação 05AB1E . Experimente online!

Explicação:

l           # Lowercase the input
 vy         # For each element..
   J        #   Join the entire stack into a single string
    ¤a      #   Check if the last character is alphabetic
      iš    #   If true, swapcase the entire string

Eu amo como tento entrar às cegas, sabendo que tenho que bater 11 bytes; então vá lentamente de 17 para 11 bytes e perceba que lvy¾Fš}Da½Jé exatamente o que você já tinha ._.
Magic Octopus Urn

11
@carusocomputing há uma solução de 8 bytes muito mais fácil: p
Adnan

4
ah sim, super fácil haha.
Magic Octopus Urn

2
@ Octopus Há alguma discussão sobre isso, mas eu uso 'osable' e 'osabie'.
Adnan

11
@ octopus Eu literalmente digo Oh-Five-Ay-Bee-One-Eee, eu não sou um homem criativo.
Magic Octopus Urn


8

Gelatina , 13 bytes

nŒsTm2
ŒlŒuǦ

Experimente online!

Como funciona

ŒlŒsǦ  Main link. Argument: s (string)

Œl      Cast to lowercase.
    Ǧ  At indices returned by the helper link...
  Œu        apply uppercase.


nŒsTm2      Helper link. Argument: s (string)

 Œs         Apply swapcase to s.
n           Perform vectorizing not-equal comparison.
   T        Compute the truthy indices.
    m2      Select every other one, starting with the first.

7

Japonês , 16 14 bytes

r"%l"_m"uv"gT°

Experimente online!

Explicação

r              // RegEx replace input
 "%l"          // [A-Za-z] as first arg to replace
     _         // created function Z=>Z as second arg to replace
       "uv"gT° // alternates "u" & "v"
      m        // map Z to either "u" upper or "v" lower

Muito agradável! Você pode remover o ,. A menos que seja um número (ou seja [12]), Japt sabe que são itens diferentes. Eu acredito que você pode remover o &1também.
Oliver

Obrigado @obarakon. A documentação do Japt é um pouco esparsa.
powelles 25/05

Obrigado por usar o Japt. Sinta-se à vontade para fazer perguntas, sugestões etc. na sala de bate-papo do Japt . Há também um tópico Dicas para o Japt . :)
Oliver

_m"uv"gT°Agradável. Eu estava prestes a sugerir isso.
Oliver

@obarakon Sim, eu vi onde a ETH respondeu à sua pergunta no chat e isso me fez tentar as coisas.
powelles 25/05


5

Alice , 18 bytes

/olZlYuN
@iy.u..//

Experimente online!

Explicação

Este programa segue um modelo menos conhecido para programas de tamanho ímpar que são executados inteiramente no modo ordinal. A versão linearizada deste código é:

il.l.uN.YuZyo@

Explicação do código:

i - push input onto stack            ["Hello world!"]
l - convert to lowercase             ["hello world!"]
. - duplicate                        ["hello world!", "hello world!"]
l - convert to lowercase (should be no-op, but avoids what seems to be a bug in the TIO implementation)
. - duplicate again                  ["hello world!", "hello world!", "hello world!"]
u - convert to uppercase             ["hello world!", "hello world!", "HELLO WORLD!"]
N - difference between sets          ["hello world!", "helloworld"]
. - duplicate reduced string         ["hello world!", "helloworld", "helloworld"]
Y - unzip (extract even positions)   ["hello world!", "helloworld", "hlool", "elwrd"]
u - convert to uppercase             ["hello world!", "helloworld", "hlool", "ELWRD"]
Z - zip evens back into string       ["hello world!", "helloworld", "hElLoWoRlD"]
y - perform substitution             ["hElLo WoRlD!"]
o - output                           []
@ - terminate

Sem usar lna duplicata, a pilha depois Nseria ["helloworld", "helloworld"]. Eu suspeito fortemente que isso seja um bug.


5

C (tcc) , 60 57 56 bytes

Graças ao DigitalTrauma por observar o bit 5, é a única diferença para maiúsculas / minúsculas ASCII.

Agradecimentos especiais ao zch por jogar fora mais três bytes.

Economize mais um byte da ideia do RJHunter

l;f(char*s){for(;*s=isalpha(*s)?*s&95|++l%2<<5:*s;s++);}

Experimente online!


I golfed-lo um pouco mais , e modificada para que ele funciona em todos gcc, tcc, clang. FWIW, o gcc coloca literais de strings na memória somente leitura, então eu costumava strdup()obter ponteiros para ler / escrever memória no código do driver de teste.
Digital Trauma

11
@DigitalTrauma, obrigado por isso. Eu deveria ter reconhecido que o bit 5 era a diferença entre superior e inferior. Agradável !
Cleblanc 25/05

Eu tentei fazer esta versão recursiva também, mas não poderia obtê-lo qualquer menor.
Digital Trauma

Você pode substituir o condicional interno por *s&~32|++l%2<<5para salvar 3 bytes.
Zch

Como a entrada promete ser ASCII imprimível, você pode substituir &~33por &95para salvar mais um byte.
RJHunter

4

Java 8, 99 bytes

a->{String r="";int i=0;for(int c:a)r+=(char)(c>64&c<91|c>96&c<123?i++%2<1?c|32:c&~32:c);return r;}

Explicação:

Experimente aqui.

a->{                          // Lambda with char-array parameter and String return-type
  String r="";                //  Result-String
  int i=0;                    //  Flag for alteration
  for(int c:a)                //  Loop over the characters of the input
    r+=(char)                 //   And append the result-String with the following (converted to char):
      (c>64&c<91|c>96&c<123?  //    If it's a letter:
       i++%2<1?               //     And the flag states it should be lowercase:
        (c|32)                //      Convert it to lowercase
       :                      //     Else (should be uppercase):
        (c&~32)               //      Convert it to uppercase
      :                       //    Else:
       c);                    //     Simply append the non-letter character as is
                              //  End of loop (implicit / single-line body)
  return r;                   //  Return result-String
}                             // End of method

Não consegui reduzi-lo, mas você pode usar (c+"").matches("[A-Za-z]")ou Character.isLetter(c)salvar bytes.
TheLethalCoder

@TheLethalCoder Ambos são mais longos do que no c>64&c<91|c>96&c<123entanto. E como eu uso de intqualquer maneira para as partes Character.toUpperCase(...)e Character.toLowerCase(...)golfed (estes: (char)(c&~32)e (char)(c|32)), duvido que poderia torná-lo mais curto com qualquer uma dessas.
Kevin Cruijssen 26/05

11
Pensei que não seria capaz de mas vale postagem para ver se você poderia fazer uso deles de qualquer maneira
TheLethalCoder

@TheLethalCoder Ah ok. :) Em alguns casos, o primeiro pode ajudar com uma abordagem ligeiramente diferente para outros desafios, mas para esse desafio é mais curto. Obrigado mesmo assim.
Kevin Cruijssen 26/05

a->{String r="";int i=0,f=32;for(int c:a)r+=(char)(c>64&c<91|c>96&c<123?(f=~f):c);return r;} ??
Roman Gräf

4

Ruby, 57 55 47 41 bytes

A contagem de bytes inclui dois bytes para opções de linha de comando.
Execute-o por exemplo assim:$ ruby -p0 alternate_case.rb <<< "some input"

gsub(/\p{L}/){($&.ord&95|32*$.^=1).chr}

Com a p0opção, toda a entrada é consumida de uma só vez, e o global mágico $.é incrementado para 1. Isso é posteriormente alternado entre 0 e 1 e usado para manter o estado.

Trabalha com entrada multilinha; Experimente online!

Agradecemos a Ventero pela contribuição incrível - verifique os comentários para obter detalhes.


11
Homem, se não fosse pelo fato de que $.auto-incrementos com cada getschamada, um programa completo com a -pbandeira teria sido mais curto ...
Valor Ink

11
1&$.+=1permite que você solte os parênteses. E para a integralidade amor, há um outro inteiro mundial - é, infelizmente, apenas só de leitura: $$.
Ventero 25/05

11
Outra coisa sobre o sinalizador de linha de comando: -p0faz com que o intérprete leia todas as entradas disponíveis de uma só vez - para que seu código seja chamado apenas uma vez, permitindo que você o use livremente $.. Combinando isso ao fato de que gsubimplicitamente opera como $_.gsub!ao especificar, -pum programa completo é significativamente menor: 48 caracteres para gsub(/[a-z]/i){[$&.upcase,$&.downcase][1&$.+=1]}e 2 para o p0sinalizador.
Ventero 25/05

11
Observação final, prometo :) Depois de usar -p0, você pode salvar mais alguns caracteres na maneira como você $.alterna: Como agora é garantido 1que o seu código seja invocado, você pode simplesmente usá-lo $.^=1.
Ventero

2
Acontece que eu menti, tenho outro comentário: D Como a entrada é garantida para conter apenas ASCII imprimível, podemos usar o suporte do Ruby para categorias Unicode em expressões regulares: /\p{L}/(categoria Unicode Letter ) é um caractere menor que /[a-z|/i.
Ventero 25/05

3

Braquilog , 25 bytes

{ḷ|ụ}ᵐ.{ḷ∈Ạ&}ˢ¬{s₂{∈Ạ}ᵐ}∧

Experimente online!

Isso é longo e lento.

Explicação

{   }ᵐ.                       The Output is the result of mapping on each char of the Input:
 ḷ                              Lowecase the char
  |                             Or
   ụ                            Uppercase the char
       {    }ˢ                In the Ouput, select the chars that:
        ḷ∈Ạ&                    when lowercased are in "abc...xyz" (ie are letters)
              ¬{       }∧     In that new string, it is impossible to find:
                s₂              a substring of 2 consecutive chars
                  {∈Ạ}ᵐ         where both of them are in the lowercase alphabet

3

MATL , 16 15 bytes

Xktkyy-f2L))5M(

Experimente online! Ou verifique todos os casos de teste .

Explicação

Considere a entrada 'olá mundo'

Xk    % To upper case
      % STACK: 'HELLO WORLD'
t     % Duplicate top element
      % STACK: 'HELLO WORLD', 'HELLO WORLD'
k     % To lower case
      % STACK: 'HELLO WORLD', 'hello word'
yy    % Duplicate top two elements
      % STACK: 'HELLO WORLD', 'hello word', 'HELLO WORLD', 'hello word'
-     % Difference (of code points; element-wise)
      % STACK: 'HELLO WORLD', 'hello word', [-32 -32 -32 -32 -32 0 -32 -32 -32 -32 -32]
f     % Indices of nonzeros
      % STACK: 'HELLO WORLD', 'hello word', [1 2 3 4 5 7 8 9 10 11]
2L)   % Keep only even-indexed values (*)
      % STACK: 'HELLO WORLD', 'hello word', [2 4 7 9 11]
)     % Reference indexing (get values at indices)
      % STACK: 'HELLO WORLD', 'elwrd'
5M    % Push (*) again
      % STACK: 'HELLO WORLD', 'elwrd', [2 4 7 9 11]
(     % Assignment indexing (write values at indices). Implicit display
      % STACK: 'HeLlO wOrLd

"


3

Perl 6 ,  32  30 bytes

{S:g/<:L><-:L>*<:L>?/$/.tclc()/}

Tente

{S:g{<:L><-:L>*<:L>?}=$/.tclc}

Tente

Expandido:

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

  S            # string replace (not in-place) implicitly against 「$_」

  :global

  {

    <+ :L >    # a letter
    <- :L >*   # any number of non-letters
    <+ :L >?   # an optional letter

  }

  =

  $/.tclc()    # uppercase the first letter, lowercase everything else
}

3

q / kdb +, 51 42 38 bytes

Solução:

{@[x;;upper]1#'2 cut(&)x in .Q.a}lower

Exemplo:

q){@[x;;upper]1#'2 cut(&)x in .Q.a}lower"hello world"
"HeLlO wOrLd"

Notas:

.Q.a        // abcde...xyz lowercase alphabet
(&) x in    // where, returns indices for where x (hello world) is an alpha
2 cut       // splits list into 2-item lists
1#'         // takes first item of each 2-item list; ie the indices to uppercase
@[x;;upper] // apply (@) upper to x at these indices

2

V , 17 , 13 bytes

VUÍშáü$©/ì&

Experimente online!

Ou Verifique todos os casos de teste!

HeXdUmP:

00000000: 5655 cde1 83a8 e1fc 24a9 2fec 26         VU......$./.&

Explicação:

Isso usa um regex compactado ️, portanto, antes de explicá-lo, vamos expandir o regex:

:%s/\v\a.{-}(\a|$)/\l&

O VUconverte tudo para maiúsculas. Então, executamos o seguinte:

:%                      " On every line:
  s/\v                  "   Substitute:
      \a                "     A letter
        .{-}            "     Followed by as few characters as possible
            (\a|$)      "     Followed by either another letter or an EOL
                  /     "   With:
                   \l   "     The next character is lowercased
                     &  "     The whole text we matched

Resposta antiga / mais interessante:

:se nows
Vuò~h2/á


2

CJam , 26 24 bytes

qeu{_'[,65>&,T^:T{el}&}%

Experimente online!

Explicação

q         e# Read all input.
eu        e# Uppercase it.
{         e# For each character:
 _        e#  Duplicate it.
 '[,65>&  e#  Set intersection with the uppercase alphabet.
 ,        e#  Length (either 0 or 1 in this case).
 T^:T     e#  XOR with T (T is initially 0), then store the result back in T.
 {el}&    e#  If The result of the XOR is true, lowercase the character.
}%        e# (end for)

2

Pitão, 11 bytes

srR~xZ}dGrZ

Experimente aqui

Explicação

              # Z = 0; Q = eval(input())
srR~xZ}dGrZQ  # Auto-fill variables
         rZQ  # lowercase the input
 rR           # Apply the r function to each letter of the input with
   ~xZ}dG     # ... this as the other argument
   ~          # use the old value of the variable Z, then update it with the value of ...
    xZ        # Z xor ...
      }dG     # the variable d is a lowercase letter
              # because of how mapping works in pyth, d will contain the current letter
              # This causes Z to flip between 0 and 1, alternately upper and lower casing
              # the current character if it is a letter

2

PowerShell, 86 bytes

-join($args[0]|%{if($_-match"[a-z]"-and($i=!$i)){"$_".toupper()}else{"$_".tolower()}})

A entrada é uma [char[]]matriz.

Comentários no código para explicação

# Join the array of string and char back together.
-join
    # Take the first argument and pass each element ([char]) down the pipe. 
    ($args[0]|%{
        # Check if this is a letter. Second condition is a boolean that changes at every pass 
        # but only if the current element is a letter. If not the condition never fires
        if($_-match"[a-z]"-and($i=!$i)){
            # Change the character to uppercase
            "$_".toupper()
        }else{
            # Output the character to lowercase. 
            # Special characters are not affected by this method
            "$_".tolower()
        }
    })

2

Haskell, 105 83 + 2 4 + 1 byte do separador = 108 86 88 Bytes

import Data.Char
f#(x:y)|isLetter x=([toUpper,toLower]!!f)x:(1-f)#y|1>0=x:f#y
_#l=l

A função é (1#), inicia em minúsculas. Experimente online!

O triste é que isso é mais longo que as respostas Java e C #. Obrigado a Ørjan Johansen por salvar 22 bytes ao mesclar três linhas em uma!


2
Vi que precisava essas funções longa importados então eu nem sequer tentar ... mas isso é um pouco demais, você pode mesclar algumas linhas:f#(x:y)|isLetter x=([toUpper,toLower]!!f)x:(1-f)#y|1>0=x:f#y
Ørjan Johansen

Desculpe por nitpicking, mas acho 1#que não conta como uma função anônima. No meu entendimento, deve-se conseguir vincular uma função anônima a um identificador, mas, por exemplo f=1#, não funcionará. Em vez disso, você precisa da seção (1#)para +2 bytes. Isso também é afirmado implicitamente em nossas diretrizes da comunidade para jogar golfe em Haskell , embora talvez essas devam ser adaptadas para mencionar explicitamente esse caso.
Laikoni

@Laikoni ok, resposta atualizada
Nome genérico para exibição

2

Planilhas Google, 264 bytes

=ArrayFormula(JOIN("",IF(REGEXMATCH(MID(A1,ROW(OFFSET(A1,0,0,LEN(A1))),1),"[A-Za-z]"),CHAR(CODE(UPPER(MID(A1,ROW(OFFSET(A1,0,0,LEN(A1))),1)))+MOD(LEN(REGEXREPLACE(LEFT(A1,ROW(OFFSET(A1,0,0,LEN(A1)))),"[^A-Za-z]","")),2)*32),MID(A1,ROW(OFFSET(A1,0,0,LEN(A1))),1))))

É uma grande bagunça, mas é um pouco mais fácil se você expandir:

=ArrayFormula(
  JOIN(
    "",
    IF(REGEXMATCH(MID(A1,ROW(OFFSET(A1,0,0,LEN(A1))),1),"[A-Za-z]"),
      CHAR(
        CODE(UPPER(MID(A1,ROW(OFFSET(A1,0,0,LEN(A1))),1)))
        +
        MOD(LEN(REGEXREPLACE(LEFT(A1,ROW(OFFSET(A1,0,0,LEN(A1)))),"[^A-Za-z]","")),2)*32
      ),
      MID(A1,ROW(OFFSET(A1,0,0,LEN(A1))),1)
    )
  )
) 

A pseudo-lógica funcionaria assim:

For each character {                                    // ArrayFormula()
  If (character is a letter) {                          // REGEXMATCH(MID())
    Return CHAR(                                        // CHAR()
      CODE(UPPER(letter))                               // CODE(UPPER(MID()))
      +
      If (nth letter found and n is odd) {32} else {0}  // MOD(LEN(REGEXREPLACE(LEFT())))
    )
  } else {
    Return character                                    // MID()
  }
}

2

Perl 5 , 24 bytes

23 bytes + 1 byte para -p.

Obrigado a @Dada por -2 bytes.

s/\pl/--$|?uc$&:lc$&/eg

Experimente online!


Arrumado. \plem vez de [a-z]a 2 bytes tho :)
Dada

@ Dadá, eu realmente não sabia disso! Como eu não sabia disso !! Obrigado!
Dom Hastings

Eu acho que aprendi com Ton Hospel, e eu o uso de vez em quando (na verdade, eu costumo esquecer isso com muita frequência e usá-lo [a-z]!). Se você quer saber, vem do perlrecharclass ;) #
Dada


1

C 64 bytes

B;R(char *s){for(;*s=isalpha(*s)?(B=!B)?*s|=32:*s&=~32:*s;s++);}

Aproveita a codificação ascii, onde as letras maiúsculas e minúsculas são deslocadas em 0x20.


Você não precisa do espaço '' entre chare*s
cleblanc

Isso parece muito com a resposta do @ cleblanc .
Digital Trauma

Publiquei quando a publicação de @ cleblanc usou toUpper () e toLower ().
User230118

11
Meu comentário sugerindo essa abordagem foi às 18: 29: 34Z. a edição da cleblanc para incorporar isso foi às 18: 37: 36Z. Sua resposta foi publicada em 18: 38: 21Z. Acho que a resposta da cleblanc foi menos de um minuto antes da sua postagem. Sua resposta é notavelmente semelhante à minha sugestão, mas acho que essa é a natureza do código-golfe - muitas vezes as soluções no mesmo idioma convergem para a mesma coisa - por isso vou deixá-lo passar :) :)
Digital Trauma

1

Retina , 32 bytes

T`l`L
01T`L`l`[A-Z][^A-Z]*[A-Z]?

Experimente online!

Primeiro converte a entrada em maiúscula e, em seguida, agrupa a entrada em correspondências que contêm até duas letras maiúsculas. O único momento em que ele conterá apenas uma letra é se a última letra não tiver um par. Em seguida, minúscula a primeira letra de cada uma dessas correspondências.

O 01segundo estágio se traduz aproximadamente em: não altere o comportamento desse estágio com base no número da partida, mas aplique as alterações apenas ao primeiro caractere de cada partida.


1

PHP 5, 54 bytes

<?=preg_filter('/\pL/e','($0|" ")^a^aA[$i^=1]',$argn);

1

C #, 100 bytes

s=>{var r="";int m=0;foreach(var c in s)r+=char.IsLetter(c)?(char)(++m%2>0?c|32:c&~32):c;return r;};



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.