PHP에서의 골프 팁


37

PHP에서 골프를 할 때 어떤 일반적인 팁이 있습니까? PHP에 일반적으로 다소 특정한 코드 골프 문제에 적용될 수있는 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다). 답변 당 하나의 팁을 게시하십시오.


잠깐, 내가 잘하고 있니? ... 어쨌든, 나는 이것에 대해 정말로 궁금합니다. PHP는 많은 사람들과 골퍼들이 사용하지만 PHP 코드를 어떻게 골프를 타는 지 잘 모릅니다.
JiminP 2016 년

짧은 태그 사용 <??> 몇 바이트를 절약 할 수 있습니다.
Mob

답변:


22

변수와 공백이 PHP의 언어 구성과 어떻게 상호 작용하는지 이해하십시오.

필자의 짧은 골프에서 변수와 공백과 상호 작용할 때 PHP의 언어 구성 (예 : echo, return, for, while 등)이 직관적이지 않은 방식으로 작동한다는 것을 알았습니다.

echo$v;예를 들어, return$v;다른 유사한 구성과 마찬가지로 완벽하게 유효합니다 . 공백의 이러한 작은 감소는 길이의 상당한 누적 감소로 이어질 수 있습니다.

그러나 다음 예제와 같이 언어 구성 이전의 변수 에는 공백이 필요 하다는 점에 유의하십시오 .

foreach($a AS$b){}

때문에 AS언어 구조이며, 공간이 변수 전에 필요하지 않습니다 $b,하지만 하나의 공간을 생략한다면 그것은 이전 의 결과로, $aAS이 구문 오류에 변수 이름과 리드로 분석된다.


3
foreach($a[1]as$b)공백이 필요 없습니다. 이것은 언어 구성과 변수가 아니라 다른 단어의 단어 문자 사이의 공백에 관한 것입니다.
Titus

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,"!";. 실제로 여러 매개 변수를 하나에 전달하는 echo것은 마이크로 최적화입니다. 코드가 조금 더 빨리 실행되므로 (출력을 연결하지 않고 별도로 보내므로). 가장 빠른 코드를 작성하는 데 어려움이 있으면 작은 작은 조각에 도움이 될 수 있습니다.
Ismael Miguel

@IsmaelMiguel 작동 echo하지만 다음 과는 작동 하지 않습니다. print(표현식에 넣는 경우 필요합니다. echo반환 값이없는 순수한 구조 이지만 함수로 작동 print 할 수 있습니다 . 괄호가 필요하지 않지만 항상을 반환합니다 int(1).
Titus

@Titus 나는 아무 말도하지 않았다 print.
Ismael Miguel

22

현명하게 끈을 사용하십시오.

이 답변은 두 가지입니다. 첫 번째 부분은 문자열을 선언 할 때 공간을 절약하기 위해 PHP의 알 수없는 상수를 문자열로 암시 적으로 변환하여 활용할 수 있다는 것입니다.

@$s=string;

@경고가 무시되도록해야합니다. 전반적으로 한 문자를 줄입니다.

때로는 자주 사용하는 함수의 이름으로 변수를 설정하는 것이 공간적으로 효과적 일 수 있습니다. 일반적으로 다음이있을 수 있습니다.

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

그러나 골프를 타면 다음과 같이 쉽게 단축 할 수 있습니다.

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

"preg_match"인스턴스가 두 개만 있으면 단일 문자 만 저장하지만 함수를 많이 사용할수록 더 많은 공간을 절약 할 수 있습니다.


10
codegolf에는 @가 필요하지 않습니다. 통지 및 경고 (포함 E_DEPRECATED)가 허용됩니다
Titus

3
@Titus 그러나 PHP에서는 경고가 표준 파일 출력으로 출력되므로 필요합니다.
brianush1

1
@Titus php.ini파일 에서 억제 할 수 있다고 생각 합니다
Stan Strum

12

항상 조건부 검사를 작성할 필요는 없습니다. 예를 들어, 일부 프레임 워크는 파일 맨 위에서 이것을 사용하여 액세스를 차단합니다.

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

또는 정상적인 기능

$value && run_this();

대신에

if($value) { run_this(); }

JS에서도 작동합니다
Евгений Новиков

8

짧은 배열 구문 사용

PHP 5.4부터 배열 대신 array()함수 대신 JavaScript와 같이 대괄호를 사용하여 배열을 선언 할 수 있습니다 .

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

5 바이트가 절약됩니다.


그러나 연관 배열에 "구멍"이 있으면 바이트가 필요할 수 있습니다.

$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;.
Titus

7

$ a [0], $ a [1], $ a [2], ... 대신 $ {0}, $ {1}, $ {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;);

이는 두 배열 참조 $a[$g]$$g대신 대신 하여 6 바이트 개선 할 수 있습니다 .

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
방금 showcase 와 함께 3 바이트를 저장했습니다 .
Titus

6

라이브러리 함수의 큰 부분 집합을 배우십시오 .

PHP의 라이브러리는 매우 커서 다양한 작업을 크게 단축시킬 수있는 편리한 기능을 제공합니다. 무언가를 시도 할 때마다 검색 할 수 있지만 시간을 넘어서서 특정 검색과 일치하는 항목을 찾지 못할 수도 있습니다. 가장 좋은 방법은 라이브러리에 익숙해지고 함수 이름과 기능을 암기하는 것입니다.


6
그것은 특히 많은 함수의 이름이 일관성이없는 것을 감안할 때 많은 암기입니다. ;-)
Joey

@Joey Agreed. 자바 라이브러리를 외우는 것과 비슷하지만 더 장황하기 때문에 유용하지 않을 것입니다.
Matthew 읽기

3
지금까지 내가 겪었던 과제에 가장 중요한 기능은 문자열 조작 및 배열 조작 기능이라는 것을 알았습니다. 그것들을 창의적으로 사용하면 실제로 코드를 줄일 수 있습니다.
migimaru

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와 혼동하지 마십시오).

중첩 함수 사용은 중첩 heredoc 내에서만 가능합니다 (또는 구문 분석 오류가 발생합니다)!


you will run into parse errors직접 읽을 수 없습니까? 성가신 젠드 엔진은 이것을 어떻게 결합 시키는가
Stan Strum

다음에 "PHP는 좋은 프로그래밍 언어입니다"라는 논거에 들어설 때, 나는 이것을 반대 지점으로 사용할 것입니다. 와.
primo

@primo 그게 나쁜가요? : O
Ismael Miguel

5

타입 캐스트와 재미

  • !!$foo진실 값을 true(또는 1출력으로), 거짓 값 (0, 빈 문자열, 빈 배열)을 false(또는 빈 출력)으로 바꿉니다
    . 코드 골프에서는 거의 필요하지 않습니다. 대부분의 경우 부울이 필요한 경우에는 어쨌든 암시 적 캐스트.

  • (int)$foo$foo|0또는 로 쓸 수 foo^0있지만 괄호가 필요할 수 있습니다.
    부울 및 문자열의 경우 $foo*1또는 +$fooint로 캐스트하는 데 사용할 수 있습니다.

  • 대부분의 다른 언어와 달리 PHP는 숫자 값을 숫자로 사용하여 문자열을 처리합니다. 따라서 계산 해야하는 숫자가 포함 된 문자열이 있으면 계산하십시오.
  • 다른 방법으로는 작동 하지 않습니다 . 변수의 숫자에을 곱하려면 100을 추가 할 수 있습니다 *10.-> .0. 그러나이 경우 PHP는 점을 소수점으로 가져 가서 불평합니다. (문자열에 가변적 인 양의 0이 있으면 다릅니다.)
  • 배열을 문자열로 바꾸려면 join대신을 사용하십시오 implode.
    당신은 구분 기호를 필요로하지는 경우, 그것을 사용하지는 : join($a)같은 않습니다join('',$a)
  • 문자열 증가 : 가장 놀라운 기능 $s=a;$s++;$s=b;. 대문자와 소문자로 작동합니다. $s=Z;$s++;결과 $s=AA;.
    대소 문자를 혼합하여 사용할 수도 있습니다 : aZto bA, A1to A2, A9to B0z99Zto aa00A. 문자열
    에서는 감소가 작동 하지 않습니다 . (그리고 그것은 아닙니다 NULL).
    돌아 가기 PHP 3, $n="001";$n++;생산 $n="002";. 나는 그들이 그것을 제거 조금 슬프다.

어떤 골프를하든 항상 운전자 우선 순위 테이블갖습니다 .


4

짧은 태그 사용

일반적인 코드에서는 <?phpand 를 사용하는 것이 좋습니다 ?>. 그러나 이것은 정상적인 코드 가 아닙니다 . 코드 골프 코드를 작성하고 있습니다. 대신을 <?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비트 단위와 (의 아스키 코드)의 문자에 수행 $a$b
의 짧은 같은 길이가 문자열의 결과 $a$b.


당신은 추가하시기 바랍니다 수있는 ord($s[$p++])대안 for(;$s+=ord($argv[++$i])%32?:die($s==100););에 대한 for(;$c=$argv[++$i];)$s+=ord($c)%32;echo$s==100;이 질문에 codegolf.stackexchange.com/questions/116933/...
요 르그 Hülsermann에게

~숫자로만 작업하는 사례를 추가하십시오
Jörg 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)합니다.
Titus

1
그리고 PHP 5.3로 시작, 당신은 두 번째 연산자를 생략 할 수 있습니다 : $a?:$b와 동일합니다 $a?$a:$b.
Titus

1
@Cyoce ||는 PHP에서 부울로 캐스팅됩니다.
Titus

3

다른 이름으로 ... 함수 별칭

사용하다 ...

  • join 대신에 implode
  • chop대신 rtrim( chopPERL은 다릅니다!)
  • die 대신에 exit
  • fputs 대신에 fwrite
  • is_intis_integer또는 대신is_long
  • is_realis_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.
Titus

3

연관 배열은 +연산자 와 병합 될 수 있습니다 .

대신에:

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

사용하다:

$merged = $a + $b;

메모 +뿐만 아니라 인덱스 배열과 운영자 작업을하지만, 아마도 당신이 원하는 것을하지 않습니다.


사실, 정확히 같은 것은 아니지만 대체로 좋은 대체품입니다. pastebin.com/seYeaP38
manatwork

아 맞아, 나는 원래 "associative arrays ..."라는 제목을 가지고 그것을 제거했다. 감사하겠습니다.
Alex Howansky

+인덱스가 구별되는 한을 사용하여 숫자 형 배열을 병합 할 수도 있습니다 . 그렇지 않은 경우 첫 번째 배열의 값을 array_merge와 같이 두 번째 배열의 값으로 덮어 씁니다. 차이점 +은 인덱스를 재정렬하지 않습니다.
Titus

3

array_flip과 array_search

사용하다

array_flip($array)[$value]

대신에

array_search($value,$array)

각 값의 발생이 고유 한 배열에 1 바이트 저장


3

변수 변수 에 대한 몇 가지 흥미로운 사실

난 그냥 (I도 전에 공유했다 확인 중 적어도 하나는 골프를하는 데 도움이) :

  • 문자 사용 : $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};인쇄 543.
  • [0-9a-zA-Z_]변수 이름뿐만 아니라 모든 문자열에 사용할 수 있습니다 :
    $x="Hello!";$$x="Goodbye.";echo${"Hello!"};prints Goodbye..
  • 그러나 [a-zA-Z_][a-zA-Z_0-9]*변수 이름을 제외한 모든 것은 문자 그대로 사용하기 위해 중괄호가 필요합니다.
  • 변수가 정의되지 않은 경우 $$x=1sets ${NULL}${false}and와 동일합니다 ${""}.
  • $a=1;$$a=5;뿐만 아니라 설정하지 ${1}뿐만 아니라 ${true}.

  • 하나 더, 내가 지금까지 찾은 가장 이상한 것 : 시도 $a=[];$$a=3;echo${[]};. 예, 인쇄합니다 3!

대부분의 이유 : 변수 이름은 항상 문자열로 평가됩니다.
(
나를 지적 해준 @Christoph에게 감사한다.) 그래서, 당신 print이나 당신 echo이 표현할 때마다 그것이 변수 이름으로 얻는 것입니다.


1
변수 이름은 목록의 마지막 세 지점을 설명하는 문자열로 변환됩니다. []로 변환 Array: ${[]} = 5;echo $Array;인쇄합니다 5. 나는 당신이 그것을 알고 있다고 확신하지만 모든 사람에게 분명하지는 않을 것입니다 :)
Christoph

@ Jeff는 오타를 수정했습니다. 알아 주셔서 감사합니다.
Titus

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 의 다소 확장 / 업데이트 된 복제본입니다 .
Titus

참고 : 7.2 이전의 PHP는 알림을 표시했습니다 ( -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 배열)에 두 번째 입력 (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접근 withing에 자신을 (슬픈 ). 따라서이 예제 는 작동하지 않으며$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)평소와 같이 전화하십시오 .
Ismael Miguel

@IsmaelMiguel 여전히 같은 오류가 발생합니다. Dennis가 한동안 PHP를 7.4 RC2로 업데이트 했기 때문에 실제로 tio.run # php를 직접 시도해 볼 수 있습니다 .
Night2

작동하지 않습니다. 이전 에 정의 된 변수 만 사용 가능한 것 같습니다 .
이스마엘 미겔


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

double array_flip vs in_array vs array_unique

특별한 경우 double 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

온라인 버전

이 프로그램에서 버그를 발견하고 더 이상 double array_flip으로 교체 $x[$i]==$o?:$c[$x[$i]]=$o($p=$x[$i])==$o?:$k[$c[$p]=$o]=$p필요가 없었습니다.


연관 안전 array_unique. 예이!
Titus

@Titus 나는 당신의 제안을 추가했습니다
Jörg Hülsermann

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이 아이디어를 좋아하는 것과 함께 예제를 추가해야 할 수도 있습니다 .
Jörg Hülsermann 2016 년

1

unset () 대 INF

배열에서 최소값을 검색하는 경우 대신 사용할 수 있습니다

unset($var[$k]);

$var[$k]=INF;

3 바이트 절약


1

str_repeat

경우에 따라 문자를 입력 할 수 있으며 각 문자마다 0보다 큰 입력을 반복하여 출력해야합니다.

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"입니다 truthy -> 출력"ab"

--$z=1 -> 출력 "abb"

--$z=0; 그래서 우리는 설정 $c="c"하고 $z=1 $c.$z="c1"진정한 출력입니다"abbc"

--$z=0그렇게 $c=""하고 $z=""-> $c.$z=""입니다 falsy -> 루프 나누기


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&&printprint첫 번째 반복을 방지 하고 증가하지 않습니다 $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 왜 빈 문자열에 대해 작동하지 않아야합니까? 이건 말도 안 돼
Jörg Hülsermann 2016 년

글쎄, 첫 번째 버전은 작동하지 않으며 ""어쨌든별로 유용하지 않습니다.
CalculatorFeline

1
@CalculatorFeline이 경우 0 바이트 솔루션이 훨씬 좋습니다. 그렇게하는 것은 말이되지 않습니다.
Jörg Hülsermann 2016 년

3
조인 예제에가 없습니다 ). 그리고 strtr($string,[" "=>""])더 짧습니다.
Titus


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

임의 길이의 문자열에는 약간 까다 롭지 만 &and ^연산자는 결과를 짧은 입력 문자열의 길이로 자릅니다. 그래서 예를 들어,이 $W긴 입력 한 적어도 자리의 문자열이 $s다음 ~$W&$s에 상당 strtoupper($s)하고, $s|$W^$s동일하다 strtolower($s)(반면 $s|$W않는 공간 부가 된 문자열을 생성한다 자체 $s$W동일한 길이이다).


0

사용되지 않는 기능을 사용
하면 표현 사용에 5 개 이상의 바이트를 낭비하지 않고 대신 PERL 정규식의 POSIX를 사용할 수있는 경우 eregeregi대신 preg_match, splitspliti대신 preg_split의. 대부분의 구분 기호
splitexplode대한 동의어로 사용할 수도 있습니다 .

이 기능은 더 이상 사용되지 않는 것으로 표시되어 E_DEPRECATED알림을 표시 하지만 (지금 소스를 찾을 수 없음) 경고와 알림이 정상임을 읽은 것 같습니다.


2
조심해! 이것들은 PHP 7.0에서 제거되었습니다.
우산
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.