¿Qué consejos generales tienes para jugar al golf en C #? Estoy buscando ideas que se puedan aplicar a problemas de golf de código en general que sean al menos algo específicos para C # (por ejemplo, "eliminar comentarios" no es una respuesta). Por favor, publique un consejo por respuesta.
- tomado de la idea de marcog;)
Respuestas:
En lugar de usar el
.ToString()
uso+""
de números y otros tipos que se pueden convertir de forma nativa en una cadena de forma segura.fuente
(1+"").DoSomethingWith1String();
String.Concat(object)
con el argumento, en lugar de la llamada virtualobject.ToString()
.Concat
se convierte explícitamentenull
a la cadena vacía ( vea la fuente de referencia ). No está ocurriendo un 'casting nativo', puedes convertir algo como esto, ¡es solo que el resultado puede no ser muy útil en algunos casos! (pero el comportamiento nulo bien puede ser).$"{n}"
Una vez coloqué mi programa deliberadamente
namespace System
para poder acortar el acceso a una clase específica. Comparara
fuente
System
espacio de nombres.using System;class P...
.using System;
de tener un alias para una clase en el mismo espacio de nombres, que es más corto de lo que he mostrado aquí.using static System.Math;
en C # 6 (agregue que puede usar cualquiera de esas funciones como si fueran realmente globales, no en una clase). La sugerencia original aún puede ser más corta queusing static
si necesita acceder a varias clases.static
palabra clave adicional a menudo es más larga que cualquier ahorro al dejar de ladoM.
las llamadas al método, pero sí, es una opción, pero tiene un costo inicial considerable que necesita muchas llamadas para amortizarse.Utilícelo
var
para declarar e inicializar variables (individuales) para guardar caracteres en el tipo:se convierte
No es particularmente necesario para
int
, por supuesto.fuente
var
no puede tener múltiples declaradores, por ejemplo,var x="x",y="y";
no es posible.Si usa LINQ, puede pasar un método directamente en
Select
lugar de hacer una lambda.Entonces, en lugar de
puedes usar
directamente.
(Descubierto recientemente al mejorar una de las respuestas C # de Timwi ).
fuente
Recuerde que el programa compilable más pequeño en C # tiene 29 caracteres:
Comience por eliminar eso de su longitud y juzgue su respuesta sobre cuánto más se necesita. C # no puede competir con otros idiomas cuando se trata de imprimir o leer entradas, que es el corazón de la mayoría de los
[code-golf]
problemas, así que no se preocupe por eso. Como golfista de C #, realmente estás compitiendo contra el lenguaje.Algunas otras cosas a tener en cuenta:
if
declaraciones a una sola línea si es posible para eliminar los corchetes.fuente
As a C# golfer, you're really competing against the language
Increíblemente relacionadostatic int Main()
también, que serían 28 caracteres.return
algo .En lugar de
hacer
Si necesita múltiples variables, use esto (sugerido por @VisualMelon )
fuente
bool a=0<1,b=!a;
Favorezca al operador ternario sobre
if
..else
bloques donde sea apropiado.Por ejemplo:
es más eficientemente:
fuente
var x = input ?? "";
(me encantan misi < 1
es una declaración compleja o cuando el nombrej
es largo. OMI, tampoco logra transmitir los efectos secundarios muy bien. En el caso de queif (i < 1)
sea algo como loif (SendEmail(recipient))
que devuelve verdadero / falso dependiendo del éxito de los efectos secundarios, prefiero la notación if / then.j=i<1?1:0;
es suficiente.Uso efectivo del uso
Puede reemplazar
float
(que es un alias paraSystem.Single
) con elz
usoz=System.Single;
Luego reemplace
z=System.Single;
conz=Single;
colocando el programa en el espacio de nombresSystem
. (Al igual que con la respuesta de Joey)Esto se puede aplicar para otros tipos de valores (use para lo que son un alias), estructuras y clases
fuente
Si necesita usar
Console.ReadLine()
varias veces en su código (mínimo 3 veces), puede hacer:y luego solo usa
en lugar
fuente
()
de la primera línea.auto r=Console.ReadLine;
?auto
es unC++
verbo.var
es paraC#
. La razón por la que esto no se puede hacer es porqueConsole.ReadLine
está sobrecargado, por lo que la firma de la función debe especificarse para indicarle al compilador qué sobrecarga se desea.Al leer cada carácter de un argumento de línea de comando, en lugar de recorrer la longitud de la cadena:
Puedes guardar un personaje usando un bloque try / catch para encontrar el final:
Esto se aplica a cualquier matriz dentro de una matriz como:
string[]
int[][]
IList<IList<T>>
fuente
Use lambdas para definir una función en C # 6
En C # 6, puede usar una lambda para definir una función:
Esto es más corto que definir una función como esta:
fuente
LINQ
En lugar de usar:
para obtener una Enumerable con el resultado de la función
f
para cadaint
en el[0,y]
que se puede utilizarsi necesita
string
o cualquier cosa que implementeEnumerable
en su programa, también puede usarlosfuente
Si necesita usar un genérico
Dictionary<TKey, TValue>
al menos dos veces en su código, puede declarar una clase de diccionario, como en este ejemplo:y luego solo usa
en lugar de repetir
Dictionary<int,string>
para cada instanciación.He usado esta técnica en esta respuesta
fuente
using D = System.Collections.Generic.Dictionary<int,string>;
Puede usar
float
ydouble
literales para guardar algunos bytes.Cuando se necesita un poco de
int
aritmética para devolver unafloat
odouble
puede utilizar los literales a forzar la conversión.Si alguna vez te encuentras con una situación en la que tienes que lanzar, puedes guardar algunos bytes usando la multiplicación.
fuente
(x-y)*1d/x/y;
Recuerde donde lo privado o lo público son inherentes, como lo siguiente:
en comparación con
fuente
Main
no necesita ningún argumento en contraste con Java, por ejemplo.Para las expresiones lambda de una línea, puede omitir los corchetes y el punto y coma. Para expresiones de un parámetro, puede omitir los paréntesis.
En lugar de
Utilizar
fuente
SomeCall(DoSomething)
es aún mejorBucle:
Declaraciones variables:
volverse:
Y si necesita o trabaja con la variable i solo una vez, puede comenzar en -1 (o 0 según la circunstancia del bucle) e incrementar en línea:
a
Y eso se reduce en un carácter, y también ofusca un poco el código. Solo haga eso a la PRIMERA
i
referencia, así: (las optimizaciones de un personaje otorgadas no son mucho, pero pueden ayudar)a
cuando el bucle no tiene que incrementarse
i
(bucle de orden inverso):fuente
++
estos casos directamente en el encabezado del bucle:for(;++i<max;)
que es más fácil de seguir y más difícil de equivocar.for
encabezado también, lo que luego guardaría un carácter nuevamente.for(;i<max;)
awhile(i<max)
. El mismo número de bytes, pero para mí solo se ve más limpio.Hay circunstancias en las que un parámetro de salida puede guardar caracteres. Aquí hay un ejemplo levemente inventado, un algoritmo de puntaje de 10 bolos.
Con una declaración de devolución:
Y con un parámetro de salida:
El parámetro de salida aquí guarda un total de 5 caracteres.
fuente
En C #, no podemos hacer
if(n%2)
para verificar sin
es un número par. Si lo hacemos, obtenemos acannot implicity convert int to bool
. Un manejo ingenuo sería hacer:Una mejor manera es usar:
Usé esto para ganar un byte aquí .
tenga en cuenta que esto solo funciona para números positivos, ya
-1%2==-1
que se considera incluso con este método.fuente
Interpolación de cuerdas
Una mejora realmente simple para ahorrar espacio es la interpolación. En lugar de:
solo use
$
para en línea expresiones:Esto, junto con los nuevos cuerpos de expresión en C # 6.0 debería hacer que cualquier desafío simple de cálculo de cadena sea bastante golfo en C #.
fuente
i+$" bottles of beer";
es más corto que$"{i} bottles of beer"
.$
lado.{i}
uno en el frente y uno en el medio;)Use C # lambda. Dado que PPCG permite lambda para entrada / salida, debemos usarlos.
Un método clásico de C # se ve así:
Como lambda, escribiremos
También se permiten lambda anónimas:
¡Elimina todo el ruido y concéntrate!
Actualizar:
Podemos mejorar un paso más con el curry como comentario de @TheLethalCoder:
Ejemplo de curring por @Felix Palmen: ¿Cómo calcular la clave WPA?
Será útil cuando tenga exactamente 2 parámetros, entonces una variable vacía no utilizada
_
será mejor. Ver meta publicación sobre esto . Yo uso este truco aquí . Tendrás que cambiar un poco la función. Ejemplo: ¡ Pruébelo en línea!fuente
s=>c=>...
s=>s.Contains
.(string s,char c)=>s.Contains(c)
Hacer nombres de clase solo una letra. Mejorando los consejos para el golf de código en C # pasamos de
a
que elimina otros 6 caracteres en este caso.
fuente
El
Compute
método de instancia deSystem.Data.DataTable
, permite evaluar una expresión de cadena simple, por ejemplo:C # (compilador de Visual C #) , 166 bytes
Pruébalo en línea!
No es muy "golf" en sí, pero a veces puede ser útil.
fuente
Intercambiando dos variables
Normalmente, para intercambiar dos variables, debe declarar una variable temporal para almacenar el valor. Se vería como algo similar a esto:
¡Eso es 16 bytes! Hay algunos otros métodos de intercambio que son mejores.
Los últimos tres solo funcionan para valores numéricos, y como se señaló solo en ASCII, los dos últimos podrían resultar en una excepción ArithmeticOverflow. Todo lo anterior tiene 12 bytes, un ahorro de 4 bytes en comparación con el primer ejemplo.
fuente
El uso de LinqPad le dará la posibilidad de eliminar todos los gastos generales del programa, ya que puede ejecutar instrucciones directamente. (Y debería ser completamente legal en codegolf ... Nadie dice que necesita un .exe)
La salida se realiza utilizando el
.Dump()
método de extensión.fuente
.Dump()
;)(¡Un caso particular de conocer la precedencia de su operador !)
Úselo
%
para la sustracción limitada (algo) limitada. Esto puede ahorrarle un par de paréntesis en torno a una resta, cuyo resultado desea multiplicar o dividir por algo; pero ten cuidado, tiene serias limitaciones.En lugar de
Considerar
Ejemplos:
Acabo de descubrir esto, y siento que será algo valioso para recordar cuando trabaje con ASCII en el futuro. (Actualmente estoy jugando golf en algún lugar donde estoy usando ASCII para representaciones numéricas compactas, pero necesita multiplicar por
1
o en-1
función de otra condición, y esto se divide en 2 bytes)fuente
Si necesita incluir múltiples correos
using
electrónicos que caen todos de la misma jerarquía, a menudo es más corto usar el más largo comonamespace
:vs:
fuente
Descubierto esta noche "en las trincheras" mientras mejora un código de golf ... si tiene una clase para su procesamiento, puede hacer el trabajo en el constructor para guardar la declaración de un método.
Descubrí esto mientras reducía una aplicación de consola, ya que había una
static void Main()
, todas las funciones y variables tenían que declararse estáticas. Creé una clase anidada con funciones y variables miembro, con el trabajo principal realizado en el constructor. Esto también guarda caracteres en el código de llamada.Por ejemplo, clase con método:
Clase con trabajo en el constructor:
Este ejemplo guarda 9 caracteres.
fuente
Use
Action
likeFunc
para establecer una función en una variable.Action
no devuelve nada (void
), por lo que es ideal para imprimir.Por ejemplo:
Estos consejos están inspirados en @ W0lf gran ejemplo de uso de
Func
conReadLine
.fuente
Declarar cadenas vacías / coincidentes juntas
Si necesita declarar varias cadenas vacías / coincidentes, puede guardar algunos bytes con lo siguiente:
Lamentablemente
var a="",b=a,c=a;
es ilegal, ya queimplicitly type variable cannot have multiple declarators
fuente
var a=b=c=""
gusta en javascript?