Skip to content

Instantly share code, notes, and snippets.

@shibason
Created September 19, 2010 08:09
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 shibason/586559 to your computer and use it in GitHub Desktop.
Save shibason/586559 to your computer and use it in GitHub Desktop.
QuineAA Generator Generator
MAIN_CODE = %w~
_quine_template_ = ->(_data_, _zipped_, _padding_, _width_, _height_) {
%`
#{(_zipped_) ? "require 'zlib';" : ''}
_aa_data_ = Marshal.load(#{(_zipped_) ? 'Zlib::Inflate.inflate(' : ''}
'#{_data_}'.unpack('m')[0]#{(_zipped_) ? ')' : ''});
_self_ = 'eval$s=%w' << 96 << ($s * #{_padding_});
_result_ = '';
_index_ = -1;
#{_width_ * _height_}.times { |_counter_|
_result_ << (_aa_data_[_counter_] == 1 ? _self_[_index_ += 1] : 32);
_result_ << 10 if (_counter_ % #{_width_} == #{_width_ - 1})
};
_result_[-7, 6] = '' << 96 << '.join';
puts(_result_)
#`
};
$*[0] ? (
__QUINIZER__;
_quine_code_ = _quine_template_[_data_, _zipped_, _padding_, _width_,
_height_];
raise('INSUFFICIENT_CAPACITY') if (_capacity_ < _quine_code_.size + 15);
eval($s = _quine_code_)
) :
eval(__QUINE_TEMPLATE__)
#~.join
QUINIZER = %w~
require 'RMagick';
include (Magick);
_filename_ = $*[0];
_size_ = ($*[1] || 80).to_i;
_threshold_ = QuantumRange * ($*[2] || 0.5).to_f;
_image_ = ImageList.new(_filename_).flatten_images;
_image_columns_ = _image_.columns;
_image_rows_ = _image_.rows;
_resizer_ = ->(_image_) {
(_image_columns_ > _image_rows_) ?
_image_.resize(_size_, _size_ * _image_rows_ / _image_columns_ / 2)
:
_image_.resize(_size_ * _image_columns_ / _image_rows_, _size_ / 2)
};
_image_ = (_image_columns_ > _size_ || _image_rows_ > _size_) ?
_resizer_[_image_.bilevel_channel(_threshold_)] :
_resizer_[_image_].bilevel_channel(_threshold_);
_width_ = _image_.columns;
_height_ = _image_.rows;
raise('INVALID_IMAGE_DATA') if (_width_ < 0 || _height_ < 0);
_bitmap_ = '';
_image_.each_pixel { |_pixel_|
_bitmap_ << ((_pixel_.red < _threshold_) ? '1' : '0')
};
__ADJUSTER__;
_capacity_ = _bitmap_.count('1');
_bit_data_ = Marshal.dump(_bitmap_.reverse.to_i(2));
require 'zlib';
_zip_data_ = Zlib::Deflate.deflate(_bit_data_);
_zipped_ = _bit_data_.size > _zip_data_.size + 37;
_data_ = [ (_zipped_) ? _zip_data_ : _bit_data_ ].pack('m').tr(10.chr, '');
_padding_ = _capacity_ / _data_.size + 1
~.join
ADJUSTER = %w~
_bitmap_[0, 10] = '1' * 10;
_bitmap_[-6, 6] = '1' * 6
~.join
raise 'NO_ARGUMENT' if ARGV.empty?
_width_ = _height_ = _capacity_ = _bit_data_ = _zip_data_ = _zipped_ = _data_ =
_padding_ = 0
eval(QUINIZER.gsub('__ADJUSTER__', ''))
#eval(QUINIZER.gsub('__ADJUSTER__', ADJUSTER))
quine_template = %W~_quine_template_['#{_data_}', #{_zipped_}, #{_padding_},
#{_width_}, #{_height_}]~.join
ARGV.clear
symbol_map = {}
code = (MAIN_CODE.gsub('96', '126').gsub('__QUINE_TEMPLATE__', quine_template)
.gsub('__QUINIZER__', QUINIZER.gsub('__ADJUSTER__', ADJUSTER)))
.gsub(/\b_(\w+)_\b/) do
unless symbol_map.has_key?($1)
raise 'TOO_MANY_SYMBOLS' if symbol_map.size == 26
symbol_map[$1] = ('a'.ord + symbol_map.size).chr
end
symbol_map[$1]
end
if $DEBUG
puts '# capacity'
puts _capacity_
puts '# bit data size'
puts _bit_data_.size
puts '# zipped data size'
puts _zip_data_.size
puts '# code size'
puts code.size + 16
puts '# code'
puts "eval$s=%w~#{code}~.join"
puts '# symbol table'
p symbol_map
end
raise ('INSUFFICIENT_CAPACITY') if (_capacity_ < code.size + 15)
eval $s = code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment