Advertisement
Guest User

Print shit in C

a guest
Apr 12th, 2019
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 3.06 KB | None | 0 0
  1. #!/usr/bin/ruby
  2. # A recursive function used elsewhere... not intended for direct use
  3. def target_through_shifts_rec(start, target, start_str, cur_depth, max_depth)
  4.   to_return = start_str
  5.   if ((start == 0) && (start != target))
  6.     start += 1
  7.     to_return += "I"
  8.   end
  9.   return to_return if (start == target)
  10.   # Just finish the thing off once it reaches a certain depth...
  11.   if (cur_depth >= max_depth)
  12.     if (start < target)
  13.       while ((start << 1) <= target)
  14.         to_return += "L"
  15.         start = start << 1
  16.       end
  17.     else
  18.       while ((start >> 1) >= target)
  19.         to_return += "R"
  20.         start = start >> 1
  21.       end
  22.       if (start <= 0)
  23.         to_return += "I"
  24.         start += 1
  25.       end
  26.     end
  27.     while (start < target)
  28.       to_return += "I"
  29.       start += 1
  30.     end
  31.     while (start > target)
  32.       to_return += "D"
  33.       start -= 1
  34.     end
  35.     return to_return
  36.   end
  37.   # Randomly shift or increment/decrement in the proper direction. Favor shifts
  38.   # for the sake of variety.
  39.   if (start > target)
  40.     if (rand < 0.75)
  41.       return target_through_shifts_rec(start >> 1, target, to_return + "R",
  42.         cur_depth + 1, max_depth)
  43.     end
  44.     return target_through_shifts_rec(start - 1, target, to_return + "D",
  45.       cur_depth + 1, max_depth)
  46.   end
  47.   if (rand < 0.75)
  48.     return target_through_shifts_rec(start << 1, target, to_return + "L",
  49.       cur_depth + 1, max_depth)
  50.   end
  51.   return target_through_shifts_rec(start + 1, target, to_return + "I",
  52.     cur_depth + 1, max_depth)
  53. end
  54.  
  55. # Returns a string describing increments and shifts: e.g. "RRRILLD" means shift
  56. # the start right by 3, increment, then shift left by 2, then decrement to
  57. # transform it to the target.
  58. def target_through_shifts(start, target)
  59.   target_through_shifts_rec(start, target, "", 0, 20)
  60. end
  61.  
  62. def translate_shifts_to_c(shift_str, var)
  63.   cur_str = var
  64.   elements = shift_str.scan(/[A-Z]/)
  65.   elements.each do |op|
  66.     if (op =~ /L/)
  67.       cur_str = "(#{cur_str})<<1"
  68.     elsif (op =~ /R/)
  69.       cur_str = "(#{cur_str})>>1"
  70.     elsif (op =~ /I/)
  71.       cur_str = "1+(#{cur_str})"
  72.     elsif (op =~ /D/)
  73.       cur_str = "(#{cur_str})-1"
  74.     end
  75.   end
  76.   cur_str
  77. end
  78.  
  79. def build_c(str)
  80.   return "" if (str.length == 0)
  81.   header = "#define l putchar\n"
  82.   header += "int main(void) {\n"
  83.   prev_val = 64
  84.   inner = "#{prev_val.to_s}"
  85.   str.each_byte do |b|
  86.     shifts = target_through_shifts(prev_val, b)
  87.     prev_val = b
  88.     new = translate_shifts_to_c(shifts, inner)
  89.     inner = "l(#{new})"
  90.   end
  91.   shifts = target_through_shifts(prev_val, 0)
  92.   new = translate_shifts_to_c(shifts, inner)
  93.   inner = "return #{new};\n"
  94.   to_return = header
  95.   # Insert newlines 90 chars, don't break shift operators
  96.   counter = 0
  97.   inner.each_char do |c|
  98.     to_return += c
  99.     if ((c =~ /[l() +-]/) && (counter >= 90))
  100.       counter = 0
  101.       to_return += "\n"
  102.     end
  103.     counter += 1
  104.   end
  105.   # Remove trailing whitespace for cleanliness :)
  106.   to_return.gsub!(/ +?\n/, "\n")
  107.   to_return + "}"
  108. end
  109.  
  110. str = ARGV.join(" ") + "\n"
  111. puts build_c(str)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement