Dicas para jogar golfe em PHP

37

Que dicas gerais você tem para jogar golfe no PHP? Estou procurando idéias que possam ser aplicadas aos problemas de código de golfe em geral, que sejam pelo menos um pouco específicos do PHP (por exemplo, "remover comentários" não é uma resposta). Poste uma dica por resposta.

JiminP
fonte
Espere, estou fazendo certo? ... De qualquer forma, estou realmente curioso sobre este. O PHP é usado por muitas pessoas e jogadores de golfe, mas quase não tenho idéia de como jogar golfe em um código PHP.
JiminP
Use tags curtas <??> Ele pode economizar alguns bytes.
Mob

Respostas:

22

Entenda como variáveis ​​e espaços em branco interagem com as construções de linguagem do PHP.

No meu tempo de jogo (reconhecidamente curto), eu descobri que as construções de linguagem do PHP (por exemplo, eco, retorno, por enquanto, etc.) se comportam de maneira menos que intuitiva ao interagir com variáveis ​​e espaços em branco.

echo$v;, por exemplo, é perfeitamente válido, como são return$v;e outras construções semelhantes. Essas pequenas reduções no espaço em branco podem levar a uma diminuição cumulativa significativa no comprimento.

Porém, lembre-se de que as variáveis anteriores às construções de linguagem requerem um espaço depois, como no exemplo a seguir:

foreach($a AS$b){}

Por ASser uma construção de linguagem, um espaço não é necessário antes da variável $b, mas se alguém omitir o espaço antes dela , resultando em $aAS, isso seria analisado como um nome de variável e levaria a um erro de sintaxe.

rintaun
fonte
3
foreach($a[1]as$b)não precisa de espaço em branco. Não se trata de construções e variáveis ​​de linguagem, mas de espaços entre caracteres de palavras de palavras diferentes.
Titus
11
Outra instância em que você precisa de espaço em branco está na concatenação de cadeias. Por exemplo, echo $a+5." text"não funcionará porque o PHP acha que .é um ponto decimal para o arquivo 5. Para fazê-lo funcionar, você precisaria adicionar um espaço como este: #echo $a+5 ." text"
Business Cat
@BasicSunset Essa declaração pode ser escrita como echo$a+5," text";. A echoconstrução permite que você passe vários parâmetros. onde alguém teria que escrever echo"result: ".($a+5)."!";, você pode escrever echo"result: ",$a+5,"!";. De fato, passar vários parâmetros para um echoé uma micro-otimização, pois o código será executado um pouquinho mais rápido (já que você não concatena a saída, mas a envia separadamente). Para desafios sobre como escrever o código mais rápido, isso pode ajudar um pouquinho.
Ismael Miguel
@IsmaelMiguel Ele funciona com echo, mas não com print(o que você precisa se você o colocar dentro de uma expressão: echoé uma construção pura, sem valor de retorno, enquanto print pode funcionar como uma função: não requer parênteses, mas sempre retorna int(1).
Titus
@ Titus eu não disse nada sobre print.
Ismael Miguel
22

Use cordas com sabedoria.

Esta resposta é dupla. A primeira parte é que, ao declarar strings, você pode utilizar a conversão implícita do PHP de constantes desconhecidas em strings para economizar espaço, por exemplo:

@$s=string;

O @é necessário para substituir as advertências Isto irá produzir. No geral, você acaba com uma redução de um caractere.

é que, às vezes, pode ser eficiente em termos de espaço definir uma variável para o nome de uma função usada com frequência. Normalmente, você pode ter:

preg_match(..);preg_match(..);

Mas quando jogar golfe, isso pode ser reduzido facilmente para:

@$p=preg_match;$p(..);$p(..);

Com apenas duas instâncias de "preg_match", você salva apenas um único caractere, mas quanto mais você usa uma função, mais espaço economiza.

rintaun
fonte
10
@ não é necessário no codegolf; avisos e advertências (incluindo E_DEPRECATED) são aceitáveis
Titus
3
@Titus Mas, no PHP, os avisos seriam enviados para o arquivo padrão, portanto, são necessários.
usar o seguinte comando
11
@Titus Eu acredito que você pode suprimi-los no php.iniarquivo
Stan Strum
12

Você nem sempre precisa escrever verificações condicionais. Por exemplo, algumas estruturas usam isso na parte superior de seus arquivos para bloquear o acesso:

<?php defined('BASE_PATH')||die('not allowed');

Ou em funções normais

$value && run_this();

ao invés de

if($value) { run_this(); }
Xeoncross
fonte
Também funciona em JS
Евгений Новиков
8

Use sintaxe de matriz curta

Desde o PHP 5.4, os arrays podem ser declarados usando colchetes (assim como JavaScript), em vez da array()função:

$arr=['foo','bar','baz'];
// instead of
$arr=array('foo','bar','baz');

Ele salvará cinco bytes.


Mas pode custar bytes se você tiver "buracos" em uma matriz associativa:

$arr=array(,1,,3,,5);
// is one byte shorter than
$arr=[1=>1,3=>3,5=>5];

a desvantagem ocorre um pouco mais tarde se você puder preencher os furos com valores "vazios":

$arr=[0,1,0,3,0,5,0,7,0,9,10,11];
// costs two byte more than
$arr=array(,1,,3,,5,,7,,9,,11);
rink.attendant.6
fonte
2
PHP 7.1 também introduziu curto atribuição lista: [,$a,$b,$c]=$argv;.
Titus
7

Use $ {0}, $ {1}, $ {2}, ... em vez de $ a [0], $ a [1], $ a [2], ...

A menos que você esteja executando uma manipulação de matriz, a maioria das referências a um índice de matriz $a[$i]pode ser substituída simplesmente $$i. Isso é verdade mesmo se o índice for um número inteiro, pois números inteiros são nomes de variáveis ​​válidos no PHP (embora literais exijam colchetes, por exemplo ${0}).

Considere a seguinte implementação da torneira Rabonowitz Wagon:

3.<?for(;$g?$d=0|($a[$g]=$d*$g--/2+($a[$g]?:2)%$g*1e4)/$g--:238<<printf($e?'%04d':'',$e+$d/$g=1e4)^$e=$d%$g;);

Isso pode ser aprimorado em 6 bytes, simplesmente substituindo as duas referências de matriz $a[$g]por $$g:

3.<?for(;$g?$d=0|($$g=$d*$g--/2+($$g?:2)%$g*1e4)/$g--:238<<printf($e?'%04d':'',$e+$d/$g=1e4)^$e=$d%$g;);
primo
fonte
11
Acabei de salvar 3 bytes com isso: showcase .
Titus
6

Aprenda um grande subconjunto das funções da biblioteca .

A biblioteca do PHP é bastante grande e oferece várias funções convenientes que podem reduzir bastante várias tarefas. Você pode pesquisar sempre que tentar fazer algo, mas além de perder tempo, pode não encontrar nada que corresponda à sua pesquisa específica. A melhor maneira é apenas se familiarizar com a biblioteca e memorizar os nomes das funções e o que elas fazem.

Matthew Read
fonte
6
Isso é um monte de memorização, especialmente tendo em conta a nomeação, em vez inconsistente de toda uma série de funções ;-)
Joey
@Joey concordou. Semelhante a memorizar a biblioteca Java, exceto que isso seria sem dúvida menos útil, pois é mais detalhado.
Matthew Leia
3
Acho que as funções mais importantes para os desafios que encontrei até agora aqui são as funções de manipulação de strings e manipulação de array. O uso criativo desses pode realmente reduzir o código.
migimaru 12/08
6

Funções em execução dentro de strings.

Tente o seguinte:

$a='strlen';
echo "This text has {$a('15')} chars";

Ou tente o seguinte:

//only php>=5.3
$if=function($c,$t,$f){return$c?$t:$f;};
echo <<<HEREDOCS
    Heredocs can{$if(true,' be','not be')} used too and can{$if(<<<BE
{$if(true,1,0)}
BE
,'','not')} be nested
HEREDOCS;
//Expected output: Heredocs can be used too and can be nested

Isso funciona apenas com strings usando ""e heredocs (NÃO confunda com nowdocs).

O uso de funções aninhadas só é possível dentro de heredocs aninhados (ou você encontrará erros de análise)!

Ismael Miguel
fonte
you will run into parse errorsEu não posso ler isso sozinho? Como o irritante mecanismo Zend coloca isso junto
Stan Strum
A próxima vez que eu estiver no argumento "PHP é uma boa linguagem de programação" , usarei isso como um contraponto. Uau.
Primo
@primo É tão ruim assim? : O
Ismael Miguel
5

diversão com tipmarks

  • !!$footransformará qualquer valor verdadeiro para true(ou 1na saída), valores falsos (0, cadeia vazia, matriz vazia) para false(ou saída vazia)
    Isso raramente será necessário no código golf, pois na maioria dos casos em que você precisa de um valor booleano, existe um elenco implícito de qualquer maneira.

  • (int)$foopode ser escrito como $foo|0ou foo^0, mas pode precisar de parênteses.
    Para booleanos e strings, $foo*1ou +$foopode ser usado para converter para int.

  • Diferentemente da maioria das outras linguagens, o PHP lida com seqüências de caracteres com valores numéricos. Portanto, se você tiver qualquer sequência que contenha um número com o qual você deve calcular, basta calcular.
  • A outra maneira não funciona: para multiplicar qualquer número em uma variável 10, você pode acrescentar um zero:*10 -> .0. Mas neste caso, o PHP pegará o ponto como ponto decimal e reclamará. (É diferente se você tiver uma quantidade variável de zeros em uma string.)
  • Para transformar uma matriz em uma sequência, use em joinvez de implode.
    Se você não precisa de um delimitador, não o use: join($a)faz o mesmo quejoin('',$a)
  • Incrementando strings: o recurso mais surpreendente que a imo é que $s=a;$s++;produz $s=b;. Isso funciona com caracteres maiúsculos e minúsculos. $s=Z;$s++;resulta em $s=AA;.
    Isso também funciona com maiúsculas e minúsculas: aZpara bA, A1para A2, A9para B0e z99Zpara aa00A.
    Decremento não funciona em seqüências de caracteres. (E isso não acontece NULL).
    De volta ao PHP 3, $n="001";$n++;produzido $n="002";. Estou um pouco triste por terem removido isso.

Qualquer que seja o seu golfe: tenha sempre em mãos a tabela de precedência do operador .

Titus
fonte
4

Use atalhos

No código normal, é uma boa prática usar <?phpe ?>. No entanto, este não é um código normal - você está escrevendo um código de código de golfe. Em vez de <?phpescrever <?. Em vez de <?php echoescrever <?=. Não digite ?>no final - é totalmente opcional. Se você precisar ?>de algum motivo (por exemplo, para gerar texto e for mais curto de alguma forma, ou algo assim, não coloque um ponto-e-vírgula antes dele - ele não é necessário, pois?> implica ponto e vírgula.

Errado (definitivamente muito longo):

<?php echo ucfirst(trim(fgets(STDIN)));?>s!

Corrigir:

<?=ucfirst(trim(fgets(STDIN)))?>s!
Konrad Borowski
fonte
Com a -rbandeira ( que é gratuita ), você não possui tags (e você não tem permissão para usá-las).
Titus
4

loop através de cordas

pode ser feito com 26 bytes ou com 24 a 18:

foreach(str_split($s)as$c)  # A) 26 - general
for($p=0;a&$c=$s[$p++];)    # B) 24 - general
for($p=0;$c=$s[$p++];)      # C) 22 - if $s has no `0` character
for(;a&$c=$s[$p++];)        # D) 20 - if $p is already NULL or 0 (does NOT work for false)
for(;$c=$s[$p++];)          # E) 18 - both C and D

for(;$o=ord($s[$p++]);)     # F) 23 - work on ASCII codes, if $s has no NULL byte and D
for(;~$c=$s[$p++];)         # G) 19 - if $s has no chr(207) and D

$a&$bfaz um bit a bit E no (códigos ASCII de) os personagens $ae $b
e resulta em uma cadeia que tem o mesmo comprimento que o mais curto de $ae $b.

Titus
fonte
por favor você pode adicionar ord($s[$p++])como alternativa for(;$s+=ord($argv[++$i])%32?:die($s==100););contra for(;$c=$argv[++$i];)$s+=ord($c)%32;echo$s==100;nesta questão codegolf.stackexchange.com/questions/116933/...
Jörg Hülsermann
Por favor, adicione ~para casos que você está trabalhando apenas com dígitos
Jörg Hülsermann
Note que o PHP 7.2 gera avisos para a ~$cabordagem.
Titus
4

Use operadores ternários

if(a==2){some code;}else{some other code;}

pode ser abreviado para isso:

(a==2?some code:some other code);

Mais curto, hein?

Chris vCB
fonte
"Taquigrafia condicional"? É melhor dizer seu nome real, para que os interessados ​​em mais detalhes possam encontrá-lo na documentação: operador ternário .
manatwork
3
A pergunta pede dicas que são um pouco específicas para o PHP. Essa é uma das dicas para todos os idiomas .
Peter Taylor
3
O operador ternário tem um comportamento estranho no PHP, se você o aninhar. a?aa:ab?aba:abb:bavalia (a?aa:ab)?(aba):(abb)ou algo assim.
Titus
11
E a partir do PHP 5.3, você pode omitir o segundo operador: $a?:$bé o mesmo que $a?$a:$b.
Titus
11
@Cyoce ||lança para booleano em PHP.
Titus
3

por qualquer outro nome ... aliases de função

usar ...

  • join ao invés de implode
  • chopem vez de rtrim( chopem PERL é diferente!)
  • die ao invés de exit
  • fputs ao invés de fwrite
  • is_intem vez de is_integerouis_long
  • is_realem vez de is_floatouis_double
  • key_exists ao invés de array_key_exists
  • mysql ao invés de mysql_db_query

... para nomear os aliases mais importantes. Dê uma olhada em http://php.net/aliases para obter mais informações.

Titus
fonte
Ah ... e você sabia que diefunciona com e sem parâmetros? die(1)sairá do programa com código de erro 1(não totalmente certo disso; precisa de teste); diesairá com código 0e die("Hello")sairá com código 0após a impressão Hello.
Titus
3

Matrizes associativas podem ser mescladas com o +operador.

Ao invés de:

$merged = array_merge($a, $b);

Usar:

$merged = $a + $b;

Observe que o +operador também trabalha com matrizes indexadas, mas provavelmente não faz o que você deseja.

Alex Howansky
fonte
Na verdade, muitas vezes um bom substituto, embora não exatamente o mesmo: pastebin.com/seYeaP38
manatwork
Ah, sim, droga, eu originalmente tinha o título "matrizes associativas ..." e depois o removi. Vou esclarecer, obrigado.
Alex Howansky
matrizes numéricas também podem ser mescladas usando +, desde que os índices sejam distintos. Caso contrário, os valores da primeira matriz serão substituídos pelos da segunda (assim como array_merge). A diferença: +não reordena índices.
Titus
3

array_flip vs array_search

usar

array_flip($array)[$value]

ao invés de

array_search($value,$array)

salvar 1 Byte em matrizes onde a ocorrência de cada valor é única

Jörg Hülsermann
fonte
3

alguns fatos interessantes sobre variáveis ​​variáveis

Eu só tinha que compartilhá-los (mesmo antes de verificar que pelo menos um deles ajuda no golfe):

  • Use letras: $x=a;$$x=1;$x++;$$x=2;echo"$a,$b";imprime1,2
    mas outras operações aritméticas não funcionam com letras.
  • Como mencionado anteriormente , você pode usar números puros como nomes de variáveis:
    $a=1;$$a=5;$a++;$$a=4;${++$a}=3;echo${1},${2},${3};prints543 .
  • Você não pode usar apenas [0-9a-zA-Z_]para nomes de variáveis, mas TODAS as strings:
    $x="Hello!";$$x="Goodbye.";echo${"Hello!"};imprimeGoodbye. .
  • Mas: tudo, exceto [a-zA-Z_][a-zA-Z_0-9]*nomes de variáveis, requer chaves para uso literal.
  • Sem variáveis ​​definidas, $$x=1conjuntos ${NULL}, que é o mesmo que ${false}e ${""}.
  • $a=1;$$a=5;não apenas define ${1}, mas também ${true}.

  • mais uma, a mais estranha que encontrei até agora: tente $a=[];$$a=3;echo${[]};. Sim, ele imprime 3!

A razão para a maior parte disso: os nomes de variáveis ​​são sempre avaliados em seqüências de caracteres.
(Obrigado @Christoph por apontar.)
Então, o que você obtém quando você printou echoa expressão, é o que você obtém como nome da variável.

Titus
fonte
11
Os nomes de variáveis ​​são convertidos em seqüências de caracteres que explicam os três últimos pontos da sua lista. []converte em Array: ${[]} = 5;echo $Array;impressões 5. Tenho certeza que você sabe isso, mas ele pode não ser óbvio para todos :)
Christoph
@ Jeff, eu consertei o erro de digitação. Obrigado por perceber.
Titus
2

quebras de linha
se a saída exigir quebras de linha, use uma quebra de linha física (1 byte) em vez de "\n"
Isso também oferece um possível benefício para você escolher entre aspas simples e duplas.

Titus
fonte
2

evite citações sempre que possível

O PHP lança implicitamente palavras desconhecidas para cadeias literais.

$foo=foo;é o mesmo que $foo='foo';(supondo que foonão seja uma palavra-chave ou uma constante definida):$foo=echo; não funciona.

MAS: $p=str_pad;faz; e $p(ab,3,c)avalia paraabc .

Usar literais de string sem aspas produzirá um aviso para Use of undefined constant; mas isso não será exibido se você usar o valor padrão para error_reporting(parâmetro CLI -n).

Titus
fonte
Acabei de notar: Esta resposta é uma duplicata um pouco extendida / atualizada de codegolf.stackexchange.com/a/2916/55735 .
Titus
Nota: O PHP anterior à 7.2 produziu avisos (que você pode usar com o -nsinalizador); 7.2 produz avisos; versões posteriores lançam erros!
Titus
2

Funções de seta no PHP 7.4

O PHP 7.4 já está na versão RC2 e, esperançosamente, será lançado em cerca de 2 meses. A lista de novos recursos está aqui (esta página pode ser atualizada quando o 7.4 for lançado). Na 7.4, finalmente, o PHP possui as funções de seta; portanto, não apenas as respostas das funções podem ser mais curtas agora, mas também a passagem de fechamentos para outras funções também pode ser muito mais curta. Aqui estão alguns exemplos:

Retorno de entrada + 1:

Função anônima (fechamento) - 25 bytes - Experimente online!

function($n){return$n+1;}

Função de seta - 12 bytes - Experimente online!

fn($n)=>$n+1

Multiplique os itens da primeira entrada (matriz de entradas) pela segunda entrada (int):

Função anônima (fechamento) - 72 bytes - Experimente online!

function($a,$n){return array_map(function($b)use($n){return$b*$n;},$a);}

Função de seta - 38 bytes - Experimente online!

fn($a,$n)=>array_map(fn($b)=>$b*$n,$a)

Você percebeu que $né acessível na função interna sem uma use $ndeclaração? Sim, esse é um dos recursos da função de seta.


Como uma observação lateral, não consegui que as funções de seta funcionassem recursivamente (chame a mesma função de seta dentro de si), porque não podemos dar um nome a elas e armazená-las como um fechamento em uma variável que $fnão se torna $facessível por si mesma (triste ) Portanto, este exemplo não funciona e o uso $fna primeira linha causa um erro fatal:

$f=fn($n)=>$n?$f($n-1):0;
$f(5); // Causes error: "PHP Notice: Undefined variable: f" + "PHP Fatal error: Uncaught Error: Function name must be a string"

Mas chamar uma função de seta dentro de uma função de seta diferente funciona:

$f1=fn($n)=>$n+1;
$f2=fn($n)=>$f1($n-1);
$f1(2) // Returns 3
$f2(2) // Returns 2
Night2
fonte
E se, em vez de $f=fn($n)=>$n?$f($n-1):0;você, fizer $f=$F=fn($n)=>$n?$F($n-1):0;? Isso funcionaria? E então você liga $(5)como de costume.
Ismael Miguel
@IsmaelMiguel ainda parece lançar o mesmo erro. Você pode realmente experimentar o tio.run # php, já que Dennis atualizou seu PHP para 7.4 RC2 há um tempo.
Night2
Não consigo fazer funcionar. Parece que apenas variáveis ​​definidas antes estão disponíveis.
Ismael Miguel
1

Matrizes de desreferência direta retornadas de funções.

Por exemplo, em vez disso:

$a = foo();
echo $a[$n];

Você pode fazer:

echo foo()[$n];

Isso funciona com métodos também:

echo $obj->foo()[$n];

Você também pode desreferenciar diretamente as declarações da matriz:

echo [1, 2, 3, 4, 5][$n];
Alex Howansky
fonte
1

Use em end()vez dearray_pop()

A end()função não apenas move o ponteiro interno para o final da matriz, mas também retorna o último valor. Observe, é claro, que ele não remove esse valor; portanto, se você não se importa com o que a matriz contém posteriormente, pode usá-lo em vez de array_pop().

Alex Howansky
fonte
1

array_flip duplo vs matriz_de_ matriz vs matriz_de_ matriz

nesse caso especial, um array_flip duplo economiza 10 bytes

($f=array_flip)($k=$f($c)))remover todos os valores double na matriz e eu ter deixado cair esta $c=[],, |in_array($o,$c)e substituir array_keys($c)com$k

for([,$x,$y]=$argv;a&$o=$y[$i];$i++)
$x[$i]==$o?:$c[$x[$i]]=$o; # if char string 1 not equal char string 2 set key=char1 value=char2
echo strtr($x,($f=array_flip)($k=$f($c)))==$y # boolean replacement string 1 equal to string 2
    ?join($k)." ".join($c) # output for true cases
:0; #Output false cases

Versão Online

contra

for($c=[],[,$x,$y]=$argv;a&$o=$y[$i];$i++)
  $x[$i]==$o|in_array($o,$c)?:$c[$x[$i]]=$o; # if char string 1 not equal char string 2 set key=char1 value=char2
echo strtr($x,$c)==$y # boolean replacement string 1 equal to string 2
  ?join(array_keys($c))." ".join($c) # output for true cases
  :0; #Output false cases

Versão online

contra array_unique, ele salva 2 bytes

for([,$x,$y]=$argv;a&$o=$y[$i];$i++)
  $x[$i]==$o?:$c[$x[$i]]=$o; # if char string 1 not equal char string 2 set key=char1 value=char2
echo strtr($x,array_unique($c))==$y # boolean replacement string 1 equal to string 2
  ?join(array_keys($c))." ".join($c) # output for true cases
  :0; #Output false cases

Versão Online

Depois de encontrar um bug neste programa e substituição $x[$i]==$o?:$c[$x[$i]]=$opara ($p=$x[$i])==$o?:$k[$c[$p]=$o]=$po duplo array_flip não era necessário mais tempo

Jörg Hülsermann
fonte
seguro associativo array_unique. Yay!
Titus
@Titus Eu adicionei sua sugestão
Jörg Hülsermann
1

cordas que se cruzam

Você já usou
join("DELIMITER",str_split($s))(31 bytes) ou mesmo
preg_replace(".","DELIMITER",$s)(32 bytes)
?

Existe um construtor para isso:

Tente chunk_split($s,1,"DELIMITER")(29 bytes).


Se você omitir o terceiro parâmetro, chunk_splitusará\r\n ; que você pode economizar 7 ou 8 bytes.

Mas cuidado: chunk_splittambém anexa o delimitador à string,
para que você não consiga exatamente o que deseja.

(Se você não fornecer o tamanho do pedaço, ele usará 76. Bastante incomum para o golfe com código, mas quem sabe.)

Titus
fonte
Talvez você deva adicionar um exemplo em combinação com strtrEu amo essa ideia.
Jörg Hülsermann
1

unset () vs INF

Em um caso, procure um mínimo em uma matriz que você possa usar em vez de

unset($var[$k]);

$var[$k]=INF;

economizar 3 bytes

Jörg Hülsermann
fonte
1

str_repeat

Em alguns casos, você tem uma entrada de caracteres e deve produzi-los repetidos com uma entrada maior zero para cada caractere.

for(;--$z?:($c=$argn[$i++]).$z=$argn[$i++];)echo$c;

(52 bytes) é menor que

for(;~$c=$argn[$i++];)echo str_repeat($c,$argn[$i++]);

ou

for(;~$c=$argn[$i++];)echo str_pad($c,$argn[$i++],$c);

(54 bytes cada)

Como funciona, por exemplo, entrada a1b2c1

$znão está definido (implícito NULL), o --$zque não faz nada e é falso;

$c="a", $z="1"E $i=2->$c.$z="a1" é verdade -> saída"a"

--$z=0; então definimos $c="b", $z="2"(e $i=4) -> $c.$z="b2"é verdade -> saída"ab"

--$z=1 -> saída "abb"

--$z=0; então definimos $c="c"e $z=1 $c.$z="c1"é a verdadeira saída"abbc"

--$z=0então $c=""e $z=""-> $c.$z=""é falso -> quebras de loop

Jörg Hülsermann
fonte
1

Combinando forloops

Suponha que você tenha um código do seguinte formato:

for($pre1; $cond1; $post1) for($pre2; $cond2; $post2) $code;

isso geralmente pode ser relançado da seguinte forma:

for($pre1; $cond2  $post2 || $cond1  $pre2  $post1; ) $code;

onde representa um operador combinado genérico. Isso geralmente resulta em uma redução na contagem de bytes, mas provavelmente exigirá alguma criatividade. $cond2precisará ser escrito para que falhe na primeira vez. $post1também deve falhar na execução pela primeira vez, embora possa ser mais fácil refatorar antecipadamente para que$post1 não esteja presente.

Se você estiver trabalhando com três ou mais loops aninhados, também poderá combinar dois primeiro e depois combinar com outro, e assim por diante. Acho que geralmente tem sido mais fácil combinar de dentro para fora.


Como exemplo, considere a seguinte solução para o fractal H-carpet ( 97 bytes ):

for(;$i<$n=3**$argn;$i+=print"$s\n")for($s=H,$e=1;$e<$n;$e*=3)$s.=str_pad($i/$e%3&1?$s:'',$e).$s;

Isso pode ser reformulado da seguinte maneira:

for(;($i+=$e&&print"$s\n")<$n=3**$argn;)for($s=H,$e=1;$e<$n;$e*=3)$s.=str_pad($i/$e%3&1?$s:'',$e).$s;

$e&&print impede print na primeira iteração e também não aumenta $i.

e finalmente ( 93 bytes ):

for(;$H>$e*=3or$e=($i+=$e&&print"$s\n")<${$s=H}=3**$argn;)$s.=str_pad($i/$e%3&1?$s:'',$e).$s;

$H>$e*=3 falhará na primeira vez, pois as duas variáveis ​​são indefinidas.

primo
fonte
1

Removendo caracteres em uma sequência

join(explode(" ",$string));

salva 1 caractere em comparação com

str_replace(" ","",$string);
Jörg Hülsermann
fonte
Observe que isso funciona para todas as strings (não vazias), não apenas caracteres.
CalculatorFeline
@CalculatorFeline Por que não deve funcionar para cadeias de caracteres vazias? Não faz sentido ou esse caso.
Jörg Hülsermann
Bem, a primeira versão não funciona ""e, de qualquer maneira, não é muito útil.
CalculatorFeline
11
@CalculatorFeline E, nesse caso, uma solução de zero byte é muito melhor. Não faz sentido fazer isso dessa maneira.
Jörg Hülsermann
3
Falta seu exemplo de associação a ). E strtr($string,[" "=>""])é ainda mais curto.
Titus
1

array_merge vs array_push

array_push($a,...$b); 

é um byte menor que

$a=array_merge($a,$b);

Não funciona da mesma forma com matrizes associativas

variável-arg-list PHP> 5.6

Jörg Hülsermann
fonte
1

Use operadores booleanos em vez de strtoupper() estrtolower()

Se você estiver trabalhando exclusivamente com strings que consistem em caracteres do alfabeto, poderá usar operadores booleanos para alterá-los para maiúsculas ou minúsculas com menos pressionamentos de tecla do que as funções internas do PHP.

Exemplo:

// Convert lowercase to uppercase
$s = "g";
echo strtoupper($s);  // Outputs 'G', uses 20 characters
echo~" "&$s;          // Outputs 'G', uses 12 characters

// Convert uppercase to lowercase
$s = "G";
echo strtolower($s);  // Outputs 'g', uses 20 characters
echo$s^" ";           // Outputs 'g', uses 11 characters

// Switch case of each character
$s = "Gg";
echo$s^"  ";          // Outputs 'gG', uses 12 characters

As coisas são um pouco mais complicadas para cadeias de comprimento arbitrário, mas os operadores &e ^truncarão o resultado para o comprimento da cadeia de entrada mais curta. Assim, por exemplo, se $Wé uma sequência de espaços pelo menos tão longo como qualquer entrada $s, então ~$W&$sé equivalente a strtoupper($s), e $s|$W^$sé equivalente a strtolower($s)(ao passo que $s|$W, por si só irá produzir uma corda com espaços adicional, a menos $se$W são de igual comprimento).

ossifrage melindroso
fonte
0

utilizar funções obsoletas
Se você pode usar POSIX em vez de PERL regex sem perder mais de 5 bytes sobre a expressão, o uso eregou eregiem vez de preg_match, splitou splitiem vez de preg_split.
splitTambém pode ser usado como sinônimo deexplode a maioria dos delimitadores.

Essas funções estão marcadas como obsoletas e lançarão E_DEPRECATEDavisos, mas (não é possível encontrar a fonte agora) Acho que li que avisos e avisos estão ok.

Titus
fonte
2
Cuidado! Estes foram removidos no PHP 7.0.
Umbrella