O comando gatinho

65

Um gatinho é muito parecido com um gato. Algumas das principais diferenças são fofura, falta de inteligência e tamanho. Da mesma forma, o catcomando é diferente do kittencomando. Felizmente, há apenas uma diferença neste caso. No comando kitten, todas as letras maiúsculas são substituídas por letras minúsculas.


Objetivo

Para implementar um programa que se comporta de maneira semelhante a cat. Todos os caracteres [A-Z]são emitidos em minúsculas.


Entrada

Uma lista de arquivos como argumentos de linha de comando. Se nenhum arquivo estiver listado, leia a partir da entrada padrão. A entrada pode conter caracteres não imprimíveis e caracteres fora do intervalo ASCII.


Resultado

Se a entrada for um monte de arquivos, concatene o conteúdo e produza todos os caracteres em minúsculas. Se estiver lendo STDIN, imprima o conteúdo de STDIN com todas as letras maiúsculas em minúsculas.

Nota: apenas coloque os caracteres em [A-Z]minúsculas. É inaceitável se outros caracteres forem minúsculos.


Exemplos

$ echo "HelLo" > file.txt
$ kitten file.txt
hello
$ echo "Good Bye" | kitten
good bye
$ echo "Ä" | kitten
Ä

Como de costume no , o mínimo de bytes vence.

Classificação


Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

# Perl, 43 + 2 (-p flag) = 45 bytes

Você também pode transformar o nome do idioma em um link que será exibido no snippet do placar de líderes:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

O número um
fonte
2
Ao declarar explicitamente "Somente [A-Z]letras minúsculas", você está antecipando a entrada Unicode?
AdmBorkBork 29/09
2
@ TimmyD Sim, mas é principalmente para impedir que as pessoas usem funções integradas para minúsculas.
TheNumberOne
3
@FryAmTheEggman permalink
Dennis
11
Que tal Ü, Ñe os gostos?
Mast
2
É tão bom quando você não vê qualquer Pyth em tudo em um codegolf ...
jmm

Respostas:

52

Perl, 6 bytes

Código de 5 bytes + linha de comando de 1 byte

$_=lc

Exemplo de uso:

echo ABCdef | perl -p kitten.pl
abcdef

Confirmação do comportamento correto do Unicode:

echo "HelloÉ" | perl -p kitten.pl
helloÉ
Steve
fonte
2
Tem certeza de que isso não afeta os caracteres Unicode?
Martin Ender
7
@ MartinBüttner Ele não faz . Estamos na categoria "caso contrário" aqui: "As regras ASCII são usadas para a mudança de caso. A minúscula de qualquer caractere fora do intervalo ASCII é o próprio caractere. ”Meu +1 para a resposta.
Xebtl # 30/15
178

Bash, 19 bytes

cat "$@"|tr A-Z a-z

A melhor maneira de fazer gatinhos é usar gatos de verdade.

Exemplo de execução

$ ./kitten kitten
cat "$@"|tr a-z a-z
Dennis
fonte
39
A ferramenta certa para o trabalho.
Digital Trauma
120
+1 por necessitar apenas de um gato para fazer um gatinho, sempre me leva dois gatos
SnoringFrog
4
Agora que me lembra daqueles man womanpiadas ...
xebtl
2
+1 para ir para o gato clonagem em vez de método de criação de filhotes de acasalamento
MD-Tech
25
@ SnoringFrog Ele bateu no outro.
TheNumberOne
22

Perl, 11 bytes

Código de 10 bytes + linha de comando de 1 byte

y/A-Z/a-z/

Exemplo de uso:

perl -p entry.pl input1.txt input2.txt
echo "ABCdef" | perl -p entry.pl
Jarmex
fonte
15

Python 3, 77 bytes

from fileinput import*
print(end=b''.join(input(mode='rb')).lower().decode())
Anders Kaseorg
fonte
11
Isso é inteligente, usando bytes para evitar alterações não-ASCII.
matsjoyce
11

Ruby, 13 bytes

A contagem de bytes inclui 1 byte para o psinalizador. Executá-lo assim: ruby -p kitten.rb.

$_.downcase!

Recebe informações dos argumentos stdin ou file, assim como o gato adulto.

daniero
fonte
Isso apenas faz a minúscula ASCII, ou também outros caracteres como Ä?
Pa Elo Ebermann
11
@ PaŭloEbermann: Acabei de testar: echo "HelloÉ" | ruby -p kitten.rb->helloÉ
Neil Slater
Juro que houve um monte de comentários aqui sobre isso ontem. Não sei para onde foram, mas: Sim, funciona de acordo com as especificações.
Daniero
5

PowerShell, 112 bytes

function l([string]$a){97..122|%{[char]$b=$_;$a=$a-split$b-join$b};$a}if($args){$args|%{l(gc $_)}}else{l $input}

Horrivelmente ilegível. Aqui está uma versão ligeiramente expandida abaixo:

function l([string]$a){
  97..122|%{
    [char]$b=$_
    $a=$a-split$b-join$b
  }
  $a
}

if($args){
  $args|%{
    l(gc $_)
  }
}
else{
  l $input
}

Define uma função interna lque itera sobre um loop de 97 a 112 (ou seja, ASCII apara ASCII z). Divide a sequência de entrada sobre esse caractere (padrão sem distinção entre maiúsculas e minúsculas) e a junta novamente com a minúscula "correta". Observe que sim, isso significa que "Teste" se tornará brevemente "T st", pois está iterando no e, por exemplo. Não afeta a saída.

A segunda metade é a parte complicada de descobrir se temos entrada de pipeline (equivalente a stdin para PowerShell) ou entrada de linha de comando. A variável especial $argsestá presente apenas se a entrada da linha de comandos estiver presente; portanto, fazemos um loop sobre cada uma delas gc(para Get-Content) e as reduzimos até l. Caso contrário, nós apenas schlep nossa $inputaté l. Observe que poderíamos trocar nossas instruções if / else (ou seja, if($input)), mas como "input" é um caractere mais longo que "args", dessa maneira é mais curto.

AdmBorkBork
fonte
@Nazek O built-in "String".ToLower()também minúsculos caracteres Unicode, o que é contra as regras. Há muitas coisas que o PowerShell não faz direito no que diz respeito ao Unicode, mas infelizmente essa é uma instância em que funciona corretamente.
AdmBorkBork
5

Python 2, 53 bytes

from fileinput import*
print''.join(input()).lower(),
Anders Kaseorg
fonte
5

R, 97 bytes

cat(chartr("A-Z","a-z",sapply(if(length(a<-commandArgs(T))){a}else{"stdin"},readLines)),sep="\n")

Uso:

$ echo "HeLlo" > file.txt
$ Rscript kitten.R file.txt
hello
$ echo "Good Bye" | Rscript kitten.R
good bye
$ echo "bLABLa" > file2.txt
$ Rscript kitten.R file.txt file2.txt
hello
blabla
$ echo Ä | Rscript kitten.R
Ä
plannapus
fonte
5

CoffeeScript , 292 bytes

f=require 'fs';d='';p=process;v=p.argv;s=p.stdin;l=((d)=>console.log d.replace /([A-Z])/g,(a,l)=>l.toLowerCase());if v.length>2 then(v.forEach (v,i)=>if i>1 then(f.exists v, (e) =>if e then(f.readFile v,'utf-8',(r,d)=>l d) else l v))else(s.resume();(s.on 'data',(c)=>d+=c);s.on 'end',()=>l d)

Uso:

$ echo "HelLo" > file.txt
$ coffee kitten.coffee file.txt
hello
$ echo "Good Bye" | coffee kitten.coffee
good bye
$ echo "Ä" | kitten
Ä
$ coffee kitten.coffee file.txt SoMeTeXt
sometext
hello

Minha primeira participação no codegolf, por favor, não seja rude :).

Com certeza, esse código pode ser jogado mais e o café / javascript não é a melhor opção para fazer isso, mas faz o que é esperado.

Quando ele lê argumentos, também se preocupa com a existência do arquivo (se o arquivo não existir, a sequência será criada).

Qualquer ajuda ou conselho para melhorar esse código é bem-vinda!

dunpeal69
fonte
4

Julia, 123 bytes

f(s)=for l=readlines(s) print(replace(l,r"[A-Z]",lowercase))end
A=ARGS
length(A)>0?for i=A open(f,i)end:open(f,readline())

Ungolfed:

function file_to_lower(s::Stream)
    # Loop over the lines of the input stream
    for l in readlines(r)
        # Print the lowercased line
        print(replace(l, r"[A-Z]", lowercase))
    end
end

if length(ARGS) > 0
    # Loop over the files specified from the command line
    for i in ARGS
        # Open the file, apply the function, then close it
        open(file_to_lower, i)
    end
else
    # Get the input file from STDIN
    open(file_to_lower, readline())
end
Alex A.
fonte
4

CJam, 18 bytes

ea_:gs{q}?'_,_eler

A lista de arquivos deve ser fornecida na forma de URLs, que é o único formato que o CJam entende.

Execuções de exemplo

$ cjam kitten <<< "AaÁáÄä"
aaÁáÄä
$ cjam kitten file:///home/dennis/kitten file:///home/dennis/kitten
ea_:gs{q}?'_,_elerea_:gs{q}?'_,_eler

Como funciona

ea                  Push the array of command-line arguments.
  _                 Push a copy.
   :g               Retrieve the contents of all files with those URLS.
     s              Flatten the resulting array of strings.
      {q}           Push a block that reads all input from STDIN.
         ?          Select the string of the array of args is non-empty.
                    Otherwise, execute the code block.
          '_,       Push the string of all ASCII characters before _.
             _el    Push a copy and convert it to lowercase.
                er  Perform transliteration.
Dennis
fonte
4

Python 2, 100 102 97 bytes

Funcionalidade corrigida (e 4 bytes adicionados) pelo matsjoyce. Felizmente, salvei dois bytes mudando para o Python 2.

from sys import*;print''.join(f.read().lower()for f in(map(open,argv[1:])if argv[1:]else[stdin]))

Recebe argumentos da linha de comando ou de STDIN se nenhum argumento foi encontrado.

Isso abusa dos argumentos padrão de algumas funções. Por padrão, openusa o modo de texto somente leitura, que é exatamente o que queremos. read, se chamado sem argumentos, retornará todo o texto no fluxo.

Ungolfed:

import sys

if len(sys.argv) > 1:              # If we have command-line arguments:
    source = []                    # Initialize an empty list
    for path in sys.argv[1:]:      # Iterate through every filename we have
        kitfile = open(path, 'rt') # Open the file in read-only text mode
        source.append(kitfile)     # Add it to the list
else:                              # Otherwise, if the args are empty:
    source = [sys.stdin]           # Set our source to STDIN wrapped in a list

kittened = []                      # Initialize an empty list
for kitfile in source:             # Iterate through every file (or just STDIN)
    text = kitfile.read()          # Read everything from the stream
    kitten_text = text.lower()     # Make it lowercase
    kittened.append(kitten_text)   # Add it to the list
final = ''.join(kittened)          # Join everything together
print final                        # Print the result
bkul
fonte
11
Isso não funcionará para o stdin, pois você lê apenas uma linha e não a minúscula.
matsjoyce
@matsjoyce Corrigi meu código. Obrigado pela lembrança! Infelizmente, ele adicionou quatro bytes, mas, não dependendo mais da inputavaliação, eu poderia mudar para o Python 2 e remover os parênteses print.
bkul
3

Python 3, 124 123 bytes


from sys import*
for f in list(map(open,argv[1:]))or[stdin]:print(f.read().translate({i:i+32for i in range(65,91)}),end="")

Python come gatinhos!

$ python kitten.py file.txt
hello
$ echo "Good Bye" | python kitten.py 
good bye
$ echo "Ä" | python kitten.py 
Ä
matsjoyce
fonte
3

C, 106 108 bytes

Editar: corrigido um erro que aparecia ao espremer bytes. Stdin não estava trabalhando, agora está.

Tenho certeza de que conseguiria extrair alguns bytes, mas aqui está um envio fácil de entender, que não é abusivo em nenhum idioma:

main(n,s,f,c)void**s;{for(f=n-1?open(*++s,0,0):0;read(f,&c,1);putchar(64<c&c<91?c+32:c));n-->2&&main(n,s);}

E uma versão um pouco mais ordenada para leitura:

main(n,s,f,c)
void**s;
{
    for(f=n-1?open(*++s,0,0):0; read(f,&c,1); putchar(64<c&c<91?c+32:c));
    n-->2&&main(n,s);
}
algmyr
fonte
+1 porque isso me ensinou que parâmetros implícitos implícitos só são possíveis com a sintaxe K&R.
Felix Dombek
2

Mathematica, 66 bytes

kit=StringReplace[#,x:RegularExpression["[A-Z]"]:>ToLowerCase[x]]&

Chamado como

kit@"HelLo"

O Mathematica já possui uma ToLowerCasefunção, mas também converte caracteres especiais (Unicode e matemáticos). Então eu tive que gatinhar. Esta função aceita qualquer entrada.

Verbeia
fonte
@ TheNumberOne - é assim que funciona no Mathematica. Não é necessário mais código para fazer isso. Se você deseja um executável, o Mathematica não é a ferramenta.
Verbeia
Isso concatena arquivos cujos nomes são inseridos como argumentos de linha de comando, conforme necessário?
Msh210
Args de linha de comando não existem no Mathematica. Conkittenates suas entradas de função. Além disso, você não precisa atribuir a uma variável.
CalculatorFeline
2

C #, 230 226 bytes

namespace System{using Linq;class P{static void Main(string[]a){Console.Write(string.Concat((a.Length>0?string.Concat(a.Select(f=>IO.File.ReadAllText(f))):Console.In.ReadToEnd()).Select(c=>c>'@'&&c<'['?char.ToLower(c):c)));}}}

Ungolfed:

namespace System
{
    using Linq;
    class P
    {
        static void Main(string[] a)
        {
            Console.Write(                                                  // Print...
                string.Concat(                                                  // ...all chars combined to a string...
                    (a.Length > 0 ?                                             // ...commandline arguments?...
                        string.Concat(a.Select(f => IO.File.ReadAllText(f))) :  // ...then all files as single string...
                        Console.In.ReadToEnd()                                  // ...else STDIN input
                    ).Select(c => c > '@' && c < '[' ? char.ToLower(c) : c)     // ...Lowercase only A..Z
                )
            );  
        }
    }
}
RobIII
fonte
2

Haskell, 133

import System.Environment
main=getArgs>>=mapM_(>>=putStr.map l).f
f[]=[getContents]
f n=map readFile n
l x=[x..]!!sum[32|x>'@',x<'[']

O processamento de args no estilo de gato é derivado deste tutorial e , em seguida, reorganizado para barbear caracteres.

Explicando l, a função para minúsculas um caractere:

  • sum[32|condition]é uma forma mais curta de if condition then 32 else 0.
  • [x..]!!counté iterate succ x !! countis toEnum $ fromEnum x + counte menor que a importação e o uso Data.Char.toLowercom uma condição para restringi-lo ao ASCII.
  • '@'e '['são os caracteres imediatamente anteriores Ae seguintes Z, para que eu possa usar em <vez de <=.

Graças ao Anders Kaseorg para contribuir o sum[...|...]e [x..]!!truques.

Kevin Reid
fonte
11
l x=[x..]!!sum[32|x>'@',x<'[']
Anders Kaseorg
1

C #, 342 bytes

  • pega a lista de arquivos dos argumentos passados.
  • leia todos os caracteres em todos os arquivos que só serão convertidos em letras minúsculas se, e somente se, o caractere no intervalo A..Z o enviar para STDOUT.
  • Se não houver uma lista de arquivos que leia STDIN, leia todos os caracteres, converta em letras minúsculas se e somente se o caractere no intervalo A..Z for enviado para STDOUT.
namespace System{
using IO;
using Linq;
class P{
static void Main(string[]a){
Action<char>e=C=>{var c=char.ToLower(C);Console.Out.Write(c>='a'&&c<='z'?c:C);};
if(a.Length>0)a.ToList().ForEach(f=>File.ReadAllText(f).ToCharArray().ToList().ForEach(e));
else 
while(true) Console.In.ReadLine().ToCharArray().ToList().ForEach(e);
}
}
}

C #, 319 bytes

forro único, o mesmo que acima:

namespace System{using IO;using Linq;class P{static void Main(string[]a){Action<char>e=C=>{var c=char.ToLower(C);Console.Out.Write(c>='a'&&c<='z'?c:C);};if(a.Length>0)a.ToList().ForEach(f=>File.ReadAllText(f).ToCharArray().ToList().ForEach(e));else while(true)Console.In.ReadLine().ToCharArray().ToList().ForEach(e);}}}
sublinhado
fonte
1

SILOS 179 caracteres

loadLine :
a = 256
x = get a
lbla
X = x
B = x
C = 91
B - 64
if B c
printChar x
GOTO x
lblc
C - x
if C D
printChar x
GOTO x
lblD
x + 32
printChar x
lblx
a + 1
x = get a
if x a
lblb

Sinta-se livre para experimentar este código online!


Essencialmente, isso se traduz em código pused.

String input = input();
for(char c in input)
if(c is uppercase) print c + 32/*lowercase c*/else print c
Rohan Jhunjhunwala
fonte
0

C, 91 bytes

#include <stdio.h>
main(){int c;while(EOF!=(c=getc(stdin))){c=tolower(c);putc(c,stdout);}}

C, 98 bytes

#include <stdio.h>
main(){int c;while(EOF!=(c=getc(stdin))){if(c>64&&c<91)c+=32;putc(c,stdout);}}

Embora a legibilidade tenha mais do que bytes contados, a mesma lógica está escrita abaixo:

#include <stdio.h>
main()
{
int c;
        while (EOF != (c = getc(stdin))) {
                if ((c >= 'A') && ((c <= 'Z')))
                        c = (c - 'A') + 'a';
                putc(c,stdout);
        }
}
Dave Thompson
fonte
Isso falha no primeiro caso de teste.
TheNumberOne
Isso não atende às especificações. Ele deve se comportar como um gato, no sentido de que você toma nomes de arquivos como argumentos e, se nenhum nome de arquivo for fornecido, leia stdin. Atualmente, você lê apenas stdin.
algmyr
0

sed, 14 bytes

s/[A-Z]/\L\0/g

Corra com env -i sed -f kitten.sed.

Anjo
fonte
11
Como essa é apenas uma maneira elegante de dizer LANG=C sed -f kitten.sed, não tenho certeza se devo aplicar uma penalidade por isso. Esta pergunta não especifica como contar chamadas de programa e não parece abordada na meta.
Ángel
Isso concatena arquivos cujos nomes são inseridos como argumentos de linha de comando, conforme necessário?
Msh210
@ msh210 Sim, claro.
Ángel
11
@ Ángel s/.*/\L&/para uma solução de nove bytes
someonewithpc
Obrigado @someonewithpc. Ambas s/.*/\L&/e s/./\L&/gsão realmente soluções de 9 bytes!
Ángel
0

Java, 198 bytes

b->B->{B="";for(java.io.File c:b)B+=new java.util.Scanner(c).useDelimiter("\\Z").next();for(int c=0;c++<B.length;)if(B.charAt(c)>64&B.charAt(c)<91)B=B.replace(B.charAt(c),B.charAt(c)|32);return B;};

Você é forçado a usar o lambda acima com arquivos, portanto, não há necessidade de receber informações do STDIN! Além disso, é um Function<File[], UnaryOperator<String>>. É usado como foo.apply(anArrayOfFiles).apply(anything).

Como algo que faz mais sentido para quem é novo em Java, são necessários 223 bytes:

String A(java.io.File[]b){String B="";for(java.io.File c:b)B+=new java.util.Scanner(c).useDelimiter("\\Z").next();for(int c=0;c++<B.length;)if(B.charAt(c)>64&B.charAt(c)<91)B=B.replace(B.charAt(c),B.charAt(c)|32);return B;}

Como algo que compila, ocupa 232 bytes:

class a{String A(java.io.File[]b){String B="";for(java.io.File c:b)B+=new java.util.Scanner(c).useDelimiter("\\Z").next();for(int c=0;c++<B.length;)if(B.charAt(c)>64&B.charAt(c)<91)B=B.replace(B.charAt(c),B.charAt(c)|32);return B;}}
dorukayhan
fonte