99-bottles-of-beer
Web
23
PHP
74
White

Vu Nhat Minh viết ngày 01/09/2015

The song, and the home page

99-bottles-of-beer cũng từng là đề bài của code golf và phpgolf. Mission của chúng ta là code 1 đoạn PHP snippet print lyric của bài hát mà dung lượng đoạn code là nhỏ nhất. Logic thật đơn giản phải không :D

99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.

98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.

97 bottles of beer on the wall, 97 bottles of beer.
Take one down and pass it around, 96 bottles of beer on the wall.

...

1 bottle of beer on the wall, 1 bottle of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.

Với mục tiêu dùng ít code nhất có thể, tôi sẽ không dùng cấu trúc rẽ nhánh if-else, thay vào đó là ternary operator của PHP. Điều đó có nghĩa là bạn có thể viết

(condition)?true-action:false-action

thay vì

if (condition) {true-action} else {false-action}

Đoạn code đầu tiên tôi nghĩ ra trong đầu như sau:

<?php
  $a="beer on the wall";
  for($i=99;$i>=1;$i--){
    $x=($i==1)?"bottle":"bottles";
    $b="<p>$i $x of $a, $i $x of beer.<br>";
    $b.=($i==1)?"Go to the store and buy some more, 99 bottles of     $a.":"Take one down and pass it around, ".($i-1)." $x of $a.</p>";
    print $b;
}
?>

Optimize

Bạn thử ls -l sẽ thấy đoạn code trên có dung lượng 288 bytes!

Để rút ngắn đoạn code trên, đầu tiên tôi nhớ lại những kiến thức cơ bản về PHP: dấu space hoàn toàn không cần thiết, và ký tự ?> ở cuối cũng có thể bỏ đi, PHP long tag ở đầu có thể thay = PHP short tag:

<?
$a="beer on the wall";
for($i=99;$i>=1;$i--){
$x=($i==1)?"bottle":"bottles";
$b="<p>$i $x of $a, $i $x of beer.<br>";
$b.=($i==1)?"Go to the store and buy some more, 99 bottles of $a.":"Take one down and pass it around, ".($i-1)." $x of $a.</p>";
print $b;
}

263 bytes!

Làm thế nào để rút ngắn hơn nữa ? Nếu để ý vào những chi tiết nhỏ hơn, bạn sẽ thấy:

  • trong điều kiện vòng lặp, thay $i>=1 bằng $i>0
  • ($i==1)? là quá dài. Ta có thể bỏ đi 2 dấu ngoặc $i==1?
  • print có thể thay bằng echo. ( Thực tế trong PHP bạn còn có thể thay rtrim -> chop, explode -> split, implode -> join, preg_split -> split (trong 1 vài trường hợp) và preg_replace -> preg_filter trong hầu hết các TH )
  • $x=($i==1)?"bottle":"bottles";" có thể được viết lại : "$x='bottle';$i==1?:$x.='s';"
  • Mỗi lần sử dụng biến $a ta đều có "of" ở đăng trước. Vậy có thể đơn giản cho word "of" vào trong biến a
  • 99 bottles of $a có thể rewrite tiếp lại thành 99{$x}s of $a
  • Chúng ta có thể xoá $i-- trong vòng lặp for, vì thế thêm -- vào trước $i==1 ở dòng gần cuối thành $i--==1 và vì thế bỏ luôn đoạn ($i-1) ở sau đó

Như vậy solution tiếp theo của chúng ta sẽ là

<?
$a=" of beer on the wall";
for($i=99;$i>=1;){
$x='bottle';$i==1?:$x.='s';
$b="<p>$i $x$a, $i $x of beer.<br>";
$b.=$i--==1?"Go to the store and buy some more, 99 {$x}s$a.":"Take one down and pass it around, ".$i." $x$a.</p>";
echo $b;
}

241 bytes!

The trick

Bạn có nghĩ đã hết cách để rút gọn đoạn code ?

Bạn có quên điều gì không ? Bỏ đi tất cả các ký tự line-feed (line break), cho code thành 1 dòng, chúng ra sẽ có kết quả tốt hơn.

<?$a=" of beer on the wall";for($i=99;$i>0;){$x='bottle';$i^1?$x.='s':0;$b="<p>$i $x$a, $i $x of beer.<br>";$b.=$
i--==1?"Go to the store and buy some more, 99 {$x}s$a.":"Take one down and pass it around, ".$i." $x$a.</p>";echo
 $b;}

233 bytes!

Bạn có tin có 1 đoạn code sẽ cho kết quả tương tự với ... 30 bytes ???

!!

<?include('http://bit.ly/xxxx'); ?>

PHP là 1 ngôn ngữ web! Với allow_url_fopenallow_url_include turn on có thể dễ dàng load 1 link kết quả có sẵn đi kèm 1 dịch vụ như bitly !

Stay hungry, stay foolish :D

Tham khảo

  1. phpgolf tips and tricks
  2. Question on StackOverFlow
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Vu Nhat Minh

54 bài viết.
721 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
116 29
Nếu bạn thường vào trang mua sắm của amazon, chắc sẽ chẳng lạ gì với menu Shop by Department. Tốc độ hiển thị nội dung của menu là tức thì so với d...
Vu Nhat Minh viết hơn 2 năm trước
116 29
White
87 4
Lời người dịch Người dịch là một developer , sau khi tìm đọc được bài viết này bằng bản gốc tiếng Anh đã cảm thấy như được "khai sáng" về khả năng...
Vu Nhat Minh viết hơn 2 năm trước
87 4
White
56 5
Đây là phần cuối của một series chuyên về thiết kế UI. Bạn nên đọc (Link) trước khi bắt đầu đọc phần này. Luật số 7: "Ăn trộm" như là một nghệ sỹ...
Vu Nhat Minh viết hơn 2 năm trước
56 5
Bài viết liên quan
White
21 8
Lâu không post gì muốn viết một bài dài dài về js cơ mà đau đầu quá viết mãi không xong, thôi post bài ngắn vậy :smiley: Lấy screen size ở đây tôi...
Hoàng Duy viết hơn 2 năm trước
21 8
White
2 2
Bash script to fast serve Laravel project Lười gõ dòng lệnh quá nên tạo ra cái script để gõ nhanh :D laravelstart.sh /bin/bash if z "$1" ] ...
Vũ Hoàng Chung viết 11 tháng trước
2 2
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
54 bài viết.
721 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!