Quels conseils généraux avez-vous pour jouer au golf en C #? Je recherche des idées pouvant être appliquées aux problèmes de code de golf en général, qui sont au moins quelque peu spécifiques à C # (par exemple, "supprimer les commentaires" n'est pas une réponse). Merci de poster un pourboire par réponse.
- emprunté à l'idée de marcog;)
Réponses:
Au lieu d'utiliser
.ToString()
use+""
pour les nombres et d'autres types pouvant être nativement transtypés en toute sécurité sur une chaîne.la source
(1+"").DoSomethingWith1String();
String.Concat(object)
avec l'argument, plutôt que l'appel virtuelobject.ToString()
.Concat
convertit explicitementnull
en chaîne vide ( voir la source de référence ). Il n'y a pas de 'casting natif' en cours, vous pouvez convertir n'importe quoi de la sorte, c'est juste que le résultat peut ne pas être très utile dans certains cas! (mais le comportement nul pourrait bien l'être).$"{n}"
Une fois, j'ai délibérément placé mon programme
namespace System
afin de pouvoir raccourcir l'accès à une classe spécifique. Comparerà
la source
System
espace de noms.using System;class P...
.using System;
mais aussi d'avoir un alias pour une classe dans le même espace de noms, ce qui est plus court que celui que j'ai montré ici.using static System.Math;
en C # 6 (vous pouvez utiliser n'importe laquelle de ces fonctions comme si elles étaient vraiment globales - pas dans une classe). La suggestion initiale peut encore être plus courte queusing static
si vous devez accéder à plusieurs classes.static
mot-clé supplémentaire est souvent plus long que les économies réalisées en laissant de côtéM.
les appels de méthode, mais oui, c'est une option, mais il en résulte un coût initial élevé qui nécessite de nombreux appels à amortir.À utiliser
var
pour déclarer et initialiser des variables (simples) afin de sauvegarder des caractères sur le type:devient
N'est pas particulièrement nécessaire pour
int
, bien sûr.la source
var
vous ne pouvez pas avoir plusieurs déclarants, par exemple, cevar x="x",y="y";
n'est pas possible.Si vous utilisez LINQ, vous pouvez passer directement à une méthode au
Select
lieu de créer un lambda.Donc, au lieu de
vous pouvez utiliser
directement.
(Découvert récemment en améliorant l'une des réponses C # de Timwi .)
la source
Rappelez-vous que le plus petit programme compilable en C # comporte 29 caractères:
Commencez donc par retirer cela de votre longueur et déterminez votre réponse en fonction du temps écoulé. C # ne peut pas rivaliser avec d’autres langues en matière d’impression ou de lecture, ce qui est au cœur de la plupart des
[code-golf]
problèmes, ne vous inquiétez donc pas. En tant que golfeur C #, vous êtes vraiment en concurrence avec la langue.Quelques autres points à garder à l'esprit:
if
Si possible, réduisez toutes les boucles et toutes les instructions en une seule ligne afin de supprimer les crochets.la source
As a C# golfer, you're really competing against the language
Incroyablement liéstatic int Main()
également, qui serait 28 caractères.return
quelque chose .Au lieu de
faire
Si vous avez besoin de plusieurs variables, utilisez ceci (suggéré par @VisualMelon )
la source
bool a=0<1,b=!a;
Privilégier l’opérateur ternaire sur
if
.. leselse
blocs le cas échéant.Par exemple:
est plus efficace:
la source
var x = input ?? "";
(j'aime mes coalesces)i < 1
s'agit d'une déclaration complexe ou lorsque le nom dej
est long. OMI, il ne réussit pas non plus à bien transmettre les effets secondaires Dans le cas oùif (i < 1)
quelque chose commeif (SendEmail(recipient))
qui renvoie vrai / faux en fonction du succès des effets secondaires, je préfère la notation if / then.j=i<1?1:0;
suffit.Utilisation efficace de l'utilisation
Vous pouvez remplacer
float
(qui est un alias pourSystem.Single
) parz
utiliserz=System.Single;
Puis remplacez
z=System.Single;
parz=Single;
en plaçant le programme dans l'espace de nomsSystem
. (Comme avec la réponse de Joey)Ceci peut être appliqué à d'autres types de valeur (utilisez ce pour quoi ils sont un alias), structs et classes
la source
Si vous devez utiliser
Console.ReadLine()
plusieurs fois dans votre code (3 fois au minimum), vous pouvez faire:et puis juste utiliser
au lieu
la source
()
de la première ligne.auto r=Console.ReadLine;
?auto
est unC++
verbe.var
est pourC#
. La raison pour laquelle cela ne peut pas être fait est parce qu’elleConsole.ReadLine
est surchargée et que la signature de la fonction doit être spécifiée afin d’indiquer au compilateur quelle surcharge est souhaitée.Lors de la lecture de chaque caractère d'un argument de ligne de commande, plutôt que de boucler jusqu'à la longueur de la chaîne:
Vous pouvez sauvegarder un personnage en utilisant un bloc try / catch pour trouver la fin:
Ceci s'applique à n'importe quel tableau dans un tableau tel que:
string[]
int[][]
IList<IList<T>>
la source
Utilisez lambdas pour définir une fonction en C # 6
En C # 6, vous pouvez utiliser un lambda pour définir une fonction:
C'est plus court que de définir une fonction comme celle-ci:
la source
LINQ
À la place d'utiliser:
pour obtenir un Enumerable avec le résultat de fonction
f
pour chaqueint
en que[0,y]
vous pouvez utilisersi vous avez besoin de
string
tout ce qui est implémentéEnumerable
dans votre programme, vous pouvez aussi les utiliserla source
Si vous devez utiliser un générique
Dictionary<TKey, TValue>
au moins deux fois dans votre code, vous pouvez déclarer une classe de dictionnaire, comme dans cet exemple:et puis juste utiliser
au lieu de répéter
Dictionary<int,string>
pour chaque instanciation.J'ai utilisé cette technique dans cette réponse
la source
using D = System.Collections.Generic.Dictionary<int,string>;
Vous pouvez utiliser
float
etdouble
littéraux pour sauver quelques octets.Lorsque vous avez besoin d’
int
arithmétique pour renvoyer unfloat
oudouble
vous pouvez utiliser les littéraux pour forcer la conversion.Si vous rencontrez un jour une situation dans laquelle vous devez effectuer un transtypage, vous pouvez économiser quelques octets en utilisant la multiplication.
la source
(x-y)*1d/x/y;
Rappelez-vous les endroits où le privé ou le public sont inhérents, tels que:
par rapport à
la source
Main
n'a pas besoin d'arguments contrairement à Java, par exemple.Pour les expressions lambda sur une ligne, vous pouvez ignorer les crochets et le point-virgule. Pour les expressions à un paramètre, vous pouvez ignorer les parenthèses.
Au lieu de
Utilisation
la source
SomeCall(DoSomething)
is better betterEn boucle:
Déclarations de variables:
devenir:
Et si vous avez besoin de ou travaillez avec la variable i une seule fois, vous pouvez commencer à -1 (ou 0 en fonction de la situation de la boucle) et incrémenter en ligne:
à
Et cela réduit d'un caractère et obscurcit également légèrement le code. Faites seulement cela avec la
i
référence FIRST , comme ceci : (accordé à un caractère, les optimisations ne sont pas importantes, mais elles peuvent aider)à
quand la boucle n'a pas à s'incrémenter
i
(boucle dans l'ordre inverse):la source
++
dans de tels cas directement dans l'en-tête de la boucle:for(;++i<max;)
ce qui est à la fois plus facile à suivre et plus difficile à obtenir.for
tête, ce qui sauvegardera à nouveau un caractère.for(;i<max;)
pourwhile(i<max)
. Même nombre d'octets, mais pour moi, ça a l'air plus propre.Dans certaines circonstances, un paramètre de sortie peut enregistrer des caractères. Voici un exemple légèrement artificiel, un algorithme de score de quilles à 10 quilles.
Avec une déclaration de retour:
Et avec un paramètre de sortie:
Le paramètre de sortie enregistre ici un total de 5 caractères.
la source
En C #, nous n'avons pas le droit
if(n%2)
de vérifier sin
est un nombre pair. Si nous le faisons, nous obtenons uncannot implicity convert int to bool
. Une manipulation naïve serait à faire:Une meilleure façon consiste à utiliser:
J'ai utilisé cela pour gagner un octet ici .
notez que cela ne fonctionne que pour les nombres positifs, car
-1%2==-1
cela est considéré même avec cette méthode.la source
Interpolation de chaîne
L'interpolation est une amélioration très simple et peu encombrante. Au lieu de:
il suffit d'utiliser
$
des expressions en ligne:Ceci, combiné aux nouveaux corps d'expression en C # 6.0, devrait permettre à tout défi de calcul de chaîne simple de devenir golfable en C #.
la source
i+$" bottles of beer";
est plus court que$"{i} bottles of beer"
.$
côté.{i}
un devant et un au milieu;)Utilisez C # lambda. Puisque PPCG autorise lambda pour les entrées / sorties, nous devrions les utiliser.
Une méthode C # classique ressemble à ceci:
En tant que lambda, nous écrirons
Les lambda anonymes sont aussi autorisés:
Enlevez tout le bruit et concentrez-vous!
Mise à jour:
Nous pouvons améliorer un pas de plus avec taitement comme @TheLethalCoder commentaire:
Exemple de mise en circulation par @Felix Palmen: Comment calculer la clé WPA?
Ce sera utile lorsque vous avez exactement 2 paramètres, alors une variable vide non utilisée
_
sera meilleure. Voir meta post à ce sujet . J'utilise cette astuce ici . Vous devrez changer un peu la fonction. Exemple: Essayez-le en ligne!la source
s=>c=>...
s=>s.Contains
.(string s,char c)=>s.Contains(c)
Faites des noms de classe une seule lettre. Amélioration des astuces pour jouer au code avec C # nous allons de
à
ce qui assomme 6 autres caractères dans ce cas.
la source
le
Compute
méthode d'instance deSystem.Data.DataTable
, permet d'évaluer une expression de chaîne simple, par exemple:C # (compilateur Visual C #) , 166 octets
Essayez-le en ligne!
Pas très "golfy" en soi, mais parfois pourrait être utile.
la source
Échange de deux variables
Normalement, pour échanger deux variables, vous devez déclarer une variable temporaire pour stocker la valeur. Cela ressemblerait à quelque chose du genre:
C'est 16 octets! Il existe d'autres méthodes d'échange qui sont meilleures.
Les trois derniers ne fonctionnent que pour les valeurs numériques et, comme souligné par ASCII uniquement, les deux derniers peuvent entraîner une exception ArithmeticOverflow. Tous ces éléments représentent 12 octets, soit une économie de 4 octets par rapport au premier exemple.
la source
L'utilisation de LinqPad vous donnera la possibilité de supprimer tout le temps système car vous pouvez exécuter des instructions directement. (Et cela devrait être tout à fait légal dans codegolf ... Personne ne dit que vous avez besoin d'un fichier .exe)
La sortie est effectuée à l'aide de la
.Dump()
méthode d'extension.la source
.Dump()
;)(Un cas particulier de connaître votre priorité d'opérateur !)
Utilisation
%
option pour une soustraction étroite (légèrement) limitée. Cela peut vous éviter une paire de parenthèses autour d'une soustraction, le résultat que vous voulez multiplier ou diviser par quelque chose; mais attention, il y a de sérieuses limitations.Au lieu de
Considérer
Exemples:
Je viens tout juste de découvrir cela, et j’ai l’impression que ce sera une chose précieuse à ne pas oublier lors de tout travail futur avec ASCII. (Je joue actuellement au golf quelque part où j'utilise ASCII pour des représentations numériques compactes, mais que je dois multiplier par
1
ou-1
sur une autre condition, et cette bande de 2 octets rayée)la source
Si vous devez inclure plusieurs
using
objets appartenant tous à la même hiérarchie, il est souvent plus court d'utiliser le plus long en tant quenamespace
:contre:
la source
Découvert ce soir "dans les tranchées" tout en améliorant un code de golf ... si vous avez une classe pour votre traitement, vous pouvez faire le travail dans le constructeur pour enregistrer en déclarant une méthode.
J'ai découvert cela en réduisant une application console - car il y avait un
static void Main()
, toutes les fonctions et variables devaient être déclarées statiques. J'ai créé une classe imbriquée avec des fonctions membres et des variables, le travail principal étant effectué dans le constructeur. Cela enregistre également les caractères dans le code d'appel.p.ex. Classe avec méthode:
Classe avec travail dans le constructeur:
Cet exemple enregistre 9 caractères.
la source
Utilisez
Action
likeFunc
pour définir une fonction sur une variable.Action
ne renvoie rien (void
), il est donc idéal pour l'impression.Par exemple:
Ces conseils sont inspirés par @W0lf, un excellent exemple d’utilisation de
Func
avecReadLine
.la source
Déclarer des chaînes vides / correspondantes ensemble
Si vous devez déclarer plusieurs chaînes vides / correspondantes, vous pouvez enregistrer quelques octets avec les éléments suivants:
Malheureusement,
var a="",b=a,c=a;
c'est illégal, commeimplicitly type variable cannot have multiple declarators
la source
var a=b=c=""
comme en javascript?