Suggerimenti per giocare a golf in Ruby


62

Quali consigli generali puoi dare per giocare a golf in Ruby?

Sto cercando idee che possano essere applicate ai problemi del codice golf in generale, specifiche di Ruby. (Ad esempio, "Rimuovi commenti" non sarebbe una risposta.)

Si prega di inviare un suggerimento per risposta.


Qualcuno deve scrivere una lingua chiamata Rub, che utilizza un singolo carattere Unicode per ogni token Ruby, un po 'come Jelly e Pyth :)
Mark Thomas,

Risposte:


46
  • I numeri 100-126 può essere scritta come ?da ?~in 1.8.
  • Allo stesso modo, se hai bisogno di una stringa di un carattere in 1.9? X è più breve di "x".
  • Se è necessario stampare una stringa senza aggiungere una nuova riga, $><<"string"è più breve di print"string".
  • Se è necessario leggere più righe di input $<.map{|l|...}è più breve di while l=gets;...;end. Inoltre puoi usare $<.readper leggerlo tutto in una volta.
  • Se devi leggere da un file $<e getsleggerai da un file invece di stdin se il nome del file è in ARGV. Quindi il modo golfiest reimplementare catsarebbe: $><<$<.read.

1
? x restituisce il codice ascii in generale, in modo da poter ottenere realisticamente tutti i numeri stampabili in cifre con due caratteri. 1.9 è diverso, 'a'.ord restituisce il numero ASCII, ma è più lungo di quattro byte rispetto alla versione decimale.
Hiato,

8
Un modo ancora più golfistico di implementare catè lasciare il file ruby ​​completamente vuoto (0 byte) e insistere sul fatto che dovrebbe essere eseguito dalla riga di comando con il -pflag.
daniero,

1
o, dalla stessa risposta di @ daniero ,puts *$<
Non che Charles

1
Quindi in 1.8, tutto quello che devo fare è andare? ~ E restituirà 126?
Arte semplicemente

5
Puoi andare oltre 126 usando think like o , o se sei abbastanza pazzo:?﷽.ord=65021
Simply Beautiful Art

32

Utilizzare l'operatore splat per ottenere la coda e la testa di un array:

head, *tail = [1,2,3]
head => 1
tail => [2,3]

Questo funziona anche nell'altro modo:

*head, tail = [1,2,3]
head => [1,2]
tail => 3

Utilizzare il *metodo con una stringa su un array per unire elementi:

[1,2,3]*?,
=> "1,2,3"

27
  • Utilizzare abortper terminare il programma e stampare una stringa su STDERR - più breve di quella putsseguita daexit
  • Se leggi una riga con gets, puoi quindi usarla ~/$/per trovarne la lunghezza (questo non conta una nuova riga finale se esiste)
  • Utilizzare []per verificare se una stringa ne contiene un'altra:'foo'['f'] #=> 'f'
  • Utilizzare trinvece di sostituzioni gsubper carattere:'01011'.tr('01','AB') #=> 'ABABB'
  • Se è necessario rimuovere le nuove righe finali, utilizzare chopinvece dichomp

2
+1 per aborte~/$/
J -_- L

Per favore, spiega come usare~/$/
Mathieu CAROFF,

@MathieuCAROFF ogni volta che chiami gets, il suo risultato viene memorizzato nella $_variabile. /regex/ ~= stringrestituisce l'indice della prima corrispondenza. Chiamare ~un regex equivale a /regex/ ~= $_. Quindi sarebbe qualcosa di similes=gets;l= ~/$/
Cyoce

20

Termina il tuo end.

Prova a rimuovere enddal tuo codice.

Non utilizzare def...endper definire le funzioni. Crea una lambda con il nuovo operatore -> in Ruby 1.9. (L'operatore -> è un "stabby lambda" o "dash rocket" .) Ciò consente di salvare 5 caratteri per funzione.

# 28 characters
def c n
/(\d)\1/=~n.to_s
end

# 23 characters, saves 5
c=->n{/(\d)\1/=~n.to_s}

Le chiamate al metodo sono c no c(n). Le chiamate Lambda sono c[n]. La modifica di ciascuno c ndi essi c[n]costa 1 carattere, quindi se puoi usarne c npiù di 5 volte, mantieni il metodo.

Tutti i metodi che accettano do...endblocchi possono {...}invece prendere blocchi. Ciò consente di salvare da 3 a 5 caratteri. Se la precedenza di {...}è troppo alta, utilizzare le parentesi per risolverlo.

# 48 characters
(?a..?m).zip (1..5).cycle do|a|puts a.join','end

# WRONG: passes block to cycle, not zip
(?a..?m).zip (1..5).cycle{|a|puts a.join','}

# 45 characters, saves 3
(?a..?m).zip((1..5).cycle){|a|puts a.join','}

Sostituire if...else...endcon l' operatore ternario ?: . Se un ramo ha due o più istruzioni, avvolgile tra parentesi.

# 67 characters
if a<b
puts'statement 1'
puts'statement 2'else
puts'statement 3'end

# 62 characters, saves 5
a<b ?(puts'statement 1'
puts'statement 2'):(puts'statement 3')

Probabilmente non hai whileo untilcicli, ma se lo fai, quindi scriverli in forma di modificatore.

(a+=1
b-=1)while a<b

Le parentesi sono puts'statement 3'necessarie?
Cyoce,

15

Aggiunta a w0lf

Quando si lavora con array, .compactpuò essere sostituito con -[nil]per salvare 2 caratteri.

Combinato con sopra -> puoi renderlo ancora più breve -[p]per salvare altri 2 caratteri.


14

Utilizzare le variabili predefinite brevi ove possibile, ad es. $*Anziché ARGV. C'è un buon elenco di questi qui , insieme a molte altre informazioni utili.


12

Quando stai usando l'interpolazione di stringhe, (come dovresti pr nel post di Martin Büttner ), non hai bisogno delle parentesi graffe se il tuo oggetto ha un sigillo ( $, @) davanti. Utile per le variabili magici come $_, $&, $1ecc:

puts "this program has read #$. lines of input"

Pertanto, anche se è necessario stampare una variabile più di quanto non si utilizzi altrimenti, è possibile salvare alcuni byte.

a=42; puts "here is a: #{a}"; puts "here is a again: #{a}"
$b=43; puts "here is b: #$b"; puts "here is b again: #$b"

11

Se devi scoprire se un particolare elemento si etrova all'interno di un intervallo r, puoi usarlo

r===e

invece del più lungo:

r.cover?(e) # only works if `r.exclude_end?` is false

o

r.member?(e)

o

r.include?(e)

3
Non è r===enemmeno più breve?
Akuhn

@akuhn Sì, lo è. Molto più breve. Grazie per averlo sottolineato, mi ha aiutato ad accorciare il mio codice di 10 caratteri, il che è enorme: codegolf.stackexchange.com/a/6125/3527
Cristian Lupascu,

1
Prego. Tutto ciò che può essere utilizzato in un'istruzione switch è stato ===implementato.
Akuhn

10

$_ è l'ultima riga di lettura.

  • print - se nessun argomento ha dato contenuto di stampa di $_
  • ~/regexp/ - Corto per $_=~/regexp/

In Ruby 1.8, hai quattro metodi per Kerneloperare su $_:

  • chop
  • chomp
  • sub
  • gsub

In Ruby 1.9, questi quattro metodi esistono solo se lo script usa -no -p.

Se si desidera stampare spesso alcune variabili, utilizzare trace_var(:var_name){|a|p a}


2
Questi sono disponibili solo quando si esegue Ruby con l' opzione -po -n. Riferimento.
Darren Stone,

1
Sembra che trace_var
funzioni

10

Usa l'interpolazione di stringhe!

  1. Per sostituire to_s. Se hai bisogno di parentesi attorno a ciò che vuoi trasformare in una stringa, to_sè due byte più lungo dell'interpolazione della stringa:

    (n+10**i).to_s
    "#{n+10**i}"
    
  2. Per sostituire la concatenazione. Se concatenate qualcosa circondato da altre due stringhe, l'interpolazione può salvarvi un byte:

    "foo"+c+"bar"
    "foo#{c}bar"
    

    Funziona anche se la cosa di mezzo è essa stessa concatenata, se sposti semplicemente la concatenazione all'interno dell'interpolazione (invece di usare interpolazioni multiple):

    "foo"+c+d+e+"bar"
    "foo#{c+d+e}bar"
    

10

Evitare lengthinif a.length<n

lengthè di 6 byte, un po 'costoso nel code golf. in molte situazioni, puoi invece verificare se l'array ha qualcosa in un determinato punto. se nilpassi oltre l'ultimo indice che otterrai , un valore falso.

Quindi puoi cambiare:

if a.length<5a if !a[4]-5 byte

o

if a.length>5a if a[5]-6 byte

o

if a.length<na if !a[n-1]-3 byte

o

if a.length>na if a[n]-6 byte

Nota : funzionerà solo con una matrice di tutti i valori di verità. avere nilo falseall'interno dell'array può causare problemi.


4
Uso sempre size... Ma questo è decisamente meglio. A proposito, funziona Stringanche per .
arte

10

Non utilizzare le parole chiave truee false.

Uso:

  • !pper true(grazie, istocratico!)
  • !0per false. Se tutto ciò di cui hai bisogno è un valore falso, puoi semplicemente usare p(che restituisce nil).

per salvare alcuni caratteri.


1
A meno che tu non abbia effettivamente bisogno true(cioè se un valore sincero è sufficiente, come in una condizione if), non ne hai nemmeno bisogno !!.
Martin Ender,

4
E allo stesso modo, p(che valuta nil) è un valore di falsità più breve. Ciò significa che il modo più breve per ottenere trueè !p.
istocrato

@histocrat buon punto! Ho modificato la mia risposta.
Cristian Lupascu,


9

Se hai mai bisogno di ottenere un numero da ARGV, geto qualcosa di simile per fare qualcosa che molte volte, invece di chiamarlo to_i, puoi semplicemente usare ?1.upto x{do something x times}dove x è una stringa.

Quindi usare ?1.upto(a){}invece di x.to_i.times{}ti farà risparmiare 2 caratteri.

Puoi anche riscrivere cose come p 1 while 1o p 1 if 1come p 1while 1op 1if 1

Quell'esempio non è molto utile, ma potrebbe essere usato per altre cose.

Inoltre, se è necessario assegnare il primo elemento di un array a una variabile, a,=cverranno salvati due caratteri anzichéa=c[0]


9

Nuove funzionalità in Ruby 2.3 e 2.4

È utile rimanere al passo con le nuove funzionalità linguistiche che aiuteranno il tuo gioco di golf. Ce ne sono alcuni fantastici negli ultimi rubini.

Ruby 2.3

L'operatore di navigazione sicura: &.

Quando si chiama un metodo che potrebbe restituire nilma si desidera concatenare chiamate di metodo aggiuntive in caso contrario, si sprecano byte gestendo il nilcaso:

arr = ["zero", "one", "two"]
x = arr[5].size
# => NoMethodError: undefined method `size' for nil:NilClass

x = arr[5].size rescue 0
# => 0

L '"operatore di navigazione sicuro" interrompe la catena di chiamate di metodo se uno ritorna nile ritorna nilper l'intera espressione:

x = arr[5]&.size || 0
# => 0

Array#dig & Hash#dig

Accesso diretto agli elementi nidificati, con un bel nome breve:

o = { foo: [{ bar: ["baz", "qux"] }] }
o.dig(:foo, 0, :bar, 1) # => "qux"

Restituisce nilse raggiunge un vicolo cieco:

o.dig(:foo, 99, :bar, 1) # => nil

Enumerable#grep_v

L'inverso di — Enumerable#greprestituisce tutti gli elementi che non corrispondono all'argomento dato (confrontato con ===). Ad esempio grep, se viene fornito un blocco, viene restituito il risultato.

(1..10).grep_v 2..5 # => [1, 6, 7, 8, 9, 10]
(1..10).grep_v(2..5){|v|v*2} # => [2, 12, 14, 16, 18, 20]

Hash#to_proc

Restituisce un Proc che restituisce il valore per la chiave fornita, che può essere molto utile:

h = { N: 0, E: 1, S: 2, W: 3 }
%i[N N E S E S W].map(&h)
# => [0, 0, 1, 2, 1, 2, 3]

Ruby 2.4

Ruby 2.4 non è ancora uscito, ma lo sarà presto e ha alcune piccole funzionalità. (Quando verrà rilasciato aggiornerò questo post con alcuni collegamenti ai documenti.) Ho imparato la maggior parte di questi in questo fantastico post sul blog .

Enumerable#sum

Non più arr.reduce(:+). Ora puoi semplicemente farlo arr.sum. Prende un argomento facoltativo sul valore iniziale, il cui valore predefinito è 0 per gli elementi numerici ( [].sum == 0). Per altri tipi dovrai fornire un valore iniziale. Accetta anche un blocco che verrà applicato a ciascun elemento prima dell'aggiunta:

[[1, 10], [2, 20], [3, 30]].sum {|a,b| a + b }
# => 66

Integer#digits

Ciò restituisce una matrice di cifre di un numero nell'ordine di significatività minimo-massimo:

123.digits # => [3, 2, 1]

Rispetto, diciamo, 123.to_s.chars.map(&:to_i).reverseè abbastanza carino.

Come bonus, prende un argomento radix opzionale:

a = 0x7b.digits(16) # => [11, 7]
a.map{|d|"%x"%d} # => ["b", "7"]

Comparable#clamp

Fa quello che dice sulla scatola:

v = 15
v.clamp(10, 20) # => 15
v.clamp(0, 10) # => 10
v.clamp(20, 30) # => 20

Dal momento che è in Comparable puoi usarlo con qualsiasi classe che include Comparable, ad esempio:

?~.clamp(?A, ?Z) # => "Z"

String#unpack1

Un risparmio di 2 byte su .unpack(...)[0]:

"👻💩".unpack(?U)    # => [128123]
"👻💩".unpack(?U)[0] # => 128123
"👻💩".unpack1(?U)   # => 128123

Argomento di precisione per Numeric#ceil, flooretruncate

Math::E.ceil(1) # => 2.8
Math::E.floor(1) # => 2.7
(-Math::E).truncate(1) # => -2.7

Assegnazione multipla in condizionali

Ciò genera un errore nelle versioni precedenti di Ruby, ma è consentito in 2.4.

(a,b=1,2) ? "yes" : "no" # => "yes"
(a,b=nil) ? "yes" : "no" # => "no"

Golf Math::E.ceil(1)a Math::E.ceil 1, e allo stesso modo per floore truncate.
Arte semplicemente

1
@SimplyBeautifulArt Mi aspetto che qualcuno giocando a golf a Ruby sarà in grado di fare questo salto da solo.
Giordania,

Perché Enumerable#sum, .flatten.sumè 2 byte più corto di.sum{|a,b|a+b}
Asone Tuhid

(-Math::E).truncate(1)equivale a -Math::E.truncate(1)1 byte in meno
Asone Tuhid

1
&.può essere utilizzato con la sottoscrizione in questo modo a&.[]i(1 byte più corto di a&.at i). a||a[i]a&.[](i)a&.at(i)
Tuttavia

7

La notazione scientifica può spesso essere utilizzata per radere un carattere o due:

x=1000
#versus
x=1e3

9
Nota: questo restituirà un valore Float (1000.0) anziché un numero intero, che potrebbe causare risultati imprecisi con numeri grandi.
Dogbert,

4
Ah, bello 1e2è meglio di 100.0quando è necessaria una percentuale.
Phrogz,

Simile a questo principio, 1.0*è 1 carattere più corto di.to_f
Unihedron il

7

Utilizzare i metodi dell'operatore anziché le parentesi

Diciamo che vuoi esprimere a*(b+c). A causa della precedenza, a*b+cnon funzionerà (ovviamente). Il bel modo di Ruby di avere operatori come metodi viene in soccorso! Puoi usare a.*b+cper rendere la precedenza *inferiore a quella di +.

a*(b+c) # too long
a*b+c   # wrong
a.*b+c  # 1 byte saved!

Questo può funzionare anche con gli operatori !e ~(cose come unarie +o unarie -non funzionano perché i loro metodi sono -@e +@, salvando ()ma aggiungendo .@)

(~x).to_s # too long
~x.to_s   # error
x.~.to_s  # 1 byte saved!

6

Usa ||invece ore &&invece and.

Accanto a un solo personaggio andpuoi salvare gli spazi (e forse la parentesi) attorno all'operatore.

p true and false ? 'yes' :'no'   #-> true (wrong result)
p (true and false) ? 'yes' :'no' #-> 'no'
p true&&false ? 'yes' :'no'      #-> 'no', saved 5 characters


p true or false ? 'yes' :'no'   #-> true (wrong result)
p (true or false) ? 'yes' :'no' #-> 'yes'
p true||false ? 'yes' :'no'      #-> 'yes', saved 4 characters

Se si esegue il loop su un array normalmente utilizzato each. Ma mapscorre anche su un array ed è più corto di un personaggio.


6

Ho appena tentato una sfida di golf in codice TDD, ovvero scrivere il codice più breve per far passare le specifiche. Le specifiche erano qualcosa del genere

describe PigLatin do
  describe '.translate' do
    it 'translates "cat" to "atcay"' do
      expect(PigLatin.translate('cat')).to eq('atcay')
    end
    # And similar examples for .translate
  end
end

Per motivi di code-golf, non è necessario creare un modulo o una classe.

Invece di

module PigLatin def self.translate s;'some code'end;end

si può fare

def(PigLatin=p).translate s;'some code'end

Salva 13 personaggi!


7
Ah, molto approfondito. Non solo si aggiunge il comportamento necessario PigLatin, ma anche per @pig_latin, $pig_latine 'pig'['latin'].
istocratico,

@histocrat: ora ho capito. È perché translateè stato definito nil.
Eric Duminil,

6

Il kernel # p è un metodo divertente.

Usa p varinvece di puts var. Funziona perfettamente con numeri interi e float, ma non con tutti i tipi. Stampa le virgolette attorno alle stringhe, che probabilmente non è quello che desideri.

Utilizzato con un singolo argomento, prestituisce l'argomento dopo averlo stampato.

Utilizzato con più argomenti, prestituisce gli argomenti in un array.

Utilizzare p(senza argomenti) invece di nil.


10
Purtroppo le p 'some string'stampe "some string"e non solo some stringsono spesso criticate da altri.
Patrick Oscity,

1
Fondamentalmente p sè lo stesso di puts s.inspect, ma ritornas
Cyoce

6

Non usare #each. Puoi scorrere su tutti gli elementi bene con #map. Quindi invece di

ARGV.each{|x|puts x}

puoi fare lo stesso in meno byte.

ARGV.map{|x|puts x}

Certo, in questo caso puts $*sarebbe ancora più breve.


Esistono letterali per numeri razionali e complessi:

puts 3/11r == Rational(3,11)
puts 3.3r == Rational(66,20)
puts 1-1.i == Complex(1,-1)

=> true
true
true

È possibile utilizzare la maggior parte dei byte all'interno delle stringhe. "\x01"(6 byte) può essere abbreviato in ""(3 byte). Se è necessario solo questo byte, questo può essere ridotto ulteriormente a ?(2 byte).

Allo stesso modo, è possibile ridurre le righe in questo modo:

(0..10).to_a.join'
'

 => "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"

Puoi usare ?\ne ?\tpure, che è un byte più corto di "\n"e "\t". Per l'offuscamento, c'è anche? \ S, uno spazio.


Usa le costanti invece di passare argomenti in giro, anche se devi cambiarli. L'interprete darà avvertimenti a stderr , ma a chi importa. Se è necessario definire più variabili correlate tra loro, è possibile raggrupparle in questo modo:

A=C+B=7+C=9

=> A=17, B=16, C=9

Questo è più breve di C=9;B=16;A=17o C=0;B=C+7;A=C+B.


Se hai bisogno di un ciclo infinito, usa loop{...}. I loop di lunghezza sconosciuta possono essere più brevi con altri loop:

loop{break if'
'==f(gets)}

while'
'!=f(gets);end

Alcuni trucchi gsub / regexp. Usa i '\1'caratteri speciali di escape invece di un blocco:

"golf=great short=awesome".gsub(/(\w+)=(\w+)/,'(\1~>\2)')

"golf=great short=awesome".gsub(/(\w+)=(\w+)/){"(#{$1}~>#{$2})")

E le variabili speciali $1ecc. Se è necessario eseguire operazioni. Tieni presente che sono definiti non solo all'interno del blocco:

"A code-golf challenge." =~ /(\w+)-(\w+)/
p [$1,$2,$`,$']

=> ["code", "golf", "A ", " challenge."] 

Sbarazzati di spazi, newline e parentesi. Puoi omettere un bel po 'di rubino. In caso di dubbi, prova sempre se funziona senza e tieni presente che ciò potrebbe interrompere l'evidenziazione della sintassi dell'editor ...

x+=1if$*<<A==????::??==??

"Si prega di inviare un suggerimento per risposta." Inoltre ?\nè bello, ma non molto più breve di quello che mette un carattere di nuova riga tra virgolette. (lo stesso per la scheda)
Martin Ender,

Ed puts$*è ancora più breve.
Cyoce,

So che stavi cercando di dimostrare un punto, ma sono abbastanza sicuro che l'ultimo esempio è lo stesso dix+=1;$*<<A
Asone Tuhid,

6

Ancora un altro modo di usare l'operatore splat: se si desidera assegnare un valore letterale a matrice singola, a *sul lato sinistro è più corto delle parentesi sul lato destro:

a=[0]
*a=0

Con più valori non hai nemmeno bisogno dell'operatore splat (grazie a histocrat per avermi corretto su questo):

a=[1,2]
a=1,2

Quest'ultimo caso in realtà non ha bisogno dello splat.
istocrato

@histocrat Oh wow, ho pensato che il secondo valore sarebbe stato scartato in quel caso.
Martin Ender,

1
Non riesco a credere di non averli conosciuti per tutto il tempo che ho passato a giocare a golf a Ruby.
Maniglia della porta

6

Quando una sfida richiede l'output di più righe, non è necessario eseguire il ciclo dei risultati per stampare ogni riga, ad esempio di un array. Il putsmetodo appiattirà un array e stamperà ogni elemento su una riga separata.

> a = %w(testing one two three)
> puts a
testing
one
two
three

Combinando l'operatore splat con #pte puoi renderlo ancora più breve:

p *a

L'operatore splat (tecnicamente il *@metodo, penso) lancia anche i tuoi enumerabili non array in array:

> p a.lazy.map{|x|x*2}
#<Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3]>:map>

vs

> p *a.lazy.map{|x|x*2}
2
4
6

1
*@non è un metodo, lo splat è lo zucchero sintattico
Asone Tuhid,

6

Salvare alcuni byte quando si rimuovono elementi ripetuti di un array

a.uniq # before
a|[]   # after
    ^^

Se utilizzerai un array vuoto []in una variabile, puoi salvare ancora più byte:

a.uniq;b=[] # before
a|b=[]      # after
      ^^^^^

2
Per il primo caso, a&aè più corto di 1 byte
Asone Tuhid

5

Usa Goruby invece di Ruby, che è qualcosa di simile a una versione abbreviata di Ruby. Puoi installarlo con rvm tramite

rvm install goruby

Goruby ti permette di scrivere la maggior parte del tuo codice come se stessi scrivendo Ruby, ma ha delle abbreviazioni aggiuntive incorporate. Per trovare l'abbreviazione più breve disponibile per qualcosa, puoi usare il metodo helper shortest_abbreviation, ad esempio:

shortest_abbreviation :puts
#=> "pts"

Array.new.shortest_abbreviation :map
#=> "m"

String.new.shortest_abbreviation :capitalize
#=> "cp"

Array.new.shortest_abbreviation :join
#=> "j"

Molto utile è anche l'alias sayper il putsquale può essere abbreviato s. Quindi invece di

puts [*?a..?z].map(&:capitalize).join

ora puoi scrivere

s [*?a..?z].m(&:cp).j

per stampare l'alfabeto in maiuscolo (che non è un ottimo esempio). Questo post sul blog spiega più cose e alcuni dei meccanismi interni se sei interessato a ulteriori letture.

PS: non perdere il hmetodo ;-)


Più di 2 anni dopo e ho finalmente capito cosa mi ricorda questa risposta ...
undergroundmonorail

5

Per unire un array, invece di questo

[...].join

Fai questo

[...]*''

che consente di risparmiare 2 byte. Per unirti a un separatore usa

[...]*?,

5

Numeri di abbonamento!

L'ho scoperto ieri. n[i]ritorna nil bit in iposizione -th. Esempio:

irb(main):001:0> n = 0b11010010
=> 210
irb(main):002:0> n[0]
=> 0
irb(main):003:0> n[1]
=> 1
irb(main):004:0> n[2]
=> 0
irb(main):005:0> n[3]
=> 0
irb(main):006:0> n[4]
=> 1
irb(main):007:0> n[5]
=> 0

E ora puoi usare altri argomenti comen[0..3]
Simply Beautiful Art, il

4

Potresti essere in grado di salvare 2 caratteri e utilizzarli

[*(...)]

invece di

(...).to_a

Ad esempio, supponiamo di avere un intervallo che vogliamo come matrice:

(1..2000).to_a

Fallo così:

[*1..2000]  #  Parentheses around the (ran..ge) is not needed!

E ora hai il tuo range come array.


5
Penso che [*1..2000]funzioni anche tu?
Lynn,

4

<< trucco

a.push x

può essere abbreviato in:

a<<x

per -4 byte.


2
Nota: questo funziona anche per Strings
Cyoce il

4

Array#assoc/rassoc

Quando si dispone di una matrice di matrici e si desidera trovare la matrice secondaria che inizia con un valore particolare, non utilizzare Enumerable#find, utilizzare Array#assoc:

a = [[0,"foo"],[0,"bar"],[1,"baz"],[0,"qux"]]
a.find{|x,|x==1} # => [1,"baz"]
a.assoc(1) # => [1,"baz"]

Questo è anche un buon sostituto per Enumerable#any?in alcune situazioni.

Array#rassoc fa la stessa cosa, ma controlla l'ultimo elemento dei sotto-array:

a = [[123,"good"],[456,"good"]]
a.any?{|*,x|x=="bad"} # => false
a.rassoc("bad") # => nil

Per la a.any?riga rassoc nell'esempio, cosa fa |x,|? In cosa differisce da |x|?
Cyoce,

@Cyoce blocco parametri destrutturazione segue le stesse regole di destrutturazione assegnazione, quindi è come x=[1,2]vs x,=[1,2]. Usando il mio esempio sopra, con |x|, nella prima iterazione xsarà [0,"foo"]. Con |x,y|, xsarà 0e ysarà "foo". Allo stesso modo, con |x,|, xsarà 0. In altre parole, dice "metti dentro il primo elemento xe butta via il resto.
Giordania

Si noti che non funziona al contrario, ad es. |,y|SyntaxError, ergo |_,y|. Ma ho appena capito che |*,y|funziona, che è più pulito dell'uso di una variabile denominata _(ma non più breve).
Giordania,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.