Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Last active January 6, 2021 13:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/cc24733096c5c8f3478e1fe698cecd0b to your computer and use it in GitHub Desktop.
Save JoshCheek/cc24733096c5c8f3478e1fe698cecd0b to your computer and use it in GitHub Desktop.
Sed is not a good language :(

Can you redeem sed's honour?

The premise

Been doing coding challenges. One of them is a golfing challenge, and you can use bash, I've got a really good Ruby solution, but figured I could get it even shorter if I used sed.

The challenge

Stdin contains the challenge input, it is a number which tells you how many lines will follow (for the people using the painful languages). Then that many lines of input. The task is to print the even numbered lines and then print the odd numbered lines.

The tests

I've recreated some example input files, the leading character is so you don't accidentally depend on the ordering of the lines. The 2spaces are b/c bash has a hard time with spaces. Eg you need to get quoting right. The numbers will be in order if your solution is correct.

input1:

6
a  000000
x  333333
x  111111
a  444444
l  222222
f  555555

input2:

5
l  000000
x  333333
q  111111
o  444444
g  222222

A Ruby solution

Here is a Ruby program that handles them, it is slightly degolfed so that it is easier to understand. The actual program, if you want to try to beat it, is these 52 characters: gets;puts$<.lines.partition.with_index{|_,i|i.even?}

$ cat entry.rb
gets
puts $stdin.lines.partition.with_index { |_, i| i.even? }

$ ruby < input1 entry.rb
a  000000
x  111111
l  222222
x  333333
a  444444
f  555555

$ ruby < input2 entry.rb
l  000000
q  111111
g  222222
x  333333
o  444444

CHALLENGE: Can you do this in sed?

This is the best I've been able to come up with for sed, but it fails on the one with 5 lines, I am pretty sure this means that sed kinda sucks. Or maybe just the one that ships with OSX (apparently there are other versions out there that support relative addresses, which seems like a super valuable feature that I don't have access to -.-)

Anyway, redeem sed's honour... if you can 😜

# it took me like 2 hours to figure out that I needed to put that `D` down there,
# I think it's b/c the `H` prepends a newline on the first hold space. It's like
# I, the user, have to do the work of keeping track of where the delimiters are,
# instead of it being smart enough to not print two line delimiters in a row.
# Anyway, it's super terse, which is the only reason I'm playing with it beyond
# the things that it's actually good at.
$ cat entry.sh
sed -n '1d
p
n
H
${x;D;p;}'

# correct
$ bash < input1 entry.sh
a  000000
x  111111
l  222222
x  333333
a  444444
f  555555

# incorrect, it doesn't print the hold space for whatever fkn reason
$ bash < input2 entry.sh
l  000000
q  111111
g  222222
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment