Create a program that output's itself as a series of punch cards:

Computer Punch Card from the 70s


  • You can use any programming language.
  • The output (i.e. punch cards) can be ASCII art.
  • Each line of code must be able to be punched into a single 80 column x 9 row punch card - i.e. you can only use 80 characters.
  • To fit in the 9 rows you need to encode your characters using 4-bit BCD.
  • Extra kudos if you use an old programming language like FORTRAN.


  • 4
    \$\begingroup\$ This is very underspecified (especially for people too young to have used punch cards). What qualifies a line to fit on a punch card? What's a face-like image? And what is your scoring mechanism (you've included 3 different tags which imply different winning criteria). \$\endgroup\$ Commented Aug 9, 2014 at 18:43
  • \$\begingroup\$ sorry, very green here. I'll add more detail \$\endgroup\$
    – Vogel
    Commented Aug 9, 2014 at 18:45
  • \$\begingroup\$ Knowing exactly how many bytes can fit on a card would be helpful. You should remove the code golf tag if you want the votes to be the score. There is already a smiley face challenge so you may want to think of something new. \$\endgroup\$ Commented Aug 9, 2014 at 19:16
  • \$\begingroup\$ is this code-golf or popularity-contest? it can't be both. If it's popularity-contest its a duplicate of codegolf.stackexchange.com/q/16587/15599 and if it's code-golf the shortest answer is print":)". Vogel, welcome to code golf. I fear this question cannot be saved. Writing a good question is hard. Please take a look around answer a few questions, and feel free to post your next question at meta.codegolf.stackexchange.com/q/1847/15599 if you would like the community to help you polish it before posting. \$\endgroup\$ Commented Aug 9, 2014 at 19:16
  • 1
    \$\begingroup\$ I agree with @B1KMusic . I managed to get 116 in perl but for just the card (first 6 lines blank, alternating rows show punch numbers, other half are blank unless they're the two with character numbers. While I'm sure I could maybe under 80 refining it, printing the text and properly knocking it out in EBCDIC encoding would blow virtually any language well over 80... \$\endgroup\$ Commented Aug 11, 2014 at 17:36

1 Answer 1


Ruby - 925

I'll get the ball rolling. Run as "ruby hammer.rb hammer.rb".


def z x
l=x.unpack u='C*'
(0..9).each do|i|d<<[].fill(48+i,0,80);end
i=0;' abcdefghi'.unpack(u).each do|c|h[c-32]=[i,11];h[c]=[i,11,0];i+=1;end
i=0;' jklmnopqr'.unpack(u).each do|c|h[c-32]=[i,10];h[c]=[i,10,11];i+=1;end
i=0;'  stuvwxyz'.unpack(u).each do|c|h[c-32]=[i,0];h[c]=[i,0,10];i+=1;end
i=0;'0123456789-&'.unpack(u).each do|c|h[c]=[i];i+=1;end
i=0;'  :#@\'="'.unpack(u).each do|c|h[c]=[i,8];i+=1;end
i=0;'  [.<(+|'.unpack(u).each do|c|h[c]=[i,8,11];i+=1;end
i=0;'  ]$*);^'.unpack(u).each do|c|h[c]=[i,8,10];i+=1;end
i=0;'  \,%_>?'.unpack(u).each do|c|h[c]=[i,8,0];i+=1;end
i=0;l.slice(0,80).each do|c|h[c].each do|r|d[r][i]=215;end;i+=1;end
puts'    %s'%('_'*81)
puts'   /%-80s |'%l.pack(u)
puts'  / %s |'%d[11].pack(u)
puts' /  %s |'%d[10].pack(u)
(0..9).each do|i|puts'|   %s |'%d[i].pack(u);end
ARGF.each do|l|z l.chop;end


def punch029(line) # line is array of ASCII characters in ordinal (integer) form
  (0..9).each do |i| chad<<[].fill(48+i,0,80) end

  r10 = 10-10
  r11 = 11-1
  r12 = 12-1
  # Reward "bad" input characters with all-row multi-punch.
  # hash = Hash.new( [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] )
  #   OR
  # Reward "bad" input characters by letting Ruby puke. (Jam the machine.)
  hash = Hash.new
  '0123456789-&'.unpack('C*').each_with_index do|c,i| hash[c]=[i] end
  ' ABCDEFGHI'.unpack('C*').each_with_index do|c,i| hash[c]=[i,r12] end
  ' JKLMNOPQR'.unpack('C*').each_with_index do|c,i| hash[c]=[i,r11] end
  ' /STUVWXYZ'.unpack('C*').each_with_index do|c,i| hash[c]=[i,r10] end
  '  :#@\'="'.unpack('C*').each_with_index do|c,i| hash[c]=[i,8] end
  '  [.<(+|'.unpack('C*').each_with_index do|c,i| hash[c]=[i,8,r12] end
  '  ]$*);^'.unpack('C*').each_with_index do|c,i| hash[c]=[i,8,r11] end
  '  \,%_>?'.unpack('C*').each_with_index do|c,i| hash[c]=[i,8,r10] end
  ' abcdefghi'.unpack('C*').each_with_index do|c,i| hash[c]=[i,r12,r10] end
  ' jklmnopqr'.unpack('C*').each_with_index do|c,i| hash[c]=[i,r11,r12] end
  '  stuvwxyz'.unpack('C*').each_with_index do|c,i| hash[c]=[i,r10,r11] end
  hash[32] = []              # fix space

  hole = 215
  line.slice(0,80).each_with_index do |c, index|
    hash[c].each do |row| chad[row][index] = hole end

  puts '    %s' % ('_'*81)
  puts '   /%-80s |' % line.pack('C*')
  puts '  / %s |' % chad[11].pack('C*')
  puts ' /  %s |' % chad[10].pack('C*')
  (0..9).each do |i|
    puts '|   %s |' % chad[i].pack('C*')
  puts "|%s|" % ('_'*84)
#        1         2         3         4         5         6         7         8

ARGF.each do |line|
  • \$\begingroup\$ The requirements aren't clear, e.g. BCD isn't 4 bit and lowercase can be created with the multi-punch key, so I decided that any character a 026/029 punch could encode was fine. \$\endgroup\$ Commented Aug 14, 2014 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.