Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active September 9, 2019 01:03
Show Gist options
  • Save tompng/5c122d953bc15c4eddc0c01161dc459f to your computer and use it in GitHub Desktop.
Save tompng/5c122d953bc15c4eddc0c01161dc459f to your computer and use it in GitHub Desktop.
require 'tempfile'
def codegolf_check file, samples: nil
unless samples
samples = DATA.read.split(/^# ?input\n/).drop(1).map { |s| s.split(/# ?output\n/) }
end
lines = File.read(file).lines
codes = []
lines.each.with_index(1).each do |line, num|
next unless /^# ?code ?(?<name>.*)$/ =~ line
code = ''
(num...lines.size).each do |i|
break if lines[i] =~ /^(# ?code|)$/
code << lines[i]
end
code.chomp! unless code =~ /\A#! ruby.+\n\z/
codes << { code: code, name: (name.empty? ? "LINE#{num}" : "#{name}(#{num})") }
end
codes.group_by { |c| c[:code] }.select { |k, v| v.size >= 2 }.each do |k, v|
puts "duplicate code in #{v.map { |c| c[:name] }}"
end
shortest = nil
codes.each do |c|
file = Tempfile.new ['code', 'rb']
file.write c[:code]
file.close
result = samples.map.with_index(1) do |(sample_input, sample_output), number|
output = IO.popen ['ruby', file.path], 'r+' do |io|
io.write sample_input
io.close_write
io.read
end
if sample_output.chomp == output.chomp
true
else
puts "#{c[:name]} \e[31mX(input#{number})\e[m"
puts "\e[37m--expected--\e[m"
puts sample_output
puts "\e[37m---output---\e[m"
puts output
puts "\e[37m------------\e[m"
false
end
end
if result.all?
puts "#{c[:name]} \e[32mO(#{c[:code].bytesize}B)\e[m"
shortest = c if shortest.nil? || c[:code].bytesize < shortest[:code].bytesize
end
end
if shortest
puts "\e[1mShortest: #{shortest[:name]} #{shortest[:code].bytesize}B\e[m"
puts shortest[:code]
end
exit
end
require './codegolf_checker'
codegolf_check __FILE__
# code
#! ruby -penguin
# code
loop { $> << ($<.getc || break) }
# code foo
Kernel.itself.puts Kernel.itself.gets
# code
$> << 5.times.map { $<.getc } * ''
__END__
#input
Hello
#output
Hello
#input
World!
#output
World!
LINE4 O(17B)
LINE7 O(33B)
foo(10) O(37B)
LINE13 X(input2)
--expected--
World!
---output---
World
------------
Shortest: LINE4 17B
#! ruby -penguin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment