Consejos para jugar golf en PHP


37

¿Qué consejos generales tienes para jugar al golf en PHP? Estoy buscando ideas que puedan aplicarse a los problemas de código de golf en general que sean al menos algo específicos de PHP (por ejemplo, "eliminar comentarios" no es una respuesta). Por favor, publique un consejo por respuesta.


Espera, ¿lo estoy haciendo bien? ... De todos modos, tengo mucha curiosidad por este. PHP es utilizado por muchas personas y golfistas, pero casi no tengo idea de cómo jugar golf en un código PHP.
JiminP

Use etiquetas cortas <??> Puede guardar algunos bytes.
Multitud el

Respuestas:


22

Comprenda cómo las variables y los espacios en blanco interactúan con las construcciones del lenguaje PHP.

En mi tiempo (ciertamente corto) jugando golf, descubrí que las construcciones del lenguaje PHP (por ejemplo, echo, return, for, while, etc.) se comportan de una manera menos que intuitiva cuando interactúan con variables y espacios en blanco.

echo$v;, por ejemplo, es perfectamente válido, como son return$v;y otras construcciones similares. Estas pequeñas reducciones en el espacio en blanco pueden conducir a una disminución acumulativa significativa en la longitud.

Sin embargo, tenga en cuenta que las variables antes de las construcciones del lenguaje requieren un espacio después, como en el siguiente ejemplo:

foreach($a AS$b){}

Debido a que ASes una construcción de lenguaje, no se requiere un espacio antes de la variable $b, pero si se omitiera el espacio anterior , $aASse analizaría como un nombre de variable y se produciría un error de sintaxis.


3
foreach($a[1]as$b)No necesita espacios en blanco. No se trata de construcciones y variables del lenguaje, sino de espacios entre caracteres de palabras de diferentes palabras.
Titus

1
Otra instancia en la que necesita espacios en blanco es la concatenación de cadenas. Por ejemplo, echo $a+5." text"no funcionará porque PHP piensa que .es un punto decimal para 5. Para que funcione, necesitará agregar un espacio como este:echo $a+5 ." text"
Business Cat

@BasicSunset Esa declaración se puede escribir como echo$a+5," text";. La echoconstrucción le permite pasar múltiples parámetros. donde uno tendría que escribir echo"result: ".($a+5)."!";, puedes escribir echo"result: ",$a+5,"!";. De hecho, pasar múltiples parámetros a una echoes una microoptimización, ya que el código se ejecutará un poco más rápido (ya que no concatena la salida, sino que la envía por separado). Para los desafíos sobre cómo escribir el código más rápido, esto puede ayudar un poquito minúsculo
Ismael Miguel

@IsmaelMiguel Funciona con echo, pero no con print(lo que necesita si lo coloca dentro de una expresión: echoes una construcción pura sin valor de retorno, mientras que print puede actuar como una función: no requiere paréntesis, pero siempre regresa int(1).
Titus

@Titus No dije nada al respecto print.
Ismael Miguel

22

Use cuerdas sabiamente.

Esta respuesta es doble. La primera parte es que al declarar cadenas, puede utilizar la conversión implícita de PHP de constantes desconocidas a cadenas para ahorrar espacio, por ejemplo:

@$s=string;

El @es necesario ignorar las advertencias Esto producirá. En general, terminas con una reducción de un personaje.

es que a veces puede ser efectivo desde el espacio establecer una variable con el nombre de una función de uso frecuente. Normalmente, podrías tener:

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

Pero al jugar al golf, esto se puede acortar fácilmente para:

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

Con solo dos instancias de "preg_match", solo está guardando un solo carácter, pero cuanto más use una función, más espacio ahorrará.


10
@ no es necesario en codegolf; los avisos y advertencias (incluidos E_DEPRECATED) son aceptables
Tito

3
@Titus Pero en PHP, las advertencias se enviarían al archivo estándar, por lo que son necesarias.
brianush1

1
@Titus Creo que puedes suprimirlos en el php.iniarchivo
Stan Strum

12

No siempre necesita escribir cheques condicionales. Por ejemplo, algunos marcos usan esto en la parte superior de sus archivos para bloquear el acceso:

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

O en funciones normales

$value && run_this();

en lugar de

if($value) { run_this(); }

Funciona también en JS
Евгений Новиков

8

Usar sintaxis de matriz corta

Desde PHP 5.4, las matrices se pueden declarar utilizando corchetes (como JavaScript) en lugar de la array()función:

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

Ahorrará cinco bytes.


Pero puede costar bytes si tiene "agujeros" en una matriz asociativa:

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

la desventaja llega un poco más tarde si puede llenar los agujeros con valores "vacíos":

$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);

2
PHP 7.1 también introdujo asignación breve lista: [,$a,$b,$c]=$argv;.
Titus

7

Use $ {0}, $ {1}, $ {2}, ... en lugar de $ a [0], $ a [1], $ a [2], ...

A menos que esté realizando una manipulación de matriz, la mayoría de las referencias a un índice de matriz $a[$i]se pueden reemplazar simplemente $$i. Esto es incluso cierto si el índice es un entero, ya que los enteros son nombres de variables válidos en PHP (aunque los literales requerirán corchetes, por ejemplo ${0}).

Considere la siguiente implementación de la espita 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;);

Esto se puede mejorar en 6 bytes, simplemente reemplazando ambas referencias de matriz $a[$g]con $$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;);

1
Acabo de guardar 3 bytes con eso: escaparate .
Titus

6

Aprenda un gran subconjunto de las funciones de la biblioteca .

La biblioteca de PHP es bastante grande y proporciona un montón de funciones convenientes que pueden acortar en gran medida varias tareas. Podrías buscar cada vez que intentes hacer algo, pero más allá de perder el tiempo, es posible que no encuentres nada que coincida con tu búsqueda en particular. La mejor manera es familiarizarse con la biblioteca y memorizar los nombres de las funciones y lo que hacen.


66
Eso es mucha memorización, especialmente dado el nombre bastante inconsistente de muchas funciones ;-)
Joey

@Joey De acuerdo. Similar a memorizar la biblioteca de Java, excepto que podría decirse que sería menos útil, ya que es más detallado.
Matthew leyó el

3
Encuentro que las funciones más importantes para los desafíos que he encontrado hasta ahora aquí son las funciones de manipulación de cadenas y manipulación de matrices. El uso creativo de esos realmente puede reducir el código.
migimaru

6

Ejecutando funciones dentro de cadenas.

Prueba esto:

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

O prueba esto:

//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

Esto solo funciona con cadenas que usan ""y heredocs (NO confunda con nowdocs).

¡El uso de funciones anidadas solo es posible dentro de heredocs anidados (o se encontrará con errores de análisis)!


you will run into parse errorsNo puedo leerlo yo mismo? ¿Cómo funciona el molesto motor Zend?
Stan Strum

La próxima vez que esté en un argumento de "PHP es un buen lenguaje de programación" , voy a usar esto como un contrapunto. Guau.
primo

@primo ¿Es tan malo? : O
Ismael Miguel

5

diversión con tipos de letra

  • !!$fooconvertirá cualquier valor verdadero a true(o 1en la salida), valores falsos (0, cadena vacía, matriz vacía) a false(o salida vacía)
    Esto rara vez se necesitará en el código de golf, ya que en la mayoría de los casos donde necesita un valor booleano, hay un elenco implícito de todos modos.

  • (int)$foopuede escribirse como $foo|0o foo^0, pero puede necesitar paréntesis.
    Para booleanos y cadenas, $foo*1o +$foopuede usarse para convertir a int.

  • A diferencia de la mayoría de los otros lenguajes, PHP maneja cadenas con valores numéricos como números. Entonces, si tiene una cadena que contiene un número con el que tiene que calcular, simplemente calcule.
  • La otra forma no funciona: para multiplicar cualquier número en una variable 10, puede agregar un cero: *10-> .0. Pero en este caso, PHP tomará el punto como punto decimal y se quejará. (Sin embargo, es diferente si tiene una cantidad variable de ceros en una cadena).
  • Para convertir una matriz en una cadena, use en joinlugar de implode.
    Si no necesita un delimitador, no lo use: join($a)hace lo mismo quejoin('',$a)
  • Incremento de cadenas: la característica más sorprendente de imo es que $s=a;$s++;produce $s=b;. Esto funciona con mayúsculas y minúsculas. $s=Z;$s++;resultados en $s=AA;.
    Esto también funciona con mayúsculas y minúsculas: aZto bA, A1to A2, A9to B0y z99Zto aa00A.
    La disminución no funciona en cadenas. (Y no está encendido NULL).
    De vuelta en PHP 3, $n="001";$n++;producido $n="002";. Estoy un poco triste porque lo quitaron.

Lo que sea que juegue golf: siempre tenga a mano la tabla de precedencia de operadores .


4

Use etiquetas cortas

En código normal, es una buena práctica usar <?phpy ?>. Sin embargo, este no es un código normal: está escribiendo un código de código de golf. En lugar de <?phpescribir <?. En lugar de <?php echoescribir<?= . No escriba ?>al final, es completamente opcional. Si lo necesita ?>por algún motivo (por ejemplo, para generar texto, y de alguna manera es más corto, o algo así, no ponga un punto y coma antes, no es necesario, como ?>implica el punto y coma.

Incorrecto (definitivamente demasiado largo):

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

Correcto:

<?=ucfirst(trim(fgets(STDIN)))?>s!

Con la -rbandera ( que viene gratis ), ni siquiera tienes etiquetas (y no puedes usar ninguna).
Tito

4

bucle a través de cadenas

se puede hacer con 26 bytes o con 24 hasta 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&$bhace un AND bit a bit en los (códigos ascii de) los caracteres en $ay $b
y da como resultado una cadena que tiene la misma longitud que la más corta de $ay $b.


puede usted por favor añadir ord($s[$p++])como alternativa for(;$s+=ord($argv[++$i])%32?:die($s==100););frente for(;$c=$argv[++$i];)$s+=ord($c)%32;echo$s==100;a esta pregunta codegolf.stackexchange.com/questions/116933/...
Jörg Hülsermann

Agregue ~para casos en los que está trabajando solo con dígitos
Jörg Hülsermann

Tenga en cuenta que PHP 7.2 genera advertencias para el ~$cenfoque.
Tito

4

Usar operadores ternarios

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

se puede abreviar a esto:

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

Más corto, ¿eh?


¿"Shorthands condicional"? Mejor diga su nombre real, para que aquellos interesados ​​en más detalles puedan encontrarlo en la documentación: operador ternario .
manatwork

3
La pregunta pide consejos que son algo específicos de PHP. Este es uno incluido en los consejos para todos los idiomas .
Peter Taylor

3
El operador ternario tiene un comportamiento extraño en PHP, si lo anida. a?aa:ab?aba:abb:bevalúa (a?aa:ab)?(aba):(abb)o algo así.
Tito

1
Y comenzando con PHP 5.3, puede omitir el segundo operador: $a?:$bes lo mismo que $a?$a:$b.
Tito

1
@Cyoce se convierte ||en booleano en PHP.
Titus

3

por cualquier otro nombre ... alias de funciones

utilizar ...

  • join en lugar de implode
  • chop en lugar de rtrim ( chopen PERL es diferente!)
  • die en lugar de exit
  • fputs en lugar de fwrite
  • is_int en lugar de is_integer ois_long
  • is_real en lugar de is_float ois_double
  • key_exists en lugar de array_key_exists
  • mysql en lugar de mysql_db_query

... para nombrar los alias más importantes. Echa un vistazo a http://php.net/aliases para más.


Ah ... y ¿Sabías que diefunciona con y sin parámetros? die(1)saldrá del programa con un código de error 1(no estoy completamente seguro de esto; necesita pruebas);diesaldrá con código 0y die("Hello")saldrá con código 0después de imprimir Hello.
Titus

3

Las matrices asociativas se pueden fusionar con el +operador.

En lugar de:

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

Utilizar:

$merged = $a + $b;

Tenga en cuenta que el +operador también funciona con matrices indexadas, pero probablemente no hace lo que desea.


De hecho, con frecuencia es un buen reemplazo, aunque no exactamente el mismo: pastebin.com/seYeaP38
manatwork el

Ah sí, maldita sea, originalmente tenía el título "matrices asociativas ..." y luego lo eliminé. Lo aclararé, gracias.
Alex Howansky

Las matrices numéricas también pueden fusionarse usando +, siempre que los índices sean distintos. Si no lo están, los valores de la primera matriz se sobrescribirán con los de la segunda (al igual que array_merge). La diferencia: +no reordena los índices.
Titus

3

array_flip vs array_search

utilizar

array_flip($array)[$value]

en lugar de

array_search($value,$array)

para guardar 1 byte en matrices donde la aparición de cada valor es única


3

algunos datos interesantes sobre variables variables

Solo tenía que compartirlos (incluso antes de verificar que al menos uno de ellos ayuda al golf):

  • Usar letras: $x=a;$$x=1;$x++;$$x=2;echo"$a,$b";imprime 1,2
    pero otras operaciones aritméticas no funcionan con letras.
  • Como primo mencionó anteriormente , puede usar números puros como nombres de variables:
    $a=1;$$a=5;$a++;$$a=4;${++$a}=3;echo${1},${2},${3};impresiones 543.
  • No solo se puede usar [0-9a-zA-Z_]para nombres de variables, sino CADA cadena: se
    $x="Hello!";$$x="Goodbye.";echo${"Hello!"};imprime Goodbye..
  • Pero: todo menos [a-zA-Z_][a-zA-Z_0-9]* como nombres de variables requiere llaves para uso literal.
  • Sin variables definidas, $$x=1establece ${NULL}, que es lo mismo que ${false}y ${""}.
  • $a=1;$$a=5;no solo establece ${1}, sino también ${true}.

  • uno más, el más extraño que he encontrado hasta ahora: Inténtalo $a=[];$$a=3;echo${[]};. Sí, se imprime 3!

La razón de la mayor parte de esto: los nombres de las variables siempre se evalúan en cadenas.
(Gracias @Christoph por señalar.)
Entonces, lo que obtienes cuando tú printo echola expresión, eso es lo que obtienes como nombre de variable.


1
Los nombres de las variables se convierten en cadenas que explican los últimos tres puntos en su lista. []se convierte en Array: ${[]} = 5;echo $Array;impresiones 5. Estoy bastante seguro de que lo sabes, pero puede que no sea obvio para todos :)
Christoph

@Jeff, arreglé el error tipográfico. Gracias por notarlo.
Tito

2

saltos de línea
si la salida requiere saltos de línea, use un salto de línea físico (1 byte) en lugar de "\n"
Esto también le brinda un posible beneficio para elegir entre comillas simples y dobles.


2

evitar comillas siempre que sea posible

PHP arroja implícitamente palabras desconocidas a cadenas literales.

$foo=foo;es lo mismo que $foo='foo';(suponiendo que foono sea una palabra clave o una constante definida):$foo=echo; no funciona.

PERO: $p=str_pad;hace; y $p(ab,3,c)evalúa aabc .

El uso de literales de cadena sin comillas generará un Aviso para Use of undefined constant; pero eso no se mostrará si usa el valor predeterminado para error_reporting(parámetro CLI -n).


Me acabo de dar cuenta: esta respuesta es un duplicado algo extendido / actualizado de codegolf.stackexchange.com/a/2916/55735 .
Tito

Nota: PHP anterior a 7.2 produjo avisos (que puede oponerse con la -nbandera); 7.2 produce advertencias; versiones posteriores arrojarán errores!
Tito

2

Funciones de flecha en PHP 7.4

PHP 7.4 está en la versión RC2 ahora y esperamos que sea lanzado en aproximadamente 2 meses. La lista de nuevas características está aquí (esta página puede actualizarse cuando se lanza 7.4). En 7.4, finalmente PHP tiene las funciones de flecha, por lo que no solo las respuestas de las funciones pueden ser más cortas ahora, sino que también pasar los cierres a otras funciones también puede ser mucho más corto. Aquí están algunos ejemplos:

Entrada de retorno + 1:

Función anónima (cierre) - 25 bytes - ¡ Pruébelo en línea!

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

Función de flecha - 12 bytes - ¡ Pruébelo en línea!

fn($n)=>$n+1

Multiplique los elementos de la primera entrada (matriz de entradas) por la segunda entrada (int):

Función anónima (cierre) - 72 bytes - ¡ Pruébelo en línea!

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

Función de flecha - 38 bytes - ¡ Pruébelo en línea!

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

¿Notaste eso? $n es accesible en la función interna sin una use $ndeclaración? Sí, esa es una de las características de la función de flecha.


Como nota al margen, no pude hacer que las funciones de flecha funcionen recursivamente (llame a la misma función de flecha dentro de sí misma), porque no podemos darles un nombre y almacenarlas como un cierre en una variable como $fno hace $faccesible dentro de sí mismo (triste ) Entonces este ejemplo no funciona y usar$f en la primera línea causa un error 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"

Pero llamar a una función de flecha dentro de una función de flecha diferente funciona:

$f1=fn($n)=>$n+1;
$f2=fn($n)=>$f1($n-1);
$f1(2) // Returns 3
$f2(2) // Returns 2

¿Qué pasa si en lugar de $f=fn($n)=>$n?$f($n-1):0;ti $f=$F=fn($n)=>$n?$F($n-1):0;? Funcionaría eso? Y luego llamas $(5)como siempre.
Ismael Miguel

@IsmaelMiguel todavía parece arrojar el mismo error. En realidad, puede probar tio.run # php usted mismo ya que Dennis ha actualizado su PHP a 7.4 RC2 hace un tiempo.
Noche2

No puedo hacer que funcione. Parece que solo las variables definidas anteriormente están disponibles.
Ismael Miguel


1

Directamente desreferencia de matrices devueltas de funciones.

Por ejemplo, en lugar de esto:

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

Tu puedes hacer:

echo foo()[$n];

Esto también funciona con métodos:

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

También puede desreferenciar directamente las declaraciones de matriz:

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

1

Usar en end()lugar dearray_pop()

La end()función no solo mueve el puntero interno al final de la matriz, sino que también devuelve el último valor. Tenga en cuenta, por supuesto, que no elimina ese valor, por lo que si no le importa lo que contiene la matriz después, puede usarlo en lugar de array_pop().


1

doble array_flip vs in_array vs array_unique

en este caso especial, un doble array_flip ahorra 10 bytes

($f=array_flip)($k=$f($c)))elimino todos los valores dobles en la matriz y he eliminado esto $c=[],, |in_array($o,$c)y reemplazar array_keys($c)con$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

Versión en línea

en 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

Versión en línea

contra array_unique ahorra 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

Versión en línea

Después de encontrar un error en este programa y la sustitución $x[$i]==$o?:$c[$x[$i]]=$ode ($p=$x[$i])==$o?:$k[$c[$p]=$o]=$pla doble array_flip no era necesario ya


asociativo seguro array_unique. ¡Hurra!
Titus

@Titus He añadido tu sugerencia
Jörg Hülsermann

1

cadenas de intersección

¿Alguna vez ha usado
join("DELIMITER",str_split($s))(31 bytes) o incluso
preg_replace(".","DELIMITER",$s)(32 bytes)
?

Hay algo para eso:

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


Si omite el tercer parámetro, chunk_splitusará\r\n ; eso puede ahorrarle 7 u 8 bytes.

Pero cuidado: chunk_splittambién agrega el delimitador a la cadena,
por lo que es posible que no obtenga exactamente lo que desea.

(Si no proporciona la longitud del fragmento, usará 76. Más bien inusual para el golf de código, pero quién sabe).


Tal vez deberías agregar un ejemplo en combinación con strtrMe encanta esta idea.
Jörg Hülsermann

1

unset () vs INF

En un caso, busque un mínimo en una matriz que pueda usar en lugar de

unset($var[$k]);

$var[$k]=INF;

para guardar 3 bytes


1

str_repeat

En algunos casos, tiene una entrada de caracteres y debe generarlos repetidos con una entrada mayor a cero para cada carácter.

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

(52 bytes) es más corto que

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

o

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

(54 bytes cada uno)

Cómo funciona, por ejemplo, entrada a1b2c1

$zno está establecido (implícito NULL), entonces--$z que no hace nada y es falso;

$c="a", $z="1"y $i=2-> $c.$z="a1"es verdad -> salida"a"

--$z=0; así que establecemos $c="b", $z="2"(y $i=4) -> $c.$z="b2"es veraz -> salida"ab"

--$z=1 -> salida "abb"

--$z=0; así que establecemos $c="c"y $z=1 $c.$z="c1"es salida verdadera"abbc"

--$z=0entonces $c=""y $z=""-> $c.$z=""es falso -> el bucle se rompe


1

Combinando forbucles

Supongamos que tiene un código de la siguiente forma:

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

esto generalmente se puede volver a enrollar de la siguiente forma:

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

donde representa un operador de combinación genérico. Esto generalmente resulta en una reducción en el conteo de bytes, pero probablemente requerirá algo de creatividad. $cond2deberá escribirse para que falle la primera vez.$post1también debe fallar la ejecución la primera vez, aunque puede ser más fácil refactorizar de antemano para que$post1 no esté presente.

Si está trabajando con tres o más bucles anidados, también puede combinar dos primero, y luego combinar eso con otro, y así sucesivamente. Encuentro que en general ha sido más fácil combinar desde adentro hacia afuera.


Como ejemplo, considere la siguiente solución para el fractal de la alfombra H ( 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;

Esto puede reformularse de la siguiente manera:

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&&printpreviene printen la primera iteración y tampoco aumenta $i.

y 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 fallará la primera vez ya que ambas variables no están definidas.


1

Eliminar caracteres en una cadena

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

ahorra 1 personaje en comparación con

str_replace(" ","",$string);

Tenga en cuenta que esto funciona para todas las cadenas (no vacías), no solo los caracteres.
CalculatorFeline

@CalculatorFeline ¿Por qué no debería funcionar para cadenas vacías? No tiene sentido ni este caso.
Jörg Hülsermann

Bueno, la primera versión no funciona ""y no es muy útil de todos modos.
CalculatorFeline

1
@CalculatorFeline Y para este caso, una solución de cero bytes es mucho mejor. No tiene sentido hacer esto de esa manera.
Jörg Hülsermann

3
Falta su ejemplo de unión a ). Y strtr($string,[" "=>""])es aún más corto.
Tito


1

Utilice operadores booleanos en lugar de strtoupper()ystrtolower()

Si está trabajando exclusivamente con cadenas que consisten en caracteres alfabéticos, puede usar operadores booleanos para cambiarlos a mayúsculas o minúsculas con menos pulsaciones de teclas que las funciones integradas de PHP.

Ejemplo:

// 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

Las cosas son un poco más difícil para las cadenas de longitud arbitraria, pero las &y ^los operadores se trunque el resultado a la longitud de la cadena de entrada más corto. Así por ejemplo, si $Wes una cadena de espacios al menos tan larga como cualquier entrada $s, a continuación, ~$W&$ses equivalente a strtoupper($s), y $s|$W^$ses equivalente a strtolower($s)(mientras que $s|$Wpor sí misma producirá una cadena con espacios adicionales a menos $sy $Wson de igual longitud).


0

utilizar funciones obsoletas
Si puede utilizar en lugar de Perl POSIX expresiones regulares sin perder más de 5 bytes en la expresión, el uso erego eregien lugar de preg_match, splito splitien lugar de preg_split.
splitTambién se puede usar como sinónimo deexplode de la mayoría de los delimitadores.

Estas funciones están marcadas como obsoletas y arrojarán E_DEPRECATEDavisos, pero (no puedo encontrar la fuente ahora) Creo que he leído que las advertencias y avisos están bien.


2
¡Cuidado! Estos fueron eliminados en PHP 7.0.
Paraguas
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.