Que dicas gerais você tem para jogar golfe em Lua? Estou procurando idéias que possam ser aplicadas para codificar problemas de golfe em geral que sejam pelo menos um pouco específicos para Lua (por exemplo, "remover comentários" não é uma resposta). Poste uma dica por resposta.
21
Respostas:
Além dos já publicados, eis alguns truques que reuni ao longo do tempo, sem ordem específica ...
Para as chamadas de função que possuem apenas um parâmetro delimitado por um símbolo (
"
para strings,{
para tabelas), o parâmetro não precisa ser colocado entre parênteses.Por exemplo, em vez de fazer
print("hello")
, você pode simplesmente fazer:print"hello"
Remova o máximo de espaço em branco possível - isso é especialmente fácil de fazer depois de um símbolo que fecha seqüências de caracteres (ou antes de uma abertura), chamadas de função, tabelas ...
Em vez de
print(42) a=1
você pode fazerprint(42)a=1
. Outro exemplo:print(a and-1 or-2)
.Use o operador ternário quando puder! Em vez de
if a>0 then print("hello") else print("goodbye") end
, prefiraprint(a>0 and "hello" or "goodbye")
. Mais informações aqui .(Isso pode ficar ainda melhor
print(a>0 and"hello"or"goodbye")
:)Use o açúcar sintático chamado cólon quando puder: em vez de
string.rep(str,12)
, façastr:rep(12)
. Isso também funciona em não variáveis desta maneira (e somente dessa maneira):("a"):rep(5)
Em vez de fazer
tonumber(str)
apenas façastr+0
Para funções sem parâmetros, em vez de defini-las da maneira usual (
function tick() blabla() end
), você pode fazerticks=loadstring"blabla()"
:, que salva 1 ou mais bytes, dependendo do conteúdo. Além disso, se você definir várias funções, localizeloadstring
antes uma variável de 1 caractere e economize muitos bytes;). Créditos a Jim Bauwens por esse truque.Lua considera a string vazia (e
0
muito diferente de outras linguagens) como verdadeira em testes condicionais; portanto, por exemplo, em vez de fazê-lowhile 1 do ... end
, salve 1 byte escrevendowhile''do ... end
fonte
str+0
equivalente~~str
, pode ser útil para a sua precedênciaEu já pensei em um. Não sei se funciona em outras línguas, mas Lua é a única que sei o que permite armazenar funções em variáveis. Portanto, se eg
string.sub
for usado várias vezes em seu programa, use egs=string.sub
.fonte
s=("").sub
ous=a.sub
para qualquer variável quea
contém o valor da sequência.É uma linguagem bastante detalhada para o golfe ... mas algumas dicas gerais que vêm à mente são:
if
...then
...else
...end
é um grande desperdício.for i=1,5 do
.#
operador é ótimo para jogar golfe (e em geral).fonte
Encurte seu loop infinito
Quando você precisa usar um loop infinito, pode pensar em usar a
while
, mas o uso de um rótulo é menor em 2 bytes:Use o menor espaço possível
Há uma coisa simples que você pode (ab) usar para remover ainda mais espaços do seu código. As especificações de Lua são claras sobre o nome que você atribui às variáveis: elas precisam começar com uma letra. Isso implica que, às vezes, você pode pular espaços entre números e funções / variáveis
A possibilidade de remover o espaço depende da letra após o número, aqui está a letra que não permitirá que você faça isso:
Ao usar isso e prestar atenção em como você chama suas variáveis, você pode tornar a maioria dos seus códigos-fonte sem espaço.
Pegando um exemplo já aqui, e usando este conselho, aqui está mais um byte que você pode raspar :).
Use o método de entrada correto
Se olharmos para o padrão e o custo de cada tipo principal de entrada, eis o que temos:
Cada um desses métodos nos permite obter 1 entrada, com a função com o custo mais alto (mas nos permite tomar uma tabela como entrada)
Agora podemos ver que o uso do argumento da linha de comando é o caminho a seguir, se você deseja jogar golfe, mas esteja ciente: ele pode ser ainda mais curto
Eles
...
são um pouco especiais em lua, é uma variável que contém o conteúdo descompactado dearg
ou os parâmetros descompactados no caso de uma função variável .Quando você precisar obter mais de uma entrada e usar cada uma delas, pode ser bom salvá-las em uma variável. Aqui estão algumas maneiras de salvar 2 entradas em variáveis
e aqui está a chamada mais curta que você poderia ter feito sem as variáveis:
Do ponto em que você tem 3 argumentos, ou quando você usa 2 argumentos, com um usado duas vezes, você já está ganhando bytes devido a
a,b=...
! :)Quase nunca use se!
Quase não há casos em que o uso de uma instrução if / elseif / if custará menos que um ternário. o padrão para essa afirmação é realmente pesado:
Com um exemplo simples, você já salva 12 bytes; quando precisar fazer outras coisas, isso se tornará cada vez mais importante; portanto, esteja ciente disso!
Além disso, os ternários em lua são especiais , há alguma condição em como eles funcionam, para os interessados, explicarei abaixo:
Os ternários em lua têm a forma
<condition> and <case true: have to be a true value> or <case false: can be anything>
Primeiro de tudo, vamos ver a tabela verdade do
or
. Aor
pode ser considerado como uma função: sempre retorna um valor, eis o valor que retorna:Isso é o que nos permite construir nosso ternário.
O
and
é o que nos permite avaliar a condição, ele sempre retornaráy
sex and y
avalia a verdade.O problema com ele é que ele irá falhar se queremos uma
nil
oufalse
estar de retorno quando a condição éfalse
. Por exemplo, o seguinte sempre retornará 5, apesar da condição ser verdadeira.Aqui está uma avaliação passo a passo de um ternário para explicar como ele funciona (será útil quando você precisar aninhar :))
fonte
Eu compilei várias dicas também. Tenho certeza de que alguns dos meus se sobrepõem aos já declarados, mas os incluirei de qualquer maneira na veia de criar uma resposta mais completa.
Atribuir funções repetidas a variáveis
Lua permite atribuir funções a variáveis. Variáveis de um caractere. Isso significa que se você repetir a função
string.sub(x, y)
mais de duas vezes, será beneficiado com a atribuição a uma variável.Sem atribuir a uma variável (69 caracteres):
Atribuindo a uma variável (51 caracteres):
Há casos em que você pode levar isso adiante ainda mais. Lua permite que um OOP manipule string, da seguinte forma:
str:sub(x, y)
oustr.sub(x, y)
Isso abre novas opções para o nosso código. Você pode atribuir uma variável à função por sua referência, como mostrado (46 caracteres).Use a maneira mais eficiente de analisar seqüências de caracteres
Você pode se encontrar usando um
for
loop estring.sub
iterar caractere por caractere em Lua. Às vezes, isso pode funcionar melhor, dependendo de suas necessidades, mas outras vezes, string.gmatch funcionará com menos caracteres. Aqui está um exemplo de ambos:E quando jogado, a diferença é mais notável:
Reestruturar atribuições para otimizar espaço em branco
Em Lua, você não precisa colocar um caractere de espaço entre parênteses fechados ou aspas finais e o próximo caractere. Até agora, encontrei dois casos em que a reestruturação com isso em mente cortará caracteres.
Atribuindo variáveis:
Declarações If:
Retorne o menor número possível de caracteres
Se você deve retornar um valor verdadeiro ou falso, parece que você deve necessariamente usar pelo menos 5 caracteres para o valor de retorno. Na realidade, o seguinte também funciona:
fonte
nil
efalse
avalia a falsa na lua, tudo o resto é verdadeiro, assim que suas dicas sobre a substituiçãox==0
,x==""
ex==''
porx
é falsa. Atualmente, estou mudando paranil
:).Estas são apenas otimizações de Lua (eu acho):
As strings são convertidas automaticamente em números ao executar operações aritméticas nelas. Cuidado com as declarações condicionais, elas não são convertidas automaticamente. Isso é ótimo para receber a entrada do usuário como números e economizar espaço.
Mudar o conteúdo de duas variáveis não requer uma variável temporária.
a,b=b,a
trocará os valores de a e b.Além disso, para estender o que foi dito acima, qualquer caractere alfanumérico pode tocar em um caractere não alfanumérico. Então,
a,b=io.read():match"(.+)/(.+)"u,v=a,b
é um script perfeito e funcional, mesmo com a falta de espaço em branco.fonte
Combinar atribuições de variáveis locais
Ao invés de:
Use atribuição paralela:
6 bytes salvos para cada variável!
Declarar variáveis locais por meio de parâmetros de função não utilizados
Ao invés de:
Usar
6 bytes salvos (menos 1-2 bytes para cada variável que pode ser duplicada).
fonte
local
seja justificado ao jogar golfe, porque você só precisa usar um nome diferente. Nós poderíamos usar todos os nomes até 7 charachters e tabelas com índices de cordas até 7 charachters combinações antes estamos atingindo algo que poderia beneficiar do uso de habitantes locaisFunções Variadic
A principal função variável que o incomodará é
print()
. Por exemplo, quando você o usa,String.gsub()
imprime a string que você modificou E o número de vezes que foigsub
acionado.Para suprimir essa segunda saída, encapsule seu
gsub
parens para forçá-lo a retornar apenas um valorfonte
Saiba como produzir
Existem dois métodos principais de saída em lua
Quando você precisar concatenar várias vezes, poderá reduzi-lo usando o
io.write()
atribuído a uma variável de uma letra em vez do operador de concatenação padrão..
Você ganha 2 bytes em cada chamada enquanto paga antecipadamente
Você está na terceira concatenação e começa a ganhar byte na quarta.
fonte
print
e nãoprintf
!Um monte de dicas em nenhuma ordem específica:
string
é um nome bastante longo. Eficientemente,('').char
é o mesmo questring.char
. Resultados ainda melhores podem ser alcançados se você o usar em conjunto com um ponto-e-vírgula nas variáveis:,a=...; print(a:sub(1, 5))
mas algumasstring
funções não recebem seqüências de caracteres como entrada.tonumber
e+0
muitas vezes desperdiçam apenas bytes.load'your function code here'
vez defunction()your function code here end
. Acesse argumentos de função usando...
inside.a:gsub('.',load'my function')
parece ser a maneira mais curta de iterar sobre caracteres em uma stringa:find('.',1,1)
(para testar esse problema, tente incluir%
em vários locais da sua entrada e verificar os resultados). Inúmeras idéias quebraram por causa de Lua tentando analisar as entradas como padrão.nil
tem três bytes,_
é um (é apenas um nome aleatório que provavelmente não existe). Além disso, qualquer dígito funcionará como um valor verdadeiro.x and i or o
. Não é apenas um operador ternário - é uma expressão lógica completa. De fato, significa o seguinte: "sex
for verdade, tentei
. Se x ou i for falso, retorne o". Portanto, sei
não for verdade, o resultado seráo
. Além disso, ambasand
ouor
partes podem ser omitidas (x and i
,x or o
).math.floor
:5.3//1==5.0
. Observe que o número resultante sempre segue o tipo de entrada um (inteiro / flutuante).fonte