LoginSignup
24
22

More than 5 years have passed since last update.

文字列に書かないで"hello world"したい (Ruby)

Last updated at Posted at 2014-03-15

文字列にそのまま"hello world"って書かないで出力したい
何もないところから"hello world"を生成してみたい

環境: ruby 2.1.1p76

文字コードから変換する

文字コードの配列から変換

配列の作成
str = "hello world"

p str.chars.map{|c|c.ord} # 1文字ずつ変換する方法

p str.chars.map(&:ord) # 上の変形

p str.unpack("U*") # String#unpackで一気に変換する方法

#=> [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
hello_world1(1文字ずつ変換)
p [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100].map(&:chr).join

#=> "hello world"
hello_world2(フォーマット指示子)
p "%c"*11 % [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]

#=> "hello world"
hello_world3(Array#pack)
p [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100].pack("U*")

#=> "hello world"

シーザー暗号もどきを使う

暗号化(空白以外の文字コードをずらす)
str = "hello world"
key = 3;

p str.gsub(/[^ ]/){|c|(c.ord + key).chr}

#=> khoor zruog
hello_world
p "khoor zruog".gsub(/[^ ]/){|c|(c.ord - 3).chr}

#=> "hello world"

基数変換で数値からアルファベットにする

単語ごとに36進数と見なす

10進数の配列にする
str = "hello world"

base10 = str.split.map{|word|word.to_i(36)}
#=> [29234652, 54903217]
hello_world
p [29234652, 54903217].map{|n|n.to_s(36)} * " "
#=> "hello world"

文字列全体を36進数と見なす

10進数にする(記号は数値に置換)
str = "hello world"

base10 = "hello world".tr(" ", ?0).to_i(36)
#=> 63637474127610289
hello_world
p 63637474127610289.to_s(36).tr(?0," ")
#=> "hello world"

36進数についてはこっち→ 36進数でちょっと遊ぶ (簡単な英文を書く)

バイナリから文字列に変換

Array#packで変換

String#unpack
str = "hello world"

p str.unpack("B*")

#=> ["0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100"]
hello_world
p ["0110100001100101011011000110110001101111001000000111011101101111011100100110110001100100"].pack("B*")

#=> "hello world"

Array#pack, String#unpackは全く使いこなせてません...

圧縮されたhello worldを解凍

圧縮
require 'zlib'

str = "hello world"

p Zlib::Deflate.deflate(str)

#=> "x\x9C\xCBH\xCD\xC9\xC9W(\xCF/\xCAI\x01\x00\x1A\v\x04]"
hello_world
require 'zlib'

p Zlib::Inflate.inflate("x\x9C\xCBH\xCD\xC9\xC9W(\xCF/\xCAI\x01\x00\x1A\v\x04]")

#=>hello world

その他

範囲オブジェクトでhelloとworldを生成

hello_world
p [*?d*5..?w*5].values_at(1851107, 8885552) * " "

#=> "hello world"

お分かりいただけただろうか...(アンビリ風)

激重いので注意
吐き気を催す、無駄な計算量 でもけっこう好き

String#trで置換

準備
str = "hello world"

chars = str.chars.uniq.sort.join
#=> " dehlorw"

indexes = str.chars.map{|c|chars.index(c)}.join
#=> "32445075641"
hello_world
32445075641.to_s.tr("0-9", " dehlorw")

#=>hello world

もう直接書けよっていう

AAで表現する

hello_world
puts 6246425679615979961138139223570875575464792243973679554789844694385270361096099355519718858714931870758664473037117779481545063056363660469764318162518838594135530337546681336517263842564103135883461414541393813521206023327887329258741858523283453602760221611404601720969507027168395954.to_s(3).tr("0-2", "\n\\-#")

#=>
#######################################
#-------------------------------------#
#--#---#--#####--#------#-------###---#
#--#---#--#------#------#------#---#--#
#--#####--#####--#------#------#---#--#
#--#---#--#------#------#------#---#--#
#--#---#--#####--#####--#####---###---#
#-------------------------------------#
#--#-#-#---###---####---#------####---#
#--#-#-#--#---#--#---#--#------#---#--#
#--#-#-#--#---#--####---#------#---#--#
#--#-#-#--#---#--#---#--#------#---#--#
#---#-#----###---#---#--#####--####---#
#-------------------------------------#
#######################################

シンボルを使う

hello_world
p [:hello, :world] * " "

#=> "hello world"

文字列ではないけど...

ライブラリのどこかから文字をパクる

全てのシンボルから、文字列を探してみる。

p Symbol.all_symbols.grep(/hello|world/)
#=> [:world_readable?, :world_writable?]

「world」を含むシンボルが2つあった。
どちらもFileクラスのメソッド。

p File.methods.index(:world_readable?)
#=> 5

p File.methods.index(:world_writable?)
#=> 8

methodsの配列の中で5番目と8番目にあるらしい。どっちでもいいけど。
文字列として取り出してみる。

world
p File.methods[5][0,5]
#=> "world"

「hello」を含むシンボルが存在しないので終了。
何やってるんだろ感が半端じゃない。楽しいけど。

3/21 追記

helloも探してみる。

str = "hello"

symbols = Symbol.all_symbols
result = temp = nil

5.times do |i|
  temp = str[0,5-i]
  break unless (result = symbols.grep(/#{temp}/)).empty?
end

p result
# => [:__attached__, :inherited, :hex, :finished, :spec_cache_dir, :check_load_path, :matches_for_glob, :fetcher, :SpecFetcher, :default_spec_cache_dir, :_clear_load_cache, :other, :matches_spec?, :cache_dir, :@cache_dir, :cache_file, :@cache_file, :for_cache, :other_spec, :to_ruby_for_cache, :shebang, :mon_check_owner]
p temp
# => "he"

5.times do |i|
  temp = str[i,5-i]
  break unless (result = symbols.grep(/#{temp}/)).empty?
end

p result
# => [:allocate, :_alloc]
p temp
# => "llo"

"he"と"llo"の組み合わせしかなかった。

多すぎて迷うけど、まぁどれ選んでも文字数に大差ないので、何でもいいから取り出す。

hello_world
p ["".methods[48][0,2], Class.methods[2][1,3], " ", File.methods[5][0,5]].join

# => "hello world"

組み込みじゃないライブラリもrequireしまくったらどこかにhelloが、、、
ないか

それかもうSymbol.all_methodsから全部取り出す

先頭から一番近いシンボルを探す
syms = Symbol.all_symbols

p idx = syms.grep(/he/).map{|s|syms.index(s)}.sort
# => [21, 57, 255, 714, 1715, 1729, 1732, 1784, 1785, 1881, 2004, 2081, 2090, 2111, 2112, 2113, 2114, 2146, 2160, 2212, 2240, 2383]

p syms[idx.first]
# => :__attached__

p idx = syms.grep(/llo/).map{|s|syms.index(s)}.sort
# => [139, 767]

p syms[idx.first]
# => :allocate

p idx = syms.grep(/world/).map{|s|syms.index(s)}.sort
# => [893, 896]

p syms[idx.first]
# => :world_readable?
hello_world
p "#{(s=Symbol.all_symbols)[21][7,2]}#{s[139][1,3]} #{s[893][0,5]}"

# => "hello world"

(´・ω・`)・・・

24
22
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
22