Convertendo uma string para minúscula (sem funções embutidas para minúsculas!)


25

O objetivo deste code-golf é criar um código que permita ao usuário inserir uma string ASCII (contém apenas caracteres ASCII imprimíveis ), e seu programa gera a variante em minúscula dessa string.

Importante: você NÃO tem permissão para usar uma função interna que converta a string (ou apenas um caractere) em minúsculas (como ToLower()no .NET, strtolower()no PHP, ...)! Você tem permissão para usar todas as outras funções internas, no entanto.

Outra observação importante: A sequência de entrada não contém apenas caracteres maiúsculos. A sequência de entrada é uma mistura de caracteres maiúsculos, minúsculos, números e outros caracteres imprimíveis ASCII .

Boa sorte!


4
infelizmente, terei que optar por não participar. Eu não sou iniciante.
John Dvorak

@ Jan: Bem, com iniciantes eu realmente quis dizer que o nível de habilidade disso seria 'iniciante', e não que apenas iniciantes pudessem entrar. Eu removi a palavra 'iniciante' e certamente você pode entrar.
ProgramFOX

1
Expressões regulares são permitidas? Apenas o GolfScript poderia vencer s/./\L\0/g.
manatwork

3
@ manatwork: certamente \Lé construído em?
marinus

@ manatwork: Sim, é permitido um regex.
ProgramFOX

Respostas:


21

Shell - 10

Tradução da solução Perl de @ Gowtham usando /bin/tr.

tr A-Z a-z

Exemplo de execução:

% tr A-Z a-z <<<'Hello WORLD! @'
hello world! @

O que faz disso a resposta aceita, por curiosidade? Gowtham teve uma solução de 10 caracteres primeiro ...
Ry- 10/10/13

1
Com base na discussão sobre meta , parece que o raciocínio é que a solução de Gowtham é de 11 caracteres (porque a -pbandeira conta como um). Eu concordo, porém, o seu parece que ele merece mais ser aceito ..
FireFly

Ah, obrigado - isso faz sentido. Vou manter isso em mente!
Ry-

53

Python 2.7 - 30 (com abuso de regras terrível e sem desculpas)

raw_input().upper().swapcase()

Como uma edição anônima apontou, você pode fazer isso em 2726 no Python 3 :

input().upper().swapcase()

Estou flagrantemente abusando das regras aqui, mas ...

Importante: você NÃO tem permissão para usar uma função interna que converta a string (ou apenas um caractere) em minúsculas (como ToLower()no .NET, strtolower()no PHP, ...)! Você tem permissão para usar todas as outras funções internas, no entanto.

Isso pega as cordas e as cobre em maiúsculas . Em seguida, em uma chamada de método não relacionada, ele reverte as letras maiúsculas e minúsculas - para que todas as letras minúsculas se tornem maiúsculas ... e troque as letras maiúsculas para minúsculas .


1
A solução Python 3 possui 26 caracteres.
Timtech

@ Timtech Eu não posso contar.

1
Não é apenas não relacionado. É muito independente.
Carter Pape

1
Isso terá resultados estranhos ao encontrar texto que contenha os caracteres ß.
FUZxxl

33

Perl - 11 10 caracteres.

y/A-Z/a-z/

y///é o mesmo que tr///!

Em ação:

% perl -pe 'y/A-Z/a-z/' <<< 'Hello @ WORLD !'
hello @ world !

3
+1, para a única linguagem da vida real que supera as menos reais (?).
Behrooz

Na verdade, são 11 caracteres. A -popção é contada como 1.
manatwork

@manatwork Ou deveria ser contado como 2: -e p:)
Gowtham

1 se você assumir -e( perl -e-> perl -pe), 3 se você assumir um script ( perl-> perl -p).
precisa saber é o seguinte

10

Befunge-98- 26 22 21 19

~:''-d2*/1-!' *+,#@

Baseia-se no fato de que (c-39)/26é 1apenas para códigos de caracteres de caracteres ASCII maiúsculos (assumindo divisão inteira). Para cada caractere c, imprima c + (((c-39)/26)==1)*' '.

Sessão de amostra:

% cfunge lower.b98
hello WORLD!
hello world!
This is a TEST!!11 az AZ @[`{
this is a test!!11 az az @[`{

9

Python 3, 58

print("".join(chr(ord(x)+('@'<x<'[')*32)for x in input()))

Você pode explicar como isso funciona? Estou realmente interessado em melhorar o Python. Eu não entendo como a parte map(ord,input())funciona.
Asteri

1
@JeffGohlke: mapaplica uma função (neste caso ord) a uma interable e retorna uma iterável. É como uma forma mais curta de (ord(x) for x in input()).
Ry-

Consegui. Obrigada pelo esclarecimento!
Asteri

1
A sua resposta segue o espírito da questão, mas o meu segue a letra da questão ...

Muito agradável. Bata minha solução de 62 comprimentos não publicada for c in input():print([c,(chr(ord(c)+32))]['@'<c<'['],end=''). Tentei alguns com o map(ord,input())truque, mas perdi a multiplicação do valor verdade por 32 e o adicionei ao truque do código de caractere. Muito agradável.
Steven Rumbalski

8

Ruby, 18 caracteres

Nada realmente interessante.

gets.tr'A-Z','a-z'

(executado no IRB)

Apenas por diversão: uma versão confusa:

$,=$* *' ';$;=$,.tr'A-Z','a-z';$><<$;

Execute assim:

c:\a\ruby>lowercase.rb Llamas are AMAZING!

Saída

llamas are amazing!

7

J - 30

'@Z'(]+32*1=I.)&.(a.&i.)1!:1]1

J é lido da direita para a esquerda, portanto, para dividir isso:

  1. Solicitar entrada do usuário: 1!:1]1
  2. Execute o algoritmo no espaço do ponto de código: &.(a.&i.)
  3. Identifique o intervalo de caracteres para cada letra; os caracteres entre codepoints "@" e "Z" são considerados maiúsculas: 1=I..
  4. Para cada ponto de código maiúsculo, adicione 32: ]+32* ...
  5. Observe que a etapa (2) cria uma etapa implícita (5): começamos projetando do caractere para o domínio inteiro; portanto, agora que terminamos, mapeamos esses números inteiros de volta aos caracteres.

Obviamente, essa implementação específica considera apenas o ASCII; mas a abordagem poderia ser estendida para pelo menos o plano multilíngue básico em Unicode.


1
Agradável! Infelizmente, parece que sua solução está indo no caminho errado. ;-) Porém, deve ser uma solução fácil. (Edit: '@Z'(]+32*1=I.)&.(a.&i.)1!:1]1should do it)
FireFly

Boa captura, obrigado. Também estou impressionado você fosse capaz de corrigir o código-se: J não é a língua mais imediatamente acessível lá fora :)
Dan Bron

Ah, eu mesmo brinquei com J .. Eu consegui pensar u:(a.i.x)+32*1='@Z'I.x=.1!:1]1, o que corresponde ao seu tamanho, mas é muito menos interessante (pois não usa 'under'). Falando nisso, eu não sabia sobre diádico I., então obrigado por usá-lo. :-)
FireFly

Cool. But your Befunge solution still has J beat by 4 characters. Obviously I can't let that stand :) I'm trying to see if trim the J solution down by following your lead in relying solely on '@', rather than both '@' and 'Z'.
Dan Bron

(32(23)b.])&.(3&u:), should be 5 bytes shorter.
FrownyFrog

7

C 64 63 59 55 chars

main(c){while(c=getchar(),~c)putchar(c-65u<27?c+32:c);}

I count only 63 characters there.
manatwork

You can lose 9 characters: drop int and ,c>=0. They're not necessary here.
JoeFish

we need c>=0 as getchar(EOF) will be < 0. Thanks for other suggestion.
Rozuur

2
1. ~(c=getchar()) 2. c-64u<27
ugoren

1
Insignificantly small bug: seems there should be 65 instead of 64. pastebin.com/Zc9zMx2W
manatwork

5

Golfscript - 17

Program:

{..64>\91<*32*+}%

Explanation:

  1. {}% maps the code inside to every character in string.
  2. .. copies the top of the stack (the character) twice.
  3. 64> 1 if character code is greater than 64, else 0.
  4. \ swaps the two items on the stack (gets the second copy of the letter, and stores the result of 64> in position two).
  5. 91< checks to see if character code is less than 91. Similar to step 3.
  6. * multiplies the results from steps 3 and 5 together. Only equal to 1, if both steps were true.
  7. 32* multiplies the result of step 6 with 32. Will be 32 if step 6 was 1, else 0.
  8. + add the result (either 32 or 0) onto the character code.

Example output:

echo HelLO @ WorLD | ruby golfscript.rb upper_to_lower.gs
hello @ world

4

Perl: 24 characters

s/[A-Z]/chr 32+ord$&/ge

Sample run:

bash-4.1$ perl -pe 's/[A-Z]/chr 32+ord$&/ge' <<< 'Hello @ WORLD !'
hello @ world !

Hem, why chr ord ? I'm pretty sure you won't learn anything in reading my answer ;-)
F. Hauri

Amazing trick, @F.Hauri!
manatwork

@nyuszika7h, the +1 is the -p command line parameter, not a newline.
manatwork

Oh right, sorry.
nyuszika7h

3

Python (33)

If in doubt, use the shell.

import os;os.system('tr A-Z a-z')

Regrettably, this is still longer than Lego's solution.


+1 That is indeed not a Python built-in you are using. Only works on linux, but still very rule-bendy!!!

@LegoStormtroopr Works everywhere there is a tr command (which does the right thing) on the path of the invoked shell, I suppose.
Paŭlo Ebermann

3

DELPHI

const
  UpChars:set of AnsiChar = ['A'..'Z'];
var
  I: Integer;
begin
  SetLength(Result, Length(pString));
  for I := 1 to length(pstring) do
    Result[i] := AnsiChar((Integer(pString[i] in UpChars))*(Ord(pString[i])+32));
  WriteLn(Result);
end;

3
This is not golf. Don't you feel this piece is very different compared to others ?
Ray

1
@ray Golfing is about getting your code as short as possible. Delphi isnt a great language for golfing. I use delphi myself and even though there isnt a big chance I could win a golf with delphi, its still fun to challenge yourself.
Teun Pronk

3

JavaScript - 109 104 (ES6: 95)

Thanks to some for the corrected version.

a=prompt();for(b=[i=0];c=a.charCodeAt(i);)b[i++]=String.fromCharCode(c|(c>64&c<91)*32);alert(b.join(""))

The following works if the browser supports ES6 function expressions:

alert(prompt().split("").map(c=>String.fromCharCode(c.charCodeAt()|(c>"@"&c<"[")*32)).join(""))

The first code doesn't work (tested in FF and Chrome) because when trying to get a character after the length of the string, you get undefined and then c.charCodeAt() fails because undefined don't have charCodeAt. A working example 105 characters: a=prompt();for(b=[i=0];c=a.charCodeAt(i);)b[i++]=String.fromCharCode(c|(c>64&&c‌​<91)*32);alert(b.join(''))
some

@some oops, I wonder how I came up with that snippet.. I'm pretty sure I tested that code, maybe I copied a non-working version in or something. Anyway, thanks for the correction.
FireFly

Using a bitwise and instead of a logical one... nice!
some

Uma ainda mais ES6 solução ( 79 ): L=s=>[String.fromCharCode(c.charCodeAt()|(c>"@"&c<"[")*32)for(c of s)].join(''). Uso:L('SoMeTeXt')
Florent

Agradável! Não tenho certeza de torná-lo uma mera função, pois todas as outras soluções são programas "adequados". Ainda assim, uso muito agradável de for..ofqualquer maneira.
FireFly

3

Perl 18

s/[A-Z]/$&|" "/eg

Algo como:

perl -pe 's/[A-Z]/$&|" "/eg'  <<<'are NOT allowed to: ToLower() in .NET, strtolower() in PHP'
are not allowed to: tolower() in .net, strtolower() in php

e

perl -pe 's/[A-Z]/$&|" "/eg' <<< "The input string Doesn't cOntaIn...( C0D3-@01F. ;-)"
the input string doesn't contain...( c0d3-@01f. ;-)

Para @FireFly :

perl -pe 's/[A-Z]/$&|" "/eg' <<< "Doesn't this translate @ to \` and [\]^_ to {|}~DEL? "
doesn't ... @ to ` and [\]^_ to {|}~del? 

não.

Mais genérico: 18 caracteres de qualquer maneira:

s/[A-Z]/$&|" "/eg

s/[A-Z]/$&^" "/eg

Isso não vai mudar nada no estado:

perl -pe 's/[A-Z]/$&^" "/eg' <<< "Doesn't ... @ to \` and [\]^_ to {|}~DEL? "
doesn't ... @ to ` and [\]^_ to {|}~del? 

Todos funcionam bem, mas a vantagem de mudar |(ou) por ^(xor) é que a mesma sintaxe poderia ser usado para toLower, toUpperouswapCase :

toUpper:

perl -pe 's/[a-z]/$&^" "/eg' <<< "Doesn't ... @ to \` and [\]^_ to {|}~DEL? "
DOESN'T ... @ TO ` AND [\]^_ TO {|}~DEL? 

e swapCase (18 + 1 = 19 caracteres) :

perl -pe 's/[a-z]/$&^" "/egi' <<< "Doesn't ... @ to \` and [\]^_ to {|}~DEL? "
dOESN'T ... @ TO ` AND [\]^_ TO {|}~del? 

Eu esqueci +1 por -pdesculpe @manatwork #
F. Hauri

Isso não se traduz @em backtick e [\]^_para {|}~DEL? E é aí que reside a parte complicada ..
FireFly

1
@FireFly Não, $&tem que combinar [A-Z].
F. Hauri 04/12/2013

Oh culpa minha. Muito legal então!
FireFly

3

javascript 80

"X".replace(/[A-Z]/g,function($){return String.fromCharCode($.charCodeAt()+32)})

(76 se você remover "X" )

com prompte alert- 92

alert(prompt().replace(/[A-Z]/g,function($){return String.fromCharCode($.charCodeAt()+32)}))

violino

Obrigado a @FireFly @some @ C5H8NNaO4 e @minitech


Er, você precisaria encerrar o segundo argumento replacecom function($){return ...}, não? A propósito, o primeiro parâmetro da função de substituição é a string correspondente, para que você possa descartar os parênteses no regex.
FireFly

Como eu iria executá-lo, assim?
C5H8NNaO4 07/10

@ C5H8NNaO4 str (código aqui)
Math chiller

6
Acho que todas (ou pelo menos a maioria) das respostas aqui são lidas de stdin e impressas para stdout. Pelo que entendi, a convenção é usar prompte alertpara E / S em JS.
FireFly

1
Você precisa de um /gsinalizador para que isso funcione corretamente.
Ry-

2

R

71 caracteres:

chartr(paste(LETTERS,collapse=""),paste(letters,collapse=""),scan(,""))

83 caracteres:

a=as.integer(charToRaw(scan(,"")))
b=a%in%(65:90)
a[b]=a[b]+32
rawToChar(as.raw(a))

São 86caracteres - as novas linhas contam como 2 caracteres. ( string-functions.com/length.aspx )
Timtech

@ Timtech: No R, você pode substituir as novas linhas no código, ;para que elas não contem apenas um caractere. Pode ser escrito:a=as.integer(charToRaw(scan(,"")));b=a%in%(65:90);a[b]=a[b]+32;rawToChar(as.raw(a))
perfil completo de plannapus

Sim, agora eu percebi. Eu li sobre meta ... parece que apenas no Windows as novas linhas têm 2 caracteres (eu estava usando um programa para medir o comprimento do meu código).
Timtech



2

PHP (42)

Execute a partir da linha de comando:

-R'echo@str_ireplace($a=range(a,z),$a,$argn);'

-R e as aspas simples não são contadas.


Se você seguir a solução Gowtham's Peal, contaria apenas 42 caracteres.
Eisberg

1
@eisberg: Atualizado a pontuação, deixando uma versão de 43 caracteres na história em caso de qualquer disputa.
PleaseStand

str_ireplacefaz pesquisa sem distinção entre maiúsculas e minúsculas, o que está esticando as regras, se não as violando.
ugoren

@ugoren Acho que não. Como é claramente afirmado, não são permitidas apenas funções integradas que alteram o caso e isso ignora o caso que não o altera.
Eisberg

2

PowerShell: 69 65 64

Eu tentei meia dúzia de maneiras de fazer o Replace funcionar da maneira que eu queria, sem usar a [regex]::Replacesintaxe longa , mas não tive sorte. Se alguém tiver uma idéia do que pode funcionar, sugira.

Código de golfe:

[regex]::Replace((read-host),"[A-Z]",{[char](32+[char]"$args")})

Alterações do original:

  • Reorganizou o último argumento para que [int]não seja mais necessário, por sugestão nos comentários.

Explicação:

(read-host) obtém a entrada do usuário.

[regex]::Replace(... )diz ao PowerShell para usar a correspondência de RegEx para executar operações de substituição em uma seqüência de caracteres.

"[A-Z]" corresponde a todas as letras maiúsculas.

{... }diz ao PowerShell para usar um script para determinar o valor de substituição.

[char]"$args" pega a correspondência atual e a digita como um caractere ASCII.

32+ converte o caractere em um número inteiro, representando o código ASCII e aumenta o valor em 32 - o que corresponderia ao código ASCII da letra minúscula correspondente.

[char](... )pega o valor resultante e o converte novamente em um caractere ASCII.

Demonstração do original:

insira a descrição da imagem aqui

(Versão atual testada - captura de tela ainda não publicada.)


1
Ainda não verifiquei como contornar isso [regex]::Replace, mas você pode salvar 4 caracteres mudando [int]para+
goric

1
Na verdade, todo o último argumento pode ser reorganizada para {[char](32+[char]"$args")}, o que elimina a necessidade de explicitamente convertido para int e raspa mais um personagem
Gorić

@ Goric Geez, por que não pensei nisso já? Ainda estou aprendendo, eu acho.
Iszi

2

k2, 15 bytes

eu sou super atrasado para este, mas achei legal assim mesmo.

{_ci 32+_ic x}'

Além disso:

Pitão, 10 bytes

Realmente não conta, porque o Pyth foi criado depois que este foi publicado. Ainda legal.

jkmC+32Cdw

2

05AB1E , 3 bytes

u.š

Porta da resposta do usuário @ user8777 Python 3 .

Experimente online.

Explicação:

u    # Convert the (implicit) input to uppercase
   # Switch the case (upper to lower and vice-versa)
     # (and output the result implicitly)

Mas sem nenhum recurso de alteração de caso:

05AB1E , 12 11 bytes

ÇIS.u32*+çJ

-1 byte graças a @Emigna .

Experimente online.

Explicação:

Ç            # Get the unicode values of each character of the (implicit) input-String
 IS          # Get the input-string, split to characters again
   .u        # Check for each if it's uppercase or not (1 if truthy; 0 if falsey)
     32*     # Multiply that result by 32 (32 if truhy; 0 if falsey)
        +    # Add it to all the unicode values at the same indices in the list
         ç   # Convert the now modified unicode values back to characters
          J  # And join all characters together to a string again
             # (which is output implicitly as result)

1
ÇIS.u32*+çJsalva um byte na sua versão de 12 bytes.
Emigna 9/04

@ Emigna Ah, inteligente. Eu havia tentado a .u32*+abordagem da seguinte maneira: εÇy.u32*+ç]Jmas, infelizmente, çagrupa os personagens em uma lista, então um adicional Jou `foi necessário após o ç..
Kevin Cruijssen 09/04

1

Javascript, 105

prompt().split("").map(function(a){c=a.charCodeAt(0);return String.fromCharCode(c|(c-64?32:0))}).join("")

Na verdade, não havia nenhum formulário de saída especificado, portanto, execute-o no console Sim, o JavaScript é realmente detalhado com o código <-> string


1
c.charCodeAt()- o padrão é 0se um índice for omitido. Além disso, as quebras no '@' Eu acredito que (ele é "minúscula" a crase)
FireFly

@FireFly agradável, Thanks !, ok eu vou vai corrigi-lo =)
C5H8NNaO4

1

Ruby: 66

def l(s)s.bytes.map{|b|(65..90).include?(b)?b+32:b}.pack('c*');end

1

C # - 108

class P{static void Main(string[]a){foreach(var c in a[0])System.Console.Write(
(char)(c>64&&c<91?c+32:c));}}

Cerca de 70 apenas para o corpo do método.

Adicione 5 caracteres para incluir um LF / CR na saída:

class P{static void Main(string[]a){foreach(var c in a[0]+"\n")System.Console.Write(
(char)(c>64&&c<91?c+32:c));}}

Uma versão do LINQ seria mais curta:

class P{static void Main(string[]a){a[0].Any(c=>System.Console.Write(
(char)(c>64&&c<91?32+c:c))is P);}}

(103) .. exceto que requer using System.Linq;(total: 121).


1

Haskell - 58

p x|(elem x['A'..'Z'])=[x..]!!32|1<2=x
main=interact$map p

1

Python 3-70

Atualizado para as alterações do OP.

Eu sou um novato em Python, então qualquer crítica é bem-vinda.

print("".join(chr(ord(c)+32) if 64<ord(c)<91 else c for c in input()))

Sinto muito, eu tinha que dizer que você não tem permissão para usar uma função para diminuir em um caractere. Pergunta atualizada.
#ProgramaFOX #

1
Por favor, veja meu comentário recente : seu código funcionará apenas se a string de entrada contiver apenas caracteres maiúsculos, mas observe que também contém outros caracteres ASCII, como caracteres minúsculos e números.
ProgramFOX

Ok, vai atualizar quando eu chegar em casa
Asteri

@ProgramFOX Atualizado.
Asteri

Jeff, confira resposta @minitechs . Vocês dois têm abordagens muito semelhantes, portanto devem poder ver como e por que a resposta dele é mais curta.

1

Perl, 9 + 1 (para sinalizador -p) = 10

$_="\L$_"

\L foi especificamente questionado e permitido, porque, mesmo sendo incorporado, não é uma função.


1

Powershell, 53 49 bytes

-4 bytes graças a @AdmBorkBork

-join($args|% t*y|%{[char](32*($_-in65..90)+$_)})

Script de teste:

$f = {

-join($args|% t*y|%{[char](32*($_-in65..90)+$_)})

}

@(
    ,("Hello WORLD from PowerShell", "hello world from powershell")
) | % {
    $a,$e = $_
    $r = &$f $a
    "$($r-eq$e): $r"
}

Saída:

True: hello world from powershell

legal! ¯\_(ツ)_/¯
Mazzy

1

Código de máquina 8086, 14 bytes

Montado:

AC 3C 41 7C 06 3C 5A 7F 02 0C 20 AA E2 F2

Listagem desmontada:

 ; Lowercase a string
 ; Input: string: SI, length: CX
 ; Output: string: DI
 TOLOW  MACRO   
        LOCAL _LOOP, _STORE
       _LOOP:
 AC         LODSB           ; load byte from [SI] into AL, advance SI 
 3C 41      CMP  AL, 'A'    ; is char less than 'A'? 
 7C 06      JL   _STORE     ; if so, do not convert 
 3C 5A      CMP  AL, 'Z'    ; is char greater than 'Z'? 
 7F 02      JG   _STORE     ; if so, do not convert 
 0C 20      OR   AL, 020H   ; lowercase the char 
       _STORE:
 AA         STOSB           ; store char to [DI], advance DI 
 E2 F2      LOOP _LOOP      ; continue loop through string 

Implementado como uma MACRO(essencialmente uma função). String de entrada SI, comprimento em CX. String de saída emDI .

Saída do programa de teste do PC DOS:

insira a descrição da imagem aqui

Baixe e teste o programa de exemplo TOLOW.COM .


de onde vem a contagem de 14 bytes? o trecho é mais longo que isso, mesmo sem comentários ... 14 bytes é o programa compilado?
Jonah

1
@Jonah O byte opcode está na coluna da esquerda, AC 3C 41 , etc. Adicionarei o código hexadecimal montado no topo para maior clareza. codegolf.meta.stackexchange.com/a/12340/84624
640 KB
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.