ใช้“ แทค”: พิมพ์บรรทัดจากไฟล์ย้อนกลับ


30

ระหว่างคำถามลูกแมวและเห็นคำถามนี้ที่ U & Lเกี่ยวกับบางsedมายากลวิธีการเกี่ยวกับการดำเนินการtac?


วัตถุประสงค์

ใช้โปรแกรมที่จะย้อนกลับและพิมพ์บรรทัดในไฟล์


อินพุต

ไฟล์ที่ระบุเป็นชื่อหรือผ่านอินพุตมาตรฐาน


เอาท์พุต

เส้นกลับด้านเพื่อออกมาตรฐาน


เกณฑ์การให้คะแนน

ไบต์ของซอร์สโค้ด


9
tacค่อนข้างแปลกเมื่อพูดถึงการป้อนบรรทัดฟีด มันแปลงa\nb\n(ลากเลื่อนบรรทัด) ลงb\na\nและa\nb(ไม่มีการเลื่อนบรรทัดต่อท้าย) ba\nลง นี่เป็นวิธีที่รหัสของเราควรประพฤติหรือไม่
Dennis


10
นอกจากนี้ถ้าเรามีพฤติกรรมซ้ำแทคของ 3 ไบต์ตอบทุบตีที่รันtacเป็นเพียงเรื่องของเวลา ...
เดนนิส

1
@Dennis ที่จุดนี้น่าจะดีที่สุดที่จะไม่ได้กำหนด
Nick T

1
@Dennis ทำให้รู้สึกถึงฉัน \nเห็นภาพเส้นของไฟล์เป็นแถวแนวนอนทั้งหมดที่ลงท้ายด้วย tacกลับคำสั่งของแถวเหล่านี้ หาก a \nถูกลบออกจากตรงกลางของไฟล์แถวที่ถูกยกเลิกจะถูกรวมเข้ากับแถวถัดไป แต่ในกรณีของบรรทัดสุดท้ายจะไม่มีแถวถัดไปที่จะเข้าร่วม
แบล็กไลท์ส่องแสง

คำตอบ:


15

GS2, 3 ไบต์

* +

สามไบต์คือตามลำดับแบ่งบรรทัดย้อนกลับและเข้าร่วมบรรทัด


9

Perl, 11 ไบต์

$\=$_.$\}{

ทำตัวเหมือนtacกัน รหัสนี้ต้องใช้-pสวิตช์ซึ่งฉันนับเป็น 1 ไบต์

ทดสอบการทำงาน

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

มันทำงานอย่างไร

ตามที่อธิบายไว้ที่นี่ที่-pสวิทช์โดยทั่วไปล้อมwhile (<>) { ... ; print }รอบโครงการเพื่อให้รหัสที่มาเทียบเท่ากับ

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

สำหรับการป้อนข้อมูลแต่ละบรรทัดเราจะเพิ่มบรรทัดปัจจุบัน ( $_) ถึง$\(ไม่ได้กำหนดไว้ในตอนแรก) เพื่ออัปเดตหลังด้วยผลลัพธ์

หลังจากประมวลผลทุกบรรทัดแล้วให้printพิมพ์ค่าของตัวแปรโลคัล$_(ไม่ได้กำหนดในขอบเขตนี้) ตามด้วยตัวคั่นเร็กคอร์ดผลลัพธ์ ( $\)


สนใจที่จะอธิบายว่ามันทำงานอย่างไร?
xebtl

2
@xebtl Evilly เพิ่ม-pสวิทช์ตัดรหัสของคุณในวงที่เริ่มต้นwhile(<>){และสิ้นสุดซึ่งจะช่วยให้การกรองการป้อนข้อมูลเพียงโดยการปรับเปลี่ยน} continue { print } เพิ่มแต่ละบรรทัดของอินพุตไปยังเทอร์มินัลการบันทึกเอาต์พุตและสิ้นสุดบล็อกที่ให้มาด้วย perl ก่อนกำหนดดังนั้นบล็อกจะไม่ถูกยึดอีกต่อไป ดังนั้นทุกสายของท่านจะถูกเพิ่มลงในการสั่งซื้อกลับแล้วในตอนท้ายที่สุดก็วิ่งพิมพ์ "ไม่มีอะไร" ( จะ undef หลังจากการสิ้นสุดของการป้อนข้อมูล) แต่กับเทอร์มิของ $_$\=$_.$\}{whilecontinue$\continue { print }$_$\
ฮอบส์

@ xebtl grr การจัดรูปแบบโค้ดในความคิดเห็นดูเหมือนจะเกิดความเสียหายเล็กน้อยซึ่งแบ็กสแลชและ backticks เข้ามาใกล้กัน บางทีคุณสามารถเดาได้ว่าฉันพยายามจะพูดอะไร
ฮอบส์

1
@primo ตัวอย่างแรกแสดงให้เห็นว่าเกิดอะไรขึ้นในกรณีนี้ ผลลัพธ์จะแปลก แต่เหมือนกับของแทค
Dennis

1
@Dennis หน้า 18 ff ของหนังสือเล่มนี้
msh210

8

Pyth, 4 ไบต์

j_.z

.zคือการป้อนข้อมูลแยกจากกันโดยเส้นเป็นรายการ_ฝืนมันและร่วมได้โดยตัวละครซึ่งเป็นค่าเริ่มต้นคือj\n



7

เรติน่า 7 ไบต์

!rm`.*$

ด้วย regex เพียงครั้งเดียว Retina ทำงานในโหมดจับคู่ โดยปกติแล้วจะพิมพ์จำนวนการแข่งขัน แต่ด้วย!การกำหนดค่าให้เราพิมพ์การแข่งขันที่แท้จริงแทน (คั่นด้วย linefeeds)

regex .*$ที่เกิดขึ้นจริงเป็นเพียง .*ตรงกับบรรทัดใด ๆ (อาจว่างเปล่า) เนื่องจาก.สามารถจับคู่อักขระใด ๆ ยกเว้น linefeeds ฉันจะไป$ในนาทีเดียว

เราจะทำให้มันพิมพ์การแข่งขันในสิ่งที่ตรงกันข้ามได้อย่างไร โดยการใช้โหมดการจับคู่ .NET rขวาไปซ้ายเปิดใช้งานด้วย ซึ่งหมายความว่าเอ็นจิ้น regex เริ่มต้นที่ส่วนท้ายของสตริงเมื่อค้นหารายการที่ตรงกัน

ในที่สุดการmทำให้$ตรงกับจุดสิ้นสุดของบรรทัดแทนส่วนท้ายของสตริง ทำไมเราถึงต้องใช้มัน? ปัญหาคือการ.*สร้างการแข่งขันที่ไม่เกี่ยวข้อง พิจารณาการทดแทน regex

s/a*/$0x/

baaababaaนำไปใช้ในการป้อนข้อมูล คุณจะคิดว่านี้จะให้ผลผลิตbaaaxbaxbaaxแต่จริง ๆ baaaxxbaxxbaaxxแล้วมันจะช่วยให้คุณ ทำไม? เพราะหลังจากที่ตรงกับaaaเคอร์เซอร์ของเครื่องยนต์อยู่ระหว่างและa bตอนนี้มันไม่สามารถจับคู่อีกaต่อไป แต่a*ก็ยังพอใจกับสตริงที่ว่างเปล่า ซึ่งหมายความว่าหลังจากทุกการแข่งขันคุณจะได้รับการจับคู่ที่ว่างเปล่าอีกครั้ง

เราไม่ต้องการที่นี่เพราะมันจะแนะนำบรรทัดว่างเพิ่มเติมดังนั้นเราจึงยกเลิกการจับคู่ที่ไม่เกี่ยวข้อง (ซึ่งเป็นจุดเริ่มต้นของบรรทัดเนื่องจากโหมดจากขวาไปซ้าย) โดยกำหนดให้การจับคู่นั้นรวมถึงจุดสิ้นสุดของ เส้น.


6

Haskell, 34 ไบต์

main=interact$concat.reverse.lines

[แก้ไข]

ที่บันทึกไว้หนึ่งไบต์โดยการแทนที่ด้วยunlinesconcat


4

CJam, 7 ไบต์

qN/W%N*

อ่าน stdin พิมพ์ไปที่ stdout

คำอธิบาย:

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



4

Pure Bash (ไม่มียูทิลิตี้ภายนอก), 56

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

นี่คือหนึ่งในไม่กี่คำตอบที่จะทำการtacจำลองที่ถูกต้องตามที่ถามในความคิดเห็นของ 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 ไบต์

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

ค่อนข้างง่าย


read() อ่านไฟล์

readline() อ่านสตริงจาก STDIN

[...str]จะแบ่งstrเป็นอาร์เรย์ของ chars

reverse() จะย้อนกลับอาร์เรย์

join`` จะ collpase อาร์เรย์เป็นสตริง


4

Python 2, 52 ไบต์

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

1
อินพุตไม่ () อ่านบรรทัดหนึ่งจาก stdin หรือไม่
ลินน์

@Mauris แก้ไขแล้ว
สลายตัวเบต้า

เกี่ยวกับimport sys;print sys.stdin.read()[::-1]อะไร
Dieter

@dieter ที่กลับตัวละครแต่ละตัวความท้าทายขอให้เพียงแค่บรรทัดที่จะกลับ
เบต้าสลาย

โอเคฉันไม่ดี - ไม่ได้อ่านอย่างระมัดระวังขออภัย
Dieter

4

C #, 179 171 ไบต์

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

อ่านบรรทัดวางมันลงในสแต็กแล้วเขียนมันไปข้างหลัง ฉันจะใช้ Mathematica สำหรับเรื่องนี้ แต่มันไม่มีความหมายของ EOF


3

sed, 9 ไบต์

1!G;h;$!d

ไม่ต้องมีการลงคะแนนนี่เป็นเซดซับหนึ่งที่โด่งดัง


10
หากไม่ใช่งานของคุณเองฉันแนะนำให้ทำวิกิชุมชนตอบคำถามของคุณ
lirtosiast


3

Powershell, 41 ไบต์

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

จัดเก็บเนื้อหาของไฟล์บรรทัดต่อบรรทัดaย้อนกลับaและพิมพ์ในที่สุด




3

Bash, 48 43 ตัวอักษร

(ได้รับแรงบันดาลใจจากคำตอบของBashของDigital Trauma การอัปเดตความคิดควรไปหาเขา)

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

วิ่งตัวอย่าง:

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.

ฉันคิดว่าคุณสามารถทำแทนmapfile -c1 -Cf mapfile -c1 -Cf a
Digital Trauma

แก้ไข. ฉันก็ค้นพบมันในขณะเดียวกันก็ลองทำสิ่งที่ยุ่งยาก-Cก่อน
จัดการ

3

GNU Awk, 27 ตัวอักษร

(แรงบันดาลใจจากเอ็ดมอร์ตัน 's คำตอบ GNU Awk . CW ขณะที่ผมไม่ได้มีเจตนาที่จะจี้แก้ปัญหาของเขา.)

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

โปรดทราบว่าด้วยการเปลี่ยนRTRSสิ่งนี้จะกลายเป็นมาตรฐานพกพา Awk แต่ขาดความสามารถในการรักษาบรรทัดใหม่ขั้นสุดท้ายไว้

วิ่งตัวอย่าง:

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.

คุณสามารถลบ "% s"
ninjalj

@ninjalj เฉพาะในกรณีที่เราสามารถสรุปได้ว่าอินพุตจะไม่มี“%”
จัดการ



2

Hassium , 90 Bytes 86 Bytes

use IO;func main(){c=File.readLines(args[0]);for(x=c.length-1;x>=0; println(c[x--]))0;

ดูการขยายที่นี่


1
ฉันสามารถย่อให้สั้นลงได้มากโดยใช้forไวยากรณ์ที่ผิด ดูตัวอย่างได้ที่นี่
FryAmTheEggman

โทรดี @FryAmTheEggman! ฉันเพิ่มมันเข้าไปใน
Jacob Misirian

2

sed, 7 ไบต์

G;h;$!d

สิ่งนี้ใช้ได้กับฉัน (และเป็นวิธีแก้ปัญหาที่สั้นที่สุดที่อื่น) แต่ฉันไม่ต้องการทราบสาเหตุ ฉันเพิ่งยุ่งกับเคล็ดลับ 9 ไบต์ที่มีชื่อเสียงจนกระทั่งฉันพบสิ่งนี้ ฉันเดาว่าGบรรทัดแรกไม่ได้ทำอะไรเลยเหรอ?


2
ทำสิ่งที่จริงแล้ว: โค้ดของคุณสร้างบรรทัดใหม่ขึ้นมาในตอนท้ายของเอาต์พุต ( Gผนวกบรรทัดใหม่และเนื้อหาของพื้นที่พักไว้กับพื้นที่รูปแบบในขณะที่การผนวกเนื้อหาของพื้นที่ว่างเปล่านั้นไม่เป็นอันตรายจริง ๆ บรรทัดใหม่จะถูกต่อท้าย)
จัดการ

2

JavaScript (Node.js), 91 ไบต์

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

คุณหมายถึงconsole.log((require('fs').readFileSync(process.argv[2])+"").split(d="\n").reverse().join(d))(92 ไบต์) หรือเปล่า รหัสปัจจุบันของคุณไม่ย้อนกลับบรรทัด
แปรงสีฟัน

2

Bash + ยูทิลิตี้ทั่วไป, 25

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

ที่นี่ ^Gเป็นตัวอักษรBELตัวอักษร ฉันสมมติว่าการป้อนข้อมูลเป็น ASCII ที่พิมพ์ได้เท่านั้น

นี่เป็นการtrเปลี่ยนรูปแบบอินพุตทั้งหมดเป็นหนึ่งบรรทัดโดยแทนที่บรรทัดใหม่ด้วย BELs แล้วrevเปลี่ยนเป็นบรรทัดนั้นจากนั้นtrเปลี่ยนกลับเป็นหลายrevบรรทัดจากนั้นแทรกแต่ละบรรทัดอีกครั้งเพื่อรับเอาต์พุตที่ต้องการ



2

จูเลีย 65 ไบต์

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

สิ่งนี้ใช้ไฟล์เป็นอาร์กิวเมนต์บรรทัดคำสั่งและพิมพ์บรรทัดในลำดับย้อนกลับ บรรทัดใหม่ของการลากจะถูกย้ายไปด้านหน้าtacซึ่งเป็นเรื่องถูกกฎหมาย

Ungolfed:

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

Pip , 3 + 2 = 5 ไบต์

ใช้rและnธง อ่านจาก stdin

RVg

rธงอ่าน stdin และเก็บไว้เป็นรายการของสายในg(ซึ่งเป็นปกติของรายการบรรทัดคำสั่ง AR กรัม s) จากนั้นเราจะกลับรายการนั้นและพิมพ์อัตโนมัติ nรายการสาเหตุธงที่จะส่งออกที่มีการขึ้นบรรทัดใหม่เป็นตัวคั่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.