Que dicas gerais você tem para jogar golfe em C #? Estou procurando idéias que possam ser aplicadas para codificar problemas de golfe em geral que sejam pelo menos um pouco específicos para C # (por exemplo, "remover comentários" não é uma resposta). Poste uma dica por resposta.
- emprestado da ideia de marcog;)
Respostas:
Em vez de usar o
.ToString()
uso+""
de números e outros tipos que podem ser convertidos nativamente para uma sequência com segurança.fonte
(1+"").DoSomethingWith1String();
String.Concat(object)
com o argumento, em vez da chamada virtualobject.ToString()
.Concat
converte explicitamentenull
para a cadeia vazia ( consulte a fonte de referência ). Não existe um 'casting nativo', você pode converter qualquer coisa assim, apenas o resultado pode não ser muito útil em alguns casos! (mas o comportamento nulo pode muito bem ser).$"{n}"
Certa vez, eu coloquei meu programa deliberadamente
namespace System
para reduzir o acesso a uma classe específica. Compararpara
fonte
System
espaço para nome.using System;class P...
.using System;
ter um alias para uma classe no mesmo espaço para nome, que é mais curto do que mostrei aqui.using static System.Math;
no C # 6 (você pode usar qualquer uma dessas funções como se fossem verdadeiramente globais - não em uma classe). A sugestão original ainda pode ser mais curta do queusing static
se você precisar acessar várias classes.static
palavra-chave adicional geralmente é mais longa do que qualquer economia de deixar de ladoM.
as chamadas de método, mas sim, é uma opção, mas tem um alto custo inicial que precisa de muitas chamadas para amortizar.Use
var
para declarar e inicializar variáveis (únicas) para salvar caracteres no tipo:torna-se
Não é particularmente necessário
int
, é claro.fonte
var
não pode ter vários declaradores, por exemplo,var x="x",y="y";
não é possível.Se você estiver usando o LINQ, poderá passar um método diretamente para, em
Select
vez de criar um lambda.Então, ao invés de
você pode usar
diretamente.
(Descoberto recentemente ao melhorar uma das respostas C # de Timwi .)
fonte
Lembre-se de que o menor programa compilável em C # tem 29 caracteres:
Portanto, comece removendo isso do seu comprimento e julgue sua resposta sobre quanto isso leva. O C # não pode competir com outros idiomas quando se trata de imprimir ou ler entradas, que é o coração da maioria dos
[code-golf]
problemas; portanto, não se preocupe. Como jogador de golfe em C #, você está realmente competindo contra o idioma.Algumas outras coisas a ter em mente:
if
instruções para uma única linha, se possível, a fim de remover os colchetes.fonte
As a C# golfer, you're really competing against the language
Inacreditavelmente relacionadostatic int Main()
também, que teria 28 caracteres.return
algo .Ao invés de
Faz
Se você precisar de várias variáveis, use isso (sugerido por @VisualMelon )
fonte
bool a=0<1,b=!a;
Favorecer o operador ternário sobre
if
..else
blocos onde apropriado.Por exemplo:
é mais eficiente:
fonte
var x = input ?? "";
(I ama meus aglutina)i < 1
é uma declaração complexa ou quando o nome dej
é longo. Na OMI, também falha em transmitir efeitos colaterais muito bem. No caso deif (i < 1)
algoif (SendEmail(recipient))
que retorna verdadeiro / falso, dependendo do sucesso dos efeitos colaterais, prefiro a notação if / then.j=i<1?1:0;
é suficiente.Uso efetivo do uso
Você pode substituir
float
(que é um apelido paraSystem.Single
)z
usandoz=System.Single;
Em seguida, substitua
z=System.Single;
comz=Single;
colocando o programa no espaço de nomesSystem
. (Como na resposta de Joey)Isso pode ser aplicado a outros tipos de valor (use o que eles são um alias), estruturas e classes
fonte
Se você precisar usar
Console.ReadLine()
várias vezes no seu código (mín. 3 vezes), poderá:e depois é só usar
em vez de
fonte
()
da primeira linha.auto r=Console.ReadLine;
?auto
é umC++
verbo.var
é paraC#
. A razão pela qual isso não pode ser feito é porqueConsole.ReadLine
está sobrecarregada, portanto a assinatura da função precisa ser especificada para informar ao compilador qual sobrecarga é desejada.Ao ler cada caractere de um argumento de linha de comando, em vez de fazer um loop até o comprimento da string:
Você pode salvar um personagem usando um bloco try / catch para encontrar o fim:
Isso se aplica a qualquer matriz dentro de uma matriz, como:
string[]
int[][]
IList<IList<T>>
fonte
Use lambdas para definir uma função em C # 6
No C # 6, você pode usar um lambda para definir uma função:
Isso é mais curto do que definir uma função como esta:
fonte
LINQ
Ao invés de usar:
para obter um Enumerable com o resultado da função
f
para todos osint
itens que[0,y]
você pode usarse você precisar
string
ou algo que implementeEnumerable
no seu programa, você também pode usá-losfonte
Se você precisar usar um genérico
Dictionary<TKey, TValue>
pelo menos duas vezes no seu código, poderá declarar uma classe de dicionário, como neste exemplo:e depois é só usar
em vez de repetir
Dictionary<int,string>
para cada instanciação.Eu usei essa técnica nesta resposta
fonte
using D = System.Collections.Generic.Dictionary<int,string>;
Você pode usar
float
edouble
literais para salvar alguns bytes.Quando você precisar de alguma
int
aritmética para retornar afloat
oudouble
você pode usar os literais para forçar a conversão.Se você se deparar com uma situação em que precisa converter, poderá salvar alguns bytes usando multiplicação.
fonte
(x-y)*1d/x/y;
Lembre-se de onde o privado ou o público são inerentes, como o seguinte:
em comparação com
fonte
Main
não precisa de argumentos em contraste com Java, por exemplo.Para expressões lambda de uma linha, você pode pular os colchetes e o ponto e vírgula. Para expressões de um parâmetro, você pode pular os parênteses.
Ao invés de
Usar
fonte
SomeCall(DoSomething)
é ainda melhorLooping:
Declarações variáveis:
tornar-se:
E se você precisar ou trabalhar com a variável i apenas uma vez, poderá começar com -1 (ou 0, dependendo da circunstância do loop) e aumentar inline:
para
E isso reduz em um caractere e ofusca um pouco o código também. Faça isso apenas com a PRIMEIRA
i
referência, da seguinte forma: (as otimizações concedidas a um personagem não são muito, mas podem ajudar)para
quando o loop não precisar ser incrementado
i
(loop de ordem inversa):fonte
++
esses casos diretamente no cabeçalho do loop: ofor(;++i<max;)
que é mais fácil de seguir e mais difícil de errar.for
cabeçalho, o que salvaria um caractere novamente.for(;i<max;)
parawhile(i<max)
. Mesmo número de bytes, mas para mim parece mais limpo.Há circunstâncias em que um parâmetro de saída pode salvar caracteres. Aqui está um exemplo um pouco artificial, um algoritmo de pontuação de boliche de 10 pinos.
Com uma declaração de retorno:
E com um parâmetro de saída:
O parâmetro de saída aqui salva um total de 5 caracteres.
fonte
Em C #, não temos permissão
if(n%2)
para verificar sen
é um número par. Se o fizermos, temos umcannot implicity convert int to bool
. Uma manipulação ingênua seria:Uma maneira melhor é usar:
Eu usei isso para ganhar um byte aqui .
note que isso só funciona para números positivos
-1%2==-1
, pois é considerado mesmo com esse método.fonte
Interpolação de String
Uma melhoria realmente simples de economia de espaço é a interpolação. Ao invés de:
use apenas
$
para incorporar expressões:Isso, junto com os novos corpos de expressão no C # 6.0, deve tornar qualquer desafio simples de cálculo de string bastante rentável no C #.
fonte
i+$" bottles of beer";
é menor que$"{i} bottles of beer"
.$
fora.{i}
um na frente e um no meio;)Use C # lambda. Como o PPCG permite lambda para entrada / saída, devemos usá-los.
Um método clássico de C # se parece com o seguinte:
Como lambda, escreveremos
Lambda anônima também é permitida:
Remova todo o barulho e foque!
Atualizar:
Podemos melhorar mais um passo com o curry, como o comentário do @TheLethalCoder:
Exemplo de curvatura de @Felix Palmen: como calcular a chave WPA?
Será útil quando você tiver exatamente 2 parâmetros, então uma variável vazia não utilizada
_
será melhor. Veja meta post sobre isso . Eu uso esse truque aqui . Você terá que mudar um pouco a função. Exemplo: Experimente online!fonte
s=>c=>...
s=>s.Contains
.(string s,char c)=>s.Contains(c)
Faça nomes de classe apenas uma letra. Aprimorando as dicas para golfe de código em C # , vamos de
para
que bate outros 6 caracteres neste caso.
fonte
O
Compute
método de instância deSystem.Data.DataTable
, permite avaliar uma expressão de cadeia simples, por exemplo:C # (compilador Visual C #) , 166 bytes
Experimente online!
Não é muito "golfe" por si só, mas às vezes pode ser útil.
fonte
Trocando duas Variáveis
Normalmente, para trocar duas variáveis, você deve declarar uma variável temporária para armazenar o valor. Seria algo parecido com isto:
São 16 bytes! Existem alguns outros métodos de troca que são melhores.
Os três últimos funcionam apenas para valores numéricos e, como apontado apenas pelo ASCII, os dois últimos podem resultar em uma exceção ArithmeticOverflow. Todos os itens acima são 12 bytes, uma economia de 4 bytes em comparação com o primeiro exemplo.
fonte
O uso do LinqPad lhe dará a possibilidade de remover toda a sobrecarga do programa, pois você pode executar instruções diretamente. (E deve ser totalmente legal no codegolf ... Ninguém diz que você precisa de um .exe)
A saída é feita usando o
.Dump()
método de extensão.fonte
.Dump()
;)(Um caso específico de conhecer a precedência do seu operador !)
Use
%
para subtração limitada (de certa forma) limitada. Isso pode economizar um par de parênteses em torno de uma subtração, cujo resultado você deseja multiplicar ou dividir por algo; mas tenha cuidado, ele tem sérias limitações.Ao invés de
Considerar
Exemplos:
Acabei de descobrir isso e sinto que será algo importante lembrar sempre que trabalhar com a ASCII no futuro. (No momento, estou jogando golfe em algum lugar em que estou usando ASCII para representações numéricas compactas, mas preciso multiplicar por
1
ou com-1
base em outra condição e esses 2 bytes distribuídos)fonte
Se você precisar incluir vários
using
s que caem da mesma hierarquia, geralmente é mais curto usar o mais longo comonamespace
:vs:
fonte
Descoberto hoje à noite "nas trincheiras" enquanto aprimora algum código de golfe ... se você tem uma classe para seu processamento, pode fazer o trabalho no construtor para salvar a declaração de um método.
Descobri isso enquanto reduzia um aplicativo de console - como havia
static void Main()
, todas as funções e variáveis tinham que ser declaradas estáticas. Criei uma classe aninhada com funções-membro e variáveis, com o trabalho principal realizado no construtor. Isso também salva caracteres no código de chamada.eg Classe com método:
Classe com trabalho no construtor:
Este exemplo salva 9 caracteres.
fonte
Use
Action
likeFunc
para definir uma função para uma variável.Action
não retorna nada (void
), por isso é ótimo para impressão.Por exemplo:
Esta dicas é inspirado @ W0lf grande exemplo de uso de
Func
comReadLine
.fonte
Declarar cadeias vazias / correspondentes juntas
Se você precisar declarar várias cadeias vazias / correspondentes, poderá salvar alguns bytes com o seguinte:
Infelizmente
var a="",b=a,c=a;
é ilegal, poisimplicitly type variable cannot have multiple declarators
fonte
var a=b=c=""
como em javascript?