É CAPS LOCK DIA

29

22 DE OUTUBRO É DIA INTERNACIONAL DOS CAPS ! Infelizmente, alguns não reconhecem a glória da trava de todos os céus. DIZEM QUE PARECE "OBRIGADO" OU "GOSTA DE GRITAR" OU ALGUM disparate. A fim de se conformar com essas queixas obviamente ilógicas e inanas, escreva-me um programa que transforma texto normal em texto "sensível" ou "razoável" para fazer com que as pessoas parem de se queixar.

Descrição

A entrada e a saída da sua solução serão cadeias que contêm apenas caracteres ASCII imprimíveis.

A cadeia de entrada conterá zero ou mais execuções de caps lock . Uma execução de caps lock (ou CLR para abreviar) é definida da seguinte maneira:

  • O CLR não deve conter letras minúsculas ( a-z), exceto como o primeiro caractere de uma palavra .

    • Uma palavra , para os propósitos deste desafio, é uma sequência de não-espaços. Assim, PPCG, correcthorsebatterystaple, e jkl#@_>00()@#__f-023\f[são todos considerados palavra s.
  • O CLR também deve conter pelo menos um espaço; portanto, deve ter pelo menos duas palavras s.

  • Cada uma das palavras s no CLR deve conter pelo menos duas letras ( A-Za-z).

    • Observe que isso se refere ao CLR obtido por ele mesmo, sem caracteres ao redor que possam não ter sido incluídos no CLR. Por exemplo, não é um CLR porque a sequência possui a palavra s com menos de duas letras.foO BarO B

Os CLRs devem ser analisados ​​"avidamente" - ou seja, você deve sempre encontrar os CLRs mais longos possíveis.

Depois de identificar todos os CLRs na sequência de entrada, troque o caso de todas as letras dentro dos CLRs e produza a sequência resultante.

Casos de teste

A primeira linha é entrada e a segunda é saída. Partes em negrito da entrada são substrings considerados CLRs.

CAPS LOCK IS THE BEST!
caps lock is the best!
I really LOVE pROGRAMMING pUZZLES AND cOde Golf!
I really love Programming Puzzles and Code Golf!
This is a challenge on PPCG. This is a test CASE. TEST
This is a challenge on PPCG. This is a test case. test
LorEM iPSUM DOLoR sIT amet, conSECTETur ADIPISciNG eLIT. MAECENAS iD orci
Lorem Ipsum doloR sIT amet, conSECTETur ADIPIScing Elit. maecenas Id orci
;'>}{/[]'"A*(389971(*(#$&B#@*(% c'>#{@D#$! :,>/;[e.[{$893F
;'>}{/[]'"a*(389971(*(#$&b#@*(% C'>#{@d#$! :,>/;[e.[{$893F
iT'S cAPS lOCK DAY!!! cELebraTE THis WONDERFUL key
It's Caps Lock day!!! Celebrate this WONDERFUL key
aBcDE fGHIj KLmNO pQrST (uVwXY) ZZ___Zz__Z
aBcde Fghij KLmno PqrST (uVwxy) zz___zz__Z
#aA# aA
#aA# aA

Regras

  • Você pode supor que a entrada nunca conterá dois ou mais espaços seguidos e que nunca conterá um espaço inicial ou final.

  • Bônus de 20% (multiplique o comprimento do código por 0,8) se todo o código for um CLR. ;) (principalmente apenas por diversão, já que é improvável que o envio vencedor tenha esse bônus)

  • Isso é , então o código mais curto em bytes vence.

Maçaneta da porta
fonte
16
Por favor, pare de gritar.
TheDoctor
4
Além disso, no caso de teste nº 3, o PPCG capitalizado também não seria minúsculo? ( PPCG. Tcontém um espaço)
TheDoctor
2
@ Dennis Li que na voz de Morty (de Rick e Morty), porque ele está falando com "Rick".
mbomb007
11
"pontos de bônus para o seu código ser um CLR" só me faz querer fazer isso em LOLCODE ...
gato

Respostas:

4

CJam, 100 86 83 81 bytes

Ml{_,),{1$<_S/(4$!>\1f>s+_eu=*S%_{'[,_el^:Af&s,2<},!*1>},_{W=/(AA26m>er}{;(}?\s}h

Experimente este violino no intérprete CJam ou verifique todos os casos de teste de uma só vez .

Algoritmo

  1. Identifique o CLR mais longo possível que começa com o primeiro caractere.

  2. Se existir, troque a caixa, imprima e remova-a do início da string.

    Senão, remova um único caractere do início da string e imprima-o sem modificação.

  3. Se houver mais caracteres, volte para a etapa 1.

Como funciona

Ml         e# Push an empty string and a line from STDIN.
{          e# Do:
  _,       e#   Copy the string on the stack and compute its length (L).
  ),       e#   Push [0 ... L].
  {        e#   Filter; for each integer I in that array:
    1$<    e#     Copy the string and keep its first I characters.
    _S/    e#     Push a copy and split at spaces.
    (      e#     Shift out the first word.
    4$!    e#     Push the logical NOT of the fifth topmost item of the stack.
           e#     This pushes 1 for the empty string on the bottom, and 0
           e#     for non-empty strings and printable characters.
    >      e#     Remove that many characters from the beginning of the first word.
           e#     This will remove the first character iff the string on the
           e#     stack is the entire input. This is to account for the fact that
           e#     the first word is not preceded by a space.
    \1f>   e#     Remove the first character of all remaining words.
    s+     e#     Concatenate all of them.
    _eu=   e#     Convert a copy to uppercase and check for equality.
    *      e#     Repeat the I characters 1 or 0 times.
    S%_    e#     Split at runs of spaces, and push a copy.
    {      e#     Filter; for each non-empty word:
      '[,  e#       Push the string of all ASCII characters up to 'Z'.
      _el  e#       Push a copy and convert to lowercase.
      ^    e#       Perform symmetric difference, pushing all letters (both cases).
      :A   e#       Store the result in A.
      f&s  e#       Intersect A with each character of the word. Cast to string.
      s    e#       This removes all non-letters from the word.
      ,2<  e#       Count the letters, and compare the result to 2.
    },     e#     If there are less than 2 letters, keep the word.
    !      e#     Push the logical NOT of the result.
           e#     This pushes 1 iff all words contain enough letters.
    *      e#     Repeat the array of words that many times.
    1>     e#     Remove the first word.
  },       e#   Keep I if there are still words left.
  _{       e#   If at least one I was kept:
    W=     e#     Select the last (highest) one.
    /      e#     Split the string on the stack into chunks of that length.
    (      e#     Shift out the first chunk.
    AA26m> e#     Push "A...Za...z" and "a...zA...Z".
    er     e#     Perform transliteration to swap cases.
  }{       e#   Else:
    ;      e#     Discard the filtered array.
    (      e#     Shift out the first character of the string on the stack.
  }?       e#
  \s       e#   Swap the shifted out chunk/character with the rest of the string.
}h         e# If the remainder of the string is non-empty, repeat.
Dennis
fonte
5
Como funciona: toca 20 notas E # no piano.
Kirbyfan64sos
Adicionei mais alguns detalhes. : P
Dennis
2

Perl, 96 82 80 bytes

-pe'$y=qr/[^a-z ]{2,}|\b\S[^a-z ]+/;s#$y( $y)+#join$,,map{uc eq$_?lc:uc}$&=~/./g#eg'

Passa em todos os testes. Assume a entrada de STDIN, imprime em STDOUT.

Como funciona:

  • configure um regex ( $y) que corresponda

    • pelo menos dois caracteres não minúsculos e sem espaços em branco OU
    • um limite de palavras, seguido por um caractere que não seja um espaço em branco, seguido por um ou mais caracteres que não sejam espaços em branco e não em minúsculas
  • corresponda a várias instâncias de cadeias separadas por espaço correspondentes $y, use s///para inverter maiúsculas e minúsculas

Tenho certeza de que há espaço para melhorias. Se houver uma maneira de se livrar de todo o join-map-splitnegócio, ainda poderá haver uma chance de se qualificar para o bônus :)

Zaid
fonte
11
Você pode salvar alguns bytes usando em a-zvez de [:lower:]. Além disso, -pegeralmente é contado como 1 byte e as aspas simples como zero bytes.
Dennis
@ Dennis: Obrigado pela sugestão! Isso me permitiu simplificar o código um pouco - até 81 de acordo com suas diretrizes sobre Perl one-liners
Zaid
Esta resposta é inválida, pois não passa no último caso de teste (cortesia recentemente adicionada por Dennis).
Maçaneta
2

Javascript, 193

decapslock =

a=>a.replace(/(^[a-z][^a-z ]+|[^a-z ]{2,})( [a-z][^a-z ]+| [^a-z ]{2,})+/g,b=>b.split` `.some(f=>f.split(/[a-z]/i).length<3)?b:b.split``.map(e=>e==(E=e.toUpperCase())?e.toLowerCase():E).join``)
<!-- Snippet UI -->
<input placeholder='sAMPLE tEXT' oninput="document.getElementsByTagName('p')[0].innerText=decapslock(this.value)" />
<p></p>

Explicação:

a=>a.replace(/* giant regex */,
  b=>
    b.split` `.some(
      f=>
        f.split(/[a-z]/i).length < 3   // check for 2+ letters
    )
      ? b                              // .some() immediately returns true if it's invalid
      : b.split``.map(                 // otherwise it's valid, so flip case
          e=>
            e == (E = e.toUpperCase()) // is it uppercase?
              ? e.toLowerCase()        // change it to LC
              : E                      // change it to UC, which was already done for
                                       // the case check
            ).join``
        )
(
^[a-z][^a-z ]+ // check for a CLR starting at the beginning with LC
|
[^a-z ]{2,}    // check for a CLR that begins in the middle of a word or starts at the
               // beginning with UC
               // in both cases, 2+ letters are required
)
(
 [a-z][^a-z ]+ // check for the next word of the CLR, starting with LC
|
 [^a-z ]{2,}   // check for the next word of the CLR, starting with UC
)+             // check for 1 or more next words
DankMemes
fonte
Esta resposta é inválida, pois não passa no último caso de teste (cortesia recentemente adicionada por Dennis).
Maçaneta
Agora, a correção adicionou toneladas de bytes a isso. Mas, está consertado #
DankMemes