Mẹo chơi gôn trong PHP


37

Bạn có lời khuyên chung nào cho việc chơi golf trong PHP? Tôi đang tìm kiếm những ý tưởng có thể được áp dụng cho các vấn đề về mã golf nói chung ít nhất là cụ thể đối với PHP (ví dụ: "xóa bình luận" không phải là một câu trả lời). Xin vui lòng gửi một lời khuyên cho mỗi câu trả lời.


Đợi đã, tôi đang làm đúng không? ... Dù sao, tôi thực sự tò mò về điều này. PHP được sử dụng bởi nhiều người và người chơi golf, nhưng tôi gần như không biết làm thế nào để chơi mã PHP.
JiminP

Sử dụng các thẻ ngắn <??> Nó có thể lưu một vài byte.
Mob

Câu trả lời:


22

Hiểu cách các biến và khoảng trắng tương tác với các cấu trúc ngôn ngữ của PHP.

Trong thời gian chơi golf (thừa nhận ngắn), tôi đã thấy rằng các cấu trúc ngôn ngữ của PHP (ví dụ: echo, return, for, while, v.v.) hành xử theo cách kém trực quan hơn khi tương tác với các biến và khoảng trắng.

echo$v;, ví dụ, là hoàn toàn hợp lệ, như return$v;và các cấu trúc tương tự khác. Những giảm nhỏ trong khoảng trắng có thể dẫn đến giảm chiều dài tích lũy đáng kể.

Mặc dù vậy, hãy ghi nhớ rằng các biến đó trước khi cấu trúc ngôn ngữ yêu cầu một khoảng trắng sau, như trong ví dụ sau:

foreach($a AS$b){}

Bởi vì ASlà một cấu trúc ngôn ngữ, không cần một khoảng trắng trước biến $b, nhưng nếu người ta bỏ qua khoảng trắng trước nó , dẫn đến $aAS, điều này sẽ được phân tích thành tên biến và dẫn đến lỗi cú pháp.


3
foreach($a[1]as$b)không cần khoảng trắng. Đây không phải là về cấu trúc ngôn ngữ và các biến, mà là khoảng trắng giữa các ký tự từ của các từ khác nhau.
Tít

1
Một trường hợp khác mà bạn cần khoảng trắng là nối chuỗi. Chẳng hạn, echo $a+5." text"sẽ không hoạt động vì PHP nghĩ rằng đó .là dấu thập phân cho 5. Để làm cho nó hoạt động, bạn sẽ cần thêm một không gian như thế này:echo $a+5 ." text"
Business Cat

@BasicSunset Câu nói đó có thể được viết là echo$a+5," text";. Cấu echotrúc cho phép bạn vượt qua nhiều tham số. nơi mà một người sẽ phải viết echo"result: ".($a+5)."!";, bạn có thể viết echo"result: ",$a+5,"!";. Trong thực tế, việc truyền nhiều tham số cho một echolà tối ưu hóa vi mô, vì mã sẽ chạy nhanh hơn một chút (vì bạn không nối đầu ra, nhưng gửi riêng nó). Đối với những thách thức về việc viết mã nhanh nhất, điều này có thể giúp một chút nhỏ xíu nhỏ xíu.
Ismael Miguel

@IsmaelMiguel Nó hoạt động với echo, nhưng không phải với print(mà bạn cần nếu bạn đặt nó bên trong một biểu thức: echolà một cấu trúc tinh khiết không có giá trị trả về khi print có thể đóng vai trò như một chức năng: nó đòi hỏi không có dấu ngoặc đơn, nhưng nó luôn luôn trở lại int(1).
Tít

@Titus Tôi không nói gì cả print.
Ismael Miguel

22

Sử dụng dây một cách khôn ngoan.

Câu trả lời này là hai lần. Phần đầu tiên là khi khai báo các chuỗi, bạn có thể sử dụng chuyển đổi ngầm định của các hằng số chưa biết thành chuỗi để tiết kiệm không gian, ví dụ:

@$s=string;

Điều @cần thiết là ghi đè các cảnh báo này sẽ tạo ra. Nhìn chung, bạn kết thúc với việc giảm một ký tự.

đôi khi, có thể là không gian hiệu quả để đặt một biến thành tên của một hàm thường được sử dụng. Thông thường, bạn có thể có:

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

Nhưng khi chơi golf, điều này có thể được rút ngắn dễ dàng thành:

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

Chỉ với hai trường hợp "preg_match", bạn chỉ lưu một ký tự, nhưng bạn càng sử dụng một chức năng, bạn sẽ càng tiết kiệm được nhiều dung lượng.


10
@ không cần thiết trong codegolf; thông báo và cảnh báo (bao gồm E_DEPRECATED) có thể được chấp nhận
Titus

3
@Titus Nhưng trong PHP, các cảnh báo sẽ xuất ra đầu ra tệp tiêu chuẩn, vì vậy chúng là cần thiết.
brianush1

1
@Titus Tôi tin rằng bạn có thể chặn chúng trong php.initệp
Stan Strum

12

Bạn không cần phải luôn luôn viết ra séc có điều kiện. Ví dụ: một số khung sử dụng phần này ở đầu tệp của chúng để chặn truy cập:

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

Hoặc trong các chức năng bình thường

$value && run_this();

thay vì

if($value) { run_this(); }

Nó cũng hoạt động trong JS
Евгений Новиков

8

Sử dụng cú pháp mảng ngắn

Kể từ PHP 5.4, các mảng có thể được khai báo bằng dấu ngoặc vuông (giống như JavaScript) thay vì array()hàm:

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

Nó sẽ tiết kiệm năm byte.


Nhưng nó có thể tốn byte nếu bạn có "lỗ hổng" trong một mảng kết hợp:

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

nhược điểm sẽ xuất hiện muộn hơn một chút nếu bạn có thể lấp đầy các lỗ hổng bằng các giá trị "trống":

$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 cũng giới thiệu bài tập danh sách ngắn : [,$a,$b,$c]=$argv;.
Tít

7

Sử dụng $ {0}, $ {1}, $ {2}, ... thay vì $ a [0], $ a [1], $ a [2], ...

Trừ khi bạn đang thực hiện thao tác mảng, hầu hết các tham chiếu đến chỉ mục mảng $a[$i]có thể được thay thế bằng cách đơn giản $$i. Điều này thậm chí đúng nếu chỉ mục là một số nguyên, vì số nguyên là tên biến hợp lệ trong PHP (mặc dù bằng chữ sẽ yêu cầu dấu ngoặc, ví dụ ${0}).

Hãy xem xét việc thực hiện sau đây của spigot 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;);

Điều này có thể được cải thiện bởi 6 byte, chỉ đơn giản bằng cách thay thế cả hai tham chiếu mảng $a[$g]bằng $$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
Tôi chỉ lưu 3 byte với điều đó: showcase .
Tít

6

Tìm hiểu một tập hợp con lớn của các chức năng thư viện .

Thư viện của PHP khá lớn và cung cấp rất nhiều chức năng tiện lợi có thể rút ngắn đáng kể các nhiệm vụ khác nhau. Bạn chỉ có thể tìm kiếm mỗi khi bạn cố gắng làm điều gì đó, nhưng ngoài việc lãng phí thời gian, bạn có thể không tìm thấy bất cứ điều gì phù hợp với tìm kiếm cụ thể của bạn. Cách tốt nhất là chỉ cần làm quen với thư viện và ghi nhớ tên hàm và những gì chúng làm.


6
Đó là rất nhiều sự ghi nhớ, đặc biệt là việc đặt tên khá không nhất quán của toàn bộ rất nhiều chức năng ;-)
Joey

@Joey Đồng ý. Akin để ghi nhớ thư viện Java, ngoại trừ việc đó sẽ ít hữu ích hơn vì nó dài dòng hơn.
Matthew đọc

3
Tôi thấy rằng các hàm quan trọng nhất cho các thách thức mà tôi đã gặp cho đến nay là các hàm thao tác chuỗi và các hàm thao tác mảng. Sử dụng sáng tạo của những người thực sự có thể cắt giảm mã.
migimaru

6

Chạy các chức năng bên trong chuỗi.

Thử đi:

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

Hoặc thử điều này:

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

Điều này chỉ hoạt động với các chuỗi sử dụng ""và heredocs (KHÔNG làm cho nhầm lẫn với nowdocs).

Sử dụng các hàm lồng nhau chỉ có thể bên trong heredocs lồng nhau (hoặc bạn sẽ gặp phải các lỗi phân tích cú pháp)!


you will run into parse errorsTôi không thể tự đọc nó? Làm thế nào để động cơ Zend pesky kết hợp điều này với nhau
Stan Strum

Lần tới khi tôi ở trong một đối số "PHP là một ngôn ngữ lập trình tốt" , tôi sẽ sử dụng điều này như một điểm đối lập. Ồ
primo

@primo Có tệ không? : O
Ismael Miguel

5

vui vẻ với các dự báo

  • !!$foosẽ biến bất kỳ giá trị trung thực nào thành true(hoặc 1đầu ra), giá trị giả (0, chuỗi trống, mảng trống) thành false(hoặc đầu ra trống)
    Điều này hiếm khi cần trong golf golf, vì trong hầu hết các trường hợp bạn cần boolean, có một diễn viên ngầm nào.

  • (int)$foocó thể được viết là $foo|0hoặc foo^0, nhưng có thể cần dấu ngoặc đơn.
    Đối với booleans và chuỗi, $foo*1hoặc +$foocó thể được sử dụng để truyền tới int.

  • Không giống như hầu hết các ngôn ngữ khác, PHP xử lý các chuỗi với các giá trị số là số. Vì vậy, nếu bạn có bất kỳ chuỗi nào chứa một số bạn phải tính toán, chỉ cần tính toán.
  • Một cách khác không hoạt động: Để nhân bất kỳ số nào trong một biến với 10, bạn có thể nối thêm số không: *10-> .0. Nhưng trong trường hợp này, PHP sẽ lấy dấu chấm làm dấu thập phân và khiếu nại. (Tuy nhiên, nó khác nhau nếu bạn có số lượng không thay đổi trong một chuỗi.)
  • Để biến một mảng thành một chuỗi, sử dụng jointhay vì implode.
    Nếu bạn không cần một người phân định, hãy sử dụng nó: join($a)không giống nhưjoin('',$a)
  • Chuỗi tăng: Imo tính năng tuyệt vời nhất là $s=a;$s++;sản xuất $s=b;. Điều này làm việc với các ký tự chữ hoa và chữ thường. $s=Z;$s++;kết quả trong $s=AA;.
    Điều này cũng hoạt động với trường hợp hỗn hợp: aZto bA, A1to A2, A9to B0z99Zto aa00A.
    Giảm không hoạt động trên chuỗi. (Và nó không bật NULL).
    Quay lại PHP 3, $n="001";$n++;được sản xuất $n="002";. Tôi hơi buồn họ đã loại bỏ điều đó.

Bất cứ điều gì bạn chơi golf: luôn có bàn ưu tiên người vận hành trong tầm tay.


4

Sử dụng shorttags

Trong mã thông thường, đó là cách thực hành tốt để sử dụng <?php?>. Tuy nhiên, đây không phải là mã thông thường - bạn đang viết mã golf. Thay vì <?php, viết <?. Thay vì <?php echo, viết <?=. Đừng gõ ?>vào cuối - nó hoàn toàn tùy chọn. Nếu bạn cần ?>một số lý do (ví dụ để xuất văn bản, và nó ngắn hơn bằng cách nào đó, hoặc một cái gì đó, đừng đặt dấu chấm phẩy trước nó - không cần thiết, như ?>ngụ ý dấu chấm phẩy.

Sai (chắc chắn quá dài):

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

Chính xác:

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

Với -rcờ ( miễn phí ), bạn không cho bất kỳ thẻ nào cả (và bạn không được phép sử dụng bất kỳ thẻ nào).
Tít

4

lặp qua các chuỗi

có thể được thực hiện với 26 byte hoặc từ 24 xuống 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&$bthực hiện một phép toán AND trên (mã ascii của) các nhân vật trong $a$b
và kết quả trong một chuỗi có chiều dài tương tự như ngắn hơn $a$b.


bạn có thể xin vui lòng thêm ord($s[$p++])như thay thế for(;$s+=ord($argv[++$i])%32?:die($s==100););chống lại for(;$c=$argv[++$i];)$s+=ord($c)%32;echo$s==100;ở câu hỏi này codegolf.stackexchange.com/questions/116933/...
Jörg Hülsermann

Vui lòng thêm ~cho các trường hợp bạn chỉ làm việc với các chữ số
Jörg Hülsermann

Lưu ý rằng PHP 7.2 mang lại các cảnh báo cho ~$ccách tiếp cận.
Tít

4

Sử dụng toán tử ternary

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

có thể được viết tắt là này:

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

Ngắn hơn hả?


Viết tắt có điều kiện Tốt hơn nên nói tên thật của nó, vì vậy những người quan tâm đến nhiều chi tiết hơn có thể tìm thấy nó trong tài liệu: toán tử ternary .
manatwork

3
Câu hỏi yêu cầu các mẹo có phần cụ thể đối với PHP. Đây là một trong những lời khuyên cho tất cả các ngôn ngữ .
Peter Taylor

3
Toán tử ternary có một hành vi kỳ lạ trong PHP, nếu bạn lồng nó. a?aa:ab?aba:abb:bđánh giá (a?aa:ab)?(aba):(abb)hoặc một cái gì đó như thế.
Tít

1
Và bắt đầu với PHP 5.3, bạn có thể bỏ qua toán tử thứ hai: $a?:$bgiống như $a?$a:$b.
Tít

1
@Cyoce ||chuyển sang boolean trong PHP.
Tít

3

bởi bất kỳ tên nào khác ... bí danh chức năng

sử dụng ...

  • join thay vì implode
  • chopthay vì rtrim( choptrong PERL thì khác!)
  • die thay vì exit
  • fputs thay vì fwrite
  • is_intthay vì is_integerhoặcis_long
  • is_realthay vì is_floathoặcis_double
  • key_exists thay vì array_key_exists
  • mysql thay vì mysql_db_query

... Để đặt tên cho các bí danh quan trọng nhất. Hãy xem http://php.net/aliases để biết thêm.


Ồ ... và bạn có biết rằng nó diehoạt động có và không có tham số không? die(1)sẽ thoát khỏi chương trình với mã lỗi 1(không hoàn toàn chắc chắn về điều này; cần thử nghiệm); diesẽ thoát bằng mã 0die("Hello")sẽ thoát bằng mã 0sau khi in Hello.
Tít

3

Mảng kết hợp có thể được hợp nhất với +toán tử.

Thay vì:

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

Sử dụng:

$merged = $a + $b;

Lưu ý rằng +toán tử cũng hoạt động với các mảng được lập chỉ mục, nhưng có lẽ không làm những gì bạn muốn.


Thật vậy, thường là một sự thay thế tốt, mặc dù không hoàn toàn giống nhau: pastebin.com/seYeaP38
manatwork

À đúng rồi, dang nó, ban đầu tôi có tiêu đề "mảng kết hợp ..." và sau đó xóa nó đi. Tôi sẽ làm rõ, cảm ơn.
Alex Howansky

mảng số cũng có thể được hợp nhất bằng cách sử dụng +, miễn là các chỉ mục là khác biệt. Nếu không, các giá trị từ mảng đầu tiên sẽ được ghi đè bằng các giá trị từ mảng thứ hai (giống như mảng_merge). Sự khác biệt: +không sắp xếp lại các chỉ mục.
Tít

3

mảng_flip vs mảng_search

sử dụng

array_flip($array)[$value]

thay vì

array_search($value,$array)

để lưu 1 Byte trong mảng trong đó sự xuất hiện của mỗi giá trị là duy nhất


3

Một số sự thật thú vị về các biến số

Tôi chỉ phải chia sẻ chúng (ngay cả trước khi tôi xác minh rằng ít nhất một trong số chúng giúp chơi gôn):

  • Sử dụng chữ cái: $x=a;$$x=1;$x++;$$x=2;echo"$a,$b";in 1,2
    nhưng các phép toán số học khác không hoạt động với chữ cái.
  • Như primo đã đề cập trước đó , bạn có thể sử dụng số thuần làm tên biến:
    $a=1;$$a=5;$a++;$$a=4;${++$a}=3;echo${1},${2},${3};bản in 543.
  • Bạn không chỉ có thể sử dụng [0-9a-zA-Z_]cho tên biến, mà là MỌI chuỗi:
    $x="Hello!";$$x="Goodbye.";echo${"Hello!"}; print Goodbye..
  • Nhưng: Mọi thứ nhưng [a-zA-Z_][a-zA-Z_0-9]* tên biến đổi đều yêu cầu niềng răng để sử dụng theo nghĩa đen.
  • Không có biến được định nghĩa, $$x=1các tập hợp ${NULL}, giống như ${false}${""} .
  • $a=1;$$a=5;không chỉ thiết lập ${1}, mà còn${true} .

  • một điều nữa, điều kỳ lạ nhất mà tôi đã tìm thấy cho đến nay: Hãy thử $a=[];$$a=3;echo${[]};. Vâng, nó in 3!

Lý do cho hầu hết điều này: tên biến luôn được ước tính thành chuỗi.
(Cảm ơn @Christoph đã chỉ ra.)
Vì vậy, bất cứ điều gì bạn nhận được khi bạn printhoặc echobiểu thức, đó là những gì bạn nhận được dưới dạng tên biến.


1
Tên biến được chuyển đổi thành chuỗi giải thích ba điểm cuối cùng trong danh sách của bạn. []chuyển đổi thành Array: ${[]} = 5;echo $Array;bản in 5. Tôi khá chắc chắn rằng bạn biết điều đó nhưng nó có thể không rõ ràng với mọi người :)
Christoph

@Jeff Tôi đã sửa lỗi chính tả. Cảm ơn đã chú ý.
Tít

2

ngắt dòng
nếu đầu ra yêu cầu ngắt dòng, sử dụng ngắt dòng vật lý (1 byte) thay vì "\n"
Điều này cũng mang lại cho bạn một lợi ích có thể có để chọn giữa dấu ngoặc đơn và dấu ngoặc kép.


2

tránh trích dẫn khi có thể

PHP mặc nhiên chuyển các từ chưa biết thành chuỗi ký tự.

$foo=foo;giống như $foo='foo';(giả sử rằng đó fookhông phải là từ khóa hoặc hằng số xác định): $foo=echo;không hoạt động.

NHƯNG: $p=str_pad;không; và $p(ab,3,c)đánh giá để abc.

Sử dụng chuỗi ký tự không có dấu ngoặc kép sẽ mang lại Thông báo cho Use of undefined constant; nhưng điều đó đã thắng hiển thị nếu bạn sử dụng giá trị mặc định cho error_reporting(tham số CLI -n).


Tôi chỉ nhận thấy: Câu trả lời này là một bản sao được mở rộng / cập nhật của codegolf.stackexchange.com/a/2916/55735 .
Tít

Lưu ý: PHP trước 7.2 mang lại Thông báo (mà bạn có thể áp dụng với -ncờ); 7.2 mang lại Cảnh báo; phiên bản sau sẽ ném lỗi!
Tít

2

Các hàm mũi tên trong PHP 7.4

PHP 7.4 hiện đã có phiên bản RC2 và hy vọng sẽ được phát hành sau khoảng 2 tháng nữa. Danh sách các tính năng mới có ở đây (trang này thực sự có thể được cập nhật khi 7.4 được phát hành). Trong 7.4, cuối cùng PHP đã có các hàm mũi tên, vì vậy không chỉ các câu trả lời của hàm có thể ngắn hơn mà còn chuyển các bao đóng cho các hàm khác cũng có thể ngắn hơn rất nhiều. Đây là vài ví dụ:

Trả về đầu vào + 1:

Hàm ẩn danh (bao đóng) - 25 byte - Hãy thử trực tuyến!

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

Hàm mũi tên - 12 byte - Hãy thử trực tuyến!

fn($n)=>$n+1

Nhân các mục của đầu vào đầu tiên (mảng ints) với đầu vào thứ hai (int):

Hàm ẩn danh (bao đóng) - 72 byte - Hãy thử trực tuyến!

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

Hàm mũi tên - 38 byte - Hãy thử trực tuyến!

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

Bạn có để ý rằng $n có thể truy cập trong chức năng bên trong mà không cần một use $ntuyên bố? Vâng, đó là một trong những tính năng chức năng mũi tên.


Là một lưu ý phụ, tôi không thể làm cho các hàm mũi tên hoạt động theo cách đệ quy (gọi cùng một hàm mũi tên bên trong), vì chúng ta không thể đặt tên cho chúng và lưu trữ chúng dưới dạng một biến trong một biến như $fkhông thể $ftruy cập được với chính nó (buồn ). Vì vậy, ví dụ này không hoạt động và sử dụng $ftrong dòng đầu tiên gây ra lỗi nghiêm trọng:

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

Nhưng việc gọi một hàm mũi tên với một hàm mũi tên khác sẽ hoạt động:

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

Nếu thay vì $f=fn($n)=>$n?$f($n-1):0;bạn làm gì $f=$F=fn($n)=>$n?$F($n-1):0;? Liệu điều đó có hiệu quả? Và sau đó bạn gọi $(5)như bình thường.
Ismael Miguel

@IsmaelMiguel nó dường như vẫn ném lỗi tương tự. Bạn thực sự có thể thử trên tio.run # php vì Dennis đã cập nhật PHP của nó lên 7.4 RC2 một lúc trước.
Đêm

Không thể làm cho nó hoạt động. Có vẻ như chỉ có các biến được xác định trước là có sẵn.
Ismael Miguel


1

Mảng trực tiếp trả lại từ các chức năng.

Ví dụ, thay vì điều này:

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

Bạn có thể làm:

echo foo()[$n];

Điều này cũng hoạt động với các phương thức:

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

Bạn cũng có thể khai báo mảng trực tiếp:

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

1

Sử dụng end()thay vìarray_pop()

Các end()chức năng không chỉ di chuyển con trỏ nội đến cuối mảng, nó cũng trả về giá trị cuối cùng. Tất nhiên lưu ý rằng nó không loại bỏ giá trị đó, vì vậy nếu bạn không quan tâm mảng đó chứa gì sau đó, bạn có thể sử dụng nó thay vì array_pop().


1

nhân đôi mảng_flip vs in_array vs mảng_unique

trong trường hợp đặc biệt này, một mảng kép_flip tiết kiệm 10 byte

($f=array_flip)($k=$f($c)))loại bỏ tất cả các giá trị tăng gấp đôi trong mảng và tôi đã giảm này $c=[],, |in_array($o,$c)và thay thế array_keys($c)bằng$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

Phiên bản trực tuyến

chống lại

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

Phiên bản trực tuyến

chống lại mảng_unique, nó tiết kiệm được 2 byte

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

Phiên bản trực tuyến

Sau khi tìm thấy một lỗi trong chương trình này và việc thay thế $x[$i]==$o?:$c[$x[$i]]=$ocho ($p=$x[$i])==$o?:$k[$c[$p]=$o]=$pmảng kép_flip không còn cần thiết nữa


liên kết an toàn array_unique. Yay!
Tít

@Titus Tôi đã thêm đề xuất của bạn
Jörg Hülsermann

1

các chuỗi giao nhau

Bạn đã bao giờ sử dụng
join("DELIMITER",str_split($s))(31 byte) hoặc thậm chí
preg_replace(".","DELIMITER",$s)(32 byte)
chưa?

Có tích hợp sẵn cho việc đó:

Hãy thử chunk_split($s,1,"DELIMITER")(29 byte).


Nếu bạn bỏ qua tham số thứ ba, chunk_splitsẽ sử dụng \r\n; có thể giúp bạn tiết kiệm 7 hoặc 8 byte.

Nhưng hãy cẩn thận: chunk_splitcũng nối thêm dấu phân cách vào chuỗi,
vì vậy bạn có thể không nhận được chính xác những gì bạn muốn.

(Nếu bạn không cung cấp độ dài chunk, nó sẽ sử dụng 76. Khá bất thường đối với môn đánh gôn, nhưng ai biết được.)


Có lẽ bạn nên thêm một ví dụ kết hợp với strtrtôi thích ý tưởng này.
Jörg Hülsermann

1

unset () vs INF

Trong trường hợp tìm kiếm tối thiểu trong một mảng, bạn có thể sử dụng thay vì

unset($var[$k]);

$var[$k]=INF;

để tiết kiệm 3 byte


1

thông số

Trong một số trường hợp, bạn có đầu vào của các ký tự và bạn nên xuất chúng lặp lại với đầu vào bằng 0 cho mỗi ký tự.

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

(52 byte) ngắn hơn

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

hoặc là

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

(54 byte mỗi)

Làm thế nào nó hoạt động ví dụ đầu vào a1b2c1

$zkhông được đặt (ngầm NULL), vì vậy--$z không có gì và là giả;

$c="a", $z="1"$i=2-> $c.$z="a1"là truthy -> đầu ra"a"

--$z=0; vì vậy chúng tôi đặt $c="b", $z="2"(và $i=4) -> $c.$z="b2"là trung thực -> đầu ra"ab"

--$z=1 -> đầu ra "abb"

--$z=0; Vì vậy, chúng tôi đặt $c="c"$z=1 $c.$z="c1"là đầu ra thực sự"abbc"

--$z=0vì vậy $c=""$z=""-> $c.$z=""là giả -> ngắt vòng


1

Kết hợp forcác vòng lặp

Giả sử bạn có mã của mẫu sau:

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

cái này thường có thể được cuộn lại dưới dạng sau:

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

trong đó đại diện cho một toán tử kết hợp chung. Điều này thường dẫn đến việc giảm số byte, nhưng có thể sẽ cần một số sáng tạo. $cond2sẽ cần phải được viết để nó thất bại lần đầu tiên thông qua. $post1cũng nên không thực hiện lần đầu tiên, mặc dù có thể dễ dàng cấu trúc lại trước để $post1không hiện diện.

Nếu bạn đang làm việc với ba vòng lặp lồng nhau trở lên, bạn cũng có thể kết hợp hai vòng đầu tiên, sau đó kết hợp nó với vòng lặp khác, v.v. Tôi thấy rằng nhìn chung dễ dàng hơn để kết hợp từ trong ra ngoài.


Ví dụ, xem xét giải pháp sau đây cho fractal thảm H ( 97 byte ):

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;

Điều này có thể được điều chỉnh lại theo cách sau:

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&&printngăn chặn printlần lặp đầu tiên, và cũng không tăng $i.

và cuối cùng ( 93 byte ):

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 sẽ thất bại lần đầu tiên vì cả hai biến không được xác định.


1

Xóa các ký tự trong một chuỗi

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

lưu 1 ký tự so với

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

Lưu ý rằng điều này hoạt động cho tất cả các chuỗi (không trống), không chỉ các ký tự.
Máy

@CalculatorFeline Tại sao nó không hoạt động cho các chuỗi trống? Nó không có ý nghĩa hoặc trường hợp này.
Jörg Hülsermann

Chà, phiên bản đầu tiên không hoạt động ""và dù sao nó cũng không hữu dụng lắm.
Máy

1
@CalculatorFeline Và trong trường hợp này, giải pháp byte không tốt hơn nhiều. Thật vô nghĩa khi làm điều này theo cách đó.
Jörg Hülsermann

3
Ví dụ tham gia của bạn bị thiếu a ). Và strtr($string,[" "=>""])thậm chí còn ngắn hơn.
Tít


1

Sử dụng toán tử boolean thay vì strtoupper()strtolower()

Nếu bạn đang làm việc riêng với các chuỗi bao gồm các ký tự bảng chữ cái, bạn có thể sử dụng các toán tử boolean để thay đổi chúng thành chữ hoa hoặc chữ thường với ít tổ hợp phím hơn các hàm dựng sẵn của PHP.

Thí dụ:

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

Mọi thứ phức tạp hơn một chút đối với các chuỗi có độ dài tùy ý, nhưng các toán tử &^toán tử sẽ cắt ngắn kết quả theo độ dài của chuỗi đầu vào ngắn hơn. Vì vậy, ví dụ, nếu $Wlà một chuỗi khoảng trắng ít nhất là bằng bất kỳ đầu vào nào $s, thì ~$W&$stương đương với strtoupper($s)$s|$W^$stương đương với strtolower($s)(trong khi $s|$Wchính nó sẽ tạo ra một chuỗi có khoảng trắng bổ sung trừ khi $s$W có độ dài bằng nhau).


0

sử dụng các hàm không dùng nữa
Nếu bạn có thể sử dụng POSIX thay vì regex PERL mà không lãng phí quá 5 byte cho biểu thức, sử dụng ereghoặc eregithay vì preg_match, splithoặcspliti thay vì preg_split.
splitCũng có thể được sử dụng như một từ đồng nghĩa explodecho hầu hết các dấu phân cách.

Các chức năng này được đánh dấu không dùng nữa và sẽ đưa ra các E_DEPRECATEDthông báo, nhưng (không thể tìm thấy nguồn ngay bây giờ) Tôi nghĩ rằng tôi đã đọc rằng các cảnh báo và thông báo là ok.


2
Xem ra! Chúng đã bị xóa trong PHP 7.0.
Ô
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.