Les bases
Retrouvez notre page dédiées aux bases du golfing en Ruby ici →
Récup l’input
Utiliser dd
plutôt que gets peut permettre de gagner un espace quand il n’y a qu’un seul input
(équivalent à $stdin.read
)
puts gets
# vs
puts`dd`
n=gets.to_i
#vs
n=eval`dd`
On peut aussi utiliser sed
pour ne prendre que la deuxième ligne
puts`sed 1d`
# vs
gets
puts gets
On peut mapper toute l’entrée en même temps avec $<
a,b,c=$<.map &:to_i
# vs
n=gets.to_i
a=gets.to_i
b=gets.to_i
Utiliser l’étoile pour utiliser directement $<
a,b,c=*$<
#vs
a,b,c = $<.map{_1}
Faire un gets peut permettre de supprimer le premier élément de $<
gets
d=$<.map &:chars
# vs
d=$<.map(&:chars)[1..]
$_
stocke la dernière ligne lue, on peut donc ne pas l’assigner
n=gets.to_i
puts (1..10).map{n*_1}
# vs
gets
puts (1..10).map{$_.to_i*_1}
Comment print
Utiliser p
pour print les entiers et les booléens
p 1
# vs
puts 1
Utiliser p *
pour print des tableaux d’entiers ou de booléens
a=[1,2,3]
p *a
# vs
puts a
Utiliser $><<
pour print les strings
$><<a
#vs
puts a
#!! attention à la priorité de l'opérateur ternaire
$><<(a?'a':'b')
# vs
puts a?'a':'b'
Les tableaux
Utiliser [*..]
pour convertir les ranges en tableaux plutot que la méthode .to_a
d=[*1..10]
# vs
d=(1..10).to_a
.product
permet de générer toutes les combinaisons possibles d’un tableau
d=[1,2,3]
d.product d
# => [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
Utiliser l’opérateur *
plutôt que .join
a=[1,2,3]
p a*" "
# vs
puts a.join" "
.each_cons
permet de générer tous les sous-tableaux de n éléments adjacents
d=[*1..10]
d.each_cons(3).to_a
# => [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6],
# [5, 6, 7], [6, 7, 8], [7, 8, 9], [8, 9, 10]]
.each_slice
permet de découper le tableau en sous-tableaux de taille n
d=[*1..10]
d.each_slice(3).to_a
# => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
Utiliser l’évaluation plutôt qu’un .reduce sur les opérations simple
d=[1,2,3,4]
p eval d*?*
# vs
p d.reduce :*
Utiliser (a...b)
plutot que (a..b-1)
tally c’est bien des fois, et transpose
flat_map vs flatten puis map
String
Utiliser .split
sans arguments
"Hello, world!".split # => ["Hello,", "world!"]
# vs
"Hello, world!".split(' ') => ["Hello,", "world!"]
.bytes
permet de travailler directement sur les valeurs ascii
"abcdefghi".bytes
# vs
"abcdefghi".chars.map(&:ord)
Utiliser des regex est souvent plus court que des méthodes empiriques
"AbCdEfGhIjKlMnOpQrStUvWxYz".scan /A-Z/
# vs
"AbCdEfGhIjKlMnOpQrStUvWxYz".chars.select{_1 == _1.upcase}
%w()
permet d’initialiser un tableau de plusieurs string
%w(one two three)
# vs
["one","two","three"]
.next
permet d’incrémenter les caractères alphanumériques une string (surtout utile pour les heures)
"12:24".succ # => "12:25"
.tr
permet de traduire une liste de caractère en une autre
"hello, world!".tr("lo","10") # => "he110, w0r1d"
.tr
est plus court que .gsub
pour supprimer les caractères
"hello, world!".tr("lo","") # => "he, wrd"
gets.ord-97 pour avoir la position de la lettre dans l’alphabet
Autres
Lorsque les valeurs possibles sont limitées, on peut souvent remplacer une égalité par une inégalité
a%10<1
#vs
a%10==0
.digits
permet de générer le tableau des chiffres en base quelconque
13.digits # => [3,1]
57.digits 9 # => [3,6]
Certaines variables sont définie dans ruby, il est possible des les utiliser afin d’éviter de déclarer une nouvelle variable
n=gets.to_i
(1..n).map{$.*_1}
puts $.
# => n!
Utiliser le spaceship operator <=>
pour indexer un tableau
puts ["a égal b","a plus grand que b","a plus petit que b"][a<=>b]
De la même manière, on peut utiliser des formules en index de tableau plutot que des conditions
(a=_1.to_i)*[3,5][a%2]
(?1..?9) pour ne pas avoir à faire des to_s dans le range
Les captures de la dernière regex est stockée dans la variable $~
on peut accéder aux éléments $~[0]
directement par $1
/ $~[1]
par $2
, etc… jusqu’à $9
On peut utiliser l’implémentation des nombres négatifs et la priorité des opérateurs unaires pour gagner des caractères (plus d’info sur le complément à 2)
~-a == a-1
-~a == a+1
On peut assigner plusieurs variables en même temps en chaînant les assignations
a=b=c=d=0
# vs
a=0
b=0
c=0
d=0
On peut tester si une string inclut une substring avec l’opérateur []
string["substring"] # renvoie "substring" ou nil
On peut se servir du même opérateur pour réaliser un sub
string["substring"]=''
#vs
string.sub("substring")
inputs = inputs.slice_when{_2-_1!=1}
inputs = inputs.chunk.with_index{_2-_1}
opérateur * qui split array
https://codegolf.stackexchange.com/questions/363/tips-for-golfing-in-ruby
permutation = combien de combinaison et ordres différents tu peux faire
combination = combien de combinaison différente tu peux faire
_1[/ */]
[a,b]* » «
»#{a} #{b} »
p 4440-dd
.sum
c,s,n,*i=dd
.split.map &:to_f
puts »%s #{a=i.sum{(_1/s).ceil}} ».%a>c ?:no: »yes »
l’opérateur % sur un range permet d’ajouter un step
*x,a=gets permet d’initialiser a
à gets, x=[]
cycle
center