Tips untuk bermain golf di PHP

37

Apa tips umum yang Anda miliki untuk bermain golf di PHP? Saya mencari ide yang dapat diterapkan pada masalah kode golf secara umum yang setidaknya agak spesifik untuk PHP (mis. "Hapus komentar" bukan jawaban). Silakan kirim satu tip per jawaban.

JiminP
sumber
Tunggu, apa aku melakukannya dengan benar? ... Ngomong-ngomong, aku benar-benar ingin tahu tentang yang ini. PHP digunakan oleh banyak orang dan pegolf, tetapi saya hampir tidak tahu cara golf kode PHP.
JiminP
Gunakan tag pendek <??> Ini dapat menghemat beberapa byte.
Mob

Jawaban:

22

Memahami bagaimana variabel dan spasi putih berinteraksi dengan konstruksi bahasa PHP.

Dalam golf waktu saya (memang singkat), saya telah menemukan bahwa konstruksi bahasa PHP (misalnya gema, return, untuk, sementara, dll) berperilaku dengan cara yang kurang intuitif ketika berinteraksi dengan variabel dan spasi.

echo$v;, misalnya, sangat valid, sebagaimana adanya return$v;dan konstruksi serupa lainnya. Pengurangan kecil ini di ruang putih dapat menyebabkan penurunan kumulatif yang signifikan dalam panjang.

Perlu diingat, bahwa variabel sebelum konstruksi bahasa memerlukan spasi setelah, seperti dalam contoh berikut:

foreach($a AS$b){}

Karena ASmerupakan konstruksi bahasa, spasi tidak diperlukan sebelum variabel $b, tetapi jika ada yang menghilangkan spasi sebelum itu , menghasilkan $aAS, ini akan diurai sebagai nama variabel dan menyebabkan kesalahan sintaks.

rintaun
sumber
3
foreach($a[1]as$b)tidak membutuhkan ruang putih. Ini bukan tentang konstruksi dan variabel bahasa, tetapi tentang ruang antara kata-karakter dari kata-kata yang berbeda.
Titus
1
Contoh lain di mana Anda perlu spasi putih dalam rangkaian string. Misalnya, echo $a+5." text"tidak akan berfungsi karena PHP berpikir bahwa itu .adalah titik desimal untuk 5. Untuk membuatnya bekerja, Anda perlu menambahkan ruang seperti ini:echo $a+5 ." text"
Business Cat
@BasicSunset Pernyataan itu dapat ditulis sebagai echo$a+5," text";. The echomembangun memungkinkan Anda untuk melewati beberapa parameter. di mana orang harus menulis echo"result: ".($a+5)."!";, Anda dapat menulis echo"result: ",$a+5,"!";. Faktanya, meneruskan beberapa parameter ke sebuah echoadalah optimasi mikro, karena kode akan berjalan sedikit lebih cepat (karena Anda tidak menggabungkan output, tetapi mengirimkannya secara terpisah). Untuk tantangan tentang penulisan kode tercepat, ini mungkin membantu sedikit sangat kecil.
Ismael Miguel
@IsmaelMiguel berfungsi dengan baik echo, tetapi tidak dengan print(yang Anda perlukan jika Anda memasukkannya ke dalam ekspresi: echoadalah konstruksi murni tanpa nilai balik sambil print dapat bertindak sebagai fungsi: tidak memerlukan tanda kurung, tetapi selalu kembali int(1).
Titus
@Itus saya tidak mengatakan apa-apa tentang print.
Ismael Miguel
22

Gunakan string dengan bijak.

Jawaban ini dua kali lipat. Bagian pertama adalah ketika mendeklarasikan string, Anda dapat memanfaatkan konversi implisit PHP dari konstanta yang tidak diketahui ke string untuk menghemat ruang, misalnya:

@$s=string;

Hal @ini diperlukan untuk mengganti peringatan yang akan dihasilkannya. Secara keseluruhan, Anda berakhir dengan pengurangan satu karakter.

adalah bahwa kadang-kadang, mungkin ruang yang efektif untuk mengatur variabel ke nama fungsi yang sering digunakan. Biasanya, Anda mungkin memiliki:

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

Tetapi ketika bermain golf, ini dapat dipersingkat dengan mudah ke:

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

Dengan hanya dua contoh "preg_match", Anda hanya menyimpan satu karakter, tetapi semakin banyak Anda menggunakan fungsi, semakin banyak ruang yang akan Anda simpan.

rintaun
sumber
10
@ tidak diperlukan dalam codegolf; pemberitahuan dan peringatan (termasuk E_DEPRECATED) dapat diterima
Titus
3
@Titus Tetapi dalam PHP, peringatan akan ditampilkan ke keluaran file standar, jadi itu diperlukan.
brianush1
1
@Itus Saya percaya Anda dapat menekan mereka dalam php.inifile
Stan Strum
12

Anda tidak selalu perlu menulis cek bersyarat. Misalnya, beberapa kerangka kerja menggunakan ini di bagian atas file mereka untuk memblokir akses:

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

Atau dalam fungsi normal

$value && run_this();

dari pada

if($value) { run_this(); }
Xeoncross
sumber
Ia bekerja juga di JS
Евгений Новиков
8

Gunakan sintaks array pendek

Sejak PHP 5.4, array dapat dideklarasikan menggunakan tanda kurung siku (seperti halnya JavaScript) alih-alih array()fungsinya:

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

Ini akan menghemat lima byte.


Tetapi mungkin biaya byte jika Anda memiliki "lubang" dalam array asosiatif:

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

kerugiannya hit sedikit kemudian jika Anda bisa mengisi lubang dengan nilai "kosong":

$arr=[0,1,0,3,0,5,0,7,0,9,10,11];
// costs two byte more than
$arr=array(,1,,3,,5,,7,,9,,11);
rink.attendant.6
sumber
2
PHP 7.1 juga memperkenalkan daftar singkat tugas: [,$a,$b,$c]=$argv;.
Titus
7

Gunakan $ {0}, $ {1}, $ {2}, ... daripada $ a [0], $ a [1], $ a [2], ...

Kecuali jika Anda melakukan manipulasi array, sebagian besar referensi ke indeks array $a[$i]dapat diganti dengan sederhana $$i. Ini bahkan benar jika indeks adalah bilangan bulat, karena bilangan bulat adalah nama variabel yang valid di PHP (meskipun literal akan memerlukan tanda kurung, misalnya ${0}).

Pertimbangkan implementasi keran Rabonowitz Wagon berikut ini:

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

Ini dapat ditingkatkan dengan 6 byte, cukup dengan mengganti kedua referensi array $a[$g]dengan $$g:

3.<?for(;$g?$d=0|($$g=$d*$g--/2+($$g?:2)%$g*1e4)/$g--:238<<printf($e?'%04d':'',$e+$d/$g=1e4)^$e=$d%$g;);
primo
sumber
1
Saya baru saja menyimpan 3 byte dengan itu: showcase .
Titus
6

Pelajari sebagian besar fungsi perpustakaan .

Pustaka PHP cukup besar dan menyediakan banyak fungsi mudah yang dapat sangat mempersingkat berbagai tugas. Anda bisa saja mencari setiap kali Anda mencoba melakukan sesuatu, tetapi melebihi membuang waktu Anda mungkin tidak menemukan apa pun yang cocok dengan pencarian khusus Anda. Cara terbaik adalah membiasakan diri dengan perpustakaan dan menghafal nama-nama fungsi dan apa yang mereka lakukan.

Matius Baca
sumber
6
Itu banyak hafalan, terutama mengingat penamaan yang agak tidak konsisten dari banyak fungsi ;-)
Joey
@ Joey Setuju. Sama halnya dengan menghafal perpustakaan Java, kecuali itu bisa dibilang kurang bermanfaat karena lebih bertele-tele.
Matius Baca
3
Saya menemukan bahwa fungsi yang paling penting untuk tantangan yang saya temui sejauh ini di sini adalah fungsi manipulasi string dan array manipulasi. Penggunaan kreatif dari mereka benar-benar dapat mengurangi kode.
migimaru
6

Menjalankan fungsi di dalam string.

Coba ini:

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

Atau coba ini:

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

Ini hanya berfungsi dengan menggunakan string ""dan heredocs (JANGAN membuat kebingungan dengan nowdocs).

Menggunakan fungsi bersarang hanya mungkin di dalam heredocs bersarang (atau Anda akan mengalami kesalahan parse)!

Ismael Miguel
sumber
you will run into parse errorsSaya tidak bisa membacanya sendiri? Bagaimana mesin Zend yang sial menyatukan ini
Stan Strum
Lain kali saya dalam argumen "PHP adalah bahasa pemrograman yang bagus" , saya akan menggunakan ini sebagai titik tandingan. Wow.
primo
@ Primo Apakah itu buruk? : O
Ismael Miguel
5

bersenang-senang dengan typecasts

  • !!$fooakan mengubah nilai kebenaran apa pun menjadi true(atau 1dalam output), nilai falsy (0, string kosong, array kosong) menjadi false(atau output kosong)
    Ini jarang diperlukan dalam kode golf, karena dalam banyak kasus di mana Anda memerlukan boolean, ada pemeran implisit pula.

  • (int)$foodapat ditulis sebagai $foo|0atau foo^0, tetapi mungkin membutuhkan tanda kurung.
    Untuk booleans dan string, $foo*1atau +$foobisa digunakan untuk cast ke int.

  • Tidak seperti kebanyakan bahasa lain, PHP menangani string dengan nilai numerik sebagai angka. Jadi, jika Anda memiliki string yang berisi angka yang harus Anda hitung, hitung saja.
  • Cara lain tidak berfungsi: Untuk mengalikan angka apa pun dalam variabel dengan 10, Anda bisa menambahkan nol: *10-> .0. Tetapi dalam kasus ini, PHP akan mengambil titik sebagai titik desimal dan mengeluh. (Namun berbeda jika Anda memiliki jumlah nol nol dalam sebuah string.)
  • Untuk mengubah array menjadi string, gunakan joinsebagai ganti implode.
    Jika Anda tidak membutuhkan pembatas, jangan gunakan: join($a)lakukan hal yang samajoin('',$a)
  • Menambah string: Fitur imo yang paling menakjubkan adalah yang $s=a;$s++;menghasilkan $s=b;. Ini berfungsi dengan karakter huruf besar dan kecil. $s=Z;$s++;hasil dalam $s=AA;.
    Ini juga bekerja dengan case campuran: aZke bA, A1ke A2, A9ke B0dan z99Zke aa00A.
    Pengurangan tidak bekerja pada string. (Dan itu tidak menyala NULL).
    Kembali di PHP 3, $n="001";$n++;diproduksi $n="002";. Saya sedikit sedih mereka menghapus itu.

Apa pun yang Anda main golf: selalu sediakan meja prioritas operator .

Titus
sumber
4

Gunakan shorttags

Dalam kode normal, itu praktik yang baik untuk digunakan <?phpdan ?>. Namun, ini bukan kode normal - Anda sedang menulis kode kode golf. Alih-alih <?php, tulis <?. Alih-alih <?php echo, tulis <?=. Jangan mengetik ?>di akhir - itu sepenuhnya opsional. Jika Anda perlu ?>untuk beberapa alasan (misalnya untuk menghasilkan teks, dan entah bagaimana lebih pendek, atau sesuatu, jangan meletakkan tanda titik koma di depannya - itu tidak diperlukan, seperti yang ?>menyiratkan titik koma.

Salah (pasti terlalu panjang):

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

Benar:

<?=ucfirst(trim(fgets(STDIN)))?>s!
Konrad Borowski
sumber
Dengan -rbendera ( yang gratis ), Anda bahkan tidak diberi tag sama sekali (dan Anda tidak diizinkan menggunakannya).
Titus
4

perulangan melalui string

dapat dilakukan dengan 26 byte atau dengan 24 hingga 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&$bmelakukan bitwise AND pada (kode ascii) karakter dalam $adan $b
dan menghasilkan string yang memiliki panjang yang sama dengan yang lebih pendek dari $adan $b.

Titus
sumber
dapatkah Anda tambahkan ord($s[$p++])sebagai alternatif for(;$s+=ord($argv[++$i])%32?:die($s==100););terhadap for(;$c=$argv[++$i];)$s+=ord($c)%32;echo$s==100;pertanyaan ini codegolf.stackexchange.com/questions/116933/…
Jörg Hülsermann
Silakan tambahkan ~untuk kasus Anda hanya bekerja dengan angka
Jörg Hülsermann
Perhatikan bahwa PHP 7.2 menghasilkan peringatan untuk ~$cpendekatan tersebut.
Titus
4

Gunakan operator ternary

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

dapat disingkat menjadi ini:

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

Lebih pendek, ya?

Chris vCB
sumber
"Steno bersyarat"? Lebih baik memberi tahu nama aslinya, sehingga mereka yang tertarik dengan lebih detail dapat menemukannya di dokumentasi: operator ternary .
manatwork
3
Pertanyaannya menanyakan tips yang agak khusus untuk PHP. Ini termasuk dalam tips untuk semua bahasa .
Peter Taylor
3
Operator ternary memiliki perilaku aneh di PHP, jika Anda membuatnya. a?aa:ab?aba:abb:bmengevaluasi ke (a?aa:ab)?(aba):(abb)atau sesuatu seperti itu.
Titus
1
Dan mulai dengan PHP 5.3, Anda dapat menghilangkan operator kedua: $a?:$bsama dengan $a?$a:$b.
Titus
1
@Cyoce melakukan ||cast ke boolean dalam PHP.
Titus
3

dengan nama lain ... alias fungsi

gunakan ...

  • join dari pada implode
  • chopalih-alih rtrim( chopdalam PERL berbeda!)
  • die dari pada exit
  • fputs dari pada fwrite
  • is_intbukannya is_integeratauis_long
  • is_realbukannya is_floatatauis_double
  • key_exists dari pada array_key_exists
  • mysql dari pada mysql_db_query

... untuk menyebutkan nama alias yang paling penting. Lihatlah http://php.net/aliases untuk informasi lebih lanjut.

Titus
sumber
Oh ... dan apakah Anda tahu itu dieberfungsi dengan dan tanpa parameter? die(1)akan keluar dari program dengan kode kesalahan 1(tidak sepenuhnya yakin tentang ini; perlu pengujian); dieakan keluar dengan kode 0, dan die("Hello")akan keluar dengan kode 0setelah mencetak Hello.
Titus
3

Array asosiatif dapat digabungkan dengan +operator.

Dari pada:

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

Menggunakan:

$merged = $a + $b;

Perhatikan bahwa +operator juga bekerja dengan array yang diindeks, tetapi mungkin tidak melakukan apa yang Anda inginkan.

Alex Howansky
sumber
Memang, sering kali pengganti yang baik, meskipun tidak persis sama: pastebin.com/seYeaP38
manatwork
Ah ya, sial, saya awalnya memiliki judul "array asosiatif ..." dan kemudian dihapus. Saya akan menjelaskan, terima kasih.
Alex Howansky
array numerik juga dapat digabungkan menggunakan +, selama indeksnya berbeda. Jika tidak, nilai-nilai dari array pertama akan ditimpa dengan yang dari array yang kedua (seperti array_merge). Perbedaannya: +tidak menyusun ulang indeks.
Titus
3

array_flip vs array_search

menggunakan

array_flip($array)[$value]

dari pada

array_search($value,$array)

untuk menyimpan 1 Byte dalam array di mana kemunculan setiap nilai unik

Jörg Hülsermann
sumber
3

beberapa fakta menarik tentang variabel variabel

Saya hanya harus membagikannya (bahkan sebelum saya memverifikasi bahwa setidaknya satu dari mereka membantu bermain golf):

  • Gunakan huruf: $x=a;$$x=1;$x++;$$x=2;echo"$a,$b";cetak 1,2
    tetapi operasi aritmatika lainnya tidak berfungsi dengan huruf.
  • Seperti yang disebutkan sebelumnya , Anda dapat menggunakan angka murni sebagai nama variabel:
    $a=1;$$a=5;$a++;$$a=4;${++$a}=3;echo${1},${2},${3};cetakan 543.
  • Anda tidak hanya dapat menggunakan [0-9a-zA-Z_]untuk nama variabel, tetapi SETIAP string:
    $x="Hello!";$$x="Goodbye.";echo${"Hello!"};cetakan Goodbye..
  • Tetapi: Semuanya kecuali [a-zA-Z_][a-zA-Z_0-9]*sebagai nama variabel membutuhkan kawat gigi untuk penggunaan literal.
  • Tanpa variabel yang ditentukan, $$x=1set ${NULL}, yang sama dengan ${false}dan ${""}.
  • $a=1;$$a=5;tidak hanya diatur ${1}, tetapi juga ${true}.

  • satu lagi, yang paling aneh yang saya temukan sejauh ini: Coba $a=[];$$a=3;echo${[]};. Ya, itu mencetak 3!

Alasan sebagian besar dari ini: nama variabel selalu dievaluasi ke string.
(Terima kasih @Christoph untuk menunjukkan.)
Jadi, apa pun yang Anda dapatkan ketika Anda printatau echoekspresi, itulah yang Anda dapatkan sebagai nama variabel.

Titus
sumber
1
Nama variabel dikonversi menjadi string yang menjelaskan tiga poin terakhir dalam daftar Anda. []dikonversi ke Array: ${[]} = 5;echo $Array;cetakan 5. Saya cukup yakin Anda tahu itu, tetapi mungkin tidak jelas bagi semua orang :)
Christoph
@ Jeff aku memperbaiki kesalahan ketik. Terima kasih telah memperhatikan.
Titus
2

jeda baris
jika output membutuhkan jeda baris, gunakan jeda garis fisik (1 byte) sebagai gantinya "\n"
Ini juga memberi Anda kemungkinan manfaat untuk memilih antara tanda kutip tunggal dan ganda.

Titus
sumber
2

hindari kutipan jika memungkinkan

PHP secara implisit melemparkan kata-kata yang tidak dikenal ke string literal.

$foo=foo;sama dengan $foo='foo';(dengan asumsi itu foobukan kata kunci atau konstanta yang didefinisikan): $foo=echo;tidak berfungsi.

TAPI: $p=str_pad;apakah; dan $p(ab,3,c)mengevaluasi ke abc.

Menggunakan string literal tanpa tanda kutip akan menghasilkan Pemberitahuan untuk Use of undefined constant; tetapi itu tidak akan muncul jika Anda menggunakan nilai default untuk error_reporting(parameter CLI -n).

Titus
sumber
Saya baru saja memperhatikan: Jawaban ini adalah duplikasi codegolf.stackexchange.com/a/2916/55735 yang agak diperluas / diperbarui .
Titus
Catatan: PHP sebelum 7.2 menghasilkan Pemberitahuan (yang dapat Anda tekan dengan -nbendera); 7.2 menghasilkan Peringatan; versi yang lebih baru akan menampilkan Kesalahan!
Titus
2

Fungsi panah di PHP 7.4

PHP 7.4 sekarang dalam versi RC2 dan mudah-mudahan akan dirilis dalam waktu sekitar 2 bulan. Daftar fitur baru ada di sini (halaman ini sebenarnya dapat diperbarui ketika 7.4 dirilis). Pada 7.4, akhirnya PHP memiliki fungsi panah, jadi tidak hanya jawaban fungsi yang dapat lebih pendek sekarang, tetapi juga melewati penutupan ke fungsi lain juga bisa jauh lebih pendek. Berikut ini beberapa contoh:

Masukan kembali + 1:

Fungsi anonim (penutupan) - 25 byte - Cobalah online!

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

Fungsi panah - 12 byte - Cobalah online!

fn($n)=>$n+1

Lipat gandakan input pertama (array int) dengan input kedua (int):

Fungsi anonim (penutupan) - 72 byte - Cobalah online!

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

Fungsi panah - 38 byte - Cobalah online!

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

Apakah Anda memperhatikan bahwa $nfungsi internal dapat diakses tanpa use $npernyataan? Ya itu adalah salah satu fitur fungsi panah.


Sebagai catatan, saya tidak bisa mendapatkan fungsi panah untuk bekerja secara rekursif (memanggil fungsi panah yang sama di dalam dirinya sendiri), karena kita tidak bisa memberi mereka nama dan menyimpannya sebagai penutup dalam variabel seperti $ftidak membuat $fdiakses dengan sendirinya (sedih ). Jadi contoh ini tidak berfungsi dan menggunakan $fdi baris pertama menyebabkan kesalahan 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"

Tetapi memanggil fungsi panah dengan fungsi panah yang berbeda berfungsi:

$f1=fn($n)=>$n+1;
$f2=fn($n)=>$f1($n-1);
$f1(2) // Returns 3
$f2(2) // Returns 2
Night2
sumber
Bagaimana jika $f=fn($n)=>$n?$f($n-1):0;Anda tidak melakukannya $f=$F=fn($n)=>$n?$F($n-1):0;? Apakah itu akan berhasil? Dan kemudian Anda menelepon $(5)seperti biasa.
Ismael Miguel
@IsmaelMiguel tampaknya masih melakukan kesalahan yang sama. Anda sebenarnya dapat mencoba sendiri tio.run # php karena Dennis telah memperbarui PHP-nya menjadi 7.4 RC2 beberapa waktu lalu.
Night2
Tidak bisa membuatnya bekerja. Tampaknya hanya variabel yang ditentukan sebelumnya yang tersedia.
Ismael Miguel
1

Array dereferensi langsung dikembalikan dari fungsi.

Misalnya, alih-alih ini:

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

Anda dapat melakukan:

echo foo()[$n];

Ini bekerja dengan metode juga:

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

Anda juga dapat langsung mendeklarasikan deklarasi array:

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

Gunakan end()sebagai gantiarray_pop()

The end()fungsi tidak hanya memindahkan pointer internal ke akhir array, juga mengembalikan nilai terakhir. Perhatikan tentu saja bahwa itu tidak menghapus nilai itu, jadi jika Anda tidak peduli apa isi array setelahnya, Anda dapat menggunakannya sebagai gantinya array_pop().

Alex Howansky
sumber
1

double array_flip vs in_array vs array_unique

dalam kasus khusus ini, array_flip ganda menghemat 10 Bytes

($f=array_flip)($k=$f($c)))hapus semua nilai ganda dalam array dan saya telah menjatuhkan ini $c=[],, |in_array($o,$c)dan ganti array_keys($c)dengan$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 Online

melawan

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 online

terhadap array_unique menghemat 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 Online

Setelah menemukan bug dalam program ini dan penggantian $x[$i]==$o?:$c[$x[$i]]=$oke ($p=$x[$i])==$o?:$k[$c[$p]=$o]=$parray_flip ganda tidak diperlukan lagi

Jörg Hülsermann
sumber
aman asosiatif array_unique. Yay!
Titus
@Titus Saya telah menambahkan saran Anda
Jörg Hülsermann
1

string berpotongan

Pernahkah Anda menggunakan
join("DELIMITER",str_split($s))(31 byte) atau bahkan
preg_replace(".","DELIMITER",$s)(32 byte)
?

Ada builtin untuk itu:

Coba chunk_split($s,1,"DELIMITER")(29 byte).


Jika Anda menghilangkan parameter ketiga, chunk_splitakan digunakan \r\n; yang dapat menghemat 7 atau 8 byte.

Namun berhati-hatilah: chunk_splitjuga menambahkan pembatas pada string,
jadi Anda mungkin tidak mendapatkan apa yang Anda inginkan.

(Jika Anda tidak memberikan panjang chunk, itu akan menggunakan 76. Agak tidak biasa untuk golf kode, tetapi siapa yang tahu.)

Titus
sumber
Mungkin Anda harus menambahkan contoh dalam kombinasi dengan strtrSaya suka ide ini.
Jörg Hülsermann
1

tidak disetel () vs INF

Dalam pencarian kasus untuk minimum dalam array, Anda dapat menggunakan sebagai gantinya

unset($var[$k]);

$var[$k]=INF;

untuk menyimpan 3 Bytes

Jörg Hülsermann
sumber
1

str_repeat

Dalam beberapa kasus, Anda memiliki input karakter dan Anda harus menampilkannya berulang dengan input nol lebih besar untuk setiap karakter.

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

(52 byte) lebih pendek dari

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

atau

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

(Masing-masing 54 byte)

Cara kerjanya misalnya input a1b2c1

$ztidak diatur (implisit NULL), jadi --$ztidak melakukan apa-apa dan palsu;

$c="a", $z="1"dan $i=2-> $c.$z="a1"benar -> keluaran"a"

--$z=0; jadi kita atur $c="b", $z="2"(dan $i=4) -> $c.$z="b2"benar - output"ab"

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

--$z=0; jadi kami mengatur $c="c"dan $z=1 $c.$z="c1"merupakan output yang benar"abbc"

--$z=0begitu $c=""dan $z=""-> $c.$z=""falsy -> loop break

Jörg Hülsermann
sumber
1

Menggabungkan forloop

Misalkan Anda memiliki kode dari formulir berikut:

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

ini umumnya dapat digulung kembali dalam bentuk berikut:

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

di mana merupakan operator penggabungan generik. Ini biasanya menghasilkan pengurangan jumlah byte, tetapi kemungkinan akan membutuhkan beberapa kreativitas. $cond2perlu ditulis agar gagal pertama kali. $post1harus juga gagal mengeksekusi pertama kali, meskipun mungkin lebih mudah untuk refactor sebelumnya sehingga $post1tidak ada.

Jika Anda bekerja dengan tiga atau lebih loop bersarang, Anda juga bisa menggabungkan dua terlebih dahulu, lalu menggabungkannya ke yang lain, dan seterusnya. Saya menemukan bahwa umumnya lebih mudah untuk menggabungkan dari dalam ke luar.


Sebagai contoh, pertimbangkan solusi berikut untuk fraktal H-carpet ( 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;

Ini dapat dirumuskan kembali dengan cara berikut:

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 mencegah print pada iterasi pertama, dan juga tidak bertambah $i.

dan akhirnya ( 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 akan gagal pertama kali karena kedua variabel tidak terdefinisi.

primo
sumber
1

Menghapus karakter dalam sebuah string

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

menghemat 1 karakter dibandingkan dengan

str_replace(" ","",$string);
Jörg Hülsermann
sumber
Perhatikan bahwa ini berfungsi untuk semua string (bukan kosong), bukan hanya karakter.
CalculatorFeline
@ CalculatorFeline Mengapa itu tidak bisa berfungsi untuk string kosong? Tidak masuk akal atau kasus ini.
Jörg Hülsermann
Nah, versi pertama tidak berfungsi ""dan itu tidak terlalu berguna.
CalculatorFeline
1
@ CalculatorFeline Dan untuk kasus ini solusi nol byte jauh lebih baik. Tidak masuk akal untuk melakukan ini dengan cara itu.
Jörg Hülsermann
3
Contoh bergabung Anda tidak ada a ). Dan strtr($string,[" "=>""])bahkan lebih pendek.
Titus
1

array_merge vs array_push

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

lebih pendek satu byte dari

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

Tidak berfungsi sama dengan array asosiatif

variabel-arg-list PHP> 5.6

Jörg Hülsermann
sumber
1

Gunakan operator boolean bukan strtoupper()danstrtolower()

Jika Anda bekerja secara eksklusif dengan string yang terdiri dari karakter alfabet, Anda dapat menggunakan operator boolean untuk mengubahnya menjadi huruf besar atau kecil dengan penekanan tombol lebih sedikit daripada fungsi bawaan PHP.

Contoh:

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

Hal-hal sedikit lebih rumit untuk string dengan panjang sewenang-wenang, tetapi operator &dan ^akan memotong hasilnya dengan panjang string input yang lebih pendek. Jadi misalnya, jika $Wstring spasi setidaknya selama input apa pun $s, maka ~$W&$ssetara dengan strtoupper($s), dan $s|$W^$ssetara dengan strtolower($s)(sedangkan $s|$Wdengan sendirinya akan menghasilkan string dengan spasi tambahan kecuali $sdan $Wdengan panjang yang sama).

lubang keras melengking
sumber
0

gunakan fungsi yang tidak digunakan lagi
Jika Anda dapat menggunakan POSIX sebagai ganti PERL regex tanpa membuang lebih dari 5 byte pada ekspresi, gunakan eregatau eregialih-alih preg_match, splitatau splitialih-alih preg_split.
splitDapat juga digunakan sebagai sinonim explodeuntuk sebagian besar pembatas.

Fungsi-fungsi ini ditandai sudah usang dan akan membuang E_DEPRECATEDpemberitahuan, tetapi (tidak dapat menemukan sumbernya sekarang) Saya pikir saya telah membaca bahwa peringatan dan pemberitahuan itu ok.

Titus
sumber
2
Awas! Ini dihapus di PHP 7.0.
Payung