Triển khai các ứng dụng trực tuyến: In các dòng từ một tệp ngược lại


30

Giữa câu hỏi mèo con và xem câu hỏi này tại U & L về một số sedphép thuật, làm thế nào về việc thực hiện tac?


Mục tiêu

Thực hiện một chương trình sẽ đảo ngược và in các dòng trong một tập tin.


Đầu vào

Một tệp, được cung cấp dưới dạng tên hoặc thông qua đầu vào tiêu chuẩn


Đầu ra

Các dòng, đảo ngược, để tiêu chuẩn ra.


Chấm điểm

Byte của mã nguồn.


9
taclà một chút lạ khi nói đến nguồn cấp dữ liệu. Nó biến đổi a\nb\n(trailfeed lineing) thành b\na\na\nb(không có trailfeed lineing) thành ba\n. Đây có phải là cách mã của chúng tôi phải hành xử?
Dennis


10
Ngoài ra, nếu chúng ta phải sao chép hành vi của tac, một câu trả lời Bash 3 byte thực thi tacchỉ là vấn đề thời gian ...
Dennis

1
@Dennis tại thời điểm này có lẽ tốt nhất để lại không xác định.
Nick T

1
@Dennis Làm cho tôi có ý nghĩa. Hình dung các dòng của một tệp dưới dạng các hàng ngang, tất cả kết thúc bằng \n. tacđảo ngược thứ tự của các hàng này. Nếu một \nbị xóa khỏi giữa tệp, hàng nó đã kết thúc được nối vào hàng tiếp theo, nhưng trong trường hợp của dòng cuối cùng, không có hàng tiếp theo để tham gia.
Blacklight Shining

Câu trả lời:


15

GS2, 3 byte

* +

Ba byte theo thứ tự là các dòng phân chia, đảo ngược và nối các dòng.


9

Perl, 11 byte

$\=$_.$\}{

Hành vi chính xác như thế tac. Mã này yêu cầu -pchuyển đổi, mà tôi đã tính là 1 byte.

Chạy thử

$ echo -en 'a\nb' | perl -pe'$\=$_.$\}{' | xxd -g 1
0000000: 62 61 0a                                         ba.
$ echo -en 'a\nb\n' | perl -pe'$\=$_.$\}{' | xxd -g 1
0000000: 62 0a 61 0a                                      b.a.

Làm thế nào nó hoạt động

Như đã giải thích ở đây , -pvề cơ bản , công tắc bao while (<>) { ... ; print }quanh chương trình, do đó mã nguồn tương đương với

 while(<>)
 {
   $\ = $_ . $\
 }
 print

Đối với mỗi dòng đầu vào, chúng tôi thêm dòng hiện tại ( $_) vào $\(ban đầu không xác định), cập nhật kết quả sau với kết quả.

Sau khi tất cả các dòng đã được xử lý, printin giá trị của biến cục bộ $_(không xác định trong phạm vi này), theo sau là dấu tách bản ghi đầu ra ( $\).


Quan tâm để giải thích làm thế nào điều này hoạt động?
xebtl

2
@xebtl Evilly. Thêm công -ptắc sẽ bọc mã của bạn trong một vòng lặp bắt đầu while(<>){và kết thúc } continue { print }, cho phép lọc đầu vào chỉ bằng cách sửa đổi $_. $\=$_.$\chuẩn bị từng dòng đầu vào cho bộ kết thúc bản ghi đầu ra và }{kết thúc whilesớm khối được cung cấp perl , do đó, continuekhối không còn được gắn vào nó. Vì vậy, tất cả các dòng đầu vào được thêm vào $\theo thứ tự ngược lại, cuối continue { print }cùng, cuối cùng sẽ chạy, in "không có gì" ( $_sẽ không hoàn thành sau khi kết thúc đầu vào), nhưng với dấu kết thúc $\.
hobbs

@xebtl grr, định dạng mã trong các bình luận có vẻ hơi bị hỏng khi các dấu gạch chéo ngược và backticks đến gần nhau. Có lẽ bạn có thể đoán những gì tôi đã cố gắng nói.
hobbs

1
@primo Ví dụ đầu tiên cho thấy những gì xảy ra trong trường hợp này. Đầu ra sẽ lạ, nhưng chính xác như của tac.
Dennis

1
@Dennis trang 18 ff của cuốn sách này
msh210

8

Bình thường, 4 byte

j_.z

.zlà đầu vào được phân tách bằng các dòng dưới dạng một danh sách, _đảo ngược nó và jnối nó với một ký tự, theo mặc định là \n.



7

Võng mạc , 7 byte

!rm`.*$

Với một regex duy nhất, Retina chạy trong chế độ Match. Điều này thường chỉ in số lượng các trận đấu, nhưng với !chúng tôi định cấu hình nó để in các trận đấu thực tế thay thế (được phân tách bằng các đường dẫn).

Regex thực tế chỉ là .*$. .*khớp với bất kỳ dòng nào (có khả năng trống), bởi vì .có thể khớp với bất kỳ ký tự nào ngoại trừ các dòng. Tôi sẽ đến $trong một phút.

Làm thế nào để chúng tôi làm cho nó in các trận đấu ngược lại? Bằng cách sử dụng chế độ khớp từ phải sang trái của .NET, được kích hoạt bằng r. Điều này có nghĩa là công cụ regex bắt đầu ở cuối chuỗi khi tìm kiếm kết quả khớp và hoạt động ngược.

Cuối cùng, mlàm cho $khớp với kết thúc của một dòng thay vì kết thúc chuỗi. Tại sao chúng ta thậm chí cần điều đó? Vấn đề là .*tạo ra các trận đấu không liên quan. Hãy xem xét sự thay thế regex

s/a*/$0x/

áp dụng cho đầu vào baaababaa. Bạn sẽ nghĩ rằng điều này sẽ mang lại baaaxbaxbaax, nhưng nó thực sự mang lại cho bạn baaaxxbaxxbaaxx. Tại sao? Bởi vì sau khi khớp aaacon trỏ của động cơ nằm giữa ab. Bây giờ nó không thể khớp với bất kỳ as nào nữa , nhưng a*cũng hài lòng với một chuỗi rỗng. Điều này có nghĩa, sau mỗi trận đấu bạn sẽ nhận được một trận đấu trống khác.

Chúng tôi không muốn điều đó ở đây, vì nó sẽ giới thiệu các dòng trống bổ sung, vì vậy chúng tôi loại bỏ các kết quả trùng khớp đó ( bắt đầu từ các dòng, do chế độ từ phải sang trái) bằng cách yêu cầu các kết quả khớp đó bao gồm phần cuối của dòng.


6

Haskell, 34 byte

main=interact$concat.reverse.lines

[chỉnh sửa]

Đã lưu một byte bằng cách thay thế unlinesbằng concat.


4

CJam, 7 byte

qN/W%N*

Đọc stdin, in ra thiết bị xuất chuẩn.

Giải trình:

q       Get input.
N/      Split at newlines.
W%      Reverse list.
N*      Join with newlines.


4

Befunge-93, 17 byte

~:1+!#v_
>:#,_@>$

Không có gì lạ mắt ở đây; chỉ cần đặt mọi thứ vào ngăn xếp, sau đó bật nó ra.


4

Pure Bash (không có tiện ích bên ngoài), 56

mapfile a
for((i=${#a[@]};i--;));{
printf %s "${a[i]}"
}

Đây là một trong số ít câu trả lời để thực hiện tacmô phỏng chính xác , như được hỏi về nhận xét của Dennis :

$ echo -en 'a\nb' | ./tacemu.sh | xxd -g 1
0000000: 62 61 0a                                         ba.
$ echo -en 'a\nb\n' | ./tacemu.sh | xxd -g 1
0000000: 62 0a 61 0a                                      b.a.
$ 



4

JavaScript (SpiderMonkey Shell), 38 byte

[...read(readline())].reverse().join``

Khá đơn giản


read() đọc một tập tin

readline() đọc một chuỗi từ STDIN

[...str]sẽ chia str thành một mảng ký tự

reverse() sẽ đảo ngược mảng

join`` sẽ collpase mảng thành một chuỗi


4

Python 2, 52 byte

import sys;print''.join(sys.stdin.readlines()[::-1])

1
Không nhập () đọc một dòng từ stdin?
Lynn

@Mauris Đã chỉnh sửa nó
Beta Decay

Thế còn import sys;print sys.stdin.read()[::-1]?
ăn kiêng 1/10/2015

@dieter Điều đó đảo ngược từng nhân vật, thử thách chỉ yêu cầu các dòng được đảo ngược
Beta Decay

ok xấu của tôi - Không đọc nó một cách cẩn thận, xin lỗi
ăn kiêng

4

C #, 179 171 byte

using B=System.Console;class A{static void Main(){var a=new System.Collections.Stack();string b;while((b=B.ReadLine())!=null)a.Push(b);foreach(var c in a)B.WriteLine(c);}}

Đọc các dòng, đặt chúng trong một ngăn xếp, và sau đó viết chúng ngược lại. Tôi sẽ sử dụng Mathicala cho việc này, nhưng nó không có ý nghĩa về EOF.


3

sed, 9 byte

1!G;h;$!d

Không muốn upvote, đây là một sed-liner nổi tiếng.


10
Nếu đó không phải là công việc của riêng bạn, tôi khuyên bạn nên tạo wiki cộng đồng trả lời của bạn.
lirtosiast

3

Perl, 16 byte

print reverse<>

@Dennis oops, bây giờ được hoàn nguyên.
steve

3

Powershell, 41 byte

$a=$args|%{gc $_};[array]::Reverse($a);$a

Lưu trữ nội dung của một dòng tệp theo dòng a, đảo ngược avà cuối cùng in nó.



3

Burlesque , 6 byte

ln<-uN

lnchia dòng, <-đảo ngược, uNnối các dòng và định dạng cho đầu ra thô.


3

Bash, 48 43 ký tự

(Lấy cảm hứng từ kỹ thuật số Chấn thương của Bash câu trả lời . Upvotes cho ý tưởng nên đi với anh.)

mapfile -c1 -C's=$2$s;set'
printf %s "$2$s"

Chạy mẫu:

bash-4.3$ echo -en 'a\nb' | bash tac.sh | xxd -g 1
0000000: 62 61 0a                                         ba.

bash-4.3$ echo -en 'a\nb\n' | bash tac.sh | xxd -g 1
0000000: 62 0a 61 0a                                      b.a.

Tôi nghĩ bạn có thể làm mapfile -c1 -Cfthay vì mapfile -c1 -Cf a.
Chấn thương kỹ thuật số

Chính xác. Tôi cũng phát hiện ra nó trong lúc này, chỉ cần thử một cái gì đó xung quanh khó khăn đó -Ctrước.
manatwork 1/10/2015

3

GNU Awk, 27 ký tự

(Lấy cảm hứng từ Ed Morton 's GNU AWK câu trả lời . CW như tôi không có ý định cướp giải pháp của mình.)

{s=$0RT s}END{printf"%s",s}

Lưu ý rằng bằng cách thay đổi RTRSđiều này trở thành Awk tiêu chuẩn di động nhưng mất khả năng duy trì sự vắng mặt của dòng mới.

Chạy mẫu:

bash-4.3$ echo -en 'a\nb' | awk '{s=$0RT s}END{printf"%s",s}' | xxd -g 1
0000000: 62 61 0a                                         ba.

bash-4.3$ echo -en 'a\nb\n' | awk '{s=$0RT s}END{printf"%s",s}' | xxd -g 1
0000000: 62 0a 61 0a                                      b.a.

Bạn có thể xóa "% s"
ninjalj

@ninjalj, chỉ khi chúng tôi có thể cho rằng đầu vào sẽ không bao giờ chứa %%.
manatwork

3

SNOBOL, 42 byte

S S =INPUT CHAR(10) S :S(S)
 OUTPUT =S
END

2

Gema, 25 ký tự

*\n=@set{s;$0${s;}}
\Z=$s

Chạy mẫu:

bash-4.3$ echo -en 'a\nb' | gema '*\n=@set{s;$0${s;}};\Z=$s'
ba

bash-4.3$ echo -en 'a\nb\n' | gema '*\n=@set{s;$0${s;}};\Z=$s'
b
a


2

sed, 7 byte

G;h;$!d

Điều này hiệu quả với tôi (và đó là giải pháp ngắn nhất ở nơi khác), nhưng tôi không thực sự muốn tìm hiểu tại sao. Tôi chỉ loay hoay với thủ thuật 9 byte nổi tiếng cho đến khi tôi tìm thấy nó. Tôi đoán Ging dòng đầu tiên không làm gì?


2
Thực tế làm một cái gì đó: mã của bạn tạo ra một dòng mới bổ sung ở cuối đầu ra. ( Gnối thêm một dòng mới và nội dung của không gian giữ vào không gian mẫu. Trong khi nối thêm nội dung của không gian giữ trống thực sự vô hại, dòng mới vẫn được nối thêm.)
manatwork 1/10/2015

2

JavaScript (Node.js), 91 byte

console.log(require('fs').readFileSync(process.argv[2])+"".split(d="\n").reverse().join(d))

Ý bạn là console.log((require('fs').readFileSync(process.argv[2])+"").split(d="\n").reverse().join(d))(92 byte)? Mã hiện tại của bạn không đảo ngược các dòng.
Bàn chải đánh răng

2

Bash + tiện ích chung, 25

tr \\n ^G|rev|tr ^G \\n|rev

Đây ^Glà một BELnhân vật theo nghĩa đen . Tôi giả sử đầu vào chỉ có thể in ascii.

Điều này sẽ trthay đổi toàn bộ đầu vào thành một dòng bằng cách thay thế các dòng mới bằng BELs, sau đó thay thế dòng đó rev, sau đó trquay trở lại multiline, sau đó revchọn lại từng dòng để có được đầu ra mong muốn.


2

MATLAB, 44

@(x) strjoin(fliplr(strsplit(x,'\n')),'\n');

Chia chuỗi ở các dòng mới, lật mảng kết quả, sau đó nối lại với các ký tự dòng mới.


2

Julia, 65 byte

open(s->print(join(reverse([l for l=readlines(s)]),"")),ARGS[1])

Cái này lấy một tệp làm đối số dòng lệnh và in các dòng của nó theo thứ tự ngược lại. Trailing newlines được chuyển lên phía trước, không giống nhưtac , đó là hợp pháp.

Ung dung:

function p(s::Stream)
    # Create a vector of the lines of the input stream
    L = [l for l in readlines(s)]

    # Reverse the vector and join it back into a string
    j = join(reverse(L), "")

    # Print the string to STDOUT
    print(j)
end

# Open the file specified in the first command line argument
# and apply the function p to its contents
open(p, ARGS[1])

2

Đường ống , 3 + 2 = 5 byte

Sử dụng rncờ; đọc từ stdin.

RVg

Các rcờ đọc stdin và lưu trữ nó như là một danh sách các dòng trong g(thường là một danh sách các dòng lệnh ar g s). Sau đó chúng tôi đảo ngược danh sách đó, và nó được in tự động. Các ndanh sách nguyên nhân cờ để được xuất ra bằng dòng mới như thiết bị tách.

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.