Советы по игре в гольф на PHP


37

Какие общие советы у вас есть для игры в гольф на PHP? Я ищу идеи, которые могут быть применены к проблемам гольф-кода вообще, которые, по крайней мере, несколько специфичны для PHP (например, «удалить комментарии» - это не ответ). Пожалуйста, оставьте один совет за ответ.


Подожди, я делаю это правильно? ... В любом случае, мне действительно интересно это. PHP используется многими людьми и игроками в гольф, но я почти не представляю, как играть в PHP-код.
JiminP

Используйте короткие теги <??> Это может сохранить несколько байтов.
Моб

Ответы:


22

Понять, как переменные и пробелы взаимодействуют с языковыми конструкциями PHP.

В моем (по общему признанию) времени игры в гольф я обнаружил, что языковые конструкции PHP (например, echo, return, for, while и т. Д.) Ведут себя менее интуитивно, когда взаимодействуют с переменными и пробелами.

echo$v;Например, совершенно справедливо, как return$v;и другие подобные конструкции. Эти небольшие сокращения пробелов могут привести к значительному кумулятивному уменьшению длины.

Имейте в виду, однако, что переменные перед языковыми конструкциями требуют пробела после, как в следующем примере:

foreach($a AS$b){}

Поскольку ASэто языковая конструкция, пробел не требуется перед переменной $b, но если пропустить пробел перед ней , в результате $aASэто будет проанализировано как имя переменной и приведет к синтаксической ошибке.


3
foreach($a[1]as$b)не нуждается в пустом пространстве. Речь идет не о языковых конструкциях и переменных, а о пробелах между символами слов разных слов.
Тит

1
Другой случай, когда вам нужны пробелы, - конкатенация строк. Например, echo $a+5." text"не будет работать, потому что PHP считает .десятичную точку для 5. Чтобы это работало, вам нужно добавить пробел, подобный следующему:echo $a+5 ." text"
Business Cat

@BasicSunset Это утверждение может быть записано как echo$a+5," text";. echoКонструкция позволяет передать несколько параметров. где нужно было бы написать echo"result: ".($a+5)."!";, вы можете написать echo"result: ",$a+5,"!";. Фактически, передача нескольких параметров в a echoявляется микрооптимизацией, поскольку код будет работать чуть-чуть быстрее (поскольку вы не объединяете выходные данные, а отправляете их отдельно). Для задач по написанию самого быстрого кода это может помочь крошечным крошечным кусочком.
Исмаэль Мигель

@IsmaelMiguel Он работает с echo, но не с print(который вам нужен, если вы поместите его в выражение: echoэто чистая конструкция без возвращаемого значения, в то время как print может действовать как функция: она не требует скобок, но всегда возвращает int(1).
Титус

@ Титус, о котором я ничего не говорил print.
Исмаэль Мигель

22

Используйте строки с умом.

Этот ответ двоякий. Первая часть заключается в том, что при объявлении строк вы можете использовать неявное преобразование PHP неизвестных констант в строки для экономии места, например:

@$s=string;

@Необходимо переопределить предупреждения этого будет производить. В целом вы получаете сокращение на один символ.

в том, что иногда может быть полезно установить переменную для имени часто используемой функции. Обычно вы можете иметь:

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

Но при игре в гольф это можно легко сократить до:

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

Имея только два экземпляра preg_match, вы сохраняете только один символ, но чем больше вы используете функцию, тем больше места вы сэкономите.


10
@ не нужен в Codegolf; Уведомления и предупреждения (в том числе E_DEPRECATED) являются приемлемыми
Тит

3
@ Titus Но в PHP предупреждения выводятся на стандартный вывод файла, поэтому они необходимы.
brianush1

1
@ Titus Я полагаю, вы можете подавить их в php.iniфайле
Стэн Струм

12

Вам не всегда нужно выписывать условные проверки. Например, некоторые платформы используют это в верхней части своих файлов, чтобы заблокировать доступ:

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

Или в нормальных функциях

$value && run_this();

вместо того

if($value) { run_this(); }

Это работает также в JS
Евгений Новиков

8

Использовать короткий синтаксис массива

Начиная с PHP 5.4, массивы могут быть объявлены с использованием квадратных скобок (как JavaScript) вместо array()функции:

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

Это сэкономит пять байтов.


Но это может стоить байтов, если у вас есть «дыры» в ассоциативном массиве:

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

недостаток наступает чуть позже, если вы можете заполнить отверстия «пустыми» значениями:

$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 также представил краткое назначение списка: [,$a,$b,$c]=$argv;.
Тит

7

Используйте $ {0}, $ {1}, $ {2}, ... вместо $ a [0], $ a [1], $ a [2], ...

Если вы не выполняете манипуляции с массивами, большинство ссылок на индекс массива $a[$i]можно просто заменить $$i. Это даже верно, если индекс является целым числом, поскольку целые числа являются допустимыми именами переменных в PHP (хотя для литералов, например, потребуются скобки ${0}).

Рассмотрим следующую реализацию втулки 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;);

Это может быть улучшена за счет 6 байт, просто заменив обе ссылки на массивы $a[$g]с $$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
Я только что сэкономил 3 байта с этим: витрина .
Тит

6

Изучите большое подмножество функций библиотеки .

Библиотека PHP довольно большая и предоставляет множество удобных функций, которые могут значительно сократить время выполнения различных задач. Вы можете просто искать каждый раз, когда пытаетесь что-то сделать, но, не теряя времени, вы можете не найти ничего, соответствующего вашему конкретному поиску. Лучший способ - просто ознакомиться с библиотекой и запомнить имена функций и то, что они делают.


6
Это много запоминания, особенно учитывая довольно непоследовательное именование целого ряда функций ;-)
Joey

@ Джой Согласен. Сродни запоминанию библиотеки Java, за исключением того, что она, возможно, будет менее полезной, поскольку она более многословна.
Мэтью Читал

3
Я считаю, что наиболее важными функциями для задач, с которыми я сталкивался здесь, являются функции манипуляции со строками и массивами. Творческое использование тех может действительно сократить код.
Мигимару

6

Запуск функций внутри строк.

Попробуй это:

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

Или попробуйте это:

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

Это работает только с использованием строк ""и heredocs (НЕ путайте с nowdocs).

Использование вложенных функций возможно только внутри вложенных heredocs (или вы столкнетесь с ошибками разбора)!


you will run into parse errorsЯ не могу прочитать это сам? Как надоедливый движок Zend соединяет все это
Stan Strum

В следующий раз , когда я буду использовать аргумент «PHP - хороший язык программирования» , я собираюсь использовать это в качестве контрапункта. Вау.
Примо

@primo Это так плохо? : O
Исмаэль Мигель

5

веселье с типами

  • !!$fooпревратит любое истинное значение в true(или 1в выходной), ложные значения (0, пустую строку, пустой массив) в false(или пустой выходной).
    Это редко понадобится в коде Golf, так как в большинстве случаев, когда вам нужен логический тип, есть неявное приведение в любом случае.

  • (int)$fooможет быть записано как $foo|0или foo^0, но может потребоваться скобки.
    Для логических значений и строк, $foo*1или +$fooможет использоваться для приведения к типу int.

  • В отличие от большинства других языков, PHP обрабатывает строки с числовыми значениями в виде чисел. Так что если у вас есть какая-либо строка, содержащая число, которое вы должны вычислить, просто рассчитайте
  • Другой способ не работает: чтобы умножить любое число в переменной на 10, вы можете добавить ноль: *10-> .0. Но в этом случае PHP примет точку как десятичную точку и пожалуется. (Это отличается, хотя, если у вас есть переменное количество нулей в строке.)
  • Чтобы превратить массив в строку, используйте joinвместо implode.
    Если вам не нужен разделитель, не используйте его: join($a)делает то же самое, что иjoin('',$a)
  • Инкрементные строки: самая удивительная особенность imo - то, что $s=a;$s++;производит $s=b;. Это работает с прописными и строчными буквами. $s=Z;$s++;результаты в $s=AA;.
    Это также работает со смешанным регистром: aZto bA, A1to A2, A9to B0и z99Zto aa00A.
    Decrement не работает на строках. (И это не вкл NULL).
    Вернуться в PHP 3, $n="001";$n++;производится $n="002";. Мне немного грустно, что они удалили это.

Что бы вы ни играли в гольф: всегда держите под рукой таблицу приоритетов оператора .


4

Используйте ярлыки

В нормальном коде рекомендуется использовать <?phpи ?>. Однако это не нормальный код - вы пишете код для игры в гольф. Вместо того <?php, чтобы писать <?. Вместо того <?php echo, чтобы писать <?=. Не печатайте ?>в конце - это совершенно необязательно. Если вам ?>по какой-то причине нужно (например, выводить текст, и он как-то короче, или что-то еще), не ставьте точку с запятой перед ним - это не нужно, поскольку ?>подразумевает точку с запятой.

Неверно (определенно слишком долго):

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

Правильный:

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

С -rфлагом ( который поставляется бесплатно ) у вас нет вообще никаких тегов (и вам не разрешено их использовать).
Тит

4

цикл через строки

может быть сделано с 26 байтами или с 24 до 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&$bвыполняет побитовое И для (ascii-кодов) символов в $aи $b
и приводит к строке, которая имеет ту же длину, что и короче $aи $b.


Пожалуйста , вы можете добавить в ord($s[$p++])качестве альтернативного for(;$s+=ord($argv[++$i])%32?:die($s==100););AGAINST for(;$c=$argv[++$i];)$s+=ord($c)%32;echo$s==100;в этом вопросе codegolf.stackexchange.com/questions/116933/...
Йорг Hülsermann

Пожалуйста, добавьте ~для случаев, когда вы работаете только с цифрами
Йорг Хюльсерманн

Обратите внимание, что PHP 7.2 выдает предупреждения для ~$cподхода.
Тит

4

Используйте троичные операторы

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

может быть сокращено до этого:

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

Короче, а?


«Условные сокращения»? Лучше назовите его настоящее имя, чтобы те, кто интересуется более подробной информацией, могли найти его в документации: троичный оператор .
manatwork

3
Вопрос требует советов, которые являются специфическими для PHP. Это входит в советы для всех языков .
Питер Тейлор

3
Тернарный оператор имеет странное поведение в PHP, если вы его вложите. a?aa:ab?aba:abb:bоценивает (a?aa:ab)?(aba):(abb)или что-то в этом роде.
Тит

1
И начиная с PHP 5.3, вы можете опустить второй оператор: так $a?:$bже, как $a?$a:$b.
Тит

1
@Cyoce приводит ||к логическому значению в PHP.
Тит

3

под любым другим именем ... псевдонимы функций

использовать ...

  • join вместо того implode
  • chopвместо rtrim( chopв PERL отличается!)
  • die вместо того exit
  • fputs вместо того fwrite
  • is_intвместо is_integerилиis_long
  • is_realвместо is_floatилиis_double
  • key_exists вместо того array_key_exists
  • mysql вместо того mysql_db_query

... чтобы назвать наиболее важные псевдонимы. Взгляните на http://php.net/aliases для получения дополнительной информации.


Ох ... а знаете ли вы, что dieработает с параметрами и без параметров? die(1)выйдет из программы с кодом ошибки 1(не совсем уверен в этом; нуждается в тестировании); dieвыйдет с кодом 0и die("Hello")выйдет с кодом 0после печати Hello.
Титус

3

Ассоциативные массивы могут быть объединены с +оператором.

Вместо того:

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

Использование:

$merged = $a + $b;

Обратите внимание, что +оператор работает и с индексированными массивами, но, вероятно, не делает то, что вы хотите.


Действительно, зачастую это хорошая замена, хотя и не совсем такая: pastebin.com/seYeaP38
manatwork

Ах да, черт возьми, у меня изначально было название «ассоциативные массивы ...», а затем я удалил его. Я уточню, спасибо.
Алекс Хованский

числовые массивы также могут быть объединены с использованием +, если индексы различны. Если это не так, значения из первого массива будут перезаписаны значениями из второго (точно так же как array_merge). Разница: +не переупорядочивать индексы.
Тит

3

array_flip vs array_search

использование

array_flip($array)[$value]

вместо того

array_search($value,$array)

сохранить 1 байт в массивах, где уникальность каждого значения


3

некоторые интересные факты о переменных переменных

Я просто должен был поделиться ими (даже прежде чем я убедился, что хотя бы один из них помогает в игре в гольф):

  • Используйте буквы: $x=a;$$x=1;$x++;$$x=2;echo"$a,$b";печатает, 1,2
    но другие арифметические операции не работают с буквами.
  • Как уже упоминалось выше , в качестве имен переменных вы можете использовать чистые числа:
    $a=1;$$a=5;$a++;$$a=4;${++$a}=3;echo${1},${2},${3};print 543.
  • Вы можете использовать не только [0-9a-zA-Z_]имена переменных, но и КАЖДУЮ строку:
    $x="Hello!";$$x="Goodbye.";echo${"Hello!"};print Goodbye..
  • Но: все, кроме [a-zA-Z_][a-zA-Z_0-9]* имен переменных требует фигурных скобок для буквального использования.
  • Если переменные не определены, $$x=1устанавливает ${NULL}, что совпадает с ${false}и ${""}.
  • $a=1;$$a=5;не только установить ${1}, но и ${true}.

  • еще один, самый странный, который я нашел до сих пор: попробуй $a=[];$$a=3;echo${[]};. Да, это печатает 3!

Причина большинства из этого: имена переменных всегда оцениваются как строки.
(Спасибо @Christoph за указание.)
Итак, все, что вы получаете, когда вы printили echoвыражение, это то, что вы получаете как имя переменной.


1
Имена переменных преобразуются в строки, которые объясняют последние три пункта в вашем списке. []преобразует в Array: ${[]} = 5;echo $Array;печать 5. Я почти уверен, что вы это знаете, но это может быть не очевидно для всех :)
Кристоф

@ Джефф Я исправил опечатку. Спасибо, что заметили.
Тит

2

разрывы строк,
если вывод требует разрывов строк, используйте физический разрыв строки (1 байт) вместо этого. "\n"
Это также дает вам возможное преимущество выбора между одинарными и двойными кавычками.


2

по возможности избегайте кавычек

PHP неявно переводит неизвестные слова в буквальные строки.

$foo=foo;аналогично $foo='foo';(при условии, что fooэто не ключевое слово или не определенная константа):$foo=echo; не работает.

НО: $p=str_pad;делает; и $p(ab,3,c)оцениваетabc .

Использование строковых литералов без кавычек даст уведомление для Use of undefined constant; но это не покажет, если вы используете значение по умолчанию для error_reporting(параметр CLI -n).


Я только заметил: этот ответ является несколько расширенным / обновленным дубликатом codegolf.stackexchange.com/a/2916/55735 .
Тит

Примечание: PHP до 7.2 дал уведомления (которые вы можете распечатать с -nфлагом); 7.2 дает предупреждения; более поздние версии будут выбрасывать ошибки!
Тит

2

Функции стрелок в PHP 7.4

PHP 7.4 находится на версии RC2 и, надеюсь, выйдет примерно через 2 месяца. Список новых функций здесь (эта страница может быть обновлена ​​после выхода 7.4). В 7.4, наконец, PHP получил функции стрелок, так что теперь не только ответы на функции могут быть короче, но и передача замыканий другим функциям также может быть намного короче. Вот несколько примеров:

Вернуть вход + 1:

Анонимная функция (закрытие) - 25 байт - попробуйте онлайн!

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

Функция стрелки - 12 байт - попробуйте онлайн!

fn($n)=>$n+1

Умножьте элементы первого ввода (массива целых) на второй ввод (int):

Анонимная функция (закрытие) - 72 байта - попробуйте онлайн!

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

Функция стрелки - 38 байт - попробуйте онлайн!

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

Вы заметили, что $nдоступно во внутренней функции безuse $n оператора? Да, это одна из функций стрелок.


В качестве примечания, я не мог заставить функции стрелок работать рекурсивно (вызывать одну и ту же функцию стрелок внутри себя), потому что мы не можем дать им имя и сохранить их как замыкание в переменной, как $fне делает $fдоступным внутри себя (печально) ). Так что этот пример не работает и использование $fв первой строке вызывает фатальную ошибку:

$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"

Но вызов функции стрелки с использованием другой функции стрелки работает:

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

Что если вместо $f=fn($n)=>$n?$f($n-1):0;тебя это сделать $f=$F=fn($n)=>$n?$F($n-1):0;? Будет ли это работать? И тогда вы звоните, $(5)как обычно.
Исмаэль Мигель

@IsmaelMiguel все равно кажется, что выдает ту же ошибку. На самом деле вы можете попробовать tio.run # php, так как Деннис недавно обновил свой PHP до 7.4 RC2.
ночь2

Не могу заставить его работать. Кажется, что доступны только переменные, определенные ранее .
Исмаэль Мигель


1

Непосредственно разыменование массивов, возвращаемых из функций.

Например, вместо этого:

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

Ты можешь сделать:

echo foo()[$n];

Это работает и с методами:

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

Вы также можете напрямую разыменовать объявления массива:

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

1

Используйте end()вместоarray_pop()

end()Функция не просто перемещает внутренний указатель на конец массива, она также возвращает последнее значение. Заметьте, конечно, что это значение не удаляется , поэтому, если вам все равно, что массив содержит впоследствии, вы можете использовать его вместо array_pop().


1

двойной массив_флип против in_array против массив_unique

в этом особом случае двойной array_flip сохраняет 10 байт

($f=array_flip)($k=$f($c)))удалить все двойные значения в массиве, и я удалил это $c=[],, |in_array($o,$c)и заменить array_keys($c)на$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

Онлайн версия

против

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

Онлайн версия

против array_unique экономит 2 байта

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

Онлайн версия

Обнаружив ошибку в этой программе и замену $x[$i]==$o?:$c[$x[$i]]=$oк ($p=$x[$i])==$o?:$k[$c[$p]=$o]=$pдвойному array_flip не надо было больше


ассоциативный сейф array_unique. Ура!
Тит

@Titus Я добавил ваше предложение
Йорг Хюльсерманн

1

пересекающиеся строки

Вы когда-либо использовали
join("DELIMITER",str_split($s))(31 байт) или даже
preg_replace(".","DELIMITER",$s) (32 байт)
?

Для этого есть встроенное:

Попробуйте chunk_split($s,1,"DELIMITER")(29 байт).


Если вы пропустите третий параметр, chunk_splitбудете использовать \r\n; это может сэкономить вам 7 или 8 байт.

Но будьте осторожны: chunk_splitтакже добавляет разделитель в строку,
так что вы можете не получить именно то, что вы хотите.

(Если вы не предоставите длину чанка, он будет использовать 76. Довольно необычно для кода гольф, но кто знает.)


Может быть, вы должны добавить пример в сочетании с strtrЯ люблю эту идею.
Йорг Хюльсерманн

1

unset () против INF

В случае поиска минимума в массиве вы можете использовать вместо

unset($var[$k]);

$var[$k]=INF;

сохранить 3 байта


1

str_repeat

В некоторых случаях у вас есть ввод символов, и вы должны выводить их повторно с вводом большего нуля для каждого символа.

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

(52 байта) короче

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

или

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

(54 байта каждый)

Как это работает, например, ввод a1b2c1

$zне установлен (неявный NULL), поэтому --$zничего не делает и является ложным;

$c="a", $z="1"И $i=2-> $c.$z="a1"это truthy -> выход"a"

--$z=0; поэтому мы устанавливаем $c="b", $z="2"$i=4) -> $c.$z="b2"правдиво -> вывод"ab"

--$z=1 -> вывод "abb"

--$z=0; поэтому мы установили $c="c"и $z=1 $c.$z="c1"верно вывод"abbc"

--$z=0так $c=""и $z=""-> $c.$z=""ложь -> разрывы цикла


1

Объединяя for петель

Предположим, у вас есть код следующей формы:

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

это обычно может быть повторно свернуто в следующей форме:

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

где представляет общий оператор объединения. Это обычно приводит к уменьшению количества байтов, но, вероятно, потребует некоторой креативности. $cond2нужно будет написать так, чтобы он потерпел неудачу в первый раз. $post1также не может быть выполнен в первый раз, хотя может быть проще выполнить рефакторинг заранее, чтобы$post1 его не было.

Если вы работаете с тремя или более вложенными циклами, вы также можете сначала объединить два, а затем объединить это с другим и так далее. Я считаю, что в целом легче было комбинировать изнутри наружу.


В качестве примера рассмотрим следующее решение фрактала с H-ковром ( 97 байт ):

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;

Это можно переформулировать следующим образом:

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предотвращает printна первой итерации, а также не увеличивает$i .

и наконец ( 93 байта ):

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 потерпит неудачу в первый раз, так как обе переменные не определены.


1

Удаление символов в строке

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

сохраняет 1 символ по сравнению с

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

Обратите внимание, что это работает для всех (непустых) строк, а не только для символов.
CalculatorFeline

@CalculatorFeline Почему это не должно работать для пустых строк? Нет смысла ни в этом случае.
Йорг Хюльсерманн

Ну, первая версия не работает ""и в любом случае она не очень полезна.
CalculatorFeline

1
@CalculatorFeline И для этого случая решение с нулевым байтом намного лучше. Нет смысла делать это таким образом.
Йорг Хюльсерманн

3
В вашем примере присоединения отсутствует ). И strtr($string,[" "=>""])еще короче.
Тит


1

Используйте логические операторы вместо strtoupper() иstrtolower()

Если вы работаете исключительно со строками, состоящими из букв алфавита, вы можете использовать логические операторы, чтобы изменить их на прописные или строчные с меньшим количеством нажатий клавиш, чем встроенные функции PHP.

Пример:

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

Вещи немного сложнее для строк произвольной длины, но &и ^операторы усечения результат длины короткой строки ввода. Так, например, если $Wэто строка пробелов, по крайней мере такая же длинная, как любой ввод $s, то ~$W&$sона эквивалентна strtoupper($s)и $s|$W^$sэквивалентна strtolower($s)(тогда как $s|$Wсама по себе создаст строку с дополнительными пробелами, если $sи $Wони не имеют равную длину)


0

используйте устаревшие функции
Если вы можете использовать POSIX вместо регулярного выражения PERL, не тратя больше 5 байт на выражение, используйте eregили eregiвместо preg_match, splitили splitiвместо preg_split.
splitМожет также использоваться как синонимexplode для большинства разделителей.

Эти функции помечены как устаревшие и будут выдавать E_DEPRECATEDуведомления, но (не могу найти источник сейчас) Я думаю, что я прочитал, что предупреждения и уведомления в порядке.


2
Осторожно! Они были удалены в PHP 7.0.
Зонт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.